From: H. Tunc Simsek
Subject: [closures] compilation of
Date: 
Message-ID: <3848AD2A.7C89C92F@EECS.Berkeley.Edu>
Why can't you compile closures?

(let ((x 1))
  (defun dene () 
      x))

(compile 'dene)

From: H. Tunc Simsek
Subject: Re: [closures] compilation of
Date: 
Message-ID: <3848AD62.9786FD4E@EECS.Berkeley.Edu>
I forgot to mention, my platform is CMUCL solaris.

Tunc

"H. Tunc Simsek" wrote:
> 
> Why can't you compile closures?
> 
> (let ((x 1))
>   (defun dene ()
>       x))
> 
> (compile 'dene)
From: David J. Cooper
Subject: Re: [closures] compilation of
Date: 
Message-ID: <3848B1A2.616828B@genworks.com>
"H. Tunc Simsek" wrote:
> 
> I forgot to mention, my platform is CMUCL solaris.
> 
> Tunc
> 
> "H. Tunc Simsek" wrote:
> >
> > Why can't you compile closures?
> >
> > (let ((x 1))
> >   (defun dene ()
> >       x))
> >
> > (compile 'dene)

In Allegro 5.01:

IDL-USER(2): (let ((x 1))
	       (defun de ()
		 x))
DE
IDL-USER(3): (compile 'de)
; While compiling DE:
Warning: Attempting to compile an interpreted closure: DE
DE
T
T
IDL-USER(4):


-- 
David J. Cooper Jr, Chief Engineer	Genworks International
·······@genworks.com			5777 West Maple, Suite 130
(248) 932-2512 (Genworks HQ/voicemail)	West Bloomfield, MI 48322-2268
(248) 407-0633 (pager)			http://www.genworks.com
From: Tim Bradshaw
Subject: Re: [closures] compilation of
Date: 
Message-ID: <ey3zovrkkqu.fsf@lostwithiel.tfeb.org>
* Christopher R Barry wrote:

> You can't compile an interpreted closure in any Lisp. AFAIK, it is
> basically impossible to do from an implementor's perspective. The
> standard may even be explicit about this (or have a cleanup issue or
> something--I'm too lazy to look for it). Anyways, you can do:

The standard says it is undefined. 

Some implementations allow it:

    > (let ((x 1)) (defun foo (y) (+ y x)) (defun bar (y) (setf x y)))
    bar
    > (foo 1)
    2
    > (bar 2)
    2
    > (foo 1)
    3
    > (compile 'foo)
    foo
    > (foo 1)
    3
    > (bar 4)
    4
    > (foo 1)
    5

(and yes, this is an implementation with a compiler)

--tim
From: Christopher R. Barry
Subject: Re: [closures] compilation of
Date: 
Message-ID: <87g0xiwqz3.fsf@2xtreme.net>
"H. Tunc Simsek" <······@EECS.Berkeley.Edu> writes:

> Nope.  That doesn't work, and careful inspection reveals that
> it is no different than the original example:
> 
> * (let ((x 1))
>     (compile (defun dene () x)))

Oops. I forgot to wrap the LET into the COMPILE. This should work:

  (funcall (compile nil (lambda () (let ((x 1)) (defun dene () x)))))

The Lisp I used for testing the original version actually accepted it....

Christopher
From: Eugene Zaikonnikov
Subject: Re: [closures] compilation of
Date: 
Message-ID: <3848E5A7.E83670F8@cit.org.by>
"H. Tunc Simsek" wrote:
> 
> Here is a quote from the ACL windows help file:
> 
> "compile is rarely called since Allegro CL for Windows compiles
> everything on definition anyway."
> 
Maybe it's true for Windows version, but:

USER(2): (lisp-implementation-version)
"5.0.1 [Linux/X86] (6/29/99 16:11)"
USER(3): (defun test (x) x)
TEST
USER(4): (compiled-function-p #'test)
NIL

--
  Eugene
  (concatenate 'string "viking" ·@" "cit.org.by")
From: Espen Vestre
Subject: Re: [closures] compilation of
Date: 
Message-ID: <w6so1hqamv.fsf@wallace.nextel.no>
"David J. Cooper" <·······@genworks.com> writes:

> Warning: Attempting to compile an interpreted closure: DE

it warns, but id *does* compile!

-- 
  (espen)
From: Duane Rettig
Subject: Re: [closures] compilation of
Date: 
Message-ID: <44sdwm1xn.fsf@beta.franz.com>
"H. Tunc Simsek" <······@EECS.Berkeley.Edu> writes:

> Here is a quote from the ACL windows help file:
> 
> "compile is rarely called since Allegro CL for Windows compiles
> everything on definition anyway."

You're probably looking at ACL/Win 3.x documentation.  Anything 5.0
and greater does not compile automatically, whether on Unixen or on
Windows.

> "Christopher R. Barry" wrote:
> > 
> > "H. Tunc Simsek" <······@EECS.Berkeley.Edu> writes:
> > 
> > > I believe that Allegro compiles everything by default, I remember
> > > reading about that somewhere.
> > 
> > No. The Allegro CL top-level is interpreted.
> 
> ...
> 
> > Christopher

-- 
Duane Rettig          Franz Inc.            http://www.franz.com/ (www)
1995 University Ave Suite 275  Berkeley, CA 94704
Phone: (510) 548-3600; FAX: (510) 548-8253   ·····@Franz.COM (internet)
From: Rob Warnock
Subject: Re: [closures] compilation of
Date: 
Message-ID: <82aqo2$8lhp6@fido.engr.sgi.com>
H. Tunc Simsek <······@EECS.Berkeley.Edu> wrote:
+---------------
| Why can't you compile closures?
| (let ((x 1))
|   (defun dene () 
|       x))
| (compile 'dene)
+---------------

Well, you *can*, just not exactly *that* way. ;-}  Whenever you compile
a top-level function, any closures within it also get compiled. So you
can define (and then compile) a top-level "closure generator" that does
what you want, albeit slightly awkwardly [though that can be fixed with
suitable macrology]. My normal example of such things is a generator of
counters, but let's use your example [aside: what does "dene" mean?]:

	> (defun make-dene (&key (init 0))
	    (let ((x init))
	      #'(lambda () x)))
	MAKE-DENE
	> (setf (symbol-function 'dene) (make-dene :init 1))
	#<Interpreted Function "LAMBDA (&KEY (INIT 0))" {90808E9}>
	> (dene)
	1
	> (describe 'dene)
	DENE is an internal symbol in the COMMON-LISP-USER package.
	Function: #<Interpreted Function "LAMBDA (&KEY (INIT 0))" {90BA369}>
	Function arguments: There are no arguments.
	Its defined argument types are: NIL
	Its result type is: *
	Its closure environment is:
	  0: 1
	Its definition is:
	  (LAMBDA () X)
	>

Now compile "make-dene", and see how it changes things:

	> (compile 'make-dene)
	Compiling LAMBDA (&KEY (INIT 0)): 
	Compiling Top-Level Form: 
	MAKE-DENE
	NIL
	NIL
	> (setf (symbol-function 'dene) (make-dene :init 23))
	#<Closure Over Function "LAMBDA (&KEY (INIT 0))" {90A5C19}>
	> (dene)
	23
	> (describe 'dene)
	DENE is an internal symbol in the COMMON-LISP-USER package.
	Function: #<Closure Over Function "LAMBDA (&KEY (INIT 0))" {90A62E1}>
	Function arguments: There are no arguments.
	Its defined argument types are: NIL
	Its result type is: T
	On Saturday, 12/4/99 02:20:12 am PST it was compiled from:
	#(#'(LAMBDA # #))
	Its closure environment is:
	0: 23
	> 

Is that close enough to what you were looking for?


-Rob

-----
Rob Warnock, 8L-846		····@sgi.com
Applied Networking		http://reality.sgi.com/rpw3/
Silicon Graphics, Inc.		Phone: 650-933-1673
1600 Amphitheatre Pkwy.		FAX: 650-933-0511
Mountain View, CA  94043	PP-ASEL-IA
From: Tim Bradshaw
Subject: Re: [closures] compilation of
Date: 
Message-ID: <ey31z93lzkb.fsf@lostwithiel.tfeb.org>
* H Tunc Simsek wrote:
> Why can't you compile closures?
> (let ((x 1))
>   (defun dene () 
>       x))

I think the reason is implementational.  

Interpreted and compiled closures may have differing representations
of the closed-over environment -- typically an interpreted closure
might have some simple but low performance representation (an alist
say) whereas a compiled closure might do some much cleverer trick like
allocating a vector of objects and then compiling references into this
vector.

Compiling a closure would involve changing the representation of the
environment from one to the other.

However, if there is more than one user of the closed-over
environment, then this is fairly difficult -- the compiler *can't*
unilaterally change the representation, because the other users may
still be interpreted.  You can't take a copy of the environment when
compiling either, because that breaks the program.  And finally, you
probably can't know who all the other users are and compile them.

So compiling a closure may be implementationally very hard, and
therefore the result is left as `undefined' in the standard.

Note that this *doesn't* imply that closures are never compiled, they
just have to be compiled in such a way that the compiler can see
`enough', like this say:

	(defun make-foo (x)
	  (defun foo (y)
	    (+ x y)))

	(compile 'make-foo)
	(make-foo)
	;; now FOO is a compiled closure

--tim	
From: Jeff Dalton
Subject: Re: [closures] compilation of
Date: 
Message-ID: <x2puwiskbm.fsf@todday.aiai.ed.ac.uk>
Tim Bradshaw <···@tfeb.org> writes:

> * H Tunc Simsek wrote:
> > Why can't you compile closures?
> > (let ((x 1))
> >   (defun dene () 
> >       x))
> 
> I think the reason is implementational.  
> 
> Interpreted and compiled closures may have differing representations
> of the closed-over environment -- typically an interpreted closure
> might have some simple but low performance representation (an alist
> say) whereas a compiled closure might do some much cleverer trick like
> allocating a vector of objects and then compiling references into this
> vector.

But in a somewhat simple Lisp, compiling closures should not be all
that hard.  You have a data structure that contains variable values,
and perhaps even the names of the "closed over" variables; and then
you just think in terms of an imaginary symbol-macrolet "wrapper" that
maps the free variables in the closure's code to the corresponding
data structure references.  [If the env data includes variable names,
you can just put them all in the symbol-macrolet, because lexical
scoping will ensure that only the free ones ever matter.]

> Compiling a closure would involve changing the representation of the
> environment from one to the other.

Not necessarily, becuase you can use the interpreter's version as
a data structure (as suggested above).

> However, if there is more than one user of the closed-over
> environment, then this is fairly difficult -- the compiler *can't*
> unilaterally change the representation, because the other users may
> still be interpreted.  You can't take a copy of the environment when
> compiling either, because that breaks the program.  And finally, you
> probably can't know who all the other users are and compile them.

But you don't need to do any of those things.

> So compiling a closure may be implementationally very hard, and
> therefore the result is left as `undefined' in the standard.

Well, it's certainly something that would require some extra work, and
may make it harder to optimize some things.  The ability to compile
closures is probably not sufficiently valuable.

There may also be something about Common Lisp that makes it much
harder than I've suggested above [hence my "somewhat simple"
qualification].  You can also close over function and block names
(and go tags).  That at least complicates things.  I can't think
of any other factors off hand.

-- j
From: Roger Corman
Subject: Re: [closures] compilation of
Date: 
Message-ID: <384d79d9.1648991904@nntp.best.com>
On 07 Dec 1999 17:59:57 +0000, Jeff Dalton <····@todday.aiai.ed.ac.uk>
wrote:

>Tim Bradshaw <···@tfeb.org> writes:
>
>> * H Tunc Simsek wrote:
>> > Why can't you compile closures?
>> > (let ((x 1))
>> >   (defun dene () 
>> >       x))
>> 
>> I think the reason is implementational.  
>> 
>> Interpreted and compiled closures may have differing representations
>> of the closed-over environment -- typically an interpreted closure
>> might have some simple but low performance representation (an alist
>> say) whereas a compiled closure might do some much cleverer trick like
>> allocating a vector of objects and then compiling references into this
>> vector.
>
>But in a somewhat simple Lisp, compiling closures should not be all
>that hard.  You have a data structure that contains variable values,
>and perhaps even the names of the "closed over" variables; and then
>you just think in terms of an imaginary symbol-macrolet "wrapper" that
>maps the free variables in the closure's code to the corresponding
>data structure references.  [If the env data includes variable names,
>you can just put them all in the symbol-macrolet, because lexical
>scoping will ensure that only the free ones ever matter.]
>
>> Compiling a closure would involve changing the representation of the
>> environment from one to the other.
>
>Not necessarily, becuase you can use the interpreter's version as
>a data structure (as suggested above).

I ran into problems with this (compiling closures) when I wrote
PowerLisp, which included both the standard integrated compiler and
interpreter. For this and several other reasons, I chose to go with
compiler-only for Corman Lisp. This has been far easier to maintain
and enhance. When you try to support both interpreted and compiled
code you end up with subtle behavioral differences if you are not very
careful every step of the way. Areas I found tricky in this regard
included closures, special variable binding, exception-handling,
debugging tools and declaration processing, to name a few.

By the way, I always assumed that the Common Lisp rule against
compiling functions with non-null lexical environments was in
deference to those implementations which could not easily support
this. However, I think it is a pretty ugly limitation of the language,
where you can otherwise treat a function as a function, regardless of
how it was defined. Also, I don't think the standard provides any way
to determine if an interpreted function was defined in a non-null
lexical environment or not.

Roger Corman
From: Barry Margolin
Subject: Re: [closures] compilation of
Date: 
Message-ID: <iYl34.35$xB.1628@burlma1-snr2>
In article <···················@nntp.best.com>,
Roger Corman <·····@xippix.com> wrote:
>By the way, I always assumed that the Common Lisp rule against
>compiling functions with non-null lexical environments was in
>deference to those implementations which could not easily support
>this. However, I think it is a pretty ugly limitation of the language,
>where you can otherwise treat a function as a function, regardless of
>how it was defined. Also, I don't think the standard provides any way
>to determine if an interpreted function was defined in a non-null
>lexical environment or not.

Yes, I think it was a concession to simplify compiler implementations.
However, it wasn't seen as a significant hardship, because of the
expectations about how people deploy software.  In general, programmers
compile files, and that's where functions in non-null environments will be
found, so they'll be compiled.  Functions that need to be compiled at
runtime are generally those that were constructed on the fly by consing up
a lambda expression and coercing it to type FUNCTION, or by passing the
lambda expression as a second argument to COMPILE; these will always be in
a null lexical environment.

Yes, it's possible to do (eval '(defun outer (x) (defun inner ...))), and
then you could conceivably want to compiler INNER without compiling OUTER.
But this unusual combination wasn't considered important enough to require
implementors to go the extra mile to support compiled access to interpreted
environments.

Can someone explain realistic circumstances when it's necessary to compile
lexical closures rather than compiling the surrounding function?

-- 
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: Robert Monfera
Subject: Re: [closures] compilation of
Date: 
Message-ID: <384E4E70.FA454E69@fisec.com>
Barry Margolin wrote:

> Can someone explain realistic circumstances when it's necessary to compile
> lexical closures rather than compiling the surrounding function?

I have been trying scenarios with SORT and STABLE-SORT.  They take
functions as arguments.  My purpose is to sort a vector, which contains
row numbers of a two-dimensional array.  It means that the functions
need to refer to values beyond the actual values in the vector.

(let ((shuffled-keys (make-array ...
.....
   (sort selected-index #'<
	:key #'(lambda (x)(declare (type fixnum x))
        	(let ((r (aref shuffled-keys x 0)))
                     (declare (type fixnum r))
                     r)))

I think this is a very real scenario, and I currently see no way of
using SORT with a compiled closure.  The only workaround I came up with
is the binary composition of array values, but it results in huge
bignums for no defendable reason :-( other than the unavailability of
compiled closures).  I was thinking of defining and compiling an
auxiliary function, which would take the number of arguments suitable
for comparison or key (2 and 1, respectively) - but it also results in
an interpreted function / closure.

Any thoughts?

Robert
From: Tim Bradshaw
Subject: Re: [closures] compilation of
Date: 
Message-ID: <ey3n1rlleh2.fsf@cley.com>
* Robert Monfera wrote:
> need to refer to values beyond the actual values in the vector.

> (let ((shuffled-keys (make-array ...
> .....
>    (sort selected-index #'<
> 	:key #'(lambda (x)(declare (type fixnum x))
>         	(let ((r (aref shuffled-keys x 0)))
>                      (declare (type fixnum r))
>                      r)))

You need to give more context.  If this is part of a function
definition then the closure will be compiled.  If it's in a file which
you compile & load, it will be compiled.  If you are typing it at the
top level of a lisp it will be compiled if the lisp compiles by
default.  The only way I can really see that it can *not* be compiled
is something like this:

	lisp> (let (...) (defun keyfun (x) ...))
	;; (compile 'keyfun) may not work here
	lisp> (sort selected-index #'< :key #'keyfun)

--tim
From: Jeff Dalton
Subject: Re: [closures] compilation of
Date: 
Message-ID: <x27lip2zf6.fsf@todday.aiai.ed.ac.uk>
Tim Bradshaw <···@cley.com> writes:

> * Robert Monfera wrote:
> > need to refer to values beyond the actual values in the vector.
> 
> > (let ((shuffled-keys (make-array ...
> > .....
> >    (sort selected-index #'<
> > 	:key #'(lambda (x)(declare (type fixnum x))
> >         	(let ((r (aref shuffled-keys x 0)))
> >                      (declare (type fixnum r))
> >                      r)))
> 
> You need to give more context.  If this is part of a function
> definition then the closure will be compiled.  If it's in a file which
> you compile & load, it will be compiled.  If you are typing it at the
> top level of a lisp it will be compiled if the lisp compiles by
> default.  The only way I can really see that it can *not* be compiled
> is something like this:
> 
> 	lisp> (let (...) (defun keyfun (x) ...))
> 	;; (compile 'keyfun) may not work here
> 	lisp> (sort selected-index #'< :key #'keyfun)

That's not quite right, because there are implementations that do not
compile forms that don't "look like" definitions, even when they're
compiling a file containing such forms.  If you write 

 (let ((shuffled-keys (make-array ...)))
   .....
   (sort selected-index #'<
     :key #'(lambda (x)(declare (type fixnum x))
              (let ((r (aref shuffled-keys x 0)))
                (declare (type fixnum r))
                r))))

at the top level of a file -- not inside any DEFUN -- it might not
be compiled even when the compiler compiles that file.

Moreover, if you write (let (...) (defun keyfun (x) ...)), keyfun may
not get compiled, because the implementation doesn't look inside the
LET to see that there's a DEFUN there.

It may look like an implementation that can compile a function that's
defined inside a LET -- as in (let (...) (defun keyfun (x) ...)) --
must be able to compile closures; but that's not so.

Implementations that *do* compile such things typically do it
as if the top-level form were wrapped inside a function definition.
So if they see (let ...), they treat it as if it were

  (defun hidden-name ()
    (let ...))

where hidden name is a gensym or something like that.  They then
emit a call to the function (to be performed a load time).  Since
this function is called only once, implementations sometimes take
that into account, or they might avoid actually creating the 
hidden-name, or depart in other ways from this model.  But
"they pretend it's wrapped in a defun" is still a good way
to understand how such things can be done.

---- Anyway ---

I think there's sometimes a confusion that can be seen as due to
an equivocation on the word "compiled".

We've been saying a closure cannot be compiled (verb).  If you have
a function object that is already a closure over a non-null env, you
(typically) cannot get COMPILE to compile it.

But, as Tim noted earlier "this *doesn't* imply that closures are
never compiled".  There can be [functions that are] compiled (adjective)
closures.  You just have to create them in some other way -- not
by giving something that's already a closure to COMPILE.

For instance,

(defun make-keyfun (shuffled-keys)
   #'(lambda (x) (declare (type fixnum x))
       (let ((r (aref shuffled-keys x 0)))
          (declare (type fixnum r))
          r)))

If you compile make-keyfun and then call it, it should return a
function that is a compiled closure.

Similarly, if you write

(defun sort-it (...)
  (let ((shuffled-keys (make-array ...)))
    (sort ...
      :key #'(lambda (x) ... ))))

and compile sort-it, then when sort-it is called, sort will be
called with a :key that is a compiled closure.

But if make-keyfun has *not* been compiled, and you call it, you
will get an closure that contains code that hasn't been compiled.
If you then try to compile that "interpreted" closure, COMPILE
will complain.

-- jeff
From: Tim Bradshaw
Subject: Re: [closures] compilation of
Date: 
Message-ID: <ey3r9gxxp9a.fsf@cley.com>
* Jeff Dalton wrote:

> That's not quite right, because there are implementations that do not
> compile forms that don't "look like" definitions, even when they're
> compiling a file containing such forms.  If you write 

Of course -- I should have thought of that as I'm sitting about a foot
from a Symbolics, which has exactly this (rather annoying I find!)
property.  I have resorted to something exactly like what you describe
to get around this in the past, something like:

    (progn 
      (defun #1=#:foo ()
	(let ((x 1))
	  (defun counter (y)
	    (incf x y))))
      (#1#))

(I always like the (#1#) thing...)

--tim
From: Robert Monfera
Subject: Re: [closures] compilation of
Date: 
Message-ID: <384D838B.6199104C@fisec.com>
Is it not a closure compilation?  Does the message mean it stays
interpreted? (Excerpt from LWW 4.1.18.)

CL-USER 225 > (let ((x 8))
                (setf adder (compile nil #'(lambda (y) (+ x y)))))
;;;*** Warning between functions:   The definition supplied, #<closure
SPECIAL::APPLY-INTERPRETED-CLOSURE 20405AAA>, is already compiled.
#<closure SPECIAL::APPLY-INTERPRETED-CLOSURE 20405AAA>

CL-USER 226 > (funcall adder 3)
11

Robert (this is not a return value)
From: Pekka P. Pirinen
Subject: Re: [closures] compilation of
Date: 
Message-ID: <ixn1rlffb9.fsf@gaspode.cam.harlequin.co.uk>
Robert Monfera <·······@fisec.com> writes:
> Is it not a closure compilation?  Does the message mean it stays
> interpreted? (Excerpt from LWW 4.1.18.)
> 
> CL-USER 225 > (let ((x 8))
>                 (setf adder (compile nil #'(lambda (y) (+ x y)))))
> ;;;*** Warning between functions:   The definition supplied, #<closure
> SPECIAL::APPLY-INTERPRETED-CLOSURE 20405AAA>, is already compiled.
> #<closure SPECIAL::APPLY-INTERPRETED-CLOSURE 20405AAA>

It's not closure compilation.  The message is slightly misleading: the
result of such a #'(lambda ...) in LWW interpreted code is a compiled
function object (a trampoline) that invokes the interpreter in the
right way to evaluate the closure.  This name of this compiled
function object is APPLY-INTERPRETED-CLOSURE, as you can see above,
and it is itself a closure (over the interpreter's representation of
the environment, naturally).  More than you wanted know, I'm sure.
-- 
Pekka P. Pirinen
          "The question of whether a computer can think is no more
interesting than the question of whether a submarine can swim."
                    E. W. Dijkstra 
From: Jeff Dalton
Subject: Re: [closures] compilation of
Date: 
Message-ID: <x266y82i3n.fsf@todday.aiai.ed.ac.uk>
·····@harlequin.co.uk (Pekka P. Pirinen) writes:

> 
> Robert Monfera <·······@fisec.com> writes:
> > Is it not a closure compilation?  Does the message mean it stays
> > interpreted? (Excerpt from LWW 4.1.18.)
> > 
> > CL-USER 225 > (let ((x 8))
> >                 (setf adder (compile nil #'(lambda (y) (+ x y)))))
> > ;;;*** Warning between functions:   The definition supplied, #<closure
> > SPECIAL::APPLY-INTERPRETED-CLOSURE 20405AAA>, is already compiled.
> > #<closure SPECIAL::APPLY-INTERPRETED-CLOSURE 20405AAA>
> 
> It's not closure compilation.

Um, *why* isn't it?  The result of #'(lambda (y) (+ x y)) will be
a closure, and it's being given to COMPILE.  Note that there's even
a free variable -- x -- in the lambda-expression.  So how can it not
be a closure compilation?

I suppose it might be said not to be a closure compilation if the
result of #'(lambda (y) (+ x y)) was *already* compiled, but the
explanation of the name APPLY-INTERPRETED-CLOSURE says that it
still contains interpreted code:

  The message is slightly misleading: the
> result of such a #'(lambda ...) in LWW interpreted code is a compiled
> function object (a trampoline) that invokes the interpreter in the
> right way to evaluate the closure.  This name of this compiled
> function object is APPLY-INTERPRETED-CLOSURE, as you can see above,
> and it is itself a closure (over the interpreter's representation of
> the environment, naturally).  More than you wanted know, I'm sure.

It's true that there's a compiled function wrapped around the
interpreted code, but that appears to be just the way that
"interpreted" closures are represented in this Lisp.

> Pekka P. Pirinen
>           "The question of whether a computer can think is no more
> interesting than the question of whether a submarine can swim."
>                     E. W. Dijkstra 

It depends on what you mean by the question.
From: Christopher R. Barry
Subject: Re: [closures] compilation of
Date: 
Message-ID: <87d7sgq959.fsf@2xtreme.net>
Jeff Dalton <····@todday.aiai.ed.ac.uk> writes:

> >           "The question of whether a computer can think is no more
> > interesting than the question of whether a submarine can swim."
> >                     E. W. Dijkstra 
> 
> It depends on what you mean by the question.

Huh???

Christopher
[Who probably just started a huge off-topic thread on AI philosophy
where 20 different people will have A Really Important Opinion That
Matters.... ;-) ]
From: Jeff Dalton
Subject: Re: [closures] compilation of
Date: 
Message-ID: <x2n1reah46.fsf@todday.aiai.ed.ac.uk>
······@2xtreme.net (Christopher R. Barry) writes:

> Jeff Dalton <····@todday.aiai.ed.ac.uk> writes:
> 
> > >           "The question of whether a computer can think is no more
> > > interesting than the question of whether a submarine can swim."
> > >                     E. W. Dijkstra 
> > 
> > It depends on what you mean by the question.
> 
> Huh???

If the question is about whether we can use the word, then of course
we could decide to use "think" for something that computers happen to
be able to do -- whether or not it's interestingly like the way humans
think -- or we might decide that "think" only applies to something
the way humans do it.  Chomsky gives an example: we say airplanes fly
but don't say ships swim (though actually it is sometimes said that
ships, or submarines, swim).  [And by "we ... decide" I really mean
that our languge will evolve in that way, not that we somehow
explicitly decide this.]

On the other hand, if I have a particular meaning of "think" in mind
and ask whether a computer can think *in that sense* that might be a
very interesting question (or not, depending on what sense of "think"
I have in mind).

-- jd
From: Pekka P. Pirinen
Subject: Re: [closures] compilation of
Date: 
Message-ID: <ixbt7yacse.fsf@gaspode.cam.harlequin.co.uk>
Jeff Dalton <····@todday.aiai.ed.ac.uk> writes:
> ·····@harlequin.co.uk (Pekka P. Pirinen) writes:
> > > CL-USER 225 > (let ((x 8))
> > >                 (setf adder (compile nil #'(lambda (y) (+ x y)))))
> > > ;;;*** Warning between functions:   The definition supplied, #<closure
> > > SPECIAL::APPLY-INTERPRETED-CLOSURE 20405AAA>, is already compiled.
> > 
> > It's not closure compilation.
> 
> Um, *why* isn't it?

Because it didn't compile anything; it just signalled a warning
saying, in effect: "But this thing is already compiled!  It's
pointless to call COMPILE on it."  We were a bit lazy there, and
didn't bother to provide a specific warning for closures, since
COMPILE already happened to behave with them in a harmless and
conformant way.

> The result of #'(lambda (y) (+ x y)) will be a closure, and it's
> being given to COMPILE.

And COMPILE returns it, unchanged.  For the reasons you state, we can
call it an attempt at closure compilation, but what we call it was not
the point here; the point was whether LWW would compile closures -- it
doesn't.
-- 
Pekka P. Pirinen, (ex-)Lisper, Harlequin Limited
A definition tells you something about the way words are used, 
not about the way the universe is put together.
  - Simon van Dongen <sgvd_pi.net>
From: Jeff Dalton
Subject: Re: [closures] compilation of
Date: 
Message-ID: <x2so16ak03.fsf@todday.aiai.ed.ac.uk>
·····@harlequin.co.uk (Pekka P. Pirinen) writes:

> Jeff Dalton <····@todday.aiai.ed.ac.uk> writes:
> > ·····@harlequin.co.uk (Pekka P. Pirinen) writes:
> > > > CL-USER 225 > (let ((x 8))
> > > >                 (setf adder (compile nil #'(lambda (y) (+ x y)))))
> > > > ;;;*** Warning between functions:   The definition supplied, #<closure
> > > > SPECIAL::APPLY-INTERPRETED-CLOSURE 20405AAA>, is already compiled.
> > > 
> > > It's not closure compilation.
> > 
> > Um, *why* isn't it?
> 
> Because it didn't compile anything;

Ok.  But in this thread, we've been using terms such as "closure
compilation" to talk about something one could try to do even if
the Lisp in question wouldn't do it; hence my misunderstanding.

>    it just signalled a warning
> saying, in effect: "But this thing is already compiled!  It's
> pointless to call COMPILE on it."  We were a bit lazy there, and
> didn't bother to provide a specific warning for closures, since
> COMPILE already happened to behave with them in a harmless and
> conformant way.

But that takes us back to my point: the interpreted function hadn't
been compiled: it just had a compiled-function wrapper around it.

> > The result of #'(lambda (y) (+ x y)) will be a closure, and it's
> > being given to COMPILE.
> 
> And COMPILE returns it, unchanged.

Yes, but I wasn't saying otherwise.

>      For the reasons you state, we can
> call it an attempt at closure compilation, but what we call it was not
> the point here; the point was whether LWW would compile closures -- it
> doesn't.

I was addressing whether it was an instance of an attempt to compile
a closure, not whether we *call* it closure compilation.  (Not that
the two questions are completely unrelated, of course, but we could
talk about the same thing in different words, for instance if we
were using French instead of English.)

-- j
From: Frode Vatvedt Fjeld
Subject: Re: [closures] compilation of
Date: 
Message-ID: <2hzovp9x6y.fsf@dslab7.cs.uit.no>
"H. Tunc Simsek" <······@EECS.Berkeley.Edu> writes:

> Why can't you compile closures?

I can't find the reference right now, but I think I read somewhere
(probably one of Graham's books) that closures can only be compiled by
COMPILE-FILE, but _not_ in the toplevel by COMPILE.

-- 
Frode Vatvedt Fjeld