Lisp HUG Maillist Archive

Confused about compiling and closures...

Hi,

I have run into a brick wall on several occasions regarding the compiler complaining about trying to compile a closure...

To whit: if I enter the following into the text editor:

(defun plus (a b)
  (+ a b))

(let ((plus #'plus))
 (defun plus3 (x)
     (funcall plus 3 x))))

(defun plus (a b)
  (* a b))

The first definition of plus is the one I want to capture. I produce the function plus3. Then I redefine plus so that I can check that the behavior of plus3 remains unchanged. It does, and so far so good. If I hadn't first captured the existing definition of #'plus by means of the surrounding LET, then the later redefinition of plus would have altered the meaning of plus3.

If I compile the region in the text editor containing this text, or even save it to a file and do compile & load, I get no errors.  A warning is issued that plus is defined more than once. Okay.

But if I evaluate the definition of plus3 with Alt-Ctl-X in the editor, or just type it into the listener, I get an interpreted closure, not a compiled one. Attempting to compile this result manually with

(compile 'plus3)

produces the error:

Error: #<interpreted function PLUS3 200D13F2> is a lexical closure.

There have been other times at which I inadvertently produced some kind of closures and the LW system refused to save as a FASL file. The CLTL2 states that this refusal is permissible behavior. The same code has been accepted and saved as a FASL file by Allegro in the past. So implementations vary in this treatment.

Under what conditions can a closure be produced as compiled code? Is it always subject to implementation variances?

David McClain
Chief Technical Officer
Refined Audiometrics Laboratory
4391 N. Camino Ferreo
Tucson, AZ  85750

Re: Confused about compiling and closures...

On 14 Mar 2008, at 19:53, David McClain wrote:


Under what conditions can a closure be produced as compiled code? Is it always subject to implementation variances?



It's never portably possible to compile a function defined in a non-null lexical environment,  The reason for this is that implementations might want to use a different representation for the lexical environment in interpreted and compiled code.  If that's the case then compiling a function defined in an (interpreted) lexical environment means that you either have to do something heroic like have a special "compiled function talking-to-interpreted-environment" mode for the compiler, or you would have to compile anything *else* which shares that environment (and the environment itself), which would probably not be what the user expects.

(I ran into this ages ago, and I think that KMP explained the reasoning to me.  The above is basically my dimming memory of that.)

--tim

Re: Confused about compiling and closures...


--- David McClain <dbm@refined-audiometrics.com>
wrote:

> (let ((plus #'plus))
>   (defun plus3 (x)
>       (funcall plus 3 x))))

> 	(compile 'plus3)

> 	Error: #<interpreted function PLUS3 200D13F2> is a
lexical closure.


Depending on what you're actually trying to
accomplish, you might be able to do it this way:

(let ((f #'plus))
  (eval `(defun plus3 (x)
           (funcall ,f 3 x)))
  (compile 'plus3))

Or maybe you could give more details of what you're
actually trying to accomplish.



      ____________________________________________________________________________________
Looking for last minute shopping deals?  
Find them fast with Yahoo! Search.  http://tools.search.yahoo.com/newsearch/category.php?category=shopping


Re: Confused about compiling and closures...

Hi all,

Many thanks for all the feedback on this one. In answer to the questions about "What the heck am I trying to do, anyway?",

I am toying around with SSA compilation -- sometimes referred to as "hyper-static" bindings. This means that all items referred to must have been previously defined. And redefinitions of items merely shadow previous values of the bindings, but all prior references to those previous bindings remain in effect, even after the later re-bindings.

I was originally trying to accomplish this in the embedded context of the running Lisp environment. But after exploring code walkers at some depth, I have decided to give up on that approach and re-implement the notions in terms of my own compiler, where I can exercise better control over bindings and macro expansions. A code walker would have been needed in order to distinguish lexical bindings from global bindings.

In concert with this I was also trying to develop something more akin to Graham's Arc language, where I could exercise greater flexibility over the meaning of expressions in function position inside SEXP forms.

The aim of this exercise is to arrive at a core collection of programming constructs to enable relatively safe embedded code. By relatively safe, I mean something which cannot accidentally be modified in midcourse due to accidental rebinding collisions. This is not the sort of thing you want in an interactive Lisp environment. But for delivered code, it is more desirable than the anything-goes philosophy of Lisp, IMO.

David McClain
Chief Technical Officer
Refined Audiometrics Laboratory
4391 N. Camino Ferreo
Tucson, AZ  85750

email: dbm@refined-audiometrics.com
phone: 1.520.390.3995
web: http://www.refined-audiometrics.com


On Mar 16, 2008, at 00:11, Eric Smith wrote:



--- David McClain <dbm@refined-audiometrics.com>
wrote:

(let ((plus #'plus))
  (defun plus3 (x)
      (funcall plus 3 x))))

(compile 'plus3)

Error: #<interpreted function PLUS3 200D13F2> is a
lexical closure.


Depending on what you're actually trying to
accomplish, you might be able to do it this way:

(let ((f #'plus))
  (eval `(defun plus3 (x)
           (funcall ,f 3 x)))
  (compile 'plus3))

Or maybe you could give more details of what you're
actually trying to accomplish.



      ____________________________________________________________________________________
Looking for last minute shopping deals?  
Find them fast with Yahoo! Search.  http://tools.search.yahoo.com/newsearch/category.php?category=shopping



Updated at: 2020-12-10 08:43 UTC