I'm just starting to learn Common Lisp using Seibel's book, and I'm a
bit confused as to the use of symbols for operators and other objects.
Am I correct in thinking that there a two namespaces in CL, one for
operators and one for other objects?
For example, when I (setf a 13) then the symbol a evaluates to 13; and
when I then (defun a () (format t "Hi!")) then the list (a) results in
"Hi", while the atom a still gives 13. In fact, I can (setf setf 17) to
get the non-operator symbol setf to evaluate to 17, without affecting
the operator of the same name.
Somebody explained that such symbols have "dual bindings", but it
seems to me that a crucial property of a symbol is that it is unique
and has only one binding at any one time. Or am I thinking too much
Smalltalk here?
Can anyone enlighten a confused noob?
Henk Koster wrote:
> I'm just starting to learn Common Lisp using Seibel's book, and I'm a
> bit confused as to the use of symbols for operators and other objects.
> Am I correct in thinking that there a two namespaces in CL, one for
> operators and one for other objects?
>
> For example, when I (setf a 13) then the symbol a evaluates to 13; and
> when I then (defun a () (format t "Hi!")) then the list (a) results in
> "Hi", while the atom a still gives 13. In fact, I can (setf setf 17) to
> get the non-operator symbol setf to evaluate to 17, without affecting
> the operator of the same name.
>
> Somebody explained that such symbols have "dual bindings", but it
> seems to me that a crucial property of a symbol is that it is unique
> and has only one binding at any one time. Or am I thinking too much
> Smalltalk here?
>
> Can anyone enlighten a confused noob?
This things happened to me some time ago.
Yes, there are 2 different namespaces, one for functions, one for data.
And you must take care too about special operatos, like setf.
You can store a function in a normal variable, using the #' simbol
macro. For example:
CL-USER> (setf a #'a)
CL-USER> a
#<FUNCTION A>
and you can, now, call the function stored in the variable a:
CL-USER> (funcall a)
hello
NIL
Elsewhere, be aware that a and #'a are not the same. a stores a
function (and can store anything else, like a number), but #'a always
refer to a function name, in this case the function named a.
If you are confused, think of #'a as a way to briefly write the
operation (symbol-function 'a), wich returns the function asociated
with the name a.
"Javier" <·······@gmail.com> writes:
> Elsewhere, be aware that a and #'a are not the same. a stores a
> function (and can store anything else, like a number), but #'a always
> refer to a function name, in this case the function named a.
> If you are confused, think of #'a as a way to briefly write the
> operation (symbol-function 'a), wich returns the function asociated
> with the name a.
Minor nit: this is not strictly true; #'a and (symbol-function 'a) are
not at all equivalent; #'a is nothing more than a reader macro which
expands to its equivalent form (function a) which is not the same as
(symbol-function 'a) in at least two respects:
1. symbol-function always accesses the global function binding for its
argument (assuming one exists) whereas #'a might not - if, for example
there is a local function binding:
...
(flet ((a ( ...)
...))
...
#'a)
the reference to #'a will return the flet, and not what is contained in
the global function slot of 'a.
2. As its name implies, symbol-function accepts only symbols as
arguments, whereas function can accept lists as arguments. CL defines
the form (setf <name>) as the standard non-symbol function name, so
#'(setf foo) is a valid operation (although like its symbolic
counterpart the behavior depends on whether that function is actually
defined). Additionally, several CL implementations define further
extensions to function-names in list form; for example, Allegro CL has
a concept of "function spec" which is user-definable; there are
several pre-defined function-specs like one for flet, so you could
take a compiled definition like
(defun foo (...)
(flet ((bar (...)
...))
...))
and refer to the function #'(flet foo bar), whereas if symbol-function
sees anything but a symbol as argument it will result in an error.
--
Duane Rettig ·····@franz.com Franz Inc. http://www.franz.com/
555 12th St., Suite 1450 http://www.555citycenter.com/
Oakland, Ca. 94607 Phone: (510) 452-2000; Fax: (510) 452-0182
Henk Koster wrote:
> I'm just starting to learn Common Lisp using Seibel's book, and I'm a
> bit confused as to the use of symbols for operators and other objects.
> Am I correct in thinking that there a two namespaces in CL, one for
> operators and one for other objects?
Yes.
> For example, when I (setf a 13) then the symbol a evaluates to 13; and
> when I then (defun a () (format t "Hi!")) then the list (a) results in
> "Hi", while the atom a still gives 13. In fact, I can (setf setf 17) to
> get the non-operator symbol setf to evaluate to 17, without affecting
> the operator of the same name.
>
> Somebody explained that such symbols have "dual bindings", but it
> seems to me that a crucial property of a symbol is that it is unique
> and has only one binding at any one time. Or am I thinking too much
> Smalltalk here?
Yes, you are.
> Can anyone enlighten a confused noob?
A symbol has indeed at least two bindings, a function and a value
binding. In fact, there are even more: for blocks, catch tags, class
names, slot names, and so on. You can create your own bindings with hash
tables, association lists, or other mapping data structures.
Since the two bindings that you are talking about are the most obvious
ones, Common Lisp is sometimes characterized as being a Lisp-2. It is
possible to design a Lisp dialect such that a name has always only one
binding - that would be a Lisp-1. In fact, Scheme is a Lisp-1.
If you google for Lisp-1 and Lisp-2, you will find lots of discussions
and flame wars about this topic.
Pascal
--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
On Fri, 25 Aug 2006 13:10:45 +0200, Pascal Costanza wrote:
> Henk Koster wrote:
>> I'm just starting to learn Common Lisp using Seibel's book, and I'm a
>> bit confused as to the use of symbols for operators and other objects.
>> Am I correct in thinking that there a two namespaces in CL, one for
>> operators and one for other objects?
>
> Yes.
>
>> For example, when I (setf a 13) then the symbol a evaluates to 13; and
>> when I then (defun a () (format t "Hi!")) then the list (a) results in
>> "Hi", while the atom a still gives 13. In fact, I can (setf setf 17) to
>> get the non-operator symbol setf to evaluate to 17, without affecting
>> the operator of the same name.
>>
>> Somebody explained that such symbols have "dual bindings", but it
>> seems to me that a crucial property of a symbol is that it is unique
>> and has only one binding at any one time. Or am I thinking too much
>> Smalltalk here?
>
> Yes, you are.
>
>> Can anyone enlighten a confused noob?
>
> A symbol has indeed at least two bindings, a function and a value
> binding. In fact, there are even more: for blocks, catch tags, class
> names, slot names, and so on. You can create your own bindings with hash
> tables, association lists, or other mapping data structures.
Aha, so the actual binding used then depends on context... an operator
when the first element of a non-quoted list (and excepting lambda).
> Since the two bindings that you are talking about are the most obvious
> ones, Common Lisp is sometimes characterized as being a Lisp-2. It is
> possible to design a Lisp dialect such that a name has always only one
> binding - that would be a Lisp-1. In fact, Scheme is a Lisp-1.
>
> If you google for Lisp-1 and Lisp-2, you will find lots of discussions
> and flame wars about this topic.
Wouldn't want to start a flame war (not yet at any rate).
>
>
> Pascal
Thanks.
Henk Koster <············@xs4all.nl> writes:
> I'm just starting to learn Common Lisp using Seibel's book, and I'm a
> bit confused as to the use of symbols for operators and other objects.
> Am I correct in thinking that there a two namespaces in CL, one for
> operators and one for other objects?
>
> For example, when I (setf a 13) then the symbol a evaluates to 13; and
> when I then (defun a () (format t "Hi!")) then the list (a) results in
> "Hi", while the atom a still gives 13. In fact, I can (setf setf 17) to
> get the non-operator symbol setf to evaluate to 17, without affecting
> the operator of the same name.
>
> Somebody explained that such symbols have "dual bindings", but it
> seems to me that a crucial property of a symbol is that it is unique
> and has only one binding at any one time. Or am I thinking too much
> Smalltalk here?
>
> Can anyone enlighten a confused noob?
Hoping the other answers will have enlightened you, here is some
more confusion:
* (cat "/tmp/haha.lisp")
(defmacro show (&rest exprs)
`(progn
,@(mapcar (lambda (expr) `(format t "~&~60A = ~S~%" ',expr ,expr)) exprs)))
#+sbcl
(defun global-value (symbol)
"Implementation-dependant way to recover the global value
of a special variable"
(let ((result nil)
(wait (sb-thread:make-waitqueue))
(wait-lock (sb-thread:make-mutex :name "wait")))
(sb-thread:make-thread
(lambda ()
(sb-thread:with-mutex (wait-lock)
(setf result (symbol-value symbol))
(sb-thread:condition-notify wait))))
(sb-thread:with-mutex (wait-lock)
(sb-thread:condition-wait wait wait-lock)
(return-from global-value result))))
#-sbcl
(defun global-value (symbol)
`(i do not know whot to get the global value
in ,(lisp-implementation-type)))
(defvar haha 0)
(defun haha () 1)
(defclass haha () ((haha :initform 2)))
(let ((haha 3))
(flet ((haha () 4))
(block haha
(catch 'haha
(tagbody
(if (zerop haha) (go haha))
(print '(it was not zero))
(show (global-value 'haha) haha (symbol-value 'haha)
(haha) (funcall (function haha)) (funcall 'haha)
(slot-value (make-instance 'haha) 'haha))
(throw 'haha nil)
haha
(print '(it was zero))
(show haha (symbol-value 'haha)
(haha) (funcall (function haha)) (funcall 'haha)
(slot-value (make-instance 'haha) 'haha))
(return-from haha t))))))
* (load"/tmp/haha.lisp")
(IT WAS NOT ZERO)
(GLOBAL-VALUE (QUOTE HAHA)) = 0
HAHA = 3
(SYMBOL-VALUE (QUOTE HAHA)) = 3
(HAHA) = 4
(FUNCALL (FUNCTION HAHA)) = 4
(FUNCALL (QUOTE HAHA)) = 1
(SLOT-VALUE (MAKE-INSTANCE (QUOTE HAHA)) (QUOTE HAHA)) = 2
T
*
--
__Pascal Bourguignon__
On Fri, 25 Aug 2006 19:01:02 +0200, Pascal Bourguignon wrote:
> Henk Koster <············@xs4all.nl> writes:
>
>> I'm just starting to learn Common Lisp using Seibel's book, and I'm a
>> bit confused as to the use of symbols for operators and other objects.
>> Am I correct in thinking that there a two namespaces in CL, one for
>> operators and one for other objects?
>>
>> For example, when I (setf a 13) then the symbol a evaluates to 13; and
>> when I then (defun a () (format t "Hi!")) then the list (a) results in
>> "Hi", while the atom a still gives 13. In fact, I can (setf setf 17) to
>> get the non-operator symbol setf to evaluate to 17, without affecting
>> the operator of the same name.
>>
>> Somebody explained that such symbols have "dual bindings", but it
>> seems to me that a crucial property of a symbol is that it is unique
>> and has only one binding at any one time. Or am I thinking too much
>> Smalltalk here?
>>
>> Can anyone enlighten a confused noob?
>
> Hoping the other answers will have enlightened you, here is some
> more confusion:
>
>
> * (cat "/tmp/haha.lisp")
>
> (defmacro show (&rest exprs)
> `(progn
> ,@(mapcar (lambda (expr) `(format t "~&~60A = ~S~%" ',expr ,expr)) exprs)))
>
>
> #+sbcl
> (defun global-value (symbol)
> "Implementation-dependant way to recover the global value
> of a special variable"
> (let ((result nil)
> (wait (sb-thread:make-waitqueue))
> (wait-lock (sb-thread:make-mutex :name "wait")))
> (sb-thread:make-thread
> (lambda ()
> (sb-thread:with-mutex (wait-lock)
> (setf result (symbol-value symbol))
> (sb-thread:condition-notify wait))))
> (sb-thread:with-mutex (wait-lock)
> (sb-thread:condition-wait wait wait-lock)
> (return-from global-value result))))
> #-sbcl
> (defun global-value (symbol)
> `(i do not know whot to get the global value
> in ,(lisp-implementation-type)))
>
>
> (defvar haha 0)
> (defun haha () 1)
> (defclass haha () ((haha :initform 2)))
> (let ((haha 3))
> (flet ((haha () 4))
> (block haha
> (catch 'haha
> (tagbody
> (if (zerop haha) (go haha))
> (print '(it was not zero))
> (show (global-value 'haha) haha (symbol-value 'haha)
> (haha) (funcall (function haha)) (funcall 'haha)
> (slot-value (make-instance 'haha) 'haha))
> (throw 'haha nil)
> haha
> (print '(it was zero))
> (show haha (symbol-value 'haha)
> (haha) (funcall (function haha)) (funcall 'haha)
> (slot-value (make-instance 'haha) 'haha))
> (return-from haha t))))))
>
>
> * (load"/tmp/haha.lisp")
> (IT WAS NOT ZERO)
> (GLOBAL-VALUE (QUOTE HAHA)) = 0
> HAHA = 3
> (SYMBOL-VALUE (QUOTE HAHA)) = 3
> (HAHA) = 4
> (FUNCALL (FUNCTION HAHA)) = 4
> (FUNCALL (QUOTE HAHA)) = 1
> (SLOT-VALUE (MAKE-INSTANCE (QUOTE HAHA)) (QUOTE HAHA)) = 2
> T
> *
I think I've got it now...
(message (Hello 'Henk)
(you :wrote :on '(Fri, 25 Aug 2006 12:50:11 +0200))
(
HK> Somebody explained that such symbols have "dual bindings", but it
HK> seems to me that a crucial property of a symbol is that it is unique
HK> and has only one binding at any one time.
symbol is unique, but it can have many slots.
symbol-value returns value cell.
symbol-function returns function cell.
symbol-plist returns property list associated with symbol. (you can access
this plist with (function get) and other)
)
(With-best-regards '(Alex Mizrahi) :aka 'killer_storm)
"People who lust for the Feel of keys on their fingertips (c) Inity")
To put it differently than others already have, though their posts
have been sufficient:
Henk Koster wrote:
> Somebody explained that such symbols have "dual bindings", but it
> seems to me that a crucial property of a symbol is that it is unique
> and has only one binding at any one time. Or am I thinking too much
> Smalltalk here?
So you expect that
!Collection methodsFor: 'inspection'!
inspect
| size |
size := self size. "error: nil is not a selector"
"..."
! !
?
Just as selectors in the message-send syntax are not subject to
ordinary evaluation, symbols in the funcall position are not subject
to ordinary evaluation.
--
Stephen Compall
http://scompall.nocandysw.com/blog