Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 17 Feb 86 00:17:00 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 16 Feb 86 18:53:05 PST Date: Sun, 16 Feb 86 21:54:41 EST From: Richard Mark Soley Subject: forwared from CommonLoops To: GJC@MC.LCS.MIT.EDU cc: common-lisp@SU-AI.ARPA In-reply-to: Msg of Sun 16 Feb 86 20:45:55 EST from George J. Carrette Message-ID: <[MC.LCS.MIT.EDU].820200.860216.SOLEY> Date: Sun, 16 Feb 86 20:45:55 EST From: George J. Carrette To: common-lisp at SU-AI.ARPA Re: forwared from CommonLoops From: ricks%ic at BERKELEY.EDU (Rick L Spickelmier) I'm in the process of porting to VAXLISP and I've come across one thing that I think should be changed. In PCL, #+3600 is used for 3600 specific code. VAXLISP dies on this since 3600 is not a symbol. The commonlisp book (Steele) also says that #+ items must be symbols. It's not so gross to force the #+/#- reader to intern all tokens; |3600| is a perfectly good symbol. Besides, if we were to allow numbers in #+/#- expressions, we'd be back to the problem found soon after the first existence of the 3600, in which a change of the read base caused #+/#- conditionals to fail . . . I think it's too restrictive to not allow "fixnum symbols" in # conditionals. -- Richard  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 16 Feb 86 21:00:08 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 16 Feb 86 17:53:13 PST Received: ID ; Sun 16 Feb 86 20:54:23-EST Date: Sun, 16 Feb 1986 20:54 EST Message-ID: From: Rob MacLachlan To: "Scott E. Fahlman" Cc: common-lisp@SU-AI.ARPA, hpfclp!diamant@HPLABS.ARPA Subject: intern In-reply-to: Msg of 16 Feb 1986 20:12-EST from Scott E. Fahlman I believe that it was decided that the correct interpretation of the manual did not support INTERN setting the package cell. Contradictory passages were considered to be dated, and inconsistent with the current notion of package semantics. It was thought that having INTERN do anything to package cells was a rather random side-effect, and was better left out since no very convincing arguments were presented in its favor. It was pointed out that IMPORT is a function which causes a symbol to be present in a package. This seems to correspond fairly well to the notion of intering a symbol. It was decided that having IMPORT home the symbol made some sense, so the change to IMPORT was put in. There is a point against INTERN setting the home package which I believe was not discussed. It is not obvious what package INTERN should choose at the home. It is a bad idea to set the package to the one being interned in, since the symbol may not be present in that package; it may be inherited. If the symbol was subsequently unexported, it would have a home package yet not be available in that package. This could be fixed up by choosing some package which the symbol is present in, but the choice would have to be fairly arbitrary, since the symbol might be inherited from more than one package. Rob  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 16 Feb 86 20:52:18 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 16 Feb 86 17:44:18 PST Date: Sun, 16 Feb 86 20:45:55 EST From: "George J. Carrette" Subject: forwared from CommonLoops To: common-lisp@SU-AI.ARPA Message-ID: <[MC.LCS.MIT.EDU].820141.860216.GJC> From: ricks%ic at BERKELEY.EDU (Rick L Spickelmier) I'm in the process of porting to VAXLISP and I've come across one thing that I think should be changed. In PCL, #+3600 is used for 3600 specific code. VAXLISP dies on this since 3600 is not a symbol. The commonlisp book (Steele) also says that #+ items must be symbols. Comments?  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 16 Feb 86 20:24:20 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 16 Feb 86 17:17:48 PST Received: ID ; Sun 16 Feb 86 20:19:01-EST Date: Sun, 16 Feb 1986 20:18 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: hpfclp!hpfcdcm!dcm@HPLABS.ARPA Cc: common-lisp@SU-AI.ARPA Subject: FUNCTION type specifier In-reply-to: Msg of 14 Feb 1986 19:06-EST from hpfclp!hpfcdcm!dcm at hplabs.ARPA In my reading of the specification for TYPEP, I see nothing that would rule out (TYPEP X 'FUNCTION) It does rule out any list-type argument whose car is a list (or any specifier containing such a list). As you surmised, the intention was to make it clear that the implementaiton is not required to keep around the argument-type or return-type information for each function. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 16 Feb 86 20:18:42 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 16 Feb 86 17:11:23 PST Received: ID ; Sun 16 Feb 86 20:12:33-EST Date: Sun, 16 Feb 1986 20:12 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: hpfclp!diamant@HPLABS.ARPA Cc: common-lisp@SU-AI.ARPA Subject: intern In-reply-to: Msg of 14 Feb 1986 19:07-EST from hpfclp!diamant at hplabs.ARPA The reason I haven't jumped into this INTERN discussion is that this ground was gone over at great length sometime in the last year (but not since the Boston meeting), and most of these INTERN problems were resolved, more or less. But it is very difficult for me to get at the archives right now, and I haven't had time to go back and review the finer points of what was decided. (Yes, it is totally unacceptable that the archives are not available in convenient form. The current plan is that the ISI support group will solve this problem when and if they ever get rolling.) If anyone has this stuff available, it would be very helpful if you could post a synopsis of the previous intern discussion. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 16 Feb 86 00:00:35 EST Received: from XEROX.COM by SU-AI.ARPA with TCP; 15 Feb 86 20:50:26 PST Received: from Cabernet.ms by ArpaGateway.ms ; 15 FEB 86 20:49:37 PST Date: 15 Feb 86 20:49 PST From: Miller.pa@Xerox.COM Subject: Re: loop macro In-reply-to: Daniel L. Weinreb 's message of Thu, 6 Feb 86 20:44 EST To: DLW@SCRC-QUABBIN.ARPA cc: gls@aquinas.think.com, common-lisp@SU-AI.ARPA Message-ID: <860215-204937-3274@Xerox> From: Daniel L. Weinreb Date: Wed, 5 Feb 86 12:01 EST From: Guy Steele Okay, now here is a different perspective on the LOOP problem. I will play devil's advocate here and claim that the main purpose of LOOP is to duplicate the functionality of the sequence functions. (1) Your message later goes on to say "This isn't operating on sequences, so I will render this as a DO loop." This in no way supports the original thesis! Many simple examples of LOOP don't operate on sequences: (loop for x from 3 to 6 do (print x)) I think the best answer for this particular kind of example is the following from Larry Masinter: We could enhance the sequence functions using Common Loops if we define default implementations for them which use only the methods that all ordered collections must follow, and then include new classes for Interval. This is the approach used successfully in Smalltalk for dealing with iteration. In particular, how about: (map #'print (interval 3 6)) Admittedly, many of GLS's other DO loops examples may be difficult or inappropriate to rephrase this way.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 14 Feb 86 19:16:09 EST Received: from HPLABS.ARPA by SU-AI.ARPA with TCP; 14 Feb 86 16:07:47 PST Received: by hplabs.ARPA ; Fri, 14 Feb 86 16:07:53 pst Date: Fri, 14 Feb 86 16:07:53 pst From: hpfclp!diamant@hplabs.ARPA To: common-lisp@su-ai.ARPA Subject: Re: intern Cc: diamant@hplabs.ARPA From: hplabs!NGALL@G.BBN.COM Subject: Re: intern What I would like to see is the following: 1. Leave the stipulation on page 172 that INTERN fix-up the package slot of an interned symbol. It may be better to remove the definition of the verb "intern" on pg. 172 since the verb is not used elsewhere in the chapter. See my comments below. 2. Refer to pg. 172 in the def. of INTERN. I think it would be a better idea to completely define the functionality of INTERN in one place (preferably on page 184). 3. Make IMPORT also fix up the package slot. I agree. 4. In UNITERN, after warning about homeless interned symbols, cf. IMPORT for fixing things up. 5. Make clear that FIND-SYMBOL has NO SIDE EFFECTS. And point out that it is the only way of mapping a name to a homeless interned symbol. For the reasons described below, I would suggest stating that INTERN also does not modify already-existing symbols. How 'bout it?! This appears O.K. at first, but consider the following example: (in-package "FOO") (intern "X") (export 'x) (in-package "BAR" :use '("FOO")) (export 'foo:x) (unintern 'foo:x (find-package "FOO")) (in-package "BAZ" :use '("BAR")) (intern "X") If we follow the proposed definition of intern, x is now internally available in BAR, available by inheritance in BAZ, but its package cell is BAZ. Now, if we (unintern 'bar:x (find-package "BAR")), then the symbol will disappear even though its home package was not BAR. Alternately, if we (unuse-package "BAR" (find-package "BAZ")), then bar:x has a home package of BAZ, but is not available in BAZ. This seems to violate print-read consinstency. (in-package "FOOBAR") (eq (read-from-string (with-output-to-string (*standard-output*) (print 'bar:x))) 'bar:x)) This will return nil, instead of t. An alternative is to have intern not set the home package, but be functionally equivalent to: (defun intern (name &optional (package *package*)) (or (find-symbol name package) (import (make-symbol name) package)))) This has the unfortunate property of having intern return uninterned symbols in some cases. See the above example. It seems that we are back to the original statement you made that IMPORT is the only function permitted to change the package cell (however, the reasons are more complicated than first suspected). Would anyone care to comment on this? By the way, it may be a good idea to make the shadowing-import explicitly state the same clarification. I suspect that the (defun intern ...) I stated above is close to what most people implemented.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 14 Feb 86 19:15:34 EST Received: from HPLABS.ARPA by SU-AI.ARPA with TCP; 14 Feb 86 16:06:59 PST Received: by hplabs.ARPA ; Fri, 14 Feb 86 16:06:37 pst Date: Fri, 14 Feb 86 16:06:37 pst From: hpfclp!hpfcdcm!dcm@hplabs.ARPA To: common-lisp@SU-AI Subject: FUNCTION type specifier In the description of typep, the following statement seems to need clarification. "The type may be any of the type specifiers mentioned in chapter 4 expcept that it may not be or contain a type specifier list whose first element is FUNCTION or VALUES." What is the correct interpretation of this statment or its intention? I am not an expert on English (is anyone?), but I believe this means that type may not be FUNCTION or VALUES or a type specifier list whose first element is FUNCTION or VALUES. Based on this interpretation I would assume the following examples are not valid. (typep x 'function) (typep x '(function (t) t)) (typep x 'values) (typep x '(values t t t)) I believe the first example is quite useful - it is equivalent to (typep x '(satisfies functionp)) However the second example may not be easy to handle without requiring implementations to keep a lot of information around. I assume the restriction was made to simplify implementation for this reason. Was it really intended to eliminate the useful form as well? Some (maybe all) implementations do accept the simple FUNCTION type specifier. Dave Matthews Hewlett-Packard Company dcm%hpfclp@hplabs  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 14 Feb 86 14:55:33 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 14 Feb 86 11:43:37 PST Received: from CONCORD.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 417632; Fri 14-Feb-86 14:34:26-EST Date: Fri, 14 Feb 86 14:43 EST From: Bernard S. Greenberg Subject: Re: loop macro To: Soley@MIT-MC.ARPA cc: common-lisp@SU-AI.ARPA In-Reply-To: <860205174634.3.SOLEY@MIT-CHERRY.ARPA> Message-ID: <860214144330.7.BSG@CONCORD.SCRC.Symbolics.COM> Date: Wed, 5 Feb 86 17:46 EST From: Soley@MIT-MC.ARPA Date: 4 Feb 86 15:50 PST From: Gregor.pa@Xerox.COM Subject: Re: loop macro In-reply-to: Bernard S. Greenberg 's message of Tue, 4 Feb 86 16:38 EST To: BSG@SCRC-STONY-BROOK.ARPA cc: Fahlman@C.CS.CMU.EDU, common-lisp@SU-AI.ARPA Message-ID: <860204-155111-2418@Xerox> I think I prefer "lispy" iteration macros. Here is an example of what I mean by a lispy iteration macro: ;; Return a list of the items in list-of-items ;; which pass the test TEST. (iterate ((item in list-of-items)) (when (test item) (collect item))) Parens do not a Lisp code make. This particular example, for instance, isn't any "lispier" than the equivalent LOOP construction; the expression "(collect item)" is CERTAINLY not a call to some new function COLLECT, is it? Don't laugh, Richard. Suppose ITERATE fletted the name COLLECT..... That could be a very reasonable implementation.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 14 Feb 86 14:49:17 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 14 Feb 86 11:37:31 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 417617; Fri 14-Feb-86 14:23:05-EST Date: Fri, 14 Feb 86 14:22 EST From: David A. Moon Subject: package system error handling To: common-lisp@SU-AI.ARPA In-Reply-To: <12183342206.27.LOOSEMORE@UTAH-20.ARPA> Message-ID: <860214142219.0.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Fri 14 Feb 86 11:17:34-MST From: SANDRA I'm trying to figure out what should happen when the reader sees something like editor:buffer and there isn't a package called "editor" or an external symbol in it called "buffer". CLtL indicates that the reader should "signal a correctable error to ask the user what he really wants to do". This is all pretty vague -- does this mean that if the user continues from the error some reasonable default action is used (like creating the package or making the symbol external), or does it mean that the user is presented with a list of alternative actions and asked to choose one? How is this handled in other implementations? Does anybody really care? I think this depends on the user-interaction style and programming-environment conventions of each particular implementation. It's not primarily a language issue. In our implementation, the response depends on context. In interactive input, we explain the problem and permit the user to edit the input to make it correct. When reading from a non-interactive source, such as a file, we go into the debugger, allowing suitable recovery choices. For example, reading editor:buffer when only editor::buffer exists offers to assume a double colon and also offers to call EXPORT. Other implementations might want to do something different. In the future, when Common Lisp is extended with error-handling machinery, we may want to define how these are errors are signalled and allow programmed recovery.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 14 Feb 86 13:29:24 EST Received: from UTAH-20.ARPA by SU-AI.ARPA with TCP; 14 Feb 86 10:18:11 PST Date: Fri 14 Feb 86 11:17:34-MST From: SANDRA Subject: package system error handling To: common-lisp@SU-AI.ARPA Message-ID: <12183342206.27.LOOSEMORE@UTAH-20.ARPA> I'm trying to figure out what should happen when the reader sees something like editor:buffer and there isn't a package called "editor" or an external symbol in it called "buffer". CLtL indicates that the reader should "signal a correctable error to ask the user what he really wants to do". This is all pretty vague -- does this mean that if the user continues from the error some reasonable default action is used (like creating the package or making the symbol external), or does it mean that the user is presented with a list of alternative actions and asked to choose one? How is this handled in other implementations? Does anybody really care? -Sandra -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 14 Feb 86 12:47:05 EST Received: from UTAH-20.ARPA by SU-AI.ARPA with TCP; 14 Feb 86 09:38:32 PST Date: Fri 14 Feb 86 10:37:50-MST From: SANDRA Subject: "include" revisited To: common-lisp@SU-AI.ARPA Message-ID: <12183334972.21.LOOSEMORE@UTAH-20.ARPA> Some time ago I posted a message to this mailing list concerning the lack of an "include" or file indirection construct in CL. (The primary motivation for having such a construct being the lack of any other way to compile several source files into a single binary file.) It was pointed out that this could be written as a macro (which reads in the entire contents of the include'd file and returns it inside a PROGN), and that was the end of the discussion. Just now, however, I happened to come across the implementation note on p.182 in CLtL, which states that it's wrong for a compiler to read in the entire file before processing any of the forms because of the presence of multiple packages. So, "include" can't be implemented correctly in this way either. Rather than introduce a special form for "include", how about extending the syntax of compile-file to accept either a single input-pathname or a list of pathnames? -Sandra -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 13 Feb 86 21:00:16 EST Date: 13 Feb 86 1744 PST From: Dick Gabriel Subject: CL-ITERATION To: common-lisp@SU-AI.ARPA ... still exists. -rpg-  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 13 Feb 86 18:29:05 EST Received: from XEROX.COM by SU-AI.ARPA with TCP; 13 Feb 86 15:13:31 PST Received: from Cabernet.ms by ArpaGateway.ms ; 13 FEB 86 15:09:24 PST Date: 13 Feb 86 15:09 PST From: Gregor.pa@Xerox.COM Subject: Re: load-time-eval In-reply-to: NGALL@G.BBN.COM's message of 13 Feb 86 17:30 EST To: NGALL@G.BBN.COM cc: Gregor.pa@Xerox.COM, Common-Lisp@SU-AI.ARPA Message-ID: <860213-150925-1811@Xerox> What is the meaning of the phrase "When [a use of LOAD-TIME-EVAL] is compiled to core (by COMPILE-FILE)..." and how does it differ/relate to the meaning of the phrase "When a use of LOAD-TIME-EVAL is compiled (by COMPILE-FILE)"? They sound the same to me. I guess there is a typo in my message. I should have said "compiled to core by COMPILE". load-time-eval is different than #, because you can use it in a macro and have part of the macroexpansion evaluated at load-time. Given: (defmacro my-macro () `(my-macro-run-time-function (load-time-eval
))) This defun: (defun foo () (my-macro)) is equivalent to: (defun foo () (my-macro-run-time-function '#,))  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 13 Feb 86 17:43:47 EST Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 13 Feb 86 14:32:51 PST Date: 13 Feb 1986 17:30-EST Sender: NGALL@G.BBN.COM Subject: Re: load-time-eval From: NGALL@G.BBN.COM To: Gregor.pa@XEROX.COM Cc: Common-Lisp@SU-AI.ARPA Message-ID: <[G.BBN.COM]13-Feb-86 17:30:37.NGALL> In-Reply-To: <860213-132305-1680@Xerox> Date: 13 Feb 86 13:23 PST From: Gregor.pa@Xerox.COM To: Common-Lisp@SU-AI.ARPA Subject: load-time-eval Message-ID: <860213-132305-1680@Xerox> I think someone has mentioned this before, but Common Lisp needs a load-time-eval or deferred-constant facility. load-time-eval (form) [macro] When evaluated (by the evaluator) simply evaluates form and returns its result. When a use of load-time-eval is compiled (by compile-file) arranges for form to be evaluated at load-time. The call to load-time-eval when evaluated will then return the result of having evaulated the form When compiled to core (by compile-file) simply evaluates form at compile time and arranges for the call to load-time-eval to return the result of evaluting form. What is the meaning of the phrase "When [a use of LOAD-TIME-EVAL] is compiled to core (by COMPILE-FILE)..." and how does it differ/relate to the meaning of the phrase "When a use of LOAD-TIME-EVAL is compiled (by COMPILE-FILE)"? They sound the same to me. It seems like it should be easy for implementors to implement this using the mechanism they already have for #,. Or we could have a deferred constant facility like the one in Interlisp. Or we could have both. We need something though, because the fact that you can't use #, in a macro and have it do "what you want" makes #, of limited usefulness. How does LOAD-TIME-EVAL relate to #,? Could you give an example? Sorry to be so dense, but I didn't see the prev. disc. on this. -- Nick  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 13 Feb 86 16:52:11 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 13 Feb 86 13:42:09 PST Received: ID ; Thu 13 Feb 86 16:43:36-EST Date: Thu, 13 Feb 1986 16:43 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Gregor.pa@XEROX.COM Cc: Common-Lisp@SU-AI.ARPA Subject: load-time-eval In-reply-to: Msg of 13 Feb 1986 16:23-EST from Gregor.pa at Xerox.COM I agree that we should make Load-time-eval available to users, since everyone has it internally and it is useful in certain kinds of code. I don't remember what Interlisp deferred constants do. Can you elaborate? -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 13 Feb 86 16:33:24 EST Received: from XEROX.COM by SU-AI.ARPA with TCP; 13 Feb 86 13:23:03 PST Received: from Cabernet.ms by ArpaGateway.ms ; 13 FEB 86 13:23:05 PST Date: 13 Feb 86 13:23 PST From: Gregor.pa@Xerox.COM Subject: load-time-eval To: Common-Lisp@SU-AI.ARPA cc: Gregor.pa@Xerox.COM Message-ID: <860213-132305-1680@Xerox> I think someone has mentioned this before, but Common Lisp needs a load-time-eval or deferred-constant facility. load-time-eval (form) [macro] When evaluated (by the evaluator) simply evaluates form and returns its result. When a use of load-time-eval is compiled (by compile-file) arranges for form to be evaluated at load-time. The call to load-time-eval when evaluated will then return the result of having evaulated the form When compiled to core (by compile-file) simply evaluates form at compile time and arranges for the call to load-time-eval to return the result of evaluting form. It seems like it should be easy for implementors to implement this using the mechanism they already have for #,. Or we could have a deferred constant facility like the one in Interlisp. Or we could have both. We need something though, because the fact that you can't use #, in a macro and have it do "what you want" makes #, of limited usefulness.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 13 Feb 86 16:22:14 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 13 Feb 86 13:13:01 PST Received: ID ; Thu 13 Feb 86 16:14:37-EST Date: Thu, 13 Feb 1986 16:14 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Jonathan A Rees Cc: common-lisp@SU-AI.ARPA Subject: loop In-reply-to: Msg of 13 Feb 1986 16:09-EST from Jonathan A Rees Yeah, we had one called CL-ITERATION, I think, but I tried mailing to that and it didn't work. Maybe something has been archived? -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 13 Feb 86 16:18:32 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 13 Feb 86 13:08:01 PST Date: Thu, 13 Feb 86 16:09:39 EST From: Jonathan A Rees Subject: loop To: common-lisp@SU-AI.ARPA Message-ID: <[MC.LCS.MIT.EDU].817522.860213.JAR> Time to start a CL-LOOP mailing list.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 13 Feb 86 13:53:05 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 13 Feb 86 10:41:03 PST Received: from CROW.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 416556; Thu 13-Feb-86 13:39:57-EST Date: Thu, 13 Feb 86 13:36 EST From: Robert W. Kerns Subject: Re: loop macro To: common-lisp@SU-AI.ARPA In-Reply-To: <8602131728.AA01858@brillig.umd.edu> Supersedes: <860213133159.1.RWK@CROW.SCRC.Symbolics.COM>, <860213133625.2.RWK@CROW.SCRC.Symbolics.COM> Message-ID: <860213133639.3.RWK@CROW.SCRC.Symbolics.COM> Date: Thu, 13 Feb 86 12:27:59 -0500 From: Liz Allen I don't really remember needing to use a DO* type binding of iteration variables. I guess I would use a LET to bind some common value and use it in the init part of the iteration values. I use the DO* type of binding far more often than not. And it isn't an issue for the init part of the iteration, it's for the stepping. I think you've kept the part people like least about LOOP (the keywords) and thrown out one of the parts people like the most.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 13 Feb 86 12:40:52 EST Received: from BRILLIG.UMD.EDU by SU-AI.ARPA with TCP; 13 Feb 86 09:32:20 PST Received: by brillig.umd.edu (5.9/4.7) id AA01858; Thu, 13 Feb 86 12:28:02 EST Message-Id: <8602131728.AA01858@brillig.umd.edu> To: jeff%aiva.edinburgh.ac.uk@cs.ucl.ac.uk Cc: common-lisp@su-ai.ARPA Subject: Re: loop macro In-Reply-To: Your message of Wed, 12 Feb 86 14:54:08 GMT. Date: Thu, 13 Feb 86 12:27:59 -0500 From: Liz Allen From: Jeff Dalton Re Maryland loop macro: one thing is still unclear to me: are the iteration variables always stepped in parallel (a la DO)? Is there any way to have it done sequentially (DO*)? One reason for linking words in ZetaLoop is to distinguish these cases. Always via DO -- they are init'd in parallel; you can use LET to bind other variables which may be ref'd. Of course, on the iteration steps, the variables are updated in sequence. The Maryland macro always expands to a DO with, possibly, one or more LET's around it. I don't really remember needing to use a DO* type binding of iteration variables. I guess I would use a LET to bind some common value and use it in the init part of the iteration values. -Liz  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 12 Feb 86 23:01:09 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 12 Feb 86 19:51:04 PST Received: ID ; Wed 12 Feb 86 22:52:34-EST Date: Wed, 12 Feb 1986 22:52 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Ken Haase Cc: common-lisp@SU-AI.ARPA Subject: The return of UNSPECIAL In-reply-to: Msg of 10 Feb 1986 15:13-EST from Ken Haase There is currently no UNSPECIAL or LEXICAL declaration in Common Lisp. I think this was done because we thought it was not needed and that it added additional complexity to the language. A lot of people ahve complained about this, and I think it will probably be put back in someday. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 12 Feb 86 11:11:25 EST Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 12 Feb 86 07:56:46 PST Date: 12 Feb 1986 10:54-EST Sender: NGALL@G.BBN.COM Subject: Re: intern From: NGALL@G.BBN.COM To: hpfclp!diamant@HPLABS.ARPA Cc: common-lisp@SU-AI.ARPA Message-ID: <[G.BBN.COM]12-Feb-86 10:54:19.NGALL> In-Reply-To: The message of Tue, 11 Feb 86 12:33:45 pst from hpfclp!diamant@hplabs.ARPA Date: Tue, 11 Feb 86 12:33:45 pst From: hpfclp!diamant@hplabs.ARPA To: hplabs!common-lisp@su-ai.ARPA Subject: Re: intern From: hplabs!NGALL@G.BBN.COM My question is: does INTERN (the function) always "intern" (the verb). Also, are there any other functions which "intern," such as import, for instance. Specificially, should INTERN set the home package of an uninterned symbol? I asked this question a while back (too bad the archives are so hard to access!). My impression was that there was a consensus that IMPORT is the function that is responsible for "updating" the package-slot of an uninterned symbol (since IMPORT is the only function that can put a SYMBOL in a package). Guy Steele sent out a list of proposed "clarifications" a few months ago (also in the archives). The clarification for IMPORT was: "If symbol has no owner, its package cell is updated." -- Nick ... Thanks for the clarification on IMPORT. I did have a copy of the clarifications, but hadn't looked them over carefully enough. I am certainly satisfied by the new definition of IMPORT, but something still bothers me about INTERN. As the reason for having import be the only function responsible for updating the package slot, you claim that IMPORT is the only function that can put a SYMBOL in a package. By this, do you mean an already existing symbol, or any symbol? Obviously, if An already existing symbol. I type (intern "FOO"), I will put the symbol FOO in the current package (if it wasn't already available). If you mean an already existing symbol, isn't that equivalent to the question I already asked? I'm not sure wwhich question you are refering to. I'm not trying to be picky -- I just don't understand the motivation for restricting INTERN from setting the home package. On page 172, CLtL says (for the Neither do I. (And I don't think you're being picky, keep the comments coming!) function INTERN): "If the symbol previously was unowned, then the package it is being interned in becomes its owner (home package); but if the symbol was previously owned by another package, the other package continues to own the symbol." To me, that seems to strongly suggest that INTERN would have to set the home package on a symbol which doesn't CURRENTLY have a home package. As I said before, this creates a problem for the definition Unfortunately, most implementors seem to have ignored this passage. of FIND-SYMBOL since it is defined to be identical to INTERN except that it can't create a new symbol. Consider: (let ((x (intern "FOO"))) (import x (find-package "BAR")) (unintern x) (find-symbol "FOO" (find-package "BAR"))) ;; the defn. in CLtL would imply that x would now be homed in BAR. In my first reply, I forgot about good old UNINTERN, which can make an interned symbol homeless (as in your example). So I was making the point that if one "fixed" import, one could never get homeless interned symbols. Wrong. I think the attitude at the time was that IMPORTing a homeless symbol (e.g., a GENSYMed symbol) was the only "straightforward" way that an interned symbol could be left homeless, i.e., it is the only way "novice" CL user's could "easily" cause such an inconsistency. The case of UNINTERN a symbol from its home package when it is also present in other packages, was considered a pathological case (it is even mentioned in the description of UNINTERN), and not worth the trouble of having INTERN deal with. So the passage on 172 was to be removed (Guy, this is not in your list of clarifications.) and the wording for IMPORT changed as I mentioned previously. As far as FIND-SYMBOL is concerned, I think the "identical behavior" wording was used because the passage on pg. 172 as overlooked. To me, the idea behind find-symbol is that it is identical to INTERN except that it does not cause ANY side-effects (incl. fixing the package slot). What I would like to see is the following: 1. Leave the stipulation on page 172 that INTERN fix-up the package slot of an interned symbol. 2. Refer to pg. 172 in the def. of INTERN. 3. Make IMPORT also fix up the package slot. 4. In UNITERN, after warning about homeless interned symbols, cf. IMPORT for fixing things up. 5. Make clear that FIND-SYMBOL has NO SIDE EFFECTS. And point out that it is the only way of mapping a name to a homeless interned symbol. How 'bout it?!  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 12 Feb 86 10:20:44 EST Received: from CS.UCL.AC.UK by SU-AI.ARPA with TCP; 12 Feb 86 07:07:42 PST Received: from aiva.edinburgh.ac.uk by 44d.Cs.Ucl.AC.UK via Janet with NIFTP id a001193; 12 Feb 86 14:55 GMT From: Jeff Dalton Date: Wed, 12 Feb 86 14:54:08 GMT Message-Id: To: dlw@scrc-quabbin.arpa, liz@brillig.umd.edu Subject: Re: loop macro Cc: bsg@scrc-stony-brook.arpa, common-lisp@su-ai.arpa Re Maryland loop macro: one thing is still unclear to me: are the iteration variables always stepped in parallel (a la DO)? Is there any way to have it done sequentially (DO*)? One reason for linking words in ZetaLoop is to distinguish these cases.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 11 Feb 86 23:16:30 EST Received: from RED.RUTGERS.EDU by SU-AI.ARPA with TCP; 11 Feb 86 20:08:41 PST Date: 11 Feb 86 23:08:16 EST From: Charles Hedrick Subject: problem with (CAR NIL) = NIL To: common-lisp@SU-AI.ARPA Message-ID: <12182663309.38.HEDRICK@RED.RUTGERS.EDU> The reason I don't like (CAR NIL) = NIL is that it causes many program errors to be undetected. I always prefered to have NIL set up so that attempts to follow its CAR or CDR resulted in illegal memory references. It is easy enough to make the CAR and CDR be NIL on most machines. It just requires monkeying around with the representations so that this falls out. E.g. on the DEC-20, NIL is 0, and we arrange that locations 0 and 1 always contain 0. This requires some care, and functions that access property lists must check specifically for NIL, but we don't think anyone notices a performance change due to this hack. What they do notice is that buggy programs take longer to debug than they should. -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 11 Feb 86 17:52:02 EST Received: from XEROX.COM by SU-AI.ARPA with TCP; 11 Feb 86 14:40:59 PST Received: from Semillon.ms by ArpaGateway.ms ; 11 FEB 86 13:59:48 PST Date: 11 Feb 86 13:58 PST From: masinter.pa@Xerox.COM Subject: Re: Car and Cdr of nil is nil In-reply-to: Fahlman%C.CS.CMU.EDU:ARPA:Xerox's message of 11 Feb 86 09:41 To: Common-Lisp@su-ai.ARPA Message-ID: <860211-135948-1619@Xerox> The use of (CAR NIL) = NIL predates 1971, which is the earliest BBN-Lisp manual I have. The operation of CAR and CDR on NIL is somewhat independent of the use of NIL as a symbol, the empty list, and false. ("this feature really messes up the type hierarchy"), in that, even if one left CAR and CDR undefined or "is an error" on NIL, one might still use NIL = () = (NOT T). As for "nasty problems for Lisp implementors on stock hardware", this was a nasty problem 10 years ago, but the technology for handling it, even on stock hardware, is well in hand. The nastiness for stock hardware is keeping (setf (car 3215) t) from crashing your system.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 11 Feb 86 16:04:46 EST Received: from BRILLIG.UMD.EDU by SU-AI.ARPA with TCP; 11 Feb 86 12:28:22 PST Received: by brillig.umd.edu (5.9/4.7) id AA09433; Tue, 11 Feb 86 15:26:29 EST Message-Id: <8602112026.AA09433@brillig.umd.edu> To: dlw@scrc-quabbin.ARPA Cc: bsg@scrc-stony-brook.ARPA, common-lisp@su-ai.ARPA Subject: Re: loop macro In-Reply-To: Your message of Thu, 6 Feb 86 08:16 EST. <860206081637.4.DLW@CHICOPEE.SCRC.Symbolics.COM> Date: Tue, 11 Feb 86 15:26:28 -0500 From: Liz Allen I guess in an effort to be concise, I didn't give enough information about out for macro to be clear... From: Bernard S. Greenberg What are "let", "initially", "eachtime", "in", "on", "from", "bind", "being", "finally", in your macro, if not connecting words, or am I totally confused? It seemed to me that the Lisp Machine loop macro uses key words (and I don't mean : words) not only to introduce loop clauses but also to connect clauses in some sense (eg "and", "whereas", etc). What I was trying to demonstrate was that it's possible to have a loop macro with much simpler syntax -- each clause is independent and even equal in some sense in our for macro. From: Daniel L. Weinreb Indeed. Furthermore, the basic syntax you gave is too basic for me to understand the syntax of your proposal, since, for example, you didn't say what an looked like. Furthermore, what does a do; that is, what does "when " mean? Does that means that the first form following the "when" is tested, and the rest are implicit-progn'ed consequents? What does "eachtime" mean and how is it different from "do"? Let me answer specifically here and then give examples and a fuller syntax below and see if I can make all this clear... It's not really that complicated, but... (If you don't get this first part the first time you read it, skip to the examples and syntax and then go back and read the first stuff again. I'm trying to put the most interesting stuff at the top of this letter...) An can be anything like: x in list y on list i from 1 to n by 2 Even though these clauses have key words in them, the clauses have definite boundaries -- each clause still stands alone. A , when * translates into when (progn *) and the value of the last given is the value tested. Using multiple forms in 's is probably not the best programming approach, but before we had an eachtime clause, it was sometimes necessary. That brings me to the next question. "Eachtime" clauses are executed every time through the loop before any of the conditions ("while", "until", "when", "unless", or even conditions generated by things like "x in list") are done. The "do" clause is only done after those tests and when appropriate -- not every time through the loop. This is suggested by the usual ordering of the clauses in the for. Remember that we don't have multiple bodies. It would help a lot to see an example, too. How would you translate this into your "for" construct? If you can't deal with "until" clauses at the end of the loop, say so and move it to the front and translate that instead. Thanks. (loop for a from start to end by 5 for b in list do (do-something a b) until (null b)) That would translate to: (for a from start to end by 5 b in list eachtime (do-something a b) until (null b)) It's unusual for in that there's no body, but the default is "do nil". What couldn't be done is if that original do up there was a collect (or almost any other body keyword) instead. Then the for macro would have to be changed so that: (for a from start to end by 5 b in list collect (do-something a b) until (null b)) expanded to something like: (let ((g0001 list)) (do (($$val) (a start (plus a 5)) (b (car g0001) (car (setq g0001 (cdr g0001))))) ((or (greaterp a end) (null g0001)) (nreverse $$val)) (setq $$val (cons (do-something a b) $$val)) (cond ((null b) (return (nreverse $$val)))))) Currently, all the termination conditions are placed in the do termination. It could be awkward to have to repeat the value to be returned if it got complicated (eg multiple values). The best alternative would be to move that part out of the do, but then the finally clause could not reference the do variables. With that, let me give some more examples and a full syntax for the current for macro. These are taken from the Univ of Maryland Franz Lisp Environment TR (authored by myself, Randy Trigg and Rich Wood). ; This is like (mapc 'patom '(a b c)) (for x in '(a b c) do (msg x)) ; print x to standard out with no terpr abcnil ; This is like (mapcar 'cons '(a b c) '(d e f)). (for x in '(a b c) y in '(d e f) collect (cons x y)) ((a . d) (b . e) (c . f)) ; This is like ; (mapcan (function (lambda (x) (list x 3))) '(a b c)). (for x in '(a b c) join (list x 3)) (a 3 b 3 c 3) ; Example of "sum" as well as "when". (for x in '(a b 3 4 c 5) when (numberp x) sum x) 12 ; Example of "destructuring" with "in". (for (x (y) . z) in '((a (b) c) (d (e) . f) (g (h) i j)) do (msg x B y B z N)) ; the B's say print blanks and the N ; says to do terpr (msg is from Franz ; and case is significant there) a b (c) d e f g h (i j) nil ; Example of "thereis" keyword. Notice that the value of the last expression ; is the one used by "thereis". (for x in '(a b 3 4 c 5) thereis (msg x N) (numberp x)) a b 3 t ; Shows off "until", "count", and "finally". Notice the reference to "$$val" ; (contains the result of the for loop) in the "finally" clause. (for let (a 3) b until (eq (setq a (add1 a)) 6) count (msg a N) finally (list $$val a)) 4 5 (2 6) ; Notice here that "bind" variables can reference "let" variables. (for let (a 3) bind (b a (add1 b)) while (lessp b 6) sum (msg (cons a b) N) b) (3 . 3) (3 . 4) (3 . 5) 12 ; Notice the use of "return" to force the loop to execute only once and the ; value of the variable "a" that the "initially" clause sees. (for let (a 1) initially (msg a N) x in '(h i j) bind (b a) (a 4) (c 1 (return $$val)) collect (list a b c x)) 1 ((4 1 1 h)) ; Example of "last". Causes the value of the last body executed to be returned. (for x in '(1 2 3) while (lessp x 3) unless (onep x) last x) 2 ; Examples of "tcollect" and "tjoin" -- they are like "collect" and "join" ; except they return tconc cells. (for x in '(a b c) tcollect x) ((a b c) c) (for x in '(a b c) tjoin (list x x)) ((a a b b c c) c) ; Some examples of "from" and "fromd" - notice that both "to" and "by" are ; optional. (for n from 0 to 2 collect n) (0 1 2) (for n fromd 0 by 2 x in '(a b c) collect n) (0 -2 -4) ; Example of "being" -- rebinds x on each iteration (for being (x 13) n from 0 to 1 do (msg x N) (setq x 14)) 13 13 nil ; Examples of "eachtime". Watch out! It may execute more often than expected. (for x in nil eachtime (msg 'hi N) collect x) hi nil (for n from 0 to 1 eachtime (msg n N) collect n) 0 1 2 (0 1) ; Example of "quit" -- allows only one execution of the body. (for n from 0 to 13 when (greaterp n 6) quit n) 7 Those should give you a pretty good feel for the macro. Now for the full syntax. First, the easiest way to view the syntax is as (for *) where is any of the things you see down below. The order in which the various clauses appear below is more intuitive (they're in the order that they will be executed) than strictly necessary. (I'm expanding on what I gave in earlier mail; the length will give you a clue as to why I didn't give all this then...) "[ ... ]" means something is optional, "[ ... ]*" or " ... *" means something can appear 0 or more times, and " ... +" means something should appear 1 or more times. (for [ let + ]* ; is or ( ) [ initially + ] [ + ]* ; in, on, from, bind, being, etc [ eachtime + ]* [ * ]* ; while + or until + [ * ]* ; when + or unless + [ + ] ; is do, collect, etc [ finally + ] ) Wherever you see +, if more than one really does appear, then a progn is put around the whole thing and the last value is the one that is used. Note that multiple let's turn into successive let's on the outside so that later let's may reference vars in earlier ones. Forms appearing in the initially clause and the 's may also reference any let variables. An can be any of the following: in on from [ to ] [ by ] ; defaults to 1 fromd [ to ] [ by ] ; subtracts each time bind + ; can be or ( [ [ ] ]), ; the latter is like a do variable clause being ( )+ ; is set to every time, like ; bind ( ) Each of the 's becomes a do iteration . Throughout the for, you can use $$val to reference the value (maybe just so far) of the for. The table below explains what the 's may be and the corresponding value for the for where x1, ... xi, ... xn are the values of the clause (last in the clause) for the 1st, ... ith, ... nth execution of the loop. $$val do nil collect (list x1 ... xi ... xn) join (nconc x1 ... xi ... xn) sum (plus x1 ... xi ... xn) count n always (and x1 ... xi ... xn) never (and (not x1) ... (not xi) ... (not xn)) thereis (or x1 ... xi ... xn) last xn tcollect like collect only a tconc cell tjoin like join only a tconc cell quit x1 (only executes body once), if body never executes, then nil Note that always, never and thereis shortcut if possible -- eg always will quit and return nil on the first null xi. They also do not execute the finally clause if they quit early. Hope all this makes sense... -Liz  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 11 Feb 86 16:03:31 EST Received: from HPLABS.ARPA by SU-AI.ARPA with TCP; 11 Feb 86 12:34:21 PST Received: by hplabs.ARPA ; Tue, 11 Feb 86 12:33:45 pst Date: Tue, 11 Feb 86 12:33:45 pst From: hpfclp!diamant@hplabs.ARPA To: hplabs!common-lisp@su-ai.ARPA Subject: Re: intern From: hplabs!NGALL@G.BBN.COM My question is: does INTERN (the function) always "intern" (the verb). Also, are there any other functions which "intern," such as import, for instance. Specificially, should INTERN set the home package of an uninterned symbol? I asked this question a while back (too bad the archives are so hard to access!). My impression was that there was a consensus that IMPORT is the function that is responsible for "updating" the package-slot of an uninterned symbol (since IMPORT is the only function that can put a SYMBOL in a package). Guy Steele sent out a list of proposed "clarifications" a few months ago (also in the archives). The clarification for IMPORT was: "If symbol has no owner, its package cell is updated." -- Nick Thanks for the clarification on IMPORT. I did have a copy of the clarifications, but hadn't looked them over carefully enough. I am certainly satisfied by the new definition of IMPORT, but something still bothers me about INTERN. As the reason for having import be the only function responsible for updating the package slot, you claim that IMPORT is the only function that can put a SYMBOL in a package. By this, do you mean an already existing symbol, or any symbol? Obviously, if I type (intern "FOO"), I will put the symbol FOO in the current package (if it wasn't already available). If you mean an already existing symbol, isn't that equivalent to the question I already asked? I'm not trying to be picky -- I just don't understand the motivation for restricting INTERN from setting the home package. On page 172, CLtL says (for the function INTERN): "If the symbol previously was unowned, then the package it is being interned in becomes its owner (home package); but if the symbol was previously owned by another package, the other package continues to own the symbol." To me, that seems to strongly suggest that INTERN would have to set the home package on a symbol which doesn't CURRENTLY have a home package. As I said before, this creates a problem for the definition of FIND-SYMBOL since it is defined to be identical to INTERN except that it can't create a new symbol. Consider: (let ((x (intern "FOO"))) (import x (find-package "BAR")) (unintern x) (find-symbol "FOO" (find-package "BAR"))) ;; the defn. in CLtL would imply that x would now be homed in BAR. John Diamant Fort Collins Systems Division UUCP: {ihnp4,hplabs}!hpfclp!diamant Hewlett Packard Co. ARPA/CSNET: diamant%hpfclp@hplabs Fort Collins, CO  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 11 Feb 86 14:35:37 EST Received: from XEROX.COM by SU-AI.ARPA with TCP; 11 Feb 86 11:21:55 PST Received: from Salvador.ms by ArpaGateway.ms ; 11 FEB 86 11:17:30 PST Date: 11 Feb 86 11:02 PST From: Bobrow.pa@Xerox.COM Subject: Re: Car and Cdr of nil is nil In-reply-to: kessler%utah-orion@utah-cs.arpa (Robert Kessler)'s message of Tue, 11 Feb 86 09:12:57 MST To: kessler%utah-orion@utah-cs.arpa cc: common-lisp@su-ai.arpa Message-ID: <860211-111730-1394@Xerox> This was a feature introduced in BBN Lisp around 1968 to allow one to access, say, the fourth element of a list without checking if the list was that long. It is a useful, though terrible, pun. For very small machines as we were on, saving the few cons cells at the end of a list was important. And after all, one might say, the REST of an empty list is still empty. ...  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 11 Feb 86 13:49:59 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 11 Feb 86 09:18:33 PST Received: ID ; Tue 11 Feb 86 12:19:44-EST Date: Tue, 11 Feb 1986 12:19 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Gregor.pa@XEROX.COM Cc: Common-Lisp@SU-AI.ARPA Subject: Compiling functions which appear inside top-level forms. In-reply-to: Msg of 10 Feb 1986 16:05-EST from Gregor.pa at Xerox.COM Again speaking only for Spice Lisp, I believe that our compiler does not create any extra hair in compiled code for getting at lexical variables unless it is actually needed. Simply compiling somethign in a non-null lexical environment will not cost you anything. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 11 Feb 86 13:09:26 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 11 Feb 86 09:40:58 PST Date: Tue 11 Feb 86 12:15:55-EST From: "Rodney A. Brooks" Subject: code density as a function of elegance To: common-lisp@SU-AI.ARPA Message-ID: <12182544551.69.BROOKS@OZ.AI.MIT.EDU> Re: Bob Kessler's question. (I don't think this made it to the CL list previously--apologies if it did.) A SHORT BALLAD DEDICATED TO THE GROWTH OF PROGRAMS ================================================== by Ashwin Ram This is a tale of a sorry quest To master pure code at the T guru's behest I enrolled in a class that appealing did seem For it promised to teach fine things like T3 and Scheme The first day went fine; we learned of cells And symbols and lists and functions as well Lisp I had mastered and excited was I For to master T3 my hackstincts did cry I sailed through the first week with no problems at all And I even said "closure" instead of "function call" Then said the master that ready were we To start real hacking instead of simple theory Will you, said he, write me a function please That in lists would associate values with keys I went home and turned on my trusty Apollo And wrote a function whose definition follows: (cdr (assq key a-list)) A one-liner I thought, fool that I was Just two simple calls without a COND clause But when I tried this function to run CDR didn't think that NIL was much fun So I tried again like the good King of yore And of code I easily generated some more: (cond ((assq key a-list) => cdr)) It got longer but purer, and it wasn't too bad But then COND ran out and that was quite sad Well, that isn't hard to fix, I was told Just write some more code, my son, be bold Being young, not even a moment did I pause I stifled my instincts and added a clause (cond ((assq key a-list) => cdr) (else nil)) Sometimes this worked and sometimes it broke I debugged and prayed and even had a stroke Many a guru tried valiantly to help But undefined datums their efforts did squelch. I returneth once more to the great sage of T For no way out of the dilemma I could see He said it was easy -- more lines must I fill with code, for FALSE was no longer NIL. (let ((val (assq key a-list))) (cond (val (cdr val)) (else nil))) You'd think by now I might be nearing the end Of my ballad which seems bad things to portend You'd think that we could all go home scot-free But COND eschewed VAL; it wanted #T So I went back to the master and appealed once again I said, pardon me, but now I'm really insane He said, no you're not really going out of your head Instead of just VAL, you must use NOT NULL instead (let ((val (assq key a-list))) (cond ((not (null? val)) (cdr val)) (else nil))) My song is over and I'm going home to bed With this ineffable feeling that I've been misled And just in case my point you have missed Somehow I preferred (CDR (ASSQ KEY A-LIST)) -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 11 Feb 86 12:26:14 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 11 Feb 86 09:15:13 PST Received: ID ; Tue 11 Feb 86 12:16:56-EST Date: Tue, 11 Feb 1986 12:16 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: kessler%utah-orion@utah-cs.arpa (Robert Kessler) Cc: common-lisp@SU-AI.ARPA Subject: Car and Cdr of nil is nil In-reply-to: Msg of 11 Feb 1986 11:12-EST from kessler%utah-orion at utah-cs.arpa (Robert Kessler) This rather controversial feature was adopted in Maclisp after some people saw it in Interlisp. I'm not sure if the Maclisp people thought it was a good idea, or if they just thought they'd better be compatible for ease in porting programs. If a program relies on this feature, it is often very hard to get it running in a Lisp that doesn't have it. I'll let the Interlisp people describe the genesis of this feature, but it's clear what the arguments pro and con are. On the plus side, this allows you to use lists as data structures and to truncate any all-NIL branches without having to put checks for this into the accessors. So the programmer (or structure-writing macro) can just write CADDDR, and get NIL if the data structure is (FOO (SOME LIST)). On the minus side, this feature really messes up the type hierarchy and it can create nasty problems for Lisp implementors on stock hardware -- a lot of trickery is required if you want CAR and CDR to operate properly and quickly without having to check for NIL as a special case. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 11 Feb 86 11:19:13 EST Received: from UTAH-CS.ARPA by SU-AI.ARPA with TCP; 11 Feb 86 08:11:16 PST Received: by utah-cs.ARPA (5.31/4.40.2) id AA03040; Tue, 11 Feb 86 09:13:02 MST Received: by utah-orion.ARPA (5.31/4.40.2) id AA23237; Tue, 11 Feb 86 09:12:57 MST Date: Tue, 11 Feb 86 09:12:57 MST From: kessler%utah-orion@utah-cs.arpa (Robert Kessler) Message-Id: <8602111612.AA23237@utah-orion.ARPA> To: common-lisp@su-ai.arpa Subject: Car and Cdr of nil is nil Does anyone recall where this feature comes from and the history behind why it was done?? Thanks. Bob.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 10 Feb 86 16:14:37 EST Received: from XEROX.COM by SU-AI.ARPA with TCP; 10 Feb 86 13:04:50 PST Received: from Cabernet.ms by ArpaGateway.ms ; 10 FEB 86 13:05:19 PST Date: 10 Feb 86 13:05 PST From: Gregor.pa@Xerox.COM Subject: Re: Compiling functions which appear inside top-level forms. In-reply-to: "Scott E. Fahlman" 's message of Mon, 10 Feb 86 15:46 EST To: Fahlman@C.CS.CMU.EDU cc: Gregor.pa@Xerox.COM, Common-Lisp@SU-AI.ARPA Message-ID: <860210-130519-1594@Xerox> Will it be a lexical closure? In this example, the question is moot since the function does not use anything from the lexical envrionment outside of itself. But in general, it will see the lexical environment. I should have said "Will it be a lexical closure or will it be something simpler (if the Lisp supports compiled functions which are simpler than lexical closures and can be funcalled faster)".  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 10 Feb 86 15:54:44 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 10 Feb 86 12:44:54 PST Received: ID ; Mon 10 Feb 86 15:46:27-EST Date: Mon, 10 Feb 1986 15:46 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Gregor.pa@XEROX.COM Cc: Common-Lisp@SU-AI.ARPA Subject: Compiling functions which appear inside top-level forms. In-reply-to: Msg of 10 Feb 1986 14:33-EST from Gregor.pa at Xerox.COM Question to implementors: Will the function #'(lambda (x y)...) be compiled? In Spice Lisp, yes, this is compiled. Will it be a lexical closure? In this example, the question is moot since the function does not use anything from the lexical envrionment outside of itself. But in general, it will see the lexical environment. General question: Would it be reasonable to require that it be compiled? Yes. There was a lot of discussion before the book came out about the technique of turning random top-level forms into functions of no args which the compiler can process normally. It then emits the definition followed by a call to this odd function. We shouldn't require exactly that, since some implementations would then have trouble GC-ing this anonymous function, but we should require equivalent semantics in judging what the compiler compiles. I don't think this is required currently -- as you say, the description of Compile-File needs a lot of work now. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 10 Feb 86 15:25:09 EST Received: from MIT-REAGAN.ARPA by SU-AI.ARPA with TCP; 10 Feb 86 12:15:41 PST Received: from SID.AI.MIT.EDU by MIT-REAGAN.ARPA via CHAOS with CHAOS-MAIL id 22617; Mon 10-Feb-86 15:14:00-EST Date: Mon, 10 Feb 86 15:13 EST From: Ken Haase Subject: The return of UNSPECIAL To: common-lisp@SU-AI.ARPA cc: KWH@MIT-AI.ARPA Message-ID: <860210151334.2.KWH@SID.AI.MIT.EDU> What is the status of UNSPECIAL in Common LISP? In the archives on MC I can find references to its demise (in the Laser edition), but no arguments as to the reasons. While it might speed up the interpreter to not have unspecial declarations (just a guess), it would be nice to have ASSURED special declarations.... Ken  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 10 Feb 86 14:54:36 EST Received: from XEROX.COM by SU-AI.ARPA with TCP; 10 Feb 86 11:45:39 PST Received: from Cabernet.ms by ArpaGateway.ms ; 10 FEB 86 11:33:14 PST Date: 10 Feb 86 11:33 PST From: Gregor.pa@Xerox.COM Subject: Compiling functions which appear inside top-level forms. To: Common-Lisp@SU-AI.arpa cc: Gregor.pa@Xerox.COM Message-ID: <860210-113314-1468@Xerox> If the following appears as a top-level form in a file: (let ((foo (make-foo))) (declare (special foo)) (setf (foo-function foo) #'(lambda (x y) (+ x y))) (store-foo-away-somewhere foo)) And I compile and load the file. Question to implementors: Will the function #'(lambda (x y)...) be compiled? Will it be a lexical closure? General question: Would it be reasonable to require that it be compiled? I think that this function should be compiled. I think portable programs should be able to count on that. ...turning up burners slightly... This seems like another instance of the general problem that thex semantics of compile-file is not well enough defined. Maybe we should take another stab at that problems now. Now that lots of people are working on new ways to store programs (databases, definition-groups etc) we can probably get some good feedback about this. If we wait until everyone has their new "code database" stuff finished it may be too late to settle on anything that will make old-fashioned files a tool for distributing quality portable code.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 8 Feb 86 23:56:39 EST Received: from CADRE.DSL.PITTSBURGH.EDU by SU-AI.ARPA with TCP; 8 Feb 86 20:48:14 PST Received: by PITTSBURGH.EDU (5.31/5.14) id AA03004; Sat, 8 Feb 86 23:48:32 EST Date: Sat, 8 Feb 86 23:48:32 EST From: sean@cadre.dsl.pittsburgh.edu (Sean McLinden) Message-Id: <8602090448.AA03004@PITTSBURGH.EDU> To: common-lisp@su-ai.arpa Subject: LOOP Macro code for Common Lisp With regard to the Common Lisp compatible LOOP macro package of which I spoke in a recent message I must apologize for what was an inadvertant misstatement of fact. I had stated (or implied) that the code, which was obtained from David Miller at DePaul University, could be freely distributed. This may be incorrect. What is true is that David Miller expressed no objection to the distribution of his changes, and was NOT AWARE of any restrictions on the distribution of the code from which it was derived. In no way does this imply that the code may be distributed without restrictions and users should be aware of this fact. Again, my apologies for the misunderstanding. Sean McLinden Decision Systems Laboratory  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 7 Feb 86 18:32:39 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 7 Feb 86 15:21:00 PST Received: from WHITE.SWW.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 412789; Fri 7-Feb-86 18:12:20-EST Received: from PURPLE.SWW.Symbolics.COM by WHITE.SWW.Symbolics.COM via CHAOS with CHAOS-MAIL id 172065; Fri 7-Feb-86 15:11:05-PST Date: Fri, 7 Feb 86 15:11 PST From: DDYER@SCRC-RIVERSIDE.ARPA Subject: loop macro To: David A. Moon , common-lisp@SU-AI.ARPA Fcc: W:>ddyer>mail.sent In-Reply-To: <860207161130.6.MOON@EUPHRATES.SCRC.Symbolics.COM> Message-ID: <860207151100.8.DDYER@PURPLE.SWW.Symbolics.COM> Date: Fri, 7 Feb 86 16:11 EST From: David A. Moon Just to set the record straight: Date: Wed, 5 Feb 86 10:49 EST From: Daniel L. Weinreb .... Since I'm getting into details, I should make quite clear that I do not speak for Moon in the matter of LOOP. Our opinions on this topic diverge much more than they do on most other topics. True. One of my own strong feelings about LOOP that Moon does not share is that we should get rid of the conditionals. False. Dan misremembered my position here. Actually, I've believed for several years that the conditionals in LOOP were the principal mistake in the current design. If I were doing it over today, I would certainly use the regular Lisp conditionals, which of course implies changes to the theory of collection. In the real world, one might consider keeping the conditionals just for compatibility, but frowning on their use in new code. The conditionals wouldn't be so bad if there were BEGIN and END markers for the scope of the body. Adding BEGIN and END as loop keywords would solve eliminate my objections to the loop conditionals.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 7 Feb 86 16:32:21 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 7 Feb 86 13:21:37 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 412621; Fri 7-Feb-86 16:11:51-EST Date: Fri, 7 Feb 86 16:11 EST From: David A. Moon Subject: loop macro To: common-lisp@SU-AI.ARPA In-Reply-To: <860205104933.5.DLW@CHICOPEE.SCRC.Symbolics.COM> Message-ID: <860207161130.6.MOON@EUPHRATES.SCRC.Symbolics.COM> Just to set the record straight: Date: Wed, 5 Feb 86 10:49 EST From: Daniel L. Weinreb .... Since I'm getting into details, I should make quite clear that I do not speak for Moon in the matter of LOOP. Our opinions on this topic diverge much more than they do on most other topics. True. One of my own strong feelings about LOOP that Moon does not share is that we should get rid of the conditionals. False. Dan misremembered my position here. Actually, I've believed for several years that the conditionals in LOOP were the principal mistake in the current design. If I were doing it over today, I would certainly use the regular Lisp conditionals, which of course implies changes to the theory of collection. In the real world, one might consider keeping the conditionals just for compatibility, but frowning on their use in new code.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 7 Feb 86 16:25:43 EST Received: from SCRC-QUABBIN.ARPA by SU-AI.ARPA with TCP; 7 Feb 86 13:13:06 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-QUABBIN.ARPA via CHAOS with CHAOS-MAIL id 243275; Fri 7-Feb-86 16:09:10-EST Date: Fri, 7 Feb 86 16:11 EST From: David A. Moon Subject: loop macro To: common-lisp@SU-AI.ARPA In-Reply-To: <860205104933.5.DLW@CHICOPEE.SCRC.Symbolics.COM> Message-ID: <860207161130.6.MOON@EUPHRATES.SCRC.Symbolics.COM> Just to set the record straight: Date: Wed, 5 Feb 86 10:49 EST From: Daniel L. Weinreb .... Since I'm getting into details, I should make quite clear that I do not speak for Moon in the matter of LOOP. Our opinions on this topic diverge much more than they do on most other topics. True. One of my own strong feelings about LOOP that Moon does not share is that we should get rid of the conditionals. False. Dan misremembered my position here. Actually, I've believed for several years that the conditionals in LOOP were the principal mistake in the current design. If I were doing it over today, I would certainly use the regular Lisp conditionals, which of course implies changes to the theory of collection. In the real world, one might consider keeping the conditionals just for compatibility, but frowning on their use in new code.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 7 Feb 86 11:24:45 EST Received: from NRL-AIC.ARPA by SU-AI.ARPA with TCP; 7 Feb 86 08:14:33 PST Date: 7 Feb 1986 10:57:53 EST (Fri) From: Dan Hoey Subject: Re: loop macro To: Daniel L. Weinreb Cc: Common-Lisp@su-ai.ARPA Message-Id: <508092818/hoey@nrl-aic> In-Reply-To: Daniel L. Weinreb's message of Wed, 5 Feb 86 1049 EST Date: Wed, 5 Feb 86 10:49 EST From: Daniel L. Weinreb We could add grouping without going so far as to force all clauses to the front. (loop (for a from 4 below 7) (for b from 7) (do ..body..) (until ..pred..)) I think this might be an improvement. One problem is that we were hoping to get rid of the "do" keyword entirely (Moon agrees with this), but with this change, it's harder to see how to accomplish that. Actually, people have been promised that if they don't use atoms in their loop, it loops forever, though possibly no one has been brave enough to use this behavior. Still, I have to agree that this stuff looks too much like function calls, and even if "FOR" and "UNTIL" are somehow implemented as macros, it's not the way I think of it. These problems and DO-removal are both solved by using alternating keywords and arguments. In the following, I don't use colons for the LOOP keywords, since they don't follow the CL keyword standard anyway. (DEFUN count-change (changepurse &OPTIONAL handfull) (LOOP ;(LOOP MEMBERS (coin changepurse) ; FOR coin IN changepurse COUNT (howmany :END handfull) ; AS count = 0 TO handfull (jingle) ; DO (jingle) (IF (soup coin) ; IF (soup coin) (COLLECT (coin :INTO sou-list); COLLECT coin INTO sou-list (SUM (coin-value coin))) ; ELSE SUM (coin-value coin) (IF (= howmany handfull) ; IF (= howmany handfull) (RETURN "Too Many")) ; RETURN "Too Many" FINALLY (drop-coins sou-list))) ; FINALLY (drop-coins sou-list)) Each keyword takes exactly one argument, which is usually a standard CL argument list (though possibly a single argument could be rendered as an atom). If not preceded by a keyword, the form is just evaluated. I am particularly grossed out by the idea of having a "dangling ELSE" in Lisp. This is fixed here, since my IF uses Common Lisp syntax. On my braver days, though, I would rather use (IF (mantrap phrase) (chant phrase) (chant phrase) (chant phrase) :ELSE ((contemplate phrase) (get-new-mantra))) but that would break everyone's habits. The main reason for the conditionals is so that COLLECT clauses can be executed conditionally. (I don't know for sure whether there are other reasons for the conditionals.) The usual proposed solution is to make COLLECT a regular Lisp macro... a separate facility completely orthogonal to LOOP.... After all, suppose you want to write a program that does a double recursion down a binary tree, and collects something as it goes? I used this form above, but there are problems. Consider the very useful (LOOP MEMBERS (x elts) SUM x) vs. (LOOP MEMBERS (x elts) COLLECT (- x)). When elts is empty, the first should return 0 and the second NIL. Also, LOOP needs some preamble code for every variable you COLLECT :INTO. I guess we need declarations of the variables you are going to use for SUM and COLLECT. TOTAL (coin-value) ACCUMULATE (:RETURN-VALUE) Where :RETURN-VALUE refers to SUM or COLLECT calls that operate on the value to be returned by LOOP. It's unfortunate that this hair has to be added. I think ACCUMULATE :UNNAMED should be the default unless TOTAL :UNNAMED appears. Something like this is also needed in the standalone SUM/COLLECT you propose. Dan Hoey  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 6 Feb 86 21:38:59 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 6 Feb 86 16:11:14 PST Received: from OWL.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 411912; Thu 6-Feb-86 19:10:38-EST Date: Thu, 6 Feb 86 19:11 EST From: Mike McMahon Subject: LOOP again To: common-lisp@SU-AI.ARPA Message-ID: <860206191124.1.MMCM@OWL.SCRC.Symbolics.COM> Isn't there a separate SIG mailing list for this discussion?  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 6 Feb 86 20:52:07 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 6 Feb 86 17:42:38 PST Received: from CHICOPEE.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 411965; Thu 6-Feb-86 20:42:00-EST Date: Thu, 6 Feb 86 20:44 EST From: Daniel L. Weinreb Subject: Re: loop macro To: gls@THINK-AQUINAS.ARPA cc: common-lisp@SU-AI.ARPA In-Reply-To: <860205120150.4.GLS@THINK-DESIDERIUS.ARPA> Message-ID: <860206204441.9.DLW@CHICOPEE.SCRC.Symbolics.COM> Date: Wed, 5 Feb 86 12:01 EST From: Guy Steele Okay, now here is a different perspective on the LOOP problem. I will play devil's advocate here and claim that the main purpose of LOOP is to duplicate the functionality of the sequence functions. Your message is interesting. I remember that you advocated the inclusion of the sequence functions partly because you wanted Lisp to benefit from the good ideas in APL, and this message seems like a further exposition of that idea. But I don't think it's a good argument against LOOP. Bearing in mind that you're playing devil's advocate, here are the problems: (1) Your message later goes on to say "This isn't operating on sequences, so I will render this as a DO loop." This in no way supports the original thesis! Many simple examples of LOOP don't operate on sequences: (loop for x from 3 to 6 do (print x)) That a LOOP can be rendered as a DO doesn't prove much; it can also be rendered as a PROG. I never use DO any more. Ever. LOOP is clearer than DO in all cases, as far as I'm concerned. It certainly doesn't prove that LOOP is being used to duplicate the functionality of the sequence functions. (2) It would indeed be nice if the cons-intensive examples you gave were optimized into the equivalent iterative code. As far as I'm concerned, it's an axiom of LOOP design/redesign that such compilers are not widespread, if indeed they exist at all. The phrase "duplicate the functionality" is only accurate if it implicitly means "but much faster". Any claim that Common Lisp should not have an improved iteration construct because it is conceivable and theoretically possible that such a compiler might exist ignores Common Lisp's goal of living in the real world. I agree that it would be interesting and valuable to have such a compiler. (3) Some people don't like having to use nameless internal functions to do simple things. We could remove DOLIST from the language, since any DOLIST can be trivially turned into a MAPC. But we don't. So in some cases where iteration is being used to do something that could be done with sequence functions, some people consider the iterative style preferable. [I agree with MMcM that based on the amount of interest so far, it would be helpful to have a special-interest mailing list for this topic.]  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 6 Feb 86 16:46:27 EST Date: 06 Feb 86 1329 PST From: Dick Gabriel Subject: Loop Macro To: common-lisp@SU-AI.ARPA During the recent discussions of loop macros there has been some mention of the ``English-like'' syntax problem. I wonder to what extent this is being tangled up with the issue of whitespace parsing. Recall the language KRL (Bobrow and Winograd) in which whitespace was considered by the reader. The idea was that if a line was underneath andother and indented to the right, it was subordinate or a sublist of the previous line. The examples of the Loop macro I've seen on this mailing list seem to emphasize this: (loop for a from start to end by 5 for b in list do (do-something a b) until (null b)) This indentation immediately suggests: (loop (for a from start to end by 5) (for b in list) (do (do-something a b)) (until (null b))) while this suggests lunacy (?): (loop for a from start to end by 5 for b in list do (do-something a b) until (null b)) -rpg-  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 6 Feb 86 16:27:47 EST Received: from XEROX.COM by SU-AI.ARPA with TCP; 6 Feb 86 13:16:45 PST Received: from Cabernet.ms by ArpaGateway.ms ; 06 FEB 86 12:44:04 PST Date: 6 Feb 86 09:01 PST From: Gregor.pa@Xerox.COM Subject: Re: loop macro In-reply-to: Soley@MC.LCS.MIT.EDU's message of Wed, 5 Feb 86 17:46 EST To: Soley@MC.LCS.MIT.EDU To: Liz@brillig.umd.edu cc: Gregor.pa@Xerox.COM, common-lisp@SU-AI.ARPA Message-ID: <860206-124404-1143@Xerox> ;; Return a list of the items in list-of-items ;; which pass the test TEST. (iterate ((item in list-of-items)) (when (test item) (collect item))) From Soley@MC.LCS.MIT.EDU Parens do not a Lisp code make. This particular example, for instance, isn't any "lispier" than the equivalent LOOP construction; the expression "(collect item)" is CERTAINLY not a call to some new function COLLECT, is it? This call to COLLECT is exactly what Guy said it was, a use of a local macro defined by a macrolet which iterate wraps around its body. From Liz@brillig.umd.edu I once worked with a looping macro that looked like that -- with lots of nested parens. The main problem with it is that, when you look at the code, you tend to think that the (when ...) up there is a function call rather than part of some loop. Yes, the point is that the WHEN up there is a call to the global macro WHEN. I think that is nicer than having some special syntax in the iteration macro that implements the same functionality WHEN already implements.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 6 Feb 86 12:48:59 EST Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 6 Feb 86 09:38:58 PST Received: from desiderius by GODOT.THINK.COM via CHAOS; Thu, 6 Feb 86 12:39:20 est Date: Thu, 6 Feb 86 12:40 EST From: Guy Steele Subject: LISP standardisation To: Fitch%cs.ucl.ac.uk@cs.ucl.ac.uk, common-lisp@SU-AI.ARPA Cc: gls@THINK-AQUINAS.ARPA In-Reply-To: The message of 5 Feb 86 17:27-EST from Fitch%cs.ucl.ac.uk@cs.ucl.ac.uk Message-Id: <860206124034.5.GLS@THINK-DESIDERIUS.ARPA> Thank you for your announcement to the Common Lisp mailing list about progress on the EuLISP effort. Would it be posssible for you (or someone else) to provide a brief description of approximately what content is envisioned for each of the language and programming environment levels, and what major differences from Common Lisp are likely to develop within EuLISP? I realize that precise statements cannot be had yet, but general indications of the current thinking of the EuLISP committee would be very helpful. --Thanks, Guy Steele  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 6 Feb 86 11:39:21 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 6 Feb 86 08:28:44 PST Received: from NEPONSET.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 411361; Thu 6-Feb-86 11:28:22-EST Date: Thu, 6 Feb 86 11:34 EST From: David C. Plummer Subject: eval'd macros (the other point of view) To: Scott E. Fahlman , hpfclp!diamant@HPLABS.ARPA cc: common-lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860206113432.4.DCP@NEPONSET.SCRC.Symbolics.COM> Date: Thu, 6 Feb 1986 00:18 EST From: "Scott E. Fahlman" In most implementations that I have seen, Compile-File lists at the end of the file, as a sort of warning, any functions that were used but that are not known to the compiler. A function generally becomes known either by being present in the Lisp doing the compiling, by being defined in a previously-compiled file, or by being defined somewhere in the current file. Dumping this list is done at the end of a file just so that the order of definitions within a file doesn't cause a lot of spurious warnigns to appear. Co-recursive functions can be defined with no problem, etc. I don't much care whether Compile warns me about undefined functions or not. Since Compile-File waits till the end of the file to complain about unknown functions and special variables, it seems consistent to keep quiet about this when compiling functions one-by-one. If there were a compile-module function (roughly (make-system 'foo :compile)) in our system it should delay warnings until all the files have been processed. Large and/or complex systems often make calls across files. (We could debate the modularity of that, but let's not.)  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 6 Feb 86 10:16:47 EST Received: from CADRE.DSL.PITTSBURGH.EDU by SU-AI.ARPA with TCP; 6 Feb 86 07:04:32 PST Received: by PITTSBURGH.EDU (5.31/5.14) id AA04241; Thu, 6 Feb 86 10:04:29 EST Date: Thu, 6 Feb 86 10:04:29 EST From: sean@cadre.dsl.pittsburgh.edu (Sean McLinden) Message-Id: <8602061504.AA04241@PITTSBURGH.EDU> To: Fahlman@c.cs.cmu.edu Subject: Common Lisp LOOP Package Cc: common-lisp@su-ai.arpa Scott: David Miller's Common Lisp LOOP package is available via ARPA ftp from CADRE (PITTSBURGH.EDU, CADRE.DSL.PITTSBURGH.EDU) on the directory ./lisp using anonymous FTP login. The file is "loop.lisp" This code has been provided by David Miller who has assured me that it was modified from code that could be freely distributed. You are welcome to use it. I would be interested to know of any improvement, bug fixes, etc. Sean  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 6 Feb 86 10:11:06 EST Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 6 Feb 86 06:59:37 PST Date: 6 Feb 1986 09:46-EST Sender: NGALL@G.BBN.COM Subject: Re: intern From: NGALL@G.BBN.COM To: hpfclp!diamant@HPLABS.ARPA Cc: common-lisp@SU-AI.ARPA Message-ID: <[G.BBN.COM] 6-Feb-86 09:46:12.NGALL> In-Reply-To: The message of Wed, 5 Feb 86 13:03:36 pst from hpfclp!diamant@hplabs.ARPA Date: Wed, 5 Feb 86 13:03:36 pst From: hpfclp!diamant@hplabs.ARPA To: hplabs!common-lisp@su-ai.ARPA Subject: intern On page 172 of CLtL, the verb "intern" is defined. It is stated that one action performed is setting the home package of a symbol which doesn't already have one. My question is: does INTERN (the function) always "intern" (the verb). Also, are there any other functions which "intern," such as import, for instance. Specificially, should INTERN set the home package of an uninterned symbol? I asked this question a while back (too bad the archives are so hard to access!). My impression was that there was a consensus that IMPORT is the function that is responsible for "updating" the package-slot of an uninterned symbol (since IMPORT is the only function that can put a SYMBOL in a package). Guy Steele sent out a list of proposed "clarifications" a few months ago (also in the archives). The clarification for IMPORT was: "If symbol has no owner, its package cell is updated." -- Nick  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 6 Feb 86 08:22:24 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 6 Feb 86 05:14:26 PST Received: from CHICOPEE.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 411167; Thu 6-Feb-86 08:13:59-EST Date: Thu, 6 Feb 86 08:16 EST From: Daniel L. Weinreb Subject: Re: loop macro To: liz%brillig.umd.edu@MIT-MC.ARPA cc: BSG@SCRC-STONY-BROOK.ARPA, common-lisp@SU-AI.ARPA In-Reply-To: <860205100800.8.BSG@CONCORD.SCRC.Symbolics.COM> Message-ID: <860206081637.4.DLW@CHICOPEE.SCRC.Symbolics.COM> Date: Wed, 5 Feb 86 10:08 EST From: Bernard S. Greenberg Date: 04 Feb 86 20:52:41 EST (Tue) From: Liz Allen The mention of connecting words kind of puzzles me (and at the same time helps me to understand the Lisp Machine loop macro). Our for macro doesn't seem to need them (though it does use "by" and "until"). What are "let", "initially", "eachtime", "in", "on", "from", "bind", "being", "finally", in your macro, if not connecting words, or am I totally confused? Indeed. Furthermore, the basic syntax you gave is too basic for me to understand the syntax of your proposal, since, for example, you didn't say what an looked like. Furthermore, what does a do; that is, what does "when " mean? Does that means that the first form following the "when" is tested, and the rest are implicit-progn'ed consequents? What does "eachtime" mean and how is it different from "do"? It would help a lot to see an example, too. How would you translate this into your "for" construct? If you can't deal with "until" clauses at the end of the loop, say so and move it to the front and translate that instead. Thanks. (loop for a from start to end by 5 for b in list do (do-something a b) until (null b))  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 6 Feb 86 08:15:21 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 6 Feb 86 05:07:26 PST Received: from CHICOPEE.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 411159; Thu 6-Feb-86 08:06:58-EST Date: Thu, 6 Feb 86 08:09 EST From: Daniel L. Weinreb Subject: lexical scope & program development To: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA, common-lisp@SU-AI.ARPA cc: willc%tektronix.csnet@CSNET-RELAY.ARPA In-Reply-To: <8602052035.AA00785@tekchips> Message-ID: <860206080937.3.DLW@CHICOPEE.SCRC.Symbolics.COM> I don't see how any of this addresses the original issue that I was discussing. Unbound variables have nothing to do with it. Did you read DCP's messages?  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 6 Feb 86 02:21:55 EST Received: from UCBVAX.BERKELEY.EDU by SU-AI.ARPA with TCP; 5 Feb 86 21:42:29 PST Received: by ucbvax.berkeley.edu (5.45/1.9) id AA09476; Wed, 5 Feb 86 20:42:29 PST Received: by renoir.berkeley.edu (5.44/5.16) id AA08869; Wed, 5 Feb 86 16:41:58 PST Message-Id: <8602060041.AA08869@renoir.berkeley.edu> To: common-lisp@su-ai.arpa Cc: larus@dali.berkeley.edu, taylor@kim.berkeley.edu, hilfingr@renoir.berkeley.edu, ho@ernie.berkeley.edu, zorn@renoir.berkeley.edu Subject: Interest in "large" Common Lisp Programs Date: 05 Feb 86 16:41:49 PST (Wed) From: Benjamin Zorn The SPUR Project at UC Berkeley is building a RISC multiprocessor that will run a multiprocessor version of Common Lisp. We are currently evaluating the architectural decisions using a simulator for the machine and are very interested in obtaining "large" Common Lisp programs that would be considered significant applications by people in the field. As we are currently concerned with the performance of Common Lisp without extensions, programs that don't use an object system are preferable to ones that do. Any pointers would be greately appreciated. Ben Zorn Jim Larus Kinson Ho George Taylor Paul Hilfinger UC Berkeley (e-mail to zorn@renoir.berkeley.edu)  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 6 Feb 86 00:33:48 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 5 Feb 86 21:16:27 PST Received: ID ; Thu 6 Feb 86 00:18:15-EST Date: Thu, 6 Feb 1986 00:18 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: hpfclp!diamant@HPLABS.ARPA Cc: common-lisp@SU-AI.ARPA Subject: eval'd macros (the other point of view) In-reply-to: Msg of 5 Feb 1986 19:49-EST from hpfclp!diamant at hplabs.ARPA (defun fn () (mac)) FN (compile 'fn) The following functions were referenced but don't seem defined: MAC referenced by FN FN I also consider this to be a bad idea. Does this mean that COMPILE-FILE will also do this? If so, then it will generate warnings on correct code. In fact, since there is no forward declaration facility, some code (mutually recursive fuctions) would necessarily generate warnings on correct code. Alternately, are you suggesting that COMPILE should generate different warnings than COMPILE-FILE? In this case, while you are not strictly changing the semantics of correct code (since it is a warning instead of an error), you are violating the intent of the consistency argument. It is not incorrect to generate warnings on correct code. A warning says that the compiler cannot prove that some code is incorrect, but that it has spotted something that may be an error, gross inefficiency, or something else the user might want to look at. Such warnings have saved me hundreds of hours of debugging time, and I wouldn't want to do without them. If you don't like them, most compilers let you turn them off. Yes, such warnings do tend to spook naive users who are compiling other people's code. To suppress such warnings, Common Lisp does provide a forward-declaration facility for functions: (declare (ftype...)) or (declare (function ...)). I don't think that the Spice Lisp compiler uses these declarations to suppress warnings, but it should. In most implementations that I have seen, Compile-File lists at the end of the file, as a sort of warning, any functions that were used but that are not known to the compiler. A function generally becomes known either by being present in the Lisp doing the compiling, by being defined in a previously-compiled file, or by being defined somewhere in the current file. Dumping this list is done at the end of a file just so that the order of definitions within a file doesn't cause a lot of spurious warnigns to appear. Co-recursive functions can be defined with no problem, etc. I don't much care whether Compile warns me about undefined functions or not. Since Compile-File waits till the end of the file to complain about unknown functions and special variables, it seems consistent to keep quiet about this when compiling functions one-by-one. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 6 Feb 86 00:02:46 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 5 Feb 86 20:44:14 PST Received: ID ; Wed 5 Feb 86 23:45:46-EST Date: Wed, 5 Feb 1986 23:45 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: "Daniel L. Weinreb" Cc: common-lisp@SU-AI.ARPA Subject: loop macro In-reply-to: Msg of 5 Feb 1986 10:49-EST from Daniel L. Weinreb Dan, From your recent message, it sounds like you and I are not so far apart after all. It seems to me that with a bit of work, one could come up with something that had all the functionality of the Zetalisp LOOP, but with some parentheses to show you where one clause leaves off and another starts instead of depending on a lot of syntactic analysis for this. The H-P and/or PCL constructs might serve as a starting point, but I'm not wedded to the idea of always putting the counters at the start. I'm sure if we all thought hard about it, we could find ways of dealing with such potential warts as UNTIL and ALWAYS. Once you've got the parens in there, things like COLLECT can be forms that are defined only within the scope of a LOOP, but that can appear inside of Lisp conditionals or other code. If enough people like this idea, it would be worth the trouble of trying to work out the details. As long as we're divided into the camps of "English-like LOOP is the only acceptable way" and "Over my dead body", there's not much point in messing with this, however. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 5 Feb 86 23:36:34 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 5 Feb 86 20:24:45 PST Received: ID ; Wed 5 Feb 86 23:25:59-EST Date: Wed, 5 Feb 1986 23:25 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: hpfclp!diamant@HPLABS.ARPA Cc: common-lisp@SU-AI.ARPA Subject: eval'd macros (the other point of view) In-reply-to: Msg of 5 Feb 1986 19:49-EST from hpfclp!diamant at hplabs.ARPA I would like to second Kent Pitman's opinion. Maybe no one has mentioned this objection because it is so obvious -- it is still very important. I think that it is a bad idea to have the interpreter defer expansion of macros because it is just one more case of differing interpreter and compiler semantics. If I am to believe the statement regarding consistency in the introduction of CLtL: "The definition of COMMON LISP avoids such anomalies by explicitly requiring the interpreter and compiler to impose identical semantics on correct programs so far as possible," then as Kent suggests, the interpreter should not defer expansion because the compiler is required not to. Well, if we wanted everything to be ABSOLUTELY IDENTICAL between compiled and interpreted code, except that the compiled code runs faster, there would be no point in having an interpreter at all. The compiler, in the name of efficiency, does certain things to the code that makes debugging and incremental changes harder. For example, in most systems you can't single-step code once it is compiled, and in some systems you can't trace it. It would be nice if these things kept on working after compilation, but it is hard to arrange this. In Lisp we go to some trouble to allow you to redefine functions, even after a lot of calls to those functions have been compiled. Those calls see the new definition, whether it is compiled or interpreted. Macros and inline functions get burned in and cannot later be changed without finding all the calls and recompiling them. That's too bad, but it's the price you pay for avoiding the overhead of a function call. (This immutability is sometimes deliberately used to lock out later changes, but that is fairly rare and could be handled by some specialized kind of call.) So we have to give up the ability to change macros (or define them after the call) in compiled code, but to live without this ability in the interpreter would be a tremendous pain. People who have written macro-memoizing functions to speed up interpreters have generally gone to a lot of trouble to put in some way of un-memoizing when a macro gets redefined. I don't think I'd try to develop code in any system that expanded all the macros at DEFUN time unless it included a very well-engineered and transparent un-memoizing function. I grant that if the interpreter waits until use before expanding a macro, it would be easy to create a file of code that works interpreted and errs out when you compile it. Any good compiler will make it very clear what the problem is: "FOO being defined as a macro, earlier assumed to be a function" or some such message, so it is not a treacherous kind of incompatibility like some of the special/local stuff used to be. So getting rid of this incompatibility is not nearly as important to me as being able to fix up faulty macros while I am debugging. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 5 Feb 86 22:14:58 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 5 Feb 86 19:01:22 PST Received: from CHICOPEE.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 410289; Wed 5-Feb-86 10:49:34-EST Date: Wed, 5 Feb 86 10:49 EST From: Daniel L. Weinreb Subject: loop macro To: Fahlman@C.CS.CMU.EDU cc: common-lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860205104933.5.DLW@CHICOPEE.SCRC.Symbolics.COM> It sounds like what you're really saying isn't that you dislike keywords in all cases, but that you dislike keywords when they aren't the first element of a list. The main reason you cite is that it's inconsistent with the rest of the language, which never does that. This is a pretty good argument and it's mostly true. On the other hand, I'm not sure it's completely true. Compare (reduce #'+ seq :start 5 :end 7) and (loop for a from 4 below 7 do ..body..) I'm not sure they're really all that different. The fact that LOOP uses infix keywords, per se, doesn't make LOOP that different from the rest of the language. The thing that's more upsetting is (loop for a from 4 below 7 for b from 7 do ..body..) because there is a clear grouping between the elements in the first "for" clause and the elements in the second "for" clause, but that grouping is not expressed by parentheses. I think this is where the existing LOOP starts to look inconsistent with the syntax of the rest of the language. Because you've mentioned "little words as delimiters" in some of your mail, I suspect that this is the real point of contention. I agree that this is a drawback to the existing LOOP. The most obvious way to try to repair this is to make the syntax look more like DO, by having a bunch of iteration-specifying constructs at the front of the form, followed by a body. This might look like the schemes we've seen in recent mail. However, this severely restricts the power of the construct. Here's the most basic and obvious example that comes to my mind. One of our basic requirements for LOOP was that it should be able to support the popular repeat/until construct present in many of the Pascal-family languages, in which the checking is done at the end of the loop rather than at the beginning. For clarity, we felt that the predicate form ought to appear syntactically following the body. It's possible that this should be handled by simply telling the program to write a (when (return )) in the body. We didn't like this solution, because it seemed too much like a step backward from DO back towards PROG. Part of the idea of DO was to get the basic iteration control constructs separate from the body. After all, we don't need the end-test part of DO at all; a similar when/return at the beginning of the body would have the same effect. We could add grouping without going so far as to force all clauses to the front. (loop (for a from 4 below 7) (for b from 7) (do ..body..) (until ..pred..)) I think this might be an improvement. One problem is that we were hoping to get rid of the "do" keyword entirely (Moon agrees with this), but with this change, it's harder to see how to accomplish that. Your argument about finding it "hard to remember which little words" is something I can only partially agree with. One might just as well point out that Common Lisp has many functions and special forms, and it's often hard to remember their names. This sounds to me like a question of the programming environment and the organization of the documentation, more than a question of language design. There's another LOOP feature that I consider quite valuable, and I also think that the clauses-up-front-and-a-body syntax might be hard to extent to handle. This is the "always" keyword and its friends. (loop for e in list always ) is more expressive than (not (dolist (e list) (when (return t)))) or (not (find-if-not #'(lambda (e) ) list) and it's also more general, because the range of iteration that LOOP can express is so much more than just iterating over one sequence. ALWAYS is strange because the predicate form is really the body, in some sense, but we aren't just executing it for effect over and over. This is why I'm not sure it fits into the clauses-up-front structure so well; I think it would be sort of strange for the predicate form to live in one of the clauses-up-front and for the body to be empty. Since I'm getting into details, I should make quite clear that I do not speak for Moon in the matter of LOOP. Our opinions on this topic diverge much more than they do on most other topics. One of my own strong feelings about LOOP that Moon does not share is that we should get rid of the conditionals. I think Common Lisp has at least enough basic conditional forms as it is, and having separate ones for LOOP is beyond the pale. I am particularly grossed out by the idea of having a "dangling ELSE" in Lisp. The present LOOP, like the conventional languages, has the convention that such an ELSE binds to the inner IF. This fits into Lisp just about as much as the concept of "operator precedence", i.e. not at all. The main reason for the conditionals is so that COLLECT clauses can be executed conditionally. (I don't know for sure whether there are other reasons for the conditionals.) The usual proposed solution is to make COLLECT a regular Lisp macro, that communicates with an outer collector macro via COMPILER-LET, making COLLECT a separate facility completely orthogonal to LOOP. It seems clear to me that this is the right thing to do. After all, suppose you want to write a program that does a double recursion down a binary tree, and collects something as it goes? LOOP can't handle this kind of iteration, but you still want COLLECT. Yes, I know you can write your own LOOP iteration path, but what if you think that nice, traditional, Lispy recursion is a simple and expressive way to write your program? These are just some of the traditional issues of LOOP redesign. There are definitely others. I just wanted to give everyone some idea of the kinds of things we've thought about.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 5 Feb 86 22:09:46 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 5 Feb 86 18:59:51 PST Received: from CONCORD.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 410230; Wed 5-Feb-86 09:59:17-EST Date: Wed, 5 Feb 86 10:08 EST From: Bernard S. Greenberg Subject: Re: loop macro To: liz%brillig.umd.edu@MIT-MC.ARPA, common-lisp@SU-AI.ARPA In-Reply-To: <8602050152.AA10539@brillig.umd.edu> Message-ID: <860205100800.8.BSG@CONCORD.SCRC.Symbolics.COM> Date: 04 Feb 86 20:52:41 EST (Tue) From: Liz Allen The mention of connecting words kind of puzzles me (and at the same time helps me to understand the Lisp Machine loop macro). Our for macro doesn't seem to need them (though it does use "by" and "until"). To explain how this works, let me give for's basic syntax: (for [ let * ]* ; is or ( ) [ initially * ]* [ * ]* ; in, on, from, bind, being, etc [ eachtime * ]* [ * ]* ; while * or until * [ * ]* ; when * or unless * [ * ] ; is do, collect, etc [ finally * ] ) I'm not trying to say that Common Lisp should necessarily adopt the Maryland for as its looping construct. I just trying to say that there ought to be some way to get rid of the concept of connecting words without having to put parens around all the clauses... Can the syntax for the Lisp Machine Loop be simplified along these lines without losing big? What are "let", "initially", "eachtime", "in", "on", "from", "bind", "being", "finally", in your macro, if not connecting words, or am I totally confused?  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 5 Feb 86 21:13:02 EST Received: from CS.UCL.AC.UK by SU-AI.ARPA with TCP; 5 Feb 86 15:34:36 PST Date: Wed, 5 Feb 86 22:27:57 GMT From: Fitch%cs.ucl.ac.uk@cs.ucl.ac.uk To: common-lisp@su-ai.arpa cc: ma_jap%ux63.bath.ac.uk@cs.ucl.ac.uk Subject: LISP standardisation A statement about the European standardisation effort on LISP. A committee, called the EuLISP committee, has met regularly since September of last year to prepare a definition of LISP for presentation to the respective national standards organisations of the members and thence to ISO. Regular participants include Chailloux, Christaller, Krumnack, Fitch, Padget, Pope, Queinnec and Steels. EuLISP is simply the name of the committee; the name of the defined language will, we hope, be ISO LISP. For convenience that name is used for the definition in the rest of this message. ISO LISP is a post Common LISP (CL) LISP, which is to say that it draws on the experience of the CL definition and development effort, as well as the experience of other LISP activities. ISO LISP has a compact, identifiable kernel, which, in itself, will correspond to the level 0 definition. The full ISO LISP will be defined at several levels in two dimensions. Along one axis is the complexity of the language, and along the other are the multiple levels of programming environment support. It is our intention to define the kernel such that Level (0,0) be very simple and portable even to current micro-computers while Level (3,3) (or more likely (3,2) or (3,1)) with less environment will have at least the breadth and depth of CL as discussed in Steele et al. (Digital Press), but this should by no means be read as a committment to correspond exactly or completely (by extension or omission) with that document. CL is certainly the major input to the definition, but it is not the only one. Even now, CL, as laid down by Steele et al., is under review and this fact alone makes such a committment unwise. The EuLISP committee includes representatives of the implementors of two LISP dialects widely used outside the United States, namely Le_LISP and Cambridge LISP, in addition to large LISP users. The effect of this is that the committee can take advantage of the lessons learnt over the lives of these systems, whilst at the same time using them as an environment for prototyping the new definition. Let it be clearly stated that this is not an attempt to make either Cambridge LISP or Le_LISP or some hybrid into a standard, but to evolve a new standard. A fundamental part of the definition process includes a rationale for ISO LISP and, incrementally, there will be a rationale for each major design decision, such as why something is included, excluded or at variance in some other way with existing dialects. The EuLISP committee meets on the first Monday of each month and the sessions are open. The next three meetings are scheduled as follows: March 3 1986 - IRCAM (near Pompidou Centre), Paris. April 7 1986 - INRIA, Sophia Antipolis (near Nice). May 5 1986 - IRCAM, Paris. Subsequent meetings will be arranged on a three month forward plan. We are determined that the definition will be complete in twelve months and in accordance with that aim, the draft level 0 definition will be produced by 1 June 1986. It is also expected that prototype implementations will conform to that definition very close to that date. The monthly meetings are first and foremost for coordination, review and setting the next group of objectives. The remaining time is allotted to technical issues, but for the most part, such details are discussed on electronic mail, to which end there is a mailing list: {seismo,decvax}!mcvax!inria!eulisp at INRIA (Paris). Interested parties should mail Chailloux at that address (...!inria!chailloux) to be added.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 5 Feb 86 21:07:11 EST Received: from CS.UCL.AC.UK by SU-AI.ARPA with TCP; 5 Feb 86 15:28:30 PST Received: from aiva.edinburgh.ac.uk by 44d.Cs.Ucl.AC.UK via Janet with NIFTP id a000388; 5 Feb 86 16:55 GMT From: Jeff Dalton Date: Wed, 5 Feb 86 16:56:03 GMT Message-Id: To: Fahlman@c.cs.cmu.edu, KMP@scrc-stony-brook.arpa Subject: Re: eval'd macros (the other point of view) Cc: common-lisp@su-ai.arpa Having macros expanded when the defun is first seen offers the nice feature that you can't easily break functions you've already written as you enter a debugging phase. You also can't FIX functions you've already written by changing the macros they call. You now have to go back and find every last function that calls FOO, and re-expand it to do the right thing, assuming that you've got the source handy. Things that I'm sure are right and that I don't want to break are usually already compiled. One advantage of having the interpreter expand macros when it sees a DEFUN is that it would reduce the differences between the compiler and the interpreter. (Of course, this may be exactly the kind of difference you want to preserve.) And, as has been mentioned, you would then know that all macro calls had been expanded, not just those that had been evaluated. You could still fix these functions by changing the macro if the macro expansion was memoized in such a way that it noticed when the macro was redefined. Similarly, if you didn't want to break functions when the macro was redefined, some way of inhibiting their noticing the redefinition could be provided. -- Jeff  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 5 Feb 86 20:47:49 EST Received: from HPLABS.ARPA by SU-AI.ARPA with TCP; 5 Feb 86 17:34:52 PST Received: by hplabs.ARPA ; Wed, 5 Feb 86 13:03:36 pst Date: Wed, 5 Feb 86 13:03:36 pst From: hpfclp!diamant@hplabs.ARPA To: hplabs!common-lisp@su-ai.ARPA Subject: intern On page 172 of CLtL, the verb "intern" is defined. It is stated that one action performed is setting the home package of a symbol which doesn't already have one. My question is: does INTERN (the function) always "intern" (the verb). Also, are there any other functions which "intern," such as import, for instance. Specificially, should INTERN set the home package of an uninterned symbol? example: (setq sym (gensym)) ; make an uninterned symbol (import sym) ; make it available in the current package ; assuming import did not set the home package (is this a correct assumption?): (intern (symbol-name sym)) ; (note: intern takes a string, not symbol, argument) ; looks up (interns?) the symbol ; should intern set the home package? ; then consider: (find-symbol (symbol-name sym)) ; find-symbol is defined to be just like intern, ; but does not make a new symbol ; in this case it finds an existing symbol, ; so should find-symbol set the home package? relevant material from CLtL page 172 a symbol is interned in a package if 1) it is accessible in that package 2) its package cell is not NIL (any package may own it) to intern a symbol in a package 1) is performed by the function INTERN 2) makes the symbol interned in the package, unless it already was 3) if the symbol was previously unowned (its package cell was NIL) then the package it is being interned in becomes its owner else the package cell is not changed page 184 the function INTERN sets the package cell if it must create a new symbol, but no mention is made of setting the package if it finds an existing unowned symbol page 185 the function FIND-SYMBOL is identical to INTERN except when no symbol is found, in which case it returns NIL page 186 the function IMPORT makes symbols "internal symbols" in a package does this imply that they are interned in the package? My feeling on this is that INTERN should set the home package if the symbol currently has none, but that FIND-SYMBOL should not. If this is correct, then the definition of FIND-SYMBOL on page 185 is misleading. John Diamant Fort Collins Systems Division UUCP: {ihnp4,hplabs}!hpfcla!diamant Hewlett Packard Co. ARPA/CSNET: diamant%hpfcla@hplabs Fort Collins, CO  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 5 Feb 86 20:01:13 EST Received: from CSNET-RELAY.ARPA by SU-AI.ARPA with TCP; 5 Feb 86 16:48:35 PST Received: from tektronix by csnet-relay.csnet id ak16364; 5 Feb 86 19:33 EST From: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA To: common-lisp@su-ai.ARPA Cc: willc%tektronix.csnet@CSNET-RELAY.ARPA Received: from tekchips by tektronix with smtp ; 5 Feb 86 12:34:05 PST Comment: Message received over unauthenticated port at tektronix Received: by tekchips (5.31/5.14), id AA00785; Wed, 5 Feb 86 12:35:28 PST Message-Id: <8602052035.AA00785@tekchips> Subject: lexical scope & program development Date: 05 Feb 86 12:35:22 PST (Wed) Date: Fri, 31 Jan 86 12:37 EST From: Daniel L. Weinreb I believe that all the problems you've been talking about have to do with the poor interaction between lexical scoping and incremental programming. These poor interactions are discussed in the paper "The Art of the Interpreter: Parts Zero, One, and Two" by Guy Steele and Gerry Sussman. They are not incidental design flaws of Common Lisp; they are part of the deep nature of lexical scoping. I don't think they represent a "time bomb" in the language. They just show how lexical scoping, itself, has problems when it comes to program development, when used in this way.... People here who have constructed an incremental programming environment for a lexically scoped language tell me that lexical scope was among the least of their worries. If a lexically scoped interactive language takes the point of view that all unbound variables are really variables bound to locations in which undefined values are stored (so that all definitions are viewed as assignments rather than bindings), and variable fetches that yield such values are trapped, then most of the problems cited in the paper by Steele and Sussman go away. There remain needs for (1) temporary assignments (as in the current MIT Scheme dynamic variable semantics); (2) module facilities that can hide or expose variables (as in the Common Lisp package system or MIT Scheme environments); and (3) debugging facilities (as in a debugger). A dynamically scoped top level only solves problem (1), and solves it only for top level variables. Since (1) must be solved for lexical variables anyway, a dynamically scoped top level is neither necessary nor useful. The real problem with lexical scope and interactive program development is that lexical scope is a hiding mechanism, and hiding hinders the debugging process. It seems to me that the solution is a good debugger that can expose the hidden, for example by allowing the programmer to crawl through the environment of a closure and to evaluate code in any environment that can be reached that way. (I realize that some compilers don't keep enough information around to support such a debugger, or they perform so much optimization that it's impractical, but in such a case I'd say that it is the compiler, not lexical scope, that is incompatible with interactive program development.) William Clinger willc@tektronix.csnet Tektronix Computer Research Laboratory  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 5 Feb 86 20:00:39 EST Received: from HPLABS.ARPA by SU-AI.ARPA with TCP; 5 Feb 86 16:49:34 PST Received: by hplabs.ARPA ; Wed, 5 Feb 86 16:49:03 pst Date: Wed, 5 Feb 86 16:49:03 pst From: hpfclp!diamant@hplabs.ARPA To: hplabs!common-lisp@su-ai.ARPA Subject: Re: eval'd macros (the other point of view) From: David C. Plummer Subject: eval'd macros Date: Mon, 3 Feb 1986 20:36 EST From: "Scott E. Fahlman" (defun fn () (mac)) ;==> FN (defmacro mac () `'foo) ;==> MAC (fn) ;==> ***Error*** ... In my opinion, this should work without an error in the interpreter. Hacking in the interpreter would be fairly awkward if it didn't. However, the fourth paragraph on page 143 seems to give implementors permission to do compiler-like macro expansion when a defun is first seen. I wouldn't want to use such an implementation, but it probably is legal as the manual currently stands. I would like to second Kent Pitman's opinion. Maybe no one has mentioned this objection because it is so obvious -- it is still very important. I think that it is a bad idea to have the interpreter defer expansion of macros because it is just one more case of differing interpreter and compiler semantics. If I am to believe the statement regarding consistency in the introduction of CLtL: "The definition of COMMON LISP avoids such anomalies by explicitly requiring the interpreter and compiler to impose identical semantics on correct programs so far as possible," then as Kent suggests, the interpreter should not defer expansion because the compiler is required not to. If the system goes further and actually DOES compile the defun, then I would consider it a user-interface bug that the compiler doesn't tell the user that it couldn't find a function call MAC. (defun fn () (mac)) FN (compile 'fn) The following functions were referenced but don't seem defined: MAC referenced by FN FN I also consider this to be a bad idea. Does this mean that COMPILE-FILE will also do this? If so, then it will generate warnings on correct code. In fact, since there is no forward declaration facility, some code (mutually recursive fuctions) would necessarily generate warnings on correct code. Alternately, are you suggesting that COMPILE should generate different warnings than COMPILE-FILE? In this case, while you are not strictly changing the semantics of correct code (since it is a warning instead of an error), you are violating the intent of the consistency argument. The problems with compiler/interpreter semantics are bad enough in packages that we should try to avoid unnecessarily propagating them in other areas. John Diamant Fort Collins Systems Division UUCP: {ihnp4,hplabs}!hpfcla!diamant Hewlett Packard Co. ARPA/CSNET: diamant%hpfcla@hplabs Fort Collins, CO  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 5 Feb 86 18:32:11 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 5 Feb 86 15:20:23 PST Received: from CHERRY.LCS.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 5 FEB 86 17:47:19 EST Date: Wed, 5 Feb 86 17:46 EST From: Soley@MIT-MC.ARPA Subject: Re: loop macro To: Gregor.pa@Xerox.COM cc: common-lisp@SU-AI.ARPA In-Reply-To: <860204-155111-2418@Xerox> Message-ID: <860205174634.3.SOLEY@MIT-CHERRY.ARPA> Date: 4 Feb 86 15:50 PST From: Gregor.pa@Xerox.COM Subject: Re: loop macro In-reply-to: Bernard S. Greenberg 's message of Tue, 4 Feb 86 16:38 EST To: BSG@SCRC-STONY-BROOK.ARPA cc: Fahlman@C.CS.CMU.EDU, common-lisp@SU-AI.ARPA Message-ID: <860204-155111-2418@Xerox> I think I prefer "lispy" iteration macros. Here is an example of what I mean by a lispy iteration macro: ;; Return a list of the items in list-of-items ;; which pass the test TEST. (iterate ((item in list-of-items)) (when (test item) (collect item))) Parens do not a Lisp code make. This particular example, for instance, isn't any "lispier" than the equivalent LOOP construction; the expression "(collect item)" is CERTAINLY not a call to some new function COLLECT, is it? -- Richard  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 5 Feb 86 18:31:53 EST Received: from MCC.ARPA by SU-AI.ARPA with TCP; 5 Feb 86 15:18:01 PST Date: Wed, 5 Feb 1986 15:56 CST Message-ID: From: AI.BOYER@MCC.ARPA To: common-lisp@SU-AI.ARPA Subject: loop speed As Guy Steele recently pointed out, it is certainly the case that constructs written with loop can often be recoded using the mapping functions. I stopped using the mapping functions a long time ago in Interlisp in large part because I found that I.S.OPR expressions, the inspiration for loop, ran significantly faster. Has the situation changed much? I certainly have not made a careful comparison of the matter recently, but I just timed the two following functions, after compilation: (defun remove-if-test (l) (remove-if #'atom l)) (defun loop-test (l) (loop for x in l unless (atom x) collect x)) Loop-test runs 3 to 4 times faster than remove-if-test in Symbolics Common Lisp on a 3640 on long lists of nils. Inspired by the fact that Guy can recode many uses of loop into maps, perhaps someone can write a compiler that can take maps back to loops for compilation efficiency!  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 5 Feb 86 18:12:59 EST Received: from UTAH-CS.ARPA by SU-AI.ARPA with TCP; 5 Feb 86 14:59:31 PST Received: by utah-cs.ARPA (5.31/4.40.2) id AA01868; Wed, 5 Feb 86 16:00:27 MST Received: by utah-orion.ARPA (5.31/4.40.2) id AA03174; Wed, 5 Feb 86 16:00:24 MST Date: Wed, 5 Feb 86 16:00:24 MST From: shebs%utah-orion@utah-cs.arpa (Stanley Shebs) Message-Id: <8602052300.AA03174@utah-orion.ARPA> To: common-lisp@su-ai.arpa Subject: GLS replacements for LOOP I really liked the examples Guy presented - I've long had the feeling that some of the sequence functions could be really really useful if only I knew how to use them! And although I've translated PSL's FOR macro into portable CL, it only seems to get used for compatibility with old PSL code. So I've sort of drifted from camp 3 to camp 1. There are a couple problems with using tricky sequence functions etc instead of generalized loop constructs. Loop macros are frequently easier to modify - I can just stick in another clause. The before and after equivalent sequence function calls may be quite dissimilar. There are more serious questions of efficiency. Loops macros tend to expand into Fortran-like code. A large proportion of the loops in PSL's runtime system are written using a version of FOR that totally opencodes; I believe the same is true of Zetalisp. On the other hand, this is a little harder to do with the sequence functions. Guy's example of a multiple-iterator loop turning into (list (mapcar ...) (mapcar ...) ...), could be fully opencoded, but that would take a pretty aggressive compiler that had just seen (proclaim '(optimize (speed 3) (safety 0))). Is anybody's compiler "sufficiently good" to turn sequence function usages into code as efficient as LOOP produces? stan  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 5 Feb 86 12:15:35 EST Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 5 Feb 86 09:00:25 PST Received: from desiderius by GODOT.THINK.COM via CHAOS; Wed, 5 Feb 86 12:00:36 est Date: Wed, 5 Feb 86 12:01 EST From: Guy Steele Subject: Re: loop macro To: Gregor.pa@Xerox.COM, BSG@SCRC-STONY-BROOK.ARPA Cc: Fahlman@C.CS.CMU.EDU, common-lisp@SU-AI.ARPA, gls@THINK-AQUINAS.ARPA In-Reply-To: <860204-155111-2418@Xerox> Message-Id: <860205120150.4.GLS@THINK-DESIDERIUS.ARPA> Okay, now here is a different perspective on the LOOP problem. I will play devil's advocate here and claim that the main purpose of LOOP is to duplicate the functionality of the sequence functions. Indeed, when illustrating uses of LOOP we tend to pick as examples things that are single sequence functions, which only gives me extra confidence that Common Lisp has captured a useful set of primitive iteration operations in these sequence functions. Here follows renderings of Gregor's examples in this manner. (I don't mean to pick on Gregor; rather, he has done us the great service of providing a few examples for discussion, and I'm discussing them.) ;; Return a list of the items in list-of-items ;; which pass the test TEST. (iterate ((item in list-of-items)) (when (test item) (collect item))) (remove-if-not #'test list-of-items) ;; Basically FIRSTN ;; Get the first 10 items in a list (iterate ((item in list) (i from 0 below 10)) (collect y)) (subseq list 0 10) ;; Sort of GETL. ;; (iterate ((prop on plist by cddr)) (when (memq (car prop) properties-to-collect) (collect prop))) This one is indeed hard to do with sequence functions (because a property list is not uniform). Instead I shall write a DO loop: (do ((prop plist (cddr prop)) (result '() (if (memq (car prop) properties-to-collect) ---------------- (cons prop result) ----- ------- result))) -------- ((null prop) (nreverse result))) ----------------- In this case the simple word "collect" certainly has captured a common pattern of use (the parts underlines above), and so I cannot deny that the iterate/collect syntax is more concise in this case. ;; Return a left hand to match left-hand-to-match ;; or error if couldn't find one. (iterate ((left in left-hands) (right in right-hands)) (when (eq left left-to-match) (return right)) (finally (error "Could find a right hand."))) (let ((pos (position left left-hands :test #'eq))) (if pos (elt right-hands pos) (error "Could find a right hand."))) ;[Sic] Because of their small size, these examples may not be convincing to everyone. As additional evidence, here are some more complex examples of uses of LOOP, taken from the Symbolics documentation (Volume 2: Reference Guide to Symbolics-Lisp, March 1985): Page 213: (loop for x in list collect (foo x) into foo-list collect (bar x) into bar-list collect (baz x) into baz-list finally (return (list foo-list bar-list baz-list))) (list (mapcar #'foo list) (mapcar #'bar list) (mapcar #'baz list)) Page 217: (loop for x in l when (atom x) when (memq x *distinguished-symbols*) do (process1 x) else do (process2 x) ;[Sic--indentation bug!] else when (memq (car x) *special-prefixes*) collect (process3 (car x) (cdr x)) and do (memorize x) else do (process4 x)) (mapcan #'(lambda (x) (cond ((atom x) (if (memq x *distinguished-symbols*) (process1 x) (process2 x)) nil) ((memq (car x) *special-prefixes*) (prog1 (list (process3 (car x) (cdr x))) (memorize x))) (t (process4 x) nil))) l) Finally, here are a few examples taken from actual code. These first few are taken from the Symbolics implementation of FORMAT (I hope Symbolics won't mind my quoting a few lines of code for academic "review purposes"). I'm more or less just going to take the first several loops I come to: (LOOP FOR I FROM OLD-FILL-POINTER BELOW NEW-FILL-POINTER DO (ASET #\SP FORMAT-STRING I)) (fill format-string #\sp :start old-fill-pointer :end new-fill-pointer) (LOOP FOR I FROM CTL-INDEX BELOW (OR TEM CTL-LENGTH) DO (FUNCALL *FORMAT-OUTPUT* ':TYO (SYS:CL-CHAR-CODE (AREF CTL-STRING I)))) (map nil #'(lambda (x) (funcall *format-output* ':tyo (sys:cl-char-code x))) (subseq ctl-string ctl-index (or tem ctl-length))) (LOOP FOR X = (ABS ARG) THEN (// X BASE) COUNT T UNTIL (< X BASE)) This isn't operating on sequences, so I will render this as a DO loop: (do ((x (abs arg) (// x base)) (n 0 (+ n 1))) ((< x base) n)) (LOOP FOR DIVISOR = (^ BASE (1- NDIGITS)) THEN (// DIVISOR BASE) DO (FUNCALL *FORMAT-OUTPUT* ':TYO (+ (// ARG DIVISOR) #/0)) UNTIL (= DIVISOR 1) DO (SETQ ARG (\ ARG DIVISOR)) (WHEN (ZEROP (\ (DECF NDIGITS) 3)) (FUNCALL *FORMAT-OUTPUT* ':TYO COMMACHAR))) Again, sequences are not involved here, so I use a DO loop. (do ((DIVISOR (^ BASE (1- NDIGITS)) (// DIVISOR BASE))) (()) (FUNCALL *FORMAT-OUTPUT* ':TYO (+ (// ARG DIVISOR) #/0)) (when (= DIVISOR 1) (return)) (SETQ ARG (\ ARG DIVISOR)) (WHEN (ZEROP (\ (DECF NDIGITS) 3)) (FUNCALL *FORMAT-OUTPUT* ':TYO COMMACHAR))) (LOOP REPEAT WIDTH DO (SEND *FORMAT-OUTPUT* ':TYO OVERFLOW-CHAR)) (dotimes (j width) (declare (ignore j)) (SEND *FORMAT-OUTPUT* ':TYO OVERFLOW-CHAR)) (LOOP FOR I FROM 0 FOR X IN LIST DO (ASET X ARRAY I)) (replace array x) Now here are some examples taken from a microcode assembler written at Thinking Machines: (LOOP FOR DELAYED-FUNCTION IN *DELAYED-ASSEMBLY-FUNCTIONS* FOR SYMBOL = (GET-DELAYED-ASSEMBLY-SYMBOL DELAYED-FUNCTION) DO (SETF (SYMEVAL SYMBOL) NIL)) (dolist (delayed-function *delayed-assembly-functions*) (setf (symeval (get-delayed-assembly-symbol delayed-function)) nil) [I don't know why SET was not used there.] ;; if there were any MMCALLs, they must be removed. (SETQ *ALL-MMCALLS* (LOOP FOR CALL-ITEM IN *ALL-MMCALLS* FOR CALLING-LOCATION = (SECOND CALL-ITEM) FOR CALLING-INSTR = (AREF INSTR-FROM-LOC CALLING-LOCATION) WHEN (NOT (<= START-INSTR CALLING-INSTR STOP-INSTR)) COLLECT CALL-ITEM)) (setq *all-mmcalls* (remove-if-not #'(lambda (call-item) (let* ((calling-location (second call-item)) (calling-instr (aref instr-from-loc calling-location))) (<= start-instr calling-instr stop-instr))) *all-mmcalls*)) (LOOP FOR INSTR FROM START-INSTR BELOW (1+ STOP-INSTR) DO ;; smash the instruction at this location (SETF (AREF INSTR-AFTER-INLINE-MACROEXPAND INSTR) NIL) (SETF (AREF INSTR-BEFORE-INLINE-MACROEXPAND INSTR) NIL) (progn (fill instr-after-inline-macroexpand nil :start start-instr :end (1+ stop-instr)) (fill instr-before-inline-macroexpand nil :start start-instr :end (1+ stop-instr))) (LOOP FOR (VARIABLE-NAME TYPE . REST) IN *UC-CS-ELEMENTS* COLLECTING VARIABLE-NAME) (mapcar #'car *uc-cs-elements*) [Admittedly the destructuring gives one a nice picture of what's going on.] In a fair amount of recent programming in Common Lisp, I have found that extensive use of MAP, REDUCE, and REMOVE-IF eliminates the need for a lots of explicit loops. Certainly the code generates some intermediate list structure that could be eliminated. I would very much like to see compilers that can, in certain easy cases, open-code calls to a few of these sequence functions and jam loops together. Here are examples of code originally rendered in that style, along with a translations using LOOP: (reduce #'union (mapcar #'xapping-exceptions args) :initial-value '()) (LOOP FOR X IN ARGS UNIONING (XAPPING-EXCEPTIONS X)) [This assumes I manage to define a new collector UNIONING (not supplied in Symbolics LOOP).] (LOOP FOR X IN ARGS FOR RESULT = '() THEN (UNION RESULT (XAPPING-EXCEPTIONS X)) FINALLY (RETURN RESULT)) (reduce #'intersection (mapcar #'xapping-domain (remove-if #'xapping-infinite args))) (LOOP FOR X IN ARGS FOR RESULT = T UNLESS (XAPPING-INFINITE X) WHEN (EQ RESULT T) DO (SETQ RESULT X) ELSE DO (SETQ RESULT (INTERSECTION RESULT X))) Can anyone else render these examples more elegantly using LOOP? I'm not sure I have demonstrated the point I set out to prove, but I think I have provided some more interesting examples to discuss. --Guy  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 5 Feb 86 10:40:40 EST Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 5 Feb 86 07:21:02 PST Received: from desiderius by GODOT.THINK.COM via CHAOS; Wed, 5 Feb 86 10:21:21 est Date: Wed, 5 Feb 86 10:22 EST From: Guy Steele Subject: Re: loop macro To: Gregor.pa@Xerox.COM, BSG@SCRC-STONY-BROOK.ARPA Cc: Fahlman@C.CS.CMU.EDU, common-lisp@SU-AI.ARPA, gls@THINK-AQUINAS.ARPA In-Reply-To: <860204-155111-2418@Xerox> Message-Id: <860205102236.3.GLS@THINK-DESIDERIUS.ARPA> Date: 4 Feb 86 15:50 PST From: Gregor.pa@Xerox.COM I think I prefer "lispy" iteration macros. Here is an example of what I mean by a lispy iteration macro: ;; Return a list of the items in list-of-items ;; which pass the test TEST. (iterate ((item in list-of-items)) (when (test item) (collect item))) I would like to note that the implementation of such an iteration macro is one of the reasons that FLET and LABELS were included. The expansion of (ITERATE ((ITEM IN LIST-OF-ITEMS)) body) might look like (DO ((#:G0001 LIST-OF-ITEMS (CDR #:G0001)) (#:G0002 '())) ((NULL #:G0001) #:G0002) (FLET ((COLLECT (X) (SETQ #:G0002 (NCONC #:G0002 (LIST X))))) (DECLARE (INLINE COLLECT)) body)) Of course, the FLET would need to define all kinds of collectors that might be needed, including MAXIMIZE, SUM, and so on; this leaves a problem as to what the initial value for the result should be, in case the collector is never called. One can do better by groveling through the body, of course. Yuk. Anyway, MACROLET is useful if some collector needs special syntax. --Guy  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 5 Feb 86 09:25:51 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 5 Feb 86 06:16:40 PST Received: ID ; Wed 5 Feb 86 09:17:49-EST Date: Wed, 5 Feb 1986 09:17 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: sean@cadre.dsl.pittsburgh.edu (Sean McLinden) Cc: common-lisp@SU-AI.ARPA Subject: loop macro In-reply-to: Msg of 4 Feb 1986 22:54-EST from sean at cadre.dsl.pittsburgh.edu (Sean McLinden) Sean, In that case, if Miller is willing and if there are no legal complications with MIT over copyright issues, this would be an excellent thing to make available to the community. We can distribute it from here, along with other portable stuff, if you like. I'm hoping that ISI will be taking over the job of librarian soon, but in the meantime I've assigned someone here to clean up our library directory and separate out the perq-specific stuff. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 4 Feb 86 23:06:01 EST Received: from CADRE.DSL.PITTSBURGH.EDU by SU-AI.ARPA with TCP; 4 Feb 86 19:53:59 PST Received: by PITTSBURGH.EDU (5.31/5.14) id AA29262; Tue, 4 Feb 86 22:54:05 EST Date: Tue, 4 Feb 86 22:54:05 EST From: sean@cadre.dsl.pittsburgh.edu (Sean McLinden) Message-Id: <8602050354.AA29262@PITTSBURGH.EDU> To: Fahlman@c.cs.cmu.edu Subject: Re: loop macro Cc: common-lisp@su-ai.arpa Scott: The DePaul Common Lisp LOOP macro does not depend upon FLAVORS. It did depend upon some knowledge of the Spice compiler but those were trivial to replace. I have gotten it to compile and run on two other versions of Common Lisp (non-Perq), so far, without trouble. Sean  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 4 Feb 86 21:38:31 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 4 Feb 86 18:26:16 PST Received: ID ; Tue 4 Feb 86 21:22:08-EST Date: Tue, 4 Feb 1986 21:21 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: "Daniel L. Weinreb" Cc: common-lisp@SU-AI.ARPA Subject: loop macro In-reply-to: Msg of 4 Feb 1986 18:56-EST from Daniel L. Weinreb One last point -- upon looking more closely at the examples Gregor sent, I notice that there is still a lot of infix stuff, which is unfortunate. In a Lisp system I'd much rather see (iterate (members-of x list) ...) than (iterate (x in list) ...) But that much is negotiable. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 4 Feb 86 21:24:47 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 4 Feb 86 18:10:44 PST Received: ID ; Tue 4 Feb 86 21:08:58-EST Date: Tue, 4 Feb 1986 21:08 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: "Daniel L. Weinreb" Cc: common-lisp@SU-AI.ARPA Subject: loop macro In-reply-to: Msg of 4 Feb 1986 18:56-EST from Daniel L. Weinreb Dan, First, you are right that my strong negative feelings were inspired by the current LOOP stuff -- a fair amount of experience trying to read loopy code and a very modest experience trying to write things in it. I believe that the problem is a direct consequence of the cute English-like syntax, but I'll try to keep an open mind in considering anything new that you folks come up with. It's not inconceivable that the real problems lie elsewhere. Of course, I can't speak for the millions of other loop-haters in the world. Second, I think that you misunderstood what I was suggesting as a remedy for LOOP. While I don't remember Bawden's old DOO thing, I was not suggesting that we flush all keywords and let levels of parentheses do all the work. The existing DO construct goes just about as far in this direction as it is wise to go, plus a bit. What I was advocating is something very much like the sort of thing that Alan Snyder and Gregor have just suggested, or like the package from PSL that was discussed on the iteration list some time ago. (I'm not sure whether the H-P proposal is the same as this.) Just as I have no problem with the use of function names like When, I have no problem with an iteration construct that uses mnemonic English-like names or keywords to INTRODUCE various clauses. My problem is with the English-like syntax, not with English-like vocabulary. If a clause like Collect or Sum has arguments or some sort of body, Lisp provides a perfectly good method for delimiting such a clause: parentheses. To use little "glue" words like "from" and "until" to stick such clauses together in this one part of the language and nowhere else is what I object to. And since the syntax of this English-like stuff is much more restricted than real English is, I find it very hard to remember which little words are going to stick which arguments to which operators. Yes, sometimes you can "read" loopy code aloud and it says just what it is going to do, but other times the best code is not the code that proudces the best approximation to grammatical English when read as a sentence. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 4 Feb 86 21:03:38 EST Received: from BRILLIG.UMD.EDU by SU-AI.ARPA with TCP; 4 Feb 86 17:52:03 PST Received: by brillig.umd.edu (5.9/4.7) id AA10539; Tue, 4 Feb 86 20:52:42 EST Message-Id: <8602050152.AA10539@brillig.umd.edu> To: common-lisp@SU-AI.ARPA Subject: Re: loop macro In-Reply-To: Your message of 4 Feb 86 15:50 PST. <860204-155111-2418@Xerox> Date: 04 Feb 86 20:52:41 EST (Tue) From: Liz Allen From: Gregor.pa@Xerox.COM I think I prefer "lispy" iteration macros. Here is an example of what I mean by a lispy iteration macro: ;; Return a list of the items in list-of-items ;; which pass the test TEST. (iterate ((item in list-of-items)) (when (test item) (collect item))) I once worked with a looping macro that looked like that -- with lots of nested parens. The main problem with it is that, when you look at the code, you tend to think that the (when ...) up there is a function call rather than part of some loop. It's too context dependent and rather confusing. From: "Scott E. Fahlman" 3. The functionality of LOOP is fine, modulo some small details, but the cute English-like syntax should be replaced with something more Lispy. Specifically, parentheses should be used to group the arguments controlling the various major options rather than doing this with connecting words like "by", "until", and "whereas". People in this group feel pretty strongly that the little pseudo-sentences people end up writing in the LOOP syntax are extremely confusing and promote bad style. Things that aren't English shouldn't look like English. The mention of connecting words kind of puzzles me (and at the same time helps me to understand the Lisp Machine loop macro). Our for macro doesn't seem to need them (though it does use "by" and "until"). To explain how this works, let me give for's basic syntax: (for [ let * ]* ; is or ( ) [ initially * ]* [ * ]* ; in, on, from, bind, being, etc [ eachtime * ]* [ * ]* ; while * or until * [ * ]* ; when * or unless * [ * ] ; is do, collect, etc [ finally * ] ) (I'll admit that not all of those *'s up there make a lot of sense -- to understand them, imagine implicit progn's around them all.) Each of those clauses stand alone -- there's no need to connect them. In fact, you tend to think of the syntax as being "(for *)". The from keyword does take by and to, but those are part of the from clause. If the for was extended to handle more than one body, then some of this neatness might disappear since the when's and unless's would be associated with the next body clause -- you'd want to indent the body clause more than the other clauses and then the nice equality of clauses would not be as strong... But, even then, you wouldn't need to add connectors. I'm not trying to say that Common Lisp should necessarily adopt the Maryland for as its looping construct. I just trying to say that there ought to be some way to get rid of the concept of connecting words without having to put parens around all the clauses... Can the syntax for the Lisp Machine Loop be simplified along these lines without losing big? -Liz  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 4 Feb 86 20:31:58 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 4 Feb 86 17:21:55 PST Received: ID ; Tue 4 Feb 86 20:23:33-EST Date: Tue, 4 Feb 1986 20:23 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: sean@cadre.dsl.pittsburgh.edu (Sean McLinden) Cc: common-lisp@SU-AI.ARPA Subject: loop macro In-reply-to: Msg of 4 Feb 1986 17:33-EST from sean at cadre.dsl.pittsburgh.edu (Sean McLinden) Sean, Unless I am confusing it with somehting else, the DePaul version of LOOP depended on flavors and therefore was non-portable. (CMU's portable flavor package never worked quite right, as you know best of all, and with the departure of Steve handerson is no longer being worked on or maintained, so nobody should depend on this.) Have you removed these dependencies? I believe that they were mostly gratuitous. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 4 Feb 86 19:59:34 EST Received: from HPLABS.ARPA by SU-AI.ARPA with TCP; 4 Feb 86 16:51:35 PST Received: from hplsny by hplabs.ARPA ; Tue, 4 Feb 86 16:50:26 pst Received: by hplsny ; Tue, 4 Feb 86 16:48:22 pst From: Alan Snyder Message-Id: <8602050048.AA01118@hplsny> Date: Tuesday, February 4, 1986 16:48:14 Subject: Re: loop macro To: DLW@SCRC-QUABBIN.ARPA Cc: common-lisp@su-ai.ARPA In-Reply-To: Your message of 4-Feb-86 18:56:00 X-Sent-By-Nmail-Version: 04-Nov-84 17:14:46 It sounds like you're in group 3 because you've seen a keyword-oriented proposal that you don't like, but you have not yet seen any non-keyword-oriented proposal at all. I hope we'll all get an opportunity to compare and contrast a better keyword-oriented proposal with someone's best shot at a non-keyword-oriented proposal, before we come to a consensus on what Common Lisp should do. We have a loop macro proposal that is parenthesized. (It would be misleading to call it non-keyword-oriented, because it uses keyword symbols to name the parenthesized clauses!) It doesn't do everything the Zetalisp loop macro does, nor does it incorporate all of the speculated improvements, but it's a start. The description is a 23 page printed document. If you'd like a copy, send your USmail address to: mingus@hplabs.arpa and ask for STL-85-04 "A Loop Macro for Common Lisp" We also have an implementation in Common Lisp that we could probably make available if there is interest. -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 4 Feb 86 19:06:22 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 4 Feb 86 15:56:42 PST Received: from CHICOPEE.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 409938; Tue 4-Feb-86 18:56:24-EST Date: Tue, 4 Feb 86 18:56 EST From: Daniel L. Weinreb Subject: loop macro To: Fahlman@C.CS.CMU.EDU cc: common-lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860204185625.4.DLW@CHICOPEE.SCRC.Symbolics.COM> Date: Tue, 4 Feb 1986 17:10 EST From: "Scott E. Fahlman" 3. The functionality of LOOP is fine, modulo some small details, but the cute English-like syntax should be replaced with something more Lispy. Specifically, parentheses should be used to group the arguments controlling the various major options rather than doing this with connecting words like "by", "until", and "whereas". This is what we used to call the "new new style DO". Back in the late 70's, Alan Bawden experimented extensively with this idea, and had a macro called DOO that was around for a while. Our conclusion was that in order to get a reasonable level of functionality, you needed such a maze of parentheses that the construct was extremely confusing and promoted bad style. Possibly the reason that your suggestion "went nowhere" is that people who tried to follow it up ran into the same problems. People in this group feel pretty strongly that the little pseudo-sentences people end up writing in the LOOP syntax are extremely confusing and promote bad style. Things that aren't English shouldn't look like English. Perhaps we should not be using WHEN as the name of a special form, on the grounds that it looks like English but isn't English, and we should stick with names like CDAR and MAKUNBOUND and HAIPART. I agree that some uses of LOOP are confusing. But I disagree with the analysis that any construct with embedded keywords must lead to confusing programs. The problems that you see with the use of LOOP are not inherent in the basic idea of LOOP, but rather a consequence of some of the details of the present LOOP design. We believe that we can come up with a keyword-oriented proposal that has the functionality that is needed and is clear, but solves a lot of the problems of the existing LOOP. It sounds like you're in group 3 because you've seen a keyword-oriented proposal that you don't like, but you have not yet seen any non-keyword-oriented proposal at all. I hope we'll all get an opportunity to compare and contrast a better keyword-oriented proposal with someone's best shot at a non-keyword-oriented proposal, before we come to a consensus on what Common Lisp should do. We've been talking about a revised LOOP proposal for some time now. I think the main reason we haven't made progress on it is the same "exhaustion" that we discussed at the recent meeting. If everyone's recovered sufficiently from the previous go-arounds, maybe it's time to get moving on this again.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 4 Feb 86 18:59:59 EST Received: from XEROX.COM by SU-AI.ARPA with TCP; 4 Feb 86 15:51:59 PST Received: from Cabernet.ms by ArpaGateway.ms ; 04 FEB 86 15:51:11 PST Date: 4 Feb 86 15:50 PST From: Gregor.pa@Xerox.COM Subject: Re: loop macro In-reply-to: Bernard S. Greenberg 's message of Tue, 4 Feb 86 16:38 EST To: BSG@SCRC-STONY-BROOK.ARPA cc: Fahlman@C.CS.CMU.EDU, common-lisp@SU-AI.ARPA Message-ID: <860204-155111-2418@Xerox> I think I prefer "lispy" iteration macros. Here is an example of what I mean by a lispy iteration macro: ;; Return a list of the items in list-of-items ;; which pass the test TEST. (iterate ((item in list-of-items)) (when (test item) (collect item))) I like this better because: -the bindings looks more like standard lisp bindings (let do etc). -I can use COLLECT, SUM etc. at any level in the body. -uses of collect sum etc. look like lisp function calls. -which makes it natural to use the existing when, unless etc. NOTE: I am not proposing this version of ITERATE as something we should consider in and of itself, I am just using it to show some things I like about it. Here are some more examples using it: ;; Basically FIRSTN ;; Get the first 10 items in a list (iterate ((item in list) (i from 0 below 10)) (collect y)) ;; Sort of GETL. ;; (iterate ((prop on plist by cddr)) (when (memq (car prop) properties-to-collect) (collect prop))) ;; Return a left hand to match left-hand-to-match ;; or error if couldn't find one. (iterate ((left in left-hands) (right in right-hands)) (when (eq left left-to-match) (return right)) (finally (error "Could find a right hand.")))  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 4 Feb 86 17:57:34 EST Received: from CADRE.DSL.PITTSBURGH.EDU by SU-AI.ARPA with TCP; 4 Feb 86 14:33:28 PST Received: by PITTSBURGH.EDU (5.31/5.14) id AA27950; Tue, 4 Feb 86 17:33:15 EST Date: Tue, 4 Feb 86 17:33:15 EST From: sean@cadre.dsl.pittsburgh.edu (Sean McLinden) Message-Id: <8602042233.AA27950@PITTSBURGH.EDU> To: Fahlman@c.cs.cmu.edu, liz@brillig.umd.edu Subject: Re: loop macro Cc: common-lisp@su-ai.arpa There was a version of the ZetaLisp LOOP macro which was ported to Perq (Spice) Common Lisp by David Miller at DePaul University. It supported everything in ZetaLisp except the NAMED keyword and user defined iteration paths. We have modified that version to accept either the Zetalisp or the Common Lisp LOOP syntax and have had no problem in dealing with Zetalisp code. I would be glad to distribute it to interested sites, assuming that it was obtained from the Zetalisp sources without restriction (I am not aware of any), and David Miller has no objection. Sean McLinden Decision Systems Laboratory University of Pittsburgh  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 4 Feb 86 17:24:23 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 4 Feb 86 14:15:47 PST Received: ID ; Tue 4 Feb 86 17:10:17-EST Date: Tue, 4 Feb 1986 17:10 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: "Bernard S. Greenberg" Cc: common-lisp@SU-AI.ARPA Subject: loop macro In-reply-to: Msg of 4 Feb 1986 16:38-EST from Bernard S. Greenberg I don't understand the general topic of discussion here. This Maryland FOR macro hasn't a dime's worth of difference from Zetalisp LOOP. The differences are trifling. I thought the issue with LOOP vs. CL was not one of trivial differences between a large number of Interlisp-like loop macros, but rather one of whether we wanted such a thing, extremely non-lispy, however useful, to some tastes, in the language. There are a couple of issues here. One is whether we want something like the Loop macro added to the Common Lisp standard; the other is whether anyone has a portable LOOP package that can be used as an add-on. On the former issue, there seem to be three schools of thought: 1. We don't need such a thing. DO and related constructs do the job just fine without adding a lot of extra hair. 2. The Lisp Machine's LOOP facility is essential for high-efficiency programming and should be added to Common Lisp. (Discussions of actually doing this usually get derailed by someone saying "..but there are some problems with the current LOOP system, so everyone should wait until we've figured out what the ultimate best thing is.") 3. The functionality of LOOP is fine, modulo some small details, but the cute English-like syntax should be replaced with something more Lispy. Specifically, parentheses should be used to group the arguments controlling the various major options rather than doing this with connecting words like "by", "until", and "whereas". People in this group feel pretty strongly that the little pseudo-sentences people end up writing in the LOOP syntax are extremely confusing and promote bad style. Things that aren't English shouldn't look like English. I used to be in group 1, but have now moved to group 3. I don't think there are very many people left who actually favor option 1. A year or so ago I proposed that we try to compromise with a scheme that basically implements proposal 3, but with English-like LOOP syntax available as an alternative syntax (a simple one-to-one mapping) for people who like that kind of stuff. This suggestion went nowhere, and I haven't seen any activity on the iteration mailing list since then. Deadlock, and position 1 wins by default. So much for standardizing on one of these things. The more recent discussion was, I think, sparked by somebody's desire to move some Loop-infested code from Zetalisp to a vanilla Common Lisp. While I don't want to see us standardize on the Loop syntax, I must admit that having a portable, compatible Loop package would make a lot of people's lives easier as they move code from one system to another. So the question of how close the Maryland code was to the current Zetalisp stuff was of some immediate practical interest. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 4 Feb 86 16:42:58 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 4 Feb 86 13:32:01 PST Received: from CONCORD.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 409709; Tue 4-Feb-86 16:30:31-EST Date: Tue, 4 Feb 86 16:38 EST From: Bernard S. Greenberg Subject: Re: loop macro To: Fahlman@C.CS.CMU.EDU cc: common-lisp@SU-AI.ARPA In-Reply-To: <8602042119.AA07277@brillig.umd.edu> Message-ID: <860204163848.9.BSG@CONCORD.SCRC.Symbolics.COM> Date: 04 Feb 86 16:19:16 EST (Tue) From: Liz Allen From: "Scott E. Fahlman" Your For macro sounds interesting in its own right, but I get the impression that it is enough different from the Lisp Machine version that it would not be of much help in porting Loop-infested Lisp Machine code into Common Lisp. Is that right? Do you have any experience with such ports? Well, I've only just started using the Lisp Machine Loop macro recently and its syntax isn't quite what I tend to expect, so I'm not sure how much I can say. There was someone who ported YAPS to a Lisp Machine a while back who said that it was easy to translate all the for's into loop's so it might not be *too* bad to go the other way. Probably the biggest thing missing from our for macro is the ability to accumulate multiple values in a single for (but then, Franz Lisp 38.91 didn't have the concept of returning multiple values from a function...). It would probably not be too hard to add that feature -- the $$val stuff would have to be revised, but in principle, there is no reason we couldn't extend it (except I'm trying to work on a PhD thesis!). -Liz I don't understand the general topic of discussion here. This Maryland FOR macro hasn't a dime's worth of difference from Zetalisp LOOP. The differences are trifling. I thought the issue with LOOP vs. CL was not one of trivial differences between a large number of Interlisp-like loop macros, but rather one of whether we wanted such a thing, extremely non-lispy, however useful, to some tastes, in the language.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 4 Feb 86 16:27:35 EST Received: from BRILLIG.UMD.EDU by SU-AI.ARPA with TCP; 4 Feb 86 13:18:49 PST Received: by brillig.umd.edu (5.9/4.7) id AA07277; Tue, 4 Feb 86 16:19:17 EST Message-Id: <8602042119.AA07277@brillig.umd.edu> To: "Scott E. Fahlman" Cc: common-lisp@SU-AI.ARPA Subject: Re: loop macro In-Reply-To: Your message of Tue, 4 Feb 1986 14:04 EST. Date: 04 Feb 86 16:19:16 EST (Tue) From: Liz Allen From: "Scott E. Fahlman" Your For macro sounds interesting in its own right, but I get the impression that it is enough different from the Lisp Machine version that it would not be of much help in porting Loop-infested Lisp Machine code into Common Lisp. Is that right? Do you have any experience with such ports? Well, I've only just started using the Lisp Machine Loop macro recently and its syntax isn't quite what I tend to expect, so I'm not sure how much I can say. There was someone who ported YAPS to a Lisp Machine a while back who said that it was easy to translate all the for's into loop's so it might not be *too* bad to go the other way. Probably the biggest thing missing from our for macro is the ability to accumulate multiple values in a single for (but then, Franz Lisp 38.91 didn't have the concept of returning multiple values from a function...). It would probably not be too hard to add that feature -- the $$val stuff would have to be revised, but in principle, there is no reason we couldn't extend it (except I'm trying to work on a PhD thesis!). -Liz  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 4 Feb 86 14:28:23 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 4 Feb 86 11:03:20 PST Received: ID ; Tue 4 Feb 86 14:04:27-EST Date: Tue, 4 Feb 1986 14:04 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Liz Allen Cc: common-lisp@SU-AI.ARPA Subject: loop macro In-reply-to: Msg of 4 Feb 1986 12:16-EST from Liz Allen Liz, Your For macro sounds interesting in its own right, but I get the impression that it is enough different from the Lisp Machine version that it would not be of much help in porting Loop-infested Lisp Machine code into Common Lisp. Is that right? Do you have any experience with such ports? -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 4 Feb 86 14:12:50 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 4 Feb 86 11:03:20 PST Received: ID ; Tue 4 Feb 86 14:04:27-EST Date: Tue, 4 Feb 1986 14:04 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Liz Allen Cc: common-lisp@SU-AI.ARPA Subject: loop macro In-reply-to: Msg of 4 Feb 1986 12:16-EST from Liz Allen Liz, Your For macro sounds interesting in its own right, but I get the impression that it is enough different from the Lisp Machine version that it would not be of much help in porting Loop-infested Lisp Machine code into Common Lisp. Is that right? Do you have any experience with such ports? -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 4 Feb 86 13:45:39 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 4 Feb 86 10:36:38 PST Received: ID ; Tue 4 Feb 86 13:36:59-EST Date: Tue, 4 Feb 1986 13:36 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Kent M Pitman Cc: common-lisp@SU-AI.ARPA Subject: eval'd macros (the other point of view) In-reply-to: Msg of 4 Feb 1986 13:24-EST from Kent M Pitman Having macros expanded when the defun is first seen offers the nice feature that you can't easily break functions you've already written as you enter a debugging phase. You also can't FIX functions you've already written by changing the macros they call. You now have to go back and find every last function that calls FOO, and re-expand it to do the right thing, assuming that you've got the source handy. Things that I'm sure are right and that I don't want to break are usually already compiled. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 4 Feb 86 13:40:57 EST Received: from XEROX.COM by SU-AI.ARPA with TCP; 4 Feb 86 10:28:54 PST Received: from Cabernet.ms by ArpaGateway.ms ; 04 FEB 86 09:54:35 PST Date: 4 Feb 86 09:54 PST From: Gregor.pa@Xerox.COM Subject: Re: Defstruct Extensions In-reply-to: Kevin Gallagher 's message of Mon, 3 Feb 86 13:15 EST To: gallagher%umass-cs.CSNet@CSNet-Relay.ARPA cc: Common-Lisp@su-ai.ARPA Message-ID: <860204-095435-1945@Xerox> Several of these functions exist in CommonLoops. In addition, the metaclass mechanism makes it easy to make Portable CommonLoops (PCL) deal with a particular CommonLisp's defstruct types as "first class" classes. This means that if you have a version of PCL which has been "taught" about the particular Common Lisp's local type system you can use the PCL functions to get the information you need regardless of whether you are asking about a type defined by defstruct or a CommonLoops class. In CommonLoops: GET-STRUCTURE-SLOT is called GET-SLOT STRUCTURE-SLOT-NAMES is called ALL-SLOTS MAKE-STRUCTURE is called MAKE STRUCTURE-OPTION STRUCTURE-SLOT-OPTION don't exist as named functions, but it might be a good idea to add them. Of course, the only interesting part is making them setfable.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 4 Feb 86 13:38:25 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 4 Feb 86 10:25:02 PST Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 409419; Tue 4-Feb-86 13:24:52-EST Date: Tue, 4 Feb 86 13:24 EST From: Kent M Pitman Subject: eval'd macros (the other point of view) To: Fahlman@C.CS.CMU.EDU, WEEKS%HP-THOR@HPLABS.ARPA cc: common-lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860204132441.1.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM> Date: Mon, 3 Feb 1986 20:36 EST From: "Scott E. Fahlman" (defun fn () (mac)) ;==> FN (defmacro mac () `'foo) ;==> MAC (fn) ;==> ***Error*** I wish we'd required that this signal an error. I like the behavior shown above. You don't say whether the problem you described occurs in the interpreter or the compiler. Your example certainly is not required to work when compiled because the macro definition follows the use. In my opinion, this should work without an error in the interpreter. Hacking in the interpreter would be fairly awkward if it didn't. However, the fourth paragraph on page 143 seems to give implementors permission to do compiler-like macro expansion when a defun is first seen. I wouldn't want to use such an implementation, but it probably is legal as the manual currently stands. Well, people frequently don't like to use something that behaves differently than what they're used to, but that doesn't make the `new' behavior wrong. In the interest of fairness, let me outline the alternate point of view -- the view to which I subscribe... Having macros expanded when the defun is first seen offers the nice feature that you can't easily break functions you've already written as you enter a debugging phase. For example, consider how redefining LET would break the world in an environment where LET wasn't resolved at definition time. Compare that to a world where you had to do things in order. You're always trading one thing for another. Also, in your preferred interpreter, allowing displacing macros to expand lazily will mean that code which is fully loaded but only partially exercised may behave inconsistently after redefinition of a macro, since only the non-displaced calls will see the update. In the case of an early-binding interpreter, the effect of the redefinition is trivially predictable. Personally, I would prefer not to work in an interpreter that did lazy expansion. The only weakness I see in the spec is that it doesn't guarantee early expansion.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 4 Feb 86 13:13:39 EST Received: from CS.UCL.AC.UK by SU-AI.ARPA with TCP; 4 Feb 86 10:04:13 PST Received: from aiva.edinburgh.ac.uk by 44d.Cs.Ucl.AC.UK via Janet with NIFTP id a001025; 4 Feb 86 17:14 GMT From: Jeff Dalton Date: Tue, 4 Feb 86 17:21:42 GMT Message-Id: To: WEEKS <@hplabs.arpa:WEEKS@hp-thor>, common-lisp@su-ai.arpa Subject: Re: eval'd macros Date: Mon 3 Feb 86 16:24:29-PST From: WEEKS Subject: eval'd macros The following results occur on my workstation: (defun fn () (mac)) ;==> FN (defmacro mac () `'foo) ;==> MAC (fn) ;==> ***Error*** It seems clear from CLtL, pg.143, second paragraph that (fn) should have evaluated to FOO. [The reference to "local definitions" indicates that the reference to "eval" really refers to evaluation in general.] Is the above ***Error*** indeed wrong? Sounds like your workstation is wrong. I've also tried it in 3 different implementations of Common Lisp, and they all say FOO.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 4 Feb 86 13:00:19 EST Received: from HPLABS.ARPA by SU-AI.ARPA with TCP; 4 Feb 86 09:50:21 PST Received: from hplabsc by hplabs.ARPA ; Tue, 4 Feb 86 09:49:10 pst Received: by hplabsc (4.16/4.30) ; id AA05360; Tue, 4 Feb 86 09:52:19 pst Date: Tue, 4 Feb 86 09:52:19 pst From: Jim Kempf Message-Id: <8602041752.AA05360@hplabsc> To: Common-Lisp@su-ai.ARPA, gallagher%umass-cs.csnet@CSNET-RELAY.ARPA Subject: Re: Defstruct Extensions >I think it is a deficiency in the language that you can't access a slot in a >structure via the slot name. Every implementation keeps this information >around and anyone who is writing a layered system eventually needs that >ability and writes a non-portable slot getter. Structure definition >information should be available also. I would agree with this, except I would go one step further. Currently, the default underlying data structure for defstruct's is unspecified. An implementation can choose to use vectors, lists or any other of the existing data structures. An enhancement to portablility would be to specify the underlying data structure, and provide portable accessor functions for getting it. An obvious choice is a vector-like data structure, which is, nevertheless, distinct from a vector. This would also be useful to implementors of object-oriented CL extensions. > > GET-STRUCTURE-SLOT structure slot [Function] > > Returns the value of the slot in STRUCTURE specified by SLOT. SETF may be > used with GET-STRUCTURE-SLOT to modify a slot in a structure. > Jim Kempf kempf@hplabs If the default data structure is a vector, then this function should also take an integer index. Compilers would be able to utilize this information to optimize structure access for variables declared as structures.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 4 Feb 86 12:24:20 EST Received: from BRILLIG.UMD.EDU by SU-AI.ARPA with TCP; 4 Feb 86 09:15:52 PST Received: by brillig.umd.edu (5.9/4.7) id AA04805; Tue, 4 Feb 86 12:16:40 EST Message-Id: <8602041716.AA04805@brillig.umd.edu> To: common-lisp@su-ai.ARPA, gls@think-aquinas.ARPA, vrotney@isi-vax.ARPA Cc: Bruce Israel Subject: loop macro In-Reply-To: Your message of Thu, 23 Jan 86 17:45:08 EST. <8601232245.AA22847@brillig.umd.edu> Date: 04 Feb 86 12:16:39 EST (Tue) From: Liz Allen This is in response to a request for a loop macro that will run in Common Lisp. At Maryland, we've been using a for macro that provides a nice looping macro and depends on almost nothing -- cond, setq, progn and do is about all. It is a version of the InterLisp for macro with a number of new keywords. If anyone would like the code for it, let me know. There are a some examples of using it and descriptions of some of the other keywords below so you can get some feeling for it. It expands into a call to do with, possibly, a let around it so it runs fairly efficiently. (for x in '(a b c) do (print x)) (for x in '(a b c) y in '(d e f) collect (cons x y)) ==> ((a . d) (b . e) (c . f)) (for x in '(a b c) join (list x 3)) ==> (a 3 b 3 c 3) (for x in '(a b 3 4 c 5) when (numberp x) sum (print x) ; all clauses may contain multiple expressions x) prints: 3 4 5 ==> 12 (for n from 0 to 13 when (> n 6) quit n) ==> 7 To bind variables, you can use: "on" (same syntax as "in"), destructuring with "in" (eg "(for (key . value) in assoc-list ...)"), "let" to bind variables you want to see in later binding clauses, and "bind" and "being" for other iteration variables. Various conditions you can use are: "when", "unless", "while" and "until". The body keywords are: "do", "collect", "join", "sum", "count", "alwyas", "never", "thereis", "last", "tcollect", "tjoin" (like collect and join except using tconc cells) and "quit" (like return). There are also "initially" and "finally" clauses. All the clauses that expect lisp bodies may have multiple clauses and an implicit progn is put around them. The value of the for is kept in the local variable $$val -- that's especially useful in the "finally" clause. Enjoy! -Liz  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 4 Feb 86 10:47:31 EST Received: from CSNET-RELAY.ARPA by SU-AI.ARPA with TCP; 4 Feb 86 07:39:46 PST Received: from umass-cs by csnet-relay.csnet id aw12431; 4 Feb 86 1:18 EST Date: Mon, 3 Feb 86 13:15 EST From: Kevin Gallagher To: Common-Lisp@su-ai.ARPA Subject: Defstruct Extensions I think it is a deficiency in the language that you can't access a slot in a structure via the slot name. Every implementation keeps this information around and anyone who is writing a layered system eventually needs that ability and writes a non-portable slot getter. Structure definition information should be available also. I propose the addition of several functions to the language: GET-STRUCTURE-SLOT structure slot [Function] Returns the value of the slot in STRUCTURE specified by SLOT. SETF may be used with GET-STRUCTURE-SLOT to modify a slot in a structure. STRUCTURE-SLOT-NAMES name [Function] NAME must be a type defined by DEFSTRUCT. This function returns a list of slot names for structures of that type. Also nice but not quite so important would be: MAKE-STRUCTURE name slot-keyword-1 form1 ... [Function] Creates an instance of a structure. NAME is the type of structure to create. The rest of the arguments are the same as for the default constructor function. If a slot is not initialised by a slot-keyword, then the slot will be initialized with the default init form specified in the defstruct. STRUCTURE-OPTION name option [Function] NAME must be a type defined by defstruct. OPTION must be a defstruct option (e.g., :conc-name). This function returns the argument that was given to that option if an argument was given in the call to defstruct. Otherwise it returns the default value of that option. For example, after the defstruct on page 312, (structure-option 'astronaut :conc-name) ==> astro- STRUCTURE-SLOT-OPTION name slot option [Function] (This function is included mostly for completeness.) NAME must be a type defined by defstruct. SLOT is the name of a slot in that defstruct. OPTION must be a defstruct slot option (:type or :read-only). This function returns the argument that was given to that option if an argument was given in the call to defstruct. Otherwise it returns the default value of that option. Kevin Gallagher  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 4 Feb 86 10:40:58 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 4 Feb 86 07:34:06 PST Received: from NEPONSET.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 409168; Tue 4-Feb-86 10:27:29-EST Date: Tue, 4 Feb 86 10:33 EST From: David C. Plummer Subject: eval'd macros To: Scott E. Fahlman , WEEKS%HP-THOR@HPLABS.ARPA cc: common-lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860204103305.6.DCP@NEPONSET.SCRC.Symbolics.COM> Date: Mon, 3 Feb 1986 20:36 EST From: "Scott E. Fahlman" (defun fn () (mac)) ;==> FN (defmacro mac () `'foo) ;==> MAC (fn) ;==> ***Error*** You don't say whether the problem you described occurs in the interpreter or the compiler. Your example certainly is not required to work when compiled because the macro definition follows the use. In my opinion, this should work without an error in the interpreter. Hacking in the interpreter would be fairly awkward if it didn't. However, the fourth paragraph on page 143 seems to give implementors permission to do compiler-like macro expansion when a defun is first seen. I wouldn't want to use such an implementation, but it probably is legal as the manual currently stands. It should probably still work if compile-like macro expansion is done at definition time. If the system goes further and actually DOES compile the defun, then I would consider it a user-interface bug that the compiler doesn't tell the user that it couldn't find a function call MAC. (defun fn () (mac)) FN (compile 'fn) The following functions were referenced but don't seem defined: MAC referenced by FN FN  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 3 Feb 86 22:20:48 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 3 Feb 86 19:05:09 PST Received: ID ; Mon 3 Feb 86 22:07:00-EST Date: Mon, 3 Feb 1986 22:06 EST Message-ID: From: Rob MacLachlan To: Rob Vollum Cc: common-lisp@SU-AI.ARPA, OLDMAN@USC-ISI.ARPA Subject: Defmacro inside of a let In-reply-to: Msg of 3 Feb 1986 18:11-EST from Rob Vollum Date: Monday, 3 February 1986 18:11-EST From: Rob Vollum Re: Defmacro inside of a let I may be missing something here, but it seems to me that the compiler wants to process ALL toplevel forms at compile time. Of course the compiler would have to interpret the surrounding code to calculate the lexical environment. I don't see why this is basically impossible. This is exactly what was being discussed in the recent "Defun inside LET" controversy. Well, the compiler does need to Process all top-level forms, but that certainly doesn't normally entail EVAL'ing them. The compiler cannot randomly eval any code just because it feels like it. Normally the compiler only evals forms if an explicit EVAL-WHEN (COMPILE) is present. Are you suggesting that the compiler should say "Oh, there's a DEFMACRO buried in here somewhere, I'd better eval this thing." If so, that seems linguistically quite unclean to me, since the presence of a defmacro would have a nonlocal effect. This isn't the same as DEFUN inside of LET, because DEFUN has no effect at compile time. The actual evaluation of the defun is put off until load time, when it is legal to evaluate the entire form. Rob  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 3 Feb 86 20:49:30 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 3 Feb 86 17:38:26 PST Received: ID ; Mon 3 Feb 86 20:36:41-EST Date: Mon, 3 Feb 1986 20:36 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: WEEKS%HP-THOR@HPLABS.ARPA Cc: common-lisp@SU-AI.ARPA Subject: eval'd macros (defun fn () (mac)) ;==> FN (defmacro mac () `'foo) ;==> MAC (fn) ;==> ***Error*** You don't say whether the problem you described occurs in the interpreter or the compiler. Your example certainly is not required to work when compiled because the macro definition follows the use. In my opinion, this should work without an error in the interpreter. Hacking in the interpreter would be fairly awkward if it didn't. However, the fourth paragraph on page 143 seems to give implementors permission to do compiler-like macro expansion when a defun is first seen. I wouldn't want to use such an implementation, but it probably is legal as the manual currently stands. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 3 Feb 86 20:19:10 EST Received: from HPLABS.ARPA by SU-AI.ARPA with TCP; 3 Feb 86 17:08:28 PST Received: from HP-THOR by hplabs.ARPA ; Mon, 3 Feb 86 16:36:02 pst Date: Mon 3 Feb 86 16:24:29-PST From: WEEKS%HP-THOR@HPLABS Subject: eval'd macros To: common-lisp@su-ai.ARPA The following results occur on my workstation: (defun fn () (mac)) ;==> FN (defmacro mac () `'foo) ;==> MAC (fn) ;==> ***Error*** It seems clear from CLtL, pg.143, second paragraph that (fn) should have evaluated to FOO. [The reference to "local definitions" indicates that the reference to "eval" really refers to evaluation in general.] Is the above ***Error*** indeed wrong? -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 3 Feb 86 19:56:18 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 3 Feb 86 16:46:33 PST Received: from SCRC-PEGASUS.ARPA by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 408712; Mon 3-Feb-86 18:15:05-EST Received: by scrc-pegasus id AA02080; Mon, 3 Feb 86 18:11:08 est Date: Mon, 3 Feb 86 18:11:08 est From: Rob Vollum To: OLDMAN@USC-ISI.ARPA, RAM@C.CS.CMU.EDU Subject: Re: Defmacro inside of a let Cc: common-lisp@SU-AI.ARPA Date: Sat, 1 Feb 1986 10:13 EST Message-Id: From: Rob MacLachlan To: OLDMAN@USC-ISI.ARPA Cc: common-lisp@SU-AI.ARPA Subject: Defmacro inside of a let That's because the compiler wants to be able to evaluate macros at compile time. It would be impossible to compute the lexical environment of a macro definition without actually interpreting the surrounding code. This is basically impossible, and is almost certainly not what you want. It is more obvious in the case of MACROLET, which is usually embedded in random code somewhere. This is explained to some degree on page 114. I may be missing something here, but it seems to me that the compiler wants to process ALL toplevel forms at compile time. Of course the compiler would have to interpret the surrounding code to calculate the lexical environment. I don't see why this is basically impossible. This is exactly what was being discussed in the recent "Defun inside LET" controversy. As for not being what the programmer wanted, what about the person that wants to (for whatever reason) write the following: (let ((counter 0)) (defmacro conditional-expand (...args...) (incf counter) (if (< counter *some-level*) `(an expansion) `(another expansion)))) I'm not defending this code, or even saying that this is the only way to do such a thing, but what's wrong with it linguistically? [...] Rob Rob  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 3 Feb 86 14:11:19 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 3 Feb 86 11:00:18 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 408282; Mon 3-Feb-86 13:54:37-EST Date: Mon, 3 Feb 86 13:55 EST From: David A. Moon Subject: Re: Re: Defun inside Let To: common-lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860203135533.3.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Sun, 2 Feb 86 18:34:00 GMT From: Jeff Dalton I have another question regarding functions, but this is only of the "Does CLtL actually say everything it should?" variety. If I do (flet ((b () 1)) (apply #'b ())) I get 1, as expected, but if I use 'B or (SYMBOL-FUNCTION 'B) instead of #'b I get an error telling me that B is undefined. It is clear that I should get this error [see pp 90 (SYMBOL-FUNCTION) and 107 (APPLY applied to a symbol)]. The description of FUNCTION (p 87) also indicates that it should work in this case ("fn is interpreted as if it had appeared..."). But then, In particular, if fn is a symbol, the functional definition associated with that symbol is returned; see SYMBOL-FUNCTION. I believe this to be an editing error. This text is left over from an earlier draft version of the manual, from before the day when full lexical scoping was adopted.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 3 Feb 86 14:08:41 EST Received: from SU-SCORE.ARPA by SU-AI.ARPA with TCP; 3 Feb 86 10:58:59 PST Received: from IMSSS by Score with Pup; Mon 3 Feb 86 10:39:00-PST Date: 3 Feb 1986 1043-PST From: Rem@IMSSS Subject: Jeff Dalton's point To: COMMON-LISP%SU-AI@SCORE It seems (FUNCTION FOO) and (SYMBOL-FUNCTION 'FOO) are different; former refers to whatever FOO would mean in that context as a function, whereas latter refers explicitly to the global function cell of FOO. In the section describing FUNCTION, instead of saying "see SYMBOL-FUNCTION" it should say "cf SYMBOL-FUNCTION", so the casual reader will immediately know a difference instead of an equivalence in function is being pointed out. Anyone else agree? (reply to whole list or REM%IMSSS@SCORE) -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 3 Feb 86 13:01:45 EST Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 3 Feb 86 09:52:35 PST Received: from jehosephat by GODOT.THINK.COM via CHAOS; Mon, 3 Feb 86 12:52:52 est Date: Mon, 3 Feb 86 12:54 EST From: Guy Steele Subject: Defun inside Let To: DLW@SCRC-QUABBIN.ARPA, DCP@SCRC-QUABBIN.ARPA, common-lisp@SU-AI.ARPA Cc: gls@THINK-AQUINAS.ARPA In-Reply-To: <860131123758.6.DLW@CHICOPEE.SCRC.Symbolics.COM> Message-Id: <860203125415.1.GLS@THINK-JEHOSEPHAT.ARPA> Date: Fri, 31 Jan 86 12:37 EST From: Daniel L. Weinreb Date: Thu, 30 Jan 86 21:03 EST From: David C. Plummer That's right, I am bothered by programming environment. I agree it is probably not in CL's domain to address these issues, but it shouldn't prohibit it. Maybe another example? I believe that all the problems you've been talking about have to do with the poor interaction between lexical scoping and incremental programming. These poor interactions are discussed in the paper "The Art of the Interpreter: Parts Zero, One, and Two" by Guy Steele and Gerry Sussman. They are not incidental design flaws of Common Lisp; they are part of the deep nature of lexical scoping. I don't think they represent a "time bomb" in the language. They just show how lexical scoping, itself, has problems when it comes to program development, when used in this way. I don't think any language change is called for. If anybody writes a textbook or something that makes recommendations about programming practices and styles, though, they should take these problems into account. I hope Steele will correct me if I'm wrong. Sure, I'll correct you if you're wrong. (I know you'll return the favor.) --Guy  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 3 Feb 86 10:43:34 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 3 Feb 86 07:35:54 PST Received: ID ; Mon 3 Feb 86 10:37:14-EST Date: Mon, 3 Feb 1986 10:37 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Jeff Dalton Cc: common-lisp@SU-AI.ARPA Subject: Defun inside Let In-reply-to: Msg of 2 Feb 1986 13:34-EST from Jeff Dalton To avoid any confusion: I agree with this interpretation of Common Lisp. What I'm wondering (and I'm beginning to think I'll wish I'd never asked this) is why this interpretation was chosen over that in Scheme. Basically, we felt that everyone viewed Defun as the way you change global function definitions and that Labels was the way you set up lexically scoped ones. You need both things, and they already had perfectly good names. While we knew about Scheme and were happy to rip off some of its good ideas, the roots of the language were in the Maclisp tradition and that's the way we did things if there was no good reason to change. For quite a while, I didn't think carefully about this and assumed that FUNCTION was equivalent to SYMBOL-FUNCTION when applied to symbols. And it is equivalent except for symbols defined as local functions. Should the description of FUNCTION explicitly mention this exception, or is it clear enough as is? It wouldn't hurt to spell this out a bit more clearly. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 3 Feb 86 09:49:55 EST Received: from CS.UCL.AC.UK by SU-AI.ARPA with TCP; 3 Feb 86 06:38:33 PST Received: from aiva.edinburgh.ac.uk by 44d.Cs.Ucl.AC.UK via Janet with NIFTP id a002924; 2 Feb 86 18:54 GMT From: Jeff Dalton Date: Sun, 2 Feb 86 18:34:00 GMT Message-Id: To: common-lisp@su-ai.arpa Subject: Re: Re: Defun inside Let Date: Thu, 30 Jan 1986 14:29 EST From: "Scott E. Fahlman" Subject: Defun inside Let There can be no question at all on the point Jeff Dalton raises: when a Defun occurs inside a Let or anywhere else, it changes the GLOBAL function definition for the symbol in question. It is not a form of LABELS. To avoid any confusion: I agree with this interpretation of Common Lisp. What I'm wondering (and I'm beginning to think I'll wish I'd never asked this) is why this interpretation was chosen over that in Scheme. It's true that Common Lisp doesn't normally go through forms and give certain subforms unusual meanings, but is that all there is to it? I have another question regarding functions, but this is only of the "Does CLtL actually say everything it should?" variety. If I do (flet ((b () 1)) (apply #'b ())) I get 1, as expected, but if I use 'B or (SYMBOL-FUNCTION 'B) instead of #'b I get an error telling me that B is undefined. It is clear that I should get this error [see pp 90 (SYMBOL-FUNCTION) and 107 (APPLY applied to a symbol)]. The description of FUNCTION (p 87) also indicates that it should work in this case ("fn is interpreted as if it had appeared..."). But then, In particular, if fn is a symbol, the functional definition associated with that symbol is returned; see SYMBOL-FUNCTION. For quite a while, I didn't think carefully about this and assumed that FUNCTION was equivalent to SYMBOL-FUNCTION when applied to symbols. And it is equivalent except for symbols defined as local functions. Should the description of FUNCTION explicitly mention this exception, or is it clear enough as is? I hope this does not contribute to another furious debate. -- Jeff  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 2 Feb 86 22:21:28 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 2 Feb 86 19:12:17 PST Received: from NEPONSET.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 407571; Sun 2-Feb-86 22:10:32-EST Date: Sun, 2 Feb 86 22:17 EST From: David C. Plummer Subject: Nothing to do with Common Lisp To: Common-Lisp@SU-AI.ARPA Message-ID: <860202221739.4.DCP@NEPONSET.SCRC.Symbolics.COM> I'm getting tired of having some mailer kicking back this kind of crap to me. First of all, the header that used to be my message has been completely parsed out of existence. Second of all, I have no idea if I can reply to MAILER-DAEMON or POSTMASTER and frankly I'm not about to try. My only hope is that this is a 4.1 Unix system doing this, because it was promised to me that 'the 4.2 mail system will fix everything.' (I know that isn't true because our 4.2 still violates half of the standard protocols.) Will somebody please either tell the losers to fix their mailers or get them out of the distribution. Sorry to bother everybody, but I don't know a better place for this gripe. ============================== Received: from SCRC-STONY-BROOK.ARPA by SCRC-QUABBIN.ARPA via CHAOS with CHAOS-MAIL id 241340; Sun 2-Feb-86 21:08:39-EST Received: from SU-AI.ARPA by SCRC-STONY-BROOK.ARPA via INTERNET with SMTP id 407543; 2 Feb 86 21:09:51-EST Received: from CCA-UNIX.ARPA by SU-AI.ARPA with TCP; 2 Feb 86 18:10:54 PST Received: by CCA-UNIX.ARPA (4.12/4.7) id AA12595; Fri, 31 Jan 86 22:24:08 est Date: Fri, 31 Jan 86 22:24:08 est From: ima!inmet!MAILER-DAEMON%cca-unix.arpa@cca-unix.arpa Message-Id: <8602010324.AA12595@CCA-UNIX.ARPA> Sender: inmet!MAILER-DAEMON%cca-unix.arpa@cca-unix.arpa Subject: Returned mail: Unable to deliver mail To: @SU-AI.ARPA.DCP@SCRC.ARPA Received: by inmet.uucp (4.12/inmet) id AA26477; Fri, 31 Jan 86 08:23:00 est Date: Fri, 31 Jan 86 08:23:00 est Message-Id: <8601311323.AA26477@inmet.uucp> ----- Transcript of session follows ----- 554 ima!cca!@SU-AI.ARPA:DCP@SCRC... Unbalanced '>' 554 ima!cca!@SU-AI.ARPA:DCP@SCRC... Unbalanced '<' 554 ima!cca!@SU-AI.ARPA:DCP@SCRC... Unbalanced '>' 554 ima!cca!@SU-AI.ARPA:DCP@SCRC... Unbalanced '<' 554 ima!cca!@SU-AI.ARPA:DCP@SCRC... Unbalanced '>' 554 ima!cca!@SU-AI.ARPA:DCP@SCRC... Unbalanced '<' 554 norman... Unbalanced '>': Bad file number 554 norman... Unbalanced '>': Bad file number 554 norman... Unbalanced '<': Bad file number 554 norman... Unbalanced '<': Bad file number 554 norman... Unbalanced '>': Bad file number 554 norman... Unbalanced '>': Bad file number 554 norman... Unbalanced '<': Bad file number 554 norman... Unbalanced '<': Bad file number 554 norman... Unbalanced '>': Bad file number 554 norman... Unbalanced '>': Bad file number 554 norman... Unbalanced '<': Bad file number 554 norman... Unbalanced '<': Bad file number ----- Unsent message follows ----- Received: by inmet.uucp (4.12/inmet) id AA26475; Fri, 31 Jan 86 08:23:00 est Date: Fri, 31 Jan 86 08:23:00 est Message-Id: <8601311323.AA26475@inmet.uucp> From: David C. Plummer <*SU-AI.ARPA:DCP*SCRC@cca.UUCP> Subject: Defun inside Let In-Reply-To: , <8601302137.AA04616@escargot.UUCP> To: cca!Rob.cca!MacLachlan.cca!Earl.cca!Killian.cca!David.cca!C.cca!Plummer To: c.cs.cmu.edu>!, To: scrc-quabbin.arpa>!, !, Date: Thu, 30 Jan 1986 20:13 EST From: Rob MacLachlan I don't have answers for any of those. My personal feeling is that DEFUN that requires a non-null lexical environment, such as created by LET, is a timebomb ticking quickly. I think many of the cited problems are contingent in the assumption that COMPILE lets you do everything you want to do. You are bothered mostly by programming environment issues which Common Lisp mostly doesn't address. That's right, I am bothered by programming environment. That isn't necessarily an issue to the people who use the code, but it sure is an issue to those that write it and have to debug it. [Actually, the users never come into it; for all they know the program they are running is written in Ada. This is only an issue for developers.] I agree it is probably not in CL's domain to address these issues, but it shouldn't prohibit it. Maybe another example? (let ((counter 0)) (defun hairy-function-counter () counter) (defun hairy-function (arg1 ...) (incf counter) ...big-and-hairy-compuation-bound-to-get- called-a-lot-and-have-bugs-that-need-fixing...)) Why, during my debugging cycle, should I be forced to have the counter reset to 0 each time I need to change hairy-function? Date: Thu, 30 Jan 86 13:37:13 pst From: mips!escargot.earl@glacier (Earl Killian) No one has suggested that making DEFUN inside of LET not work is the right thing (people have suggested that it may not be required by the current wording of the Common Lisp manual). If someone feels that DEFUN inside of LET shouldn't work, they ought to speak up! I have reservations.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 1 Feb 86 19:46:43 EST Received: from MIT-EMS.ARPA by SU-AI.ARPA with TCP; 1 Feb 86 16:38:39 PST Received: by mit-ems.ARPA (4.12/4.8) id AA17208; Fri, 31 Jan 86 17:42:25 est Date: Fri, 31 Jan 86 17:42:25 est From: Steven Haflich Message-Id: <8601312242.AA17208@mit-ems.ARPA> To: DCP@SCRC-QUABBIN.ARPA Subject: Re: Defun inside Let Cc: common-lisp@su-ai.ARPA > From DCP@SCRC-STONY-BROOK.ARPA Thu Jan 30 18:03:04 1986 > (setf (symbol-function 'foo) #'(lambda arglist . body)) > Minor nit: some systems would lose the name of the function inside the > lambda. All compiled functions have names. (^ minor-nit 2): CLtL p.439 explicitly allows the first argument to the compile function to be nil, allowing unnamed compiled functions. Indeed, I can find nothing in the language spec suggesting that any compiled or interpreted functional object necessarily has a name. That Symbolics and others support such a slot, of course, is a big debugging win.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 1 Feb 86 19:37:22 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 1 Feb 86 16:25:55 PST Date: Sat, 1 Feb 86 19:27:28 EST From: "George J. Carrette" Subject: Retraction To: Moon@SCRC-STONY-BROOK.ARPA cc: Common-Lisp@SU-AI.ARPA In-reply-to: Msg of Fri 31 Jan 86 20:18 EST from David A. Moon Message-ID: <[MC.LCS.MIT.EDU].804711.860201.GJC> If you spend too much effort being careful about what you say in terms of the released software you might not have time to say anything interesting. So dont be too careful. I would think that any implementor would appreciate that position.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 1 Feb 86 18:09:46 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 1 Feb 86 15:00:27 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 407198; Sat 1-Feb-86 17:58:40-EST Date: Sat, 1 Feb 86 18:00 EST From: David A. Moon Subject: deftype with &key To: OLDMAN@USC-ISI.ARPA cc: common-lisp@SU-AI.ARPA In-Reply-To: <[USC-ISI.ARPA]31-Jan-86 15:58:40.OLDMAN> Message-ID: <860201180011.1.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 31 Jan 1986 15:58-EST From: OLDMAN@USC-ISI.ARPA In the area of minor cleanup, I propose that deftype add &key to its list of legal lambda-list markers. I don't see why it is not there now and it seems that it would be occationally useful. I don't know why it's not there either. We put it into our DEFTYPE.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 1 Feb 86 15:58:47 EST Received: from SCRC-QUABBIN.ARPA by SU-AI.ARPA with TCP; 1 Feb 86 12:35:27 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-QUABBIN.ARPA via CHAOS with CHAOS-MAIL id 241003; Sat 1-Feb-86 15:32:32-EST Date: Sat, 1 Feb 86 15:35 EST From: David A. Moon Subject: get-setf-method-multiple-value To: OLDMAN@USC-ISI.ARPA cc: common-lisp@SU-AI.ARPA In-Reply-To: <[USC-ISI.ARPA]31-Jan-86 15:49:30.OLDMAN> Message-ID: <860201153520.7.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 31 Jan 1986 15:49-EST From: OLDMAN@USC-ISI.ARPA Could anyone give me some motivation for the existance of this function? I don't understand what is ment by storing multiple values into a generalized variable. (setf (values a b c) (foo x y)) is a simple example. Presumably this expands into (multiple-value-setq (a b c) (foo x y)). A more interesting example would be (setf (values (aref a i) (aref a j) (aref a k)) (foo x y)) This is a possible extension rather than standard Common Lisp because some people thought it was too complicated and hard to understand, although to me it seems like an obvious symmetry.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 1 Feb 86 11:13:18 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 1 Feb 86 08:05:42 PST Received: ID ; Sat 1 Feb 86 11:05:57-EST Date: Sat, 1 Feb 1986 11:05 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: "David A. Moon" Cc: Common-Lisp@SU-AI.ARPA Subject: Retraction In-reply-to: Msg of 31 Jan 1986 20:18-EST from David A. Moon Anyway, the point I was trying to make was that we all agree that those two forms are equivalent. The questions are (less important) does Common Lisp say that these are legal forms, and (much more important) does Common Lisp presently contain everything needed to effectively make use of that programming technique. I believe that the consensus is that they are legal forms, the waffling language about top-level forms notwithstanding. And I feel strongly that the language has everything NEEDED to effectively make use of that programming technique. We are missing a few things that would make it more CONVENIENT, but those can easily be added on an implementation-specific basis. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 1 Feb 86 10:20:17 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 1 Feb 86 07:13:17 PST Received: ID ; Sat 1 Feb 86 10:13:42-EST Date: Sat, 1 Feb 1986 10:13 EST Message-ID: From: Rob MacLachlan To: OLDMAN@USC-ISI.ARPA Cc: common-lisp@SU-AI.ARPA Subject: Defmacro inside of a let That's because the compiler wants to be able to evaluate macros at compile time. It would be impossible to compute the lexical environment of a macro definition without actually interpreting the surrounding code. This is basically impossible, and is almost certainly not what you want. It is more obvious in the case of MACROLET, which is usually embedded in random code somewhere. This is explained to some degree on page 114. If you really want a closure as macroexpansion function, you can (setf (macro-function 'foo) #'(lambda (form env) ...)) In this case there is no problem, since the macro won't be defined until the form is evaluated, in which case its environment will be available. Rob  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 1 Feb 86 04:21:08 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 31 Jan 86 17:19:46 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 406640; Fri 31-Jan-86 20:17:17-EST Date: Fri, 31 Jan 86 20:18 EST From: David A. Moon Subject: Retraction To: Common-Lisp@SU-AI.ARPA Message-ID: <860131201842.6.MOON@EUPHRATES.SCRC.Symbolics.COM> Comment: Remailed at SU-AI after delay caused by mailing list error. Date: Thu, 30 Jan 86 21:02 EST From: David A. Moon Subject: Defun inside Let Let me put it this way. It's easy enough to say that (LET ... (DEFUN FOO ...)) has the same effect as (LET ... (SETF (SYMBOL-FUNCTION 'FOO) #'(LAMBDA ...))), and in fact I know of no implementation where that is not already true. As a couple of people have pointed out to me, they do not have the same effect in Symbolics Release 6.1. I apologize for leaping without looking. I assumed that because it worked in the newer software I was running, I didn't need to check whether it worked in the released version. I'll try to be more careful about opening my mouth in the future. Anyway, the point I was trying to make was that we all agree that those two forms are equivalent. The questions are (less important) does Common Lisp say that these are legal forms, and (much more important) does Common Lisp presently contain everything needed to effectively make use of that programming technique.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 1 Feb 86 03:33:07 EST Received: from USC-ISI.ARPA by SU-AI.ARPA with TCP; 31 Jan 86 12:58:27 PST Date: 31 Jan 1986 15:58-EST Sender: OLDMAN@USC-ISI.ARPA Subject: deftype with &key From: OLDMAN@USC-ISI.ARPA To: common-lisp@SU-AI.ARPA Message-ID: <[USC-ISI.ARPA]31-Jan-86 15:58:40.OLDMAN> Comment: Remailed at SU-AI after delay caused by mailing list error. In the area of minor cleanup, I propose that deftype add &key to its list of legal lambda-list markers. I don't see why it is not there now and it seems that it would be occationally useful. -- Dan  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 1 Feb 86 02:44:57 EST Received: from USC-ISI.ARPA by SU-AI.ARPA with TCP; 31 Jan 86 12:50:43 PST Date: 31 Jan 1986 15:49-EST Sender: OLDMAN@USC-ISI.ARPA Subject: get-setf-method-multiple-value From: OLDMAN@USC-ISI.ARPA To: common-lisp@SU-AI.ARPA Message-ID: <[USC-ISI.ARPA]31-Jan-86 15:49:30.OLDMAN> Comment: Remailed at SU-AI after delay caused by mailing list error. Could anyone give me some motivation for the existance of this function? I don't understand what is ment by storing multiple values into a generalized variable. -- Dan  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 1 Feb 86 02:21:12 EST Received: from USC-ISI.ARPA by SU-AI.ARPA with TCP; 31 Jan 86 12:50:28 PST Date: 31 Jan 1986 15:43-EST Sender: OLDMAN@USC-ISI.ARPA Subject: &environment From: OLDMAN@USC-ISI.ARPA To: common-lisp@SU-AI.ARPA Message-ID: <[USC-ISI.ARPA]31-Jan-86 15:43:34.OLDMAN> Comment: Remailed at SU-AI after delay caused by mailing list error. Are there any restrictions on placement of the &environment marker in a lambda list? Our implementation currently requires that it be either after an &body or first if there is no &body. -- Dan  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 1 Feb 86 01:36:38 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 31 Jan 86 21:59:09 PST Received: ID ; Sat 1 Feb 86 00:59:29-EST Date: Sat, 1 Feb 1986 00:59 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: OLDMAN@USC-ISI.ARPA Cc: common-lisp@SU-AI.ARPA Subject: &environment In-reply-to: Msg of 31 Jan 1986 15:43-EST from OLDMAN at USC-ISI.ARPA Lacking any evidence to the contrary, I would think that &environment should be allowed to appear anywhere in the lambda list. Is it really important to you that the location be restricted? I can't see why it would be. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 1 Feb 86 01:08:01 EST Received: from USC-ISI.ARPA by SU-AI.ARPA with TCP; 31 Jan 86 12:33:37 PST Date: 31 Jan 1986 15:33-EST Sender: OLDMAN@USC-ISI.ARPA Subject: Defmacro inside of a let From: OLDMAN@USC-ISI.ARPA To: common-lisp@SU-AI.ARPA Message-ID: <[USC-ISI.ARPA]31-Jan-86 15:33:44.OLDMAN> Comment: Remailed at SU-AI after delay caused by mailing list error. We all agree that a defun should be ok inside a let. Why does the language explicitly state that a defmacro evaluated inside a let is ok but must IGNORE the lexical environment? (See the first paragraph on page 145 of CLtL.) -- Dan  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 31 Jan 86 22:16:21 EST Received: from USC-ISI.ARPA by SU-AI.ARPA with TCP; 31 Jan 86 12:33:37 PST Date: 31 Jan 1986 15:33-EST Sender: OLDMAN@USC-ISI.ARPA Subject: Defmacro inside of a let From: OLDMAN@USC-ISI.ARPA To: common-lisp@SU-AI.ARPA Message-ID: <[USC-ISI.ARPA]31-Jan-86 15:33:44.OLDMAN> Comment: Remailed at SU-AI after delay caused by mailing list error. We all agree that a defun should be ok inside a let. Why does the language explicitly state that a defmacro evaluated inside a let is ok but must IGNORE the lexical environment? (See the first paragraph on page 145 of CLtL.) -- Dan  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 31 Jan 86 12:48:29 EST Received: from SCRC-QUABBIN.ARPA by SU-AI.ARPA with TCP; 31 Jan 86 09:38:01 PST Received: from CHICOPEE.SCRC.Symbolics.COM by SCRC-QUABBIN.ARPA via CHAOS with CHAOS-MAIL id 240693; Fri 31-Jan-86 12:35:03-EST Date: Fri, 31 Jan 86 12:37 EST From: Daniel L. Weinreb Subject: Defun inside Let To: DCP@SCRC-QUABBIN.ARPA, common-lisp@SU-AI.ARPA In-Reply-To: <860130210351.3.DCP@NEPONSET.SCRC.Symbolics.COM> Message-ID: <860131123758.6.DLW@CHICOPEE.SCRC.Symbolics.COM> Date: Thu, 30 Jan 86 21:03 EST From: David C. Plummer That's right, I am bothered by programming environment. I agree it is probably not in CL's domain to address these issues, but it shouldn't prohibit it. Maybe another example? I believe that all the problems you've been talking about have to do with the poor interaction between lexical scoping and incremental programming. These poor interactions are discussed in the paper "The Art of the Interpreter: Parts Zero, One, and Two" by Guy Steele and Gerry Sussman. They are not incidental design flaws of Common Lisp; they are part of the deep nature of lexical scoping. I don't think they represent a "time bomb" in the language. They just show how lexical scoping, itself, has problems when it comes to program development, when used in this way. I don't think any language change is called for. If anybody writes a textbook or something that makes recommendations about programming practices and styles, though, they should take these problems into account. I hope Steele will correct me if I'm wrong.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 31 Jan 86 12:15:51 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 31 Jan 86 09:06:15 PST Received: from CHICOPEE.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 406162; Fri 31-Jan-86 12:04:41-EST Date: Fri, 31 Jan 86 12:06 EST From: Daniel L. Weinreb Subject: Defun inside Let To: Fahlman@C.CS.CMU.EDU, common-lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860131120618.3.DLW@CHICOPEE.SCRC.Symbolics.COM> Date: Thu, 30 Jan 1986 14:29 EST From: "Scott E. Fahlman" There can be no question at all on the point Jeff Dalton raises: when a Defun occurs inside a Let or anywhere else, it changes the GLOBAL function definition for the symbol in question. It is not a form of LABELS. Agreed. This is completely clear from the manual. If DEFUN inside LET is valid Common Lisp (I think it is, modulo the general smokescreen of the page 66 paragraph), then it changes the global definition.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 31 Jan 86 00:16:42 EST Received: from YALE.ARPA by SU-AI.ARPA with TCP; 30 Jan 86 20:49:53 PST Received: by Yale-Bulldog.YALE.ARPA; 30 Jan 86 23:47:30 EST (Thu) Date: 30 Jan 86 23:47:30 EST (Thu) From: James Meehan Message-Id: <8601310447.AA06340@Yale-Bulldog.YALE.ARPA> To: common-lisp@su-ai.arpa [This may be a duplicate message. Our mail system is ill.] I remember seeing some bboard mail on this topic, but I don't remember whether there was a consensus: Is Common Lisp supposed to allow DEFUN inside LET? I know I can say (setf (symbol-function 'foo) #'(lambda ...)) and get much the same effect, but that's more awkward.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 31 Jan 86 00:07:38 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 30 Jan 86 20:55:24 PST Received: ID ; Thu 30 Jan 86 23:55:50-EST Date: Thu, 30 Jan 1986 23:55 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: James Meehan Cc: common-lisp@SU-AI.ARPA In-reply-to: Msg of 30 Jan 1986 23:47-EST from James Meehan Your mail system must be ill. Your earlier message arrived and has sparked a furious debate on the Common Lisp mailing list. I thought it was a simple question, but apparently there's no such thing in this forum. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 30 Jan 86 22:57:04 EST Received: from SU-GLACIER.ARPA by SU-AI.ARPA with TCP; 30 Jan 86 17:23:29 PST Received: by glacier with Sendmail; Thu, 30 Jan 86 17:21:39 pst Received: from escargot.UUCP (escargot.ARPA) by mips.UUCP (4.12/4.7) id AA18926; Thu, 30 Jan 86 13:37:50 pst Received: by escargot.UUCP (4.12/4.7) id AA04616; Thu, 30 Jan 86 13:37:13 pst Date: Thu, 30 Jan 86 13:37:13 pst From: mips!escargot.earl@glacier (Earl Killian) Message-Id: <8601302137.AA04616@escargot.UUCP> To: common-lisp@SU-AI.ARPA In-Reply-To: Rob MacLachlan's message of Thu, 30 Jan 1986 14:46 EST Subject: DEFUN inside of LET No one has suggested that making DEFUN inside of LET not work is the right thing (people have suggested that it may not be required by the current wording of the Common Lisp manual). If someone feels that DEFUN inside of LET shouldn't work, they ought to speak up!  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 30 Jan 86 22:44:00 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 30 Jan 86 19:23:20 PST Received: ID ; Thu 30 Jan 86 22:23:40-EST Date: Thu, 30 Jan 1986 22:23 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: common-lisp@SU-AI.ARPA Subject: Defun inside Let I was about to reply to Plummer's objections, but discovered that others had already said most of what I want to. I agree with Jonathan Rees and with Rob Maclachlan on this issue. It is certainly true that for debugging purposes, there are some useful things that a Common Lisp environment might supply to make people with debugging styles like Plummer's more comfortable. For example, it might be nice to be able to grab a function's definition and say "I want to define an additional function in the same lexical environment that this guy sees" or "I want to redefine this function, but continue using the lexical environment of the old definition (plus the following additional lexical variables)". In most Common Lisp interpreters I have seen (and all of the ones I've written), it's pretty trivial to add that, though it does require descending to system-internal levels to do it. Nothing in Common Lisp makes this impossible or even very hard. We could probably add a standard set of hooks to make such a feature portable if we tried hard enough, but after all the hassle we went through to put in the evalhook stuff, I'm not eager to go through that sort of exercise again. Let the manufacturers compete to produce the best debugging environment, each consistent with his machine's style and philosophy of user interaction. It is much harder to add such facilities for modifying compiled functions that share a lexical environment. The easy way to do this would be to follow the trail back to the source code, make the changes the user wants, and then recompile the whole top-level form which defines the lexical environment in question. I'm quite content to do this by hand, but there's no reason that someone couldn't write a package to do it automatically, much as flavor methods are now recompiled when you change anything. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 30 Jan 86 21:29:03 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 30 Jan 86 18:11:07 PST Date: Thu, 30 Jan 86 21:12:29 EST From: "George J. Carrette" Subject: editing environments To: DCP@SCRC-QUABBIN.ARPA cc: common-lisp@SU-AI.ARPA, Fahlman@C.CS.CMU.EDU In-reply-to: Msg of Thu 30 Jan 86 16:08 EST from David C. Plummer Message-ID: <[MC.LCS.MIT.EDU].802352.860130.GJC> I guess what you can say is that the 'text editor' (human readable) will sectionalize the buffer in such a way so that a compile-region is meaningfull only for the entire top-level-form, so that the question of 'the environment editor' doesnt come up. But lets face it, CL, as defined, is very compile-whole-file oriented. It doesnt take into account very well the programming environment style that has been in use with Emacs/LEDIT/MACLISP on the PDP-10 and the Lispmachine for at least a decade. Constructs such as (in-package ...) and (eval-when (compile) (setq *readtable* ...)) etc that cause the most painful confusion to even our best attempts at making our program editors deal with such thing are, in the final analysis, far too unconstrained to be able to expect a uniform and well understood behavior. It will be very difficult to come up with a workable model. Greenblatt had some suggestions recently in private correspondence that harken back to certain tricks that the famous MDL compiler "COMBAT" used. Such analogies however do not add any comfort to the situation. -gjc  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 30 Jan 86 21:24:50 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 30 Jan 86 17:59:15 PST Received: from NEPONSET.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 405743; Thu 30-Jan-86 20:57:21-EST Date: Thu, 30 Jan 86 21:03 EST From: David C. Plummer Subject: Defun inside Let To: Rob MacLachlan , Earl Killian , David C. Plummer , common-lisp@SU-AI.ARPA cc: Scott E. Fahlman In-Reply-To: , <8601302137.AA04616@escargot.UUCP> Message-ID: <860130210351.3.DCP@NEPONSET.SCRC.Symbolics.COM> Date: Thu, 30 Jan 1986 20:13 EST From: Rob MacLachlan I don't have answers for any of those. My personal feeling is that DEFUN that requires a non-null lexical environment, such as created by LET, is a timebomb ticking quickly. I think many of the cited problems are contingent in the assumption that COMPILE lets you do everything you want to do. You are bothered mostly by programming environment issues which Common Lisp mostly doesn't address. That's right, I am bothered by programming environment. That isn't necessarily an issue to the people who use the code, but it sure is an issue to those that write it and have to debug it. [Actually, the users never come into it; for all they know the program they are running is written in Ada. This is only an issue for developers.] I agree it is probably not in CL's domain to address these issues, but it shouldn't prohibit it. Maybe another example? (let ((counter 0)) (defun hairy-function-counter () counter) (defun hairy-function (arg1 ...) (incf counter) ...big-and-hairy-compuation-bound-to-get- called-a-lot-and-have-bugs-that-need-fixing...)) Why, during my debugging cycle, should I be forced to have the counter reset to 0 each time I need to change hairy-function? Date: Thu, 30 Jan 86 13:37:13 pst From: mips!escargot.earl@glacier (Earl Killian) No one has suggested that making DEFUN inside of LET not work is the right thing (people have suggested that it may not be required by the current wording of the Common Lisp manual). If someone feels that DEFUN inside of LET shouldn't work, they ought to speak up! I have reservations.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 30 Jan 86 21:24:12 EST Received: from SCRC-QUABBIN.ARPA by SU-AI.ARPA with TCP; 30 Jan 86 18:02:52 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-QUABBIN.ARPA via INTERNET with SMTP id 240543; 30 Jan 86 20:59:51-EST Date: Thu, 30 Jan 86 21:02 EST From: David A. Moon Subject: Defun inside Let To: Jonathan A Rees cc: DCP@SCRC-QUABBIN.ARPA, common-lisp@SU-AI.ARPA In-Reply-To: <[MC.LCS.MIT.EDU].802081.860130.JAR0> Message-ID: <860130210226.4.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Thu, 30 Jan 86 17:05:05 EST From: Jonathan A Rees Date: Thu, 30 Jan 86 16:08 EST From: David C. Plummer The questions you raise are valid and important ones, but I don't see what they have to do with DEFUN. They apply equally to SETQ, SETF, FLET, LABELS, etc., and are bound to arise the minute you have lexical closures at all. Yes, it would be nice to be able to update the code for a closure, alter environments, and so forth, for debugging. But I don't see why debugging questions should enter into this semantic question. Is there some reason that DEFUN is different? Yes, it defines a name in the global environment. This means the user can talk about a particular DEFUN. A user can't talk about a particular SETQ or a particular FLET in this way, because they don't have names. I think calling this "debugging" is ducking a genuine issue of language definition. "Making DEFUN inside of LET work" is not as simple as some people seem to think, because the definition of what it means to "work" is not simple and involves issues like the ones DCP raised, which have been raised many times before and are probably the reason for the paragraph on page 66 that everyone likes to dump on. If there's a problem with making (DEFUN FOO ...) mean the same [except with respect to debugging, which Common Lisp doesn't address anyhow] as (SETF (SYMBOL-FUNCTION 'FOO) #'(LAMBDA ...)), why isn't that problem also a problem with the SETF form? Who says it isn't? The only difference is that users aren't accustomed to writing (SETF (SYMBOL-FUNCTION 'FOO) #'(LAMBDA ...)) all the time. Let me put it this way. It's easy enough to say that (LET ... (DEFUN FOO ...)) has the same effect as (LET ... (SETF (SYMBOL-FUNCTION 'FOO) #'(LAMBDA ...))), and in fact I know of no implementation where that is not already true. The problem comes when people try to use this to do real work. It quickly becomes apparent that you have actually added a whole new feature to the language, without much thought or standardization of how it is to be used.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 30 Jan 86 20:28:22 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 30 Jan 86 17:13:57 PST Received: ID ; Thu 30 Jan 86 20:13:52-EST Date: Thu, 30 Jan 1986 20:13 EST Message-ID: From: Rob MacLachlan To: "David C. Plummer" Cc: common-lisp@SU-AI.ARPA, "Scott E. Fahlman" Subject: Defun inside Let In-reply-to: Msg of 30 Jan 1986 16:08-EST from David C. Plummer Date: Thursday, 30 January 1986 16:08-EST From: David C. Plummer To: Scott E. Fahlman , common-lisp at SU-AI.ARPA Re: Defun inside Let That's all fine and dandy. Now come the hard parts. - What if I want to redefine add-and-increment to be ... Is the system expected to know that >the old version< of add-and-increment is a lexical closure over some variables and make the new one share that same environment? No, and for the reson REM says. The new definition is in the environment you define it in, which is null in this case. Common Lisp doesn't need to be able to redefine functions within an old environment. Perhaps a useful feature, but certainly not necessary to make good use of definitions in non null-environments. This is more of a programming environment issue than a lexical environment issue. Uses of definitions in non-null environments are usually such that it is easy to recompile the whole shebang. You can't do it with COMPILE, but in Hemlock, all I have to do is "Compile Defun". - What if I wanted to add a variable to the lexical environment? What forms to I type to splice something in? Not defined in Common Lisp. I have been living without it. - What if I want to redefine add-and-increment to be interpreted? Are you forcing all implementations to have the same compiler and interpreter environment? If you can't redefine it without its environment, you can't redefine it to be interpreted without EVAL'ing it all, thus there is no problem. - Suppose you declare 'you are not allowed to redefine a function whose old definition is closed over a non-null lexical environment and expect it to inherit the old environment.' What if I interpret the above LET. Am I allowed to compile just one of the functions? If not, why not? If not, am I allowed to compile both? If so, how do I manage that with the tools provided (which presumably compile on thing at a time.) If I am allowed to compile just one, does that enforce the same format for compiled and interpreted lexical environments? Well, you can expect whatever you want... :-) Spice Lisp doesn't let you use COMPILE on functions defined in a non-null environment. Why not? Because it's hard to implement and not worth the effort. Of course, Common Lisp COMPILE could just do nothing in this case. I don't have answers for any of those. My personal feeling is that DEFUN that requires a non-null lexical environment, such as created by LET, is a timebomb ticking quickly. I think many of the cited problems are contingent in the assumption that COMPILE lets you do everything you want to do. You are bothered mostly by programming environment issues which Common Lisp mostly doesn't address. Rob  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 30 Jan 86 20:27:40 EST Received: from MIT-EMS.ARPA by SU-AI.ARPA with TCP; 30 Jan 86 17:08:54 PST Received: by mit-ems.ARPA (4.12/4.8) id AA10928; Thu, 30 Jan 86 20:03:44 est Date: Thu, 30 Jan 86 20:03:44 est From: Steven Haflich Message-Id: <8601310103.AA10928@mit-ems.ARPA> To: REM%IMSSS.MIT.EDU@mit-ems.ARPA Subject: Re: Defun inside Let Cc: common-lisp@su-ai.ARPA > From @SU-AI.ARPA:REM@IMSSS Thu Jan 30 19:00:10 1986 > > But if you had explicitly recovered the lexical environment from > either add-and-increment or sub-and-decrement (either will do in this > case), and executed the new DEFUN in that environment, then the new > function-object could share lexical a,b once again. > I'm under the impression lexical environments (except possibly the null > environment) can't get new variables once they are formed, but there > were suggestions to change this both for debugging reasons and for > consistency with the null environment. I'm under the same impression. There is a very good motivation for hiding the insides of lexical closures: The compiler (and by implication also the interpreter) is allowed to do whatever flow and variable analysis it can in order to bum or completely eliminate closures. By requiring that it be possible subsequently to modify a closure, such analysis becomes impossible. See the four examples on CLtL pp.88-9 where in one case the compiler can avoid making a closure, and in another merge many closures into a single object. These optimizations could be especially important when compiling automatically-generated code. It is worth every bit of effort to make CL compilers super-analyzing/optimizing, because that's the place in a CL system that has the most leverage on language performance. > Has anybody written a completely correct implemention of CL so that we > can establish by example that CLtL isn't self-contradictory?? How would he know if he had? If knowing were so easy, compiler validation wouldn't be the subject of so much research. And we wouldn't hear about validation suites in Ada land that execute such-and-so percentage of the language features...  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 30 Jan 86 19:36:38 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 30 Jan 86 15:05:47 PST Received: from NEPONSET.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 405638; Thu 30-Jan-86 18:03:56-EST Date: Thu, 30 Jan 86 18:10 EST From: David C. Plummer Subject: Defun inside Let To: Jonathan A Rees , Steven Haflich cc: DCP@SCRC-QUABBIN.ARPA, JAR%MC.LCS.MIT.EDU@MIT-EMS.ARPA, NGALL%G.BBN.COM@MIT-EMS.ARPA, common-lisp@SU-AI.ARPA In-Reply-To: <[MC.LCS.MIT.EDU].802081.860130.JAR0>, <8601302218.AA10164@mit-ems.ARPA> Message-ID: <860130181022.1.DCP@NEPONSET.SCRC.Symbolics.COM> You two bring up the same point. What if DEFUN's macro expansion were (setf (symbol-function 'foo) #'(lambda arglist . body)) Minor nit: some systems would lose the name of the function inside the lambda. All compiled functions have names. Disagreement with Rees: I think debugging questions should come into the semantics of things. Some companies use debuggability and the power of their debug tools as one of their selling points. Indeed this isn't an issue for applications that don't alter functions, but it is to developers. Anyway... This is no different from defun. The problem is that there is a top level functional form, #'(lambda ...) in this case, that the compiler has to do something with. Maybe a compiler that sees such a thing in a non-null lexical environment punts (this doesn't address several other issues I raised). Then people will complain, and have to us, that it is inefficient by generating interpreted code.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 30 Jan 86 18:47:04 EST X-Sent: to SU-AI.ARPA by IMSSS.FRONSTAD.EDU via ETHERNET with PUPFTP; 1986-Jan-30 15:28:45 PST (=GMT-8hr) X-Mailer: EMACS -> PSL (FORMAT+SEND-ALL) -> PUPFTP Date: 1986 January 30 15:26:53 PST (=GMT-8hr) From: Robert Elton Maas (this host known locally only) To:DCP@SCRC-QUABBIN.ARPA CC:Fahlman@C.CS.CMU.EDU,COMMON-LISP@SU-AI.ARPA Subject: Defun inside Let Sender: REM%IMSSS@SU-SCORE.ARPA (for undeliverable-mail notifications) Reply-to: REM%IMSSS@SU-SCORE.ARPA S> Date: Thu, 30 Jan 1986 14:29 EST S> From: "Scott E. Fahlman" S> when a Defun occurs inside a Let or anywhere else, it changes the S> GLOBAL function definition for the symbol in question. It is not a S> form of LABELS. I agree, see my related opinion below. D> Date: Thu, 30 Jan 86 16:08 EST D> From: David C. Plummer D> (let ((a 3) (b 5)) D> (defun add-and-increment () D> (prog1 (+ a b) (incf a) (incf b))) D> (defun sub-and-decrement () D> (prog1 (- a b) (decf a) (decf b)))) Clearly that creates two global function-bindings (definitions) to function-objects each of which has access to the same lexical environment (the one containing a and b initialized to 3 and 5 resp.). I think we all agree so far. D> That's all fine and dandy. Now come the hard parts. D> - What if I want to redefine add-and-increment to be D> (defun add-and-increment (&optional amount) D> (prog1 (+ a b) (incf a amount) (incf b amount))) If you just do a toplevel defun, you are replacing the old definition with a new one that uses the null lexical environment instead of the one with a and b used by the earlier definitions. Thus you are probably making a mistake, doing something other than what you obviously wanted to do. The old function-object still accesses the a,b environment but is inaccessible, while the new function-object currently function-bound to the symbol add-and-increment access the null environment instead. But if you had explicitly recovered the lexical environment from either add-and-increment or sub-and-decrement (either will do in this case), and executed the new DEFUN in that environment, then the new function-object could share lexical a,b once again. In this particular example you can recover from the mistake because even though the old add-and-increment function-object is inaccessible so you can no longer recover the a,b environment from it (unless your user interface has a history/undo mechanism), you can still recover the environment from the not-yet-lost sub-and-increment function-object which is still function-bound to the sub-and-increment symbol thus accessible. (However I don't know how to actually obtain explicit CLtL-level access to that lexical environment; in earlier debate on macro expansion didn't we decide that at present CLtL provides no such mechanism for explicitly handling &environment stuff but ought to be changed to provide it?) D> Is the system expected to know that >the old version< of D> add-and-increment is a lexical closure over some variables and make the D> new one share that same environment? I'd say definitely not. If you specify null lexical environment, by doing a toplvel DEFUN, that's what you should get. D> - What if I wanted to add a variable to the lexical environment? What D> forms to I type to splice something in? I'm under the impression lexical environments (except possibly the null environment) can't get new variables once they are formed, but there were suggestions to change this both for debugging reasons and for consistency with the null environment. D> - What if I want to redefine add-and-increment to be interpreted? Are you D> forcing all implementations to have the same compiler and interpreter D> environment? Now the cans of worms really start to open. I'd say if there is a mechanism for redefining functions inside a non-null lexical environment, as in the a,b example above, or if by any other mechanism it is possible to create a situation where some but not all functions in a particular lexical environment are compiled, this implies that both interpreted and compiled functions must access lexical environments in the same way essentially, i.e. that there be just one implementation of lexical environment that is used by both kinds of code. (Well, it would maybe be possible to have two kinds of lexical environments, one optimized for compiled code and one not, but allow either kind of function to access either kind of environment, sort of like the way interpreted functions can call compiled functions by calling APPLY on the contents of the function cell and vice versa by linking to COMPILED-CALLING-INTERPRETED or whatever which sets up a call to APPLY. But then if you initially load some functions interpreted and later compile them in memory you may be permanently stuck with the compiled functions running slowly as they access the non-compiled lexical environment.) D> My personal feeling is that DEFUN that requires a D> non-null lexical environment, such as created by LET, is a timebomb D> ticking quickly. Well, if the language allows the DEFUN to be done, but the implementor doesn't take care to do things correctly, indeed poor programmers will find their code blowing up whenever they trigger the bugs. One major question for CL advocates. Has anybody written a completely correct implemention of CL, with no exceptions whatsoever, with all these esoteric/messy cases correctly handled, with both interpretor and compiler doing the expected things, so that we can establish by example that CLtL isn't self-contradictory?? I personally believe that as currently documented CLtL is indeed self-contradictory, even after all the typos have been fixed, and thus in some sense hopeless as a standard, but I'd be glad if I was wrong.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 30 Jan 86 17:38:13 EST Received: from MIT-EMS.ARPA by SU-AI.ARPA with TCP; 30 Jan 86 14:25:34 PST Received: by mit-ems.ARPA (4.12/4.8) id AA10164; Thu, 30 Jan 86 17:18:25 est Date: Thu, 30 Jan 86 17:18:25 est From: Steven Haflich Message-Id: <8601302218.AA10164@mit-ems.ARPA> To: DCP@SCRC-STONY-BROOK.ARPA, JAR%MC.LCS.MIT.EDU@mit-ems.ARPA, NGALL%G.BBN.COM@mit-ems.ARPA Subject: Re: DEFUN inside LET Cc: common-lisp@SU-AI.ARPA > From @SU-AI.ARPA:NGALL@G.BBN.COM Thu Jan 30 11:27:51 1986 > > > Also, since DEFUN is a macro, it's hard to imagine what it could expand > > into in order to behave much differently from this. > > Imagine this: > > (defmacro simple-defun (name lambda-list &body body) > `(setf (symbol-function ',name) > '(lambda ,lambda-list ,@body))) > > The quote in front of the lambda ensures that the lambda expression is > defined in the null lexical environment. Wouldn't one instead use: (defmacro simple-defun (name lambda-list &body body) `(setf (symbol-function ',name) (function (lambda ,lambda-list ,@body)))) This would seem to capture the lexical environment quite unambiguously. If, as DCP suggests, a defun that captures its lexical environment is really a "time bomb", defun could be "fixed". But how could it be possible to prohibit constructions like the above?  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 30 Jan 86 17:19:13 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 30 Jan 86 14:03:37 PST Date: Thu, 30 Jan 86 17:05:05 EST From: Jonathan A Rees Sender: JAR0@MC.LCS.MIT.EDU Subject: Defun inside Let To: DCP@SCRC-QUABBIN.ARPA cc: common-lisp@SU-AI.ARPA In-reply-to: Msg of Thu 30 Jan 86 16:08 EST from David C. Plummer Message-ID: <[MC.LCS.MIT.EDU].802081.860130.JAR0> Date: Thu, 30 Jan 86 16:08 EST From: David C. Plummer ... That's all fine and dandy. Now come the hard parts. Is the system expected to know that >the old version< of add-and-increment is a lexical closure over some variables and make the new one share that same environment? - What if I wanted to add a variable to the lexical environment? What forms to I type to splice something in? ... I don't have answers for any of those. It's not clear to me there ARE answers to some of them. What if somebody on the ISO board thinks up roughly the same questions? If somebody does have >answers<, I'd like to hear them. My personal feeling is that DEFUN that requires a non-null lexical environment, such as created by LET, is a timebomb ticking quickly. The questions you raise are valid and important ones, but I don't see what they have to do with DEFUN. They apply equally to SETQ, SETF, FLET, LABELS, etc., and are bound to arise the minute you have lexical closures at all. Yes, it would be nice to be able to update the code for a closure, alter environments, and so forth, for debugging. But I don't see why debugging questions should enter into this semantic question. Is there some reason that DEFUN is different? If there's a problem with making (DEFUN FOO ...) mean the same [except with respect to debugging, which Common Lisp doesn't address anyhow] as (SETF (SYMBOL-FUNCTION 'FOO) #'(LAMBDA ...)), why isn't that problem also a problem with the SETF form? Jonathan  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 30 Jan 86 16:32:42 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 30 Jan 86 13:03:18 PST Received: from NEPONSET.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 405501; Thu 30-Jan-86 16:01:52-EST Date: Thu, 30 Jan 86 16:08 EST From: David C. Plummer Subject: Defun inside Let To: Scott E. Fahlman , common-lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860130160817.5.DCP@NEPONSET.SCRC.Symbolics.COM> Date: Thu, 30 Jan 1986 14:29 EST From: "Scott E. Fahlman" There can be no question at all on the point Jeff Dalton raises: when a Defun occurs inside a Let or anywhere else, it changes the GLOBAL function definition for the symbol in question. It is not a form of LABELS. We've discussed this inside Symbolics, and we don't have a solution for the following problem: (let ((a 3) (b 5)) (defun add-and-increment () (prog1 (+ a b) (incf a) (incf b))) (defun sub-and-decrement () (prog1 (- a b) (decf a) (decf b)))) That's all fine and dandy. Now come the hard parts. - What if I want to redefine add-and-increment to be (defun add-and-increment (&optional amount) (prog1 (+ a b) (incf a amount) (incf b amount))) Is the system expected to know that >the old version< of add-and-increment is a lexical closure over some variables and make the new one share that same environment? - What if I wanted to add a variable to the lexical environment? What forms to I type to splice something in? - What if I want to redefine add-and-increment to be interpreted? Are you forcing all implementations to have the same compiler and interpreter environment? - Suppose you declare 'you are not allowed to redefine a function whose old definition is closed over a non-null lexical environment and expect it to inherit the old environment.' What if I interpret the above LET. Am I allowed to compile just one of the functions? If not, why not? If not, am I allowed to compile both? If so, how do I manage that with the tools provided (which presumably compile on thing at a time.) If I am allowed to compile just one, does that enforce the same format for compiled and interpreted lexical environments? I don't have answers for any of those. It's not clear to me there ARE answers to some of them. What if somebody on the ISO board thinks up roughly the same questions? If somebody does have >answers<, I'd like to hear them. My personal feeling is that DEFUN that requires a non-null lexical environment, such as created by LET, is a timebomb ticking quickly.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 30 Jan 86 14:58:36 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 30 Jan 86 11:46:39 PST Received: ID ; Thu 30 Jan 86 14:46:55-EST Date: Thu, 30 Jan 1986 14:46 EST Message-ID: From: Rob MacLachlan To: common-lisp@SU-AI.ARPA Subject: DEFUN inside of LET The meaning of DEFUN inside of LET has been discussed at least twice before on thie mailing list. Each time some people say that they aren't sure whether it is required to work, and the rest of the people say that "The U.S. will look pretty wimpy in ISO standardization if DEFUN doesn't work inside of LET." If you have a lexical Lisp, DEFUN with a non-null environment will work without any major effort. I can't think of any reason for arbitrarily making the environment for DEFUN null, and I can think of good reasons for not doing so. If you want a definition in a null environment, you can always put the definition in a null environment. It is my opinion that the notion of a top-level form doesn't make sense in a lexical Lisp. This issue definitely needs to be clarified. I think that passage in CLTL about top-level forms not being well defined in non-top-level contexts should be flushed. It should be replaced with text describing what the forms do. This opinion is based on the assumption that it is reasonable to make definitions in a non-null environment. Such definitions are clearly not in a top-level context, so the semantics of definitions in non-top-level contexts must be defined. As to whether DEFUN makes a local definition, I would say no. It seems to me that the semantics of defun is to change the global function definition, no matter where it appears. Common Lisp has no notion of a block which implicitly gloms onto definitions in its body. If you want to make a local definition, you use a binding form. Rob P.S. Rambo for technical committee!  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 30 Jan 86 14:42:02 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 30 Jan 86 11:29:25 PST Received: ID ; Thu 30 Jan 86 14:29:43-EST Date: Thu, 30 Jan 1986 14:29 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: common-lisp@SU-AI.ARPA Subject: Defun inside Let There can be no question at all on the point Jeff Dalton raises: when a Defun occurs inside a Let or anywhere else, it changes the GLOBAL function definition for the symbol in question. It is not a form of LABELS. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 30 Jan 86 13:52:21 EST Received: from CS.UCL.AC.UK by SU-AI.ARPA with TCP; 30 Jan 86 10:10:53 PST Received: from aiva.edinburgh.ac.uk by 44d.Cs.Ucl.AC.UK via Janet with NIFTP id a000168; 30 Jan 86 13:33 GMT From: Jeff Dalton Date: Wed, 29 Jan 86 17:47:51 GMT Message-Id: To: Fahlman@c.cs.cmu.edu, meehan <@yale.arpa,@harvard.harvard.edu:meehan@csi> Subject: Re: DEFUN inside LET Cc: common-lisp@su-ai.arpa Date: Tue, 28 Jan 1986 23:12 EST From: "Scott E. Fahlman" I'm not sure if there's actually a firm consensus on this, but in my opinion Defun inside Let should always work. It's an idiom I use a lot, and if some alleged Common Lisp didn't supply this, I'd either complain or fix it myself. Another issue is what DEFUN inside LET should do. My understanding of Common Lisp is that (let ((a 1)) (defun f () a) ...) is supposed to be equivalent (modulo implicit blocks, &c) to (let ((a 1)) (setf (symbol-function 'f) #'(lambda () a)) ...) but that in Scheme it is equivalent to (let ((a 1)) (labels ((f () a)) ...)) In other words, does an internal DEFUN define a local or a global function? My opinion now is that I would rather have it define a local function (a la Scheme), because I think that looks better than a LABELS, because I use local functions a lot, and because, to me, it seems more natural. But if I used global functions defined inside environments a lot, I could well change my mind since the SETF is clearly worse than LABELS (and hence more in need of a sweetened syntax). At the moment, though, I'm not sure what a global DEFUN inside a LET is supposed to express (i.e., what is it good for?). -- Jeff  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 30 Jan 86 11:44:41 EST Received: from SEISMO.CSS.GOV by SU-AI.ARPA with TCP; 30 Jan 86 08:31:41 PST Return-Path: Received: from mcvax.UUCP by seismo.CSS.GOV with UUCP; Thu, 30 Jan 86 11:10:05 EST From: mcvax!nplmg1a.uucp!jrp@seismo.CSS.GOV Received: by mcvax.uucp; Thu, 30 Jan 86 16:03:51 +0100 (MET) Received: by mcvax.uucp; Thu, 30 Jan 86 16:03:33 +0100 (MET) Received: from nplmg1a.uucp by eagle.Ukc.AC.UK with UUCP id a009312; 30 Jan 86 9:44 GMT To: Fahlman@c.cs.cmu.edu Cc: nplmg1a!jrp@seismo.CSS.GOV, common-lisp@su-ai.arpa Subject: Re: Floating Point Computation In-Reply-To: Your message of Wed, 29 Jan 1986 13:52 EST. Date: 30 Jan 86 09:42:27 GMT (Thu) Message-Id: <1000.507462147@nplmg1a> Thanks for the reference. I'm not sure what point you are trying to make, however. Is there some specific recommendation lurking in here? I don't think that I have anything very profound to say, save don't take *anything* for granted when it comes to floating point. The reference gives a number of simple axioms which *should* be satisfied by any reasonable processor, but are surprisingly often not satisfied in all cases. In any case, these axioms should permit you to determine what you can resonably do with floating-point in what might be called a "sane" environment. By the way, there are a number of packages for assessing the floating-point performance of a given processor (e.g. from NAG, the Numerical Algorithms Group in Oxford). And when it comes to "double-length" arithmetic... Or are you just saying that everything about floating-point is so screwed up that we shouldn't waste time arguning about how to make it better? I would not go that far, but when it comes to "double-length" arithmetic... John Pavel  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 30 Jan 86 10:27:26 EST Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 30 Jan 86 06:58:56 PST Date: 30 Jan 1986 09:58-EST Sender: NGALL@G.BBN.COM Subject: Re: DEFUN inside LET From: NGALL@G.BBN.COM To: JAR@MC.LCS.MIT.EDU Cc: common-lisp@SU-AI.ARPA Message-ID: <[G.BBN.COM]30-Jan-86 09:58:55.NGALL> In-Reply-To: <[MC.LCS.MIT.EDU].800572.860129.JAR> Date: Wed, 29 Jan 86 14:45:27 EST From: Jonathan A Rees Subject: DEFUN inside LET Date: Tue, 28 Jan 1986 23:12 EST From: Scott E. Fahlman I'm not sure if there's actually a firm consensus on this... I don't understand how one can argue with p. 67 of CLtL which (to me) unequivocally says that DEFUN inside LET should "work": "Evaluating a DEFUN form causes the symbol ... to be a global name for the function specified by the LAMBDA-expression ... in the lexical environment in which the DEFUN form was executed." That passage sounds unequivocal (by itself) to me too (and I am VERY much in favor of DEFUNs in LETs). Unfortunately, on pg. 66, is this very equivocal passage that may imply that a DEFUN inside a LET is not guaranteed to work in CL: "It is not illegal to use these forms at other than top level, but whether it is meaningful to do so depends on context [talk about waffling!]. Compilers, for example, may not recognize these forms properly in other than top-level contexts." As I recall, this is the passage that has prevented a "firm consensus" and I think there was some sort of consensus that the passage should be clarified to unequivocally allow DEFUNs in LETs (and to state more explicitly what forms are not meaningful in which contexts). Also, since DEFUN is a macro, it's hard to imagine what it could expand into in order to behave much differently from this. Imagine this: (defmacro simple-defun (name lambda-list &body body) `(setf (symbol-function ',name) '(lambda ,lambda-list ,@body))) The quote in front of the lambda ensures that the lambda expression is defined in the null lexical environment. -- Nick  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 29 Jan 86 15:58:24 EST Received: from UCBVAX.BERKELEY.EDU by SU-AI.ARPA with TCP; 29 Jan 86 11:32:59 PST Received: by ucbvax.berkeley.edu (5.44/1.9) id AA25344; Wed, 29 Jan 86 11:32:58 PST Received: by dali.berkeley.edu (5.44/5.16) id AA21319; Wed, 29 Jan 86 11:32:39 PST Date: Wed, 29 Jan 86 11:32:39 PST From: fateman@dali.berkeley.edu (Richard Fateman) Message-Id: <8601291932.AA21319@dali.berkeley.edu> To: common-lisp@su-ai.arpa, mcvax!nplmg1a.uucp!jrp@seismo.css.gov Subject: Re: Floating Point Computation Sorry to disappoint you, but Brown's model was intended to provide a model to include nearly all known horrors. It is hardly a prescription for what to do in designing either a computer or a language.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 29 Jan 86 15:18:24 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 29 Jan 86 12:05:52 PST Received: ID ; Wed 29 Jan 86 15:06:10-EST Date: Wed, 29 Jan 1986 15:06 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Jonathan A Rees Cc: common-lisp@SU-AI.ARPA Subject: DEFUN inside LET In-reply-to: Msg of 29 Jan 1986 14:45-EST from Jonathan A Rees Fine, I'm happy to agree that this passage is unequivocal. One might have been confused by the mumbling about "top-level forms" that surrounds this passage, but let's not be. Does anyone out there want to argue that DEFUN inside of LET is not required to work? -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 29 Jan 86 15:17:55 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 29 Jan 86 10:52:10 PST Received: ID ; Wed 29 Jan 86 13:52:43-EST Date: Wed, 29 Jan 1986 13:52 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: mcvax!nplmg1a.uucp!jrp@SEISMO.CSS.GOV Cc: common-lisp@SU-AI.ARPA Subject: Floating Point Computation In-reply-to: Msg of 29 Jan 1986 11:38-EST from mcvax!nplmg1a.uucp!jrp at seismo.CSS.GOV Thanks for the reference. I'm not sure what point you are trying to make, however. Is there some specific recommendation lurking in here? Or are you just saying that everything about floating-point is so screwed up that we shouldn't waste time arguning about how to make it better? -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 29 Jan 86 15:05:52 EST Received: from SEISMO.CSS.GOV by SU-AI.ARPA with TCP; 29 Jan 86 10:38:08 PST Return-Path: Received: from mcvax.UUCP by seismo.CSS.GOV with UUCP; Wed, 29 Jan 86 13:09:37 EST From: mcvax!nplmg1a.uucp!jrp@seismo.CSS.GOV Received: by mcvax.uucp; Wed, 29 Jan 86 18:43:01 +0100 (MET) Received: by mcvax.uucp; Wed, 29 Jan 86 18:42:49 +0100 (MET) Received: from nplmg1a.uucp by eagle.Ukc.AC.UK with UUCP id a000367; 29 Jan 86 16:44 GMT To: common-lisp@su-ai.arpa Subject: Floating Point Computation Return-Receipt-To: mcvax!nplmg1a.uucp!jrp@seismo.CSS.GOV Date: 29 Jan 86 16:38:25 GMT (Wed) Message-Id: <1000.507400705@nplmg1a> I hope that the following paper will put final rest to the speculations on floating point arithmetic:- Brown, W.S., A Simple but Realistic Model of Floating-Point Computation, ACM Transactions on Mathematical Software Vol. 7 No. 4, Dec 81. (Material is also to be found in the ADA reference manual) Do not assume that the arithmetic on your machine is implemented correctly (in hardware). Do not assume (particularly for UNIX-based systems) that the text -> internal conversion routines are any good. Do not assume that the elementary functions are any good on your machine. You will not go far wrong! John Pavel  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 29 Jan 86 14:54:41 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 29 Jan 86 11:43:55 PST Date: Wed, 29 Jan 86 14:45:27 EST From: Jonathan A Rees Subject: DEFUN inside LET To: common-lisp@SU-AI.ARPA In-reply-to: Msg of Tue 28 Jan 1986 23:12 EST from Scott E. Fahlman Message-ID: <[MC.LCS.MIT.EDU].800572.860129.JAR> Date: Tue, 28 Jan 1986 23:12 EST From: Scott E. Fahlman I'm not sure if there's actually a firm consensus on this, but in my opinion Defun inside Let should always work. It's an idiom I use a lot, and if some alleged Common Lisp didn't supply this, I'd either complain or fix it myself. I don't understand how one can argue with p. 67 of CLtL which (to me) unequivocally says that DEFUN inside LET should "work": "Evaluating a DEFUN form causes the symbol ... to be a global name for the function specified by the LAMBDA-expression ... in the lexical environment in which the DEFUN form was executed." Also, since DEFUN is a macro, it's hard to imagine what it could expand into in order to behave much differently from this.