Path: utzoo!utgpu!news-server.csri.toronto.edu!rpi!zaphod.mps.ohio-state.edu!mips!spool.mu.edu!uunet!mcsun!ukc!edcastle!aiai!jeff From: jeff@aiai.ed.ac.uk (Jeff Dalton) Newsgroups: comp.lang.lisp Subject: Re: compiling lambda-CLOSUREs Keywords: was monitoring functions Message-ID: <4448@skye.ed.ac.uk> Date: 9 Apr 91 18:22:03 GMT References: <14172@medusa.cs.purdue.edu> <1991Apr3.095336.29725@hellgate.utah.edu> Reply-To: jeff@aiai.UUCP (Jeff Dalton) Organization: AIAI, University of Edinburgh, Scotland Lines: 79 In article <1991Apr3.095336.29725@hellgate.utah.edu> moore%defmacro.utah.edu@cs.utah.edu (Tim Moore) writes: > >"It is an error if the function to be compiled was defined >interpretively in a non-null lexical environment. (An implementation >is free to extend the behavior of COMPILE to compile such functions >properly, but portable programs may not depend on this capability.)" > >It should be obvious why compiling a closed "lambda expression" (as if >there was any such thing) doesn't work; same reason that they can't be >EVAL'ed. I don't quite understand the point about EVAL. The original question talked about a "lambda-closure", which is presumably what you get as the value of (FUNCTION (LAMBDA ...)) in some Common Lisp. Indeed, in KCL you will get a list (LAMBDA-CLOSURE ...). [That sort of result isn't allowed in CLtL II, where functions are supposed to be distinct from lists, but it's allowed in CLtL I.] That is, it's a function object. It may make sense to say it can't be evaluated, just as it may make sense to say hash tables (for example) can't be evaluated. It isn't what we normally think of as an expression. But it is a function, and functions are just the sort of thing one can give to COMPILE. So I don't think it's _obvious_ why compiling them doesn't work, though it's certainly understandable -- for more or less the reasons you give below. >There are several problems that come up when compiling interpreted >closures. The biggest one I can think of is dealing with the object >that represents the closed-over environment. Normally, when compiling >files, if the compiler encounters an object (such as an array), it can >treat it as a constant and proceed. But in this case, not only is the >environment object not constant, it has to be the same (i.e., EQ) >object that was used in the interpreted function, because other >functions may be closed over it too. It may be unreasonable to make >the compiler deal with this special case. I think this is right except for a few details. When compiling a file, the compiler or loader can cause constants to be "coalesced" (see section 25.1.4 Similarity of Constants, and especially page 694, in CLtL II). However, COMPILE is not allowed to do this. An object referred to as a constant by the compiled code has to be the same (in this case EQL) object referred to by the code before it was compiled (see CLtL II, page 115). Consequently, if an environment were an object, it's arguable that it would be the usual case for COMPILE to make the compiled function use the same one as the interpreted function, not a special case. However, these environments are not 1st-class objects in Common Lisp, and there is no defined way for them to appear as constants in code, so the rule does not apply. >Also, compiled and interpreted code may use different representations >of closed-over environments. In this case it would be impossible to >compile an interpreted closure because other interpreted functions >might be sharing the same environment. It depends on how different the representations are. For example, in KCL two different representations are used in compiled closures. One of them is more or less the same as that used in interpreted closures (an alist), the other is not (it's a vector). Both representations might be used for the same environment, and it works because both will contain the same bindings. (If we say a variable names a location in which a value is stored, two functions closed over the same variables have to acess the same locations so that an assinment in one will be seen in the other. In KCL, the two representations contain the same locations.) So it doesn't matter if the environment representations are different so long as they contain the same locations for the variables. On the other hand, this is still a strong limitation on what representations could be used, and it would probably be unreasonable to impose it on implementations. -- jeff