Path: utzoo!utgpu!news-server.csri.toronto.edu!rutgers!usc!zaphod.mps.ohio-state.edu!rpi!sci.ccny.cuny.edu!phri!marob!cowan From: cowan@marob.masa.com (John Cowan) Newsgroups: comp.lang.lisp Subject: Re: Dumb Common Lisp question Message-ID: <269B8AAA.1FF5@marob.masa.com> Date: 11 Jul 90 20:23:05 GMT References: <4204@jato.Jpl.Nasa.Gov> <1990Jun29.162248.7846@Neon.Stanford.EDU> <1005@lehi3b15.csee.Lehigh.EDU> Reply-To: cowan@marob.masa.com (John Cowan) Distribution: usa Organization: ESCC, New York City Lines: 58 In article <1005@lehi3b15.csee.Lehigh.EDU>, jearly@lehi3b15.csee.Lehigh.EDU (John Early) writes: And in article <1990Jun29.162248.7846@Neon.Stanford.EDU>, max@Neon.Stanford.EDU (Max Hailperin) writes: And in article <4204@jato.Jpl.Nasa.Gov> brian@granite.Jpl.Nasa.Gov (Brian of ASTD-CP) writes: Brian> [...] I have one pressing question about CL. What is the rationale Brian> behind the (function ...) or #' construct? [...] Brian> I'm most familiar with Scheme/T, where this kind of thing is Brian> not necessary. All symbols are evaluated the same way [...] Max> It's done this way for the sake of people who like to call an argument Max> that's a list "list" and still be able to use the "list" function, as in Max> (defun foo (list) Max> "Return a list of the sum of the list and the sum-of-squares of the list." Max> (list (apply #'+ list) Max> (apply #'+ (mapcar #'square list)))) Max> Max> instead of having to call it the-list like you would in scheme. Max> [Of course, this applies to other names as well, list is just a common one.] JEarly> Since this is bad programming (at best) I suspect that that is not the reason. JEarly> I would guess that there is instead an historical/compatibility reason. Max and JEarly are both right: the use of (function ...) does indeed stem from the desire to be backward compatible with older LISPS, specifically in the ability to give a symbol both a function and a non-function ("value") binding. In the oldest Lisps, the value was stored in a global association list to which new entries were added as needed (all variables were special), whereas the function binding was stored on the symbol's property list. Later, the value binding was moved to the property list as well, and saved/restored as needed; still later (MACLisp), the value was placed in a slot of the symbol object itself; still later (most Common Lisps), both the value and the function binding were moved to slots. Scheme, having the advantage of dismissing backward compatibility (eq vs. eq?, for example), could go for the one-symbol-one-binding style and did so. A subtler point: in pre-Common Lisps, where there were officially no lexical variables (except in compiled code, where the compiler "sneaked them in" unless prevented by a special declaration), (function ...) had the effect of capturing the current >dynamic< bindings, a property it no longer has in Common Lisp. Typically, (function ...) was a special form which returned a triplet (FUNARG function environment) where environment could be either an a-list or a stack pointer. When applied, "FUNARG triples" would have the effect of temporarily restoring the dynamic environment in the third component for the duration of the application. Whether changes to that dynamic environment were preserved after the FUNARG terminated was implementation-dependent, as was whether it was safe to use "upward FUNARGS" that referred to dynamic environments that had already exited. In the new world of mostly lexical variables all of this cruft goes away. -- cowan@marob.masa.com (aka ...!hombre!marob!cowan) e'osai ko sarji la lojban