Page 1 of 1

symbol-function

Posted: Fri Dec 07, 2012 12:48 pm
by James
I'm working my way through On Lisp

What's the difference between

Code: Select all

(setf (symbol-function 'my-double)
      #'(lambda (x) (* x 2)))
and

Code: Select all

(setf my-double
      #'(lambda (x) (* x 2)))
On SBCL they both seem to produce a function that can be called normally

Code: Select all

(my-double 2)
4
see end of this section http://www.bookshelf.jp/texi/onlisp/onlisp_3.html#SEC14

thanks.

Re: symbol-function

Posted: Sat Dec 08, 2012 4:35 am
by Goheeca
CL is Lisp-2, therefore it doesn't produce the same thing - a function which can be called normally.

Code: Select all

* (lisp-implementation-type)

"SBCL"
* (lisp-implementation-version)

"1.0.56.0.debian"
* (defvar f nil)

F
* (boundp 'f)

T
* (fboundp 'f)

NIL
* (setf f #'(lambda (x) (expt x 2)))

#<FUNCTION (LAMBDA (X)) {BF7DD1D}>
* (boundp 'f)

T
* (fboundp 'f)

NIL
* (funcall f 3)

9
* (f 3)

; in: F 3
;     (F 3)
; 
; caught STYLE-WARNING:
;   undefined function: F
; 
; compilation unit finished
;   Undefined function:
;     F
;   caught 1 STYLE-WARNING condition

debugger invoked on a UNDEFINED-FUNCTION in thread
#<THREAD "initial thread" RUNNING {AB19829}>:
  The function COMMON-LISP-USER::F is undefined.

* (setf (symbol-function 'f) #'(lambda (x) (expt x 3)))

#<FUNCTION (LAMBDA (X)) {BFAD1BD}>
* (f 3)

27
* (funcall f 3)

9
* (fboundp 'f)

T
* (dribble)
As you can see the symbol must be fbound, so that it can be used in a first position of list. If the function is saved as a value of variable denoted by that symbol, you can call it via funcall.

Re: symbol-function

Posted: Sun Dec 09, 2012 1:14 am
by Konfusius
You may think of a symbol as having two slots, one for the variable value and one for the functional value. If the evaluator encounters a symbol then it looks up the variable value. But if it encounters a form like (sym args ...) then it looks up the functional value for sym and calls that function with args.

The reason for that is macro hygene. If you bind a variable named f and then call a macro that expands to a call to function f and if CL wasn't a Lisp-2 then the call would fail because f isn't bound to a function. Or maybe bound to a different function that the author of the macro didn't intend to call.

Another reason is efficiency. If CL was using the variable value slot for functions too then every time a function is called Lisp first had to check the value for beeing a function. In a Lisp-2 this check could already be done when assigning the functional value to the symbol. With the optimizing compilers of today this isn't that important anymore, tough.