How is sharp quote (#') different from symbol-function? - lisp

To me these operators seem to do the same thing. Both take a symbol and return the function associated with it. Is there any difference?
elisp evaluation returns the following:
(defun foo (x) (+ 1 x))
foo
(foo 3)
4
#'foo
Which I don't understand either.
Furthermore is there a difference between common lisp and elisp? I'm learning from resources on either.

Common Lisp:
SYMBOL-FUNCTION can't retrieve functions from lexically bound functions. FUNCTION references the lexically bound function by default. #'foo is just a shorter notation for (FUNCTION foo).
CL-USER 1 > (defun foo () 'foo)
FOO
CL-USER 2 > (flet ((foo () 'bar))
(list (funcall (symbol-function 'foo))
(funcall #'foo)
(funcall (function foo))
(eq (function foo) (symbol-function 'foo))))
(FOO BAR BAR NIL)
CL-USER 3 > (eq (function foo) (symbol-function 'foo))
T

Rainer's answer discusses the things that you can do with function that you can't do with symbol-function, namely retrieve the value of lexically scoped functions, but there are a few other differences too.
The special operator FUNCTION
The special operator FUNCTION provides a way to find the functional value of a name in a lexical environment. Its argument is either a function name or a lambda expression. That function can take a lambda expression means that you can write: (function (lambda (x) (list x x))). The term function name includes more than just symbols. It also includes lists of the form (setf name), which means that you can do things like (function (setf car)).
The accessor SYMBOL-FUNCTION
The accessor symbol-function, on the other hand, lets you retrieve and set the functional value of a symbol. Since it requires a symbol, you can't do (symbol-function (lambda …)) or (function (setf name)). Symbol-function also can't see lexical environments; it only works with global definitions. E.g.,
(flet ((foo () 'result))
(symbol-function 'foo))
;=> NIL
Since symbol-function is an accessor, you can change the value of a function's symbol with it. E.g.:
CL-USER> (setf (symbol-function 'foo) (lambda () 42))
#<FUNCTION (LAMBDA ()) {1005D29AAB}>
CL-USER> (foo)
42
CL-USER> (setf (symbol-function 'foo) (lambda () 26))
#<FUNCTION (LAMBDA ()) {1005D75B9B}>
CL-USER> (foo)
26
The accessor FDEFINITION
There's also the accessor fdefinition which is kind of like symbol-function in that is can only access globally defined functions, but kind of like function in that it can access of symbols and (setf name) lists. However, it does not retrieve the value of lambda functions.

Related

Is defun or setf preferred for creating function definitions in common lisp and why?

What is the fundamental difference in the functions defined using defun and setf as below and is one method preferred over another outside of style considerations?
Using defun:
* (defun myfirst (l)
(car l) )
MYFIRST
* (myfirst '(A B C))
A
Using setf:
* (setf (fdefinition 'myfirst) #'(lambda (l) (car l)))
#<FUNCTION (LAMBDA (L)) {10021B477B}>
* (myfirst '(A B C))
A
If, as according to Wikipedia:
named functions are created by storing a lambda expression in a symbol using the defun macro
Using setf to create a variable in a different way requires the use of funcall:
* (defvar myfirst)
MYFIRST
* (setf myfirst (lambda (l) (car l)))
#<Interpreted Function (LAMBDA (X) (+ X X)) {48035001}>
* (funcall myfirst '(A B C))
A
My understanding is that this type of variable is different than the previous in that this variable is not found in the same namespace as the defun bound symbol as described in Why multiple namespaces?.
First of all, one should never underestimate the importance of style.
We write code not just for computers to run, but, much more importantly, for people to read.
Making code readable and understandable for people is a very important aspect of software development.
Second, yes, there is a big difference between (setf fdefinition) and defun.
The "small" differences are that defun can also set the doc string of the function name (actually, depending on how your imeplementation works, it might do that with lambda also), and creates a named block (seen in the macroexpansions below) which you would otherwise have to create yourself if you want to.
The big difference is that the compiler "knows" about defun and will process it appropriately.
E.g., if your file is
(defun foo (x)
(+ (* x x) x 1))
(defun bar (x)
(+ (foo 1 2 x) x))
then the compiler will probably warn you that you call foo in bar with the wrong number of arguments:
WARNING: in BAR in lines 3..4 : FOO was called with 3 arguments, but it requires 1
argument.
[FOO was defined in lines 1..2 ]
If you replace the defun foo with (setf (fdefinition 'foo) (lambda ...)), the compiler is unlikely to handle it as carefully. Moreover, you will probably get a warning along the lines of
The following functions were used but not defined:
FOO
You might want to examine what defun does in your implementation by macroexpanding it:
(macroexpand-1 '(defun foo (x) "doc" (print x)))
CLISP expands it to
(LET NIL (SYSTEM::REMOVE-OLD-DEFINITIONS 'FOO)
(SYSTEM::EVAL-WHEN-COMPILE
(SYSTEM::C-DEFUN 'FOO (SYSTEM::LAMBDA-LIST-TO-SIGNATURE '(X))))
(SYSTEM::%PUTD 'FOO
(FUNCTION FOO
(LAMBDA (X) "doc" (DECLARE (SYSTEM::IN-DEFUN FOO)) (BLOCK FOO (PRINT X)))))
(EVAL-WHEN (EVAL)
(SYSTEM::%PUT 'FOO 'SYSTEM::DEFINITION
(CONS '(DEFUN FOO (X) "doc" (PRINT X)) (THE-ENVIRONMENT))))
'FOO)
SBCL does:
(PROGN
(EVAL-WHEN (:COMPILE-TOPLEVEL) (SB-C:%COMPILER-DEFUN 'FOO NIL T))
(SB-IMPL::%DEFUN 'FOO
(SB-INT:NAMED-LAMBDA FOO
(X)
"doc"
(BLOCK FOO (PRINT X)))
(SB-C:SOURCE-LOCATION)))
The point here is that defun has a lot "under the hood", and for a reason. setf fdefinition is, on the other hand, more of "what you see is what you get", i.e., no magic involved.
This does not mean that setf fdefinition has no place in a modern lisp codebase. You can use it, e.g., to implement a "poor man's trace" (UNTESTED):
(defun trace (symbol)
(setf (get symbol 'old-def) (fdefinition symbol)
(fdefinition symbol)
(lambda (&rest args)
(print (cons symbol args))
(apply (get symbol 'old-def) args))))
(defun untrace (symbol)
(setf (fdefinition symbol) (get symbol 'old-def))
(remprop symbol 'odd-def))

Unquoting without eval

I store some macros in quoted form (because in fact they produce lambdas with tricky lexical environment and I prefer store and serialize them as lists). So now I'm trying:
(defun play (s)
(funcall (macroexpand s)))
Macroexpand evaluates quoted lambda, so funcall can't run it. How to unquote result of macroexpand without eval? Because in my case it would cause indefensible security hole.
MORE INFO:
What I get look like this (in simplest case):
FUNCALL: #1=#'(LAMBDA (#:G6008) (SYMBOL-MACROLET NIL T)) is not a function name; try using a symbol instead
and symbol-macrolet is what actually builds up "tricky lexical environment" inside lambda.
Macroexpand evaluates quoted lambda, so funcall can't run it. How to
unquote result of macroexpand without eval? Because in my case it
would cause indefensible security hole.
I think that Sylwester's comment about the XY problem is probably right here; it sounds like you're trying to do something that might be done better in a different way. That said, if you have a list that's a lambda expression, you can use coerce to get a function object instead of using eval. That is, you can do this:
CL-USER> (funcall '(lambda () 42))
; Error, like you've been having
CL-USER> (funcall (coerce '(lambda () 42) 'function))
42 ; turned the list (lambda () 42) into a function and called it
This is described in the documentation for coerce; when the "output" type is function, this is what happens with the object argument:
If the result-type is function, and object is any function name that
is fbound but that is globally defined neither as a macro name nor as
a special operator, then the result is the functional value of object.
If the result-type is function, and object is a lambda expression,
then the result is a closure of object in the null lexical
environment.
Thus, if you have a function that returns list of the form (lambda ...), you can use coerce and funcall with its result. This includes macroexpansions, although you may want to use macroexpand-1 rather than macroexpand, because lambda is already a macro, so if you expand too far, (lambda () ...) turns into (function (lambda () ...)).
CL-USER> (defmacro my-constantly (value)
`(lambda () ,value))
MY-CONSTANTLY
CL-USER> (macroexpand-1 '(my-constantly 36))
(LAMBDA () 36)
T
CL-USER> (funcall (coerce (macroexpand-1 '(my-constantly 36)) 'function))
36
If you try that with the plain macroexpand, though, there's a problem. Consider yourself warned:
CL-USER> (macroexpand '(my-constantly 36))
#'(LAMBDA () 36) ; not a list, but a function
T
CL-USER> (funcall (coerce (macroexpand '(my-constantly 36)) 'function))
; Error. :(
I think this is a case where you will find that the REPL is your friend. To get you started:
cl-user> (defmacro foo () #'(lambda () :hi))
foo
cl-user> (foo)
#<Compiled-function (:internal foo) (Non-Global) #x3020014F82FF>
cl-user> (funcall *)
:hi
cl-user> (macroexpand '(foo))
#<Compiled-function (:internal foo) (Non-Global) #x3020014F82FF>
t
cl-user> (funcall *)
:hi
cl-user>
I'll note in passing that the lambda form that appears in your example takes an argument, while your funcall doesn't provide one.
There are several issues with this. First I think this is a XY problem so if you show more of your problem I guess we might find a solution for it.
It has nothing with unquoting since when evaluation a quoted expression it's not longer quoted, but it's turn into data representation of the original quoted expression. You must eval data if you want to run it.
With eval you won't get the current lexical scope. So since you mention eval and lexical environment in the same post makes me thing you won't get what you want.
Now it's no problem making a list of functions, like this:
(list (lambda (x) (+ x x))
This is not quoted since I use list and teh lambda is evaluated to a closure. If it was assigned to variable x you could call it with (funcall (car x) 10)) ; ==> 20
EDIT
I actually made the same error message with this code:
(defmacro test () '#'(lambda (x) x))
(macroexpand '(test)) ; ==> #'(lambda (x) x) ; t
(funcall (macroexpand '(test)) 5) ; ==>
*** - funcall: #'(lambda (x) x) is not a function name; try using a symbol
instead
It doesn't work since you cannot call a lambda unevaluated. You need to call the closure (function) which is the result of the evaluation of the lambda form. If you would instead not quote it you'll have that evaluation in the macro:
(defmacro test () #'(lambda (x) x))
(macroexpand '(test)) ; ==> #<function :lambda (x) x> ;
(funcall (macroexpand '(test)) 5) ; ==> 5
Actually I cannot see why you would need to make this a macro. Lets make it a function instead.
(defun test () #'(lambda (x) x))
(funcall (test) 5 ) ; ==> 5
Even if this was more comples in most cases you would do with a closure.

Higher Order Function Syntax in Common Lisp

I'm teaching myself Common Lisp using Norvig's Paradigms of AI Programming and came across something I didn't understand and he didn't explain.
(defun mappend (fn the-list)
(apply #'append (mapcar fn the-list)))
What is the difference between calling a higher order function as follows, higherOrderFunc #'funcName funcArg and what he does when calling mapcar without #'? Is #' necessary when calling a higher order function?
Common Lisp has different namespaces for functions and variables.
(defun mappend (fn the-list)
(apply #'append (mapcar fn the-list)))
Above MAPPEND gets defined with two local variables fn and the-list
APPLY gets passed the function value of APPEND.
MAPCAR gets passed the variable value of FN.
Similar see this:
CL-USER 129 > (flet ((add-something (number)
(+ number 17)))
(let ((add-something (lambda (number)
(+ number 42))))
(list
(mapcar #'add-something '(1 2 3))
(mapcar add-something '(1 2 3)))))
->
((18 19 20) (43 44 45))
LET creates local variables, FLET creates local functions.
The first mapcar uses the function namespace and the second uses the variable namespace.
Common Lisp uses a special function namespace because it was thought to be more efficient (slightly easier to implement a fast Lisp) and to allow functions and variables to have the same name.
In Common Lisp we can write:
(defun list-me (list)
(list list))
In Scheme, which does not have separate namespaces one would write something like this:
(define (list-me lst)
(list lst))
#' is syntactic sugar for function: #'foo is read as (function foo).
Function is a special operator that returns the function value bound to the name given. If you pass a function as a parameter, that parameter (in your case, fn) has its value bound to the function. To pass it on to another function, you can simply put the variable name into the call form. However, to get the function value of a name, you need to access it with function.
Using #' is not strictly required. If instead you simply pass 'foo the symbol-function will be invoked. Consider the following:
* (defvar foo #'(lambda (a) 'var))
* (setf (symbol-function 'foo) #'(lambda (a) 'fun))
* (mapcar 'foo '(a b))
(FUN FUN)
* (mapcar #'foo '(a b))
(FUN FUN)
* (mapcar foo '(a b))
(VAR VAR)
Practially #'foo or 'foo are equivalent:
X3J13 voted [...] to allow the 'function' to the only of type 'symbol'
or 'function'; [...] one must use the 'function' special form [...]
before a lambda-expression [...].
Specification of the function in flet has some interesting properties:
* (flet ((foo (a) 'FLET))
(mapcar foo '(a b))) ; Uses 'value' of foo
(VAR VAR)
* (flet ((foo (a) 'FLET))
(mapcar 'foo '(a b))) ; Uses 'function' of foo
(FUN FUN)
* (flet ((foo (a) 'FLET))
(mapcar #'foo '(a b))) ; Uses local binding 'flet' of foo
(FLET FLET)

Higher order programming with Lisp: Passing a function to mapcar?

I'm just learning ANSI Common Lisp (using clisp on a Win32 machine) and I was wondering if mapcar could use a function passed in as a formal argument? Please see the following:
(defun foo (fn seq)
(mapcar #'fn seq))
This would, in my opinion, provide a greater level of flexibility than:
(defun mult (i)
(* i 2))
(defun foo ()
(mapcar #'mult '(1 2 3)))
This is absolutely possible! You're almost there. You just bumped into Common Lisp's dual namespaces, which can take a lot of getting used to. I hope I can say a thing or two to make Common Lisp's two namespaces a bit less confusing.
Your code is almost correct. You wrote:
(defun foo (fn seq)
(mapcar #'fn seq))
But, what is that trying to do? Well, #' is shorthand. I'll expand it out for you.
(defun foo (fn seq)
(mapcar (function fn) seq))
So, #'symbol is shorthand for (function symbol). In Common Lisp -- as you seem to know -- symbols can be bound to a function and to a variable; these are the two namespaces that Lispers talk so much about: the function namespace, and the variable namespace.
Now, what the function special form does is get the function bound to a symbol, or, if you like, the value that the symbol has in the function namespace.
Now, on the REPL, what you wrote would be obviously what you want.
(mapcar #'car sequence)
Would map the car function to a sequence of lists. And the car symbol has no variable binding, only a function binding, which is why you need to use (function ...) (or its shorthand, #') to get at the actual function.
Your foo function doesn't work because the function you pass it as an argument is being bound to a symbol as a variable. Try this:
(let ((fn #'sqrt))
(mapcar #'fn '(4 9 16 25)))
You might have expected a list of all those numbers' square roots, but it didn't work. That's because you used let to bind the square root function to fn as a variable. Now, try this code:
(let ((fn #'sqrt))
(mapcar fn '(4 9 16 25)))
Delightful! This binds the square root function to the fn symbol as a variable.
So, let's go revise your foo function:
(defun foo (fn seq)
(mapcar fn seq))
That will work, because fn is a variable. Let's test it, just to make sure:
;; This will not work
(foo sqrt '(4 9 16 25))
;; This will work
(foo #'sqrt '(4 9 16 25))
The first one didn't work, because the square root function is bound to sqrt in the function namespace. So, in the second one, we grabbed the function from the symbol, and passed it to foo, which bound it to the symbol fn as a variable.
Okay, so what if you want to bind a function to a symbol in the function namespace? Well, for starters, defun does that, permanently. If you want it to be temporary, like a let binding, use flet. Flet is, in my opinion, stupid, because it doesn't work exactly like let does. But, I'll give an example, just so you can see.
(flet ((fn (x) (sqrt x)))
(mapcar fn '(4 9 16 25)))
will not work, because flet didn't bind the function to the symbol in the variable namespace, but in the function namespace.
(flet ((fn (x) (sqrt x)))
(mapcar #'fn '(4 9 16 25)))
This will do what you expect, because flet bound that function to the symbol fn in the function namespace. And, just to drive the idea of the function namespace home:
(flet ((fn (x) (sqrt x)))
(fn 16))
Will return 4.
Sure, you can do this:
(defun foo (fn)
(mapcar fn '(1 2 3)))
Examples:
(foo #'(lambda (x) (* x 2)))
(foo #'1+)
(foo #'sqrt)
(foo #'(lambda (x) (1+ (* x 3))))

returning a lambda function in clisp, then evaluating it

Suppose I have this wonderful function foo
[92]> (defun foo () (lambda() 42))
FOO
[93]> (foo)
#<FUNCTION :LAMBDA NIL 42>
[94]>
Now, suppose I want to actually use foo and return 42.
How do I do that? I've been scrounging around google and I can't seem to come up with the correct syntax.
You want the FUNCALL function:
* (defun foo () (lambda () 42))
FOO
* (funcall (foo))
42
The relevant terms here are "Lisp-1" and "Lisp-2".
Your attempt at calling would work in a Lisp-1 like e.g. Scheme or Clojure.
Common Lisp is a Lisp-2 however which roughly means that variable names and function names are separate.
So, in order to call the function bound to a variable you either need to use the special forms funcall or apply as others have pointed out or set the function value of the symbol foo rather than the variable value.
The former basically takes the variable value of the symbol, assumes/checks that value is a function and then calls the function (with whatever arguments you passed to funcall/apply.
You don't really want to do the latter as that is quite silly in all but very specialised cases, but for completness sake this is roughly how you'd do it:
CL-USER> (setf (symbol-function 'foo) (lambda () 42))
#<FUNCTION (LAMBDA ()) {C43DCFD}>
CL-USER> (foo)
42
You should also want to look into the labels and flet special forms (which are commonly used) - there you actually do use the latter methods (these forms create a temporary function binding for symbols).
So your problem would there look like this:
(flet ((foo ()
42))
(foo))
i.e. here you temporarily bind the function value of the symbol foo to the function returning 42. Within that temporary context you can then call (foo) like regular global functions.
Your function foo returns a function. Use the funcall function to apply a function to arguments, even if the argument set is empty.
Here you can see that foo returns a value of type function:
CL-USER> (let ((f (foo)))
(type-of f))
FUNCTION
CL-USER> (let ((f (foo)))
(funcall f))
42
CL-USER> (type-of (foo))
FUNCTION
CL-USER> (funcall (foo))
42
Another option besides FUNCALL is APPLY:
(apply (foo) nil)
FUNCALL is the idiomatic way here, but you'll need APPLY when you have a list of parameters.