defparameter vs defun for passing functions around - lisp

So I can do this:
(defparameter *some-function* ... ; returns lambda later
or this:
(defun some-function ...
With either, I can use funcall:
(funcall 'some-function ...
or
(funcall *some-function* ...
With the defun version I can also do this:
(some-function ...
I cannot do that with the defparameter function.
defparameter provides easier technique for re-assigning some-function to a different function (or anything else, including non-function data) later.
But other than these two points, what are other considerations of using one over another?

This is an odd one to answer as we are somewhat comparing apples with oranges.
For those new to lisp who are looking at this, defparameter is for defining a dynamic variable whereas defun is for defining a function.
If you are worried about being able to programmatically reassign a function without using defun check out the following:
CL-USER> (defun jam () (print 'some-jam))
JAM
CL-USER> (jam)
SOME-JAM
CL-USER> (setf (symbol-function 'jam) (lambda () (print 'some-ham)))
#<FUNCTION (LAMBDA ()) {1004C033DB}>
CL-USER> (jam)
SOME-HAM
So defparameter doesn’t have an advantage when it comes to reassigning a function. Also if you want to redefine the function you could look into the compile command.

Related

Lisp changes function to lambda expression when stored in function cell

In this post, I ask tangentially why when I declare in SBCL
(defun a (&rest x)
x)
and then check what the function cell holds
(describe 'a)
COMMON-LISP-USER::A
[symbol]
A names a compiled function:
Lambda-list: (&REST X)
Derived type: (FUNCTION * (VALUES LIST &OPTIONAL))
Source form:
(LAMBDA (&REST X) (BLOCK A X))
I see this particular breakdown of the original function. Could someone explain what this output means? I'm especially confused by the last line
Source form:
(LAMBDA (&REST X) (BLOCK A X))
This is mysterious because for some reason not clear to me Lisp has transformed the original function into a lambda expression. It would also be nice to know the details of how a function broken down like this is then called. This example is SBCL. In Elisp
(symbol-function 'a)
gives
(lambda (&rest x) x)
again, bizarre. As I said in the other post, this is easier to understand in Scheme -- but that created confusion in the answers. So once more I ask, Why has Lisp taken a normal function declaration and seemingly stored it as a lambda expression?
I'm still a bit unclear what you are confused about, but here is an attempt to explain it. I will stick to CL (and mostly to ANSI CL), because elisp has a lot of historical oddities which just make things hard to understand (there is an appendix on elisp). Pre-ANSI CL was also a lot less clear on various things.
I'll try to explain things by writing a macro which is a simple version of defun: I'll call this defun/simple, and an example of its use will be
(defun/simple foo (x)
(+ x x))
So what I need to do is to work out what the expansion of this macro should be, so that it does something broadly equivalent (but simpler than) defun.
The function namespace & fdefinition
First of all I assume you are comfortable with the idea that, in CL (and elisp) the namespace of functions is different than the namespace of variable bindings: both languages are lisp-2s. So in a form like (f x), f is looked up in the namespace of function bindings, while x is looked up in the namespace of variable bindings. This means that forms like
(let ((sin 0.0))
(sin sin))
are fine in CL or elisp, while in Scheme they would be an error, as 0.0 is not a function, because Scheme is a lisp-1.
So we need some way of accessing that namespace, and in CL the most general way of doing that is fdefinition: (fdefinition <function name>) gets the function definition of <function name>, where <function name> is something which names a function, which for our purposes will be a symbol.
fdefinition is what CL calls an accessor: this means that the setf macro knows what to do with it, so that we can mutate the function binding of a symbol by (setf (fdefinition ...) ...). (This is not true: what we can access and mutate with fdefinition is the top-level function binding of a symbol, we can't access or mutate lexical function bindings, and CL provides no way to do this, but this does not matter here.)
So this tells us what our macro expansion needs to look like: we want to set the (top-level) definition of the name to some function object. The expansion of the macro should be like this:
(defun/simple foo (x)
x)
should expand to something involving
(setf (fdefinition 'foo) <form which makes a function>)
So we can write this bit of the macro now:
(defmacro defun/simple (name arglist &body forms)
`(progn
(setf (fdefinition ',name)
,(make-function-form name arglist forms))
',name))
This is the complete definition of this macro. It uses progn in its expansion so that the result of expanding it is the name of the function being defined, which is the same as defun: the expansion does all its real work by side-effect.
But defun/simple relies on a helper function, called make-function-form, which I haven't defined yet, so you can't actually use it yet.
Function forms
So now we need to write make-function-form. This function is called at macroexpansion time: it's job is not to make a function: it's to return a bit of source code which will make a function, which I'm calling a 'function form'.
So, what do function forms look like in CL? Well, there's really only one such form in portable CL (this might be wrong, but I think it is true), which is a form constructed using the special operator function. So we're going to need to return some form which looks like (function ...). Well, what can ... be? There are two cases for function.
(function <name>) denotes the function named by <name> in the current lexical environment. So (function car) is the function we call when we say (car x).
(function (lambda ...)) denotes a function specified by (lambda ...): a lambda expression.
The second of these is the only (caveats as above) way we can construct a form which denotes a new function. So make-function-form is going to need to return this second variety of function form.
So we can write an initial version of make-function-form:
(defun make-function-form (name arglist forms)
(declare (ignore name))
`(function (lambda ,arglist ,#forms)))
And this is enough for defun/simple to work:
> (defun/simple plus/2 (a b)
(+ a b))
plus/2
> (plus/2 1 2)
3
But it's not quite right yet: one of the things that functions defined by defun can do is return from themselves: they know their own name and can use return-from to return from it:
> (defun silly (x)
(return-from silly 3)
(explode-the-world x))
silly
> (silly 'yes)
3
defun/simple can't do this, yet. To do this, make-function-form needs to insert a suitable block around the body of the function:
(defun make-function-form (name arglist forms)
`(function (lambda ,arglist
(block ,name
,#forms))))
And now:
> (defun/simple silly (x)
(return-from silly 3)
(explode-the-world x))
silly
> (silly 'yes)
3
And all is well.
This is the final definition of defun/simple and its auxiliary function.
Looking at the expansion of defun/simple
We can do this with macroexpand in the usual way:
> (macroexpand '(defun/simple foo (x) x))
(progn
(setf (fdefinition 'foo)
#'(lambda (x)
(block foo
x)))
'foo)
t
The only thing that's confusing here is that, because (function ...) is common in source code, there's syntactic sugar for it which is #'...: this is the same reason that quote has special syntax.
It's worth looking at the macroexpansion of real defun forms: they usually have a bunch of implementation-specific stuff in them, but you can find the same thing there. Here's an example from LW:
> (macroexpand '(defun foo (x) x))
(compiler-let ((dspec::*location* '(:inside (defun foo) :listener)))
(compiler::top-level-form-name (defun foo)
(dspec:install-defun 'foo
(dspec:location)
#'(lambda (x)
(declare (system::source-level
#<eq Hash Table{0} 42101FCD5B>))
(declare (lambda-name foo))
x))))
t
Well, there's a lot of extra stuff in here, and LW obviously has some trick around this (declare (lambda-name ...)) form which lets return-from work without an explicit block. But you can see that basically the same thing is going on.
Conclusion: how you make functions
In conclusion: a macro like defun, or any other function-defining form, needs to expand to a form which, when evaluated, will construct a function. CL offers exactly one such form: (function (lambda ...)): that's how you make functions in CL. So something like defun necessarily has to expand to something like this. (To be precise: any portable version of defun: implementations are somewhat free to do implementation-magic & may do so. However they are not free to add a new special operator.)
What you are seeing when you call describe is that, after SBCL has compiled your function, it's remembered what the source form was, and the source form was exactly the one you would have got from the defun/simple macro given here.
Notes
lambda as a macro
In ANSI CL, lambda is defined as a macro whose expansion is a suitable (function (lambda ...)) form:
> (macroexpand '(lambda (x) x))
#'(lambda (x) x)
t
> (car (macroexpand '(lambda (x) x)))
function
This means that you don't have to write (function (lambda ...)) yourself: you can rely on the macro definition of lambda doing it for you. Historically, lambda wasn't always a macro in CL: I can't find my copy of CLtL1, but I'm pretty certain it was not defined as one there. I'm reasonably sure that the macro definition of lambda arrived so that it was possible to write ISLisp-compatible programs on top of CL. It has to be in the language because lambda is in the CL package and so users can't portably define macros for it (although quite often they did define such a macro, or at least I did). I have not relied on this macro definition above.
defun/simple does not purport to be a proper clone of defun: its only purpose is to show how such a macro can be written. In particular it doesn't deal with declarations properly, I think: they need to be lifted out of the block & are not.
Elisp
Elisp is much more horrible than CL. In particular, in CL there is a well-defined function type, which is disjoint from lists:
> (typep '(lambda ()) 'function)
nil
> (typep '(lambda ()) 'list)
t
> (typep (function (lambda ())) 'function)
t
> (typep (function (lambda ())) 'list)
nil
(Note in particular that (function (lambda ())) is a function, not a list: function is doing its job of making a function.)
In elisp, however, an interpreted function is just a list whose car is lambda (caveat: if lexical binding is on this is not the case: it's then a list whose car is closure). So in elisp (without lexical binding):
ELISP> (function (lambda (x) x))
(lambda (x)
x)
And
ELISP> (defun foo (x) x)
foo
ELISP> (symbol-function 'foo)
(lambda (x)
x)
The elisp intepreter then just interprets this list, in just the way you could yourself. function in elisp is almost the same thing as quote.
But function isn't quite the same as quote in elisp: the byte-compiler knows that, when it comes across a form like (function (lambda ...)) that this is a function form, and it should byte-compile the body. So, we can look at the expansion of defun in elisp:
ELISP> (macroexpand '(defun foo (x) x))
(defalias 'foo
#'(lambda (x)
x))
(It turns out that defalias is the primitive thing now.)
But if I put this definition in a file, which I byte compile and load, then:
ELISP> (symbol-function 'foo)
#[(x)
"\207"
[x]
1]
And you can explore this a bit further: if you put this in a file:
(fset 'foo '(lambda (x) x))
and then byte compile and load that, then
ELISP> (symbol-function 'foo)
(lambda (x)
x)
So the byte compiler didn't do anything with foo because it didn't get the hint that it should. But foo is still a fine function:
ELISP> (foo 1)
1 (#o1, #x1, ?\C-a)
It just isn't compiled. This is also why, if writing elisp code with anonymous functions in it, you should use function (or equivalently #'). (And finally, of course, (function ...) does the right thing if lexical scoping is on.)
Other ways of making functions in CL
Finally, I've said above that function & specifically (function (lambda ...)) is the only primitive way to make new functions in CL. I'm not completely sure that's true, especially given CLOS (almost any CLOS will have some kind of class instances of which are functions but which can be subclassed). But it does not matter: it is a way and that's sufficient.
DEFUN is a defining macro. Macros transform code.
In Common Lisp:
(defun foo (a)
(+ a 42))
Above is a definition form, but it will be transformed by DEFUN into some other code.
The effect is similar to
(setf (symbol-function 'foo)
(lambda (a)
(block foo
(+ a 42))))
Above sets the function cell of the symbol FOO to a function. The BLOCK construct is added by SBCL, since in Common Lisp named functions defined by DEFUN create a BLOCK with the same name as the function name. This block name can then be used by RETURN-FROM to enable a non-local return from a specific function.
Additionally DEFUN does implementation specific things. Implementations also record development information: the source code, the location of the definition, etc.
Scheme has DEFINE:
(define (foo a)
(+ a 10))
This will set FOO to a function object.

How is the defun macro implemented in lisp?

I'd like to learn more about lisp macros and I want to create a simple implementation of the defun macro.
I'm also interested in lisp's source code in all the implementations.
This is a tricky question, because of bootstrapping: defun does a lot of things (iow, calls a lot of functions), but to define those functions one needs a working defun. Thus there are three(3!) definitions of defun in clisp/src/init.lisp: at lines
228
1789
1946
The very basic definition of defun could be this:
(defmacro defun (fname lambda-list &rest body)
`(setf (fdefinition ',fname)
(lambda ,lambda-list
(block ,fname ,#body))))
In fact, this is the first definition of defun in CLISP (line 228), except that there is no defmacro and no backquote at that moment yet, so the actual code looks a lot uglier.
See also Is defun or setf preferred for creating function definitions in common lisp and why? where I discuss macroexpansions of defuns.
You can easily check how your particular CL implementation, implemented defun by running
(macroexpand '(defun add2 (x) (+ x 2)))
On SBCL it expands to:
(PROGN
(EVAL-WHEN (:COMPILE-TOPLEVEL) (SB-C:%COMPILER-DEFUN 'ADD2 NIL T))
(SB-IMPL::%DEFUN 'ADD2
(SB-INT:NAMED-LAMBDA ADD2
(X)
(BLOCK ADD2 (+ X 2)))
(SB-C:SOURCE-LOCATION)))
T
To see the particular source code that implemented the I would use (on Emacs) the M-. key binding and then I will write defun and hit enter. Then Emacs will get to the source code:
(sb!xc:defmacro defun (&environment env name lambda-list &body body)
#!+sb-doc
"Define a function at top level."
[...]
I am not going to paste the whole macro as it is rather long. If you are not on Emacs, you can try searching in the repos as most implementations are open source.
BTW defun is not so special. You can implement much of it with setf-inf a symbol-function to a lambda. E.g.:
(setf (symbol-function 'ADD3) #'(lambda (x) (+ x 3)))
; => #<FUNCTION (LAMBDA (X)) {1006E94EBB}>
(add3 4)
; => 7

Trying to understand setf + aref "magic"

I now have learnt about arrays and aref in Lisp. So far, it's quite easy to grasp, and it works like a charme:
(defparameter *foo* (make-array 5))
(aref *foo* 0) ; => nil
(setf (aref *foo* 0) 23)
(aref *foo* 0) ; => 23
What puzzles me is the aref "magic" that happens when you combine aref and setf. It seems as if aref knew about its calling context, and would then decide whether to return a value or a place that can be used by setf.
Anyway, for the moment I just take this as granted, and don't think about the way this works internally too much.
But now I wanted to create a function that sets an element of the *foo* array to a predefined value, but I don't want to hardcode the *foo* array, instead I want to hand over a place:
(defun set-23 (place)
…)
So basically this function sets place to 23, whatever place is. My initial naive approach was
(defun set-23 (place)
(setf place 23))
and call it using:
(set-23 (aref *foo* 0))
This does not result in an error, but it also doesn't change *foo* at all. My guess would be that the call to aref resolves to nil (as the array is currently empty), so this would mean that
(setf nil 23)
is run, but when I try this manually in the REPL, I get an error telling me that:
NIL is a constant, may not be used as a variable
(And this absolutely makes sense!)
So, finally I have two questions:
What happens in my sample, and what does this not cause an error, and why doesn't it do anything?
How could I solve this to make my set-23 function work?
I also had the idea to use a thunk for this to defer execution of aref, just like:
(defun set-23 (fn)
(setf (funcall fn) 23))
But this already runs into an error when I try to define this function, as Lisp now tells me:
(SETF FUNCALL) is only defined for functions of the form #'symbol.
Again, I wonder why this is. Why does using setf in combination with funcall apparently work for named functions, but not for lambdas, e.g.?
PS: In "Land of Lisp" (which I'm currently reading to learn about Lisp) it says:
In fact, the first argument in setf is a special sublanguage of Common Lisp, called a generalized reference. Not every Lisp command is allowed in a generalized reference, but you can still put in some pretty complicated stuff: […]
Well, I guess that this is the reason (or at least one of the reasons) here, why all this does not work as I'd expect it, but nevertheless I'm curious to learn more :-)
A place is nothing physical, it's just a concept for anything where we can get/set a value. So a place in general can't be returned or passed. Lisp developers wanted a way to easily guess a setter from just knowing what the getter is. So we write the getter, with a surrounding setf form and Lisp figures out how to set something:
(slot-value vehicle 'speed) ; gets the speed
(setf (slot-value vehicle 'speed) 100) ; sets the speed
Without SETF we would need a setter function with its name:
(set-slot-value vehicle 'speed 100) ; sets the speed
For setting an array we would need another function name:
(set-aref 3d-board 100 100 100 'foo) ; sets the board at 100/100/100
Note that the above setter functions might exist internally. But you don't need to know them with setf.
Result: we end up with a multitude of different setter function names.
The SETF mechanism replaces ALL of them with one common syntax. You know the getter call? Then you know the setter, too. It's just setf around the getter call plus the new value.
Another example
world-time ; may return the world time
(setf world-time (get-current-time)) ; sets the world time
And so on...
Note also that only macros deal with setting places: setf, push, pushnew, remf, ... Only with those you can set a place.
(defun set-23 (place)
(setf place 23))
Above can be written, but place is just a variable name. You can't pass a place. Let's rename it, which does not change a thing, but reduces confusion:
(defun set-23 (foo)
(setf foo 23))
Here foo is a local variable. A local variable is a place. Something we can set. So we can use setf to set the local value of the variable. We don't set something that gets passed in, we set the variable itself.
(defmethod set-24 ((vehicle audi-vehicle))
(setf (vehicle-speed vehicle) 100))
In above method, vehicle is a variable and it is bound to an object of class audi-vehicle. To set the speed of it, we use setf to call the writer method.
Where does Lisp know the writer from? For example a class declaration generates one:
(defclass audi-vehicle ()
((speed :accessor vehicle-speed)))
The :accessor vehicle-speed declaration causes both reading and setting functions to be generated.
The setf macro looks at macro expansion time for the registered setter. That's all. All setf operations look similar, but Lisp underneath knows how to set things.
Here are some examples for SETF uses, expanded:
Setting an array item at an index:
CL-USER 86 > (pprint (macroexpand-1 '(setf (aref a1 10) 'foo)))
(LET* ((#:G10336875 A1) (#:G10336876 10) (#:|Store-Var-10336874| 'FOO))
(SETF::\"COMMON-LISP\"\ \"AREF\" #:|Store-Var-10336874|
#:G10336875
#:G10336876))
Setting a variable:
CL-USER 87 > (pprint (macroexpand-1 '(setf a 'foo)))
(LET* ((#:|Store-Var-10336877| 'FOO))
(SETQ A #:|Store-Var-10336877|))
Setting a CLOS slot:
CL-USER 88 > (pprint (macroexpand-1 '(setf (slot-value o1 'bar) 'foo)))
(CLOS::SET-SLOT-VALUE O1 'BAR 'FOO)
Setting the first element of a list:
CL-USER 89 > (pprint (macroexpand-1 '(setf (car some-list) 'foo)))
(SYSTEM::%RPLACA SOME-LIST 'FOO)
As you can see it uses a lot of internal code in the expansion. The user just writes a SETF form and Lisp figures out what code would actually do the thing.
Since you can write your own setter, only your imagination limits the things you might want to put under this common syntax:
setting a value on another machine via some network protocol
setting some value in a custom data structure you've just invented
setting a value in a database
In your example:
(defun set-23 (place)
(setf place 23))
you can't do it just like that, because you have to use setf in context.
This will work:
(defmacro set-23 (place)
`(setf ,place 23))
CL-USER> (set-23 (aref *foo* 0))
23
CL-USER> *foo*
#(23 NIL NIL NIL NIL)
The trick is, setf 'knows' how to look at real place its arguments come from, only for limited number of functions. These functions are called setfable.
setf is a macro, and to use it the way you wanted to, you also have to use macros.
The reason why you have not been getting errors, is that you actually successfully modified lexical variable place which was bound to copy of selected array element.

why defun is not the same as (setq <name> <lambda>)?

I'm confused about how defun macro works, because
(defun x () "hello")
will create function x, but symbol x still will be unbound.
If I'll bind some lambda to x then x will have a value, but it will not be treated by interpreter as function in form like this:
(x)
I think that it is related to the fact that defun should define function in global environment, but I'm not sure what does it exactly mean. Why can't I shadow it in the current environment?
Is there any way to force interpreter treat symbol as function if some lambda was bound to it? For example:
(setq y (lambda () "I want to be a named function"))
(y)
P.S.: I'm using SBCL.
Common Lisp has different namespaces for functions and values.
You define functions in the function namespace with DEFUN, FLET, LABELS and some others.
If you want to get a function object as a value, you use FUNCTION.
(defun foo (x) (1+ x))
(function foo) -> #<the function foo>
or shorter:
#'foo -> #<the function foo>
If you want to call a function, then you write (foo 100).
If you want to call the function as a value then you need to use FUNCALL or APPLY:
(funcall #'foo 1)
You can pass functions around and call them:
(defun bar (f arg)
(funcall f arg arg))
(bar #'+ 2) -> 4
In the case of DEFUN:
It is not (setf (symbol-value 'FOO) (lambda ...)).
It is more like (setf (symbol-function 'foo) (lambda ...)).
Note that the two namespaces enable you to write:
(defun foo (list)
(list list))
(foo '(1 2 3)) -> ((1 2 3))
There is no conflict between the built-in function LIST and the variable LIST. Since we have two different namespaces we can use the same name for two different purposes.
Note also that in the case of local functions there is no symbol involved. The namespaces are not necessarily tied to symbols. Thus for local variables a function lookup via a symbol name is not possible.
Common Lisp has multiple slots for each symbol, including a value-slot, and a function-slot. When you use the syntax (x), common lisp looks for the function-slot-binding of x. If you want to call the value-binding, use funcall or apply.
See http://cl-cookbook.sourceforge.net/functions.html

Creating a lambda from an s-expression

I have an s-expression bound to a variable in Common Lisp:
(defvar x '(+ a 2))
Now I want to create a function that when called, evaluates the expression in the scope in which it was defined. I've tried this:
(let ((a 4))
(lambda () (eval x)))
and
(let ((a 4))
(eval `(lambda () ,x)))
But both of these create a problem: EVAL will evaluate the code at the top level, so I can't capture variables contained in the expression. Note that I cannot put the LET form in the EVAL. Is there any solution?
EDIT: So if there is not solution to the EVAL problem, how else can it be done?
EDIT: There was a question about what exactly I am try to do. I am writing a compiler. I want to accept an s-expression with variables closed in the lexical environment where the expression is defined. It may indeed be better to write it as a macro.
You need to create code that has the necessary bindings. Wrap a LET around your code and bind every variable you want to make available in your code:
(defvar *x* '(+ a 2))
(let ((a 4))
(eval `(let ((a ,a))
,*x*)))
CLISP implements an extension to evaluate a form in the lexical environment. From the fact that it is an extension, I suspect you can't do that in a standard-compliant way.
(ext:eval-env x (ext:the-environment))
See http://clisp.cons.org/impnotes.html#eval-environ.
What is the actual problem that you want to solve? Most likely, you're trying to tackle it the wrong way. Lexical bindings are for things that appear lexically within their scope, not for random stuff you get from outside.
Maybe you want a dynamic closure? Such a thing doesn't exist in Common Lisp, although it does in some Lisp dialects (like Pico Lisp, as far as I understand).
Note that you can do the following, which is similar:
(defvar *a*)
(defvar *x* '(+ *a* 2)) ;'
(let ((a 10))
;; ...
(let ((*a* a))
(eval *x*)))
I advise you to think hard about whether you really want this, though.
In Common Lisp you can define *evalhook* Which allows you to pass an environment to (eval ...). *evalhook* is platform independent.
It is possible to use COMPILE to compile the expression into function and then use PROGV to FUNCALL the compiled function in the environment where variables are dynamically set. Or, better, use COMPILE to compile the expression into function that accepts variables.
Compile accepts the function definition as a list and turns it into function. In case of SBCL, this function is compiled into machine code and will execute efficiently.
First option (using compile and progv):
(defvar *fn* (compile nil '(lambda () (+ a 2)))
(progv '(a) '(4) (funcall *fn*))
=>
6
Second option:
(defvar *fn* (compile nil '(lambda (a) (+ a 2))))
(funcall *fn* 4)
=>
6