Author Topic: What is the best way to localise or set variable to NIL  (Read 7116 times)

0 Members and 1 Guest are viewing this topic.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: What is the best way to localise or set variable to NIL
« Reply #15 on: August 13, 2011, 05:05:13 AM »
BTW, I've seen in some other thread that using the foreach "Doesn't require localization ... as the value gets turned to nil when the loop finishes". See my PrintABC function in the previous post. IMO it still requires localization since it could cause clashes with surrounding (also calling) functions. Say the var variable had a global value, at the end this value is still retained. But if I didn't localize it the value would be nil.

Also note, lisp has what's called "closures". A simple explanation is that you would get the same effect if the testlocal-sub was defined outside of the testlocal. I.e. the localizations apply to "when the function is called" not "where it is made".
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: What is the best way to localise or set variable to NIL
« Reply #16 on: August 13, 2011, 05:11:27 AM »
And to answer the last portion of your post: You're close to correct. (setq a nil) doesn't clear the variable from RAM ... immediately. Lisp takes what's known as garbage collection: whenever there's some idle time it runs a (gc) which checks through all the atoms-family list and removes all atoms = nil from RAM.

With localized it gets removed from ram when the defun completes.

There's no functional difference in this case, since if you test a variable which has not been setq'ed (i.e. it's not in RAM), its value would be nil in any case.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

Lee Mac

  • Seagull
  • Posts: 12726
  • London, England
Re: What is the best way to localise or set variable to NIL
« Reply #17 on: August 13, 2011, 08:20:14 AM »
Nice explanation Irneb, this is another good read.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: What is the best way to localise or set variable to NIL
« Reply #18 on: August 13, 2011, 10:05:48 AM »
Thanks. I was thinking of explaining the "true" ins-and-outs about how Lisp handles localized variables ... but no-one actually needs to know that all variables are in fact lists (used as stacks) and each time a variable is localized again it gets another cons on top of that list, then a cdr after the defun completes.

What it does tell me however is there should be a way to modify the golbal version of a variable even if it has a localized symbol name. Though I don't see any way of doing so in AutoLisp ... unless you pass it as a quoted argument and then use set instead of setq on it. But that kind of defeats the "purpose" ... I'd have like to be able to do something like this:
Code: [Select]
(setq var "Global")
(defun test (/ var)
  (setq var "Local")
  (print var)
  (print (cdr var))
  (setq (cdr var) "Global changed in defun")
)
(print var)
(test)
(print var)
As you can already see the cdr would cause an error, since the internal workings of the variable's allocation isn't available to the lisp program. But I'd have liked to see an output from that like the following:
Code: [Select]
"Global"
"Local"
"Global changed in defun"
"Global changed in defun"
That way you could have the best of both worlds ... allow assignment to globals even if a local variable has the same name.

Edit: Anyhow, to get around this scenario - it shows one of the reasons for using the asterisk prefix/suffix for global variable names. Makes for the possibility of a clash with a local var's name impossible.
« Last Edit: August 13, 2011, 10:19:38 AM by irneb »
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

jaydee

  • Guest
Re: What is the best way to localise or set variable to NIL
« Reply #19 on: August 13, 2011, 01:50:59 PM »
Thankyou irneb
I alway been very confused about localising vars especially it involve multiple subfunctions that require to pass the vars from one subfunction to another or main function.

Now your explanation is clear as mud

Very appriciated for you to take time to write and formated it in a very easy to understand.

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: What is the best way to localise or set variable to NIL
« Reply #20 on: August 13, 2011, 02:00:38 PM »
You're welcome  :kewl: . Lisp is a bit "strange" when it comes to variables ... at least in comparison to most other programming languages. It's not easy to understand how it works the first time round. We all get better as our experience grows, I guess. Happy lisping!
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

Lee Mac

  • Seagull
  • Posts: 12726
  • London, England
Re: What is the best way to localise or set variable to NIL
« Reply #21 on: August 13, 2011, 02:55:35 PM »
Say the var variable had a global value, at the end this value is still retained. But if I didn't localize it the value would be nil.

Not quite - the symbol argument passed to foreach (in this case 'var')  is local to that expression:

Code: [Select]
(setq var "Global")

(defun test ( )
  (foreach var '(1 2 3 4 5) (print var))
)
(print var)
(test)
(print var)
Code: [Select]
"Global"
1
2
3
4
5
"Global"

Also:

Code: [Select]
(setq var "Global")

(defun test ( / var )
  (setq var "Local")
  (foreach var '(1 2 3 4 5) (print var))
  (print var)
)
(print var)
(test)
(print var)
Code: [Select]
"Global"
1
2
3
4
5
"Local"
"Global"

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: What is the best way to localise or set variable to NIL
« Reply #22 on: August 13, 2011, 03:52:49 PM »
Thanks! I didn't know that. So the foreach automatically localizes the incremental variable. Awesome!

So it works much the same as the let construct in Common Lisp?
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

Lee Mac

  • Seagull
  • Posts: 12726
  • London, England
Re: What is the best way to localise or set variable to NIL
« Reply #23 on: August 13, 2011, 04:43:24 PM »
Yes, the variable is local to the function, just as the bindings are local to the 'let' body - the same is true of vlax-for.

There are a few of these floating around but here's a possible 'let' function for AutoLISP:

Code: [Select]
(defun let ( bindings body )
  (apply (list 'lambda (mapcar 'car bindings) body) (mapcar 'eval (mapcar 'cadr bindings)))
)