Re: question about eval
From: Peter Seibel (peter_at_gigamonkeys.com)
Date: 03/03/05
- Next message: bhaskara_at_gmail.com: "Re: question about eval"
- Previous message: Hannah Schroeter: "Re: question about eval"
- In reply to: bhaskara_at_gmail.com: "Re: question about eval"
- Next in thread: bhaskara_at_gmail.com: "Re: question about eval"
- Reply: bhaskara_at_gmail.com: "Re: question about eval"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Date: Thu, 03 Mar 2005 00:28:45 GMT
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
- Next message: bhaskara_at_gmail.com: "Re: question about eval"
- Previous message: Hannah Schroeter: "Re: question about eval"
- In reply to: bhaskara_at_gmail.com: "Re: question about eval"
- Next in thread: bhaskara_at_gmail.com: "Re: question about eval"
- Reply: bhaskara_at_gmail.com: "Re: question about eval"
- Messages sorted by: [ date ] [ thread ] [ subject ] [ author ]
Relevant Pages
|