Curious about using quote in set

Started by DrDave, August 25, 2008, 12:08:36 PM

Previous topic - Next topic

DrDave

Just curious as to why a quote is needed when using set.
(set 'something "A")or
(setq another x)
Is it a convention from other LISPs? Really, why can't the quote just be dropped? If it is somehow needed "behind the scenes", then why not make it a part of the definition of set itself?



To a nOOb like me, I just see the function set followed by a minimum of one argument, the argument being a symbol.



As far as I can figure out, set works *only* when followed immediately by a space and a quote. So as the code writer, set already tells me that I am going to assign something to an object, making the quote totally superfluous.
...it is better to first strive for clarity and correctness and to make programs efficient only if really needed.

\"Getting Started with Erlang\"  version 5.6.2

Jeff

#1
If you don't use a quote, set attempts to evaluate the symbol (meaning you can set one symbol to point to another and set the second symbol using the first symbol).  To skip the quote, use setq (short for set-quote).
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code

DrDave

#2
Maybe I wasn't clear enough in the first post. I undersand that setq is just another way of supplying the quote, so that is not really eliminating the quote.



I also understand that set will attempt to evaluate the symbol if the quote is not supplied, and throws an error if the quote is not there. In fact, it is already "smart" enough to "know" that a symbol is not being supplied if you omit the quote or if you try to use a list as the first argument. If it is already this "smart", why can't it go one small step further and accept an unquoted symbol as the first argument, and "know" that it must not evaluate it?



My point is, other functions "know what to do" without any special "instruction" or marker being fed to them. For example, the function string "knows" to evaluate the argument(s) and convert them to strings, and then concatenate. Does the code writer need to put some special mark on the expression to signal to string that it needs to convert the result of the evaluation into a string? No, it doesn't. That "knowlwdge" (functionality) is built into the function string. So, that is why I ask, what is the point of the function set requiring a quote? Why wasn't it designed to "know" that it *must not* evaluate the first symbol, just like string "knows" to convert to strings? Or, as I already asked, is this just a holdover from earliy LISP?



Another similar example is the function define. It is fed a list comprising two other lits, the function head and the function body. I don't see anything marking the first member of the function head, which is the function name, so that it is not evaluated. After I define the function, I can examine its contents the same way as for the object defined with set.
(set 'TESTA 10)
;check the contents of the object  TESTA defined by set
TESTA => 10

(define (TESTB) (+ 3 7))
;check the contents of the functiion TESTB
TESTB => (lambda () (+ 3 7))

So we can see here that define is "smart" and "knows" not to evaluate the first member of the function head, so why wasn't set designed with the same kind of "smarts"?



+++++++++++

Addendum

I subsequently thought about let. I don't see quote used with let, but it is setting a local variable. So it seems to me inconsistent to require set to use a quote but let does not.
(set 'x 10)              ;=> 10
(define (test)
        (let (x 3))
        (println x))  
(println x)              ;=> 10
(test)                   ;=>  3
(println x)              ;=> 10
...it is better to first strive for clarity and correctness and to make programs efficient only if really needed.

\"Getting Started with Erlang\"  version 5.6.2

Jeff

#3
No, it cannot know what to do.  As I said, you can point a symbol to a symbol, so that using set evaluates the first symbol and sets the second:


(set 'a 'b)
(set a 10)
;; b => 10
;; a => 'b


However, what if 'a already contains something else?  What if it was previously used to store an expression, like:


(set 'a '(println "Hello world"))

...and you want to set it now to 'b?  If you do:


(set a 'b)

In order to decide to set the symbol 'a, it has to evaluate '(println "Hello world"), which is an unintended side effect.



Additionally, if 'a points to 'b, then what should happen in this case:


(set a 10)

Should a or b be set to 10?  With two different set functions, you have:


(set a 10) ; => sets b to 10
(setq a 10) ; => sets a to 10
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code

DrDave

#4
Quote from: "Jeff"No, it cannot know what to do.

Then why does LET know what to do without using quote?



As for this
Quote(set 'a 'b)

(set a 10)

;; b => 10

;; a => 'b

being a nOOb, I was not aware that set could ever be used without the quote as you showed above.



But even so, that does not explain the inconsistency between LET and SET.
...it is better to first strive for clarity and correctness and to make programs efficient only if really needed.

\"Getting Started with Erlang\"  version 5.6.2

Jeff

#5
Let does not care what to do.  It automatically quotes the symbol and evaluates the expression it points to.  (let ((foo 10))) is the equivalent of:


(local (foo)
  (setq foo 10))


Re the last example -


(set 'a 'b) ; a now points to b
(set a 10) ; sets b to 10
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code

DrDave

#6
Ok, so now that you explained how LET is really using SETQ behind the scenes, it all makes sense.



Thanks for the explanations.
...it is better to first strive for clarity and correctness and to make programs efficient only if really needed.

\"Getting Started with Erlang\"  version 5.6.2

cormullion

#7
(I hope this discussion is 'academic'. If the set function gets changed, I'm going over to Perl! :)



I can see that set could be considered an awkward customer. After all, you're probably using it to create a new symbol, but when you give it a symbol it goes off and evaluates it to a string or list or whatever (probably) then turns round and says "You're supposed to give me a symbol, are you stupid or something?". I know some people like that.



Once you know that set evaluates its first argument you can handle it easily: just give it a symbol that doesn't get evaluated, or something that evaluates to a symbol, and you're OK. And quoting to prevent evaluation is definitely the second thing to learn about newLISP. Perhaps



(set (sym "x") 42)



would be a good way to encounter it?



I suspect that setq was introduced to newLISP to make other-Lisp programmers feel at home. Is set derived from its other-Lisp antecedents too?

HPW

#8
QuoteI suspect that setq was introduced to newLISP to make other-Lisp programmers feel at home.


Yes, it was introduced a long time ago to let Autolisp-programmers feel at home. (Others lisp also of cource)
Hans-Peter

hsmyers

#9
HPW,



If you are going to blame setq on someone, that would be David Betz author of the Lisp implementation that John Walker used to provide an embedded language. That said, I believe that setq is older than that--- I think(could certainly be wrong) that Soft Warehouse's muLisp had a setq which if so would predate AutoLisp.



--hsm

p.s. I'm uncertain if David's code had setq or whether John added it as part of the embedding...
\"Censeo Toto nos in Kansa esse decisse.\"—D. Gale \"[size=117]ℑ♥λ[/size]\"—Toto

DrDave

#10
Quote from: "cormullion"
Once you know that set evaluates its first argument you can handle it easily: just give it a symbol that doesn't get evaluated, or something that evaluates to a symbol, and you're OK. And quoting to prevent evaluation is definitely the second thing to learn about newLISP. Perhaps



(set (sym "x") 42)



would be a good way to encounter it?


That is a really helpful explanation. Now it is clear that set expects a symbol, and you can explicity create a symbol. It looks much more "LISPy" that way.
...it is better to first strive for clarity and correctness and to make programs efficient only if really needed.

\"Getting Started with Erlang\"  version 5.6.2

cormullion

#11
If (define x 42) and (set 'x 24) are exactly equivalent, I'll think I'll try switching over to the former when creating new symbols. I like the clear way it says "I'm creating a new thing".



Then I have to remember to switch over to set when the symbols exists and I want to adjust its value.



Also, you can't do:



(define x 42 y  -1)



like you can with set.



(Apparently, the word SET has the most definitions of any word in the English language. SET has 464 definitions in the Oxford English Dictionary.)

Jeff

#12
That will make your code confusing to others who expect define to define a new function.  It's generally best for a programmer not to make up conventions when writing code.  You never when *you* will be person who has to update it.
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code

Lutz

#13
In Scheme using 'define' to declare/assign new variables is the rule, and the reason that this form of 'define' was introduced in newLISP.



Although not mandatory in newLISP, many users coming from Scheme expect it to work this way.

Jeff

#14
Oh, yeah :)
Jeff

=====

Old programmers don\'t die. They just parse on...



http://artfulcode.net\">Artful code