bernat@utep-vaxa.UUCP (Dr. Bernat ) (05/02/88)
I am trying to compile a lexical closure in Franz Common LISP and keeping getting the "illegal function form" message. It seems to me that I should be able to compile closures. For example, (defun test (a) (function (lambda (x) (cons x a)))) (test 5) => returns a lexical closure (funcall (test 5) 6) => (6.5) as expected but (compile nil (test 5)) gives the error message Can anyone help? Thanks, Andrew Bernat CS Dept. U.Texas @ El Paso UUCP ...ut-sally!utep-vaxa!bernat BITNET BJ00@UTEP 915/747-5470
mcconnel@zodiac.ads.com (Chris McConnell) (05/04/88)
To get a compiled closure, you want to compile the function that generates the closure, not the closure itself. So, in your example: (compile 'test) #<test number> (test 5) #<(:internal test 0) number>
miller@ACORN.CS.ROCHESTER.EDU (Brad Miller) (05/05/88)
Date: 2 May 88 16:28:55 GMT From: bernat@utep-vaxa.UUCP (Dr. Bernat ) I am trying to compile a lexical closure in Franz Common LISP and keeping getting the "illegal function form" message. It seems to me that I should be able to compile closures. For example, (defun test (a) (function (lambda (x) (cons x a)))) (test 5) => returns a lexical closure (funcall (test 5) 6) => (6.5) as expected but (compile nil (test 5)) gives the error message Can anyone help? Thanks, Andrew Bernat CS Dept. U.Texas @ El Paso UUCP ...ut-sally!utep-vaxa!bernat BITNET BJ00@UTEP 915/747-5470 Try redefining test to: (defun test (a) (compile nil `(lambda (x) (cons x ,a)))) The problem is that compile doesn't know what to do with a closure, you have to compile the lambda form. [I don't have a franz common lisp, this follows from Steele, and works on a Symbolics] ---- Brad Miller U. Rochester Comp Sci Dept. miller@cs.rochester.edu {...allegra!rochester!miller}
cox@renoir.Berkeley.EDU (Charles A. Cox) (05/05/88)
In article <304@utep-vaxa.UUCP> bernat@utep-vaxa.UUCP (Dr. Bernat ) writes: >I am trying to compile a lexical closure in Franz Common LISP and >keeping getting the "illegal function form" message. It seems to >me that I should be able to compile closures. Page 438 of CLtL: compile name &optional definition [function] If definition is supplied, it should be a lambda-expression, the interpreted function to be compiled. If not supplied, then name should be a symbol with a definition that is a lambda-expression. [...] If you want compiled closures, the correct thing to do is to compile the function which creates the closures, as this will cause all closures created to be compiled.
duff@eraserhead.steinmetz (David A Duff) (05/05/88)
In article <23878@ucbvax.BERKELEY.EDU> cox@renoir.Berkeley.EDU.UUCP (Charles A. Cox) writes: >In article <304@utep-vaxa.UUCP> bernat@utep-vaxa.UUCP (Dr. Bernat ) writes: >>I am trying to compile a lexical closure in Franz Common LISP ... > [...] > >If you want compiled closures, the correct thing to do is to compile >the function which creates the closures, as this will cause all >closures created to be compiled. FYI: In lucid common lisp, compiling the function that generates the closure will, indeed, cause the function to generate a compiled closure. Also, if you try to just compile a closure by itself e.g. (compile nil (return-a-closure)), you get the following message: (compile nil (return-a-closure)) #<Interpreted-Function (LAMBDA (X) (PRINT X)) 7E26F7> has a non-empty lexical environment. References to this environment will not be compiled correctly. Do you wish to try compiling #<Interpreted-Function (LAMBDA (X) (PRINT X)) 7E26F7> anyway? (Y or N): y #<Compiled-Function 7E3357> Offhand, I can't see any reason why a compile shouldn't be able to do this correctly, since the closure obviously must have a pointer to the the environment that was in effect at the time that it was created. I assume that it was just a special case that the implementors chose to ignore. Dave Duff GE Research and Development Center Schenectady, New York 518-387-5649 Note: in case default return address doesn't work try one of: duffd@ge-crd.ARPA uunet!steinmetz!eraserhead!duff
hoey@etl.ARPA (Dan Hoey) (05/06/88)
In article <10734@steinmetz.ge.com> duff@eraserhead.UUCP (David A Duff) writes: ... >In lucid common lisp, compiling the function that generates the closure will, >indeed, cause the function to generate a compiled closure. Also, if you try >to just compile a closure by itself e.g. (compile nil (return-a-closure)), you >get the following message: >...References to this environment will not be compiled correctly.... >Offhand, I can't see any reason why a compile shouldn't be able to do this >correctly, since the closure obviously must have a pointer to the the >environment that was in effect at the time that it was created. I assume that >it was just a special case that the implementors chose to ignore. I think the key here is that the format of the environment for an interpreted closure doesn't have to be the same as the format of the environment for a compiled closure. This works because in its usual operation, the compiler compiles the environment for each bit of code it compiles. So the job of an implementor to deal with the special case would be to either 1) Convert the interpreter environment to a compiler environment on entry, and restore any changes on exit, or 2) Emit compiled code that can manage references to an interpreter environment. Either choice would be a lot of work to implement a feature not required by the Common Lisp specification. The runtime overhead for choice 1 might well exceed the gains made by compiling. Choice 2 might require sweeping changes throughout the code generator. With the costs in mind, it is a lot easier to understand why ignoring this case is a good idea. Dan