From: Joe Marshall
Subject: Re: What's the CL equivalent of Scheme's letrec?
Date:
Message-ID: <7k2utypg.fsf@ccs.neu.edu>
Wang Yin <··@wangyin.com> writes:
> Finally I reached this:
>
> (define (partial-sums s)
> (letrec ((p (cons-stream (stream-car s)
> (add-streams p (stream-cdr s)))))
> p))
>
>
> I don't know how to express this letrec in CL. I tried to express like
> this:
>
>
> (defun partial-sums (s)
> (let ((p nil))
> (setf p (cons-stream (stream-car s)
> (add-streams p (stream-cdr s))))
> p))
>
> But after doing that, p becomes globally visible!
> That should not happen.
I'm sure you accidentally did something that proclaimed P to be
special. Restart your lisp and try this again.
In article <············@ccs.neu.edu>, Joe Marshall <···@ccs.neu.edu> wrote:
> Wang Yin <··@wangyin.com> writes:
>
> > Finally I reached this:
> >
> > (define (partial-sums s)
> > (letrec ((p (cons-stream (stream-car s)
> > (add-streams p (stream-cdr s)))))
> > p))
> >
> >
> > I don't know how to express this letrec in CL. I tried to express like
> > this:
> >
> >
> > (defun partial-sums (s)
> > (let ((p nil))
> > (setf p (cons-stream (stream-car s)
> > (add-streams p (stream-cdr s))))
> > p))
> >
> > But after doing that, p becomes globally visible!
> > That should not happen.
>
> I'm sure you accidentally did something that proclaimed P to be
> special. Restart your lisp and try this again.
Or (unintern 'p) and try again.
E.
In article <··············@wangyin.com>, Wang Yin <··@wangyin.com> wrote:
>Finally I reached this:
>
>(define (partial-sums s)
> (letrec ((p (cons-stream (stream-car s)
> (add-streams p (stream-cdr s)))))
> p))
>
>
>I don't know how to express this letrec in CL. I tried to express like
>this:
I think this might be it, but I'm not sure:
(defun partial-sums (s)
(labels ((p ()
(lambda () (cons-stream (stream-car s)
(add-streams #'p (stream-cdr s))))))
#'p))
--
Barry Margolin, ··············@level3.com
Level(3), Woburn, MA
*** DON'T SEND TECHNICAL QUESTIONS DIRECTLY TO ME, post them to newsgroups.
Please DON'T copy followups to me -- I'll assume it wasn't posted to the group.
Wang Yin wrote:
> Hi,
>
> Question again :)
Answer: labels :)
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: Wang Yin
Subject: Re: What's the CL equivalent of Scheme's letrec?
Date:
Message-ID: <m3smliek7d.fsf@wangyin.com>
But it seems labels can only bind function bodies.
If I do like this:
(defun partial-sums (s)
(labels ((p (cons-stream (stream-car s)
(add-streams p (stream-cdr s)))))
p))
I got the following error:
Lambda-variable is not a symbol: (STREAM-CAR S).
Error flushed ...
I tried to solve the problem with
(defun partial-sums (s)
(let ((p '<undefined>))
(let ((temp (cons-stream (stream-car s)
(add-streams p (stream-cdr s)))))
(setf p temp))
p))
just as the Scheme macro does. It works.
If there is not equivalent of letrec in CL. I'd like to write a macro
myself :)
--
Yin Wang,
EDA Lab,
Deparment of Computer Science and Technology,
Tsinghua University,
100084
Beijing China
Labels is like defun or flet; you need to specify the function's
parameters:
(defun partial-sums (s)
(labels ((p () (cons-stream (stream-car s)
(add-streams p (stream-cdr s)))))
#'p))
Hope that helps,
Justin Dubs
From: Wang Yin
Subject: Re: What's the CL equivalent of Scheme's letrec?
Date:
Message-ID: <m37k2osd8n.fsf@wangyin.com>
I forgot to tell you that, p is a variable, not a function.
p is a "stream object" (a delayed list) that partial-sums return.
(defun partial-sums (s)
(letrec ((p (cons-stream (stream-car s)
(add-streams p (stream-cdr s)))))
p))
is equivalent to
(defun partial-sums (s)
(letrec ((p (cons (car s)
(lambda () (add-streams p (stream-cdr s))))))
p))
So you see here, the second p is inside a lambda. It must refer to the
very variable p we are creating. It seems that labels will not do the
work to set a variable.
--
Yin Wang,
EDA Lab,
Deparment of Computer Science and Technology,
Tsinghua University,
100084
Beijing China
Wang Yin wrote:
> I forgot to tell you that, p is a variable, not a function.
> p is a "stream object" (a delayed list) that partial-sums return.
>
> (defun partial-sums (s)
> (letrec ((p (cons-stream (stream-car s)
> (add-streams p (stream-cdr s)))))
> p))
>
> is equivalent to
>
> (defun partial-sums (s)
> (letrec ((p (cons (car s)
> (lambda () (add-streams p (stream-cdr s))))))
> p))
>
>
> So you see here, the second p is inside a lambda. It must refer to the
> very variable p we are creating. It seems that labels will not do the
> work to set a variable.
Functions and variables in CL live in separate spaces. I showed you how
you can get a similar result in CL, but I still have to point out that
most likely in CL you have a better way of doing whatever you are trying
to do by emulating Scheme.
Cheers
--
Marco
Wang Yin wrote:
> But it seems labels can only bind function bodies.
>
> If I do like this:
>
> (defun partial-sums (s)
> (labels ((p (cons-stream (stream-car s)
> (add-streams p (stream-cdr s)))))
> p))
The syntax is wrong. Assuming that this is the standard example of
STREAMS (as defined in SICP,) you should write
(defun partial-sums (s)
(labels ((p ()
(cons-stream (stream-car s)
(add-streams #'p (stream-cdr s))))
)
#'p))
(I am not sure it will work. I have not tested it and I do not remember
off the top of my head if LABELS creates bindings with indefinite extent)
> I got the following error:
>
> Lambda-variable is not a symbol: (STREAM-CAR S).
> Error flushed ...
>
>
> I tried to solve the problem with
>
> (defun partial-sums (s)
> (let ((p '<undefined>))
> (let ((temp (cons-stream (stream-car s)
> (add-streams p (stream-cdr s)))))
> (setf p temp))
> p))
>
> just as the Scheme macro does. It works.
>
> If there is not equivalent of letrec in CL. I'd like to write a macro
> myself :)
Pardon the bluntness, but.... why do you need that?
Cheers
--
Marco