I want to store a function like print
in a variable so that I can just type something short like p
, e.g:
In Scheme
:
(define print display)
(print "Hello world\n")
;; alternate way
(define print 'display)
((eval print) "Hello world\n")
The same approach does not seem to work in Common Lisp
:
(defvar p 'print)
;;(print (type-of p))
(p "Hello world") ;; Attempt 1
((eval p) "Hello world") ;; >> Attempt 2
((eval (environment) p) "Hello world") ;; Attempt 3
I'm getting this error with Attempt 1
above:
*** - EVAL: undefined function P
And this with Attempt 2
and 3
in Clisp
:
*** - EVAL: (EVAL (ENVIRONMENT) P) is not a function name; try using a
symbol instead
*** - EVAL: (EVAL P) is not a function name; try using a symbol instead
And with gcl
:
Error: (EVAL P) is invalid as a function.
Error: (EVAL (ENVIRONMENT) P) is invalid as a function.
So:
try using a symbol
mean? p
is definitely a symbol
; false positive? eval
? Doesn't the evaluation of p
yield the procedure print
?Lisp
procedures were first class objects
. Why is Attempt 1
not working like in Scheme
?EDIT
(Moved from a comment below)
I was wondering why (setf (symbol-function 'p) #'print)
won't work this way
(setf (symbol-function 'p) 'print)
. I get the following(not so helpful) error:
*** - SYSTEM::%PUTD: PRINT is not a function ;; CLisp
Error: PRINT is not of type LIST. ;; Gcl
I know that the sharp sign(#
) is supposed to disambiguate between a function and a variable
with the same name but in this case, there's only one print
, the function.
Also, why won't it work with defvar
instead of setf
like so:
(defvar (symbol-function 'p) #'print)
yet defvar
and setf
both assign values to a variable.
The associated error is:
*** - DEFVAR: non-symbol (SYMBOL-FUNCTION 'P) cannot be a variable ;; Clisp
Error: (SYMBOL-FUNCTION (QUOTE P)) is not of type SYMBOL. ;; Gcl
Common Lisp is a "Lisp-2". Among other things, the first position in a function call is evaluated in the "function namespace". In your case, the symbol p
names a variable, not a function.
This works better:
(defvar p 'print)
(funcall p "Hello world")
Or possibly, but you probably don't want to do this:
(setf (symbol-function 'p) #'print)
(p "Hello world")