Writing a macro that has a named symbol correctly - macros

The problem with the following code is multiple evaluation:
(defmacro with-object (name &body body)
`(let ((,name (create-object)))
,#body
(free-object ,name)))
but I don't know how to do this the right way.

In order to use name in the let binding in your code, it has to hold a symbol. There should be no multiple evaluation problem in the code you supplied, since the symbol held by name is just given a binding in the expansion and evaluated for the free-object call within the context of that binding.

Related

Implement Lisp eval function in Common Lisp

I am trying to implement a eval function using CLISP.
My motivation: suppose I have a Lisp program like this:
(defun call (arg)
(cond
(some-condition (call (other (strange (functions (on arg)))))
(t nil)
)
)
(defun mysterious-function (arg)
(call (strange (functions (on arg))))
)
(mysterious-function 100) ; only this line can be changed
I want to know what is actually called in (mysterious-function 100).
Currently my idea looks like below, but the obstacles are:
How to look up a symbol (currently using eval)
How to grab a definition of a function (e.g. get something like (defun f (x))) and then parse it
How to detect macro and expand them
Am I in the correct direction?
(defun my-eval (body)
(cond
((typep body 'integer) body)
((typep body 'float) body)
((typep body 'rational) body)
((typep body 'complex) body)
((typep body 'boolean) body)
((typep body 'symbol) (eval body))
((typep body 'list) (eval body))
(t (error))
)
)
(my-eval '(mysterious-function 100))
Most of the cases in your code can be replaced with a single check: ((constantp body) body)
As for other cases:
You can use boundp to check if a symbol has a global value.
To look up a global symbol value you can use symbol-value.
fboundp can be used to check if a symbol is globally bound to a function
To look up a global function you can use symbol-function to access its function object and can sometimes use function-lambda-expression to retrieve a parseable source code list from the function object. Sometimes this will not work as built in CLISP functions can be defined in C.
To check if a symbol has an associated global macro, use macro-function (returns non-nil if it does).
To expand a macro form, use macroexpand.
You will probably also need to detect special operators with special-operator-p, and handle them accordingly.
I think what you are trying to do would be simplified if you restrict the code you interpret to macros and user-defined functions as much as possible.
I remember reading about a fast-eval function used in genetic programming to skip the macroexpansion phase of evaluating code, and its approach looked similar to what you seem to have in mind.

Why does this common lisp macro not evaluate the first s-exp?

I studied define-easy-handler macro from the hunchentoot package (which creates a function with the name NAME), and got the defun part to work, but I can't get this macro to push NAME to a list called *observers*:
(defmacro add-observer (name params &body body)
;; add NAME to the list *observers*
`(push ,name *observers*)
;; define a lisp function with the name NAME
;; with key arguments given in PARAMS
`(defun ,name (&key ,#(loop for p in params
collect p))
,#body)))
An example call to #'add-observer is:
(add-observer below-80 (id blood-sugar)
(when (< blood-sugar 80)
(format t "Patient No: ~A is hypoglycemic." id))
The function NAME is defined and works fine, but the NAME is not added to the list *observers*. It does not matter if I put both s-expressions inside a progn or not. The macroexpand clearly shows the absence of the call to push with and without a progn. What am I interpreting wrong?
EDIT
When I try this with a progn like:
`(progn
(push ...
(defn ...
it fails with Unbound variable: below-80. And when I put the backquotes back to the #'push and #'defun, again #'push doesn't work.
The macro gets the source form and computes the first result form: (push foo *observers*) and then this form is returned into the nirvana of the garbage collector, since it is not stored anywhere, not returned to any caller, not executed, ... It's garbage, immediately. So a clever compiler might even remove it...
The macro form then computes the second form (defun ...). This form is returned from the macro and then later executed.
Either you want to execute the first form at macro expansion time, then you would need to make it executable - by removing the backquote and comma.
Or you want to include it into the generated source code, then you need to return a progn form, which encloses all the sub-forms.
You also might want to think about the effects of PUSH vs. PUSHNEW, when a macro form gets executed / expanded multiple times...
Unwanted evaluation of symbols when using macros
Remember: symbols are variables in Lisp code. If you want to treat them as symbols as themselves, then you need to quote the symbol or the data structure, where they occur.
Say, your form is:
(add-observer below-80 ...)
That meansbelow-80 is unquoted.
Now you generate code where the symbol is unquoted, too.:
(push below-80 ...)
Naturally, this tries to evaluate the variable below-80, which seems to be unbound in your code.
If you want below-80 treated to be a symbol during evaluation, you have to quote it: 'below-80. Your generated code should look like this:
(push 'below-80 ...)
Quote it either in your code
(add-observer 'below-80 ...)
or by the macro into the expansion:
(push 'below-80 ...)
The backquote template for that is
`(progn
(push ',name ...)
...)

Macro that defines functions whose names are based on the macro's arguments

*Note: Despite having frequented StackOverflow for a long time, this is the first question that I have posted myself. Apologies if it's a bit verbose. Constructive criticism appreciated.
When I define a struct in Common Lisp using defstruct, a predicate function is automatically generated that tests whether its argument is of the type defined by the defstruct. Eg:
(defstruct book
title
author)
(let ((huck-finn (make-book :title "The Adventures of Huckleberry Finn" :author "Mark Twain")))
(book-p huck-finn))
=> True
However, when defining a class using defclass, such functions are seemingly not generated by default (is there a way to specify this?), so I'm trying to add this functionality myself, because I'd like a) for this syntax to be consistent between structs and classes, b) to have an abbreviation of (typep obj 'classname), which I need to write very often and is visually noisy,
and c) as a programming exercise, since I'm still relatively new to Lisp.
I could write a macro that defines a predicate function given the name of a class:
(defclass book ()
((title :initarg :title
:accessor title)
(author :initarg :author
:accessor author)))
;This...
(defmacro gen-predicate (classname)
...)
;...should expand to this...
(defun book-p (obj)
(typep obj 'book))
;...when called like this:
(gen-predicate 'book)
The name that I need to pass to defun must be of the form 'classname-p. Here's where I have difficulty. To create such a symbol, I could use the "symb" function from Paul Graham's On Lisp (p. 58). When it is run on the REPL:
(symb 'book '-p)
=> BOOK-P
My gen-predicate macro looks like this so far:
(defmacro gen-predicate (classname)
`(defun ,(symb classname '-p) (obj)
(typep obj ,classname)))
(macroexpand `(gen-predicate 'book))
=>
(PROGN
(EVAL-WHEN (:COMPILE-TOPLEVEL) (SB-C:%COMPILER-DEFUN '|'BOOK-P| 'NIL T))
(SB-IMPL::%DEFUN '|'BOOK-P|
(SB-INT:NAMED-LAMBDA |'BOOK-P|
(OBJ)
(BLOCK |'BOOK-P| (TYPEP OBJ 'BOOK)))
NIL 'NIL (SB-C:SOURCE-LOCATION)))
T
It would seem that the symbol created by (symb 'book '-p) is actually considered |'BOOK-P| by the implementation (SBCL), not BOOK-P. Sure enough, this now works:
(let ((huck-finn (make-instance 'book)))
(|'BOOK-P| huck-finn))
=> True
Why is the symbol created by symb interned as |'BOOK-P|? In On Lisp (same page as above) Graham says: "Any string can be the print-name of a symbol, even a string containing lowercase letters or macro characters like parentheses. When a symbol's name contains such oddities, it is printed within vertical bars." No such oddities exist in this case, do they? And am I correct in thinking that the "print-name" of a symbol is what is actually displayed on the standard output when the symbol is printed, and is, in the case of such oddities, distinct from the form of the symbol itself?
To be able to write function-defining macros like gen-predicate - whose defined functions are named based on the arguments passed to the macro - seems to me like something that Lisp hackers have probably been doing for ages. User Kaz says here (Merging symbols in common lisp) that the "mashing-up" of symbols can often be avoided, but that would defeat the purpose of this macro.
Finally, assuming I could get gen-predicate to work how I want, what would be the best way of ensuring that it be called for each new class as they are defined? Much in the same way as initialize-instance can be customized to perform certain actions upon instantiation of a class, is there a generic function called by defclass that can perform actions upon definition of a class?
Thank you.
That's a usual problem: what gets passed to a Macro?
Compare calls like this:
(symb 'book '-p)
and
(symb ''book '-p)
Your macro form is this:
(gen-predicate 'book)
GEN-PREDICATE is a macro. classname is a parameter for this macro.
Now what is the value of classname inside the macro during code expansion? Is it book or 'book?
Actually it is the latter, because you wrote (gen-predicate 'book). Remember: macros see source code and the argument source gets passed to the macro function - not the value. The argument is 'book. Thus this gets passed. (QUOTE BOOK) is the same, only printed differently. So it is a two element list. The first element is the symbol QUOTE and the second element is the symbol BOOK.
Thus the macro now calls the function SYMB with the argument value (QUOTE BOOK) or, shorter, 'BOOK.
If you want to generate the predicate without the quote character, you need to write:
(gen-predicate book)
Alternatively you can also change the macro:
(symb classname '-p)
would be:
(symbol (if (and (consp classname)
(eq (first classname) 'quote))
(second classname)
classname))
Compare
We write
(defun foo () 'bar)
and not
(defun 'foo () 'bar) ; note the quoted FOO
DEFUN is a macro and the first argument is the function name. It's a similar problem then...
Second part of the question
I don't really know any good answer to that. I can't remember any easy way to run code (for example to define a function) after a class definition.
Maybe use the MOP, but that's ugly.
write a custom macro DEFINE-CLASS which does what you want: expands into DEFCLASS and the DEFUN.
iterate over all symbols in a package, find the classes and define the corresponding predicates
To address the second part of the question, classes are themselves objects, thanks to the MOP, so it might be possible to write an :after method on initialize-instance specialized on STANDARD-CLASS. But you should check the MOP to see whether defining such a method is allowed or not.
If it's possible, then yes, you can run code in response to the creation of a class; however, since you don't know the name of the class being created until runtime, you cannot spell it textually in the source, so you cannot use your macro (unless you use eval). You'd rather use something like
(let ((classname (class-name class)))
(compile (generate-my-predicate-symbol classname)
(lambda (x) (typep x classname))))
I think Rainer's suggestion to write your own DEFINE-CLASS macro is the way to go, I mean, the way a seasoned Lisper most likely would do it, if there aren't any other considerations at play. But I'm not really a seasoned Lisper, so I might be wrong ;)

Why a parameter of an Emacs lisp function is not evaluated?

I want to define a list of accumulators with Emacs Lisp and write the following code, but I got a error saying that initV is a void variable. It seems initV is not evaluated in the function define-accum. Where is I make a mistake? (I just want to know why although I know there is other ways to reach my target.)
(defun define-accum (name initV)
(defalias name (lambda (v) (+ v initV))))
(setq accums '((myadd1 . 1)
(myadd2 . 2)))
(dolist (a accums)
(define-accum (car a) (cdr a)))
(message "result = %d" (+ (myadd1 1) (myadd2 1)))
You need to use backquotes properly. This would work for you, for instance:
(defun define-accum (name initV)
(defalias name `(lambda (v) (+ v ,initV))))
See here for an explanation
Apart from using backquotes, you can activate lexical binding (if you're using Emacs 24 or newer). For example, if I put your code in a .el file and put this on the first line:
;; -*- lexical-binding: t -*-
then I get the output:
result = 5
This works because the lambda function in define-accum will reference the initV in the environment where it's being defined (thus picking the variable in the argument list), and create a closure over this variable. With dynamic binding (the default), the function would look for initV in the environment where it's being called.
To add a little to what others have said -
If the variable (initV) is never actually used as a variable, so that in fact its value at the time the accumulator is defined is all that is needed, then there is no need for the lexical closure that encapsulates that variable and its value. In that case, the approach described by #juanleon is sufficient: it uses only the value at definition time - the variable does not exist when the function is invoked (as you discovered).
On the other hand, the lexical-closure approach lets the function be byte-compiled. In the backquote approach, the function is simply represented at runtime by a list that represents a lambda form. If the lambda form represents costly code then it can make sense to use the lexical-closure approach, even though (in this case) the variable is not really needed (as a variable).
But you can always explicitly byte-compile the function (e.g. ##NAME## in your define-accum. That will take care of the inefficiency mentioned in #2, above.

Scheme syntax-rules - Difference in variable bindings between (let) and (define)

The R5RS spec states that as part of the requirements for a macro defined using syntax-rules:
If a macro transformer inserts a free reference to an identifier, the reference refers to the binding that was visible where the transformer was specified, regardless of any local bindings that may surround the use of the macro.
I am trying to understand how this works in practice. So for example, if I have the following code:
(define var 'original)
(define-syntax test-var
(syntax-rules (var)
((_ var)
var)
((_ pattern-var)
'no-match)))
I would expect the following, if executed immediately after, to evaluate to original, which it does:
(test-var var)
And I would expect this one to be no-match since the var introduced into scope prior to test-var does not match the binding of var at macro definition:
(let ((var 1)) (test-var var))
However the following example has me puzzled:
(define var 'new-var)
(test-var var)
In Chicken Scheme, this evaluates to new-var. I would have expected it to be no-match for the same reasons as the previous (let) example. I thought that perhaps this was an issue with using define twice, but the result is still new-var even if I use (set! var 'new-var)
Does anyone have any insight as to what is going on here? What should happen per R5RS?
This is the usual trick that Schemes have when dealing with redefinitions on the REPL -- treating them as a mutation for the existing binding. So the second define is not really creating a new binding, and instead it just set!s the existing one.