In my experiments below I've abbreviated where the REPL returns an error, & added [num] so these can be referenced in discussion.
I'm a bit confused as to why my attempts to call a function stored in a variable are failing. It seems to me that the syntax is more complex than it needs to be.
Why can I issue neither (f 3) nor even (#'f 3)?
Is sharp quote not allowed as the first element of a form?
Why is funcall required here?
[235]> (setf f #'abs) ; I'm ok with this
#<SYSTEM-FUNCTION ABS>
[236]> (abs 3) ; This is fine
3
[237]> (f 3) ; Err due to sep. fn namespace. OK.
-- Err[1]: "Undefined function f" --
[238]> (#'f 3) ; Don't get what this err is telling me...
-- Err[2]: "#'F is not a function name, try using a symbol instead"
[239]> (funcall #'f 3) ; seems very long winded...!
3
Does this mean system functions are treated differently from user defined functions?
For completeness:
[240]> (funcall abs 3)
-- Err[3]: variable ABS has no value -- ; I get why this is an error.
[241]> (funcall #'abs 3) ; Isn't this verbose... ?
3
I haven't got to the symbols chapter in ANSI Common Lisp yet, maybe that will help... thanks for any tips.
[235]> (setf f #'abs) ; I'm ok with this
#<SYSTEM-FUNCTION ABS>
Above kind of sets a variable named f to a function object - from the function called abs.
[236]> (abs 3) ; This is fine
3
Above called the function abs.
[237]> (f 3) ; Err due to sep. fn namespace. OK.
Above: there is no function named f.
-- Err[1]: "Undefined function f" --
[238]> (#'f 3) ; Don't get what this err is telling me...
-- Err[2]: "#'F is not a function name, try using a symbol instead"
Above: Common Lisp accepts only symbols as function names, symbols as macro names, symbols as special operators or lambda expressions as the first element of a cons form. (function f) is not a function name.
Does this mean system functions are treated differently from user defined functions?
No.
[239]> (funcall #'f 3) ; seems very long winded...!
3
Above calls the function funcall with the function object from the named function f. funcall then calls this function object with 3 as the argument.
seems very long winded
It is.
Why can I issue neither (f 3) nor even (#'f 3)? Is sharp quote not allowed as the first element of a form?
Because f is not naming a function. It names a variable. #'f is also not a function name. We are required to use a function name (a symbol actually).
Namespaces
Common Lisp (like some other Lisp dialects) has two namespaces for functions and for variables.
Defining a variable foo:
CL-USER 54 > (defvar foo 3)
FOO
Defining a function foo:
CL-USER 55 > (defun foo (x) (* foo 10))
FOO
We can call the function foo with the value obtained from the variable foo:
CL-USER 56 > (foo foo)
30
How to get the function object from the global name of the function:
CL-USER 57 > (fdefinition 'foo)
#<interpreted function FOO 4060001CAC>
CL-USER 58 > (symbol-function 'foo)
#<interpreted function FOO 4060001CAC>
Same as above, but with a short notation:
CL-USER 58a > #'foo
#<interpreted function FOO 4060001CAC>
CL-USER 59 > (function foo) ; works also for local functions
#<interpreted function FOO 4230008AAC>
How to get a value from a global variable:
CL-USER 60 > (symbol-value 'foo)
3
Or just use the variable:
CL-USER 61 > foo
3
Some positives:
Positive: No name clashes.
We can write
(defun foo (list) (list list))
and don't have to write
(defun foo (lst) (list lst))
Positive: simpler compilation
(let ((list 3))
(list 1 list 3))
Above will never be an error in Common Lisp. In Scheme it would be an error: 3 is not a function.
Related
In my experiments below I've abbreviated where the REPL returns an error, & added [num] so these can be referenced in discussion.
I'm a bit confused as to why my attempts to call a function stored in a variable are failing. It seems to me that the syntax is more complex than it needs to be.
Why can I issue neither (f 3) nor even (#'f 3)?
Is sharp quote not allowed as the first element of a form?
Why is funcall required here?
[235]> (setf f #'abs) ; I'm ok with this
#<SYSTEM-FUNCTION ABS>
[236]> (abs 3) ; This is fine
3
[237]> (f 3) ; Err due to sep. fn namespace. OK.
-- Err[1]: "Undefined function f" --
[238]> (#'f 3) ; Don't get what this err is telling me...
-- Err[2]: "#'F is not a function name, try using a symbol instead"
[239]> (funcall #'f 3) ; seems very long winded...!
3
Does this mean system functions are treated differently from user defined functions?
For completeness:
[240]> (funcall abs 3)
-- Err[3]: variable ABS has no value -- ; I get why this is an error.
[241]> (funcall #'abs 3) ; Isn't this verbose... ?
3
I haven't got to the symbols chapter in ANSI Common Lisp yet, maybe that will help... thanks for any tips.
[235]> (setf f #'abs) ; I'm ok with this
#<SYSTEM-FUNCTION ABS>
Above kind of sets a variable named f to a function object - from the function called abs.
[236]> (abs 3) ; This is fine
3
Above called the function abs.
[237]> (f 3) ; Err due to sep. fn namespace. OK.
Above: there is no function named f.
-- Err[1]: "Undefined function f" --
[238]> (#'f 3) ; Don't get what this err is telling me...
-- Err[2]: "#'F is not a function name, try using a symbol instead"
Above: Common Lisp accepts only symbols as function names, symbols as macro names, symbols as special operators or lambda expressions as the first element of a cons form. (function f) is not a function name.
Does this mean system functions are treated differently from user defined functions?
No.
[239]> (funcall #'f 3) ; seems very long winded...!
3
Above calls the function funcall with the function object from the named function f. funcall then calls this function object with 3 as the argument.
seems very long winded
It is.
Why can I issue neither (f 3) nor even (#'f 3)? Is sharp quote not allowed as the first element of a form?
Because f is not naming a function. It names a variable. #'f is also not a function name. We are required to use a function name (a symbol actually).
Namespaces
Common Lisp (like some other Lisp dialects) has two namespaces for functions and for variables.
Defining a variable foo:
CL-USER 54 > (defvar foo 3)
FOO
Defining a function foo:
CL-USER 55 > (defun foo (x) (* foo 10))
FOO
We can call the function foo with the value obtained from the variable foo:
CL-USER 56 > (foo foo)
30
How to get the function object from the global name of the function:
CL-USER 57 > (fdefinition 'foo)
#<interpreted function FOO 4060001CAC>
CL-USER 58 > (symbol-function 'foo)
#<interpreted function FOO 4060001CAC>
Same as above, but with a short notation:
CL-USER 58a > #'foo
#<interpreted function FOO 4060001CAC>
CL-USER 59 > (function foo) ; works also for local functions
#<interpreted function FOO 4230008AAC>
How to get a value from a global variable:
CL-USER 60 > (symbol-value 'foo)
3
Or just use the variable:
CL-USER 61 > foo
3
Some positives:
Positive: No name clashes.
We can write
(defun foo (list) (list list))
and don't have to write
(defun foo (lst) (list lst))
Positive: simpler compilation
(let ((list 3))
(list 1 list 3))
Above will never be an error in Common Lisp. In Scheme it would be an error: 3 is not a function.
Let us suppose we have a function func1 :
(defun func1 (&rest values)
; (do something with values...)
(loop for i in values collect i))
Now, we have a function func2 which calls func1 :
(defun func2 (&rest values)
; (do something with values...)
(func1 ???))
What should I put instead of ??? to "copy" all the parameters of func2's values to func1's values ?
For instance, I would have the following behavior :
(func2 1 2 3 4) ; result is (1 2 3 4) and not ((1 2 3 4)).
In an earlier question I tried to do something like this :
(defun func2 (&rest values)
(macrolet ((my-macro (v)
`(list ,#v)))
(func1 (my-macro values))))
But the defun cannot get the value because it is not runtime. In this answer, he suggested that I use apply, but this function takes a &rest parameter too, so it doesn't solve my problem...
If possible, I would rather avoid to change the prototype of both functions, and the behavior of func1.
In common lisp, it has to be
(apply #'func1 values) ;; since `func1` has to be looked up in function namespace
remember, Clojure and Racket/Scheme are Lisp1, and common lisp is Lisp2.
Alternative solution (just for the sake)
I was asking myself, how to get it done without apply - just for the sake.
The problem with
`(func2 ,#values)
is, that if e.g.
(func2 (list 1 2 3) (list 4) 5)
is called, the values variable is ((1 2 3) (4) 5)
But when it is spliced into (func1 ,#values), what is created is
(func1 (1 2 3) (4) 5). But if we compare this with the func2 call,
it should be rather (func1 (list 1 2 3) (list 4) 5) which is perhaps not possible, because when (func2 (list 1 2 3) (list 4) 5) is called -
in the lisp manner - the arguments of func2 are each evaluated, before they enter the function body of func2, so we end up with values as a list of already evaluated arguments, namely ((1 2 3) (4) 5).
So somehow, concerning the arguments for func1 in the last expression, we are one evaluation-step offbeat.
But there is a solution with quote, that we manage to quote each of the arguments before giving it to func1 in the last expression, to "synchronize" the func1 function call - to let the arguments' evaluation pause for one round.
So my first aim was to generate a new values list inside the func2 body where each of the values list's argument is quoted (this is done in the let-binding).
And then at the end to splice this quoted-values list into the last expression: (func1 '(1 2 3) '(4) '5) which can be regarded as equivalent to (func1 (list 1 2 3) (list 4) 5) for this kind of problems / for this kind of calls.
This was achieved by this code:
(defun func2 (&rest vals)
(let ((quoted-values (loop for x in vals
collect `',x)))
; do sth with vals here - the func2 function -
(eval `(func1 ,#quoted-values))))
This is kind of a macro (it creates code btw. it organizes new code) but executed and created in run-time - not in pre-compile time. Using an eval we execute that generated code on the fly.
And like macroexpand-1, we can look at the result - the code - to which the func1 expression "expands", by removing eval around it - I call it func2-1:
(defun func2-1 (&rest vals)
(let ((quoted-values (loop for x in vals
collect `',x)))
; do sth with vals here - the func2 function -
`(func1 ,#quoted-values)))
And if we run it, it returns the last expression as code immediately before it is evluated in the func2 version:
(func2-1 (list 1 2 3) (list 4) 5)
;; (FUNC1 '(1 2 3) '(4) '5) ;; the returned code
;; the quoted arguments - like desired!
And this happens if we call it using func2 (so with evaluation of the func1 all:
(func2 (list 1 2 3) (list 4) 5)
;; ((1 2 3) (4) 5) ;; the result of (FUNC1 '(1 2 3) '(4) '5)
So I would say this is exactly what you desired!
lists vs. spread arguments
In Common Lisp it is good style to pass lists as lists and not as spread arguments:
(foo (list 1 2 3)) ; better interface
(foo 1 2 3) ; interface is not so good
The language has been defined in a way that efficient function calling can be used by a compiler and this means that the number of arguments which can be passed to a function is limited. There is a standard variable which will tell us how many arguments a particular implementation supports:
This is LispWorks on my Mac:
CL-USER 13 > call-arguments-limit
2047
Some implementations allow much larger number of arguments. But this number can be as low as 50 - for example ABCL, Common Lisp on the JVM, allows only 50 arguments.
Computing with argument lists
But sometimes we want the arguments as a list and then we can use the &rest parameter:
(lambda (&rest args)
(print args))
This is slightly in-efficient, since a list will be consed for the arguments. Usually Lisp tries to avoid to cons lists for arguments - they will be passed in registers or on the stack - if possible.
If we know that the argument list will not be used, then we can give the compiler a hint to use stack allocation - if possible:
(lambda (&rest args)
(declare (dynamic-extent args))
(reduce #'+ args))
In above function, the list of arguments can be deallocated when leaving the function - because the argument list is no longer used then.
If you want to pass these arguments to another function you can use FUNCALL and usually more useful APPLY:
(lambda (&rest args)
(funcall #'write (first args) (second args) (third args)))
or more useful:
(lambda (&rest args)
(apply #'write args))
One can also add additional arguments to APPLY before the list to apply:
CL-USER 19 > ((lambda (&rest args)
(apply #'write
(first args) ; the object
:case :downcase ; additional args
(rest args))
(values))
'(defun foo () 'bar)
:pretty t
:right-margin 15)
(defun foo ()
'bar)
There is the infix package for common lisp (see http://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/lang/lisp/code/syntax/infix/infix.cl), which transforms infix form to prefix.
For example:
(string->prefix "1+2") ;; => (+ 1 2)
It also provides the reader macro #I, which can evaluate an infix form, e.g.,
#I(1+2) ;; => 3
But I don't want to use this reader macro.
I have written a simple function, which uses cl-ppcre, to substitute a string with a number, i.e.,
(prepare-form "1+x*x" "x" 3) ;; => "1+3*3"
Finally, I have a function which evaluates the infix form
(defun eval-infix (form &rest args)
(eval (string->prefix (apply #'prepare-form form args))))
Can the function eval-infix be implemented without using the eval function?
My final goal is to call eval-infix like this:
(eval-infix "1+x*x" "x" (+ 1 2))
Well I think what you want to use is string->prefix. This will intern symbols so to avoid polluting your own package lets define one. Finally you can avoid the security problems of eval by defining your own eval. There is still a problem where symbols from other packages can be written and this makes me sad. There is also the problem that the infix reader can escape to the Lisp reader which can do arbitrary evaluation. Here is a sketch of the parts of the solution. I’ve probably got the arguments for some functions in the wrong order.
(defpackage infix-vars)
(defun read-infix-string (s) (let ((*package* (find-package "INFIX-VARS"))) (string->prefix s)))
(defun substitute-var (expr v val)
(let ((v (etypecase v (symbol v) (string (intern v (find-package "INFIX-VARS"))))))
(subst expr v val)))
(defun eval-expr (e)
(etypecase e
(number e)
(list
(ecase (car e)
(+ (apply #'+ (mapcar #'eval-expr (cdr e))))))))
On page 329 of Land of Lisp, Conrad Barski explains the technique of memoization with the following example code
(let ((old-neighbors (symbol-function 'neighbors))
(previous (make-hash-table)))
(defun neighbors (pos)
(or (gethash pos previous)
(setf (gethash pos previous) (funcall old-neighbors pos)))))
The idea is nice: when I call the neighbors function, I save the result into a hash table, so that the next time calling neighbors with the same value of pos, I can just look-up the result without having to compute it again.
So I was wondering, whether it would not be easier to rename the function neighbors to old-neighbors by editing and recompiling its source code (given on page 314 of the book). Then the memoization example could be simplified to
(let ((previous (make-hash-table)))
(defun neighbors (pos)
(or (gethash pos previous)
(setf (gethash pos previous) (funcall old-neighbors pos)))))
or, by turning previous into a global variable *previous-neighbors* beforehand, even into
(defun neighbors (pos)
(or (gethash pos *previous-neighbors*)
(setf (gethash pos *previous-neighbors*) (funcall old-neighbors pos))))
thus rendering the closure unnecessary.
So my question is: what is the reason for doing it this way?
Reasons I could imagine:
It's didactical, showing what could be done with a closure (which had been explained just before) and providing an example of symbol-function.
This technique is applicable even in situations, where you cannot or may not change the source code of neighbors.
I am missing something.
You have made some good observations.
Generally the style to use closures like that is more likely to be found in Scheme code - where Scheme developers often use functions to return functions.
Generally as you have detected it makes little sense to have a memoize function foo calling an function old-foo. Using global variables reduces encapsulation (-> information hiding), but increases the ability to debug a program, since one can more easily inspect the memoized values.
A similar, but potentially more useful, pattern would be this:
(defun foo (bar)
<does some expensive computation>)
(memoize 'foo)
Where ˋmemoizeˋ would be something like this
(defun memoize (symbol)
(let ((original-function (symbol-function symbol))
(values (make-hash-table)))
(setf (symbol-function symbol)
(lambda (arg &rest args)
(or (gethash arg values)
(setf (gethash arg values)
(apply original-function arg args)))))))
The advantage is that you don't need to write the memoizing code for each function. You only need one function memoize. In this case the closure also makes sense - though you could also have a global table storing memoize tables.
Note the limitations of above: the comparison uses EQL and only the first argument of the function to memoize.
There are also more extensive tools to provide similar functionality.
See for example:
https://github.com/fare/fare-memoization
https://github.com/sharplispers/cormanlisp/blob/master/examples/memoize.lisp
https://github.com/AccelerationNet/function-cache
Using my memoize from above:
CL-USER 22 > (defun foo (n)
(sleep 3)
(expt 2 n))
FOO
CL-USER 23 > (memoize 'foo)
#<Closure 1 subfunction of MEMOIZE 40600008EC>
The first call with arg 10 runs three seconds:
CL-USER 24 > (foo 10)
1024
The second call with arg 10 runs faster:
CL-USER 25 > (foo 10)
1024
The first call with arg 2 runs three seconds:
CL-USER 26 > (foo 2)
4
The second call with arg 2 runs faster:
CL-USER 27 > (foo 2)
4
The third call with arg 10 runs fast:
CL-USER 28 > (foo 10)
1024
Say I have a function foo:
(defun foo (x y &rest args)
...)
And I later want to wrap it with a function bar:
(defun bar (x &rest args)
(foo x 100 args))
Assume bar was then called like this: (bar 50 1 2 3)
With this setup, args is a list within the body of bar that holds the trailing parameters, so when I pass it to foo, instead of getting the equivalent of (foo 50 100 1 2 3) I of course get (foo 50 100 '(1 2 3)). If these were macros, I would use ``(foo ,x 100 ,#args)` within the body of bar to splice args into the function call. ,# only works inside a backtick-quoted list, however.
How can I do this same sort of splicing within a regular function?
APPLY will call its first argument with its subsequent arguments, and the last argument must be a list. So:
(apply #'foo x 100 args)
This method is slow, but it may be what you're looking for.
Backquotes, commas, and comma-ats aren't only for macros. They can also be used in functions if you use eval too. Again, this is not fast or efficient. At any rate, here it is:
(defun bar (x &rest args)
(eval `(foo ,x 100 ,#args)))