Eval

Discussion of Common Lisp

Eval

Postby Indecipherable » Sat Jul 30, 2011 3:01 am

So far I could replicate any macro by using (eval) in a function. I have to add quotes when I call the function though, but I feel like I've began to understand macros and now I am back at square 1. Could anyone give me an example of a macro where eval won't work?

e.g

Code: Select all
(defmacro setvar-m (var value)
 `(setf ,var ,value))

(defun setvar-f (var value)
 (eval
 `(setf ,var ,value)))

[3]> (setvar-m a 5)

5

(setvar-f 'v 7)

7


I also had trouble creating a macro out of this since it expanded into a wrong form:

Code: Select all
(defun lvar (vlist)
 (loop
  for sub in vlist doing
   (eval
   `(setf ,(first sub) ,(second sub)))
   (format t "~%~a : ~a~%" (first sub) (second sub))))
Don't take the FUN out of DEFUN !
User avatar
Indecipherable
 
Posts: 47
Joined: Fri Jun 03, 2011 5:30 am
Location: Behind you.

Re: Eval

Postby Paul » Sat Jul 30, 2011 5:02 am

Indecipherable wrote:So far I could replicate any macro by using (eval) in a function. I have to add quotes when I call the function though, but I feel like I've began to understand macros and now I am back at square 1. Could anyone give me an example of a macro where eval won't work?


Ultimately a macro is just a function whose return value is evaluated by the "eval" part of the read-eval-print loop (or, equivalently, seen by the compiler). By calling eval explicitly, you block the compiler...and you evaluate things in a different scope: your "setf" thing is an example of a macro where eval won't work (except for special variables; e.g., try
Code: Select all
(let ((a 0))
  (setvar-f 'a 42)
  a)

in a fresh Lisp. It'll return 0, not 42; and the symbol-value of the symbol A will be set to 42 afterwards (some implementations (CMUCL) will make A special in the process, so the next time you try it it'll appear to work, hence the call for a fresh Lisp); strictly speaking, the behaviour is undefined, lacking an explicit special declaration for A)

I also had trouble creating a macro out of this since it expanded into a wrong form:

Code: Select all
(defun lvar (vlist)
 (loop
  for sub in vlist doing
   (eval
   `(setf ,(first sub) ,(second sub)))
   (format t "~%~a : ~a~%" (first sub) (second sub))))


Not entirely sure what you're trying to do, but I suspect
Code: Select all
(defmacro lvar (vlist)
  `(progn ,@(loop for sub in vlist collect `(setf ,(first sub) ,(second sub)))))

is what you're after. FWIW, you can do
Code: Select all
(loop for (var val) in vlist collect `(setf ,var ,val)
Paul
 
Posts: 106
Joined: Tue Jun 02, 2009 6:00 am


Return to Common Lisp

Who is online

Users browsing this forum: No registered users and 3 guests

cron