From: Benjamin Tovar on

I am having trouble mixing progv and eval when a binding from progv is
supposed to be a function.

Particularly, this one works:

(progv '(op n m) '(+ 2 3)
(eval '(eql (+ n m) 5)))

However, this one complains that the function OP is undefined:

(progv '(op n m) '(+ 2 3)
(eval '(eql (op n m) 5)))

I would appreciate if somebody can point me in the right direction.

Thanks!


Benjamin
From: pocket on
Hello I'm not a lisp hacker
but I try to do like this:

(progv '(op n m) '(+ 2 3)
(eval '(eql (funcall op n m) 5)))

then it works fine.
From: Pascal Costanza on
On 25/03/2010 06:46, Benjamin Tovar wrote:
>
> I am having trouble mixing progv and eval when a binding from progv is
> supposed to be a function.
>
> Particularly, this one works:
>
> (progv '(op n m) '(+ 2 3)
> (eval '(eql (+ n m) 5)))
>
> However, this one complains that the function OP is undefined:
>
> (progv '(op n m) '(+ 2 3)
> (eval '(eql (op n m) 5)))
>
> I would appreciate if somebody can point me in the right direction.
>
> Thanks!

progv only works for variable bindings, not for function bindings. If
you want to invoke a first-class function objects stored in a variable,
you have to use funcall, as always. That's the same for all kinds of
variable bindings, not just the ones introduced by progv.


Pascal

--
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/
From: Alex Mizrahi on
BT> Particularly, this one works:

BT> (progv '(op n m) '(+ 2 3)
BT> (eval '(eql (+ n m) 5)))

BT> However, this one complains that the function OP is undefined:

BT> (progv '(op n m) '(+ 2 3)
BT> (eval '(eql (op n m) 5)))

BT> I would appreciate if somebody can point me in the right direction.

I think you're mis-using PROGV here. Did you define op, n and m as special
variables?

If you want some kind of templating, why not use backquote:

(let ((op '+)
(n 2)
(m 3))
(eval `(eql (,op ,n ,m) 5)))


Or if you want to preserve the form

(destructuring-bind (op n m)
'(+ 2 3)
(eval `(eql (,op ,n ,m) 5)))

Or you can paste whole form this way:

(let ((form '(+ 2 3)))
(eval `(eql ,form 5))

Backquote is much more flexible.


From: Benjamin Tovar on
"Alex Mizrahi" <udodenko(a)users.sourceforge.net> writes:

> I think you're mis-using PROGV here. Did you define op, n and m as
> special variables?
>
> If you want some kind of templating, why not use backquote:
>
> (let ((op '+)
> (n 2)
> (m 3))
> (eval `(eql (,op ,n ,m) 5)))

Alex, both the number and names of variables are determined at
run-time. Therefore, progv seems a better fit. As Pascal and pocket
pointed out, I was missing a funcall.

My confusion came from the following code evaluating to 5:

(progv '(op n m) '(+ 2 3)
(eval (list op n m)))

Compared to this one, which fails:

(progv '(op n m) '(+ 2 3)
(eval (op n m)))

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?

Benjamin