Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

newbie - partially evaluate expression

1 view
Skip to first unread message

Sushovan

unread,
Jan 27, 2009, 5:59:34 PM1/27/09
to
Hi,
I am trying to write a function that generates a lisp expression
ready to pass to eval like this:
(defun foo (x y) '(expt x (- y 1)))
However, when I run this with
(foo 'z 24)
I get:
(EXPT X (- Y 1))

What do I need to change in foo to make it evaluate to
(EXPT Z 23)

Any help would be appreciated. Thanks.
Sushovan

Pascal Costanza

unread,
Jan 27, 2009, 6:11:03 PM1/27/09
to

(defun foo (x y) `(expt ,x ,(- y 1)))


Pascal

--
ELS'09: http://www.european-lisp-symposium.org/
My website: http://p-cos.net
Common Lisp Document Repository: http://cdr.eurolisp.org
Closer to MOP & ContextL: http://common-lisp.net/project/closer/

Sushovan

unread,
Jan 27, 2009, 6:18:56 PM1/27/09
to

Thank you so very much. Works perfectly.

Thomas A. Russ

unread,
Jan 27, 2009, 8:00:04 PM1/27/09
to
Pascal Costanza <p...@p-cos.net> writes:

> Sushovan wrote:
> > Hi,
> > I am trying to write a function that generates a lisp expression
> > ready to pass to eval like this:
> > (defun foo (x y) '(expt x (- y 1)))
> > However, when I run this with
> > (foo 'z 24)
> > I get:
> > (EXPT X (- Y 1))
> > What do I need to change in foo to make it evaluate to
> > (EXPT Z 23)
> > Any help would be appreciated. Thanks.
>
> (defun foo (x y) `(expt ,x ,(- y 1)))

A more flexible approach would be to use the built-in SUBLIS function to
do the substitutions for you. It should work well as long as you don't
have any binding forms or constants in the expression tree.

(sublis '((x . z) (y . 23)) '(expt x (- y 1)))

==> (EXPT Z (- 23 1))

But one is compelled by decades of lisp group tradition to ask:
"Why do you want to use EVAL in the first place?"

--
Thomas A. Russ, USC/Information Sciences Institute

Pascal J. Bourguignon

unread,
Jan 27, 2009, 9:30:16 PM1/27/09
to

Indeed. You should probably better provide a lambda form that can be compiled:

(defun foo (x y)
`(lambda ()
(let ((x ,x)
(y ,y))
(expt x (1- y)))))


Then you can do:

(funcall (compile nil (foo 2 3)))

and avoid the so dreaded EVAL.

--
__Pascal Bourguignon__

Sushovan

unread,
Jan 27, 2009, 10:11:12 PM1/27/09
to
On Jan 27, 7:30 pm, p...@informatimago.com (Pascal J. Bourguignon)
wrote:
> __Pascal Bourguignon__- Hide quoted text -
>
> - Show quoted text -

The problem statement says.. Write a lisp program to generate an
expression A that when eval-ed would produce output B. I am not
actually using eval in my code.

Sushovan.

Matthew D Swank

unread,
Jan 27, 2009, 10:19:27 PM1/27/09
to

Why is this necessarily better than eval (especially if you funcall the
compiled function only once)?

Matt

--
Wrinkles should merely indicate where smiles have been.
-- Mark Twain

William James

unread,
Jan 27, 2009, 11:36:56 PM1/27/09
to
Sushovan wrote:

def foo x,y
"expt( #{ x }, #{ y-1 } )"
end
==>nil
foo :z, 24
==>"expt( z, 23 )"

D Herring

unread,
Jan 28, 2009, 12:05:39 AM1/28/09
to
Sushovan wrote:

> The problem statement says.. Write a lisp program to generate an
> expression A that when eval-ed would produce output B. I am not
> actually using eval in my code.


FWIW, politeness dictates that you always indicate when your question
is part of your homework.

- Daniel

Pascal J. Bourguignon

unread,
Jan 28, 2009, 3:40:29 AM1/28/09
to

Well, technically I didn't say that FUNCALL COMPILE LAMBDA was better
than eval. I said that you'd better use it to be able to avoid EVAL.
I have no a-priori about whether you should avoid EVAL or not.

Perhaps you've noticed it's not the first time I mention the
equivalence between EVAL and FUNCALL COMPILE LAMBDA. Perhaps this
constitutes a hint about what I really think about using EVAL (when
it's required)?

--
__Pascal Bourguignon__

Chaitanya Gupta

unread,
Jan 28, 2009, 4:15:34 AM1/28/09
to
Pascal J. Bourguignon wrote:
>
> Indeed. You should probably better provide a lambda form that can be compiled:
>
> (defun foo (x y)
> `(lambda ()
> (let ((x ,x)
> (y ,y))
> (expt x (1- y)))))
>
>
> Then you can do:
>
> (funcall (compile nil (foo 2 3)))
>

Why not just

(defun foo (x y)
(lambda () (expt x (1- y))))

And then

(compile 'foo)

and finally

(funcall (foo 2 3))

Won't (foo 2 3) return a compiled closure?

Chaitanya

Pascal J. Bourguignon

unread,
Jan 28, 2009, 4:40:10 AM1/28/09
to
Chaitanya Gupta <ma...@chaitanyagupta.com> writes:

Yes. But this is not what is specified, and it doesn't give the same
results:


C/USER[1]> (defun foo (x y)


(lambda () (expt x (1- y))))

FOO
C/USER[2]> (foo 2 3)
#<FUNCTION :LAMBDA NIL (EXPT X (1- Y))>
C/USER[3]> (eval *)
#<FUNCTION :LAMBDA NIL (EXPT X (1- Y))>

C/USER[4]> (defun foo (x y)
`(expt ,x (1- ,y)))
FOO
C/USER[5]> (foo 2 3)
(EXPT 2 (1- 3))
C/USER[6]> (eval *)
4


And presumably, foo will build (or read) different expressions, it
won't always be the same I'd guess.

--
__Pascal Bourguignon__

Marco Antoniotti

unread,
Jan 28, 2009, 5:26:37 AM1/28/09
to

Now you are making sense. It is obvious that Ruby gets uglier and
uglier when trying to do simple things :)

Cheers
--
Marco Antoniotti
www.european-lisp-symposium.org

Matthew D. Swank

unread,
Jan 28, 2009, 12:21:40 PM1/28/09
to
On Jan 28, 2:40 am, p...@informatimago.com (Pascal J. Bourguignon)
wrote:

> Perhaps you've noticed it's not the first time I mention the
> equivalence between EVAL and FUNCALL COMPILE LAMBDA.  

I'm lucky if I notice what day of the week it is. Sometimes the only
reason I know I've been up all night is the cats suddenly want fed.

I wish wish you luck in all you comp.lang.lisp pedagogical exercises.
Now if you could only give an example eval/compile equivalency that
included a way to erase someone's hard drive.

Matt

w_a_...@yahoo.com

unread,
Jan 28, 2009, 1:14:08 PM1/28/09
to

OCaml:

# let mul x y = x * y;;
val mul : int -> int -> int = <fun>
# mul 7 8;;
- : int = 56
# let mul_55 = mul 55;;
val mul_55 : int -> int = <fun>
# mul_55 3;;
- : int = 165

jos...@corporate-world.lisp.de

unread,
Jan 28, 2009, 2:21:48 PM1/28/09
to

I don't think that was the requested task.

The task is to write a function that generates an expression.
You wrote a function that computes a multiplication
and then a curried version.

You failed to write a function that generates an expression.

Mark Wooding

unread,
Jan 28, 2009, 4:15:19 PM1/28/09
to
p...@informatimago.com (Pascal J. Bourguignon) writes:

> Indeed. You should probably better provide a lambda form that can be
> compiled:
>
> (defun foo (x y)
> `(lambda ()
> (let ((x ,x)
> (y ,y))
> (expt x (1- y)))))
>
>
> Then you can do:
>
> (funcall (compile nil (foo 2 3)))

There's no need to invoke the compiler here.

(funcall (coerce (foo 2 3) 'function))

is sufficient. I didn't see a performance requirement mentioned in the
thread. (I think SBCL, for example, will exercise the compiler anyway
in COERCE.)

-- [mdw]

Marco Antoniotti

unread,
Jan 29, 2009, 6:52:11 AM1/29/09
to

This OCaml is the following CL (sans types)

(defun mul (x y) (* x y))

(defsubst mul_55 (curry 'mul 55))

(mul_55 3)

where DEFSUBST and CURRY are just a macro away (or other appropriately
named macros, whose existence in ALEXANDRIA I now conjecture :) )

But that is not wat the OP asked. He asked for something returning a
partially evaluated *expression*.

As for CURRY, let's do a preventive googling with "currying in Ruby"
just for fun.... :)

Cheers
--
Marco


0 new messages