Browse files

Added back in macroexpansion-time side effect which stores the argume…

…nt number

of the container.  Why is this necessary?

We want people to be able to recursively define Modf expansion functions and
methods.  This means that within the body of a Modf expansion function/method,
the macroexpander will need to know how to invert the accessor you are currently
defining how to invert.  Luckily, it only needs to know which argument it is
operating on.  This is important with we were defining an inversion for NTH or
GETHASH if those inversion functions were recursive (which might be the case
with NTH).

Since, as was pointed out, we need this this side effect to happen whether this
is a file was loaded or compiled then loaded into a fresh Lisp image, and we
need the side effect as we compile (in case it is recursive), the side effects
are wrapped in an EVAL-WHEN with all three cases specified.  If we have mutually
recursive Modf functions, well that is still an open problem.

Lastly, just to reduce the number of surprises, I have added the same side
effect explicitly at macroexpand time.  This means that things will work even if
definition forms don't happen in top-level forms.  See the test suite for an
example of this (in fact, this was initially motivated because it is difficult
to write a test of this recursive stuff that can be called more than once and
actually test this setup).
  • Loading branch information...
1 parent 2eca024 commit ed4c12792f06ce03545ae905e36315fcc6786779 @smithzvk committed Aug 7, 2011
Showing with 11 additions and 2 deletions.
  1. +11 −2 modf.lisp
View
13 modf.lisp
@@ -22,6 +22,9 @@
should return an expansion from EXPR to a form that will build a new object that
has NEW-VAL in the place specified by expr. NTH-ARG marks which argument is
considered the actual data which will be inverted next."
+ (setf
+ (gethash name *modf-nth-arg*)
+ nth-arg )
`(eval-when (:compile-toplevel :load-toplevel :execute)
(setf
(gethash ',name *modf-nth-arg*)
@@ -76,6 +79,10 @@ functional analog of #'\(SETF SYM)."
(defmacro define-modf-function (name nth-arg (new-val &rest args) &body body)
"Define a new modf function. It inverts NAME forms by modifying the NTH-ARG
term of the arguments of the place form in the MODF macro."
+ ;; Side effect in a macro, I know. How can you do this via EVAL-WHEN if I
+ ;; want it to run even if not a toplevel macro?
+ (setf (gethash name *modf-nth-arg*)
+ nth-arg )
`(progn
(eval-when (:compile-toplevel :load-toplevel :execute)
(setf (gethash ',name *modf-nth-arg*)
@@ -88,8 +95,10 @@ term of the arguments of the place form in the MODF macro."
"Define a new modf method. It inverts NAME forms by modifying the NTH-ARG
term of the arguments of the place form in the MODF macro. This method can
specialize on any of ARGS."
- ;; Side effect in a macro, I know. How can you do this via EVAL-WHEN if the
- ;; rest of the macro-expansion depends on the side effect.
+ ;; Side effect in a macro, I know. How can you do this via EVAL-WHEN if I
+ ;; want it to run even if not a toplevel macro?
+ (setf (gethash name *modf-nth-arg*)
+ nth-arg )
`(progn
(eval-when (:compile-toplevel :load-toplevel :execute)
(setf (gethash ',name *modf-nth-arg*)

0 comments on commit ed4c127

Please sign in to comment.