From: Rolf Wester
Subject: Some symbol questions
Date: 
Message-ID: <b4mpsb$bj3$1@nets3.rz.RWTH-Aachen.DE>
Hi,

it seems that I still didn't get all about symbols.
I tried the following on CMUCL (and CLISP):

(let ((x 'a))
   (set x 2))
x - unbound
a = 2
(set x 2) sets the value of the symbol a to 2.
Is a a special variable now?


(let ((x 'b))
   (setq x 3))
x - unbound
b - unbound
I guess (setq x 3) just sets the lexical variable to 3.
Is x a symbol here or just a placeholder?


(let ((x 'c))
   (setq c 4))
x - unbound
c = 4
(setq c 4) sets the value of the symbol c to 4.
Is c special now?


(let ((x 'd))
   (defparameter x 5))
x - unbound
d - unbound
CLISP here gives x = 5. What behaviour is correct?


(let ((x 'e))
   (defparameter e 6))
x - unbound
e = 6
(defparameter e 6) creates a new special variable e and sets it's value 
to 6.

I have some further questions on symbols:

When are symbols created (added to the package's symbol table)?
(describe 'nix) results in:

   NIX is an internal symbol in the COMMON-LISP-USER package.

although NIX has never been usee before. Now (intern "NIX")
gives:

   NIX
   :INTERNAL

whereas (intern "NIX2") results in:

   NIX2
   NIL

Does this mean that (describe 'nix) interns (creates ?) the symbol NIX?

I would be very appreciative for any comments that help me to understand
Lisp symbols better.

Thanks in advance.

Rolf Wester

From: Tim Bradshaw
Subject: Re: Some symbol questions
Date: 
Message-ID: <ey3vfyprmrg.fsf@cley.com>
* Rolf Wester wrote:

> When are symbols created (added to the package's symbol table)?

By the reader, or by code that does creates symbols explicitly (INTERN
&co).  

> (describe 'nix) results in:

In this case, by the reader, which creates from the input the
structure (describe (quote nix)).  The evaluator then gets this
structure and evaluates it, calling the function DESCRIBE on the
symbol NIX.  DESCRIBE just describes what it is given...

> whereas (intern "NIX2") results in:

>    NIX2
>    NIL

This means that the symbol has been freshly created by INTERN.  The
reader didn't create it since you didn't type anything that it cause
it to create it (hmm, this is kind of badly worded, sorry).

> Does this mean that (describe 'nix) interns (creates ?) the symbol
> NIX?

Not really, or rather, the thing that created the symbol was the thing
that read the source text - the reader - and not the function
DESCRIBE.

--tim
From: Rolf Wester
Subject: Re: Some symbol questions
Date: 
Message-ID: <b4nbrl$2ft$1@nets3.rz.RWTH-Aachen.DE>
Tim Bradshaw wrote:
> * Rolf Wester wrote:
> 
> 
>>When are symbols created (added to the package's symbol table)?
> 
> 
> By the reader, or by code that does creates symbols explicitly (INTERN
> &co).  
> 
> 
>>(describe 'nix) results in:
> 
> 
> In this case, by the reader, which creates from the input the
> structure (describe (quote nix)).  The evaluator then gets this
> structure and evaluates it, calling the function DESCRIBE on the
> symbol NIX.  DESCRIBE just describes what it is given...
> 
> 
>>whereas (intern "NIX2") results in:
> 
> 
>>   NIX2
>>   NIL
> 
> 
> This means that the symbol has been freshly created by INTERN.  The
> reader didn't create it since you didn't type anything that it cause
> it to create it (hmm, this is kind of badly worded, sorry).
> 
> 
>>Does this mean that (describe 'nix) interns (creates ?) the symbol
>>NIX?
> 
> 
> Not really, or rather, the thing that created the symbol was the thing
> that read the source text - the reader - and not the function
> DESCRIBE.
> 
> --tim
> 
Hi Tim,

thank you for your reply. I think (or hope at least) that I now 
understand what Lisp symbols are all about.

Rolf Wester
From: Peter Seibel
Subject: Re: Some symbol questions
Date: 
Message-ID: <m3llzl55e3.fsf@localhost.localdomain>
Rolf Wester <······@ilt.fhg.de> writes:

> Hi,
> 
> it seems that I still didn't get all about symbols.
> I tried the following on CMUCL (and CLISP):

Okay, these experiments aren't doing what you think they're doing, I
don't think. If I can be so bold as to guess at the source of your
confusion, I'd say you think there's a tighter binding between symbols
and variables than there is. Symbols are things that have names and
are (usually) interned in packages. They are in turn used to name
things in various contexts. To start with your last question first:
symbols are created when the reader reads sexps that contain text that
the reader interprets as the name of a symbol. A symbol is created and
interned in the current package (unless the symbol name specifically
contains a package via ':' or '::'.) You can also create symbols
explicitly with the INTERN function.

> (let ((x 'a))
>    (set x 2))

When this expression is read potentially two symbols are created in
the current package, assuming they don't already exist: X and A. X
happens to be used as the name of a lexical variable into which you
store the symbol named A. Since SET takes a symbol as its first
argument, (set x 2) is equivalent to (setq 'a 2).

> x - unbound
> a = 2
> (set x 2) sets the value of the symbol a to 2.
> Is a a special variable now?

X the variable is unbound because it was only used as a lexical
variable. A is still bound because it was a free variable in the body
of the let. (I believe using it that way was strictly speaking
undefined if A wasn't declared prior. But many implementations assume
you want a new global (therefore special) variable if you SET an
unbound variable.)

> (let ((x 'b))
>    (setq x 3))
> x - unbound
> b - unbound
> I guess (setq x 3) just sets the lexical variable to 3.

Yes. (setq x 3) is sugar for (set 'x 3), i.e. store 3 in the variable
named by the symbol X. You created a lexical variable named X that
intially had the value 'b and then changed it's value to 3. The use of
the symbol B as the initial value of X has nothing to do with any
variable that might happen to be named B. So if B wasn't bound before
you evaluated the LET, it's not going to be after.

> Is x a symbol here or just a placeholder?

X is a symbol that was used as the name of a lexical variable. Note,
however, that because it's a lexical variable the binding between that
symbol and the actual variable is only in scope in the text of the LET
expression. And when the code is compiled the compiler is likely to
lose the relation between the variable (which will become a register
or particular spot on the runtime stack) and the name X.

> (let ((x 'c))
>    (setq c 4))
> x - unbound
> c = 4
> (setq c 4) sets the value of the symbol c to 4.
> Is c special now?

This is pretty much the same as the first case. And again, using a
variable named C that hasn't been defined yet is strictly speaking
undefined. But your impl probably treated this as if you had done:

(defvar c)

(let ((x 'c))
  (setq c 4))

So C *is* special.

> (let ((x 'd))
>    (defparameter x 5))
> x - unbound
> d - unbound
> CLISP here gives x = 5. What behaviour is correct?

Hmmm. I'm not sure what the correct behavior is: you declared a
lexical variable named X and then tried, with it still in scope, to
create a non-lexical variable named X. I'm not surprised that
different impls give different behavior. And D is unbound for the same
reason as B was a couple experiments ago.

> (let ((x 'e))
>    (defparameter e 6))
> x - unbound
> e = 6
> (defparameter e 6) creates a new special variable e and sets it's
> value to 6.

Yup. And the fact that you happened to store the symbol E in the
lexical variable named X has nothing to do with anything.

> I have some further questions on symbols:
> 
> When are symbols created (added to the package's symbol table)?
> (describe 'nix) results in:
> 
>    NIX is an internal symbol in the COMMON-LISP-USER package.
>
> although NIX has never been usee before.

It's always going to say that for any symbol that hasn't been interned
elsewhere already because the very fact of reading the sexp "(describe
'nix)" is going to create and intern the symbol NIX which is then
passed to DESCRIBE which finds that it is interned.

> Now (intern "NIX") gives:
> 
>    NIX
>    :INTERNAL
> 
> whereas (intern "NIX2") results in:
> 
>    NIX2
>    NIL
> 
> Does this mean that (describe 'nix) interns (creates ?) the symbol NIX?

Yes. Both.

> I would be very appreciative for any comments that help me to
> understand Lisp symbols better.

Hope this helps some. Let me ask you a question (if I don't someone
else is bound to). What are you really trying to do? Do you have some
real code that isn't behaving the way you expect? It might be easier
for folks here to explain what's going on with actual code--these
experiments are mostly just muddying the waters.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

  The intellectual level needed   for  system design is  in  general
  grossly  underestimated. I am  convinced  more than ever that this
  type of work is very difficult and that every effort to do it with
  other than the best people is doomed to either failure or moderate
  success at enormous expense. --Edsger Dijkstra
From: Rolf Wester
Subject: Re: Some symbol questions
Date: 
Message-ID: <b4nbls$2a2$1@nets3.rz.RWTH-Aachen.DE>
Peter Seibel wrote:
> Rolf Wester <······@ilt.fhg.de> writes:
> 
> Hope this helps some. Let me ask you a question (if I don't someone
> else is bound to). What are you really trying to do? Do you have some
> real code that isn't behaving the way you expect? It might be easier
> for folks here to explain what's going on with actual code--these
> experiments are mostly just muddying the waters.
> 
> -Peter
> 
Hi Peter,

thanks a lot for your explanations. What I was trying to do was
the following:

I have a C++ program that reads a parameter file and makes some 
computations. I wanted to check some of the results using CMUCL
but didn't want to write to much code. The parameter file looks
like:

x = 1
y = 2

etc.

and in the C++ code the variables have the same name as the entries in 
the parameter file. I wanted to check the results of some arithmetic 
expression like say 3*x+5*y*y.

So I defined:

(defun read-data (file)
   (with-open-file (in file :direction :input)
	(loop for name  = (read in nil 'eof)
	      for c     = (read in nil 'eof)
	      for value = (read in nil 'eof)
		  until (or (eql name 'eof) (eql value 'eof)) do
		  (format t "~A  ~A~%" name value)
		  (set name value)
		  ;(defparameter name value)
		  )))

and then I could just type:
(+ (* 3 x) (* 5 y y))

and had the result without having to define x,y etc. myself. This is 
probably not a problem of general interest but while defining read-data 
the questions that I asked in my origional post arose.

Thanks again

Rolf Wester
From: Peter Seibel
Subject: Re: Some symbol questions
Date: 
Message-ID: <m3fzps5pup.fsf@localhost.localdomain>
Rolf Wester <······@ilt.fhg.de> writes:

> Peter Seibel wrote:
> > Rolf Wester <······@ilt.fhg.de> writes:
> > Hope this helps some. Let me ask you a question (if I don't someone
> 
> > else is bound to). What are you really trying to do? Do you have some
> > real code that isn't behaving the way you expect? It might be easier
> > for folks here to explain what's going on with actual code--these
> > experiments are mostly just muddying the waters.
> > -Peter
> 
> >
> 
> Hi Peter,
> 
> thanks a lot for your explanations. What I was trying to do was
> the following:
> 
> I have a C++ program that reads a parameter file and makes some
> computations. I wanted to check some of the results using CMUCL
> 
> but didn't want to write to much code. The parameter file looks
> like:
> 
> x = 1
> y = 2
> 
> etc.
> 
> and in the C++ code the variables have the same name as the entries in
> the parameter file. I wanted to check the results of some arithmetic
> expression like say 3*x+5*y*y.
> 
> 
> So I defined:
> 
> (defun read-data (file)
>    (with-open-file (in file :direction :input)
> 	(loop for name  = (read in nil 'eof)
> 	      for c     = (read in nil 'eof)
> 	      for value = (read in nil 'eof)
> 		  until (or (eql name 'eof) (eql value 'eof)) do
> 		  (format t "~A  ~A~%" name value)
> 		  (set name value)
> 		  ;(defparameter name value)
> 		  )))


Aaahh. So your problem is that you have all the parts (symbols and
numbers) ready to be interpreted as lisp code but you need to make the
jump from data to code. So build up a lisp expression and EVAL it.
Something like this will work, though it will create all global
variables which may or may not be what you want:

  (defun read-data (file)
    (with-open-file (in file :direction :input)
      (loop for name  = (read in nil 'eof)
            for c     = (read in nil 'eof)
            for value = (read in nil 'eof)
            until (or (eql name 'eof) (eql value 'eof)) do
            (format t "~A  ~A~%" name value)
            (eval `(defparameter ,name ,value)))))

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

  The intellectual level needed   for  system design is  in  general
  grossly  underestimated. I am  convinced  more than ever that this
  type of work is very difficult and that every effort to do it with
  other than the best people is doomed to either failure or moderate
  success at enormous expense. --Edsger Dijkstra
From: Peter Seibel
Subject: Re: Some symbol questions
Date: 
Message-ID: <m365qo5ljj.fsf@localhost.localdomain>
Rolf Wester <······@ilt.fhg.de> writes:

> I have a C++ program that reads a parameter file and makes some
> computations. I wanted to check some of the results using CMUCL
> 
> but didn't want to write to much code. The parameter file looks
> like:
> 
> x = 1
> y = 2
> 
> etc.
> 
> and in the C++ code the variables have the same name as the entries in
> the parameter file. I wanted to check the results of some arithmetic
> expression like say 3*x+5*y*y.

[...]

> and then I could just type:
> (+ (* 3 x) (* 5 y y))

Enhancing the code in my last response, you could also make your own
little REPL loop:

  (defun read-data-repl (file)
    (with-open-file (in file :direction :input)
      (let ((bindings
             (loop for name  = (read in nil 'eof)
                   for c     = (read in nil 'eof)
                   for value = (read in nil 'eof)
                   until (or (eql name 'eof) (eql value 'eof))
                   collecting (list name value))))
        (eval `(let (,@bindings)
                (declare (special ,@(mapcar #'car bindings)))
                (loop
                    (format t "> ")
                    (let ((exp (read)))
                      (case exp
                        (:vars
                         (loop for b in '(,@(mapcar #'car bindings))
                               do (format t "~A = ~A~&" b (eval b))))
                        (:quit (return))
                        (t (format t "~&~A~&" (eval exp)))))))))))


Given the data file:

  x = 10
  y = 20
  z = 30

You can have this interaction:

  CL-USER(1800): (read-data-repl "data.txt")
  > :vars
  X = 10
  Y = 20
  Z = 30
  > (setq x 20)
  20
  > x
  20
  > :vars
  X = 20
  Y = 20
  Z = 30
  > (+ x y)
  40
  > (+ x (* y z))
  620
  > :quit
  NIL
  CL-USER(1802): 

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

  The intellectual level needed   for  system design is  in  general
  grossly  underestimated. I am  convinced  more than ever that this
  type of work is very difficult and that every effort to do it with
  other than the best people is doomed to either failure or moderate
  success at enormous expense. --Edsger Dijkstra
From: Pierpaolo BERNARDI
Subject: Re: Some symbol questions
Date: 
Message-ID: <eFIba.45736$pG1.1087068@news1.tin.it>
"Peter Seibel" <·····@javamonkey.com> ha scritto nel messaggio ···················@localhost.localdomain...
> Rolf Wester <······@ilt.fhg.de> writes:

> > (let ((x 'b))
> >    (setq x 3))
> > x - unbound
> > b - unbound
> > I guess (setq x 3) just sets the lexical variable to 3.
> 
> Yes. (setq x 3) is sugar for (set 'x 3), i.e. store 3 in the variable
> named by the symbol X. 

Only true if X is a dynamic variable.  Not true in general.
Not true in this particular case.

> > (let ((x 'c))
> >    (setq c 4))
> > x - unbound
> > c = 4
> > (setq c 4) sets the value of the symbol c to 4.
> > Is c special now?
> 
> This is pretty much the same as the first case. And again, using a
> variable named C that hasn't been defined yet is strictly speaking
> undefined. But your impl probably treated this as if you had done:
> 
> (defvar c)
> 
> (let ((x 'c))
>   (setq c 4))
> 
> So C *is* special.

Only CMUCL with its default setting would treat it like this.
Other implementations, typically,  treat this code as if it were

(let ((x 'c))
  (locally (declare (special c))
    (setq c 4)))

> > (let ((x 'd))
> >    (defparameter x 5))
> > x - unbound
> > d - unbound
> > CLISP here gives x = 5. What behaviour is correct?
> 
> Hmmm. I'm not sure what the correct behavior is: you declared a
> lexical variable named X and then tried, with it still in scope, to
> create a non-lexical variable named X. I'm not surprised that
> different impls give different behavior. 

I'm surprised.  Obviously this is a bug in cmucl.

P.
From: Peter Seibel
Subject: Re: Some symbol questions
Date: 
Message-ID: <m3k7f445e6.fsf@localhost.localdomain>
"Pierpaolo BERNARDI" <··················@hotmail.com> writes:

> "Peter Seibel" <·····@javamonkey.com> ha scritto nel messaggio ···················@localhost.localdomain...
> > Rolf Wester <······@ilt.fhg.de> writes:
> 
> > > (let ((x 'b))
> > >    (setq x 3))
> > > x - unbound
> > > b - unbound
> > > I guess (setq x 3) just sets the lexical variable to 3.
> > 
> > Yes. (setq x 3) is sugar for (set 'x 3), i.e. store 3 in the variable
> > named by the symbol X. 
> 
> Only true if X is a dynamic variable. Not true in general. Not true
> in this particular case.

Right. Tim Bradshaw pointed out in email that I was a bit off target
in a couple thins I said. Here are some corrections:

  (set 'x 3) is equivalent to (setf (symbol-value 'x) 3)

And (setq x 3) is *not* sugar for (set 'x 3). If X is a dynamic
variable it is probably equivalent but it also works if X is lexical
in which case it just stores the value in the lexical variable that
happens to be named by the symbol X. And if X is a bound with
symbol-macrolet then it's equivalent to (setf x 3) with all the
madness that can then ensue. (Which I won't try to explain so as to
avoid getting into further trouble. ;-))

> > Hmmm. I'm not sure what the correct behavior is: you declared a
> > lexical variable named X and then tried, with it still in scope,
> > to create a non-lexical variable named X. I'm not surprised that
> > different impls give different behavior.
> 
> I'm surprised.  Obviously this is a bug in cmucl.

I only meant I'm not suprised in that this seems to be an edge case
and that's where the bugs tend to lurk.

-Peter

-- 
Peter Seibel                                      ·····@javamonkey.com

  The intellectual level needed   for  system design is  in  general
  grossly  underestimated. I am  convinced  more than ever that this
  type of work is very difficult and that every effort to do it with
  other than the best people is doomed to either failure or moderate
  success at enormous expense. --Edsger Dijkstra
From: Joe Marshall
Subject: Re: Some symbol questions
Date: 
Message-ID: <bs0gslla.fsf@ccs.neu.edu>
Rolf Wester <······@ilt.fhg.de> writes:

> Hi,
> 
> it seems that I still didn't get all about symbols.
> I tried the following on CMUCL (and CLISP):
> 
> (let ((x 'a))
>    (set x 2))
> x - unbound
> a = 2
> (set x 2) sets the value of the symbol a to 2.
> Is a a special variable now?

No.  A is a symbol with the integer 2 in it's value cell.

> (let ((x 'b))
>    (setq x 3))
> x - unbound
> b - unbound
> I guess (setq x 3) just sets the lexical variable to 3.
> Is x a symbol here or just a placeholder?

X is an identifier that names the lexical variable.

> (let ((x 'c))
>    (setq c 4))
> x - unbound
> c = 4
> (setq c 4) sets the value of the symbol c to 4.
> Is c special now?

It might be.  The behavior is implementation dependent.  CMUCL has a
switch, EXT:*TOP-LEVEL-AUTO-DECLARE*, that controls whether free
assignments cause a variable to become special.

> (let ((x 'd))
>    (defparameter x 5))
> x - unbound
> d - unbound
> CLISP here gives x = 5.  What behaviour is correct?

X should be equal to 5.

> (let ((x 'e))
>    (defparameter e 6))
> x - unbound
> e = 6
> (defparameter e 6) creates a new special variable e and sets it's
> value to 6.
> 
> 
> I have some further questions on symbols:
> 
> When are symbols created (added to the package's symbol table)?

When they are INTERNED.  This can happen by an explicit call to
INTERN, or implicitly during READ. 

> (describe 'nix) results in:
> 
>    NIX is an internal symbol in the COMMON-LISP-USER package.
> 
> although NIX has never been used before. 

Ah, but it was!  When the reader read the form, it interned the symbol
NIX in the current package.  When the call to describe occurred, the
symbol had already been created.

> Now (intern "NIX")
> gives:
> 
>    NIX
>    :INTERNAL
> 
> whereas (intern "NIX2") results in:
> 
>    NIX2
>    NIL

In this case, the reader read a string.  The symbol doesn't exist
until you call intern.

> Does this mean that (describe 'nix) interns (creates ?) the symbol NIX?

It isn't the describe that interns the symbol, it is the reading of
the quoted form.
From: Rolf Wester
Subject: Re: Some symbol questions
Date: 
Message-ID: <b4pkjr$e84$1@nets3.rz.RWTH-Aachen.DE>
Thanks to all for your replies that helped me a lot to better
understand how Lisp symbols work.

Rolf Wester