From: Yongwei Xing on
Hi all

Today I read the book SICP, chapter 3. I read the code below
(define (make-simplified-withdraw balance)
(lambda (amount)
(set! balance (- balance amount))
balance))

I use the common lisp write like below
(defun (make-simplified-withdraw balance)
(lambda (amount)
(setf balance (- balance amount))
balance))

Then I use it like below:
(defvar x (make-simplified-withdraw 100) )
(x 10)
It would give a error:
Then I use it
(funcall x 10)
It works.
Can someone explain why?

Best Regards,
From: D Herring on
Yongwei Xing wrote:
> Hi all
>
> Today I read the book SICP, chapter 3. I read the code below
> (define (make-simplified-withdraw balance)
> (lambda (amount)
> (set! balance (- balance amount))
> balance))
>
> I use the common lisp write like below
> (defun (make-simplified-withdraw balance)
> (lambda (amount)
> (setf balance (- balance amount))
> balance))

You mean
(defun make-simplified-withdraw (balance)
(lambda (amount)
(setf balance (- balance amount))
balance))
?

> Then I use it like below:
> (defvar x (make-simplified-withdraw 100) )
> (x 10)
> It would give a error:
> Then I use it
> (funcall x 10)
> It works.
> Can someone explain why?

Scheme is a "lisp-1" and Common Lisp (CL) is a "lisp-2". FYI, the
terms were coined in the following paper which you don't need to read
right now.
http://www.nhplace.com/kent/Papers/Technical-Issues.html

The essential point is that CL symbols have two values: a
"symbol-function" and a "symbol-value". Scheme symbols only have a
single value. CL uses the symbol-function for the first entry in a
form, and the symbol-value for the rest. Scheme uses the same value
in both places.

Consider the simple example (f f).
In common lisp, this represents a function named f being passed the
value in variable f (which is probably not the function f).
In scheme, this represents the function f being passed itself.

A CL defvar sets the symbol-value, not the symbol-function. So when
you evaluate (x 10), CL complains that the symbol-function was not
set. When you (funcall x 10), funcall receives the value of x (a
lambda function) and the argument 10.

Does that help?

- Daniel
From: Yongwei Xing on
On 1ÔÂ3ÈÕ, ÏÂÎç2ʱ59·Ö, D Herring <dherr...(a)at.tentpost.dot.com> wrote:
> Yongwei Xing wrote:
> > Hi all
>
> > Today I read the book SICP, chapter 3. I read the code below
> > (define (make-simplified-withdraw balance)
> > (lambda (amount)
> > (set! balance (- balance amount))
> > balance))
>
> > I use the common lisp write like below
> > (defun (make-simplified-withdraw balance)
> > (lambda (amount)
> > (setf balance (- balance amount))
> > balance))
>
> You mean
> (defun make-simplified-withdraw (balance)
> (lambda (amount)
> (setf balance (- balance amount))
> balance))
> ?
>
> > Then I use it like below:
> > (defvar x (make-simplified-withdraw 100) )
> > (x 10)
> > It would give a error:
> > Then I use it
> > (funcall x 10)
> > It works.
> > Can someone explain why?
>
> Scheme is a "lisp-1" and Common Lisp (CL) is a "lisp-2". FYI, the
> terms were coined in the following paper which you don't need to read
> right now.http://www.nhplace.com/kent/Papers/Technical-Issues.html
>
> The essential point is that CL symbols have two values: a
> "symbol-function" and a "symbol-value". Scheme symbols only have a
> single value. CL uses the symbol-function for the first entry in a
> form, and the symbol-value for the rest. Scheme uses the same value
> in both places.
>
> Consider the simple example (f f).
> In common lisp, this represents a function named f being passed the
> value in variable f (which is probably not the function f).
> In scheme, this represents the function f being passed itself.
>
> A CL defvar sets the symbol-value, not the symbol-function. So when
> you evaluate (x 10), CL complains that the symbol-function was not
> set. When you (funcall x 10), funcall receives the value of x (a
> lambda function) and the argument 10.
>
> Does that help?
>
> - Daniel

Hi Daniel

Thanks very much for your detailed explanation.

One question, if I want to use it like the Schema (f 10). What should
I do in the commin lisp?

Best Regards,
From: D Herring on
Yongwei Xing wrote:
> On 1��3��, ����2ʱ59��, D Herring <dherr...(a)at.tentpost.dot.com> wrote:
>> Yongwei Xing wrote:
>>> Today I read the book SICP, chapter 3. I read the code below
>>> (define (make-simplified-withdraw balance)
>>> (lambda (amount)
>>> (set! balance (- balance amount))
>>> balance))
>>
>> (defun make-simplified-withdraw (balance)
>> (lambda (amount)
>> (setf balance (- balance amount))
>> balance))

> Thanks very much for your detailed explanation.
You're welcome.

> One question, if I want to use it like the Schema (f 10). What should
> I do in the commin lisp?
(defvar x) ; you can give it a value if desired
(setf (symbol-function 'x) (make-simplified-withdraw 10))
(x 10)

Later,
Daniel
From: Nicolas Neuss on
Yongwei Xing <jdxyw2004(a)gmail.com> writes:

> Thanks very much for your detailed explanation.
>
> One question, if I want to use it like the Schema (f 10). What should
> I do in the commin lisp?

You mean "The Coming Lisp"? :-)

Ask yourself also the question if you really that short notation. The
interpretation of this message passing OO stuff is something like "send
object message", so instead of getting around funcall one better should
rename it:

(defun send (object arg)
(funcall object arg))

(I have introduced such a send function even when using Scheme.)

Nicolas