Let's assume that I got the following macro:
(defmacro my-check (number)
`(> 3 ,(apply #'+ number)))
How can I call this macro in a function?
I tried,for example, the following function:
(defun do-test (my-object)
(my-check my-object)))
but I get the following error when compiling:
during macroexpansion of (MY-CHECK MY-OBJECT). Use *BREAK-ON-SIGNALS* to
intercept.
The value MY-OBJECT is not of type LIST.
The comma in your macro is in the wrong place. It is trying to evaluate the entire (apply ...) during macroexpansion, which of course fails since number is a symbol rather than a list. Remember that macros are expanded during compilation, not at run-time.
The correct version would be:
(defmacro my-check (number)
`(> 3 (apply #'+ ,number)))
Related
I've been trying to write a recursive loop in clojure that will print me out the very last number in the list. The point is not that I need to get the last number (for which I'm sure there's a built in function for that) but that I want to better understand recursion and macros in clojure. So I have this macro...
(defmacro loop-do [the-list]
`(if (= (count '~the-list) 1)
(println (first '~the-list))
(loop-do (rest '~the-list))))
But I get a stackoverflow error. What am I doing wrong?
How will people use your macro?
Somewhere, someone will call:
(loop-do list)
As a piece of code, those are only two symbols in a list. The first one is recognized as your macro, and the second one, list, is a symbol that represents a variable that will be bound at runtime. But your macro only knows that this is a symbol.
The same goes for:
(loop-do (compute-something))
The argument is a form, but you do not want to get the last element of that form, only the last element of the list obtained after evaluating the code.
So: you only know that in your macro, the-list will be bound to an expression that, at runtime, will have to be a list. You cannot use the-list as-if it was a list itself: neither (count 'list) nor (count '(compute-something)) does what you want.
You could expand into (count list) or (count (compute-something)), though, but the result would only be computed at runtime. The job of the macro is only to produce code.
Recursive macros
Macros are not recursive: they expand into recursive calls.
(and a b c)
might expand as:
(let [a0 a] (if a0 a0 (and b c)))
The macroexpansion process is a fixpoint that should terminate, but the macro does not call itself (what would that mean, would you expand the code while defining the macro?). A macro that is "recursive" as-in "expands into recursive invocations" should have a base case where it does not expand into itself (independently of what will, or will not, happen at runtime).
(loop-do x)
... will be replaced by:
(loop-do (rest 'x))
... and that will be expanded again.
That's why the comments say the size actually grows, and that's why you have a stackoverflow error: macroexpansion never finds a fixpoint.
Debugging macros
You have a stackoverflow error. How do you debug that?
Use macroexpand-1, which only performs one pass of macroexpansion:
(macroexpand-1 '(loop-do x))
=> (if (clojure.core/= (clojure.core/count (quote x)) 1)
(clojure.core/println (clojure.core/first (quote x)))
(user/loop-do (clojure.core/rest (quote x))))
You can see that the generated code still contains a call to usr/loop-do , but that the argument is (clojure.core/rest (quote x)). That's the symptom you should be looking for.
Consider this question. Here the basic problem is the code:
(progv '(op arg) '(1+ 1)
(eval '(op arg)))
The problem here is that progv binds the value to the variable as variable's symbol-value not symbol-function. But, that's obvious because we didn't explicitly suggest which values are functions.
The Plan
So, in order to solve this problem, I thought of manually dynamically binding the variables, to their values based on the type of values. If the values are fboundp then they should be bound to the symbol-function of the variable. A restriction, is that match-if can't be a macro. It has to be a function, because it is called by a funcall.
Macro : functioner:
(defmacro functioner (var val)
`(if (and (symbolp ',val)
(fboundp ',val))
(setf (symbol-function ',var) #',val)
(setf ,var ,val)))
Function: match-if:
(defun match-if (pattern input bindings)
(eval `(and (let ,(mapcar #'(lambda (x) (list (car x))) bindings)
(declare (special ,# (mapcar #'car bindings)))
(loop for i in ',bindings
do (eval `(functioner ,(first i) ,(rest i))))
(eval (second (first ,pattern))))
(pat-match (rest ,pattern) ,input ,bindings))))
Here, the let part declares all the variables lexically (supposedly). Then declare declares them special. Then functioner binds the variables and their values aptly. Then the code in the pattern is evaluated. If the code part is true, then only the pattern-matcher function pat-match is invoked.
The Problem
The problem is that in the function, all it's arguments are evaluated. Thus bindings in the let and declare parts will be replaced by something like :
((v1 . val1)(v2 . val2)(v3 . val3))
not
'((v1 . val1)(v2 . val2)(v3 . val3))
So, it's treated as code, not a list.
So, I'm stuck here. And macros won't help me on this one.
Any help appreciated.
Not the answer you are looking for, but PROGV is a special operator; it is granted the ability to modify the dynamic bindings of variables at runtime; AFAIK, you can't simply hack it to operate on "dynamic function bindings".
The point of progv is to use list of symbols and values that are evaluated, meaning that you can generate symbols at runtime and bind them dynamically to the corresponding values.
You might be able to find a solution with eval but note that if you macroexpand into (eval ...), then you loose the surrounding lexical context, which is generally not what you want ("eval" operates on the null lexical environment). I speculate that you could also have a custom code walker which works on top-level forms but reorganizes them, when it finds your special operator, to bring the context back in, producing something like (eval '(let (...) ...)).
Why doesn't this work?
( ((lambda () (lambda (x) (funcall #'1+ x)))) 2)
; yields Compile-time error: illegal function call
I ran into a situation like this and it later turned out that a funcall fixes it, i.e.
(funcall ((lambda () (lambda (x) (funcall #'1+ x)))) 2) ; => 3
I'm confused because it seems like the first one should work, because I actually have a function I'm calling, not just a symbol that may belong to either namespace (i.e. (type-of ((lambda () #'1+))) ; => FUNCTION). I thought it would be kind of like how you don't need to funcall a lambda for example, e.g.((lambda (x) x) :HI) ; => :HI. What am I missing?
Common Lisp uses the word form for everything which can be evaluated.
A form is either
a symbol like foo
a compound form, a list, see below
or a self-evaluating object (like numbers, characters, arrays, strings, ...).
A compound form is either
a special form (<special-operator> ...)
a lambda form like (lambda (...) ...)
a macro form (<macroname> ...)
or a function form (<functionname> ...).
Above is the set of compound forms. The ANSI Common Lisp specification provides no way to add a new type of forms or a different syntax. The interface of what forms the functions like EVAL or COMPILE accept is not extensible.
So something like
(((lambda (foo)
(lambda (bar)
(list foo bar)))
1)
2)
is not valid Common Lisp. This is not meaningful in Common Lisp:
( <not a lambda form,
not a special operator,
not a macro name
and not a function name>
2)
Note that Common Lisp allows lambda forms, special operators, macro names and function names as the first element in a compound form. But it does not allow variables and it does not allow other compound forms as the first element in a compound form.
Means this is not meaningful in Common Lisp:
( <a function form> 2)
Thus ((foo 1) 2) or (((foo 1) 2) 3) or ((((foo 1) 2) 3) 4) or (((((foo 1) 2) 3) 4) 5) is not legal in Common Lisp. You get the idea. To call function objects returned from function calls, we have to use (funcall (foo ...) ...). This makes calling returned function objects more obvious than just ((foo ...) ...).
Let's praise the designers of Common Lisp for this feature. Otherwise I might have to look at possibly meaningful code beginning with
(((((((((((( .....
and it would be very hard to figure out what it does. Basically that would be write-only code.
Your question:
Why must I funcall a function returned from another?
The short answer: because the syntax does not allow other ways, in Common Lisp.
The syntax of Common Lisp requires that, everytime you want to call a function through a compund form of the type:
(f a1 a2 ... an)
the first element of the list, f, must be a symbol denoting a function name, or a list denoting a lambda expression, i.e. (see the manual):
lambda expression n. a list which can be used in place of a function name in certain contexts to denote a function by directly describing its behavior rather than indirectly by referring to the name of an established function; its name derives from the fact that its first element is the symbol lambda.
So, this basically means that you cannot have as first element any expression that returns a function as value. In those cases, you must use funcall.
So, in your second example, the first argument of the funcall is ((lambda () (lambda (x) (funcall #'1+ x)))), which is a correct coumpound form, in which the first element of the list is the lambda expression (lambda () (lambda (x) (funcall #'1+ x))) (applied to an empty list of arguments).
In the first example, instead, you have as first element of the list an expression returning a function, so that you must use funcall.
I have read this article and then modified my code below:
(defparameter *my-fun* 1)
(defun my-func (v0)
(setf (symbol-function '*my-fun*)
(lambda (v1)
(+ v0 v1)))
'*my-fun*)
And call it in this way ((my-func 2) 3),but it also report "illegal function call". I think my code is keeping with lambda calculus,but where is wrong.
In my opinion, (my-func 2) returns symbol *my_fun*, and the function cell of *my-fun* points to a function object, so ((my-func 2) 3) => (*my-fun* 3) => ((lambda (v1) (+ 2 v1)) 3) => (+ 2 3) => 5
This works: First your identical definitions:
(defparameter *my-fun* 1)
(defun my-func (v0)
(setf (symbol-function '*my-fun*)
(lambda (v1)
(+ v0 v1)))
'*my-fun*)
However, invoke using funcall:
(funcall (my-func 2) 3)
I thought I would be able to find this through Google, SO, or the books I'm reading, but it is proving elusive.
In the implementation I'm learning with, I can do the following at the top-level:
(defvar *foo* 4)
(set 'bar 3)
If I then call (describe '*foo*) and (describe 'bar), I get a description saying that *foo* is special and bar is non-special (among other details).
Is there a function that takes a symbol variable as an argument and returns true or false if it is special? If so, is describe probably implemented in part by calling it?
Context: I'm learning Common Lisp, but at work I have a system with a dialect of Lisp similar to Common Lisp, but the describe function is unimplemented. There's sort of an XY thing going on here, but I'm also trying to grok Lisp and CL.
Many Common Lisp implementations provide the function variable-information in some system dependent package.
Here in SBCL:
* (require :sb-cltl2)
NIL
* (sb-cltl2:variable-information '*standard-output*)
:SPECIAL
NIL
((TYPE . STREAM))
This function was proposed as part of some other functionality to be included into ANSI CL, but didn't make it into the standard. Still many implementations have it. For documentation see: https://www.cs.cmu.edu/Groups/AI/html/cltl/clm/node102.html
A non-special variable's environment will be captured when you create a closure over it:
(let ((x 1))
(let ((f (lambda () x)))
(let ((x 2))
(eql 2 (funcall f)))))
;;=> NIL
A special variable's lexical environment will not:
(defvar *x*) ; *x* is special
(let ((*x* 1))
(let ((f (lambda () *x*)))
(let ((*x* 2))
(eql 2 (funcall f)))))
;;=> T
Using this approach, you could easily define a macro that will expand to code like the previous that will let you determine whether a symbol is globally proclaimed special:
(defmacro specialp (symbol)
(let ((f (gensym "FUNC-")))
`(let ((,symbol 1))
(let ((,f (lambda () ,symbol)))
(let ((,symbol 2))
(eql 2 (funcall ,f)))))))
(specialp x) ;=> NIL
(specialp *x*) ;=> T
Note that this isn't a function, it's a macro. That means that the macro function for specialp is getting called with the symbols X and *X*. This is important, because we have to construct code that uses these symbols. You can't do this with a function, because there'd be no (portable) way to take a symbol and create a lexical environment that has a lexical variable with that name and a lambda function that refers to it.
This also has some risks if you try to use it with certain symbols. For instance, in SBCL, if you try to bind, e.g., *standard-output* to something that isn't a stream or a stream designator, you'll get an error:
CL-USER> (specialp *standard-output*)
; in: SPECIALP *STANDARD-OUTPUT*
; (LET ((*STANDARD-OUTPUT* 1))
; (LET ((#:FUNC-1038 (LAMBDA # *STANDARD-OUTPUT*)))
; (LET ((*STANDARD-OUTPUT* 2))
; (EQL 2 (FUNCALL #:FUNC-1038)))))
;
; caught WARNING:
; Constant 1 conflicts with its asserted type STREAM.
; See also:
; The SBCL Manual, Node "Handling of Types"
;
; compilation unit finished
; caught 1 WARNING condition
Defining globals with set or setq is not supported. There are 2 common ways to define globals:
(defparameter *par* 20) ; notice the earmuffs in the name!
(defvar *var* 30) ; notice the earmuffs in the name!
All global variables are special. Lexically scoped variables (not special) are not possible to get described. E.g.
(let ((x 10))
(describe 'x)) ; ==> X is the symbol X
It describes not the lexical variable but the symbol representation. It really doesn't matter since you probably never need to know in run time since you know this when you're writing if it's a bound lexical variable or global special by conforming to the earmuffs naming convention for global variables.
I believe the only way to get this information at run time* is by either using an extension to CL, as Rainer noted, or to use eval.
(defun specialp (x)
(or (boundp x)
(eval `(let (,x)
(declare (ignorable ,x))
(boundp ',x)))))
(Defect warning: If the variable is unbound but declared to be a type incompatible with nil, this could raise an error. Thanks Joshua for pointing it out in his answer.)
* The macro approach determines which symbol it is checking at macro expansion time, and whether that symbol is lexical or special at compile time. That's fine for checking the status of a variable at the repl. If you wanted to e.g. print all of the special variables exported by a package, though, you would find that to use the macro version you would end up having to use eval at the call site:
(loop for s being the external-symbols of :cl-ppcre
when (eval `(specialp-macro ,s)) do (print s))
Can someone explain why I get different results for the following simple program with sbcl and clisp? Is what I am doing undefined by the language, or is one of the two lisp interpreters wrong?
; Modify the car of the passed-in list
(defun modify (a) (setf (car a) 123))
; Create a list and print car before and after calling modify
(defun testit () (let ((a '(0)))
(print (car a))
(modify a)
(print (car a))))
(testit)
SBCL (version 1.0.51) produces:
0
0
CLISP (version 2.49) produces (what I would expect):
0
123
I agree with Seth's and Vsevolod's comments in that this behavior is due to your modification of literal data. Try using (list 0) instead of '(0). Questions relating to this come up relatively frequently, so I'll quote the HyperSpec here.
3.7.1 Modification of Literal Objects:
The consequences are undefined if literal objects are destructively
modified.
The definition of "literal":
literal adj. (of an object) referenced directly in a program rather
than being computed by the program; that is, appearing as data in a
quote form, or, if the object is a self-evaluating object, appearing
as unquoted data. ``In the form (cons "one" '("two")), the expressions
"one", ("two"), and "two" are literal objects.''
Note that often (in many implementations), if you modify literal values, you'll really modify them in the code itself – writing self modifying code. Your example code will not work as you expect.
Your example code in CCL:
CL-USER> (defun modify (a) (setf (car a) 123))
MODIFY
CL-USER> (defun testit ()
(let ((a '(0)))
(print (car a))
(modify a)
(print (car a))))
TESTIT
CL-USER> (testit)
0
123
123
CL-USER> (testit)
123
123
123
Take a look at the second evaluation of testit, where the let itself really already contains the modified value, thus the first print also yields 123.
Also see: Lisp, cons and (number . number) difference, where I explained this in more detail, or the question linked in Vsevolod's comment above.