Page 1 of 1

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

Posted: Sat Jul 21, 2012 10:29 am
by sinnatagg
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

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

Posted: Sat Jul 21, 2012 11:57 am
by pjstirling
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 :)

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

Posted: Sat Jul 21, 2012 1:54 pm
by Konfusius
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))