Re: question about eval

bhaskara_at_gmail.com
Date: 03/03/05


Date: 2 Mar 2005 17:12:40 -0800

OK, but the point is that we may not know at compile time what the
forms are. I want to be able to write things like

(defun print-a-number (M)
     (choose (loop for i below M collect '(pprint i))))

Is that just impossible in Lisp?

- Bhaskara

Peter Seibel wrote:
> bhaskara@gmail.com writes:
>
> > Thanks everybody for all the responses. Here's the original
problem I
> > was trying to solve. I'm writing an interpreter for a
nondeterministic
> > language built on top of lisp that has a construct called choose.
> > choose L &rest ARGS takes a list l and some other arguments, picks
an
> > index i between 0 and length(l)-1 (using reinforcement learning,
but
> > that's another story), does some bookkeeping, and finally evaluates
the
> > i^th form in l. This last part requires a macro, call it select,
that
> > takes a list l and an integer i and causes the ith form in list l
to be
> > evaluated.
>
> I'm not sure why you want this extra macro. Anyway, here's a macro
> that implements a CHOOSE operator similar to what you want. It
doesn't
> take any other arguments or do any bookkeeping since I didn't know
> what you needed but hopefully this will give you some ideas. The
trick
> is that you need to be clear about what things you want to do at
> macroexpand time (most likely when you compile the code) and what you
> need to do at runtime. For instance this macro generates code that
> chooses, at runtime, which of several forms, all known at compile
> time, to execute.
>
> (defmacro choose (&body forms)
> (let ((tags (loop for f in forms collect (gensym)))
> (number (length forms))
> (block-name (gensym)))
> `(block ,block-name
> (tagbody
> (case (random ,number)
> ,@(loop for n from 0 for tag in tags collect `(,n (go
,tag))))
> ,@(loop for tag in tags for form in forms
> nconc (list tag `(return-from ,block-name
,form)))))))
>
> This will let your users write:
>
> (choose
> (some-thing)
> (some-other-thing a b c)
> (biff-bam-boom))
>
> Each time that expression is run, one of the three forms will be
> executed. And code within a CHOOSE can refer to lexical bindings
> established in the surrounding lexical context.
>
> > Anyway, I was messing around a bit more, and I came up with the
> > following contorted attempt :
> >
> > (defmacro select-helper (l i)
> > (elt (eval l) (eval i)))
> >
> > (defmacro select (l i)
> > (let ((*l* (gensym)) (*i* (gensym)))
> > `(progv '(,*l* ,*i*) (list ,l ,i)
> > (select-helper ,*l* ,*i*))))
> >
> > Now this is really ugly, and I suspect that there's some case that
it
> > fails on. But it works on the cases I tried. E.g.
>
> If that works, it's only by accident. Look at the definiton of CHOOSE
> I gave you. Macro expand some uses of it and look at the code it
> generates. Or perhaps take a look at:
>
> <http://www.gigamonkeys.com/book/macros-defining-your-own.html>
>
> -Peter
>
> --
> Peter Seibel
peter@gigamonkeys.com
>
> Lisp is the red pill. -- John Fraser, comp.lang.lisp



Relevant Pages

  • Re: modifying array access syntax
    ... I published recent speculation on the ARRAY ... > are in fact remnants of the property lists of these Lisp-N ... these that were meaningful at compile time (FEXPR, FSUBR, and MACRO ...
    (comp.lang.lisp)
  • DISFAVORED Was: name for 3 PICK finally?
    ... I'd nominate IMMEDIATE. ... I wouldn't mind having a MACRO: ... No need for [COMPILE] POSTPONE etc. ... execute it by executing the macro. ...
    (comp.lang.forth)
  • Re: DISFAVORED Was: name for 3 PICK finally?
    ... complexity is reduced by reducing the phases of execution to keep ... outside happens when the word containing the macro executes. ... LITERAL COMPILE, .... ... ``GET LITERAL @ LITERAL `EXECUTE COMPILE,'' ...
    (comp.lang.forth)
  • Re: Open stack and colon definitions as a features (was: Of course it IS!!!)
    ... execute at compile time like immediate words did thirty years ... So now we also know what color a macro has: ... In Chuck's colorforth green is more like "]" and yellow is ... They do something more like change the system's STATE to execute ...
    (comp.lang.forth)
  • Re: apparently undefined function called by macro
    ... However, as almost always in Common Lisp;), there are exceptions to this rules: Some top-level forms do indeed have effects at compile time. ... The reason is that you typically want to base subsequent code on your macro definitions, and the compiler must be able to completely macro-expand away these macro definitions as well. ... A system definition allows you to declare that one file of lisp code depends on some other file of lisp code. ...
    (comp.lang.lisp)