From: Constantine Vetoshev
Subject: A question about closures
Date: 
Message-ID: <87r9fkxz9z.fsf@leopard.dartmouth.edu>
Greetings all,

I'm in the process of teaching myself Common Lisp. I know Scheme
fairly well already, and I usually just try to recreate some of my
existing Scheme code in Common Lisp, trying to make use of as many of
CL's extensions as possible. Well, I just hit a stumbling block.

In Scheme, I can define a local state using closures by doing
something like this:

(define testfun
    (let ((counter 0))
      (lambda ()
	(set! counter (+ counter 1))
	(display counter))))

In this case, counter is a variable that maintains state throughout
all the invocations of testfun. I've been trying to do the same thing
with Common Lisp, and have run into the problem of the lack of a
general define statement. defun already creates the closure for
me. The only thing that I did that worked is:

(defconstant testfun
  (let ((counter 0))
    #'(lambda ()
	(incf counter)
	(print counter))))

And I call it using (funcall testfun). This seems like a very
desperate kludge, though. Is there any more elegant way, using defun
for example?

Thanks,
---Constantine Vetoshev

From: Frode Vatvedt Fjeld
Subject: Re: A question about closures
Date: 
Message-ID: <2hzou8xxq9.fsf@dslab7.cs.uit.no>
Constantine Vetoshev <····················@Dartmouth.EDU> writes:

> And I call it using (funcall testfun). This seems like a very
> desperate kludge, though. Is there any more elegant way, using defun
> for example?

Well, the obvious thing to do is

  (let ((counter 0))
    (defun testfun () ...))

However, (I believe) this is not typically done, because DEFUN works
on the global environment, and so any lexical variables like your
counter are really global variables, and more suitably established
with DEFVAR or DEFPARAMETER.

  (defvar *counter* 0)
  (defun testfun () ...)

Note that this reflects the real world situation much better than your
original closure construct in scheme (or CL), because for global
variables (which "counter" really is, lexical or not) you really do
need the control that DEFVAR and DEFPARAMETER provides. (The problem
is, when _exactly_ should the counter be initialized to zero?)

I may be wrong, but I think named closures are very rarely needed in
well-designed programs.

-- 
Frode Vatvedt Fjeld
From: Barry Margolin
Subject: Re: A question about closures
Date: 
Message-ID: <YaLf4.70$%%2.772@burlma1-snr2>
In article <··············@dslab7.cs.uit.no>,
Frode Vatvedt Fjeld  <······@acm.org> wrote:
>Well, the obvious thing to do is
>
>  (let ((counter 0))
>    (defun testfun () ...))
>
>However, (I believe) this is not typically done, because DEFUN works
>on the global environment, and so any lexical variables like your
>counter are really global variables, and more suitably established
>with DEFVAR or DEFPARAMETER.

Although you're correct that most CL programmers make use of global
variables for this, I can understand the original poster's wish.  A number
of languages have per-function static variables, I believe originally
called "own" variables in Algol.  With closures you can actually do better
than this -- you can have own variables that are shared by just a small
group of functions:

(let ((counter 0))
  (defun reinit ()
    (setq counter 0))
  (defun next ()
    (incf counter)
    counter))

The reason that you can generally get away with using global variables in
Common Lisp, rather than closures like this, is because of packages.
Without some kind of module or package system, it would be more likely that
different applications would try to use the same global variable names --
you can only have one global named "counter".  Closures allow you to keep
variables private -- the above functions don't interfere with any other
uses of variables named "counter".  A package or module system allows you
to use the same name in different programs, because they're in different
namespaces.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, 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.
From: Constantine Vetoshev
Subject: Re: A question about closures
Date: 
Message-ID: <87ogaocjvh.fsf@leopard.dartmouth.edu>
Barry Margolin <······@bbnplanet.com> writes:


> The reason that you can generally get away with using global variables in
> Common Lisp, rather than closures like this, is because of packages.
> Without some kind of module or package system, it would be more likely that
> different applications would try to use the same global variable names --
> you can only have one global named "counter".  Closures allow you to keep
> variables private -- the above functions don't interfere with any other
> uses of variables named "counter".  A package or module system allows you
> to use the same name in different programs, because they're in different
> namespaces.

My original reason for asking is that using global variables with
packages is just overkill for many purposes. My favorite example of
this is memoization. A simple implementation would involve calling a
function (memoize ...) that takes another function as a parameter and
returns a memoized version of the original function. The memoized
information can be stored in a list or an array within the closure of
the new function. (If anyone cares to see an implementation---I have
one in Dylan right now, but will rewrite it for Common Lisp when find
time---send me an e-mail.)

Regards,
---Constantine Vetoshev
From: Pierre R. Mai
Subject: Re: A question about closures
Date: 
Message-ID: <87puv4mn2i.fsf@orion.dent.isdn.cs.tu-berlin.de>
Constantine Vetoshev <····················@Dartmouth.EDU> writes:

> In Scheme, I can define a local state using closures by doing
> something like this:
> 
> (define testfun
>     (let ((counter 0))
>       (lambda ()
> 	(set! counter (+ counter 1))
> 	(display counter))))

You can do it in CL like this:

(let ((counter 0))
  (defun testfun ()
    (incf counter)
    (print counter)))

OTOH keep in mind that in CL you might prefer to use a global
parameter instead:

(defparameter *testfun-counter* 0
  "Current counter for testfun.")

(defun testfun ()
  (incf *testfun-counter*)
  (print *testfun-counter*))

This has a number of advantages as well as disadvantages when compared 
to the closure approach.  In general CL programmers lean towards the
second solution, though.

Regs, Pierre.

-- 
Pierre Mai <····@acm.org>         PGP and GPG keys at your nearest Keyserver
  "One smaller motivation which, in part, stems from altruism is Microsoft-
   bashing." [Microsoft memo, see http://www.opensource.org/halloween1.html]
From: Barry Margolin
Subject: Re: A question about closures
Date: 
Message-ID: <ywKf4.68$%%2.136@burlma1-snr2>
In article <··············@leopard.dartmouth.edu>,
Constantine Vetoshev  <····················@Dartmouth.EDU> wrote:
>(defconstant testfun
>  (let ((counter 0))
>    #'(lambda ()
>	(incf counter)
>	(print counter))))
>
>And I call it using (funcall testfun). This seems like a very
>desperate kludge, though. Is there any more elegant way, using defun
>for example?

(let ((counter 0))
  (defun testfun
    (incf counter)
    (print counter)))

There are some issues surrounding compiling this.  You may not be able to
do (compile 'testfun), but if you compile the file containing this there
should be no problem.  There was a thread a couple of months ago about
compiling closures that goes into this subject, you should be able to find
it on Deja.com.

-- 
Barry Margolin, ······@bbnplanet.com
GTE Internetworking, Powered by BBN, Burlington, 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.
From: Marco Antoniotti
Subject: Re: A question about closures
Date: 
Message-ID: <lwiu0r7g39.fsf@parades.rm.cnr.it>
Constantine Vetoshev <····················@Dartmouth.EDU> writes:

> Greetings all,
> 
> I'm in the process of teaching myself Common Lisp. I know Scheme
> fairly well already, and I usually just try to recreate some of my
> existing Scheme code in Common Lisp, trying to make use of as many of
> CL's extensions as possible.

.... which will make your programs much shorter, since you won't have
to recreate all the missing features of Scheme :)

> Well, I just hit a stumbling block.
> 
> In Scheme, I can define a local state using closures by doing
> something like this:
> 
> (define testfun
>     (let ((counter 0))
>       (lambda ()
> 	(set! counter (+ counter 1))
> 	(display counter))))
> 
> In this case, counter is a variable that maintains state throughout
> all the invocations of testfun. I've been trying to do the same thing
> with Common Lisp, and have run into the problem of the lack of a
> general define statement. defun already creates the closure for
> me. The only thing that I did that worked is:
> 
> (defconstant testfun
>   (let ((counter 0))
>     #'(lambda ()
> 	(incf counter)
> 	(print counter))))
> 
> And I call it using (funcall testfun). This seems like a very
> desperate kludge, though. Is there any more elegant way, using defun
> for example?

The easy way is to do the following

(let ((counter 0))
  (defun testfun ()
     (incf counter)
     (print counter)))

However, using packages you are better off doing something like

(in-package "MY-COUNTER")

(export '(testfun))

(defvar *counter* 0)

(defun testfun ()
  (incf *counter*)
  (print *counter*))

This is more C-like than Scheme.  Note that the symbol (i.e. the
variable) *COUNTER* is not exported from the package, hence giving you
control on its accesses (prsumably only from within the MY-COUNTER
package.


Cheers

-- 
Marco Antoniotti ===========================================
PARADES, Via San Pantaleo 66, I-00186 Rome, ITALY
tel. +39 - 06 68 10 03 17, fax. +39 - 06 68 80 79 26
http://www.parades.rm.cnr.it/~marcoxa