From: Alex Mizrahi on
BT> Alex, both the number and names of variables are determined at
BT> run-time.

Here's a solution which works in runtime and doesn't require funcalls.
It just replaces symbols with their values in the form and then executes it.

(let ((form '(eql (op n m) 5)))
(mapcar (lambda (from to)
(setf form (subst to from form)))
'(op n m)
'(+ 2 3))
(eval form))

BT> But I think I get it now. In the former, the value of op is some
BT> function which gets to live at the front of the list given to eval.

Um, in the former case op is just a variable. You construct list '(+ 2 3)
this way and pass it to eval.
(eval '(+ 2 3)) works fine. Note that you're working with symbols here, not
functions.

BT> In the latter, eval immediately looks for (symbol-function op), which
BT> as Pascal pointed out, it is not defined by progv. Is that correct?

Yeah, progv binds variable, but not a function. Variables and functions live
in different namespaces in Common Lisp.

From: Thomas A. Russ on
Benjamin Tovar <nospam.at.mugrido(a)the.google.mail.thing> writes:

> "Alex Mizrahi" <udodenko(a)users.sourceforge.net> writes:
>
> My confusion came from the following code evaluating to 5:
>
> (progv '(op n m) '(+ 2 3)
> (eval (list op n m)))

Right. Because EVAL is a normal lisp function, it evaluates its
arguments.

You already know that
(eval '(+ 2 3)) => 5

because you have a form (with symbols that can be evaluated).

Note that (list '+ 2 3) and '(+ 2 3) evaluate to the same list
structure, so either one can be used.

> Compared to this one, which fails:
>
> (progv '(op n m) '(+ 2 3)
> (eval (op n m)))

In this case, what happens is that (op n m) is first evaluated as an
argument to EVAL, even before EVAL gets a chance to do anything with
it. You would have the same problem if you tried
(print (op n m))

because OP does not have a function binding. It has a value binding to
the symbol +. So this evaluation will fail, even in the absence of
EVAL.

The difference in the first case is that if you called
(identity (list '+ 2 3))
and
(eval (list '+ 2 3))
you would see differences.
>
> But I think I get it now. In the former, the value of op is some
> function which gets to live at the front of the list given to eval. In
> the latter, eval immediately looks for (symbol-function op), which as
> Pascal pointed out, it is not defined by progv. Is that correct?

As noted above, it isn't eval (or at least not the one that you
explicitly put in the code) that tries to look up OP as a function. It
is the built-in evaluation of function arguments that does that.

But the general notion is heading in the right direction. The first
symbol in a list that is being evaluated will be looked up in the
function namespace, but PROGV only binds the value namespace. To bind
functions, you need to use something like LABELS or FLET, but you can't
dynamically pass in a symbol to use as the name.

--
Thomas A. Russ, USC/Information Sciences Institute
From: Benjamin Tovar on
tar(a)sevak.isi.edu (Thomas A. Russ) writes:

> As noted above, it isn't eval (or at least not the one that you
> explicitly put in the code) that tries to look up OP as a function. It
> is the built-in evaluation of function arguments that does that.
>
> But the general notion is heading in the right direction. The first
> symbol in a list that is being evaluated will be looked up in the
> function namespace, but PROGV only binds the value namespace. To bind
> functions, you need to use something like LABELS or FLET, but you can't
> dynamically pass in a symbol to use as the name.

Thanks Thomas, that cleared all my confusion.

Benjamin