Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Lisp theory question on setting variables to nil

10 REPLIES 10
Reply
Message 1 of 11
ynotrobits
1700 Views, 10 Replies

Lisp theory question on setting variables to nil

Hello all,

 

I was curious: In the back of my mind there is something that says that in Lisp, one should set variables back to nil when they are no longer needed. For example:

 

(Setq V1 5)

(Do stuff with V5)

(finish with V5)

 

(setq V1 nil)

 

(go on to do other things)

 

 

Do I gain anything by using the above tactic as opposed to placing the variable inside the switch at the beginning of the Lisp:

 

(defun c:MyLisp (/ V5)

 

Or is this something that was necessary when computers had less available memory and is no longer applicable today?

 

Thanks for looking.

10 REPLIES 10
Message 2 of 11
Anonymous
in reply to: ynotrobits

Look into the differences of local and global variables and use the one that best suits your needs.  HTH.

Message 3 of 11
scot-65
in reply to: ynotrobits

If you do not declare "V1" in the defun, it becomes a loose gremlin

that *might* interfere with (your) other third-party programs.

 

It is a good habit to declare these, but optional to clear them at the end of the program.

I personally clear them at the end of the program. I also clear them in the local error handler.

 

As an example, I want to show a dialog box the first time a program is run, but do not

want that dialog to show on successive calls during a particular editing session.

This calls for a "flag" to be set, which, in turn is a gremlin. The structure I use for this

is "USER_ProgramName". This item is not shown in the defun section.

 

(defun c:XYZ ()

 (if (not USER_XYZ)

 (progn

  (setq USER_XYZ 1)

  [show alert box]

 );progn

);if

[do stuff]

(princ)

);end

 

???


Scot-65
A gift of extraordinary Common Sense does not require an Acronym Suffix to be added to my given name.


Message 4 of 11
dbroad
in reply to: ynotrobits

[quote]Do I gain anything by using the above tactic as opposed to placing the variable inside the switch at the beginning of the Lisp:[/quote]


No.  Local variables are generally a better approach.  Garbage cleanup is automatic.

 

If you  need to store data between function executions, name the symbols uniquely so that it is unlikely to be overwritten (example:  providing prompt defaults).

 

If symbols are used in certain loops, then the garbage collection of the loop will clean them up automatically.

(Example:  (foreach n ....)  The n will not need to be set to nil and it does not need to be declared locally.

 

Many situations where a setq is used can be rewritten as nested function calls.

 

For certain situations involving activeX objects, it has been recommended that those objects be released.  I have found that declaring those variables local is generally sufficient.

Architect, Registered NC, VA, SC, & GA.
Message 5 of 11
ynotrobits
in reply to: ynotrobits

Thanks for the answers. Yes, that was my question: Whether or not I gained anything by dumipng the local variables into the "garbage" earlier during the program via nils or waiting until the end of the run to have them dumped automatically.

 

Thanks

Message 6 of 11
TomBeauford
in reply to: ynotrobits

You don't have to worry about conflicts with local variables.  If Var is set to 55 globaly and you set it locally to 30 even if you crash or hit escape before the routine is complete Var will be 55 afterwards.  In a properly error proofed routine the *error* should be localized as well. 

64bit AutoCAD Map & Civil 3D 2023
Architecture Engineering & Construction Collection
2023
Windows 10 Dell i7-12850HX 2.1 Ghz 12GB NVIDIA RTX A3000 12GB Graphics Adapter
Message 7 of 11
stevor
in reply to: ynotrobits

One possible reason to Not make them local variables would be to check their values, their contents, after the routine closes. That would conflict with the global variables that are intentionally global. In that case, setting them to nil would not preserve the values of the intended globals either;  they would have the last contents that was set.

So, often global variable names are made with special  features, like an '*' or a '_' etc; to avoid the accidental overwriting .

S
Message 8 of 11
Kent1Cooper
in reply to: stevor


@stevor wrote:

One possible reason to Not make them local variables would be to check their values, their contents, after the routine closes. ....


I sometimes do that, while I'm developing something, this way:

 

(defun C:Whatever

  (/ *error*); varA varB varC); list ready, but temporarily not localized

  (setq varA nil varB nil varC nil); temporary for testing purposes

  (defun *error*

    ....
 

That way, each time I test the command, it wipes those values clean to start, which has the same effect as if they're localized for its internal purposes, but they remain set after I've run it.  So if it doesn't work right, I can look at variable values until I find one that doesn't exist or is wrong somehow, and narrow down where the problem is.

 

After it's working right, I just take out the ); in the variables list to make those variable names local, and remove the line below that sets them all to nil.

Kent Cooper, AIA
Message 9 of 11
ynotrobits
in reply to: ynotrobits

Boy, that final answer was definitely woth the post. Thanks, that' ssomething that will come in handy as of today since I'm troubleshooting right now; Greatly apprecciated.

Message 10 of 11
dbroad
in reply to: ynotrobits

>>After it's working right, I just take out the ); in the variables list to make those variable names local, and remove the line below that sets them all to nil.<<

 

Or just comment out the line with the nils for future testing.  I sometimes use this technique but have found that with "break on error" active, if an actual error occurs, then the local values remain on the break, even those declared local.  Testing lines one by one by selective loading or by setting breakpoints and stepping can also be used in lieu of temporarily commenting out the local variables. 

 

The advantage to this is that "reset to top" restores the global variables that might have been wiped out during testing. This is done after "break on error" stops execution.  "Go to break point" is also useful for errors.

 

>>Boy, that final answer was definitely woth the post. 

 

Alas, no kudos or chili donuts awarded to any contributor.

Architect, Registered NC, VA, SC, & GA.
Message 11 of 11
stevor
in reply to: Kent1Cooper

To all:   My, our, tools for this:

 

To nil a few vars,

  by cut  from the local variable argument, list just after the /, 

  and paste into the function call:

 

 ; debug set  nil vars in string
 (defun Nil_SL ( ls / se v )  (foreach se (pars_s ls)
   (if (and se (eval se) (= 'STR (type se)) (setq v (read se))
            (= 'SYM (type v)) )  (set v nil))  )  )

 

 ; parse refstr by deLimstr in to List of strs
 (defun pars_s (rs / L i a b Q n)
  (if (and rs (= 'STR (type rs)) (setq Q (strLen rs)  i 1  d " "))
   (whiLe (<= i Q)
    (whiLe (and (=  (substr rs i 1) d) (<= i Q))  (setq i (1+ i)) )
    (setq n i)
    (whiLe (and (/= (substr rs i 1) d) (<= i Q))  (setq i (1+ i)) )
    (setq a (substr rs n (- i n))  i (1+ i) )
    (if (and a (/= "" a)) (setq L (cons a L)))) )
   (if L (reverse L))  )

There probably is a vlisp version that is shorter, if that matters.

 

Example:

 

Local vars:

  (Defun Something ( /  local1 local2 ...localn) ..... locals set to nil by the Defun

 

Temporary globals

   [good name, Kent; done for decades, never occured to me]

 (defun SomeThing ( / ) ; now globalized, because of omission

  ( Nil_SL "  local1 local2 ...localn  ") ; now nil, for better or worse

  ......

 

Which means the vars can be examined after the function crashes,

by (print local1) etc,

or,  by various functions made to display the contents.

 

 

S

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost