From: ········@gmail.com
Subject: question about eval
Date: 
Message-ID: <1109783083.032443.155790@o13g2000cwo.googlegroups.com>
Hi all,

Is there a function that is like eval except that it evaluates its
argument in the current lexical scope rather than the null lexical
scope.  The reason is that I want to write a macro that takes in a list
and an integer i, and evaluates the ith element of the list in the
current lexical scope.  For example,

(let ((a 3))
    (my-macro '((pprint a) (pprint "foo")) 0))

should print 3

Thanks,
Bhaskara

From: Kaz Kylheku
Subject: Re: question about eval
Date: 
Message-ID: <1109787611.925982.172610@f14g2000cwb.googlegroups.com>
········@gmail.com wrote:
> Hi all,
>
> Is there a function that is like eval except that it evaluates its
> argument in the current lexical scope rather than the null lexical
> scope.

No. You cannot assemble source code, and compile/evaluate it in the
surrounding lexical context. A lexical scope is "baked" during
compiling. The information needed to hook into the lexical environment
is no longer available, because the current environment may be compiled
into machine code in which all the lexical variable references are just
numeric offsets into some vector-like object. That's one of the
beauties of lexical scope. The compiler sees the entire scope at once
and can translate it into efficient code.

> The reason is that I want to write a macro that takes in a list
> and an integer i, and evaluates the ith element of the list in the
> current lexical scope.  For example,
>
> (let ((a 3))
>     (my-macro '((pprint a) (pprint "foo")) 0))
>
> should print 3

Is the list of forms always a literal? If so, then the macro can just
turn it into code.

If not, consider using special variables. Code that is processed with
EVAL does have access to the current /dynamic/ environment. That's
because the dynamic environment isn't "baked" by compiling; it contains
self-descriptive information that allows for late binding. The elements
of the dynamic environment such as special variables, catch tags or
restarts are located via symbolic references.

(let ((a 3)
      (l '(list a)))
  (declare (special a))
  (eval l))

--> (3)
From: Duane Rettig
Subject: Re: question about eval
Date: 
Message-ID: <43bvdivzy.fsf@franz.com>
"Kaz Kylheku" <···@ashi.footprints.net> writes:

> ········@gmail.com wrote:
> > Hi all,
> >
> > Is there a function that is like eval except that it evaluates its
> > argument in the current lexical scope rather than the null lexical
> > scope.
> 
> No. You cannot assemble source code, and compile/evaluate it in the
> surrounding lexical context. A lexical scope is "baked" during
> compiling. The information needed to hook into the lexical environment
> is no longer available, because the current environment may be compiled
> into machine code in which all the lexical variable references are just
> numeric offsets into some vector-like object. That's one of the
> beauties of lexical scope. The compiler sees the entire scope at once
> and can translate it into efficient code.

Interestingly, though, the Environments Access project I've been
working on has given us the capability to pass a compilation
environment into eval as-is, in order to grab macro definitions
for compile-time evaluation.  I've intended to experiment with
other types of environment passing, such as other interpreter
environments, to see if anything useful could be scraped up with
this unconventional approach, but have not had time to do this
yet.

The name of the unexported (and unsupported, so don't blame me:-)
function is excl::**eval, and it is even available in Allegro CL 6.2.
I show an example below from the 6.2 lisp, even though the call
to augment-environment is much more cumbersome than it is now
in 7.0.  Maybe someone else would like to experiment with it...

CL-USER(1): (setq env (sys::make-augmentable-environment-boa :interpreter))
#<Augmentable :INTERPRETER Environment NIL @ #x717c26ca>
CL-USER(2): (sys::augment-environment env :reuse t :variable (list (cons 'a (list 3))))
#<Augmentable :INTERPRETER Environment NIL @ #x717c26ca>
CL-USER(3): (sys::variable-information 'a env)
:LEXICAL
(3)
NIL
CL-USER(4): (excl::**eval 'a env)
3
CL-USER(5): (excl::**eval 'a nil)
Error: Attempt to take the value of the unbound variable `A'.
  [condition type: UNBOUND-VARIABLE]

Restart actions (select using :continue):
 0: Try evaluating A again.
 1: Use :A instead.
 2: Set the symbol-value of A and use its value.
 3: Use a value without setting A.
 4: Return to Top Level (an "abort" restart).
 5: Abort entirely from this process.
[1] CL-USER(6): 

-- 
Duane Rettig    ·····@franz.com    Franz Inc.  http://www.franz.com/
555 12th St., Suite 1450               http://www.555citycenter.com/
Oakland, Ca. 94607        Phone: (510) 452-2000; Fax: (510) 452-0182   
From: Tayssir John Gabbour
Subject: Re: question about eval
Date: 
Message-ID: <1109865548.435220.107460@f14g2000cwb.googlegroups.com>
Kaz Kylheku wrote:
> No. You cannot assemble source code, and compile/evaluate it in the
> surrounding lexical context. A lexical scope is "baked" during
> compiling. The information needed to hook into the lexical
> environment is no longer available, because the current environment
> may be compiled into machine code in which all the lexical variable
> references are just numeric offsets into some vector-like object.
> That's one of the beauties of lexical scope. The compiler sees the
> entire scope at once and can translate it into efficient code.

For anyone curious, the dialect "Pico Lisp" seems to go nuts with
code-is-data at runtime. You have to build an environment if you want
lexical binding though.
http://software-lab.de/faq.html
http://software-lab.de/down.html

Not to be confused with the Scheme dialect called simply "Pico".
From: Pascal Bourguignon
Subject: Re: question about eval
Date: 
Message-ID: <873bvenemo.fsf@thalassa.informatimago.com>
········@gmail.com writes:

> Hi all,
> 
> Is there a function that is like eval except that it evaluates its
> argument in the current lexical scope rather than the null lexical
> scope.  The reason is that I want to write a macro that takes in a list
> and an integer i, and evaluates the ith element of the list in the
> current lexical scope.  For example,
> 
> (let ((a 3))
>     (my-macro '((pprint a) (pprint "foo")) 0))
> 
> should print 3

You cannot round-trip between compilation-time (actually macroexpansion
time) and run-time randomly.

If you want to have a (sub)expression evaluated from a macro, just
return it in the generated code.


(defmacro my-macro (expressions selector)
    (elt expressions selector))

(let ((a 3))
  (macroexpand-1 '(my-macro ((pprint a) (pprint "foo")) 0)))
--> (PPRINT A) ; T

(let ((a 3))
  (my-macro ((pprint a) (pprint "foo")) 0))
--> 3


-- 
__Pascal Bourguignon__                     http://www.informatimago.com/

Nobody can fix the economy.  Nobody can be trusted with their finger
on the button.  Nobody's perfect.  VOTE FOR NOBODY.
From: ········@gmail.com
Subject: Re: question about eval
Date: 
Message-ID: <1109784798.070024.241770@g14g2000cwa.googlegroups.com>
OK.  The problem is that in some situations the list of forms may not
be known at macroexpansion time.  E.g.,

(my-macro (mapcar (lambda (i) `(pprint ,i)) '(0 1 2 3)) 1)

should print 1.

So is this just impossible?

Bhaskara


Pascal Bourguignon wrote:
> ········@gmail.com writes:
>
> > Hi all,
> >
> > Is there a function that is like eval except that it evaluates its
> > argument in the current lexical scope rather than the null lexical
> > scope.  The reason is that I want to write a macro that takes in a
list
> > and an integer i, and evaluates the ith element of the list in the
> > current lexical scope.  For example,
> >
> > (let ((a 3))
> >     (my-macro '((pprint a) (pprint "foo")) 0))
> >
> > should print 3
>
> You cannot round-trip between compilation-time (actually
macroexpansion
> time) and run-time randomly.
>
> If you want to have a (sub)expression evaluated from a macro, just
> return it in the generated code.
>
>
> (defmacro my-macro (expressions selector)
>     (elt expressions selector))
>
> (let ((a 3))
>   (macroexpand-1 '(my-macro ((pprint a) (pprint "foo")) 0)))
> --> (PPRINT A) ; T
>
> (let ((a 3))
>   (my-macro ((pprint a) (pprint "foo")) 0))
> --> 3
>
>
> --
> __Pascal Bourguignon__
http://www.informatimago.com/
>
> Nobody can fix the economy.  Nobody can be trusted with their finger
> on the button.  Nobody's perfect.  VOTE FOR NOBODY.
From: Tayssir John Gabbour
Subject: Re: question about eval
Date: 
Message-ID: <1109788999.386671.82800@z14g2000cwz.googlegroups.com>
········@gmail.com wrote:
> OK.  The problem is that in some situations the list of forms may not
> be known at macroexpansion time.  E.g.,
>
> (my-macro (mapcar (lambda (i) `(pprint ,i)) '(0 1 2 3)) 1)
>
> should print 1.
>
> So is this just impossible?

How's about something like:

(defun call-nth-function (n list)
  (funcall (elt list n)))

(call-nth-function 1 (mapcar (lambda (i) (lambda () (pprint i)))
                             '(0 1 2 3)))

This works at runtime. Instead of sticking the PPRINT in a QUOTE, you
stick it in a LAMBDA instead.

I have to admit, those who think the book SICP is good for not
introducing macros quickly have a point.
From: Peter Seibel
Subject: Re: question about eval
Date: 
Message-ID: <m3acpmt07m.fsf@gigamonkeys.com>
········@gmail.com writes:

> OK. The problem is that in some situations the list of forms may not
> be known at macroexpansion time. E.g.,
>
> (my-macro (mapcar (lambda (i) `(pprint ,i)) '(0 1 2 3)) 1)
>
> should print 1.
>
> So is this just impossible?

Yes. There is no way for a macro to select, at macroexpansion time,
from forms that don't yet exist. Which means its time for the
perennial comp.lang.lisp question: what are you *really* trying to do.
What larger problem were you trying to solve when you came up with the
idea of MY-MACRO?

-Peter

P.S. To answer your original question, there is no such version of
EVAL.

-- 
Peter Seibel                                     ·····@gigamonkeys.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: ········@gmail.com
Subject: Re: question about eval
Date: 
Message-ID: <1109801260.384877.322120@f14g2000cwb.googlegroups.com>
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.

So I want to write the choose (and select) macro, but users of this
language will write code that calls it.  Some of the solutions that
have been proposed in this thread, such as declaring all relevant
variables special or using closures, are possible, but all add some
complexity on the `user-side' and I wanted to see if I could make the
user's syntax as simple as possible.  Hence my question.

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.

(defun foo (i j)
  (let ((a (make-array i)))
    (select
      (loop for k below i collecting `(setf (aref a ,k) "foo"))
      j)
   a))

[2] CL-USER(89): (foo 5 1)
#(NIL "foo" NIL NIL NIL)
[2] CL-USER(90): 


What am I missing?
From: Peter Seibel
Subject: Re: question about eval
Date: 
Message-ID: <m3ekexshfv.fsf@gigamonkeys.com>
········@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                                     ·····@gigamonkeys.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: ········@gmail.com
Subject: Re: question about eval
Date: 
Message-ID: <1109812360.943880.204820@g14g2000cwa.googlegroups.com>
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:
> ········@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
·····@gigamonkeys.com
> 
>          Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Peter Seibel
Subject: Re: question about eval
Date: 
Message-ID: <m31xaxse84.fsf@gigamonkeys.com>
········@gmail.com writes:

> 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))))

And what do you want the expansion of CHOOSE to be? That is, write "by
hand" the code that you want CHOOSE to generate. (BTW, I assume you
mean `(print ,i)?)

-Peter

-- 
Peter Seibel                                     ·····@gigamonkeys.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: ········@gmail.com
Subject: Re: question about eval
Date: 
Message-ID: <1109820533.723778.163430@o13g2000cwo.googlegroups.com>
Peter Seibel wrote:
> ········@gmail.com writes:
>
> > 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))))
>
> And what do you want the expansion of CHOOSE to be? That is, write
"by
> hand" the code that you want CHOOSE to generate. (BTW, I assume you
> mean `(print ,i)?)
>
> -Peter


Well, I guess that's where my original question that started this
thread came from :)  If there existed a lisp function eval2 FORM that
was like eval except that it evaluated its argument in the current
lexical scope, then I would want the expansion of the choose statement
to be

(eval2
   (elt
       (loop for i below M collect `(pprint ,i))
       (compute-index-somehow)))



(of course in this particular case, eval would work fine as well since
the forms don't refer to any lexical variables)

Unfortunately, it seems that there is no such function eval2.

An alternative that I would be equally happy with is if the choose
macro somehow automatically figured out what the lexical variables in
the form were and created special bindings for them first.  So in the
code above, say instead of `(pprint ,i) we had `(pprint ,(+ i a)) where
a was bound by an enclosing let statement.  Then I would want the
choose to expand to

(progv
   '(_G12345) (list a)
  (eval
     (elt
        (loop for i below M collect `(pprint ,(+ i a)))
        (compute-index-somehow))))

But I have no idea how to write a choose macro that can figure out what
the lexical variables are.
From: Peter Seibel
Subject: Re: question about eval
Date: 
Message-ID: <m3ekexqt3w.fsf@gigamonkeys.com>
········@gmail.com writes:

> Peter Seibel wrote:
>> ········@gmail.com writes:
>>
>> > 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))))
>>
>> And what do you want the expansion of CHOOSE to be? That is, write
>> "by hand" the code that you want CHOOSE to generate. (BTW, I assume
>> you mean `(print ,i)?)
>>
>> -Peter
>
>
> Well, I guess that's where my original question that started this
> thread came from :) If there existed a lisp function eval2 FORM that
> was like eval except that it evaluated its argument in the current
> lexical scope, then I would want the expansion of the choose
> statement to be
>
> (eval2
>    (elt
>        (loop for i below M collect `(pprint ,i))
>        (compute-index-somehow)))

Okay, so given that that's impossible, the question is, why is this
what you want to do? The thing that is strange--to me anyway--is that
you want your users to write Lisp code that is going to run at runtime
that generates more Lisp code to be run at runtime. Maybe there's a
good reason you need to do that but it's not leaping out at me.

Obviously this LOOP expression is not the kind of thing you really
care about. Can you give an example of a real use of CHOOSE that you'd
like to enable? What Common Lisp code are your users going to be
writing that needs to run at runtime to generate new code to run?

-Peter

-- 
Peter Seibel                                     ·····@gigamonkeys.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: ········@gmail.com
Subject: Re: question about eval
Date: 
Message-ID: <1109826436.801748.127570@g14g2000cwa.googlegroups.com>
The quick summary : i'm trying to write an extension of lisp that
allows users to create nondeterministic programs containing these
choose statements, and have the system learn over time how best to make
those choices.  For example, the top-level loop for a program that
controlled a robot might say

(loop
      until (battery-low)
      do (choose (get-task-list)))

where get-task-list contained some code that looked at the current
world state and figured out what tasks were currently applicable.

But it's true that all this could be achieved by making choose be a
function, not a macro, that just takes in a list of task IDs rather
than the forms themselves, and returns one of the IDs, and have the
caller look at the returned ID and figure out what task it corresponds
to.  I was just wondering if I could add some syntactic sugar so the
user could just directly call choose with the list of forms rather than
messing around with IDs.
From: Peter Seibel
Subject: Re: question about eval
Date: 
Message-ID: <m3u0ntp6nz.fsf@gigamonkeys.com>
········@gmail.com writes:

> The quick summary : i'm trying to write an extension of lisp that
> allows users to create nondeterministic programs containing these
> choose statements, and have the system learn over time how best to make
> those choices.  For example, the top-level loop for a program that
> controlled a robot might say
>
> (loop
>       until (battery-low)
>       do (choose (get-task-list)))
>
> where get-task-list contained some code that looked at the current
> world state and figured out what tasks were currently applicable.
>
> But it's true that all this could be achieved by making choose be a
> function, not a macro, that just takes in a list of task IDs rather
> than the forms themselves, and returns one of the IDs, and have the
> caller look at the returned ID and figure out what task it
> corresponds to. I was just wondering if I could add some syntactic
> sugar so the user could just directly call choose with the list of
> forms rather than messing around with IDs.

Well, you can--the only caveat is the one you started the thread
asking about--forms generated at runtime don't have access to the
lexical environment of the code surrounding the CHOOSE form. But
that's going to be the case whether CHOOSE is a macro or a
function--it's a consequence of the way EVAL works and the way the
Common Lisp compiler compiles lexical bindings. But since the task
forms are to be generated dynamically, it makes sense that the
variables they access be dynamically scoped. So you can bind dynamic
variables and use them from your forms. And you can, of course,
provide a macro to sugar that up:

  (defmacro with-task-vars ((&rest bindings) &body body)
    `(let ,bindings
       (declare (special ,@(mapcar #'car bindings)))
       ,@body))

Now:

  (with-task-vars ((location #C(0 0)) (arm-engaged nil))
    (loop until (battery-low) do (choose (get-task-list))))

where GET-TASK-LIST includes forms that contain references to LOCATION
and ARM-ENGAGED.

I think that's as good as it gets unless you want to go all the way to
writing a compiler or interpreter for your language so you can build
in runtime-accessible first-class lexical environments. Which is less
work in Common Lisp than it would be in many other languages but still
probably not a small undertaking, if you want this language to be a
lot like Common Lisp.

-Peter

-- 
Peter Seibel                                     ·····@gigamonkeys.com

         Lisp is the red pill. -- John Fraser, comp.lang.lisp
From: Rahul Jain
Subject: Re: question about eval
Date: 
Message-ID: <871xati8p3.fsf@nyct.net>
········@gmail.com writes:

> The quick summary : i'm trying to write an extension of lisp that
> allows users to create nondeterministic programs containing these
> choose statements, and have the system learn over time how best to make
> those choices.

Why not simply add this feature to Screamer?

-- 
Rahul Jain
·····@nyct.net
Professional Software Developer, Amateur Quantum Mechanicist
From: Alan Crowe
Subject: Re: question about eval
Date: 
Message-ID: <86psygvpeh.fsf@cawtech.freeserve.co.uk>
bhaskara worried:
> So I want to write the choose (and select) macro, but
> users of this language will write code that calls it.
> Some of the solutions that have been proposed in this
> thread, such as declaring all relevant variables special
> or using closures, are possible, but all add some
> complexity on the `user-side' and I wanted to see if I
> could make the user's syntax as simple as possible.

I cannot see the problem with making all relevant variables
special. I agree that if you proclaim them to be special,
for example by using DEFVAR, that will cause difficulties,
because the declaration will be pervasive, effectively
making the symbol special, not just the binding. However, an
ordinary special declaration is not pervasive, and plays
nicely with inner closures. For example


(prog ((x 5)(y 7)(f (lambda()'initial)))
      (declare (special x y f))
      top
      (format t "~&Type in a form ")
      (eval (read))
      (print (funcall f))
      (print (funcall f))
      (go top))

The variables are readable without special syntax:

     Type in a form (print (* x y))

     35 
     INITIAL 
     INITIAL 

Setting them is slightly different:

     Type in a form (set 'f (lambda()(+ x y)))

     Warning: These variables are undefined:
       X Y

     12 
     12 

Notice that returning a function to the outer
environment works as expected, (Hmm, need to get rid of the
warning)

Closures returned from the inner environment to the outer
one still work

     Type in a form (let ((x 10)) (set 'f (lambda()(setf x (* x x)))))

     100 
     10000 

Indeed one can emphasise the point by using the symbol F as
the name of the variable that one closes over

     Type in a form (let ((f 1/3))(set 'f (lambda()(setf f (* f f)))))

     1/9 
     1/81 

The only problem that I can see is when one attempts, in the
inner environment, to close over a variable from the outer
environment. That partially works, but is only guaranteed so
long as you stay in the inner environment, making the
variable effectively global.

If you return to the outer environment, the code in the
outer environment could exit the scope of the binding,
dis-establishing it. Then the fact that one had not actually
created a lexical closure would become apparent. However, in
the absence of some prior agreement between the inner and
outer environments about how to use the variable, the outer
environment could alter the variable in an unacceptable way,
even if it had been lexical, so I don't feel that I'm seeing
a problem of practical importance.

My turn to ask "What am I missing?"

Alan Crowe
Edinburgh
Scotland
From: Pascal Bourguignon
Subject: Re: question about eval
Date: 
Message-ID: <87psyhnbe8.fsf@thalassa.informatimago.com>
········@gmail.com writes:

> OK.  The problem is that in some situations the list of forms may not
> be known at macroexpansion time.  E.g.,
> 
> (my-macro (mapcar (lambda (i) `(pprint ,i)) '(0 1 2 3)) 1)
> 
> should print 1.
> 
> So is this just impossible?

Instead of a macro, you could use closures:

(let ((a 42))
  (funcall (elt (mapcar (lambda (i)
                            (lambda () (pprint (+ a i)))) 
                        '(0 1 2 3)) 
                1)))



-- 
__Pascal Bourguignon__                     http://www.informatimago.com/
Kitty like plastic.
Confuses for litter box.
Don't leave tarp around.
From: Wade Humeniuk
Subject: Re: question about eval
Date: 
Message-ID: <PtoVd.25098$TB.7951@edtnps84>
········@gmail.com wrote:
> Hi all,
> 
> Is there a function that is like eval except that it evaluates its
> argument in the current lexical scope rather than the null lexical
> scope.  The reason is that I want to write a macro that takes in a list
> and an integer i, and evaluates the ith element of the list in the
> current lexical scope.  For example,
> 
> (let ((a 3))
>     (my-macro '((pprint a) (pprint "foo")) 0))
> 
> should print 3
> 

Here is one way:

(defun eval-with-context (vars &rest body)
   (eval `(let ,vars ,@body)))

(eval-with-context '((a 3)) (elt '((pprint a) (pprint "foo")) 0))

CL-USER 1 > (eval-with-context '((a 3)) (elt '((pprint a) (pprint "foo")) 0))

3

CL-USER 2 > (let ((x 100))
               (eval-with-context `((a ,x))
                                  (elt '((pprint a) (pprint "foo"))
                                       0)))

100

CL-USER 3 >

One would have to specify the vars arg with all the bindings you need.

Wade
From: Hannah Schroeter
Subject: Re: question about eval
Date: 
Message-ID: <d05ktf$bf3$1@c3po.use.schlund.de>
Hello!

 <········@gmail.com> wrote:

>Is there a function that is like eval except that it evaluates its
>argument in the current lexical scope rather than the null lexical
>scope.  The reason is that I want to write a macro that takes in a list
>and an integer i, and evaluates the ith element of the list in the
>current lexical scope.  For example,

>(let ((a 3))
>    (my-macro '((pprint a) (pprint "foo")) 0))

>should print 3

I don't think you need eval (in fact eval doesn't help as it doesn't
allow to access lexical variables).

If the index is a constant, it's very simple:

(defmacro my-macro (forms-list n)
  (nth n forms-list))

(let ((a 3))
  (my-macro ((pprint a) (pprint "foo")) 0)) ; <-- even w/o quote
    ; remember, it's a macro!

If the index is variable, it's a bit more complicated. I could be
wrong, but perhaps something like this works:

(defmacro my-macro (forms-list n)
  `(funcall (nth ,n (list ,@(mapcar #'(lambda (form) `#'(lambda () ,form))
                                    forms-list)))))

(let ((a 3))
  (my-macro ((pprint a) (pprint "foo")) (- 1 1))) ; <-- even w/o quote
    ; remember, it's a macro! And see, you can use an expression!

(defun f (n)
  (let ((a 3))
    (my-macro ((pprint a) (pprint "foo")) n)))

; (compile 'f)

(f 0)
-> 3

(f 1)
-> foo

Kind regards,

Hannah.