Un-named Intrepreted Functions Question

Discussion of Common Lisp
Post Reply
macrolyte
Posts: 40
Joined: Sat Jan 25, 2014 8:56 pm
Location: The wilderness of North America

Un-named Intrepreted Functions Question

Post by macrolyte » Thu Mar 13, 2014 4:28 pm

This may be a really dumb question, but in the code below, what the heck is *d*?!!

Code: Select all

     (setq *d* (λ(r)(* 2 pi r)))     ;; just an identifier picked at random, the lambda form is the formula for circumference
     (funcall *d* 4)                 ;; the λ form is applied to 4, its missing argument
     (*d* 3)                         ;; *d* is a not a function; evaluating this will cause an undefined function error
     (functionp #'*d*)               ;; undefined function error, again
     (describe *d*)                  ;; #<FUNCTION :LAMBDA (R) (* 2 PI R)> is an interpreted function.|Argument list: (R)|; No values
     (type-of *d*)                   ;; FUNCTION 
I understand that *d*'s function value is set to the lambda form, but it really isn't a named function:

Code: Select all

    (defun circumference(r)(* 2 pi r))
    (circumference 4)
    (functionp #'circumference) ;; T
So just what should I call *d*? Thanks.

edgar-rft
Posts: 226
Joined: Fri Aug 06, 2010 6:34 am
Location: Germany

Re: Un-named Intrepreted Functions Question

Post by edgar-rft » Fri Mar 14, 2014 3:19 am

macrolyte wrote:I understand that *d*'s function value is set to the lambda form...
No, it's the variable value of *d* that is set to the function object returned by the lambda form:

Code: Select all

(setq *d* (lambda (r) (* 2 pi r)))
is the same as:

Code: Select all

(setf (symbol-value '*d*) (lambda (r) (* 2 pi r)))
Here *d* is a variable pointing to a function object, because the SYMBOL-VALUE slot of *d* points to the function object returned by the LAMBDA macro. But a function object in a SYMBOL-VALUE slot can only be used with FUNCALL or APPLY:

Code: Select all

(*d* 2)          => error: undefined function
(funcall *d* 2)  => 12.566370614359172d0
(apply *d* '(2)) => 12.566370614359172d0
The "undefined function" error happens because the SYMBOL-VALUE slot of *d* and not the SYMBOL-FUNCTION slot of *d* points ot the function object, what means that the function ist stored as the variable value of *d* and not as the function value of *d*.

The counter-example would be:

Code: Select all

(defun *d* (r) (* 2 pi r))
is the same as:

Code: Select all

(setf (symbol-function '*d*) (lambda (r) (* 2 pi r)))
Here *d* is a function, because the SYMBOL-FUNCTION slot of *d* points to a function object:

Code: Select all

(*d* 2) => 12.566370614359172d0
But a function as argument to FUNCALL or APPLY needs to be prefixed by #' because otherwise the SYMBOL-VALUE slot is used:

Code: Select all

(funcall *d* 2)     ; uses the symbol-value slot of *d*
(apply *d* '(2))    ; uses the symbol-value slot of *d*

(funcall #'*d* 2)   ; uses the symbol-function slot of *d*
(apply #'*d* '(2))  ; uses the symbol-function slot of *d*
#' is a shortcut for the FUNCTION special operator:

Code: Select all

(funcall (function *d*) 2)   ; uses the symbol-function slot of *d*
(apply (function *d*) '(2))  ; uses the symbol-function slot of *d*
Summary:

In Common Lisp the SYMBOL-FUNCTION as well as the SYMBOL-VALUE slot can point to function objects (even two different function objects), but a function in a SYMBOL-VALUE slot can only be used with FUNCALL or APPLY.

Often it's really handy that Common Lisp is a Lisp-2 (the same symbol name can be used as function and as variable), but sometimes things can become really complicated because of this.

- edgar

macrolyte
Posts: 40
Joined: Sat Jan 25, 2014 8:56 pm
Location: The wilderness of North America

Re: Un-named Intrepreted Functions Question

Post by macrolyte » Sat Mar 15, 2014 11:35 am

THANK YOU! I have to say that I couldn't have wanted a more cogent and concise explanation. And yes, the different namespaces had me confused and unsure of what behavior to expect. I'm so glad that you and the others here take the time to answer newbie questions, it is a blessing. I really don''t wish to just know the how of Lisp, the why is far more important to me, hence my taking my time. I have started reading the HyperSpec, so expect more interesting questions soon... Now I can get back to work.

Post Reply