Author Topic: Declaring variables in nested functions  (Read 12237 times)

0 Members and 1 Guest are viewing this topic.

MP

  • Seagull
  • Posts: 17342
Re: Declaring variables in nested functions
« Reply #30 on: February 06, 2009, 09:22:42 AM »
<I shouldn't be posting yet as I haven't had my first coffee but this thread has been bugging me, so forgive me if it lacks some coherency>

About quote, setq and set ...

Quote (') simply instructs the lisp interpreter "return an expression without evaluating it" (from the help), so if a statement is quoted, e.g. '(+ 2 2) or (quote (+ 2 2)) ... it is not evaluated, thus does not return 4 but the term '(+ 2 2). If a symbol is quoted it similarly is not evaluated but returned as a symbol, e.g. assuming the symbol b hosts hosts the value 42, 'b,  or (quote b) will not return 42 but the symbol b.

Now has does this manifest itself with set / setq? It's right in the help file: "The set function is similar to setq except that set evaluates both of its arguments whereas setq only evaluates its second argument."

Say what? First setq.

(setq a b) ... assuming b is bound to the value 42 from before a is now bound to 42. Remember "setq only evaluates its second argument". So the symbol a is not evaluated, but b is evaluated, thus the symbol a is bound to the value 42.

Wait a second, isn't (setq a b) the same as (set 'a b)? Yes it is, setq is merely a convenience function.

Now set.

But what if we don't quote the first term when using set? If you don't quote the first term it is evaluated, which can cause problems if you don't understand what the ramifications are, and haven't initialized a accordingly. As exists currently, a is bound to 42, so if we tried to execute this statement (set a 7) we would get an error, because we would be trying to bind the value 7 to ... the value of 42.

What?

Again, given that a is currently bound to 42, (set a 7) once a is evaluated (value 42) would be analogous to (setq 42 7) which is of course, impossible.

So how do you use set?

Well if you want to set the symbol a to something you would use either (setq a something) or (set 'a something).

However, if you want to take advantage of what is sometimes referred to as "indirect addressing", that is, use one symbol to bind another symbol to some value then the following may illuminate. In order for this work the first symbol must point to another symbol, for example (setq a 'b) or (set 'a 'b). Now we can bind the symbol b to some value using the symbol a: (set a 7). The symbol b is now bound to the value 7.

So ... all this seems academic, where would you use this in the real world? To be honest, it doesn't come up that frequently, is frequently misused, but here are a couple uses.

;; bind the symbols x, y and z to the values 1, 2 and 3 respectively.
(mapcar 'set '(x y z) '(1 2 3))

;; null out the values for multiple symbols
(foreach x '(a b c) (set x nil))

I'd post more but I'm late for work as it is and gotta run.

Edit: After typing out all this sht CAB beat me to it; grrrrr, later.

ciao
\|// Set goal. Experiment tirelessly until
|Oo| practice has become expertise.  Loop.
|- | LinkedIn | Dropbox

MP

  • Seagull
  • Posts: 17342
Re: Declaring variables in nested functions
« Reply #31 on: February 06, 2009, 09:26:24 AM »
Here is one more example ...

Be careful using that technique as you are creating / using variables which have global scope. :)
\|// Set goal. Experiment tirelessly until
|Oo| practice has become expertise.  Loop.
|- | LinkedIn | Dropbox

CAB

  • Global Moderator
  • Seagull
  • Posts: 10339
Re: Declaring variables in nested functions
« Reply #32 on: February 06, 2009, 09:27:39 AM »
Even without coffee you quite clear headed.   :roll:
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

CAB

  • Global Moderator
  • Seagull
  • Posts: 10339
Re: Declaring variables in nested functions
« Reply #33 on: February 06, 2009, 09:34:02 AM »
Here is one more example ...

Be careful using that technique as you are creating / using variables which have global scope. :)

You would need this when your were through with the variables.
Code: [Select]
(mapcar '(lambda (x)(set (read x) nil)) varlst)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

MP

  • Seagull
  • Posts: 17342
Re: Declaring variables in nested functions
« Reply #34 on: February 06, 2009, 09:39:25 AM »
You would need this when your were through with the variables ...

And if another program happened to be using those (global) variables? While creating vars on the fly is interesting academically, the same can usually be replicated using judicious list management using local scope, which imo is safer and more readily understood, especially if you write code for others. Just sayin'. :)
\|// Set goal. Experiment tirelessly until
|Oo| practice has become expertise.  Loop.
|- | LinkedIn | Dropbox

CAB

  • Global Moderator
  • Seagull
  • Posts: 10339
Re: Declaring variables in nested functions
« Reply #35 on: February 06, 2009, 09:59:41 AM »
And well said.  8-)
I've reached the age where the happy hour is a nap. (°¿°)
Windows 10 core i7 4790k 4Ghz 32GB GTX 970
Please support this web site.

gile

  • Water Moccasin
  • Posts: 2219
  • Marseille, France
Re: Declaring variables in nested functions
« Reply #36 on: February 06, 2009, 10:04:34 AM »
Very nice explaination MP, really more readable than what I tried to write in my poor English :|
Speaking English as a French Frog

MP

  • Seagull
  • Posts: 17342
Re: Declaring variables in nested functions
« Reply #37 on: February 06, 2009, 10:40:54 AM »
Thanks guys. Wish Tony would have piped in, he could have said it better in half the verbiage. If he doesn't beat me to it I'll rewrite what I penned below, but I've too many guns pointed at my head write now.
\|// Set goal. Experiment tirelessly until
|Oo| practice has become expertise.  Loop.
|- | LinkedIn | Dropbox

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Declaring variables in nested functions
« Reply #38 on: February 06, 2009, 04:32:15 PM »
<I shouldn't be posting yet as I haven't had my first coffee but this thread has been bugging me, so forgive me if it lacks some coherency>

About quote, setq and set ...

< .... >
ciao

Morning Michael ... It's been bugging me too, and I was planning on commennting today { Saturday morning ( but I HAVE coffee)}
looks like you've covered the relevant points and better than I'd be able to.
:)
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

--> Donate to theSwamp<--

Daniel J. Ellis

  • Swamp Rat
  • Posts: 798
Re: Declaring variables in nested functions
« Reply #39 on: February 09, 2009, 09:06:29 AM »
Sorry I've not responded earlier - been away all weekend.

Only last (hopefully) attempt at understanding:

  • EVAL and QUOTE area actually as I described earlier
  • SETQ recognises its first term as a "target," so does nothing with it, but evaluates the second term and assigns that to the "target," hence (SETQ a (+ 1 2)) it ignores anything that might be in a, assigning the result of (+ 1 2) to it instead
  • SET, the tricky one!  SET tries to figure out what, if anything, it's target means, and uses that in its computations, hence (SET a (+ 1 2)) would check to see whether or not anything had been assigned to a.  If nothing has been assigned to a, it calculates (+ 1 2) and assigns that to a.  If a already has a value, it spills out an error.
  • Basically, SET is used for doing stuff to variable names, whereas SETQ is for doing stuff to the value of variables
dJE
===
dJE

gile

  • Water Moccasin
  • Posts: 2219
  • Marseille, France
Re: Declaring variables in nested functions
« Reply #40 on: February 09, 2009, 09:34:29 AM »
Quote
hence (SET a (+ 1 2)) would check to see whether or not anything had been assigned to a.  If nothing has been assigned to a, it calculates (+ 1 2) and assigns that to a.  If a already has a value, it spills out an error.

No, set evaluates the first argument, then :
If the evaluation result is not valid symbol, an error occur.
Quote
Commande: (setq a nil b 12)
12
Commande: (set a (+ 1 2))
; erreur: type d'argument incorrect: symbolp nil
Commande: (set b (+ 1 2))
; erreur: type d'argument incorrect: symbolp 12
If the evaluation result is valid symbol, the evaulation of the second argument is bounded to the symbol.
Quote
Commande: (setq c 'b)
B
Commande: (set c (+ 1 2))
3
Commande: !c
B
Commande: !b
3
Speaking English as a French Frog

Daniel J. Ellis

  • Swamp Rat
  • Posts: 798
Re: Declaring variables in nested functions
« Reply #41 on: February 26, 2009, 09:01:29 AM »
As an addendum to this, I've just found myself in one final relevant (to my original query) situation:

Code: [Select]
(defun c:rtest (/)
(GETSET "0-fdp-h-blocks")
)

(DEFUN getset ( layer / )
(SETQ
ss (SSGET "x" (LIST (CONS 8 layer)))
ssl (SSLENGTH ss)
cnt 0
) ;SETQ
)

My question is, does "layer" need declaring as a variable, and it so, where.

I don't think it *does* need declaring, and will simply pop out of existence after "getset" finishes running, but I wanted to check...

dJE
===
dJE

John Kaul (Se7en)

  • Administrator
  • Needs a day job
  • Posts: 9227
Re: Declaring variables in nested functions
« Reply #42 on: February 26, 2009, 09:22:26 AM »
`layer' is an ARGUMENT not a variable in that snip-it.

I'm going to try and find an article i think will help you; brb.
“Common sense is not so common.” ~Voltaire

--> Donate to TheSwamp.org <--

John Kaul (Se7en)

  • Administrator
  • Needs a day job
  • Posts: 9227
Re: Declaring variables in nested functions
« Reply #43 on: February 26, 2009, 09:27:42 AM »
Read and study that pdf; it will help you. There is quite a bit of information between the lines so to speak.
http://www.theswamp.org/index.php?topic=5203.0
“Common sense is not so common.” ~Voltaire

--> Donate to TheSwamp.org <--

Daniel J. Ellis

  • Swamp Rat
  • Posts: 798
Re: Declaring variables in nested functions
« Reply #44 on: February 27, 2009, 02:56:05 AM »
`layer' is an ARGUMENT not a variable in that snip-it.

That's what I thought, I wanted to check though, thanks :)

Read and study that pdf; it will help you. There is quite a bit of information between the lines so to speak.
http://www.theswamp.org/index.php?topic=5203.0

I have actually read this before, in fact implimenting some of it has lead, in part, to some of the questions that caused me to start this thread.

(I have a generic "extract assoc value" function, for example)

dJE
===
dJE