need help with with-open-file() style macro

Discussion of Common Lisp
Post Reply
sinnatagg
Posts: 29
Joined: Tue Apr 21, 2009 3:04 am

need help with with-open-file() style macro

Post by sinnatagg » Sat Jul 21, 2012 10:29 am

Ayup, I'm trying to create a macro binding a symbol in the same manner as with-open-file():

Code: Select all

(defmacro with-experiment ((experiment file) &body body)
  `(let* ((,experiment (read-experiment-file ,file)))
     ,@body))
This works but I'm a bit worried that "file" is evaluated before "experiment", but is this even a valid concern? with-open-file() and this code doesn't handle a non-symbol argument in this position.

Anybody know of any pitfalls in this regard?

-a

pjstirling
Posts: 166
Joined: Sun Nov 28, 2010 4:21 pm

Re: need help with with-open-file() style macro

Post by pjstirling » Sat Jul 21, 2012 11:57 am

This only matters in cases where you don't specify the order of evaluation in your documentation and it violates the principle of least surprise.

You are using experiment purely as a name, don't worry about it :)

Konfusius
Posts: 62
Joined: Fri Jun 10, 2011 6:38 am

Re: need help with with-open-file() style macro

Post by Konfusius » Sat Jul 21, 2012 1:54 pm

Backquote replaces ,experiment by the value of the variable experiment. The value itself (that is, the actual argument to the macro) isn't evaluated.

The code

Code: Select all

(with-experiment ((car ex) "file")
  ...)
will be replaced by

Code: Select all

(let* (((car ex) (read-experiment-file "file)))
  ..)
which causes an error from let* because (car ex) isn't a symbol. But (car ex) wont be evaluated.

Since it can be confusing if an error is issued by let* though there is no let* in the source code your macro will become more user friendly if you add a check-type:

Code: Select all

(defmacro with-experiment ((experiment file) &body body)
  (check-type experiment symbol)
  `(let* ((,experiment (read-experiment-file ,file)))
     ,@body))

Post Reply