From: Ryszard Szopa
Subject: simple question (at least I hope so...)
Date: 
Message-ID: <b1ln1a$idh$3@atlantis.news.tpi.pl>
hi, I'm quite new to lisp and I have a problem I cannot solve by myself.
if I'm the 1000th person asking the same question -- I'm sorry -- just
ignore me.
		
I've got an array *arr* of expressions in the style 
of ``(+ x (* 2 (sqrt x)))''-- in fact, they look like 
(or, at least i tried hard to make them look like)
the body of a lambda function.

i also have the macro
(defmacro calculate (expr y)
    `(apply (lambda (x) ,expr) '(,y)))

which works when I type something like
``(calculate (+ x (* 2 (sqrt x))) 1)
        => 3'',
but when I try, for exmaple,
``(calculate (aref *arr* 1) 1'',
it throws back the expression itself, 
        => (+ X (* 2 (SQRT X)))...

I spent about an hour  trying different 
combinations of ",", "'" ····@"... what am I doing wrong? maybe I 
need a totally different aproach?
thanks in advance
                -- Ryszard Szopa

-- 
(email '(bies (at) hell org pl))   ;; Sancte Socrates, ora pro nobis!
(name (or '(ryszard szopa) 'bies)) ;;     -- Erasmus
(www '(bies hell org pl))          ;;

From: Larry Clapp
Subject: Re: simple question (at least I hope so...)
Date: 
Message-ID: <ua0m1b.atu.ln@theclapp.ddts.net>
In article <············@atlantis.news.tpi.pl>, Ryszard Szopa wrote:
> hi, I'm quite new to lisp and I have a problem I cannot solve by myself.
> if I'm the 1000th person asking the same question -- I'm sorry -- just
> ignore me.
> 		
> I've got an array *arr* of expressions in the style 
> of ``(+ x (* 2 (sqrt x)))''-- in fact, they look like 
> (or, at least i tried hard to make them look like)
> the body of a lambda function.
> 
> i also have the macro
> (defmacro calculate (expr y)
>     `(apply (lambda (x) ,expr) '(,y)))
> 
> which works when I type something like
> ``(calculate (+ x (* 2 (sqrt x))) 1)
>         => 3'',
> but when I try, for exmaple,
> ``(calculate (aref *arr* 1) 1'',
> it throws back the expression itself, 
>         => (+ X (* 2 (SQRT X)))...

Hint:

* (macroexpand-1 '(calculate (+ x (* 2 (sqrt x))) 1))
(APPLY (LAMBDA (X) (+ X (* 2 (SQRT X)))) '(1))
T

* (macroexpand-1 '(calculate (aref *arr* 1) 1))
(APPLY (LAMBDA (X) (AREF *ARR* 1)) '(1))
T

> I spent about an hour  trying different combinations of ",", "'"
> ····@"... what am I doing wrong? maybe I need a totally different
> aproach?

Yes.  You have some code that wants both evaluated and unevaluated
arguments.  I fiddled for a while, and came up with this:

    (defun calculate (expr y)
      (eval `(funcall (lambda (x) ,expr) ,y)))

* (calculate '(+ x (* 2 (sqrt x))) 1) ; note ' in front of first
				      ; argument
3.0

* (let ((arr (make-array 10)))
    (setf (aref arr 0) '(+ x (* 2 (sqrt x))))
    (calculate (aref arr 0) 1))
3.0

(I couldn't come up with anything that doesn't call EVAL, though.
Many folks consider EVAL a no-no in most cases, as this often
indicates that one should use a macro.  I think you've encountered one
where it's not.  I could be wrong.  :)

You should note that this particular CALCULATE function (and your
previous macro, too) works only for expressions of one variable: X.

-- 
Larry Clapp / ·····@theclapp.org
Use Lisp from Vim: VILisp: http://vim.sourceforge.net/script.php?script_id=221
From: Ryszard Szopa
Subject: Re: simple question (at least I hope so...)
Date: 
Message-ID: <b1m2oh$1da$1@atlantis.news.tpi.pl>
3 Feb 2003 10:02:54 -0500, Larry Clapp <·····@theclapp.org> wrote:
> Yes.  You have some code that wants both evaluated and unevaluated
> arguments.  I fiddled for a while, and came up with this:
> 
>     (defun calculate (expr y)
>       (eval `(funcall (lambda (x) ,expr) ,y)))
I've tried to solve my problem both with eval and funcall, but never at
the same time ;).

> (I couldn't come up with anything that doesn't call EVAL, though.
> Many folks consider EVAL a no-no in most cases, as this often
> indicates that one should use a macro.  I think you've encountered one
> where it's not.  I could be wrong.  :)
well, using a macro was my first idea... however, I couldn't make
anything that would work - and you managed to do something using with
eval that works, which may indicate that we have here a special
case, where eval is ok.

> You should note that this particular CALCULATE function (and your
> previous macro, too) works only for expressions of one variable: X.
yes, I'm aware of it. I'm implementing (trying to implement ;) a very
simple genetic algorythm to aproxymate a function of one variable on 
the basis of a number of points belonging to its graph - and therefore I
don't think I would need anything more sophisticated... however, there's
a possibility that storing the expressions as an array of lambdas will
make everything much more easier to write (appart from the fact that my
program would be able to aproxymate functions of not only one
variable...).

thanks.
		-- Ryszard Szopa

-- 
(email '(bies (at) hell org pl))   ;; ``Asi es la vida...''' - dijo la vaca
(name (or '(ryszard szopa) 'bies)) ;; despues de la corrida.
(www '(bies hell org pl))          ;;     -- (spanish proverb)
From: Pascal Costanza
Subject: Re: simple question (at least I hope so...)
Date: 
Message-ID: <b1lrea$v1q$1@f1node01.rhrz.uni-bonn.de>
Ryszard Szopa wrote:
  		
> I've got an array *arr* of expressions in the style 
> of ``(+ x (* 2 (sqrt x)))''-- in fact, they look like 
> (or, at least i tried hard to make them look like)
> the body of a lambda function.

I don't know why your code does not work, I can only guess. But I think 
it would be a lot easier from the start if you would just store lambda 
expressions in your array, as follows.

(setf (aref *arr* ...)
       (lambda (x) (+ x ...)))

> i also have the macro
> (defmacro calculate (expr y)
>     `(apply (lambda (x) ,expr) '(,y)))

Then you could write instead: [1]

(defmacro calculate (expr y)
    `(funcall ,expr ,y))

...and the following should work.

(calculate (aref *arr* ...) ...)

Or just:

(funcall (aref *arr* ...) ...)


I haven't checked this, but I am pretty sure it works.

Does this help you?

Pascal


[1] In general, funcall seems to be simpler than apply.

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Kaz Kylheku
Subject: Re: simple question (at least I hope so...)
Date: 
Message-ID: <cf333042.0302031417.7948a1@posting.google.com>
Pascal Costanza <········@web.de> wrote in message news:<············@f1node01.rhrz.uni-bonn.de>...
> Ryszard Szopa wrote:
>   		
> > I've got an array *arr* of expressions in the style 
> > of ``(+ x (* 2 (sqrt x)))''-- in fact, they look like 
> > (or, at least i tried hard to make them look like)
> > the body of a lambda function.
> 
> I don't know why your code does not work, I can only guess. But I think 
> it would be a lot easier from the start if you would just store lambda 
> expressions in your array, as follows.
> 
> (setf (aref *arr* ...)
>        (lambda (x) (+ x ...)))

To clarify the wording, you are storing the function-objects now, not
the original expressions from which they are derived.
From: Ryszard Szopa
Subject: Re: simple question (at least I hope so...)
Date: 
Message-ID: <b1m3d2$6l4$1@atlantis.news.tpi.pl>
Mon, 03 Feb 2003 14:39:20 +0100, Pascal Costanza <········@web.de>
wrote:
> I don't know why your code does not work, I can only guess. But I think 
> it would be a lot easier from the start if you would just store lambda 
> expressions in your array, as follows.
> 
> (setf (aref *arr* ...)
>        (lambda (x) (+ x ...)))
I think it's a good idea...

> Or just:
> 
> (funcall (aref *arr* ...) ...)
> 
> 
> I haven't checked this, but I am pretty sure it works.
well, I'm not sure if I didn't misunderstand something, but clisp says
that

4. Break [5]> (setf k '(lambda (x) (+ x 1))) ; storing in a simple
                                             ; variable shouldn't 
											 ; make any difference?
(LAMBDA (X) (+ X 1))
4. Break [5]> (funcall k 1)

*** - FUNCALL: argument (LAMBDA (X) (+ X 1)) is not a function.
To get a function in the current environment, write (FUNCTION ...).
To get a function in the global environment, write (COERCE '...
'FUNCTION).

I've tried quite hard to make use of the message above, but in the end 
it didn't help me.
thanks for your answer.
		-- Ryszard Szopa

-- 
(email '(bies (at) hell org pl))    
(name (or '(ryszard szopa) 'bies))  
(www '(bies hell org pl))          
From: Kaz Kylheku
Subject: Re: simple question (at least I hope so...)
Date: 
Message-ID: <cf333042.0302031423.6a820104@posting.google.com>
Ryszard Szopa <····@dont.ask.stupid.questions> wrote in message news:<············@atlantis.news.tpi.pl>...
> 4. Break [5]> (setf k '(lambda (x) (+ x 1))) ; storing in a simple
>                                              ; variable shouldn't 
> 											 ; make any difference?

But you quoted the lambda form, so it was not evaluated to produce a
function object.

What you have stored in the variable K is not a function object, but a
list.

That list represents the source code to a function object, but only
you know that. To the Lisp system, it's just another list, just like:

  (setf k '(a b c))

See?

> (LAMBDA (X) (+ X 1))
> 4. Break [5]> (funcall k 1)
> 
> *** - FUNCALL: argument (LAMBDA (X) (+ X 1)) is not a function.

Right, it's not a function, it's source code! If you want to run
source code, you have two alternatives. You can eval it:

   (eval k)

or you can compile it using the compile function:

   (compile nil k)

Either way, you now get a function object, which you can then funcall.
It's possible that the second one is in a representation that is
faster compared to the first, but that might not be true.

This is a powerful feature of Lisp; you can construct source code as a
data object, and then ``activate'' it by compiling it. The compilation
can produce highly optimized native code, depending on your
implementation.
From: Ryszard Szopa
Subject: Re: simple question (at least I hope so...)
Date: 
Message-ID: <b1ohi1$n8j$2@atlantis.news.tpi.pl>
[Mon, 03 Feb 2003 o 22:23 GMT], Kaz Kylheku <···@ashi.footprints.net>:
> source code, you have two alternatives. You can eval it:
> 
>    (eval k)
> 
> or you can compile it using the compile function:
> 
>    (compile nil k)
> 
> Either way, you now get a function object, which you can then funcall.
> It's possible that the second one is in a representation that is
> faster compared to the first, but that might not be true.
> 
> This is a powerful feature of Lisp; you can construct source code as a
> data object, and then ``activate'' it by compiling it. The compilation
> can produce highly optimized native code, depending on your
> implementation.
thanks. now everything seems to me a bit more clear.
		-- Ryszard Szopa

-- 
(email '(bies (at) hell org pl))   ;; do czego to dosz�o. znalaz�em dzi�
(name (or '(ryszard szopa) 'bies)) ;; przy pracy zastosowanie dla XMLa...
(www '(bies hell org pl))          ;;     -- p./duncz/
From: Pascal Costanza
Subject: Re: simple question (at least I hope so...)
Date: 
Message-ID: <b1m4hh$lha$1@f1node01.rhrz.uni-bonn.de>
Ryszard Szopa wrote:

> well, I'm not sure if I didn't misunderstand something, but clisp says
> that
> 
> 4. Break [5]> (setf k '(lambda (x) (+ x 1))) ; storing in a simple
>                                              ; variable shouldn't 

Try the following instead.

(setf k (lambda (x) (+ x 1)))

Then,

> 4. Break [5]> (funcall k 1)

should yield 2.


Pascal

-- 
Pascal Costanza               University of Bonn
···············@web.de        Institute of Computer Science III
http://www.pascalcostanza.de  R�merstr. 164, D-53117 Bonn (Germany)
From: Tim Bradshaw
Subject: Re: simple question (at least I hope so...)
Date: 
Message-ID: <ey3of5tme71.fsf@cley.com>
* Ryszard Szopa wrote:
> (defmacro calculate (expr y)
>     `(apply (lambda (x) ,expr) '(,y)))

Surely this will work:

(defun calculate (expr arg)
  (funcall (coerce `(lambda (x) ,expr) 'function) arg))

--tim
From: Kalle Olavi Niemitalo
Subject: Re: simple question (at least I hope so...)
Date: 
Message-ID: <87d6m9ci0w.fsf@Astalo.y2000.kon.iki.fi>
Ryszard Szopa <····@dont.ask.stupid.questions> writes:

> ``(calculate (aref *arr* 1) 1'',

You can do this with EVAL:

  (defun calculate (expr y)
    (eval `(let ((x ',y)) ,expr)))

Or with COERCE:

  (defun calculate (expr y)
    (funcall (coerce `(lambda (x) ,expr) 'function) y))
  ;; If you calculate the same expressions multiple times
  ;; with different parameters, you may be able to speed
  ;; things up by caching the resulting functions, and
  ;; perhaps even compiling them at run time.

Or, if the array is ready at read time:

  (calculate #.(aref *arr* 1) 1)