Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Apr 86 23:16:57 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 30 Apr 86 20:06:49 PDT Received: ID ; Wed 30 Apr 86 23:07:40-EDT Date: Wed, 30 Apr 1986 23:07 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: SANDRA Cc: common-lisp@SU-AI.ARPA Subject: editing a function definition In-reply-to: Msg of 30 Apr 1986 14:50-EDT from SANDRA The manual says that doing (ed ) lets you edit the text for the function named , but it doesn't say what happens to it once you've left the editor. Is the definition replaced by whatever you did in the editor? If so, are other forms you added while in the editor evaluated too? Also, the manual leaves open the possibility of searching the file system for the file containing the original definition of the function. Does this mean that the entire file may be passed to the editor, or should the definition of that one function be extracted from the file instead? All of this is totally up to the implementor of the Lisp environment. In fact, implementing ED is optional. The only purpose of including this function is to provide a standard way of getting over to the editor to edit the source for a given function, IF that sort of operation makes sense in your implementation. My own opinion (none of which is or should be in the Common Lisp spec) is that an Emacs-like editor ought to zap you over to the right place in the right file. I don't much care if it sets up buffer bounds around the function, but it should be easy to get loose and edit other stuff in the file. Facilities must be provided for moving the just-edited function and any number of other forms back into the Lisp. I have no opinions about what an Interlisp-like in-core editor should do. -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Apr 86 19:03:31 EDT Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 30 Apr 86 15:52:37 PDT Date: 30 Apr 1986 18:55-EDT Sender: NGALL@G.BBN.COM Subject: Re: FUNCTION and MACROLET From: NGALL@G.BBN.COM To: Common-Lisp@SU-AI.ARPA Message-ID: <[G.BBN.COM]30-Apr-86 18:55:25.NGALL> In-Reply-To: Date: Wed, 30 Apr 1986 17:44 EDT From: Rob MacLachlan To: NGALL@BBNG.ARPA Subject: FUNCTION and MACROLET In-Reply-To: Msg of 30 Apr 1986 10:28-EDT from NGALL at G.BBN.COM Message-ID: To me, it isn't an obvious clarification that FUNCTION can return strange objects. I always though of function as causing "functional evaluation", and would always result in a callable object. Are people really suggesting that the compiler should arrange to compile and dump macrolet functions? Is this legal? (defun def-a-macro (name) (macrolet ((foo (a b) `(cons ,a ,b))) (setf (symbol-function name) #'foo))) Of course, if the manual is interpreted as saying that *nothing* is guaranteed about what symbol-function returns in the non-function case, then the compiler could compile the FUNCTION call so that it returned something totally random. Unless more is guaranteed about what SYMBOL-FUNCTION does in the non-function case, this option is useless. I think it would better to say that it is an error to call SYMBOL-FUNCTION on any symbol which isn't the name of a function. Sensibly, it is illegal to do anything with a special-form object, and it is much more tasteful to manipulate macro definitions using MACRO-FUNCTION, so it seems that the ability to call SYMBOL-FUNCTION on non-functions it worthless. And it we change SYMBOL-FUNCTION in this way, then it would be consistent with what FUNCTION already does in Spice Lisp. Rob -------------------- I agree that SYMBOL-FUNCTION should be redefined so that "it is an error" to give it a symbol that is fbound as a macro or special-form and that FUNCTION be defined analogously. That will require an incompatible change to the language, whereas Guy's clarification (which I was merely interpreting, not supporting) does not. I am in favor of such a change, but then I don't have to implement it. -- Nick  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Apr 86 17:55:42 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 30 Apr 86 14:43:55 PDT Received: ID ; Wed 30 Apr 86 17:44:20-EDT Date: Wed, 30 Apr 1986 17:44 EDT Message-ID: From: Rob MacLachlan To: NGALL@BBNG.ARPA Cc: Common-Lisp@SU-AI.ARPA, nttlab!kurims!yuasa@SU-SHASTA.ARPA Subject: FUNCTION and MACROLET In-reply-to: Msg of 30 Apr 1986 10:28-EDT from NGALL at G.BBN.COM To me, it isn't an obvious clarification that FUNCTION can return strange objects. I always though of function as causing "functional evaluation", and would always result in a callable object. Are people really suggesting that the compiler should arrange to compile and dump macrolet functions? Is this legal? (defun def-a-macro (name) (macrolet ((foo (a b) `(cons ,a ,b))) (setf (symbol-function name) #'foo))) Of course, if the manual is interpreted as saying that *nothing* is guaranteed about what symbol-function returns in the non-function case, then the compiler could compile the FUNCTION call so that it returned something totally random. Unless more is guaranteed about what SYMBOL-FUNCTION does in the non-function case, this option is useless. I think it would better to say that it is an error to call SYMBOL-FUNCTION on any symbol which isn't the name of a function. Sensibly, it is illegal to do anything with a special-form object, and it is much more tasteful to manipulate macro definitions using MACRO-FUNCTION, so it seems that the ability to call SYMBOL-FUNCTION on non-functions it worthless. And it we change SYMBOL-FUNCTION in this way, then it would be consistent with what FUNCTION already does in Spice Lisp. Rob  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Apr 86 16:51:49 EDT Received: from A.CS.CMU.EDU by SU-AI.ARPA with TCP; 30 Apr 86 13:40:11 PDT Date: Wed, 30 Apr 86 15:25 EDT From: David.Dill@A.CS.CMU.EDU (C410DD60) To: common-lisp@SU-AI.ARPA Subject: readtables & packages Message-Id: <30Apr86.152509.DD60@A.CS.CMU.EDU> As far as I'm concerned, associating readtables with packages is a bad heuristic for always having the right readtable in effect. Also, in my experience, the problem for which this solution is proposed does not arise very often, nor is it particularly troublesome. The package system was designed for structuring large systems -- the fact that it is handy for embedding other dialects of lisp or entirely different programming languages is gravy. People who take it upon themselves to have a variety of readtables in simultaneous use can also make the extra effort to add facilities for switching between them conveniently. Are you folks even talking about the common lisp package system? All this discussion about hierarchies makes it sound more like the lisp machine package system.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Apr 86 15:19:26 EDT Received: from [192.10.41.223] by SU-AI.ARPA with TCP; 30 Apr 86 11:54:34 PDT Received: from FIREBIRD.SCRC.Symbolics.COM by SAPSUCKER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 13400; Wed 30-Apr-86 14:52:18 EDT Date: Wed, 30 Apr 86 14:51 EDT From: David C. Plummer Subject: Readtables To: Brad Miller , DCP@SCRC-QUABBIN.ARPA cc: GJC@MC.LCS.MIT.EDU, common-lisp@SU-AI.ARPA In-Reply-To: <8604301804.2438@ur-seneca.rochester.arpa> Message-ID: <860430145111.9.DCP@FIREBIRD.SCRC.Symbolics.COM> Just one quickie. After this, you and I have probably said as much as we can say to each other, and more input is needed from the rest of the community. I wasn't suggesting A:@*foo-readtable*!foo I was suggesting A@!foo where the A@ put the reader into program A's context, which includes package, readtable and whatever else.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Apr 86 15:11:03 EDT Received: from UTAH-20.ARPA by SU-AI.ARPA with TCP; 30 Apr 86 11:51:14 PDT Date: Wed 30 Apr 86 12:50:32-MDT From: SANDRA Subject: editing a function definition To: common-lisp@SU-AI.ARPA Message-ID: <12203009007.11.LOOSEMORE@UTAH-20.ARPA> The manual says that doing (ed ) lets you edit the text for the function named , but it doesn't say what happens to it once you've left the editor. Is the definition replaced by whatever you did in the editor? If so, are other forms you added while in the editor evaluated too? Also, the manual leaves open the possibility of searching the file system for the file containing the original definition of the function. Does this mean that the entire file may be passed to the editor, or should the definition of that one function be extracted from the file instead? -Sandra -------  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Apr 86 14:48:47 EDT Received: from ROCHESTER.ARPA by SU-AI.ARPA with TCP; 30 Apr 86 11:27:06 PDT Received: from ur-seneca.rochester.arpa (ur-seneca) by ur-cayuga.rochester.arpa id AA00377 (4.12w); Wed, 30 Apr 86 14:27:28 edt Received: by ur-seneca.rochester.arpa id AA02438 (4.12w); Wed, 30 Apr 86 14:04:57 edt Message-Id: <8604301804.2438@ur-seneca.rochester.arpa> Date: Wed, 30 Apr 86 14:04:57 edt From: Brad Miller(Tech. Ops. Mgr) To: DCP@SCRC-QUABBIN.ARPA Cc: lab@rochester.arpa, DCP@SCRC-QUABBIN.ARPA, GJC@MC.LCS.MIT.EDU, common-lisp@SU-AI.ARPA In-Reply-To: David C. Plummer's message of Wed, 30 Apr 86 13:19 EDT Subject: Readtables Well, more answers, as usual, bring more questions.... A purely environmental work-around might be to set the readtable in different listeners differently. This doesn't help you 'break out' of the readtable into another program's readtable, however. I suspect the least confusing thing would be to have some syntax to break out on a local (single string) level rather than until an escape, e.g. (similar to before the ! macro) (pkg-goto 'USER) ;no macros (!foo A:!foo !foo) ;1st and 3rd do not use macro, A:!foo does if A: has defined it. Now, we may want to say: (!foo A:@*foo-readtable*!foo !foo) but my feeling is that this sort of explict declaration of readtables is rather clumsy at best, at least for 'normal' usage. Having such a mechanism exist is probably a good idea though. Part of the problem with distinguishing readtables and languages from packages is that languages are ALSO designed with their own packages. (Since they must inherit the meanings of their constructs from some 'definitional' package - e.g. CL for common-lisp on Symbolics.) It seems like it would be less confusing to a USER if they were associated a little closer. Now, you are quite correct in what you are about to say: that if I try to invoke some function in CL from Zetalisp, I should not have to say CL:frozzbozz where frozzbozz is in the CL dialect - I should just have to name the function in that package, which is where your distinction has appeal. Let me give another example which illuminates the problem more succinctly: Say I write a program using the macro #\!. Since I don't want a separate 'listener' or any other such reader for this program, I define it in the default readtable. It gets saved in the world. Naive user #1 comes up to use the machine and decides his variables should all start with !. Silly Luser! He gets his variables clobbered by the macro defined in my package, even though my package is NOT part of USER, :USEd by USER, or anything else. Yet hack user #2 comes up t the machine and happily calls functions in my FOO: package, knowing his !'s will all be interpreted appropriately, even though his default package is USER. The thing that will be the most obvious to both users is to have the macro invocation local to the package. Luser 1 doesn't lose, and doesn't even have to know about the existance of !. Hacker 2 still wins big because whenever he invokes the FOO: package, he gets it's readtable. Luser 1 is still served if we have a separate syntax for defining readtables - ignorance is bliss. Hacker 2 is served, but irritated perhaps, because he feels he is forced to supply redundant information (you and I realize it isn't but still). Maybe the 'real' solution is to support package names, readtable names, and a way to set both with a single (new) name? Just more incremental thoughts. Think the idea of putting extension on -*- line for readtable solves THAT problem quite nicely. Hope symbolics reads this mailing list and picks up on that! B  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Apr 86 13:41:46 EDT Received: from [192.10.41.223] by SU-AI.ARPA with TCP; 30 Apr 86 10:22:53 PDT Received: from FIREBIRD.SCRC.Symbolics.COM by SAPSUCKER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 13326; Wed 30-Apr-86 13:20:37 EDT Date: Wed, 30 Apr 86 13:19 EDT From: David C. Plummer Subject: Readtables To: Brad Miller cc: DCP@SCRC-QUABBIN.ARPA, GJC@MC.LCS.MIT.EDU, common-lisp@SU-AI.ARPA In-Reply-To: <8604301601.29900@ur-seneca.rochester.arpa> Message-ID: <860430131930.8.DCP@FIREBIRD.SCRC.Symbolics.COM> I don't have any good answers for you right now, but I do have some comments. Your message does illustrate the issue quite well, thanks. It could be argued that a different readtable is really implementing a parser for a different language. Indeed, the Symbolics implementatin supports two languages on the same machine: Zetalisp and Symbolics Common Lisp. They do have different readtables and they also have different package hierarchies. There is a command (Set Lisp Syntax, I think) I think that selects between the two and sets up all the necessary environment variables, which include package and readtable. The editor also knows about this. This point of view says there should be a concept of a 'language' which is the right collection of 'things'. This thing of yours, however: (pkg-goto 'USER) (pkg-goto 'A) would definitely be part of the language. I'm not sure I like it though because it is very surprising behavior (based on today's paradigms). As for your doing development on two or more programs, I think if the compiler and loader bound *readtable* around the compile/load operation, then you wouldn't have any problem because CLtL's development paradigm is file-at-a-time operations. This leaves two major areas, I think: incremental development (which is programming environment) and using the two programs (which isn't, or is at least fuzzy). Incremental development usually means incremental editing and compiling out of the editor buffer. Here it would be nice if the editor knew what the necessary variables in order to understand the language are. This could be an extension to the -*- line to the systems that do such things. Using the programs, or typing to "its reader" is the unclear issue for me. Currently, FOO: affects the translation from strings to symbols, and you want it to affect the parsing of text at a more global level. I think that might be a useful thing, but I don't think : is the place to put it, but instead something else (@?). There is the question: Should this affect the next form in that parser's language or should it affect all forms until an escape in the other language switches back or out?  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Apr 86 12:36:11 EDT Received: from ROCHESTER.ARPA by SU-AI.ARPA with TCP; 30 Apr 86 09:26:59 PDT Received: from ur-seneca.rochester.arpa (ur-seneca) by ur-cayuga.rochester.arpa id AA01089 (4.12w); Wed, 30 Apr 86 08:22:51 edt Received: by ur-seneca.rochester.arpa id AA29900 (4.12w); Wed, 30 Apr 86 12:01:53 edt Message-Id: <8604301601.29900@ur-seneca.rochester.arpa> Date: Wed, 30 Apr 86 12:01:53 edt From: Brad Miller(Tech. Ops. Mgr) To: DCP@SCRC-QUABBIN.ARPA Cc: GJC@MC.LCS.MIT.EDU, lab@rochester.arpa, common-lisp@SU-AI.ARPA In-Reply-To: David C. Plummer's message of Wed, 30 Apr 86 08:59 EDT Subject: Readtables OK, let me redefine the original problem. Maybe this 'makes' it an environment issue. Given that I have two or more programs under development. Why should my defining a macro in one program have an effect on the other? Currently it does because I have changed the default readtable. Changing my package from one program's package to the other program's package used to be sufficent for a 'context switch' but now I also have to change readtables. What I was suggesting is that the readtable was defined inside of a package, and in some sense should be part of that package. i.e. if I change the default readtable, I am really changeing the default FOR A PACKAGE. Packages are very much like contexts. If I have a package that has an ancestor, it should inherit the default readtable from that ancestor. If I redefine the default readtable, I do it locally, not to the ancestor (unless I do so explicitly). Note that this is just a change to the DEFAULT readtable mechanism, and does not constitute a change to other mechanisms already present. If a prlog user wants to write code in the USER package, that's fine, and he can use the prolog readtable. When he changes to the CL package, he shouldn't still be stuck with the prolog readtable, however, (and have to do something explicit to change it). Now you could argue that I shouldn't be altering the default readtable at all, and changing the readtable depending on the task involved (rather than just changing packages, or whatever). But consider this, given two programs in package A and B, where A has a macro bound to #\! and B does not, this is what would be nice: (pkg-goto 'USER) (pkg-goto 'A) Note that this does not imply any change to the way readtables or referenced. If mI want to talk about a readtable explitily, I may still want to use variable, but each package might have associated with it a variable *default-readtable*, and it is inheritable if it is defined. Now I will totally agree that whether this is a basic/advanced/toplevel etc. issue is unclear to me. All I am stating is that I think there is a need to do this sort of thing; it would be nice that if everyone who said they supported CL supported this. Also, does anyone else think similar thoughts, or am I out in left field, since there are other existing easy ways to do this sort of thing, and/or it has no business being in the CL language? Brad Miller ARPA: lab@rochester.arpa UUCP:rochester!lab (also miller@rochester for grad student stuff) Title: CS Technical Operations Manager Snail: University of Rochester Computer Science Department 617 Hylan Building Rochster, NY 14627  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Apr 86 10:36:45 EDT Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 30 Apr 86 07:26:35 PDT Date: 30 Apr 1986 10:28-EDT Sender: NGALL@G.BBN.COM Subject: Re: FUNCTION and MACROLET From: NGALL@G.BBN.COM To: nttlab!kurims!yuasa@SU-SHASTA.ARPA Cc: Common-Lisp@SU-AI.ARPA Message-ID: <[G.BBN.COM]30-Apr-86 10:28:34.NGALL> In-Reply-To: <8605010119.AA00467@kurims.kyoto-u.junet> Date: Wed, 30 Apr 86 18:19:24 pdt From: yuasa@kurims.kurims.kyoto-u.junet To: nttlab!Common-Lisp@SU-AI Message-ID: <8605010119.AA00467@kurims.kyoto-u.junet> 87 Rewrite the second sentence in the description of FUNCTION as follows: "In particular, if fn is a symbol, then the functional definition of that name is returned, which is that established by the innermost lexically enclosing FLET, LABELS, or MACROLET construct, if there is one, or else the global functional definition of the symbol (see SYMBOL-FUNCTION)." Is this sentense really intended to require that (FUNCTION FOO) in the body of (MACROLET ((FOO . )) ...) should return the macroexpansion function of the local macro FOO? No. (FUNCTION FOO) in the body of a (MACROLET ((FOO... should return "an object representing a ... macro ... it is an error to attempt to invoke the object as a function" (cf. SYMBOL-FUNCTION, pg. 90). (FUNCALL (MACROLET ((FOO (X) `(LIST ,X ,X))) (FUNCTION FOO)) '(FOO (BAR))) Thus this example is not legal common lisp. If this is really the case, then what are the merits of this mechanism? The behavior of FUNCTION when given the name of a local function/macro should be consistent with its behavior when given the name of a global function/macro, and the behavior of FUNCTION when given the name of a global function/macro/special-form should be consistent with the behavior of SYMBOL-FUNCTION when given the name of a global function/macro/special-form. I think this is what Guy's proposed clarification is trying to get across. -- Taiichi (one of the implementors of Kyoto Common Lisp) (nttlab!kurims!yuasa@su-shasta.arpa) -------------------- -- Nick  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Apr 86 09:12:01 EDT Received: from [192.10.41.223] by SU-AI.ARPA with TCP; 30 Apr 86 06:03:05 PDT Received: from FIREBIRD.SCRC.Symbolics.COM by SAPSUCKER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 13169; Wed 30-Apr-86 09:01:02 EDT Date: Wed, 30 Apr 86 08:59 EDT From: David C. Plummer Subject: Readtables To: George J. Carrette , Brad Miller cc: common-lisp@SU-AI.ARPA In-Reply-To: <[MC.LCS.MIT.EDU].897993.860428.GJC>, <8604290138.13994@ur-seneca.rochester.arpa> Message-ID: <860430085956.3.DCP@FIREBIRD.SCRC.Symbolics.COM> Date: Mon, 28 Apr 86 20:01:23 EDT From: "George J. Carrette" NIL and the MIT/LMI-LISPM system had just such a mechanism, named readtables. (GET-READTABLE-NAMED "Maclisp") would be analogous to (FIND-PACKAGE "Maclisp"). The mechanism was invoked by the good-old file mode line: ;;;-*-mode:lisp;readtable:maclisp;base:10-*- I suppose we will have to wait for the gods-on-high, er, I mean Symbolics REL7, before any discussion of "environment issues" can progress however. We all wait, breathless. Give us all a break, George. You used to, and possibly still do but I can't tell since your mail originates from MIT, work for one of Symbolics' comercial competitors whose system has the same roots as Symbolics'. The reason Symbolics people ask others to be careful about the distinction between language and programming environment is because we think about it every day as part of our work. People at LMI, Xerox and others probably do too. People at Lucid (possibly the other end of the spectrum) probably don't because their current business is to produce a powerful compiler. This also has nothing to do with releases. We need to decide what is part of Common Lisp, the Language. With the multidimensional designations I've seen for the ISO Common Lisp, we need to be even more specific. Not only do we need to know if it is language or environment, but we have to know what level (substrate, basic, advanced, toplevel, etc) of each it is. Date: Mon, 28 Apr 86 21:38:33 edt From: Brad Miller(Tech. Ops. Mgr) So you feel this is an environment issue rather than a language design issue? I would think the need and the solution (at least a proposed solution of formally folding it into packages) could be addressed at the language level: gives us portability of code; forces all vendors to address the problem, and other nice side effects... A few questions: Why should readtables be folded into packages? Consider the following, not too far-fetched, duple: - What's wrong with using a prolog readtable with the USER package? The implication is that the user is writing code for the USER package, but the code is being written in prolog! - What's wrong with using a CL readtable in the PROLOG-USER package (which normally uses a prolog read-table)? The implication here is that a prolog user is writing code, but is writing it in Common Lisp. The current main differences between the interfaces to readtable and packages that I can think of off the top of my head are the following. (1) Packages are globally named and seldom stored in variables, whereas readtables are not generally named but are stored in variables. (1a) To find a package one generally uses (find-package ). To find a readtable one generally uses *foo-readtable*. (2) Packages cannot be copied for the purpose of modification. Readtables can, and this mechanism exists. (3) Because of (1) and (2), packages determine the identity of symbols for the lifetime of the incarnation of the Lisp in which they exist (which includes saving worlds and rebooting, etc). Symbols are rather permanent in this sense. Readtables, on the other hand, determine how TEXT is parsed into LISP. By changing the readtable you can alter the parsing. There aren't any "reasonable" ways to meaningfully alter packages to get similar effects. (4) If packages did not have names, we would be writing symbols as *foo-package*:print-name instead of foo:print-name. But since this IS THE TEXT it is divorced from the readtable. We currently don't have a way to say #@Maclisp ...maclisp-form.... (5) The effects of in-package are the dynamic extent of the load operation of the file (see page 183). I couldn't find an equivalent thing for *readtable*. I personally don't have any problems with (1), (2) or (3). I think the current readtable paradigm is sufficient and adequate. Regarding (5), I will cast a vote that the effects of (eval-when (eval load compile) (setq *readtable* *my-readtable*)) have the dynamic extent of the load operation in the same way in-package does. I will also cast a vote that a form should be considered to capture the above notion. Regarding (4), we need to decide if we want to add some functionality to readtables that are parallel to packages. Do we want to globally name readtables? Do we want an in-band way to change the readtable for one or more forms? The package system has its roots in experience, and it still has problems. Do people have enough experience with readtables to feel comfortable about any of these issues?  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Apr 86 08:20:05 EDT Received: from SU-SHASTA.ARPA by SU-AI.ARPA with TCP; 30 Apr 86 05:12:32 PDT Received: by su-shasta.arpa with TCP; Wed, 30 Apr 86 05:12:33 pdt Received: by ntt.junet (4.12/4.7JC-7) CHAOS with CHAOS-MAIL id AA19453; Wed, 30 Apr 86 17:22:38 jst From: yuasa@kurims.kurims.kyoto-u.junet Received: by kurims.kyoto-u.junet (2.0/4.7) id AA00467; Wed, 30 Apr 86 18:19:24 pdt Date: Wed, 30 Apr 86 18:19:24 pdt Message-Id: <8605010119.AA00467@kurims.kyoto-u.junet> To: nttlab!Common-Lisp@SU-AI The following is the text, verbatim, of the other handout I made available this past Monday at the Common Lisp meeting. ---------------------------------------------------------------------- Corrections to first printing of Common Lisp: The Language Thanks to the many people who noticed these problems, and especially to Dr. Masayuki Ida, who found over fifty of them. -- Guy Steele, December 1985 ......... 87 Rewrite the second sentence in the description of FUNCTION as follows: "In particular, if fn is a symbol, then the functional definition of that name is returned, which is that established by the innermost lexically enclosing FLET, LABELS, or MACROLET construct, if there is one, or else the global functional definition of the symbol (see SYMBOL-FUNCTION)." ......... Is this sentense really intended to require that (FUNCTION FOO) in the body of (MACROLET ((FOO . )) ...) should return the macroexpansion function of the local macro FOO? For example, should (FUNCALL (MACROLET ((FOO (X) `(LIST ,X ,X))) (FUNCTION FOO)) '(FOO (BAR))) evaluate to (LIST (BAR) (BAR)) ? If this is really the case, then what are the merits of this mechanism? For your information, Kyoto Common Lisp just ignores local macro definitions when evaluating FUNCTION special forms. The version of Spice Lisp which I received in April 1985 causes an error if in (FUCNTION ) names a local macro. -- Taiichi (one of the implementors of Kyoto Common Lisp) (nttlab!kurims!yuasa@su-shasta.arpa)  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 28 Apr 86 21:51:15 EDT Received: from ROCHESTER.ARPA by SU-AI.ARPA with TCP; 28 Apr 86 18:38:24 PDT Received: from ur-seneca.rochester.arpa (ur-seneca) by ur-cayuga.rochester.arpa id AA11693 (4.12w); Mon, 28 Apr 86 17:37:52 edt Received: by ur-seneca.rochester.arpa id AA13994 (4.12w); Mon, 28 Apr 86 21:38:33 edt Message-Id: <8604290138.13994@ur-seneca.rochester.arpa> Date: Mon, 28 Apr 86 21:38:33 edt From: Brad Miller(Tech. Ops. Mgr) To: GJC@MC.LCS.MIT.EDU Cc: lab@rochester.arpa, common-lisp@SU-AI.ARPA In-Reply-To: "George J. Carrette"'s message of Mon, 28 Apr 86 20:01:23 EDT Subject: Readtables So you feel this is an environment issue rather than a language design issue? I would think the need and the solution (at least a proposed solution of formally folding it into packages) could be addressed at the language level: gives us portability of code; forces all vendors to address the problem, and other nice side effects... Brad Miller  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 28 Apr 86 20:16:14 EDT Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 28 Apr 86 16:59:45 PDT Date: Mon, 28 Apr 86 20:01:23 EDT From: "George J. Carrette" Subject: Readtables To: lab@ROCHESTER.ARPA cc: common-lisp@SU-AI.ARPA In-reply-to: Msg of Mon 28 Apr 86 17:27:21 edt from Brad Miller(Tech. Ops. Mgr) Message-ID: <[MC.LCS.MIT.EDU].897993.860428.GJC> NIL and the MIT/LMI-LISPM system had just such a mechanism, named readtables. (GET-READTABLE-NAMED "Maclisp") would be analogous to (FIND-PACKAGE "Maclisp"). The mechanism was invoked by the good-old file mode line: ;;;-*-mode:lisp;readtable:maclisp;base:10-*- I suppose we will have to wait for the gods-on-high, er, I mean Symbolics REL7, before any discussion of "environment issues" can progress however. We all wait, breathless.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 28 Apr 86 17:37:16 EDT Received: from ROCHESTER.ARPA by SU-AI.ARPA with TCP; 28 Apr 86 14:26:40 PDT Received: from ur-seneca.rochester.arpa (ur-seneca) by ur-cayuga.rochester.arpa id AA09597 (4.12w); Mon, 28 Apr 86 13:27:05 edt Received: by ur-seneca.rochester.arpa id AA09514 (4.12w); Mon, 28 Apr 86 17:27:21 edt Message-Id: <8604282127.9514@ur-seneca.rochester.arpa> Date: Mon, 28 Apr 86 17:27:21 edt From: Brad Miller(Tech. Ops. Mgr) To: common-lisp@su-ai.arpa Subject: Readtables I have a question about readtables. Forgive me if this is an already discussed topic. I have a program, in package FOO. It sets a macro character via (set-macro-character) using the default readtable. Problem: now all programs on the machine will call the macro function regardless of whether they USE the package. One solution: do (set-macro-character char function nil (setq my-readtable (copy-readtable nil))) which will put it in a readtable "separate" from everyone elses. Problem: have no way of determining when the "new" readtable should be used. Either have to have separate read loop just for this program, or do something else crufty like recognize the current default package isn't the one we want. It seems, at first blush, the desired feature would be to somehow associate readtables with packages. That is, if the readtable I use is associated with my current package, my current problem is solved. This seems pretty general. Hierarchical packages would also have hierarchical readtables. You could still change readtables while IN a package, but the big win is on most machines, making the package with your program in it (or a child of that one) the default means your macro is in effect. Packages which do not inherit from your special one won't know about your macro. Thanks for your help, Brad Miller Brad Miller ARPA: lab@rochester.arpa UUCP:rochester!lab (also miller@rochester for grad student stuff) Title: CS Technical Operations Manager Snail: University of Rochester Computer Science Department 617 Hylan Building Rochster, NY 14627  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 28 Apr 86 12:15:53 EDT Received: from HPLABS.ARPA by SU-AI.ARPA with TCP; 28 Apr 86 09:00:15 PDT Received: from hplsny by hplabs.ARPA ; Mon, 28 Apr 86 09:01:04 pdt Received: by hplsny ; Mon, 28 Apr 86 09:00:47 pdt From: Alan Snyder Message-Id: <8604281600.AA00138@hplsny> Date: Monday, April 28, 1986 09:00:36 Subject: Re: with-output-to-string To: Moon@SCRC-STONY-BROOK.ARPA Cc: common-lisp@su-ai.ARPA In-Reply-To: Your message of 23-Apr-86 22:31:00 X-Sent-By-Nmail-Version: 04-Nov-84 17:14:46 In some implementations WITH-OUTPUT-TO-STRING does not work by calling MAKE-STRING-OUTPUT-STREAM, since the former stream has dynamic extent and the latter stream has indefinite extent. That makes sense, but the ability for a user to create an output stream to an existing string would still be useful. The extension I think you are proposing is reasonable as an extension. Do you propose that GET-OUTPUT-STREAM-STRING be allowed on that type of stream? That is not required, but would seem useful. -------  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 28 Apr 86 10:53:17 EDT Received: from HUDSON.DEC.COM by SU-AI.ARPA with TCP; 28 Apr 86 07:44:51 PDT Date: 28 Apr 86 10:36:00 EST From: "BACH::GREEK" Subject: Environment Query Functions. To: "common-lisp" Reply-To: "BACH::GREEK" I think the watchword is "short and sweet" as far as the environment query functions are concerned. Here's what we do for VAX LISP. LISP-IMPLEMENTATION-TYPE is "VAX LISP". LISP-IMPLEMENTATION-VERSION is something like "V2.0". MACHINE-TYPE is the machine name, like "DEC VAX 11/780" "DEC VAXstation II". MACHINE-VERSION is tough to call, so we return the SID register, which uniquely identifies the CPU. Not so great. MACHINE-INSTANCE is setable by the system manager/user. SOFTWARE-TYPE is "VMS" or "ULTRIX". SOFTWARE-VERSION is whatever the operating system says its version is. SHORT-SITE-NAME & LONG-SITE-NAME is setable by the system manager/user. In particular, we felt in the three cases where it's setable that we just couldn't guess what it ought to be. - Paul ------  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 27 Apr 86 18:52:49 EDT Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 27 Apr 86 15:43:58 PDT Received: from HUMMINGBIRD.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 473377; Sun 27-Apr-86 18:43:05-EDT Date: Sun, 27 Apr 86 18:44 EDT From: Kent M Pitman Subject: SOFTWARE-TYPE, SOFTWARE-VERSION, ... To: Fahlman@C.CS.CMU.EDU cc: Common-Lisp@SU-AI.ARPA References: , <8604260647.AA14901@ntt.junet> Message-ID: <860427184404.3.KMP@HUMMINGBIRD.SCRC.Symbolics.COM> While we're on the subject, let me say that my experience in trying to port Macsyma has suggested that we have not been specific enough in the description of what SOFTWARE-TYPE should return for it to be very useful even in the range of things for which I think it was intended. For example,... LISP-IMPLEMENTATION-TYPE Not enough examples are given to figure out what this might return. I believe this should have been defined as the vendor. It's dumb for a 3600 to respond "Zetalisp" since the trend on the 3600 is for Zetalisp to be supported as a Common Lisp compatibility thing and not vice versa. Because the manual cites the example of "Zetalisp", it's hard to imagine us not returning that value. I still think it should return "Symbolics". Also, it doesn't say whether the word "lisp" will get included. It leaves one open to return "Franz" or "Lucid". It would have been better to actually give an example sentence into which the result of functions like this item should have fit. eg, (FORMAT T "~&This is the ~A implementation of Common Lisp." (LISP-IMPLEMENTATION-TYPE)) LISP-IMPLEMENTATION-VERSION Some lisps return something fairly short so you could imagine doing: (FORMAT T "~&This is Macsyma in ~A ~A." (LISP-IMPLEMENTATION-TYPE) (LISP-IMPLEMENTATION-VERSION)) but it isn't suggested that this might be something you'd want to do so the 3600 Release 6 implementation I'm running returns something like: "Release 6.1, System 271.216, Hardcopy 46.34, Zmail 107.25, Experimental Something 12.36, IP-TCP 29.13, SCRC 5.26, Something Else 60.0, Experimental Something More 389.0, microcode IFU-IO4-XSQ-COL-MIC 353, FEP 127, FEP0:>v127-lisp.flod(4), FEP0:>v127-loaders.flod(4), FEP0:>v127-i-cache.flod(29), FEP0:>v127-debug.flod(10), FEP0:>v127-info.flod(4)" and it would look really yucky to use that format string because of the line over-run that would result. MACHINE-TYPE This is one of the only things that I think is adequately constrained. MACHINE-VERSION This isn't very well-constrained. For example, I can't imagine writing (FORMAT T "This is Common Lisp on a ~A ~A" (MACHINE-TYPE) (MACHINE-VERSION)) even with the examples you've given. eg, it might come out as: "This is Common Lisp on a DEC PDP-10 KL10, microcode 9" In other words, isn't "KL10" part of the machine-type, not the version? Maybe it's really well-formed -- I've just never seen it referred to that way. Again, saying in the documentation that operations like the FORMAT I've just given should produce meaningful, non-cluttered output would be very handy. MACHINE-INSTANCE It was dumb given that any of these operations can return NIL if it doesn't have something meaningful to return to say that this could return either a serial number or a host-id. We should have had a HOST-NAME and a MACHINE-UNIQUE-ID. The former should have returned the host name for the purpose of things like (FORMAT T "~&From: ~A@~A~%" (USER-ID) ;we forgot to include this but it should be added (HOST-NAME)) SOFTWARE-TYPE It doesn't indicate at what level the supporting software is. eg, your examples seem to imply that you want the operating system type. What if LUCID had a lisp that ran under VMS. Would you want "VMS", "DEC", or "LUCID"? If you can't be specific about this, then how can you expect it to be meaningfully used in portable code? We return "Lisp Machine", which seems pretty random, but I'm not sure what we could do that is better. SOFTWARE-VERSION This suffers from the same vagueness problems. We return "Pre-release Symbolics Common Lisp" in Release 6. What can I do with this? I can write: (FORMAT T "~&You are being supported by ~A ~A" (SOFTWARE-TYPE) (SOFTWARE-VERSION)) Can you imagine how well this will port? On our implementation, this will produce: You are being supported by Lisp Machine Pre-release Symbolics Common Lisp. which looks pretty dumb... and that's using it in the least committal way possible. Imagine if I wanted to include it into any other output in a more specific way. SHORT-SITE-NAME LONG-SITE-NAME Nothing specifies whether "site" means "host" or "community". The Symbolics community distinguishes these terms. A site to us would be like "MIT" or the "MIT AI Lab". A host is a specific machine at a site. I'm told by friends at DEC that (SHORT-SITE-NAME) is treated more like "host". Without standardizing on this term, the description is fairly meaningless. I was amazingly disappointed when I found out how poorly these were specified and how little-useful they were going to be in portable code. The only way I can think to use this information in a portable way is to do: (FORMAT T "Random debugging data:~{~@[~%~1{~A: ~A~}~]~}" (MAPCAR #'(LAMBDA (X) (LET ((Y (FUNCALL X))) (IF Y (LIST X Y)))) '(LISP-IMPLEMENTATION-TYPE LISP-IMPLEMENTATION-VERSION ...))) That's pretty weak.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 27 Apr 86 14:59:39 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 27 Apr 86 11:52:46 PDT Received: ID ; Sun 27 Apr 86 14:53:50-EDT Date: Sun, 27 Apr 1986 14:53 EDT Message-ID: From: Rob MacLachlan To: Pavel.pa@XEROX.COM Cc: Common-Lisp@SU-AI.ARPA Subject: macro-let and *macroexpand-hook* In-reply-to: Msg of 26 Apr 1986 21:12-EST from Pavel.pa at Xerox.COM I believe that there wouldn't be any problem if MACRO-FUNCTION took an optional environment arg. Of course, it would be illegal to set the value of a lexical macro. Rob  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 26 Apr 86 21:40:39 EST Received: from XEROX.COM by SU-AI.ARPA with TCP; 26 Apr 86 18:32:52 PST Received: from Cabernet.ms by ArpaGateway.ms ; 26 APR 86 18:30:58 PST Date: 26 Apr 86 18:12 PST From: Pavel.pa@Xerox.COM Subject: macro-let and *macroexpand-hook* To: Common-Lisp@SU-AI.ARPA Message-ID: <860426-183058-1028@Xerox> Well, I've looked through the archives and I've read through the silver book but I still can't tell whether or not expansion of macro-let'ed macros is supposed to use *macroexpand-hook* or not. It is clear that the environment argument passed to macroexpand-1 must contain those lexically-defined macros, but should *macroexpand-hook* be prepared to deal with them? It seems like the right thing is that *macroexpand-hook* should, indeed, be called, but it makes it harder to write a portable memoization facility; at least one such facility, in the Spice Lisp code, assumes that macro-function will retrieve the expansion function for any macro it is asked to deal with. Pavel  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 26 Apr 86 21:31:08 EST Received: from XEROX.COM by SU-AI.ARPA with TCP; 26 Apr 86 18:18:09 PST Received: from Cabernet.ms by ArpaGateway.ms ; 26 APR 86 18:19:07 PST Date: 26 Apr 86 18:12 PST From: Pavel.pa@Xerox.COM Subject: macro-let and *macroexpand-hook* To: Common-Lisp@SU-AI.ARPA Message-ID: <860426-181907-1025@Xerox> Well, I've looked through the archives and I've read through the silver book but I still can't tell whether or not expansion of macro-let'ed macros is supposed to use *macroexpand-hook* or not. It is clear that the environment argument passed to macroexpand-1 must contain those lexically-defined macros, but should *macroexpand-hook* be prepared to deal with them? It seems like the right thing is that *macroexpand-hook* should, indeed, be called, but it makes it harder to write a portable memoization facility; at least one such facility, in the Spice Lisp code, assumes that macro-function will retrieve the expansion function for any macro it is asked to deal with. Pavel  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 26 Apr 86 15:54:12 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 26 Apr 86 12:45:04 PST Received: ID ; Sat 26 Apr 86 15:45:55-EST Date: Sat, 26 Apr 1986 15:45 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: franz!fimass!franz!rfr@kim.berkeley.edu (Robert Rorschach) Cc: common-lisp@SU-AI.ARPA Subject: :allow-other-keys In-reply-to: Msg of 25 Apr 1986 16:07-EST from franz!fimass!franz!rfr at kim.berkeley.edu (Robert Rorschach) I don't think it ever occurred to anyone that there might be two occurrences of :allow-other-keys among a function's arguments, especially with conflicting values. We should probably just declare this situation to be an error. If we don't do that, we should rule that the leftmost occurrence of this keyword governs, since that is consistent with what other keywords do and, I suspect, is what most existing compilers and interpreters do. -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 26 Apr 86 15:46:37 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 26 Apr 86 12:38:55 PST Received: ID ; Sat 26 Apr 86 15:39:53-EST Date: Sat, 26 Apr 1986 15:39 EST Message-ID: From: Rob MacLachlan To: David Bein Cc: common-lisp@SU-AI.ARPA Subject: funcall In-reply-to: Msg of 26 Apr 1986 12:19-EST from David Bein Date: Saturday, 26 April 1986 12:19-EST From: David Bein Re: funcall Suppose we have the following code: (defun mumble (a) (flet ((mumble (a) (print "internal-mumble"))) (when (something a) (funcall 'mumble a)) (print "external-mumble") Is it 100% legal to pass funcall a symbol? Most implementations I have seen allow this although the manual tends to imply that the thing being funcall'ed must be a "function". It is pretty clear that passing a symbol to FUNCALL is legal. Although it doesn't say so in the funcall description, it is explicitly allowed in APPLY. It would be pretty silly not to apply the same rule to FUNCALL. I would say that regardless of whether a symbol is a function or not, it is legal to pass a symbol to FUNCALL. Is a compiler justified in simply turning this into a call to mumble as if it had been written as (mumble a) in the first place? No, as in APPLY, calling a symbol calls the global definition. Another related matter, suppose we change the funcall arg to #'mumble --> (function mumble). Is it clearly the case then that the mumble which is apparent is the inner one? Yes, FUNCTION evaluates a "functional expression" in the lexical environment at the point of call. Rob  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 26 Apr 86 15:40:40 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 26 Apr 86 12:32:07 PST Received: ID ; Sat 26 Apr 86 15:33:09-EST Date: Sat, 26 Apr 1986 15:33 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: nttlab!umemura@su-shasta (Kyoji UMEMURA) Cc: common-lisp@SU-AI.ARPA Subject: SOFTWARE-TYPE & SOFTWARE-VERSION There are really two uses for Software-Type, Software-Version, Machine-Type, and Machine-Version. The more common use is so that a Lisp user can precisely identify exactly what configuration he is running on. This is especially useful in reporting bugs, reporting benchmarks, etc. In an environment with many machines and many Lisp versions, it is very difficult for the maintainers to do anything when a bug report comes in without this precise information. For this purpose, all that is required is that the information be precise, unambigious, and human-readable. The other use is in portable programs that may want to adjust their behavior according to the kind of environment in which they are running. The way a certain display is set up, for example, might be different according the machine type, the machine version, the operating system type, and the operating system version. It would be useful for the version calls to return numbers in this case, rather than strings, so that Lisp code could say things like (if (> (software-version) 100) (new-style-stuff) (old-style-stuff)) However, it was observed that the use of a number here is not general enough to handle all the different version-numberins schemes used by diferent manufacturers. Some use fixnums, some use numbers like 1.5 and 4.2, some use letter-number combinations like G12b, some use name-number combiantions, like "internal 27.3". The real problem is that software releases are often not linearly ordered, but form a complex lattice, with some version being split off, developing independently through several versions, and then being merged back into the mainstream. So we felt that a call like this, to be universal, has to return an aribtrary string that the user can examine and that software can compare in a system-specific way. If a given system uses a simple integer numbering scheme, the user can just call Parse-Integer to get the numerical value. -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 26 Apr 86 13:39:03 EST Received: from SUN.COM by SU-AI.ARPA with TCP; 26 Apr 86 10:30:13 PST Received: from sun.uucp by sun.com (3.2-/SMI-3.0) id AA08705; Sat, 26 Apr 86 10:17:53 PST Received: by sun.uucp (1.1/SMI-2.0) id AA09632; Sat, 26 Apr 86 10:20:42 PST Received: by pyramid (4.12/3.14) id AA21984; Sat, 26 Apr 86 09:43:24 pst Date: 26 Apr 1986 09:19-PST From: David Bein Subject: funcall To: common-lisp@su-ai.arpa Message-Id: <514919994/bein@pyramid> Suppose we have the following code: (defun mumble (a) (flet ((mumble (a) (print "internal-mumble"))) (when (something a) (funcall 'mumble a)) (print "external-mumble") Is it 100% legal to pass funcall a symbol? Most implementations I have seen allow this although the manual tends to imply that the thing being funcall'ed must be a "function". Notice that I am carefully trying avoid what exactly is a function question which others have raised recently. Is a compiler justified in simply turning this into a call to mumble as if it had been written as (mumble a) in the first place? If so, which mumble should be apparent? If not, is a compiler justified in turning the form into: (funcall (symbol-function 'mumble) a) ? Another related matter, suppose we change the funcall arg to #'mumble --> (function mumble). Is it clearly the case then that the mumble which is apparent is the inner one? --David p.s. Sorry if this question has been answered previously..  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 26 Apr 86 08:37:37 EST Received: from SU-SHASTA.ARPA by SU-AI.ARPA with TCP; 26 Apr 86 05:30:22 PST Received: by su-shasta.arpa with TCP; Sat, 26 Apr 86 05:30:15 pst Received: by ntt.junet (4.12/4.7JC-7) CHAOS with CHAOS-MAIL id AA14901; Sat, 26 Apr 86 15:47:38 jst Date: Sat, 26 Apr 86 15:47:38 jst From: nttlab!umemura@su-shasta.arpa (Kyoji UMEMURA) Message-Id: <8604260647.AA14901@ntt.junet> To: Common-lisp@SU-AI.ARPA Subject: SOFTWARE-TYPE & SOFTWARE-VERSION Why does SOFTWARE-VERSION returns not number, but string? If we cannot compare two versions and cannot determine which is newer, why does SOFTWARE-TYPE exist? It is the same about MACHINE-TYPE and MACHINE-VERSION. (I am a newcomer. Sorry, if it is already discussed) Kyoji Umemura (nttlab)  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 26 Apr 86 00:56:33 EST Received: from KIM.BERKELEY.EDU by SU-AI.ARPA with TCP; 25 Apr 86 21:47:25 PST Received: by kim.berkeley.edu (5.45/1.12) id AA03204; Fri, 25 Apr 86 21:48:20 PST Resent-Date: Fri, 25 Apr 86 13:07:03 PST Resent-From: franz!fimass!jkf@kim.berkeley.edu Resent-Message-Id: <8604260548.AA03204@kim.berkeley.edu> Received: from fimass by franz (5.5/3.14) id AA01489; Fri, 25 Apr 86 20:49:27 PST Received: by fimass (5.5/3.14) id AA01541; Fri, 25 Apr 86 20:49:51 PST Return-Path: Message-Id: <8604260449.AA01541@fimass> Replied: Fri, 25 Apr 86 20:49:16 PST Replied: "franz!rfr (Robert Rorschach) cl" id AA00976; Fri, 25 Apr 86 13:07:55 PST id AA00637; Fri, 25 Apr 86 13:07:03 PST Date: Fri, 25 Apr 86 13:07:03 PST From: franz!fimass!franz!rfr@kim.berkeley.edu (Robert Rorschach) To: cl@kim.berkeley.edu Subject: :allow-other-keys Resent-To: common-lisp@su-ai.arpa Sender: franz!fimass!jkf@kim.berkeley.edu The way CLtL is written, this keyword's behaviour is nonstandard. (foo :allow-other-keys nil :allow-other-keys t), according to the letter, allows other keys. With all other keyword arguments, only the first occurrence of the keyword counts. Does anyone know whether this anomaly is intentional? It seems like it could be an accident of phrasing.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 25 Apr 86 13:28:05 EST Received: from AQUINAS.THINK.COM by SU-AI.ARPA with TCP; 25 Apr 86 10:15:23 PST Received: from THINK-KATHERINE.ARPA by THINK-AQUINAS.ARPA via CHAOS with CHAOS-MAIL id 21402; Fri 25-Apr-86 13:19:42-EST Date: Fri, 25 Apr 86 13:17 EST From: Guy Steele Subject: What is a compiler (vol. 63827) meets what are gensyms. To: Moon@SCRC-STONY-BROOK.ARPA, Common-Lisp@SU-AI.ARPA cc: gls@THINK-AQUINAS.ARPA In-Reply-To: <860419181953.7.MOON@EUPHRATES.SCRC.Symbolics.COM> Message-ID: <860425131707.1.GLS@THINK-KATHERINE.ARPA> Date: Sat, 19 Apr 86 18:19 EST From: David A. Moon ... (DEFSETF BAR (#:G1890) (#:G1891) `(SET-BAR ,#:G1890 ,#:G1891)), where the symbols that look the same are EQ ... Tangential point: the above can be rendered in Common Lisp without a tag line in English as follows: (DEFSETF BAR (#1=#:G1890) (#2=#:G1891) `(SET-BAR ,#1# ,#2#)), --Guy  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 23 Apr 86 22:41:16 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 23 Apr 86 19:32:30 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 470760; Wed 23-Apr-86 22:31:52-EST Date: Wed, 23 Apr 86 22:31 EST From: David A. Moon Subject: with-output-to-string To: common-lisp@SU-AI.ARPA In-Reply-To: <8604231512.AA01394@hplsny> Message-ID: <860423223103.6.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Wednesday, April 23, 1986 07:12:11 From: Alan Snyder I haven't looked too hard, so perhaps I am missing something, but: What function is used by WITH-OUTPUT-TO-STRING to create an output stream to an existing string? One that isn't documented. MAKE-STRING-OUTPUT-STREAM does not take an argument. In some implementations WITH-OUTPUT-TO-STRING does not work by calling MAKE-STRING-OUTPUT-STREAM, since the former stream has dynamic extent and the latter stream has indefinite extent. The extension I think you are proposing is reasonable as an extension. Do you propose that GET-OUTPUT-STREAM-STRING be allowed on that type of stream?  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 23 Apr 86 21:56:08 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 23 Apr 86 18:46:55 PST Received: ID ; Wed 23 Apr 86 21:46:59-EST Date: Wed, 23 Apr 1986 21:46 EST Message-ID: From: Rob MacLachlan To: Alan Snyder Cc: common-lisp@SU-AI.ARPA Subject: with-output-to-string In-reply-to: Msg of 23 Apr 1986 07:12-EST from Alan Snyder Date: Wednesday, 23 April 1986 07:12-EST From: Alan Snyder Re: with-output-to-string I haven't looked too hard, so perhaps I am missing something, but: What function is used by WITH-OUTPUT-TO-STRING to create an output stream to an existing string? MAKE-STRING-OUTPUT-STREAM does not take an argument. Not a Common Lisp function. It has been suggested by other people that MAKE-STRING-OUTPUT-STREAM could take a optional arg which would be a string with a fill-pointer. Rob  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 23 Apr 86 18:22:30 EST Received: from HPLABS.ARPA by SU-AI.ARPA with TCP; 23 Apr 86 15:13:07 PST Received: from hplsny by hplabs.ARPA ; Wed, 23 Apr 86 08:32:23 pst Received: by hplsny ; Wed, 23 Apr 86 07:12:18 pst From: Alan Snyder Message-Id: <8604231512.AA01394@hplsny> Date: Wednesday, April 23, 1986 07:12:11 Subject: with-output-to-string To: common-lisp@su-ai.ARPA X-Sent-By-Nmail-Version: 04-Nov-84 17:14:46 I haven't looked too hard, so perhaps I am missing something, but: What function is used by WITH-OUTPUT-TO-STRING to create an output stream to an existing string? MAKE-STRING-OUTPUT-STREAM does not take an argument. -------  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 22 Apr 86 17:18:11 EST Received: from XEROX.COM by SU-AI.ARPA with TCP; 22 Apr 86 13:53:47 PST Received: from Cabernet.ms by ArpaGateway.ms ; 22 APR 86 13:48:57 PST Date: 22 Apr 86 13:48 PST From: Gregor.pa@Xerox.COM Subject: Re: What is a compiler (vol. 63827) meets what are gensyms. In-reply-to: David A. Moon 's message of Tue, 22 Apr 86 15:15 EST To: Moon@SCRC-STONY-BROOK.ARPA cc: Common-Lisp@SU-AI.ARPA Message-ID: <860422-134857-1288@Xerox> I think that making the language specification very explicit about what object relationships are preserved by loading and dumping in the way that DLW and Moon have suggested is what I was asking for by sending my original message.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 22 Apr 86 16:59:51 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 22 Apr 86 13:31:33 PST Date: Tue, 22 Apr 86 16:32:57 EST From: Jonathan A Rees Subject: What is a compiler (vol. 63827) meets what are gensyms. To: DLW@SCRC-QUABBIN.ARPA cc: Common-Lisp@SU-AI.ARPA, Gregor.pa@XEROX.COM, Fahlman@C.CS.CMU.EDU In-reply-to: Msg of Tue 22 Apr 86 10:47 EST from Daniel L. Weinreb Message-ID: <[MC.LCS.MIT.EDU].892135.860422.JAR> Date: Tue, 22 Apr 86 10:47 EST From: Daniel L. Weinreb For purposes of the archives, though, I'd like to point out that if we try to define this formally in the manual, we had better be careful. Consider what happens if you run the dumper twice, creating two independent files, and each run contains a certain uninterned symbol. Then, in a new Lisp world, you load both files. If you require the dumper to maintain EQness in this case, the dumper will be extremely difficult to implement correctly. In fact, the same issues apply to objects other than uninterned symbols, such as conses. Also just for the archives: all these problems with EQness of gensyms and locations could be solved if Common Lisp had a way to generate truly unique names. The Aegis operating system has this feature, and it's incredibly powerful: a "generate UID" system call will give you a bit string (64 bits long) which is different from any other UID created at any time by any other call to generate-UID on any machine running Aegis. UID's are generated from the time of day and the serial number of the CPU. Within the operating system they're used mostly to identify files, processes, types, and other objects, but anyone is free to use them in any circumstance which requires a unique token. A very similar mechanism which more of you might be familiar with is the "message id's" generated by mail systems, although I'm not aware of the existence of any universally applied convention which really guarantees uniqueness. One convention that would work would be if message-id's began with the domain name of the machine which generated the message id. (To make that really work, you'd have to make sure that every machine had a domain name, and that different machines had different names.) I believe a mechanism like these could be adopted by a language and made to work on arbitrary host operating systems and machines. If the operating system has a way to determine the CPU's serial number, the date & time of day (precisely), and a process ID, then it's straightforward. (I leave out some detail that makes sure there won't be collisions between names generated by different implementations or machine types.) If a machine serial number isn't available, then guaranteeing uniqueness is more difficult, but still possible; e.g. a serial number could be generated when Lisp is installed on a particular CPU (or file system). E.g.: (gensym) => #:860422104731.16.9112.JAR@MC.MIT.LCS.EDU or whatever. Given a mechanism like this, gensyms could in fact be interned, and so could locations of conses and other mutable objects. Since the identity of a gensym would be determined by its truly unique name, it could be freely dumped and restored, or even printed and read, just like any other symbol. This may be a little too ambitious for Common Lisp, but I just wanted to point out that the process of dumping and restoring gensyms is not prone to inconsistencies, if gensyms really are unique. (Maybe this could solve the package name collision problem, too...) Jonathan  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 22 Apr 86 16:13:25 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 22 Apr 86 12:57:01 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 469458; Tue 22-Apr-86 15:16:52-EST Date: Tue, 22 Apr 86 15:15 EST From: David A. Moon Subject: What is a compiler (vol. 63827) meets what are gensyms. To: Common-Lisp@SU-AI.ARPA In-Reply-To: <860418101724.8.DCP@FIREBIRD.SCRC.Symbolics.COM> Message-ID: <860422151556.9.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Fri, 18 Apr 86 10:17 EST From: David C. Plummer I think CLtL must be very explicit about what is preserved in the load/dump process. The Symbolics implementation is EQUAL (often EQL) for lists and EQL for everything else. For the record, this is not exactly true. The Symbolics implementation preserves EQness of objects within a single binary file output by the compiler; this is a little stronger than PRINT/READ equality; perhaps it's equivalent to PRINT/READ equality with *PRINT-CIRCLE* turned on and a giant PROGN wrapped around the entire file. The Symbolics implementation does not make lists that are EQUAL become EQ as part of the load/dump process, contrary to what DCP implied. What it actually does is to make constants within a compiled function or an unspecified group of compiled functions that satisfy a certain predicate (which is approximately EQUAL) become EQ, which is not quite the same. I agree both that it would be good for the language specification to be very explicit about what object relationships are preserved by loading and dumping, and that this is very difficult.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 22 Apr 86 13:07:10 EST Received: from HUDSON.DEC.COM by SU-AI.ARPA with TCP; 22 Apr 86 09:42:36 PST Date: 22 Apr 86 09:18:00 EST From: "BACH::GREEK" Subject: Ignoring bound variables. To: "common-lisp" Reply-To: "BACH::GREEK" Well, how about we add a new ampersand keyword, &IGNORE ? We would allow &IGNORE in lambda lists and in special forms like MULTIPLE-VALUE-BIND. The keyword would mean "ignore exactly one argument in this position". - Paul ------  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 22 Apr 86 13:06:36 EST Received: from HUDSON.DEC.COM by SU-AI.ARPA with TCP; 22 Apr 86 09:43:32 PST Date: 22 Apr 86 09:34:00 EST From: "BACH::GREEK" Subject: A New &IGNORE keyword To: "common-lisp" Reply-To: "BACH::GREEK" Well, that'll teach me to send out mail without first reading all of my new messages. Since I proposed the same thing as Dave Touretzky, I must agree with him. Scott has a reasonable objection in that all other &-keywords are punctuation, not actual placeholders. It's not really the case that users can scan a lambda list and assume each top-level item in the list grabs one of the arguments. That's certainly not true for &REST, &BODY, or &ALLOW-OTHER-KEYS. I'm not really bothered by an &-keyword that actually stands for an argument. All in all, however, I agree that the IGNORE declaration is sufficient. - Paul ------  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 22 Apr 86 13:03:34 EST Received: from HUDSON.DEC.COM by SU-AI.ARPA with TCP; 22 Apr 86 09:43:05 PST Date: 22 Apr 86 09:21:00 EST From: "BACH::GREEK" Subject: Proclaiming IGNORE To: "common-lisp" Reply-To: "BACH::GREEK" I agree that proclaiming things about lexical variables is really opening up a can of worms. I think we ought not. - Paul ------  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 22 Apr 86 11:04:03 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 22 Apr 86 07:54:24 PST Received: from CHICOPEE.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 469050; Tue 22-Apr-86 10:46:43-EST Date: Tue, 22 Apr 86 10:47 EST From: Daniel L. Weinreb Subject: What is a compiler (vol. 63827) meets what are gensyms. To: Fahlman@CMU-CS-C.ARPA, Gregor.pa@XEROX.ARPA cc: Common-Lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860422104731.7.DLW@CHICOPEE.SCRC.Symbolics.COM> Date: Fri, 18 Apr 1986 09:50 EST From: "Scott E. Fahlman" the dumper has no business losing track of the EQ-ness of the symbols, whether or not they are interned anywhere. I agree with this (and this is what Moon said as well). For purposes of the archives, though, I'd like to point out that if we try to define this formally in the manual, we had better be careful. Consider what happens if you run the dumper twice, creating two independent files, and each run contains a certain uninterned symbol. Then, in a new Lisp world, you load both files. If you require the dumper to maintain EQness in this case, the dumper will be extremely difficult to implement correctly. In fact, the same issues apply to objects other than uninterned symbols, such as conses. Also, we should keep in mind that the semantics of dump/load in the presence of uninterned symbols clearly are not quite the same as the semantics of print/read, despite the fact that the two operations are roughly the same kind of thing.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 21 Apr 86 17:20:05 EST Received: from MIT-ZERMATT.ARPA by SU-AI.ARPA with TCP; 21 Apr 86 14:06:51 PST Received: from VIOLIN.LCS.MIT.EDU by MIT-ZERMATT.ARPA via CHAOS with CHAOS-MAIL id 34013; Mon 21-Apr-86 17:07:52-EST Date: Mon, 21 Apr 86 17:07 EST From: Richard E. Zippel Subject: Re: Type Specifier: (OR (FUNCTION ...) ...) To: NGALL@G.BBN.COM, gls@AQUINAS.THINK.COM cc: Fahlman@C.CS.CMU.EDU, common-lisp@SU-AI.ARPA In-Reply-To: <[G.BBN.COM]21-Apr-86 16:31:40.NGALL> Message-ID: <860421170750.1.RZ@VIOLIN.LCS.MIT.EDU> Date: 21 Apr 1986 16:31-EST From: NGALL@G.BBN.COM Date: Sun, 20 Apr 86 16:14 EST From: Guy Steele Date: 19 Apr 1986 17:08-EST From: NGALL@G.BBN.COM Date: Sat, 19 Apr 1986 16:24 EST From: "Scott E. Fahlman" Regarding your proposal that we allow forms like the following (or (function (list) list) (function (vector) vector)) as a way of specifying that the output type of a function matches its input type... ... I don't think it is a proposal. I can find nothing in CLtL that forbids using such a form right now. I find no justification in CLtL for a compiler's insisting that a type specifier given to FTYPE be of the form (FUNCTION ...). What I said in my original letter was: "Unfortunately, it is not clear from pg. 158 whether or not the following is legal: ... It is not legal in VaxLisp, and my guess is that there aren't any implementations that would do the right thing with it. So I would like to propose that such a use of OR/FUNCTION be considered legal CL." I guess I should have said "So I would like to propose that pg. 158 be 'clarified' to explicitly state that such a use of OR/FUNCTION be considered legal CL." To be more explicit: Clarify the def. of FTYPE (pg. 158) by changing (FTYPE type ...) to (FTYPE function-type ...) and defining function-type to either (FUNCTION ...), (NOT function-type), (AND function-type ...), or (OR function-type ...). I would still like to know if there are any implementations that do consider (OR (FUNCTION ... meaningful! Unless a compiler can prove that a declaration is actually inconsistent, it should not signal an error. (Warnings are another matter and, as always, subject to judements of taste.) A compiler is not justified in signalling an error just because it doesn't know how to make use of a perfectly legitimate declaration. ... If someone were to say (or (function (list sequence) foo) (function (sequence list) bar)) then what do we do? According to the definition of the OR type-spec on pg. 45, "it always tests each of the component types in order from left to right and stops procesing as soon as one component of the union has been found to which the object belongs." But hold on here, now. That specification applies specifically to the case of TYPEP processing the type specifier, not to the case of using the type specifier in a declaration. Also, do not make the mistake of thinking that one can decide which of several function type specifiers applies to a function call by examining the argument types only. If function BAZ has the type shown above, then we are entitled only to conclude that the call (BAZ '(a) '(b)) will return an object of type (OR FOO BAR). I stand corrected. But here is a more subtle point. The above type states that BAZ is either a function of type (FUNCTION (LIST SEQUENCE) FOO) or a function of type (FUNCTION (SEQUENCE LIST) BAR). Assume FOO and BAR to be disjoint types. Suppose BAZ is called twice in succession, and the result of the first call is determined to be of type FOO: (WHEN (TYPEP (BAZ '(a) '(b)) 'FOO) (BAZ '(c) '(d))) We have no cause to believe that BAZ will change between the two calls, I disagree for the same reason as REM. and so we are entitled to deduce that the second call to BAZ, if executed, will necessarily return a FOO and not a BAR, because the first call produced a FOO and thus BAZ is of type (FUNCTION (LIST SEQUENCE) FOO). So maybe Nick isn't actually expressing quite what he wanted to in the first place. --Guy No I guess I'm not. But I am quite happy with Guy's correction. I can still do things like: (proclaim '(ftype (or (function (t list &rest t) list) (function (t vector &rest t) vector)) remove)) And expect that a very good compiler would be able to deduce that the call (remove 1 '#(1 2 3 4)) will return a vector. I think I will now try to come up with a declaration for +. -- Nick  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 21 Apr 86 16:46:04 EST Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 21 Apr 86 13:33:39 PST Date: 21 Apr 1986 16:31-EST Sender: NGALL@G.BBN.COM Subject: Re: Type Specifier: (OR (FUNCTION ...) ...) From: NGALL@G.BBN.COM To: gls@AQUINAS.THINK.COM Cc: Fahlman@C.CS.CMU.EDU, common-lisp@SU-AI.ARPA Message-ID: <[G.BBN.COM]21-Apr-86 16:31:40.NGALL> In-Reply-To: <860420161452.2.GLS@THINK-YON.ARPA> Date: Sun, 20 Apr 86 16:14 EST From: Guy Steele Date: 19 Apr 1986 17:08-EST From: NGALL@G.BBN.COM Date: Sat, 19 Apr 1986 16:24 EST From: "Scott E. Fahlman" Regarding your proposal that we allow forms like the following (or (function (list) list) (function (vector) vector)) as a way of specifying that the output type of a function matches its input type... ... I don't think it is a proposal. I can find nothing in CLtL that forbids using such a form right now. I find no justification in CLtL for a compiler's insisting that a type specifier given to FTYPE be of the form (FUNCTION ...). What I said in my original letter was: "Unfortunately, it is not clear from pg. 158 whether or not the following is legal: ... It is not legal in VaxLisp, and my guess is that there aren't any implementations that would do the right thing with it. So I would like to propose that such a use of OR/FUNCTION be considered legal CL." I guess I should have said "So I would like to propose that pg. 158 be 'clarified' to explicitly state that such a use of OR/FUNCTION be considered legal CL." To be more explicit: Clarify the def. of FTYPE (pg. 158) by changing (FTYPE type ...) to (FTYPE function-type ...) and defining function-type to either (FUNCTION ...), (NOT function-type), (AND function-type ...), or (OR function-type ...). I would still like to know if there are any implementations that do consider (OR (FUNCTION ... meaningful! Unless a compiler can prove that a declaration is actually inconsistent, it should not signal an error. (Warnings are another matter and, as always, subject to judements of taste.) A compiler is not justified in signalling an error just because it doesn't know how to make use of a perfectly legitimate declaration. ... If someone were to say (or (function (list sequence) foo) (function (sequence list) bar)) then what do we do? According to the definition of the OR type-spec on pg. 45, "it always tests each of the component types in order from left to right and stops procesing as soon as one component of the union has been found to which the object belongs." But hold on here, now. That specification applies specifically to the case of TYPEP processing the type specifier, not to the case of using the type specifier in a declaration. Also, do not make the mistake of thinking that one can decide which of several function type specifiers applies to a function call by examining the argument types only. If function BAZ has the type shown above, then we are entitled only to conclude that the call (BAZ '(a) '(b)) will return an object of type (OR FOO BAR). I stand corrected. But here is a more subtle point. The above type states that BAZ is either a function of type (FUNCTION (LIST SEQUENCE) FOO) or a function of type (FUNCTION (SEQUENCE LIST) BAR). Assume FOO and BAR to be disjoint types. Suppose BAZ is called twice in succession, and the result of the first call is determined to be of type FOO: (WHEN (TYPEP (BAZ '(a) '(b)) 'FOO) (BAZ '(c) '(d))) We have no cause to believe that BAZ will change between the two calls, I disagree for the same reason as REM. and so we are entitled to deduce that the second call to BAZ, if executed, will necessarily return a FOO and not a BAR, because the first call produced a FOO and thus BAZ is of type (FUNCTION (LIST SEQUENCE) FOO). So maybe Nick isn't actually expressing quite what he wanted to in the first place. --Guy No I guess I'm not. But I am quite happy with Guy's correction. I can still do things like: (proclaim '(ftype (or (function (t list &rest t) list) (function (t vector &rest t) vector)) remove)) And expect that a very good compiler would be able to deduce that the call (remove 1 '#(1 2 3 4)) will return a vector. I think I will now try to come up with a declaration for +. -- Nick  Received: from MC.LCS.MIT.EDU by AI.AI.MIT.EDU via Chaosnet; 21 APR 86 16:26:06 EST Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 21 Apr 86 16:25:16 EST Received: from SU-GLACIER.ARPA by SU-AI.ARPA with TCP; 21 Apr 86 13:14:16 PST Received: by su-glacier.arpa with Sendmail; Mon, 21 Apr 86 13:01:50 pst Received: from pachyderm.UUCP (pachyderm.ARPA) by mips.UUCP (4.12/4.7) id AA11916; Mon, 21 Apr 86 12:07:26 pst Received: by pachyderm.UUCP (4.12/4.7) id AA24766; Mon, 21 Apr 86 12:06:47 pst Date: Mon, 21 Apr 86 12:06:47 pst From: mips!pachyderm.earl@su-glacier.arpa (Earl Killian) Message-Id: <8604212006.AA24766@pachyderm.UUCP> To: common-lisp@SU-AI.ARPA Subject: IGNORE, warnings, and &stuff Naming a variable IGNORE is not a general solution: how do I ignore multiple arguments? Writing IGNORE multiple times would probably give me complaints about using a variable name twice in the lambda list.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 21 Apr 86 13:42:16 EST Received: from YALE-BULLDOG.ARPA by SU-AI.ARPA with TCP; 21 Apr 86 10:31:17 PST Received: by Yale-Bulldog.YALE.ARPA; 21 Apr 86 13:09:51 EST (Mon) Date: 21 Apr 86 13:09:51 EST (Mon) From: James Meehan Message-Id: <8604211809.AA03911@Yale-Bulldog.YALE.ARPA> Subject: *print-circle* To: common-lisp@su-ai.arpa When *print-circle* is true, the printer should "endeavor to detect circularities" in the thing it's printing. Is this supposed to include structures that have :print-function methods? I know it's more work, but it seems like the right thing. -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 21 Apr 86 11:40:51 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 21 Apr 86 08:26:15 PST Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 468268; Mon 21-Apr-86 11:25:11-EST Date: Mon, 21 Apr 86 11:26 EST From: Kent M Pitman Subject: [marchett%cod@nosc: slotp] To: Common-Lisp@SU-AI.ARPA Message-ID: <860421112614.3.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM> The following came just to me, but as long as he's taken the trouble to write all this down, it might as well be archived... Date: Mon, 21 Apr 86 07:20:53 PST From: David J. Marchette To: kmp@scrc-stony-brook Cc: priebe%cod@nosc.ARPA Subject: slotp Message-Id: <8604211520.AA09291@cod.ARPA> I had several reasons for asking the question. I admit it sounds silly that the person who did the programming wouldn't know what he called the slots. That isn't what I'm talking about here. The problem is that I am writing a rule parser similar to ops5, but with a more object-oriented view point. A rule may deal with several objects, or structures, and there may be many different kinds of data objects. When the time comes to test the rules, the program needs a way of determining which objects are valid data for the rules, and this cannot be written in to the rule language. I realize that there are other ways to do this, but it seemed to be an easy quick and dirty way to get things going if I could check the data objects to see if they had the necessary structure for that particular rule. A second reason for doing this is that it would be nice to be able to have a simple way of viewing the data built in to the rule language. The Symbolics has such a tool, called the inspector, which allows one to see the values of the slots and prints the "name" of the slot next to it. The inspector of course cannot know ahead of time what kind of data it will be given. Finally, the fact that a debugger may want to have this ability is another argument for making it a part of the language since this would make one more part of the debugger implementation independant. After all, someone has to write debuggers. Since, as I understand it, there is nothing forcing an implementation to store structures in a particular way, there may be no way to get this information in an implementation independant way unless the implementer also provides a function to do this. I may be wrong, they may always store the names of slots in a property list, in which case I have no problem, but I don't want to write code that will only run on my symbolics. If I'm going to do that, I might as well stick with zetalisp with all the good stuff it gives me.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 21 Apr 86 11:04:49 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 21 Apr 86 07:49:21 PST Received: ID ; Mon 21 Apr 86 10:51:42-EST Date: Mon, 21 Apr 1986 10:51 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Soley@MC.LCS.MIT.EDU Cc: common-lisp@SU-AI.ARPA Subject: IGNORE, warnings, and &stuff In-reply-to: Msg of 21 Apr 1986 10:23-EST from Soley at MIT-MC.ARPA But how about if (lambda (x &ignore y &ignore z) ...) was instead the same as (lambda (x y z) (declare (ignore y z)) ...) I don't see this as any big improvement in convenience over the declare form we have now. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 21 Apr 86 10:31:34 EST Received: from MIT-LIVE-OAK.ARPA by SU-AI.ARPA with TCP; 21 Apr 86 07:22:09 PST Received: from MIT-CHERRY.ARPA by MIT-LIVE-OAK.ARPA via CHAOS with CHAOS-MAIL id 701; Mon 21-Apr-86 10:22:58-EST Date: Mon, 21 Apr 86 10:23 EST From: Soley@MIT-MC.ARPA Subject: IGNORE, warnings, and &stuff To: Fahlman@C.CS.CMU.EDU, Dave.Touretzky@A.CS.CMU.EDU cc: common-lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860421102327.4.SOLEY@MIT-CHERRY.ARPA> Date: Sun, 20 Apr 1986 23:19 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" Since &-stuff in the lambda list is already treated as magic, I propose adding a new lambda list keyword called &IGNORE. Writing (lambda (x &ignore y &ignore z) ...) should be equivalent to (lambda (x g0001 y g0002 z) (declare (ignore g0001 g0002)) ...) I really don't like this. The other &-thingies are punctuation within the lambda list which separate the variables into groups; they are not stand-ins or place-holders for the variables themselves. I agree. In addition, you don't get the argument list documentation of the names of the ignored variables. But how about if (lambda (x &ignore y &ignore z) ...) was instead the same as (lambda (x y z) (declare (ignore y z)) ...) ?? -- Richard  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 21 Apr 86 04:17:35 EST Received: from [192.10.41.45] by SU-AI.ARPA with TCP; 21 Apr 86 01:02:20 PST Received: from FIREBIRD.SCRC.Symbolics.COM by ALLEGHENY.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 12718; Fri 18-Apr-86 10:19:54-EST Date: Fri, 18 Apr 86 10:17 EST From: David C. Plummer Subject: What is a compiler (vol. 63827) meets what are gensyms. To: Gregor.pa@Xerox.COM, Common-Lisp@SU-AI.ARPA In-Reply-To: <860417141538.0.GREGOR@AVALON.XEROX-PARC> Message-ID: <860418101707.7.DCP@FIREBIRD.SCRC.Symbolics.COM> Date: Thu, 17 Apr 86 14:15 PST From: Gregor.pa@Xerox.COM In this issue the subject of what compile file is required to do with top-level forms meets the subject of top-level calls to macros which expand into code containing gensyms. Suppose I have the following macro. (defmacro foo (x y) (let ((var (gensym)) (nv-var (gensym))) `(progn (defun ,x ..) (defun ,y ..) (defsetf ,x (,var) (,nv-var) `(,',y ,,var ,,nv-var))))) And I have a file that includes the form: (FOO BAR SET-BAR) [ For clarities sake, the point is that the macro expands to a progn that includes a defsetf that has gensyms for the access-function-args and storing-variables, like this: (DEFSETF BAR (#:G1890) (#:G1891) `(SET-BAR ,#:G1890 ,#:G1891)) ] Is compiling and loading the file legal Common Lisp? Is the original foo macro legal Common Lisp? I claim that the answer to both questions is yes. After all, it is clearly legal interpreted/compiled to core Common Lisp. I believe that CLtL is "silent" on this issue. I got bit by a Common Lisp compiler which macroexpands top-level forms, but which does not necessarily compile the entire result of the macroexpansion. In this particular case the compiler expanded the two defuns, but left the defsetf as (store-setf ') Then the dumper dumped that list in such a way that when the file was loaded the gensyms which should have been eq were not. My opinion is that what you are doing is legal. My guess is that the dumper/loader you are using dumps all symbols as (more-or-less) package::print-name. This WILL preserve EQness for non-gensyms but loses for gensyms. I think CLtL must be very explicit about what is preserved in the load/dump process. The Symbolics implementation is EQUAL for lists and EQL for everything else.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 21 Apr 86 04:17:13 EST Received: from [192.10.41.45] by SU-AI.ARPA with TCP; 21 Apr 86 01:05:45 PST Received: from FIREBIRD.SCRC.Symbolics.COM by ALLEGHENY.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 12719; Fri 18-Apr-86 10:20:10-EST Date: Fri, 18 Apr 86 10:17 EST From: David C. Plummer Subject: What is a compiler (vol. 63827) meets what are gensyms. To: Gregor.pa@Xerox.COM, Common-Lisp@SU-AI.ARPA In-Reply-To: <860417141538.0.GREGOR@AVALON.XEROX-PARC> Supersedes: <860418101707.7.DCP@FIREBIRD.SCRC.Symbolics.COM> Message-ID: <860418101724.8.DCP@FIREBIRD.SCRC.Symbolics.COM> Date: Thu, 17 Apr 86 14:15 PST From: Gregor.pa@Xerox.COM In this issue the subject of what compile file is required to do with top-level forms meets the subject of top-level calls to macros which expand into code containing gensyms. Suppose I have the following macro. (defmacro foo (x y) (let ((var (gensym)) (nv-var (gensym))) `(progn (defun ,x ..) (defun ,y ..) (defsetf ,x (,var) (,nv-var) `(,',y ,,var ,,nv-var))))) And I have a file that includes the form: (FOO BAR SET-BAR) [ For clarities sake, the point is that the macro expands to a progn that includes a defsetf that has gensyms for the access-function-args and storing-variables, like this: (DEFSETF BAR (#:G1890) (#:G1891) `(SET-BAR ,#:G1890 ,#:G1891)) ] Is compiling and loading the file legal Common Lisp? Is the original foo macro legal Common Lisp? I claim that the answer to both questions is yes. After all, it is clearly legal interpreted/compiled to core Common Lisp. I believe that CLtL is "silent" on this issue. I got bit by a Common Lisp compiler which macroexpands top-level forms, but which does not necessarily compile the entire result of the macroexpansion. In this particular case the compiler expanded the two defuns, but left the defsetf as (store-setf ') Then the dumper dumped that list in such a way that when the file was loaded the gensyms which should have been eq were not. My opinion is that what you are doing is legal. My guess is that the dumper/loader you are using dumps all symbols as (more-or-less) package::print-name. This WILL preserve EQness for non-gensyms but loses for gensyms. I think CLtL must be very explicit about what is preserved in the load/dump process. The Symbolics implementation is EQUAL (often EQL) for lists and EQL for everything else.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 21 Apr 86 03:43:58 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 21 Apr 86 00:32:42 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 467615; Sat 19-Apr-86 18:19:54-EST Date: Sat, 19 Apr 86 18:19 EST From: David A. Moon Subject: What is a compiler (vol. 63827) meets what are gensyms. To: Common-Lisp@SU-AI.ARPA In-Reply-To: <860417141538.0.GREGOR@AVALON.XEROX-PARC> Message-ID: <860419181953.7.MOON@EUPHRATES.SCRC.Symbolics.COM> I don't think this is a language issue at all. I think it's simply a bug in the implementation. Compiling (DEFSETF BAR (#:G1890) (#:G1891) `(SET-BAR ,#:G1890 ,#:G1891)), where the symbols that look the same are EQ, is certainly supposed to work. I'm not sure I understood what Fahlman said, but he and I are probably saying the same thing.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 20 Apr 86 23:28:17 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 20 Apr 86 20:17:07 PST Received: ID ; Sun 20 Apr 86 23:19:38-EST Date: Sun, 20 Apr 1986 23:19 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Dave.Touretzky@A.CS.CMU.EDU Cc: common-lisp@SU-AI.ARPA Subject: IGNORE, warnings, and &stuff In-reply-to: Msg of 20 Apr 1986 22:32-EST from Dave.Touretzky at A.CS.CMU.EDU Since &-stuff in the lambda list is already treated as magic, I propose adding a new lambda list keyword called &IGNORE. Writing (lambda (x &ignore y &ignore z) ...) should be equivalent to (lambda (x g0001 y g0002 z) (declare (ignore g0001 g0002)) ...) I really don't like this. The other &-thingies are punctuation within the lambda list which separate the variables into groups; they are not stand-ins or place-holders for the variables themselves. At present, users can scan a lambda list and see each top-level item in the list grabs one of the arguments unless it is one of these &-markers. &IGNORE would mess this up. I would find IGNORE much less objectionable than &IGNORE in this role, even if it carves one extra symbol out of the namespace. But I still think that the existing IGNORE declaration does the job just fine, except in code passed down from the ancients. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 20 Apr 86 22:39:05 EST Received: from A.CS.CMU.EDU by SU-AI.ARPA with TCP; 20 Apr 86 19:30:19 PST Date: 20 Apr 86 22:32 EST From: Dave.Touretzky@A.CS.CMU.EDU To: common-lisp@SU-AI.ARPA Subject: IGNORE, warnings, and &stuff Since &-stuff in the lambda list is already treated as magic, I propose adding a new lambda list keyword called &IGNORE. Writing (lambda (x &ignore y &ignore z) ...) should be equivalent to (lambda (x g0001 y g0002 z) (declare (ignore g0001 g0002)) ...) I agree that code is not acceptable if it generates compiler warnings, because (a) it trains people to ignore compiler output, so they won't notice when significant warnings appear in the middle of routine stuff, and (b) people who port code to a new machine can't be expected to know which warnings can safely be ignored, unless they read and analyze the entire code. For the same reasons, we should be careful about allowing users to turn off entire classes of warnings just to silence a paranoid compiler. Instead. I think compilers should be required to provide a declaration for each class of warnings to locally specify that the user knows he is doing X and doesn't need a warning about X in this instance. The IGNORE declaration is a good example.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 20 Apr 86 21:09:23 EST Received: from YALE-BULLDOG.ARPA by SU-AI.ARPA with TCP; 20 Apr 86 17:58:18 PST Received: by Yale-Bulldog.YALE.ARPA; 19 Apr 86 14:01:22 EST (Sat) Date: 19 Apr 86 14:01:22 EST (Sat) From: James Meehan Message-Id: <8604191901.AA01167@Yale-Bulldog.YALE.ARPA> Subject: ignore To: pitman@YALE.ARPA Cc: common-lisp@su-ai.arpa Personally, I've grown very fond of the T convention that allows you to write () for ignored variables; e.g., (lambda (() y) y), (multiple-value-bind (a () c) ...). The one hassle with that convention in T, which was that (lambda (a b . ()) ...) doesn't "work," goes away in Common Lisp: (lambda (a b &rest ()) ...). As far as compiler warnings are concerned, though, I think they're still a good idea in a world of ipmerfect typists, but I wouldn't mind seeing a switch to turn the warnings off. -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 20 Apr 86 18:30:12 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 20 Apr 86 15:17:39 PST Received: ID ; Sun 20 Apr 86 18:18:45-EST Date: Sun, 20 Apr 1986 18:18 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: NGALL@BBNG.ARPA Cc: common-lisp@SU-AI.ARPA Subject: true-list type specifier In-reply-to: Msg of 20 Apr 1986 12:48-EST from NGALL at G.BBN.COM You're wrong here. The term "list" already means what you want to call a "true list". See the definition on page 26. No, you're wrong here. On pg. 27 it says: "The Lisp data type LIST is taken to mean the union of the CONS and NULL data types, and therefore encompasses both true lists and dotted lists." OK, now that you mention it, the statement at the bottom of page 27 seems to be more clearly applicable LIST as a type-specifier than the definition on page 26. I wonder if any exisitng code would break if we were to define the List type-specifier to mean "true list"? Implementations would then be free to use a null test instead of a consp test, though consp would also be legal. My guess is that some implementations follow this convention already, even though page 27 seems to label this an error. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 20 Apr 86 17:15:26 EST Date: 1986 April 20 13:49:52 PST (=GMT-8hr) From: Robert Elton Maas To:COMMON-LISP@SU-AI CC:"TRYG%IMSSS"@SCORE Subject:Need way to suppress warning messages after first see F> Date: Sun, 20 Apr 1986 11:33 EST F> From: "Scott E. Fahlman" F> Subject: (PROCLAIM '(IGNORE ...)) [SIC] F> ... F> Spurious compiler warnings seem to bother some people more than others. F> I have generally taken the view that if the compiler spots something F> vaguely suspicious, even if it is not clearly incorrect, it can't hurt F> to issue a warning. It costs very little to ignore such a warning, and F> if the problem is a real one, you might save the user many hours of F> debugging time. However, some individuals and companies seem to believe F> that code is not in a presentable state until all compiler warnings have F> been eliminated, either by fixing the code or by explicitly suppressing F> the error message. Seeing and thinking and ignoring one warning once is no big problem, it takes about a minute of my time, maybe less if it's something halfway obvious, maybe five minutes if it's a really fatal looking error I have to figure out carefully, maybe an hour if I have to discuss it with my boss (for example CANNOT CHANGE FLUID TO GLOBAL or vice versa in PSL). After I've hassled with one particular instance of one particular warning a couple times I get more efficient, but the total time wasted looking at the same error over and over and over accumulates over the months I work on a system. If in building a large system I have to look at a hundred warning messages each of a hundred recompilations during development, that's ten thousand individual lookings at those idiotic warnings. More likely I just get in the habit of ignoring them en masse, which is where the harm happens, because when an important new warning happens I never even look at it much less study it, in fact I complete miss other obvious things like DISK FULL, CANNOT OPEN OUTPUT FILE because I'm not even bothering to eyeball the batch log file. -- Conclusion, it's absolutely essential for proper use of programmer time and adequate detection of problems to have a way to suppress individual instances of various warning messages and in some cases whole classes of warning messages which are known a priori never to be significant. Any LISP system that fails to allow the programmer to suppress warnings is (in my opinion) unacceptable. F> At present, the language spec does not say what warnings a compiler must F> or may issue, and there is nothing in the spec about suppressing such F> warnings. Accompanying the language syntax&semantics spec should be important guidelines, such as "the compiler should make the resultant as efficient as possible without sacrificing correctness" (i.e. it's not legal to sell a "compiler" that just passes most program source thru to be interpreted at runtime), and "except for detection of outright errors, it should be possible for the user/programmer to suppress virtually all warnings and other unnecessary output, as selectively as reasonable" (i.e. it should be possible to declare individual names/objects (variables, and data or functions) as well as to declare classes of names/objects or classes of messages). A general guideline (desiderata) should be given, so that really obnoxious compilers can be declared "technically Common LISP but not really in the spirit of the language". F> One reasonable position (that looks good to me) is that this F> is an environment issue and the language doesn't need to say anything F> about this. Insufficient response (my opinion). F> But if people are going to get upset when allegedly F> portable programs give rise to compiler warnings, then ... Yup, something is needed (my opinion).  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 20 Apr 86 17:14:46 EST Date: 1986 April 20 14:01:58 PST (=GMT-8hr) From: Robert Elton Maas To:COMMON-LISP@SU-AI Subject:What really are semantics of (OR ...) type specifier?? G> Date: Sun, 20 Apr 86 16:14 EST G> From: Guy Steele G> Subject: Re: Type Specifier: (OR (FUNCTION ...) ...) (or (function (list) list) (function (vector) vector)) as a way of specifying that the output type of a function matches its input type... G> ... G> But here is a more subtle point. The above type states that BAZ is either G> a function of type (FUNCTION (LIST SEQUENCE) FOO) or a function of type G> (FUNCTION (SEQUENCE LIST) BAR). Assume FOO and BAR to be disjoint types. G> Suppose BAZ is called twice in succession, and the result of the first call G> is determined to be of type FOO: G> (WHEN (TYPEP (BAZ '(a) '(b)) 'FOO) G> (BAZ '(c) '(d))) G> We have no cause to believe that BAZ will change between the two calls, G> and so we are entitled to deduce that the second call to BAZ, if G> executed, will necessarily return a FOO and not a BAR, because the first G> call produced a FOO and thus BAZ is of type (FUNCTION (LIST SEQUENCE) FOO). G> So maybe Nick isn't actually expressing quite what he wanted to in the G> first place. Very good analysis. (:- I'm glad such subtle points were carefully studied before anybody publishes an official standard in book form -:) My guess is nobody thought of this before, so the manual is ambiguous and needs to be fixed (your interpretation, or his, or it's not legal CL). One possible cook of your analysis, it's possible that since BAZ is defined globally it may get defined out from under this program loop. I.e. the code must fetch the function definition of BAZ twice rather than fetch it once and use that fetched&cached value twice, so there's nothing to stop BAZ from redefining itself each time it is called. This is PSL but: (DE BAZ1 (A B) (PROGN (COPYD 'BAZ 'BAZ2) ...)) (DE BAZ2 (A B) (PROGN (COPYD 'BAZ 'BAZ1) ...)) (COPYD BAZ 'BAZ1) ;; Initialize the flip-flop function  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 20 Apr 86 16:41:06 EST Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 20 Apr 86 13:24:40 PST Received: from yon by GODOT.THINK.COM via CHAOS; Sun, 20 Apr 86 16:25:29 est Date: Sun, 20 Apr 86 16:26 EST From: Guy Steele Subject: (PROCLAIM '(IGNORE ...)) To: Fahlman@C.CS.CMU.EDU, NGALL@BBNG.ARPA Cc: common-lisp@SU-AI.ARPA, gls@THINK-AQUINAS.ARPA In-Reply-To: Message-Id: <860420162638.3.GLS@THINK-YON.ARPA> Date: Sun, 20 Apr 1986 11:33 EST From: "Scott E. Fahlman" Where in the manual does it say or imply that a lambda-list keyword cannot be used as a normal variable? To the contrary, pg 60 says, "They are ordinary symbols each of whose names begins with an ampersand." Hmmm...I guess it never comes right out and says that, probably because it was too obvious to mention. At least, it seems very clear to me that the lambda-list keywords cannot be used as normal variables in lambda-lists. Most such uses would screw up the parsing, and any that are not ambiguous by would be confusing as hell. Most exisitng compilers warn about any lambda-list keywords that seem to be out of order in a lambda list, and some compilers issue a warning about any unknown symbol starting with an ampersand. Such symbols are not illegal, but a warning doesn't imply illegality -- merely something suspicious that the user might want to take a close look at. See page 65, in the middle. --Guy  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 20 Apr 86 16:22:19 EST Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 20 Apr 86 13:13:03 PST Received: from yon by GODOT.THINK.COM via CHAOS; Sun, 20 Apr 86 16:13:43 est Date: Sun, 20 Apr 86 16:14 EST From: Guy Steele Subject: Re: Type Specifier: (OR (FUNCTION ...) ...) To: NGALL@G.BBN.COM, Fahlman@C.CS.CMU.EDU Cc: common-lisp@SU-AI.ARPA, gls@THINK-AQUINAS.ARPA In-Reply-To: <[G.BBN.COM]19-Apr-86 17:08:16.NGALL> Message-Id: <860420161452.2.GLS@THINK-YON.ARPA> Date: 19 Apr 1986 17:08-EST From: NGALL@G.BBN.COM Date: Sat, 19 Apr 1986 16:24 EST From: "Scott E. Fahlman" Regarding your proposal that we allow forms like the following (or (function (list) list) (function (vector) vector)) as a way of specifying that the output type of a function matches its input type... Your proposal seems to take one small step in the direction of such a declarative language, and then it stops. ... ... I don't think it is a proposal. I can find nothing in CLtL that forbids using such a form right now. I find no justification in CLtL for a compiler's insisting that a type specifier given to FTYPE be of the form (FUNCTION ...). Unless a compiler can prove that a declaration is actually inconsistent, it should not signal an error. (Warnings are another matter and, as always, subject to judements of taste.) A compiler is not justified in signalling an error just because it doesn't know how to make use of a perfectly legitimate declaration. ... If someone were to say (or (function (list sequence) foo) (function (sequence list) bar)) then what do we do? According to the definition of the OR type-spec on pg. 45, "it always tests each of the component types in order from left to right and stops procesing as soon as one component of the union has been found to which the object belongs." But hold on here, now. That specification applies specifically to the case of TYPEP processing the type specifier, not to the case of using the type specifier in a declaration. Also, do not make the mistake of thinking that that one can decide which of several function type specifiers applies to a function call by examining the argument types only. If function BAZ has the type shown above, then we are entitled only to conclude that the call (BAZ '(a) '(b)) will return an object of type (OR FOO BAR). But here is a more subtle point. The above type states that BAZ is either a function of type (FUNCTION (LIST SEQUENCE) FOO) or a function of type (FUNCTION (SEQUENCE LIST) BAR). Assume FOO and BAR to be disjoint types. Suppose BAZ is called twice in succession, and the result of the first call is determined to be of type FOO: (WHEN (TYPEP (BAZ '(a) '(b)) 'FOO) (BAZ '(c) '(d))) We have no cause to believe that BAZ will change between the two calls, and so we are entitled to deduce that the second call to BAZ, if executed, will necessarily return a FOO and not a BAR, because the first call produced a FOO and thus BAZ is of type (FUNCTION (LIST SEQUENCE) FOO). So maybe Nick isn't actually expressing quite what he wanted to in the first place. --Guy  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 20 Apr 86 13:16:23 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 20 Apr 86 08:46:02 PST Received: ID ; Sun 20 Apr 86 11:47:49-EST Date: Sun, 20 Apr 1986 11:47 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: NGALL@BBNG.ARPA Cc: common-lisp@SU-AI.ARPA Subject: Type Specifier: (OR (FUNCTION ...) ...) In-reply-to: Msg of 19 Apr 1986 17:08-EST from NGALL at G.BBN.COM Your proposal for an extension of the current declaration machinery so that there is a richer langauge in which to express constraints to the compiler looks interesting. I don't have any specific objections to what you propose -- it may be the right thing. However, I think that this is an area in which there are several possible approaches, and I would like to see some systematic exploration and some real experience here before we start extending the language spec piecemeal. I would suggest that if you want to experiment in this area, you develop a non-standard but compatible superset of the current declaration language, and that you install this in an experimental version of your system along with a compiler that uses this information. I'd like to see this in a context that includes CommonLoops or New Flavors, since there are some strong parallels between the kind of type-restricted arguments that those systems support and the sort of thing that you propose for declarations. If actual experience shows that this is a good way to go, then it would be time to seriously consider extending the standard in this way. If it is impractical for people out in industry to try this, maybe it would make a good M.S. thesis project for someone. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 20 Apr 86 13:06:30 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 20 Apr 86 07:39:17 PST Received: ID ; Sun 20 Apr 86 10:41:49-EST Date: Sun, 20 Apr 1986 10:41 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: NGALL@BBNG.ARPA Cc: common-lisp@SU-AI.ARPA Subject: true-list type specifier In-reply-to: Msg of 19 Apr 1986 19:11-EST from NGALL at G.BBN.COM (defun foo (my-list) (declare (list my-list)) (member 'my my-list)) and a compiler that has been told to turn off type-checking where licenced by user declarations. One might assume that MEMBER need not do a LIST check on each CDR of MY-LIST. But this is not the case, the above declaration merely licences the compiler to assume that MY-LIST is NIL or a CONS, but a type check should still be done on the CDR of MY-LIST (when it is a CONS), and on its CDR, etc. My question is: How does one declare that MY-LIST is a true list? You're wrong here. The term "list" already means what you want to call a "true list". See the definition on page 26. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 20 Apr 86 12:57:52 EST Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 20 Apr 86 09:49:31 PST Date: 20 Apr 1986 12:48-EST Sender: NGALL@G.BBN.COM Subject: Re: true-list type specifier From: NGALL@G.BBN.COM To: Fahlman@C.CS.CMU.EDU Cc: common-lisp@SU-AI.ARPA Message-ID: <[G.BBN.COM]20-Apr-86 12:48:43.NGALL> In-Reply-To: Date: Sun, 20 Apr 1986 10:41 EST From: "Scott E. Fahlman" To: NGALL@BBNG.ARPA Subject: true-list type specifier In-Reply-To: Msg of 19 Apr 1986 19:11-EST from NGALL at G.BBN.COM Message-ID: (defun foo (my-list) (declare (list my-list)) (member 'my my-list)) and a compiler that has been told to turn off type-checking where licenced by user declarations. One might assume that MEMBER need not do a LIST check on each CDR of MY-LIST. But this is not the case, the above declaration merely licences the compiler to assume that MY-LIST is NIL or a CONS, but a type check should still be done on the CDR of MY-LIST (when it is a CONS), and on its CDR, etc. My question is: How does one declare that MY-LIST is a true list? You're wrong here. The term "list" already means what you want to call a "true list". See the definition on page 26. -- Scott -------------------- No, you're wrong here. On pg. 27 it says: "The Lisp data type LIST is taken to mean the union of the CONS and NULL data types, and therefore encompasses both true lists and dotted lists." So my question and proposal still stand. Although I would not be against redefining LIST to mean true-list and using (OR NULL CONS) to mean true-or-dotted-list. But this would be an incompatible change, which might be harder to get into the language. -- Nick  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 20 Apr 86 12:54:59 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 20 Apr 86 08:31:19 PST Received: ID ; Sun 20 Apr 86 11:33:31-EST Date: Sun, 20 Apr 1986 11:33 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: NGALL@BBNG.ARPA Cc: common-lisp@SU-AI.ARPA Subject: (PROCLAIM '(IGNORE ...)) In-reply-to: Msg of 19 Apr 1986 17:36-EST from NGALL at G.BBN.COM Where in the manual does it say or imply that a lambda-list keyword cannot be used as a normal variable? To the contrary, pg 60 says, "They are ordinary symbols each of whose names begins with an ampersand." Hmmm...I guess it never comes right out and says that, probably because it was too obvious to mention. At least, it seems very clear to me that the lambda-list keywords cannot be used as normal variables in lambda-lists. Most such uses would screw up the parsing, and any that are not ambiguous by would be confusing as hell. Most exisitng compilers warn about any lambda-list keywords that seem to be out of order in a lambda list, and some compilers issue a warning about any unknown symbol starting with an ampersand. Such symbols are not illegal, but a warning doesn't imply illegality -- merely something suspicious that the user might want to take a close look at. I suppose one could argue that lambda-list keywords ought to be legal as variable names in non-lambda contexts. I think that this should be illegal -- it is amazingly confusing -- but by a strict reading of the current manual, I guess it is legal at present. Maybe the best way to resolve this IGNORE issue is to leave the language spec as it is, but to encourage compiler writers to provide some mechanism whereby the user can specify that certain classes of warnings can be suppressed. In this case, one would like to suppress "bound but not referenced" warnings for particular symbols. There's a more general issue here regarding compiler warnings: Spurious compiler warnings seem to bother some people more than others. I have generally taken the view that if the compiler spots something vaguely suspicious, even if it is not clearly incorrect, it can't hurt to issue a warning. It costs very little to ignore such a warning, and if the problem is a real one, you might save the user many hours of debugging time. However, some individuals and companies seem to believe that code is not in a presentable state until all compiler warnings have been eliminated, either by fixing the code or by explicitly suppressing the error message. At present, the language spec does not say what warnings a compiler must or may issue, and there is nothing in the spec about suppressing such warnings. One reasonable position (that looks good to me) is that this is an environment issue and the language doesn't need to say anything about this. But if people are going to get upset when allegedly portable programs give rise to compiler warnings, then maybe we need to think about some standard in-file mechanism (perhaps an extension to Proclaim/Declare, or perhaps something new) for suppressing certain classes of warnings at various places within a file. Such a thing would provide a common language for creating such advisories, but it would not be mandatory for compilers to pay any attention to them -- just desirable. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 19 Apr 86 19:25:32 EST Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 19 Apr 86 16:12:06 PST Date: 19 Apr 1986 19:11-EST Sender: NGALL@G.BBN.COM Subject: true-list type specifier From: NGALL@G.BBN.COM To: common-lisp@SU-AI.ARPA Message-ID: <[G.BBN.COM]19-Apr-86 19:11:32.NGALL> Since we seem to be on the subject of type specifiers, let me add this question. Given the following code (defun foo (my-list) (declare (list my-list)) (member 'my my-list)) and a compiler that has been told to turn off type-checking where licenced by user declarations. One might assume that MEMBER need not do a LIST check on each CDR of MY-LIST. But this is not the case, the above declaration merely licences the compiler to assume that MY-LIST is NIL or a CONS, but a type check should still be done on the CDR of MY-LIST (when it is a CONS), and on its CDR, etc. My question is: How does one declare that MY-LIST is a true list? For the purpose of discrimination, I suppose the following would suffice: (deftype true-list () '(or null (and cons (satisfies true-list-p)))) (defun true-cons-p (cons) (declare (cons cons)) (null (last cons))) But this would not be usable for purposes of declaration (unless one was dealing with an AI compiler :->). So I propose that the type specifier true-list be introduced. This would then allow compilers to validly substitute a NULL test for a NULL/CONSP test in the case mentioned above. -- Nick  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 19 Apr 86 18:46:34 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 19 Apr 86 15:36:29 PST Date: Sat, 19 Apr 86 18:37:59 EST From: Richard Mark Soley Subject: (PROCLAIM '(IGNORE ...)) To: Fahlman@C.CS.CMU.EDU cc: common-lisp@SU-AI.ARPA, KMP@SCRC-STONY-BROOK.ARPA In-reply-to: Msg of Sat 19 Apr 1986 16:07 EST from Scott E. Fahlman Message-ID: <[MC.LCS.MIT.EDU].889436.860419.SOLEY> Date: Sat, 19 Apr 1986 16:07 EST From: Scott E. Fahlman Sender: FAHLMAN at C.CS.CMU.EDU The lexically scoped IGNORE declaration seemed a much cleaner solution. Allowing global IGNORE proclamations seems a bit unclean to me, since it can have an effect on variables that come in from God-knows-where and that were never intended to be ignored. On the other hand, this would not be disastrous -- it would result in a few spurious compiler warnings in a few odd cases, and it wouldn't be at all hard to see what went wrong. Additionally, the package system offers some protection against this. I don't think Kent was suggesting that (PROCLAIM '(IGNORE FNORX)) should cause ignorance of all symbols string-equal to "FNORX"! Note the difference with Zetalisp, in which all variables STRING-equal to IGNORE are "ignore"d. -- Richard  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 19 Apr 86 17:53:55 EST Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 19 Apr 86 14:38:21 PST Date: 19 Apr 1986 17:36-EST Sender: NGALL@G.BBN.COM Subject: Re: (PROCLAIM '(IGNORE ...)) From: NGALL@G.BBN.COM To: Fahlman@C.CS.CMU.EDU Cc: KMP@SCRC-STONY-BROOK.ARPA, common-lisp@SU-AI.ARPA Message-ID: <[G.BBN.COM]19-Apr-86 17:36:18.NGALL> In-Reply-To: Date: Sat, 19 Apr 1986 16:07 EST From: "Scott E. Fahlman" To: Kent M Pitman Subject: (PROCLAIM '(IGNORE ...)) In-Reply-To: Msg of 18 Apr 1986 00:50-EST from Kent M Pitman Message-ID: Special treatment of IGNORE as a variable name was left out of the language because a lot of people objected to having the language poke holes in the namespace. (However, we relented with T, NIL, and the various &... symbols.) Where in the manual does it say or imply that a lambda-list keyword cannot be used as a normal variable? To the contrary, pg 60 says, "They are ordinary symbols each of whose names begins with an ampersand." The lexically scoped IGNORE declaration seemed a much cleaner solution. I agree. Allowing global IGNORE proclamations seems a bit unclean to me, since I agree. it can have an effect on variables that come in from God-knows-where and that were never intended to be ignored. On the other hand, this would not be disastrous -- it would result in a few spurious compiler warnings in a few odd cases, and it wouldn't be at all hard to see what went wrong. So I wouldn't object to a decision that (PROCLAIM '(IGNORE ...)) is legal. The definition of PROCLAIM on pg 156 says, "Any variable names mentioned are assumed to refer to the dynamic values of the variable." But the definition of IGNORE on pg. 160 says, "It is desirable for a compiler to issue a warning if a variable so declared is ... also declared special". Thus it is legal, but meaningless to PROCLAIM IGNORE. If you are proposing that IGNORE be a special case that refers to the lexical value (or lack thereof) of mentioned variable names, I would be stronly against it; the semantics of PROCLAIM are confusing enough already. Also, once IGNORE can be used on lexicals in a proclaim, why not TYPE also, then I wouldn't have to put a declare in each function that share a common parameter. No, I would contend that the need does not outweigh the consequences. -- Scott -------------------- -- Nick  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 19 Apr 86 17:21:33 EST Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 19 Apr 86 14:09:11 PST Date: 19 Apr 1986 17:08-EST Sender: NGALL@G.BBN.COM Subject: Re: Type Specifier: (OR (FUNCTION ...) ...) From: NGALL@G.BBN.COM To: Fahlman@C.CS.CMU.EDU Cc: common-lisp@SU-AI.ARPA Message-ID: <[G.BBN.COM]19-Apr-86 17:08:16.NGALL> In-Reply-To: Date: Sat, 19 Apr 1986 16:24 EST From: "Scott E. Fahlman" To: NGALL@BBNG.ARPA Subject: Type Specifier: (OR (FUNCTION ...) ...) In-Reply-To: Msg of 18 Apr 1986 16:07-EST from NGALL at G.BBN.COM Message-ID: Regarding your proposal that we allow forms like the following (or (function (list) list) (function (vector) vector)) as a way of specifying that the output type of a function matches its input type... It seems to me that there are a lot of things one might want to tell a compiler about the type relationships between the arguments to a function and its values. For example, + performed on a positive fixnum and a negative one is sure to return a fixnum, so no bignum check is required. Under my proposal, the above constraint could be declared as follows: (proclaim '(ftype (or (function ((integer 0 #.most-positive-fixnum) (integer #..most-negative-fixnum 0)) fixnum) (function (&rest number) number)))) Of course, other constraints (e.g., + performed on integers results in an integer) could be included also. One constraint that could not be directly declared is that + performed on N rationals one of which is a float results in a float. But since most compilers transform the multi-argument versions of functions into equivalent nested two-arg version, enumerating the two-arg type combinations would suffice. Your proposal seems to take one small step in the direction of such a declarative language, and then it stops. Could you give me an example of the further steps you would like to see? If it were clear that the extra cases your mechanism handles are the most common and important ones, then I'd favor adding this special case, but it isn't clear to me. Also, it gets into all the issues raised by the Commonloops type-precedence stuff. If someone were to say (or (function (list sequence) foo) (function (sequence list) bar)) then what do we do? According to the definition of the OR type-spec on pg. 45, "it always tests each of the component types in order from left to right and stops procesing as soon as one component of the union has been found to which the object belongs." Once the object-oriented stuff settles a bit, maybe the answer will be clear. -- Scott -------------------- -- Nick  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 19 Apr 86 16:35:14 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 19 Apr 86 13:22:06 PST Received: ID ; Sat 19 Apr 86 16:24:24-EST Date: Sat, 19 Apr 1986 16:24 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: NGALL@BBNG.ARPA Cc: common-lisp@SU-AI.ARPA Subject: Type Specifier: (OR (FUNCTION ...) ...) In-reply-to: Msg of 18 Apr 1986 16:07-EST from NGALL at G.BBN.COM Regarding your proposal that we allow forms like the following (or (function (list) list) (function (vector) vector)) as a way of specifying that the output type of a function matches its input type... It seems to me that there are a lot of things one might want to tell a compiler about the type relationships between the arguments to a function and its values. For example, + performed on a positive fixnum and a negative one is sure to return a fixnum, so no bignum check is required. Your proposal seems to take one small step in the direction of such a declarative language, and then it stops. If it were clear that the extra cases your mechanism handles are the most common and important ones, then I'd favor adding this special case, but it isn't clear to me. Also, it gets into all the issues raised by the Commonloops type-precedence stuff. If someone were to say (or (function (list sequence) foo) (function (sequence list) bar)) then what do we do? Once the object-oriented stuff settles a bit, maybe the answer will be clear. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 19 Apr 86 16:17:30 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 19 Apr 86 13:05:18 PST Received: ID ; Sat 19 Apr 86 16:07:29-EST Date: Sat, 19 Apr 1986 16:07 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Kent M Pitman Cc: common-lisp@SU-AI.ARPA Subject: (PROCLAIM '(IGNORE ...)) In-reply-to: Msg of 18 Apr 1986 00:50-EST from Kent M Pitman Special treatment of IGNORE as a variable name was left out of the language because a lot of people objected to having the language poke holes in the namespace. (However, we relented with T, NIL, and the various &... symbols.) The lexically scoped IGNORE declaration seemed a much cleaner solution. Allowing global IGNORE proclamations seems a bit unclean to me, since it can have an effect on variables that come in from God-knows-where and that were never intended to be ignored. On the other hand, this would not be disastrous -- it would result in a few spurious compiler warnings in a few odd cases, and it wouldn't be at all hard to see what went wrong. So I wouldn't object to a decision that (PROCLAIM '(IGNORE ...)) is legal. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 19 Apr 86 11:57:19 EST Received: from CSNET-RELAY.ARPA by SU-AI.ARPA with TCP; 19 Apr 86 08:31:40 PST Received: from utokyo-relay by csnet-relay.csnet id ac08654; 19 Apr 86 11:26 EST Received: by u-tokyo.junet (4.12/4.9J-1[JUNET-CSNET]) id AA28200; Sat, 19 Apr 86 18:47:46+0900 Received: by tansei.u-tokyo.junet (4.12/4.9J) id AA29674; Sat, 19 Apr 86 11:53:51+0900 Date: Sat, 19 Apr 86 11:53:51+0900 From: Masayuki Ida Message-Id: <8604190253.AA29674@tansei.u-tokyo.junet> To: common-lisp%su-ai.arpa@CSNET-RELAY.ARPA, ida@utokyo-relay.CSNET Subject: We are entering a new stage.... We are entering a new stage in japan. First,` it is my great pleasure to tell you all that we had have a firm link to USA. Since this april, Utokyo-relay, which is also called as ccut, is now an offical node of CSNet, with the efforts of many university professors. This mail is directed through csnet. With this link, I can communicate with many key members in USA more conveniently than last year. So, I am trying to communicate with arpa bboard. Second, as the chair, I finished the first year of our commonlisp committee at jeida, Japan Electronics Industries`Development Association, and now entering the second year from this April. Please don't missunderstand the committee I am talking of is closed against USA. We have several members from subsidaries`of US companys, such as xerox, symbolics, digital, data`general, univac. I reported the existence of the committee to several key members of USA, and at IJCAI'85 press conference. I want to assist to grow up Common Lisp community in Japan. We have a meeting once a month. This year, we want to do the followings. 1) finish the subset spec discussions after one year efforts and compile a subset draft. 2) make a kanji standard`for`CommonLisp. 3)`try to contribute the object oriented discussions. I will send`a report to this bboard periodically. Thank you Masayuki Ida (Assoc.Prof. Aoyama Gakuin University) ida%utokyo-relay.csnet@csnet-relay.arpa (ida is aliased to my registered code, A37078) UUCP: ...!hplabs!kddlab!ccut!ida ...!Shasta!ntt!ccut!ida (UUCP link over the pacific ocean may fail accidentally by`non-techical`reasons)  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 18 Apr 86 23:25:24 EST Received: from [192.10.41.223] by SU-AI.ARPA with TCP; 18 Apr 86 19:59:10 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SAPSUCKER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 9243; Fri 18-Apr-86 17:31:13 EST Date: Fri, 18 Apr 86 17:30 EST From: David A. Moon Subject: Should the floating-point constants really be constants? To: common-lisp@SU-AI.ARPA In-Reply-To: The message of 16 Apr 86 15:51 EST from hpfclp!paul@hplabs.ARPA Message-ID: <860418173043.9.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Wed, 16 Apr 86 12:51:09 pst From: hpfclp!paul@hplabs.ARPA Question: Should the floating point constants on pgs. 231-232 of CLtL really be constants? Here is an example. Take the constant double-float-epsilon. Suppose it is derived on a system in which doubles are IEEE 64 bit format, and in which the rounding precision is round to double. Fine. Now suppose we want to use an MC68881, and we want to use the default rounding precision (round to extended) because it is faster and gives "better" results. The problem is that double-float-epsilon, a constant is now incorrect; i.e. it will not satisfy the criteria on pg 232. Basically the reason is that when using the extended precision mode of the 881, a double round error takes place (rounding the extended precison result to extended precision and then rounding that to a double). In the software, however, only one rounding takes place. Doesn't this only show that this particular method of implementing floating point has a bug in it? You can either live with the bug or not use this method of implementing floating point, whichever you judge is best. Hence, any code compiled on a system in which the floating point constants are folded in-line will fail on 881 systems because the constants no longer satisfy whatever their criteria was. This problem could manifest itself in other instances - for example, optional floating point accelerators in which the numeric format and/or range is different from the host system's. How will that be handled? This I think is a different issue, and a more interesting one. Let me rephrase what I think you are saying: Suppose I have two Lisp systems that are so close to each other that compiled code from one can be loaded into the other. The only difference between them is that they use different floating-point formats. Should the Common Lisp language be changed to allow me to call these two Lisp systems one Lisp system that from time to time changes its floating-point format, by changing these constants to variables? My reaction is that I'm uncomfortable with changing the definition of the language to provide such a specialized feature (compiled code portability between two similar implementations). Perhaps there is another solution that doesn't involve changing the language. One obvious candidate is this: if you have two different floating-point formats, don't call them by the same name. Perhaps you can call one of them double and the other one long. If the total number of formats is more than four, introduce some more floating-point types (the manual pp.33-5 appears to allow this.)  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 18 Apr 86 23:24:44 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 18 Apr 86 20:11:40 PST Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 466463; Fri 18-Apr-86 00:49:38-EST Date: Fri, 18 Apr 86 00:50 EST From: Kent M Pitman Subject: (PROCLAIM '(IGNORE ...)) To: greek%bach.decnet@hudson.dec.com cc: common-lisp@SU-AI.ARPA In-Reply-To: The message of 17 Apr 86 09:41-EST from "BACH::GREEK" References: <860416222044.5.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM> Message-ID: <860418005011.3.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM> Date: 17 Apr 86 09:41:00 EST From: "BACH::GREEK" The book says that the IGNORE declaration affects only variable bindings. I think this is trying to say that you can't proclaim an ignore. I dunno. The wording is kinda fuzzy if you ask me. Is it really that hard to put the appropriate declarations in the (hopefully) few places where you want to ignore something? Yes, it is somewhat of a hassle because it does occur a lot. Macsyma, for example, has a couple hundred functions which either ignore some argument or which MULTIPLE-VALUE-BIND for a set of quantities, some of which will need to be ignored. Writing the IGNORE declaration wastes lots of screen space and sometimes makes just enough difference to make it impossible to see an entire definition on one screen. (I didn't write those definitions so please no lectures about how such functions are too long; I agree, but it's not always so easy a thing to fix and I have more important things to be doing with my time anyway.) The places where I find the use of an IGNORE variable especially attractive are things like: (MAPCAR #'(LAMBDA (IGNORE) (GENSYM)) THINGS) This is short and to-the-point. Having to write: (MAPCAR #'(LAMBDA (THING) (DECLARE (IGNORE THING)) (GENSYM)) THINGS) makes the form wide enough and cluttered enough that it starts to be hard to read. Also, as a point of style I like to break multi-statement LAMBDAs onto multiple lines, and end up writing: (MAPCAR #'(LAMBDA (THING) (DECLARE (IGNORE THING)) (GENSYM)) THINGS) which I find to be readable, but which unfortunately uses a ridiculous amount of screen space to say something which should be much shorter and punchier. Sometimes it makes sense to (DECLARE (IGNORE ...)). For example, I may do: (DEFUN CURSOR-Y () (MULTIPLE-VALUE-BIND (X Y) (CURSOR-POSITION) (DECLARE (IGNORE X)) Y)) because it provides a kind of documentation in spite of its obvious waste of vertical space. Plenty of my co-workers wouldn't dream of writing anything other than this: (DEFUN CURSOR-Y () (MULTIPLE-VALUE-BIND (IGNORE Y) (CURSOR-POSITION) Y)) In other situations, though, I may not know or care what the thing is that I'm ignoring, so it's a pain to have to think up a name for the argument. For example, sometimes I just want to do: (DEFUN DRAW-LINE (&REST IGNORE) (ERROR "I don't know how to draw a line.")) and I resent having to do: (DEFUN DRAW-LINE (&REST WHATEVER) (DECLARE (IGNORE WHATEVER)) (ERROR "I don't know how to draw a line.")) because I think it's visual clutter to no good end. In fact, there is at least one family of functions in Macsyma which we've just never gotten around to fixing which take three arguments, the middle of which is always ignored. NIL is always passed as the actual argument, so there is really no proper name for the incoming data, the true purpose is long-since forgotten. Instead, the functions all look like: (DEFUN FOO (X VESTIGIAL Y) (DECLARE (IGNORE VESTIGIAL)) ...) but again I'd prefer to be doing just (DEFUN FOO (X IGNORE Y) ...) One of these days I'll get around to just changing the arg conventions and updating all the callers, but in the meantime I find it distracting to waste a screen line for a nonsensical declaration. The real problem in my mind is that there is nothing in error about the following code: (LAMBDA (X Y) X) There is really no reason for the compiler to be warning me about it. This sort of thing used to be the bread and butter of the lambda calculus. You'd never have been able to write a serious program without it. It's quite well-formed. It has an obvious interpretation. Warnings about code like this from modern compilers is presumably intended as a courtesy to me because someone thinks it's unlikely that I would really want to do this. There are certainly many possible good reasons for doing it, though. As such, the thing that warns me should take reasonable steps to notice any clues that I might have given that would suggest that I might not want to be bothered about this. I suggest that (LAMBDA (X IGNORE) X) is about as blatant a clue as I can think of. Heck, I'm even willing to write: (PROCLAIM '(IGNORE IGNORE)) to make it doubly clear that when I really mean to ignore IGNORE. I'm not asking for natural language parsing, after all. So here I am bending over backward with a desire to tell compilers that it's OK to not warn me about dozens of functions that weren't in error in the first place and some of the compilers just aren't going to want to listen... Sigh.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 18 Apr 86 23:24:23 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 18 Apr 86 20:12:45 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 467060; Fri 18-Apr-86 17:31:08-EST Date: Fri, 18 Apr 86 17:30 EST From: David A. Moon Subject: Should the floating-point constants really be constants? To: common-lisp@SU-AI.ARPA In-Reply-To: The message of 16 Apr 86 15:51 EST from hpfclp!paul@hplabs.ARPA Message-ID: <860418173043.9.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Wed, 16 Apr 86 12:51:09 pst From: hpfclp!paul@hplabs.ARPA Question: Should the floating point constants on pgs. 231-232 of CLtL really be constants? Here is an example. Take the constant double-float-epsilon. Suppose it is derived on a system in which doubles are IEEE 64 bit format, and in which the rounding precision is round to double. Fine. Now suppose we want to use an MC68881, and we want to use the default rounding precision (round to extended) because it is faster and gives "better" results. The problem is that double-float-epsilon, a constant is now incorrect; i.e. it will not satisfy the criteria on pg 232. Basically the reason is that when using the extended precision mode of the 881, a double round error takes place (rounding the extended precison result to extended precision and then rounding that to a double). In the software, however, only one rounding takes place. Doesn't this only show that this particular method of implementing floating point has a bug in it? You can either live with the bug or not use this method of implementing floating point, whichever you judge is best. Hence, any code compiled on a system in which the floating point constants are folded in-line will fail on 881 systems because the constants no longer satisfy whatever their criteria was. This problem could manifest itself in other instances - for example, optional floating point accelerators in which the numeric format and/or range is different from the host system's. How will that be handled? This I think is a different issue, and a more interesting one. Let me rephrase what I think you are saying: Suppose I have two Lisp systems that are so close to each other that compiled code from one can be loaded into the other. The only difference between them is that they use different floating-point formats. Should the Common Lisp language be changed to allow me to call these two Lisp systems one Lisp system that from time to time changes its floating-point format, by changing these constants to variables? My reaction is that I'm uncomfortable with changing the definition of the language to provide such a specialized feature (compiled code portability between two similar implementations). Perhaps there is another solution that doesn't involve changing the language. One obvious candidate is this: if you have two different floating-point formats, don't call them by the same name. Perhaps you can call one of them double and the other one long. If the total number of formats is more than four, introduce some more floating-point types (the manual pp.33-5 appears to allow this.)  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 18 Apr 86 22:55:32 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 18 Apr 86 19:46:32 PST Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 466458; Thu 17-Apr-86 23:56:29-EST Date: Thu, 17 Apr 86 23:57 EST From: Kent M Pitman Subject: slotp To: marchett%cod@NOSC.ARPA, common-lisp@SU-AI.ARPA In-Reply-To: <8604171608.AA25949@cod.ARPA> Message-ID: <860417235708.2.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM> Date: Thu, 17 Apr 86 08:08:14 PST From: David J. Marchette Is there an easy way to tell if an instance variable (or slot) is available in a particular structure? What good would it do to have a SLOTP predicate? What operation can you do on a structure once you know it has such a slot? The point is that you're not supposed to go around looking for slots by name except maybe in a debugger, and debuggers are intended to be provided in an implementation-dependent fashion by each system. It's a data-abstraction violation to know what a structure calls its slot names. If you're supposed to be poking about in the structure, the person who authorized you to do so will have given you the following information: a symbol which can be used as a second argument to TYPEP to tell if you have one of the structures in question, a function which creates such structures and/or a set of functions which will access their slots, and documentation on how to use those accessors correctly.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 18 Apr 86 16:34:07 EST Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 18 Apr 86 13:24:09 PST Date: 18 Apr 1986 16:07-EST Sender: NGALL@G.BBN.COM Subject: Type Specifier: (OR (FUNCTION ...) ...) From: NGALL@G.BBN.COM To: common-lisp@SU-AI.ARPA Message-ID: <[G.BBN.COM]18-Apr-86 16:07:14.NGALL> Question: What is the 'most informative' type specifier for the CL function COPY-SEQ? How 'bout? (function (sequence) sequence) Unfortunately, this does not tell the reader nor the compiler that if the argument is a list, then the result is also a list, and vice versa. So how about this: (or (function (list) list) (function (vector) vector)) This is syntactically valid CL, and the definition of the OR and FUNCTION type specifiers makes it meaningful. Unfortunately, it is not clear from pg. 158 whether or not the following is legal: (proclaim '(ftype (or (function (list) list) (function (vector) vector)) copy-seq)) It is not legal in VaxLisp, and my guess is that there aren't any implementations that would do the right thing with it. So I would like to propose that such a use of OR/FUNCTION be considered legal CL. Without such a declaration, one is forced to either wrap (the ...) around all calls to such functions or to DECLARE a restricted version of FUNCTION in the appropriate places, e.g., (defun foo (alist avector) (declare (list alist) (vector avector) (function copy-seq (list) list)) (zap (copy-seq alist) (let () (declare (function copy-seq (vector) vector)) (zoop (copy-seq avector)))) Either method is a real pain. This use of OR would give CL something akin to Ada overloading. It allows the overloading of multiple 'function type signatures' on a single function name. Such overloading is already implicit throughout CL (esp. the seq. functions). My proposal would merely allow a way of describing it. -- Nick  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 18 Apr 86 12:48:23 EST Received: from HUDSON.DEC.COM by SU-AI.ARPA with TCP; 18 Apr 86 09:39:26 PST Date: 18 Apr 86 12:26:00 EST From: "BACH::GREEK" Subject: Bit fields in structures. To: "common-lisp" Reply-To: "BACH::GREEK" I agree with Rob that we should stay away from this issue. In particular, if people want features for interfacing with alien languages, then Common LISP should include an alien structure and alien routine facility, separate from the rest of the language. I think this for two reasons. 1. There are a lot of features needed to adequately support alien languages, and we ought to put them in one place instead of sprinkling them around the language. 2. We could all too easily invent features that some implementations couldn't handle. This is less likely if there is one facility, carefully designed, with hooks for additional system-dependent goodies. - Paul ------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 18 Apr 86 12:18:33 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 18 Apr 86 09:11:13 PST Received: ID ; Fri 18 Apr 86 12:13:34-EST Date: Fri, 18 Apr 1986 12:13 EST Message-ID: From: Rob MacLachlan To: Dave.Touretzky@A.CS.CMU.EDU Cc: common-lisp@SU-AI.ARPA Subject: Plummer wins In-reply-to: Msg of 17 Apr 1986 18:51-EST from Dave.Touretzky at A.CS.CMU.EDU Well, I haven't said anything yet because I was hoping that this discussion would die without any help. I strongly believe that nothing even remotely resembling bit-fields should be a part of Common Lisp. There seem to be two general kinds of uses for this thing: 1] External interfaces in which the exact bit layout must be specified. 2] Compact representation of structures containing small integers. The bit-field mechanism is more oriented to systems hacking, in that it allows the exact layout of bits to be specified. This is necessary for systems hacking but is totally unnecessary for the second class of uses. This exact-layout provision is also the cause of portability problems with respect to fixnum size. It seems pretty clear that the only portable programs that could use bit-fields would use it simply to get compact record structures. As people have observed, nothing prevents the current defstruct from representing fields compactly, at least in the named case. The only other justification for putting bit-fields in Common Lisp is that it is so obviously useful for systems hacking that we might as well standardize it. I strongly disagree with this view. At one time we had a mechanism similar to defstruct with bit-fields; although it was more general than what is proposed, we found it totally inadequate for specifying our external interfaces. It might be worth adding a :optimize defstruct keyword which could be used to specifiy whether the representation should be optimized for speed or space. It might also be worth relaxing the defstruct specification so that even typed structures could have packed fields. Rob  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 18 Apr 86 10:04:28 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 18 Apr 86 06:48:34 PST Received: ID ; Fri 18 Apr 86 09:50:10-EST Date: Fri, 18 Apr 1986 09:50 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: What is a compiler (vol. 63827) meets what are gensyms. In-reply-to: Msg of 17 Apr 1986 17:15-EST from Gregor.pa at Xerox.COM Unless I'm missing soemthing very subtle, I think that your example is legal Common Lisp. I don't think the current manual actually forces you to compile that Defsetf, but whether or not it is compiled, the dumper has no business losing track of the EQ-ness of the symbols, whether or not they are interned anywhere. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 17 Apr 86 19:20:00 EST Received: from A.CS.CMU.EDU by SU-AI.ARPA with TCP; 17 Apr 86 16:09:50 PST Date: 17 Apr 86 18:51 EST From: Dave.Touretzky@A.CS.CMU.EDU To: common-lisp@SU-AI.ARPA Subject: Plummer wins I like Plummer's revised proposal (including boolean fields) better than my revised proposal. Nobody else has said anything on the issue. So now what happens? That is, what does it take to get this feature added to the next revision of the Common Lisp standard? -- Dave  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 17 Apr 86 17:43:50 EST Received: from XEROX.COM by SU-AI.ARPA with TCP; 17 Apr 86 14:32:32 PST Received: from Semillon.ms by ArpaGateway.ms ; 17 APR 86 14:19:29 PST Date: Thu, 17 Apr 86 14:15 PST From: Gregor.pa@Xerox.COM Subject: What is a compiler (vol. 63827) meets what are gensyms. To: Common-Lisp@SU-AI.arpa cc: Gregor.pa@Xerox.COM Message-ID: <860417141538.0.GREGOR@AVALON.XEROX-PARC> Line-fold: no In this issue the subject of what compile file is required to do with top-level forms meets the subject of top-level calls to macros which expand into code containing gensyms. Suppose I have the following macro. (defmacro foo (x y) (let ((var (gensym)) (nv-var (gensym))) `(progn (defun ,x ..) (defun ,y ..) (defsetf ,x (,var) (,nv-var) `(,',y ,,var ,,nv-var))))) And I have a file that includes the form: (FOO BAR SET-BAR) [ For clarities sake, the point is that the macro expands to a progn that includes a defsetf that has gensyms for the access-function-args and storing-variables, like this: (DEFSETF BAR (#:G1890) (#:G1891) `(SET-BAR ,#:G1890 ,#:G1891)) ] Is compiling and loading the file legal Common Lisp? Is the original foo macro legal Common Lisp? I claim that the answer to both questions is yes. After all, it is clearly legal interpreted/compiled to core Common Lisp. I believe that CLtL is "silent" on this issue. I got bit by a Common Lisp compiler which macroexpands top-level forms, but which does not necessarily compile the entire result of the macroexpansion. In this particular case the compiler expanded the two defuns, but left the defsetf as (store-setf ') Then the dumper dumped that list in such a way that when the file was loaded the gensyms which should have been eq were not. -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 17 Apr 86 14:37:10 EST Received: from [192.10.41.45] by SU-AI.ARPA with TCP; 17 Apr 86 11:23:22 PST Received: from FIREBIRD.SCRC.Symbolics.COM by ALLEGHENY.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 12617; Thu 17-Apr-86 12:44:09-EST Date: Thu, 17 Apr 86 12:41 EST From: David C. Plummer Subject: extending defstruct To: Dave.Touretzky@A.CS.CMU.EDU, common-lisp@SU-AI.ARPA In-Reply-To: The message of 16 Apr 86 23:55 EST from Dave.Touretzky@A.CS.CMU.EDU Message-ID: <860417124125.3.DCP@FIREBIRD.SCRC.Symbolics.COM> Date: 16 Apr 86 23:55 EST From: Dave.Touretzky@A.CS.CMU.EDU I want to modify my suggestion for the syntax of byte fields in defstruct in response to David Plummer's note. First, in order to be compatible with existing CLtL syntax (as opposed to Zetalisp), the first element of the slot description should be a *list* of byte field descriptions; thus we follow the convention that the car of a slot descriptor names the slot(s), and the cdr contains default values and options. Second, there is no need for a :byte-field keyword, since the shape of every byte field *must* be specified. Even so, I think the :byte-field keyword should be there for consistency. There's another reason: consider the possibility of boolean fields (NIL/T instead of 0/1). This could look like :boolean-field instead of :byte-field. There is no reason why bytes and booleans can't be mixed. Also, there is no hard reason why a boolean field need be 1 bit wide. (This assumes any 1 is truth, and that setting to truth sets all bits.) Also, the shape of every byte field does NOT need to be specified. Consider (defstruct thingie (foo 'default-foo-value) ((whole-second-slot 0 :type fixnum) (low-bar nil (byte 8 0)) (mid-bar #x00 (byte 8 8) :read-only t) (high-bar #x1a (byte 8 16))) (baz 'default-baz-value)) This is a natural place to declare the whole-second-slot to be of type fixnum. So I propose the following: (defstruct thingie (foo 'default-foo-value) ((low-bar nil (byte 8 0)) (mid-bar #x00 (byte 8 8) :read-only t) (high-bar #x1a (byte 8 16))) (baz 'default-baz-value)) Some notes: (1) A slot that is divided up into byte fields should be restricted to type fixnum unless the user explicitly specifies that it should be a bignum (or something else) via the :type keyword. So byte specifiers that exceed the dimensions of a fixnum (or whatever type is specified) should generate an error. I disagree with this because it can lead to non-portable code, that is, it depends on the size of fixnums. I think the default should be integer and the user must explicitly state fixnum. As stated above, the :TYPE keyword could be awkward in the individual bytes and is better placed in the whole slot descriptor. (2) the list of byte field descriptors may also contain as its first element a symbol, in which case the symbol is taken to be the name of the entire slot. I'm confused. Maybe that's why you had an extra (, for a total of three, before low-bar? I think there is too much symmetry being broken. (3) Per Plummer's suggestion, a default value of NIL for a byte field means ``no default.'' (4) If the user specifies incompatible defaults for overlapping byte fields, an error should be generated. (5) If overlapping byte fields are both filled by a constructor, or if one is filled by a default and the other by a constructor, the results of the operation are undefined. Here's another example: (defstruct gadget (common-name nil) ((feature-bits (input-size nil (byte 3 0)) (output-size nil (byte 3 3) :read-only t) (clock-pins nil (byte 2 6)) (internal-store nil (byte 10 8))) #x12345 :type fixnum) (gadget-cost :type short-float)) [Gadget-cost default??] The slot GADGET-FEATURE-BITS is of type fixnum and is divided into four byte fields. Note that in this example we gave the entire slot a default value rather than giving the byte fields separate defaults. For comparison, this is how it would look in my proposed scheme, with some more things that use the boolean-field feature. (defstruct gadget (common-name nil) ((feature-bits #x12345 :type fixnum) (input-size nil :byte-field (byte 3 0)) (output-size nil :byte-field (byte 3 3) :read-only t) (clock-pins nil :byte-field (byte 2 6)) (internal-store nil :byte-field (byte 10 8)) (something-on-p nil :boolean-field (byte 3 18)) (foo-on nil :boolean-field (byte 1 18)) (bar-on nil :boolean-field (byte 1 19)) (baz-on nil :boolean-field (byte 1 20))) (gadget-cost 0.0 :type short-float))  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 17 Apr 86 14:34:26 EST Received: from [192.10.41.45] by SU-AI.ARPA with TCP; 17 Apr 86 11:22:46 PST Received: from FIREBIRD.SCRC.Symbolics.COM by ALLEGHENY.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 12613; Thu 17-Apr-86 12:29:29-EST Date: Thu, 17 Apr 86 12:26 EST From: David C. Plummer Subject: Integer Shift Function(s) To: Scott E. Fahlman , David Singer cc: common-lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860417122623.2.DCP@FIREBIRD.SCRC.Symbolics.COM> Date: Wed, 16 Apr 1986 22:28 EST From: "Scott E. Fahlman" [This looks like a reply.] All of the logical operations are defined in terms of an abstract integer type that is infinitely sign-extended to the left. That way, the machine's word-length, or the length of the data part of its fixnum representation, is hidden. What would a logical shift operation (or a rotate, though you don't ask about that) do in this context? I agree, it can't do anything. An implementation may want to define LSH and ROT operations for its own peculiar fixnum length, but such a thing makes no sense in portable code. JonL, at one point, suggested abstract LSH and ROT operations that take a third argument which is the pretend-I'm-a-fixnum-length. Thus, (rot 1 -1 5) == (ash -1 4) == -16. (lsh -1 -1 6) == #2r011111 == 31. Personally, I think this is cute, but probably not extrememly practical. Also note: I think you will find most uses of LSH and ROT (for those extended Common Lisps that implement them) are almost exclusively inside operating system code.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 17 Apr 86 12:38:47 EST Received: from SRI-KL.ARPA by SU-AI.ARPA with TCP; 17 Apr 86 09:25:37 PST Received: from GODOT.THINK.COM by SRI-KL.ARPA with TCP; Thu 17 Apr 86 09:26:25-PST Received: from sebastian by GODOT.THINK.COM via CHAOS; Thu, 17 Apr 86 12:26:01 est Date: Thu, 17 Apr 86 12:27 EST From: Guy Steele Subject: Integer Shift Function(s) To: DSinger@SRI-KL, common-lisp%SU-AI@SRI-KL Cc: gls@AQUINAS In-Reply-To: <8604170313.AA00311@GODOT.THINK.COM> Message-Id: <860417122722.1.GLS@THINK-SEBASTIAN.ARPA> Date: Wed 16 Apr 86 15:42:31-PST From: David Singer I was translating an Interlisp program into Common Lisp and found that Common Lisp has only arithmetic shift (ash, page 224), and unlike many systems which have shift functions, no logical shift. Is this an oversight, or a deliberate omission? Certainly it's possible to make an lsh function, but taking care of word length etc. is painful and it would (probably) not be as fast as a 'built-in'. (I note that the Symbolics Common Lisp system and Lucid on Sun both provide lsh, but Kyoto on Sun do not ... these are all the Common Lisp systems I have access to). Sorry if this question has previously been raised and answered, or if I have missed something. Dave Singer (dsinger@sri-kl) ------- This was deliberate omission, for essentially the reasons you cite of pain and portability. Note that LDB can handle many of the purposes of LSH. --Guy  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 17 Apr 86 11:24:08 EST Received: from NOSC.ARPA by SU-AI.ARPA with TCP; 17 Apr 86 08:07:09 PST Received: by bass.ARPA (5.31/4.7) id AA01935; Thu, 17 Apr 86 08:08:17 PST Received: by cod.ARPA (5.31/4.7) id AA25949; Thu, 17 Apr 86 08:08:14 PST Date: Thu, 17 Apr 86 08:08:14 PST From: David J. Marchette Message-Id: <8604171608.AA25949@cod.ARPA> To: common-lisp@su-ai Subject: slotp Is there an easy way to tell if an instance variable (or slot) is available in a particular structure? Given an instance of a structure, I'd like an easy way to tell if location is one of its instance variables (or slots). One way would be to inspect the plist of the instances structure: (I don't have a machine available at the moment, but you get the idea) (member 'location (symbol-plist (type-of foobar))) ...or whatever. Is there an easier way, assuming that something like the above would even work? I think something like it would work on the Symbolics, but I don't know if it would be portable. A predefined function slotp would be nice, but such does not seem to be available. Thanks for any help. dave *********************************** * David Marchette * * * * marchett@cod.UUCP * * marchett@noscvax.UUCP * * marchett@cod.nosc.MIL * * ucbvax!sdcsvax!noscvax!marchett * * * * Naval Ocean Systems Center * * Code 421 * * 271 Catalina Blvd. * * San Diego, CA 92152 * * * * Ph. (619) 225-6571 * ***********************************  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 17 Apr 86 10:17:43 EST Received: from HUDSON.DEC.COM by SU-AI.ARPA with TCP; 17 Apr 86 07:01:02 PST Date: 17 Apr 86 09:41:00 EST From: "BACH::GREEK" Subject: (PROCLAIM '(IGNORE ...)) To: "common-lisp" Reply-To: "BACH::GREEK" The book says that the IGNORE declaration affects only variable bindings. I think this is trying to say that you can't proclaim an ignore. Is it really that hard to put the appropriate declarations in the (hopefully) few places where you want to ignore something? - Paul ------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 17 Apr 86 09:34:44 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 17 Apr 86 06:20:03 PST Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 465565; Wed 16-Apr-86 22:20:09-EST Date: Wed, 16 Apr 86 22:20 EST From: Kent M Pitman Subject: (PROCLAIM '(IGNORE ...)) To: Common-Lisp@SU-AI.ARPA Message-ID: <860416222044.5.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM> I know some implementations don't have the "feature" that the variable IGNORE implicitly declared IGNORE by the compiler. My question is, can I do: (PROCLAIM '(IGNORE IGNORE IGNORED IGNORABLE DONT-CARE HUNOZ ...)) to teach those implementations? My reading of CLtL (p160) is that I should be able to. Does anyone disagree?  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 17 Apr 86 02:44:36 EST Received: from A.CS.CMU.EDU by SU-AI.ARPA with TCP; 16 Apr 86 20:54:22 PST Date: 16 Apr 86 23:55 EST From: Dave.Touretzky@A.CS.CMU.EDU To: common-lisp@SU-AI.ARPA Subject: extending defstruct I want to modify my suggestion for the syntax of byte fields in defstruct in response to David Plummer's note. First, in order to be compatible with existing CLtL syntax (as opposed to Zetalisp), the first element of the slot description should be a *list* of byte field descriptions; thus we follow the convention that the car of a slot descriptor names the slot(s), and the cdr contains default values and options. Second, there is no need for a :byte-field keyword, since the shape of every byte field *must* be specified. So I propose the following: (defstruct thingie (foo 'default-foo-value) (((low-bar nil (byte 8 0)) (mid-bar #x00 (byte 8 8) :read-only t) (high-bar #x1a (byte 8 16))) (baz 'default-baz-value)) Some notes: (1) A slot that is divided up into byte fields should be restricted to type fixnum unless the user explicitly specifies that it should be a bignum (or something else) via the :type keyword. So byte specifiers that exceed the dimensions of a fixnum (or whatever type is specified) should generate an error. (2) the list of byte field descriptors may also contain as its first element a symbol, in which case the symbol is taken to be the name of the entire slot. (3) Per Plummer's suggestion, a default value of NIL for a byte field means ``no default.'' (4) If the user specifies incompatible defaults for overlapping byte fields, an error should be generated. (5) If overlapping byte fields are both filled by a constructor, or if one is filled by a default and the other by a constructor, the results of the operation are undefined. Here's another example: (defstruct gadget (common-name nil) ((feature-bits (input-size nil (byte 3 0)) (output-size nil (byte 3 3) :read-only t) (clock-pins nil (byte 2 6)) (internal-store nil (byte 10 8))) #x12345 :type fixnum) (gadget-cost :type short-float)) The slot GADGET-FEATURE-BITS is of type fixnum and is divided into four byte fields. Note that in this example we gave the entire slot a default value rather than giving the byte fields separate defaults. -- Dave  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 17 Apr 86 02:16:39 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 16 Apr 86 19:28:16 PST Received: ID ; Wed 16 Apr 86 22:29:00-EST Date: Wed, 16 Apr 1986 22:28 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: David Singer Cc: common-lisp@SU-AI.ARPA Subject: Integer Shift Function(s) In-reply-to: Msg of 16 Apr 1986 18:42-EST from David Singer All of the logical operations are defined in terms of an abstract integer type that is infinitely sign-extended to the left. That way, the machine's word-length, or the length of the data part of its fixnum representation, is hidden. What would a logical shift operation (or a rotate, though you don't ask about that) do in this context? An implementation may want to define LSH and ROT operations for its own peculiar fixnum length, but such a thing makes no sense in portable code. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 16 Apr 86 23:59:05 EST Received: from SRI-KL.ARPA by SU-AI.ARPA with TCP; 16 Apr 86 18:40:35 PST Date: Wed 16 Apr 86 15:42:31-PST From: David Singer Subject: Integer Shift Function(s) To: common-lisp%SU-AI@SRI-KL I was translating an Interlisp program into Common Lisp and found that Common Lisp has only arithmetic shift (ash, page 224), and unlike many systems which have shift functions, no logical shift. Is this an oversight, or a deliberate omission? Certainly it's possible to make an lsh function, but taking care of word length etc. is painful and it would (probably) not be as fast as a 'built-in'. (I note that the Symbolics Common Lisp system and Lucid on Sun both provide lsh, but Kyoto on Sun do not ... these are all the Common Lisp systems I have access to). Sorry if this question has previously been raised and answered, or if I have missed something. Dave Singer (dsinger@sri-kl) -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 16 Apr 86 21:25:33 EST Received: from SU-SHASTA.ARPA by SU-AI.ARPA with TCP; 16 Apr 86 16:52:40 PST Received: by su-shasta.arpa with TCP; Wed, 16 Apr 86 16:52:32 pst Received: by ntt.junet (4.12/4.7JC-7) CHAOS with CHAOS-MAIL id AA18711; Wed, 16 Apr 86 09:08:16 jst From: hagiya@kurims.kurims.kyoto-u.junet Received: by ntt.junet (4.12/4.7JC-7) CHAOS with CHAOS-MAIL id AA18442; Wed, 16 Apr 86 09:02:50 jst Received: by kurims.kyoto-u.junet (2.0/4.7) id AA00595; Tue, 15 Apr 86 17:08:02 pst Date: Tue, 15 Apr 86 17:08:02 pst Message-Id: <8604160108.AA00595@kurims.kyoto-u.junet> To: COMMON-LISP@SU-AI.ARPA Hi, my name is Masami Hagiya, one of the implementors of a Common Lisp system called KCL (Kyoto Common Lisp). This is a kind of test mail to the Common Lisp mailing list from the UNIX network in Japan, called JUNET. Unfortunately, we don't have direct access to ARPA now. There are many people in Japan who are interested in the development of Common Lisp. For example, in last June, we had a panel discussion on Common Lisp in Information Processing Society of Japan, whose panelists were: Ikuo Takeuchi (NTT) Masayuki Ida (Aoyama-Gakuin Univ.) Michiaki Yasumura (Hitachi) Motoaki Terashima (Denki-Tsushi Univ.) Taiichi Yuasa (Kyoto Univ.) There are also several companies in Japan actually implementing Common Lisp; I don't know whether I can make their names public (oops, you can see two names above). Our Common Lisp system, KCL, is not an evolutional one; our major concern was * faithfulness to CLtL * portability * compactness and simplicity rather than the efficiency or the sophisticated debugging system. The system seems quite comfortable now; it's as efficient as other systems (or, at least, comparable; please look at the benchmarks) and although we've implemented all the functions in CLtL, the system is very small (e.g. KCL/SUN takes only about 1.7 mega). The most interesting thing is that since the system is written in C and the compiler is a Lisp-to-C translator, we can port the system to almost any UNIX (-like) machine. In fact, KCL now runs on many machines including VAX/4.2BSD, SUN2, SUN3, 3B2, MV/AOSVS, Apollo. Articles to the Common Lisp mailing list are now distributed in Japan via SHASTA-NTTLAB. Thank you. Masami Hagiya  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 16 Apr 86 21:10:38 EST Received: from HPLABS.ARPA by SU-AI.ARPA with TCP; 16 Apr 86 13:25:27 PST Received: by hplabs.ARPA ; Wed, 16 Apr 86 12:51:09 pst Date: Wed, 16 Apr 86 12:51:09 pst From: hpfclp!paul@hplabs.ARPA To: common-lisp@SU-AI.ARPA Question: Should the floating point constants on pgs. 231-232 of CLtL really be constants? Here is an example. Take the constant double-float-epsilon. Suppose it is derived on a system in which doubles are IEEE 64 bit format, and in which the rounding precision is round to double. Fine. Now suppose we want to use an MC68881, and we want to use the default rounding precision (round to extended) because it is faster and gives "better" results. The problem is that double-float-epsilon, a constant is now incorrect; i.e. it will not satisfy the criteria on pg 232. Basically the reason is that when using the extended precision mode of the 881, a double round error takes place (rounding the extended precison result to extended precision and then rounding that to a double). In the software, however, only one rounding takes place. Hence, any code compiled on a system in which the floating point constants are folded in-line will fail on 881 systems because the constants no longer satisfy whatever their criteria was. What to do? I see 2 viable solutions: 1). Put the 881 in the same rounding precision as the software. 2). Make the floating point constants variables. This has some precedence; look at float-base, float-digits, and float-precision. This problem could manifest itself in other instances - for example, optional floating point accelerators in which the numeric format and/or range is different from the host system's. How will that be handled? Comments? Paul Beiser Hewlett-Packard Ft. Collins, Colorado uucp: ...{ihnp4!hpfcla,hplabs}!hpfclp!paul arpa: paul%hpfclp@hplabs  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 16 Apr 86 18:32:39 EST Received: from UTAH-20.ARPA by SU-AI.ARPA with TCP; 16 Apr 86 08:08:03 PST Date: Wed 16 Apr 86 09:09:23-MST From: SANDRA Subject: Re: block/tagbody and catch/throw To: RAM@C.CS.CMU.EDU cc: DCP@SCRC-QUABBIN.ARPA, common-lisp@SU-AI.ARPA In-Reply-To: Message-ID: <12199309654.18.LOOSEMORE@UTAH-20.ARPA> Date: Tue, 15 Apr 1986 19:59 EST From: Rob MacLachlan I think that the two examples referred to create more confusion than they eliminate. It is a feature of the language that GO or RETURN can change the dynamic environment. It is obvious from the scope rules that the block or tag is not within the catch, therefore when control is transferred to the block or tag, the catch is no longer in the dynamic environment. How the catch disappears is an implementation detail. It does make some sense to say that these code fragments are legal, but discussion about the implementation is inappropriate in the main text; it only confuses people. I have a feeling that these features are much more surprising to implementors than to users. My thoughts exactly. It should be sufficient to say that the return-from (or go) can appear anywhere within the lexical scope of the block (or tagbody). The current wording about "surprising consequences" is so vague that non-wizardly readers can easily be mislead into thinking the behavior is much more mysterious than that. It should be made clear that the business of breaking up catchers is something that the implementor, not the user, needs to think about. -Sandra -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 15 Apr 86 20:11:25 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 15 Apr 86 16:59:05 PST Received: ID ; Tue 15 Apr 86 19:59:41-EST Date: Tue, 15 Apr 1986 19:59 EST Message-ID: From: Rob MacLachlan To: "David C. Plummer" Cc: common-lisp@SU-AI.ARPA, SANDRA Subject: block/tagbody and catch/throw In-reply-to: Msg of Tue 15 Apr 86 15:22 EST from David C. Plummer Date: Tue, 15 Apr 86 15:22 EST From: David C. Plummer To: SANDRA , Rob MacLachlan , common-lisp at SU-AI.ARPA Re: block/tagbody and catch/throw Date: Tue 15 Apr 86 11:28:18-MST From: SANDRA Am I the only person who finds the descriptions of the interaction between block/tagbody and catch/throw in CLtL confusing? On both pages 120 and 131, it's mentioned that the lexical scoping of the block/tag names "has consequences that may be suprising to users". What are these consequences? Date: Tue, 15 Apr 1986 14:03 EST From: Rob MacLachlan GO and RETURN sometimes need to remove crap from the stack in most implementations. This may involve undoing special bindings and "breaking up catchers." This is a feature of the implementation, not the language. No, "breaking up catchers" is a feature of the language, because a lexical GO has to get back to the lexical environment of the target tag, which may be outside the dynamic extent of some CATCH form. I think that the two examples referred to create more confusion than they eliminate. It is a feature of the language that GO or RETURN can change the dynamic environment. It is obvious from the scope rules that the block or tag is not within the catch, therefore when control is transferred to the block or tag, the catch is no longer in the dynamic environment. How the catch disappears is an implementation detail. It does make some sense to say that these code fragments are legal, but discussion about the implementation is inappropriate in the main text; it only confuses people. I have a feeling that these features are much more surprising to implementors than to users. It may not be obvious that a particular combination is legal, but it should be fairly obvious what it does as long as you haven't been damaged too much by Lisps with bizzare scope rules. Rob  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 15 Apr 86 15:41:49 EST Received: from [192.10.41.45] by SU-AI.ARPA with TCP; 15 Apr 86 12:25:14 PST Received: from FIREBIRD.SCRC.Symbolics.COM by ALLEGHENY.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 12323; Tue 15-Apr-86 15:24:52-EST Date: Tue, 15 Apr 86 15:22 EST From: David C. Plummer Subject: block/tagbody and catch/throw To: SANDRA , Rob MacLachlan , common-lisp@SU-AI.ARPA In-Reply-To: <12199072800.26.LOOSEMORE@UTAH-20.ARPA>, Message-ID: <860415152211.9.DCP@FIREBIRD.SCRC.Symbolics.COM> Date: Tue 15 Apr 86 11:28:18-MST From: SANDRA Am I the only person who finds the descriptions of the interaction between block/tagbody and catch/throw in CLtL confusing? On both pages 120 and 131, it's mentioned that the lexical scoping of the block/tag names "has consequences that may be suprising to users". What are these consequences? After being told that my intuitions about their behavior may be wrong, it's confusing to be told in the very next sentence that the examples work "as one might expect"; at this point, I don't really know *what* to expect! It would be helpful to describe the behavior of the examples in more detail instead of resorting to hand-waving. The reference to "breaking up catchers" in the following paragraph should also be explained in more detail. block/tagbody have lexical scope and dynamic extent. catch/throw have dynamic scope and dynamic extent. Things work 'as one might expect' if you fully understand that. If you don't fully understand that, it may have "consequences that may be surprising." Granted the manual could probably use improving. Date: Tue, 15 Apr 1986 14:03 EST From: Rob MacLachlan There is no language-level interaction between catch and throw and the lexical control mechanisms. To someone who understands lexical scoping, RETURN and GO do "what one might expect." The tag or block referred to is the one lexically apparent at the point of the GO or RETURN. People more familiar with dynamic scoping "may be surprised", since the lexically apparent tag or block is not necessarly the dynamically innermost one. GO and RETURN sometimes need to remove crap from the stack in most implementations. This may involve undoing special bindings and "breaking up catchers." This is a feature of the implementation, not the language. No, "breaking up catchers" is a feature of the language, because a lexical GO has to get back to the lexical environment of the target tag, which may be outside the dynamic extent of some CATCH form.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 15 Apr 86 14:36:50 EST Received: from XEROX.COM by SU-AI.ARPA with TCP; 15 Apr 86 11:24:39 PST Received: from Cabernet.ms by ArpaGateway.ms ; 15 APR 86 11:24:22 PST Date: 15 Apr 86 11:22 PST From: Daniels.pa@Xerox.COM Subject: Re: unwind-protect description In-reply-to: "George J. Carrette" 's message of Tue, 15 Apr 86 07:13:50 EST To: GJC@MC.LCS.MIT.EDU cc: gls@AQUINAS.THINK.COM, common-lisp@SU-AI.ARPA Message-ID: <860415-112422-1346@Xerox> "(unwind-protect body1 body2) => (*unwind-protect #'(lambda () body1) #'(lambda () body2)) Which makes the environment issue clear" This only addresses the lexical environment of the cleanup forms. It says nothing about the dynamic environment. -- Andy. --  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 15 Apr 86 14:27:33 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 15 Apr 86 11:13:40 PST Received: ID ; Tue 15 Apr 86 14:03:16-EST Date: Tue, 15 Apr 1986 14:03 EST Message-ID: From: Rob MacLachlan To: SANDRA Cc: common-lisp@SU-AI.ARPA Subject: block/tagbody and catch/throw In-reply-to: Msg of 15 Apr 1986 13:28-EST from SANDRA There is no language-level interaction between catch and throw and the lexical control mechanisms. To someone who understands lexical scoping, RETURN and GO do "what one might expect." The tag or block referred to is the one lexically apparent at the point of the GO or RETURN. People more familiar with dynamic scoping "may be surprised", since the lexically apparent tag or block is not necessarly the dynamically innermost one. GO and RETURN sometimes need to remove crap from the stack in most implementations. This may involve undoing special bindings and "breaking up catchers." This is a feature of the implementation, not the language. Rob  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 15 Apr 86 13:40:19 EST Received: from UTAH-20.ARPA by SU-AI.ARPA with TCP; 15 Apr 86 10:28:04 PST Date: Tue 15 Apr 86 11:28:18-MST From: SANDRA Subject: block/tagbody and catch/throw To: common-lisp@SU-AI.ARPA Message-ID: <12199072800.26.LOOSEMORE@UTAH-20.ARPA> Am I the only person who finds the descriptions of the interaction between block/tagbody and catch/throw in CLtL confusing? On both pages 120 and 131, it's mentioned that the lexical scoping of the block/tag names "has consequences that may be suprising to users". What are these consequences? After being told that my intuitions about their behavior may be wrong, it's confusing to be told in the very next sentence that the examples work "as one might expect"; at this point, I don't really know *what* to expect! It would be helpful to describe the behavior of the examples in more detail instead of resorting to hand-waving. The reference to "breaking up catchers" in the following paragraph should also be explained in more detail. -Sandra -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 15 Apr 86 11:05:08 EST Received: from SCRC-QUABBIN.ARPA by SU-AI.ARPA with TCP; 15 Apr 86 07:52:52 PST Received: from FIREBIRD.SCRC.Symbolics.COM by SCRC-QUABBIN.ARPA via CHAOS with CHAOS-MAIL id 264679; Tue 15-Apr-86 09:44:46-EST Date: Tue, 15 Apr 86 09:40 EST From: David C. Plummer Subject: bit fields in defstruct To: Dave.Touretzky@A.CS.CMU.EDU, common-lisp@SU-AI.ARPA In-Reply-To: The message of 15 Apr 86 00:17 EST from Dave.Touretzky@A.CS.CMU.EDU Message-ID: <860415094007.3.DCP@FIREBIRD.SCRC.Symbolics.COM> Date: 15 Apr 86 00:17 EST From: Dave.Touretzky@A.CS.CMU.EDU Can someone tell me why Common Lisp defstruct doesn't support bit fields? This is a Zetalisp feature that I make heavy use of. The equivalent feature in Common Lisp would look something like: (defstruct thingie (foo 'default-foo-value) ((low-bar (byte 8 0)) (mid-bar (byte 8 8) #x00 :read-only t) ;filled by constructor (high-bar (byte 8 12) #x1a)) (baz 'default-baz-value)) This makes THINGIE a vector with 4 elements (counting the structure name); the second element is an integer with default value #x1a0000. The structure has 5 access functions: THINGIE-FOO THINGIE-LOW-BAR THINGIE-MID-BAR THINGIE-HIGH-BAR THINGIE-BAZ The access function for -BAR slots expands to a LDB, and the SETF macro expands to a DPB. The knowledge that three of the slots of a THINGIE are bit fields of the same integer is hidden from the rest of the program. The reason I need this feature is I am building thousands of instances of a particular structure, and the difference between representing half a dozen bit fields with one integer versus six integers is significant in terms of memory cost. I don't think a user should build his own access functions for bit fields; I think defstruct should do that for him. Two things: (1) Syntax. What do you think about (defstruct thingie (foo 'default-foo-value) ((low-bar 0 :byte-field (byte 8 0)) (mid-bar #x00 :byte-field (byte 8 8) :read-only t) (high-bar #x1A :byte-field (byte 8 12))) (baz 'default-baz-value)) instead of yours? Yes, I know the default value must be specified, but this syntax is consistent with non-nested syntax. I propose that a value of NIL means that it isn't filled in (and isn't forced to zero (see [3]). (2) Performance. Users should be wary that doing such things has efficiency issues depending on the boundaries between fixnum and bignum. That is, since the fields are integers, a user could accidentally go consing a lot of bignums, where a normal defstruct wouldn't. [3, In your example, mid-bar and high-bar overlap. mid-bar gets filled in by the constructor, and high-bar has a default. How are these merged, since they overlap?] PS: I suppose if defstruct were highly optimizing one could declare six fields of :TYPE BIT and expect them to be packed into one word. This doesn't solve everything though; in some cases (like when communicating with external programs) one wants to specify the exact postion of each bit field in a word. Also, one might want to have overlapping bit fields in the same word, such as three 1-bit fields and a 3-bit field that covers them. Indeed, this is one of the motivations for Symbolics extending defstruct along these lines. Normal users don't need this; it is usually used for interfacing to hardware device registers, and sometimes network packets that have overlapping fields themselves.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 15 Apr 86 07:26:45 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 15 Apr 86 04:17:46 PST Date: Tue, 15 Apr 86 07:18:49 EST From: "George J. Carrette" Subject: contents of SYMBOL-FUNCTION for special forms. To: common-lisp@SU-AI.ARPA In-reply-to: Msg of Mon 14 Apr 86 05:00 EST from Christopher Fry Message-ID: <[MC.LCS.MIT.EDU].884888.860415.GJC> Intent clarification: Is the manual really trying to say that (SYMBOL-FUNCTION 'SETQ) *must* return something when it says that it "may return something for special forms and macros" ??? Do we really want (FBOUNDP 'SETQ) => T?  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 15 Apr 86 07:22:10 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 15 Apr 86 04:12:37 PST Date: Tue, 15 Apr 86 07:13:50 EST From: "George J. Carrette" Subject: unwind-protect description To: gls@AQUINAS.THINK.COM cc: common-lisp@SU-AI.ARPA In-reply-to: Msg of Mon 14 Apr 86 13:12 EST from Guy Steele Message-ID: <[MC.LCS.MIT.EDU].884886.860415.GJC> You could word it by giving an implementation of unwind-protect as a macro in terms of other primitives. The first step is of course (unwind-protect body1 body2) => (*unwind-protect #'(lambda () body1) #'(lambda () body2)) Which makes the environment issue clear. Then, given a form of catch and throw called %CATCH and %THROW that do not take a TAG first argument you can implement common-lisp CATCH and THROW while taking care of unwind protect quite neatly.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 15 Apr 86 00:26:58 EST Received: from A.CS.CMU.EDU by SU-AI.ARPA with TCP; 14 Apr 86 21:16:58 PST Date: 15 Apr 86 00:17 EST From: Dave.Touretzky@A.CS.CMU.EDU To: common-lisp@SU-AI.ARPA Subject: bit fields in defstruct Can someone tell me why Common Lisp defstruct doesn't support bit fields? This is a Zetalisp feature that I make heavy use of. The equivalent feature in Common Lisp would look something like: (defstruct thingie (foo 'default-foo-value) ((low-bar (byte 8 0)) (mid-bar (byte 8 8) #x00 :read-only t) ;filled by constructor (high-bar (byte 8 12) #x1a)) (baz 'default-baz-value)) This makes THINGIE a vector with 4 elements (counting the structure name); the second element is an integer with default value #x1a0000. The structure has 5 access functions: THINGIE-FOO THINGIE-LOW-BAR THINGIE-MID-BAR THINGIE-HIGH-BAR THINGIE-BAZ The access function for -BAR slots expands to a LDB, and the SETF macro expands to a DPB. The knowledge that three of the slots of a THINGIE are bit fields of the same integer is hidden from the rest of the program. The reason I need this feature is I am building thousands of instances of a particular structure, and the difference between representing half a dozen bit fields with one integer versus six integers is significant in terms of memory cost. I don't think a user should build his own access functions for bit fields; I think defstruct should do that for him. -- Dave PS: I suppose if defstruct were highly optimizing one could declare six fields of :TYPE BIT and expect them to be packed into one word. This doesn't solve everything though; in some cases (like when communicating with external programs) one wants to specify the exact postion of each bit field in a word. Also, one might want to have overlapping bit fields in the same word, such as three 1-bit fields and a 3-bit field that covers them.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 14 Apr 86 21:23:56 EST Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 14 Apr 86 10:11:46 PST Received: from sebastian by GODOT.THINK.COM via CHAOS; Mon, 14 Apr 86 13:11:10 est Date: Mon, 14 Apr 86 13:12 EST From: Guy Steele Subject: unwind-protect To: Pavel.pa@Xerox.COM, common-lisp@SU-AI.ARPA Cc: vanMelle.pa@Xerox.COM, gls@THINK-AQUINAS.ARPA In-Reply-To: <860411-194759-1452@Xerox> Message-Id: <860414131231.1.GLS@THINK-SEBASTIAN.ARPA> Date: 11 Apr 86 19:47 PST From: Pavel.pa@Xerox.COM What is the result of this code: (proclaim '(special *foo*)) (let* ((x 'good) (*foo* x)) (block bar (unwind-protect (let ((*foo* 'bad)) (return-from bar)) (setq x *foo*))) x) The Zetalisp manual says it will return GOOD, but the silver book is silent on the issue. This should be clarified. Pavel I also believe that it should return GOOD. There should be some prose in the silver book (not there now) that says that the cleanup-forms are executed in the dynamic environment of the unwind-protect form itself. Loosely speaking, it is as if there were a TAGBODY tag just in front of the first cleanup form, and any exit causes a transfer of control to that tag as if by a GO (but with further actions pending, such as the returning of a value or resumption of a THROW). This will be very hard to word properly. --Guy  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 14 Apr 86 20:37:44 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 14 Apr 86 05:56:19 PST Received: from FIREBIRD.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 462563; Mon 14-Apr-86 08:56:18-EST Date: Mon, 14 Apr 86 08:53 EST From: David C. Plummer Subject: unwind-protect To: Pavel.pa@Xerox.COM, common-lisp@SU-AI.ARPA cc: vanMelle.pa@Xerox.COM In-Reply-To: <860411-194759-1452@Xerox> Message-ID: <860414085344.8.DCP@FIREBIRD.SCRC.Symbolics.COM> Date: 11 Apr 86 19:47 PST From: Pavel.pa@Xerox.COM What is the result of this code: (proclaim '(special *foo*)) (let* ((x 'good) (*foo* x)) (block bar (unwind-protect (let ((*foo* 'bad)) (return-from bar)) (setq x *foo*))) x) The Zetalisp manual says it will return GOOD, but the silver book is silent on the issue. This should be clarified. The only possible clarification is an infinite enumeration of scoping examples. The scope of the binding of *FOO* to 'BAD does NOT include the SETQ in the cleanup clause. In other words, the ONLY time *FOO* has the value BAD is during the (dynamic extent) of the body of the LET clause. The cleanup is outside the LET and therefore the dynamic extent has finished.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 14 Apr 86 19:42:31 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 14 Apr 86 01:59:44 PST Received: from DUANE.AI.MIT.EDU by OZ.AI.MIT.EDU via Chaosnet; 14 Apr 86 05:01-EST Date: Mon, 14 Apr 86 05:00 EST From: Christopher Fry Subject: Successor to eval-when? To: RAM@C.CS.CMU.EDU, common-lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860414050020.7.CFRY@DUANE.AI.MIT.EDU> Received: from MC.LCS.MIT.EDU by OZ.AI.MIT.EDU via Chaosnet; 10 Apr 86 04:17-EST Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 10 Apr 86 04:16:41 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 10 Apr 86 00:50:38 PST Received: ID ; Thu 10 Apr 86 03:51:25-EST Date: Thu, 10 Apr 1986 03:51 EST Message-ID: From: Rob MacLachlan To: common-lisp@SU-AI.ARPA Subject: Successor to eval-when? If anyone has an idea for a replacement to eval-when, speak up. I don't have any idea of anything that would be better. There seem to be two main reasons people are upset with eval-when: 1] It is currently ill-defined. 2] It is hard to understand. I believe that the first problem is fairly easy to fix; I suspect that the second problem is inherent in the nature of the beast. Rob It is also poorly named according to the semantics that people seem to have agreed upon.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 14 Apr 86 19:39:44 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 14 Apr 86 16:29:55 PST Date: Mon, 14 Apr 86 18:43:38 EST From: "George J. Carrette" To: common-lisp@SU-AI.ARPA Message-ID: <[MC.LCS.MIT.EDU].884011.860414.GJC> A user pointed out that the CL manual specifies that (FBOUNDP 'SETQ) must be T (true). And that also symbol-function of a special form should return . Is this a correct reading? There are a few uses of the word "may be" on that page that could be confusing.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 14 Apr 86 18:51:53 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 14 Apr 86 15:40:32 PST Date: Mon, 14 Apr 86 18:41:30 EST From: Jonathan A Rees Subject: Are isomorphic structures EQUAL? To: NGALL@BBNG.ARPA cc: nlp@BBN-LABS-B.ARPA, common-lisp@SU-AI.ARPA In-reply-to: Msg of 11 Apr 1986 16:43-EST from NGALL at G.BBN.COM Message-ID: <[MC.LCS.MIT.EDU].884004.860414.JAR> Date: 11 Apr 1986 16:43-EST From: NGALL at G.BBN.COM What happens to implementations that want to represent structures using plain old vectors?... If this isn't forbidden by the language spec, it ought to be. Jonathan  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 14 Apr 86 17:10:03 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 14 Apr 86 01:59:44 PST Received: from DUANE.AI.MIT.EDU by OZ.AI.MIT.EDU via Chaosnet; 14 Apr 86 05:01-EST Date: Mon, 14 Apr 86 05:00 EST From: Christopher Fry Subject: Successor to eval-when? To: RAM@C.CS.CMU.EDU, common-lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860414050020.7.CFRY@DUANE.AI.MIT.EDU> Received: from MC.LCS.MIT.EDU by OZ.AI.MIT.EDU via Chaosnet; 10 Apr 86 04:17-EST Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 10 Apr 86 04:16:41 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 10 Apr 86 00:50:38 PST Received: ID ; Thu 10 Apr 86 03:51:25-EST Date: Thu, 10 Apr 1986 03:51 EST Message-ID: From: Rob MacLachlan To: common-lisp@SU-AI.ARPA Subject: Successor to eval-when? If anyone has an idea for a replacement to eval-when, speak up. I don't have any idea of anything that would be better. There seem to be two main reasons people are upset with eval-when: 1] It is currently ill-defined. 2] It is hard to understand. I believe that the first problem is fairly easy to fix; I suspect that the second problem is inherent in the nature of the beast. Rob It is also poorly named according to the semantics that people seem to have agreed upon.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 11 Apr 86 23:01:18 EST Received: from XEROX.COM by SU-AI.ARPA with TCP; 11 Apr 86 19:47:07 PST Received: from Cabernet.ms by ArpaGateway.ms ; 11 APR 86 19:47:59 PST Date: 11 Apr 86 19:47 PST From: Pavel.pa@Xerox.COM Subject: unwind-protect To: common-lisp@SU-AI.ARPA cc: vanMelle.pa@Xerox.COM,Pavel.pa@Xerox.COM Format: TEdit Message-ID: <860411-194759-1452@Xerox> What is the result of this code: (proclaim '(special *foo*)) (let* ((x 'good) (*foo* x)) (block bar (unwind-protect (let ((*foo* 'bad)) (return-from bar)) (setq x *foo*))) x) The Zetalisp manual says it will return GOOD, but the silver book is silent on the issue. This should be clarified. Pavel  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 11 Apr 86 20:45:45 EST Received: from HPLABS.ARPA by SU-AI.ARPA with TCP; 11 Apr 86 17:16:35 PST Received: by hplabs.ARPA ; Fri, 11 Apr 86 17:14:47 pst Date: Fri, 11 Apr 86 17:14:47 pst From: hpfclp!diamant@hplabs.ARPA To: common-lisp@su-ai.ARPA Subject: Re: SYMBOL-FUNCTION I am quite satisfied with Nick's proposal. The distinction between FUNCTION OBJECT and FUNCTION NAME is an important one, and the proposal handles it in an intuitive way. The EQL requirement for function objects (but not function names) seems reasonable as well. Thanks, Nick, for crystallizing the concepts we have been discussing. By the way, I don't consider this proposal an incompatible change to CLtL. Rather, it is a clarification which eliminates inconsistencies in the current specification. This is, in fact, what we have implemented independently of this discussion. It is probably close to what most implementations do. John Diamant Systems Software Operation UUCP: {ihnp4!hpfcla,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 Apr 86 18:17:28 EST Received: from HUDSON.DEC.COM by SU-AI.ARPA with TCP; 11 Apr 86 13:38:36 PST Date: 11 Apr 86 16:21:00 EST From: "BACH::GREEK" Subject: Questions and an offer concerning "EVAL-WHEN" issues. To: "common-lisp" Reply-To: "BACH::GREEK" Here is some food for thought concerning the "EVAL-WHEN" issues. Let's assume that we define the "global environment" as that information established by the read-eval-print loop or loaded from files. And let's define the "compilation environment" as the information established by compilations. How about these for three rules (certainly open to debate). 1. The compiler is required to use information in the global environment. 2. The compiler is required to use information in the compilation environment established by prior compilations. 3. The compiler is not allowed to affect the global environment. Many schemes can be devised to implement these rules, but no matter how clever they get, it's tough to solve the following problems. o How does the user alter the readtable for the duration of a compilation but not permanently? o How does the compiler handle package functions in the source file without actually evaluating them? o What about necessary uses of (EVAL-WHEN (COMPILE) ...), such as DEFCONSTANTs used as keys with the CASE macro? o Etc., etc. Thinking about schemes to implement these rules also brings up questions of the organization of source files. For example, is it OK for a file to contain contradictory proclamations: (PROCLAIM '(FIXNUM *FOO*)) . . (PROCLAIM '(SIMPLE-STRING *FOO*)) In other words, is a proclamation static or "scoped"? Without getting too clever, you can write a source file which knows whether the compiler is one-pass or multi-pass. How about the question of which "top-level" forms the compiler pays special attention to. For example, we know that the compiler notices a DEFMACRO so that it can expand such macros later on. What makes it notice the macro? 1. The presence of the LOAD situation (which is the default). 2. The presence of a hidden situation, say called COMPILER-NOTICE (this must also be the default). 3. Nothing in particular, it always looks at it. If you think a bit, you'll find problem with all three of these theories. In particular, how do you tell the compiler to notice the macro definition but not dump it? What else does the compiler pay special attention to? How about DEFUN? Can I call a function from a macro expander and expect that to work? How do PROVIDE and REQUIRE work during a compilation? Then there is the age-old question of whether an unqualified symbol should be loaded into the package that was current at compilation time or the package that is current at load time. If the latter, how do you distinguish an unqualified symbol from one that was explicity qualified with the package current at compilation time? Should there be a function to flush the compilation environment? One might use this in between compilation of two sets of related files. This causes one to wonder if the compilation environment shouldn't be trashed after every compilation, forcing users to compile related files using PROVIDE and REQUIRE (see above). If people are interested in compiling a list of compilation environment questions, so that we have a place to start in solving these problems, I'd be happy to collect the questions and compile a complete list. - Paul ------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 11 Apr 86 16:57:30 EST Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 11 Apr 86 13:42:22 PST Date: 11 Apr 1986 16:43-EST Sender: NGALL@G.BBN.COM Subject: Are isomorphic structures EQUAL? From: NGALL@G.BBN.COM To: common-lisp@SU-AI.ARPA, nlp@LABS-B.BBN.COM Message-ID: <[G.BBN.COM]11-Apr-86 16:43:13.NGALL> I don't want to reopen the discussion that we had about equality a while back, but someone in my group just tripped over an ambiguity in the manual. She was using DEFSTRUCT with the (:TYPE ...) option and using EQUAL to compare structures and everything worked fine since EQUAL did a component-wise equality test. Then she got bold and decided to let DEFSTRUCT choose the representation, so she left off the (:TYPE ...) option. Low and behold, EQUAL did not do a component-wise equality test, it tested for EQL! So she looked at the def. on page 80 where it said "Certain objects that have components are EQUAL if they are of the same type and corresponding components are EQUAL." Unfortunately, the rest of the definition did not make it at all clear whether or not objects created by DEFSTRUCT were among these "Certain objects". Looking on the next page at the def. of EQUALP (which happened to do a component-wise equality test), she read "Objects that have components..." The only difference was the word "Certain"! So we tried it on another CL (SymbolicsCL), and got the same behavior (as with VaxLisp). Which leads me to almost believe that EQUAL NOT supposed to to a component-wise test for equality. Except... What happens to implementations that want to represent structures using plain old vectors? How will EQUAL distinguish vectors from structure-vectors? This interaction of DEFSTRUCT/EQUAL is going to cause a lot of bugs. People are going to prototype structues using the (:TYPE LIST) option and use EQUAL to do equality tests. Then when they remove the :TYPE option, KaBoom! There will be no way to do a component-wise test (using EQUAL on each component) on two structures unless one writes a structure-specific equality predicate. Therefore, I propose that two structures of the same type that are created by DEFSTRUCT (regardless of the :TYPE option) be tested for equality component-wise and that the CLtL make this clear. Until then, she can get by with EQUALP (since her structures don't conatin strings, floats, etc.). -- Nick  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 11 Apr 86 11:57:48 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 11 Apr 86 08:27:10 PST Received: ID ; Fri 11 Apr 86 11:26:40-EST Date: Fri, 11 Apr 1986 11:26 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: NGALL@BBNG.ARPA Cc: common-lisp@SU-AI.ARPA Subject: SYMBOL-FUNCTION In-reply-to: Msg of 11 Apr 1986 11:02-EST from NGALL at G.BBN.COM I propose that we adopt the distinction between a FUNCTION OBJECT and a FUNCTION NAME mentioned on pg. 59. By this definition, lambda-expressions and symbols would be FUNCTION NAMES, but NOT function objects (this restriction is mine, pg. 59 would need to be 'clarified' :->). Compiled-code objects and closures would be the ONLY CL defined FUNCTIONS (i.e., FUNCTION DEFINITIONS or FUNCTION OBJECTS). I agree that something like this is badly needed in the next official document (presumably the one for ANSI) to clear up all the ambiguity about what is a function. I'm not sure that we want to make lambda expressions function names rather than function objects, however. I'll have to think about that one. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 11 Apr 86 11:17:28 EST Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 11 Apr 86 08:01:26 PST Date: 11 Apr 1986 11:02-EST Sender: NGALL@G.BBN.COM Subject: Re: SYMBOL-FUNCTION From: NGALL@G.BBN.COM To: common-lisp@SU-AI.ARPA Message-ID: <[G.BBN.COM]11-Apr-86 11:02:34.NGALL> In-Reply-To: The message of Thu, 10 Apr 86 23:05:47 pst from hpfclp!diamant@hplabs.ARPA Date: Thu, 10 Apr 86 23:05:47 pst From: hpfclp!diamant@hplabs.ARPA To: common-lisp@su-ai.ARPA Subject: Re: EVAL-WHEN (really symbol-function) I think it is time we back off for a second from what is in the book, and just think about what makes sense for Common LISP. I would advocate making the restriction I have suggested explicit: "It is an error to setf the symbol-function to an object not of type FUNCTION." Also, the Yes, I agree that we should restrict what can be assigned to SYMBOL-FUNCTION, but it cannot be based on the the type FUNCTION as it is currently defined, since (FUNCTIONP 'CAR) is true. This would allow (SETF (SYMBOL-FUNCTION 'FOO) 'CAR), which is what we are trying to prevent. I propose that we adopt the distinction between a FUNCTION OBJECT and a FUNCTION NAME mentioned on pg. 59. By this definition, lambda-expressions and symbols would be FUNCTION NAMES, but NOT function objects (this restriction is mine, pg. 59 would need to be 'clarified' :->). Compiled-code objects and closures would be the ONLY CL defined FUNCTIONS (i.e., FUNCTION DEFINITIONS or FUNCTION OBJECTS). (Cf. pg 89 for explanation of why closures are sufficient for all uncompiled functions). Thus type FUNCTION would have two subtypes (not necessarily disjoint in all implementations, since some might use lambda-expressions as function objects): FUNCTION-NAME and FUNCTION-OBJECT (I would prefer to call it FUNCTION-DEFINITION so we wouldn't have to say things like "an object of type function-object"). If the value to be assigned to SYMBOL-FUNCTION is a FUNCTION-NAME (note that this test should be done first), then the FUNCTION OBJECT that it NAMES is assigned (and it is an error if the NAME does not name a function object (which can happen only with symbols). In the case of a lambda-expression, this means that the implementation turns it into a closure or a compiled-code object. Note that the following two assignments would still be quite different: (let ((x 1)) (setf (symbol-function 'foo) '(lambda () x)) ; x is implicitly special (setf (symbol-function 'foo) #'(lambda () x))) ; x is lexical In the case of a symbol (e.g., FOO) that names a FUNCTION OBJECT, it would be undefined whether or not (eql (symbol-function 'foo) (symbol-function (prog1 'bar (setf (symbol-function 'bar) 'foo)))) Also, note that (setf (symbol-function '<>) '<>) would be unusual among SETFs in that the value returned by the setf would not be EQL to the value subsequently returned by the accessor form. Such a definition would also clear up the definition of FUNCTION. The arg. to function must be a FUNCTION-NAME and the result will be a FUNCTION-OBJECT. It would also clear up APPLY and FUNCALL. The first arg. to both functions must be of type FUNCTION. In the case of a FUNCTION-OBJECT, it is 'used' directly. In the case of a FUNCTION-NAME, the FUNCTION-OBJECT that it names will be 'used'. This will also clear up wording like "The argument...should be a function...in a form acceptable to the FUNCTION special form" (pg. 314). Instead, we merely say, "The argument must be a function name." implementation should be at liberty to store the functional interpretation of a lambda or symbol if that is what setf is given. Note that this doesn't restrict the implementation from setting it in the case of a macro or special form. My real concern is that no gain is made by making the function cell completely general, and there are some losses (consistency with (setf (macro-function...)) and performance). It seems every time we get into a discussion about an ambiguity, we always make a change that tends to make the language more complicated. Why can't we try for simplicity this time (I really don't see that we are losing anything)? All this hidden hash concept does for you is give the user one function cell and the implementation an other one. What good is the user function cell if the system isn't even using it? If anybody has a reason why the restriction I mention above interferes with execution of correct code, please say so (don't tell me about doing an EQL test before and after a (setf (symbol-function...)) because that is what we are disputing. I mean when would someone legitimately write a piece of Common LISP with non-function items in the function cell (unless they were simply using it as a value cell)? Until someone can generate such an example, I see no reason why some people are so tenaciously insisting that anything can be stored in the funtion cell. If I directly assign a function object using (SETF (SYMBOL-FUNCTION...)...), I would like it guaranteed that (SYMBOL-FUNCTION...) return the EQL function object (not that this definitely does not hold for names). In trace packages, encapsulations, etc., the program putting in a wrapper may need to know if the current function definition for a symbol is EQL to the one it SETF in there. My proposal allows this. Consider what happens if you allow arbitrary objects in the function cell as in the following example: (setf x '(lambda () "Hi")) (setf (symbol-function 'y) x) (setf (third x) "Bye") (y) What is this supposed to return? In an implementation which guarantees that Under my proposal, it would be undefined, since an implementation is free to use the lambda-expression directly, closure it, compile it, or just copy it. -- Nick  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 11 Apr 86 10:19:09 EST Received: from [192.10.41.223] by SU-AI.ARPA with TCP; 11 Apr 86 07:04:07 PST Received: from CHICOPEE.SCRC.Symbolics.COM by SAPSUCKER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 7537; Fri 11-Apr-86 10:03:07 EST Date: Fri, 11 Apr 86 10:04 EST From: Daniel L. Weinreb Subject: Re: EVAL-WHEN (really symbol-function) To: common-lisp@SU-AI.ARPA In-Reply-To: The message of 11 Apr 86 02:05 EST from hpfclp!diamant@hplabs.ARPA Message-ID: <860411100408.9.DLW@CHICOPEE.SCRC.Symbolics.COM> Date: Thu, 10 Apr 86 23:05:47 pst From: hpfclp!diamant@hplabs.ARPA I think it is time we back off for a second from what is in the book, and just think about what makes sense for Common LISP. I would advocate making the restriction I have suggested explicit: "It is an error to setf the symbol-function to an object not of type FUNCTION." While it's true in general that we must consider what seems to be the best language design, it is not true that we should adopt the attitude that Common Lisp's definition should, at this point, be changed every time we see something that we think could be changed for the better (even assuming a strong concensus). We have long since reached the point at which stability of the definition of the language is an important issue. The detailed arguments to this effect have been made several times already, so I won't repeat them; I'd just like to throw in this reminder. I presume that the technical committee will write up a set of guidelines regarding this tradeoff.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 11 Apr 86 03:49:05 EST Received: from HPLABS.ARPA by SU-AI.ARPA with TCP; 10 Apr 86 23:07:34 PST Received: by hplabs.ARPA ; Thu, 10 Apr 86 23:05:47 pst Date: Thu, 10 Apr 86 23:05:47 pst From: hpfclp!diamant@hplabs.ARPA To: common-lisp@su-ai.ARPA Subject: Re: EVAL-WHEN (really symbol-function) I think it is time we back off for a second from what is in the book, and just think about what makes sense for Common LISP. I would advocate making the restriction I have suggested explicit: "It is an error to setf the symbol-function to an object not of type FUNCTION." Also, the implementation should be at liberty to store the functional interpretation of a lambda or symbol if that is what setf is given. Note that this doesn't restrict the implementation from setting it in the case of a macro or special form. My real concern is that no gain is made by making the function cell completely general, and there are some losses (consistency with (setf (macro-function...)) and performance). It seems every time we get into a discussion about an ambiguity, we always make a change that tends to make the language more complicated. Why can't we try for simplicity this time (I really don't see that we are losing anything)? All this hidden hash concept does for you is give the user one function cell and the implementation an other one. What good is the user function cell if the system isn't even using it? If anybody has a reason why the restriction I mention above interferes with execution of correct code, please say so (don't tell me about doing an EQL test before and after a (setf (symbol-function...)) because that is what we are disputing. I mean when would someone legitimately write a piece of Common LISP with non-function items in the function cell (unless they were simply using it as a value cell)? Until someone can generate such an example, I see no reason why some people are so tenaciously insisting that anything can be stored in the funtion cell. Consider what happens if you allow arbitrary objects in the function cell as in the following example: (setf x '(lambda () "Hi")) (setf (symbol-function 'y) x) (setf (third x) "Bye") (y) What is this supposed to return? In an implementation which guarantees that the value stored really is EQL to the one given, it seems reasonable that "Bye" would be returned. But in order to make that work, the implementation couldn't use the hidden hash method because it wouldn't reflect the change. It would still have to interpret each time! You can always say that it doesn't have to reflect the list surgery, but then what's the point of requiring that the result be EQL? From: hplabs!NGALL@G.BBN.COM Date: Wed, 9 Apr 86 21:08:05 GMT From: Jeff Dalton Subject: Re: EVAL-WHEN (really symbol-function) Date: 8 Apr 1986 17:34-EST From: NGALL@arpa.bbng 3. Under interp 1. consider the following: (defun foo () (print "hello")) (setf (symbol-function 'bar) 'foo) Which of the following are legal?: (funcall 'bar) ; A (funcall #'bar) ; B (funcall (symbol-function 'bar)) ; C Case C is the only one I am sure is legal. The other two depend on the ambiguous description of function calling (pg. 58) and APPLY (pg. 107). Case C should be legal because it should be the same as (funcall 'foo). Case B should also be legal because #'bar == (function bar) should be equivalent to (symbol-function 'bar) in a context where bar refers to a global function (i.e., when there's no lexically enclosing flet or labels that binds bar), as it does in this case. One of (:->) the definitions of FUNCTION on pg. 87 states that "FN is interpreted as if it had appeared in the functional position of a function invocation". As most of us would agree (but CLtL does not pin down), the function call (bar) is erroneous (again, CLtL does not define what should happen when the function definition is illegal or even unbound). By this definition of FUNCTION then, (function bar) is erroneous. Up until now, I think most people thought that (bar) and (funcall (function bar)) were semantically equivalent (i.e., both are illegal). By your definition of FUNCTION (as being eqiv. to SYMBOL-FUNCTION in the case of a global function name), the former is still illegal but the latter is perfectly legal. Yecch! I'll stick with my reading of FUNCTION. The definition of FUNCTION (on page 87) also says: "If fn is a symbol, the functional definition associated with that symbol is returned; see symbol-function." Yecch is right, but that's what it says! ... I guess my point is that I think most implementors followed interpretation 2 which prevents the kind of confusion where C is legal but B is not; so we should clarify CLtL in that direction rather than towards interp 1. I don't think there is a case where C should be legal and B not. As I showed above, I think there is. Thank you for pointing out pg 32. It states that "The result of evaluating a FUNCTION special form will always be a function." If we accept this statement. Then under interp. 2: (setf (symbol-function 'zap) 1.0) What does this return?: (function zap) => A) 1.0 ; According to your definition of FUNCTION. B) <>. C) Undefined by CL (implementations are encouraged to signal an error). I hope that I have made my point that interp. 2 is unintuitive (since most implementations didn't do it that way) and leads to confusion. Well, based on the statement I quoted above from FUNCTION, it must be A, but based on the statement you quoted from page 32, that is impossible. Again, I can only conclude that only objects of type FUNCTION should be allowed in the function cell! I still believe that the only way the statements about FUNCTION (page 32 and 87) can be interpreted consistently is if function cells are only allowed to contain objects which are FUNCTIONP. Equally important is the point which Nick makes, namely that it is much more intuitive (and consistent with (setf (macro-function...)) (which states that "the value installed must be a function ...") Indeed, SYMBOL-FUNCTION says much the same thing: "the definition may be a function or an object ======== representing a special form or macro [ underlining added by me]" John  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 11 Apr 86 02:18:21 EST Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 10 Apr 86 23:03:28 PST Received: from thorlac by GODOT.THINK.COM via CHAOS; Thu, 10 Apr 86 12:12:04 est Date: Thu, 10 Apr 86 12:13 EST From: Guy Steele Subject: [gls@THINK-AQUINAS.ARPA: setf place] To: common-lisp@SU-AI.ARPA Cc: gls@THINK-AQUINAS.ARPA Message-Id: <860410121335.1.GLS@THINK-THORLAC.ARPA> Date: Thu, 10 Apr 86 11:32 EST From: Guy Steele Date: 8 Apr 86 23:36:00 EST From: "BACH::NELSON" Guy, we've had a request from a VAX LISP customer to change our implementation of SETF. This user reads the description of acceptable places (p. 97) to mean that if one says (setf (a b) c) and if A has a macro definition, that we first check for a setf expander for the form (a b), and only macroexpand if we find no setf expander for the un-macroexpanded form. I consider this an incorrect reading of the book; I think that the book says that if A has a macro definition, only the result of the macroexpansion will be used. Could you tell me what you think the book says? Thanks very much. Beryl Nelson nelson@hudson.dec.com ------ I agree that the book is not properly organized here. The list of items on pp. 94-97 was not intended to be in any particular order, and certainly not in priority order. However, I can see that the list might be interpreted in that manner. It should be clear that what your user wants will "do the right thing" under more sets of circumstances, and it is what I would expect; but I agree that the book should be made more clear. --Guy  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 10 Apr 86 14:32:52 EST Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 10 Apr 86 09:33:39 PST Date: 10 Apr 1986 12:34-EST Sender: NGALL@G.BBN.COM Subject: Re: EVAL-WHEN (really symbol-function) From: NGALL@G.BBN.COM To: jeff%aiva.edinburgh.ac.uk@CS.UCL.AC.UK Cc: gls@AQUINAS.THINK.COM, common-lisp@SU-AI.ARPA Cc: diamant@HPLABS.ARPA Message-ID: <[G.BBN.COM]10-Apr-86 12:34:53.NGALL> In-Reply-To: <12977.8604092108@aiva.ed.ac.uk> Date: Wed, 9 Apr 86 21:08:05 GMT From: Jeff Dalton To: NGALL@bbng.arpa, gls@aquinas.think.com Subject: Re: EVAL-WHEN (really symbol-function) Message-ID: <12977.8604092108@aiva.ed.ac.uk> Date: 8 Apr 1986 17:34-EST From: NGALL@arpa.bbng 1. How many implementations interpreted CLtL the way Guy intended? In other words, How many implementations allow, for example, (setf (symbol-function 'foo) 1.0d0). VaxLisp does not allow this. I tried (setf (symbol-function 'foo) 'bar) in the two CLs within easy reach. Both signal errors, and not particularly nice ones either. (I'd expect something like "illegal value ~S for SYMBOL-FUNCTION", but I get things like "segmentation-violation".) 2... 3. Under interp 1. consider the following: (defun foo () (print "hello")) (setf (symbol-function 'bar) 'foo) Which of the following are legal?: (funcall 'bar) ; A (funcall #'bar) ; B (funcall (symbol-function 'bar)) ; C Case C is the only one I am sure is legal. The other two depend on the ambiguous description of function calling (pg. 58) and APPLY (pg. 107). Case C should be legal because it should be the same as (funcall 'foo). Case B should also be legal because #'bar == (function bar) should be equivalent to (symbol-function 'bar) in a context where bar refers to a global function (i.e., when there's no lexically enclosing flet or labels that binds bar), as it does in this case. One of (:->) the definitions of FUNCTION on pg. 87 states that "FN is interpreted as if it had appeared in the functional position of a function invocation". As most of us would agree (but CLtL does not pin down), the function call (bar) is erroneous (again, CLtL does not define what should happen when the function definition is illegal or even unbound). By this definition of FUNCTION then, (function bar) is erroneous. Up until now, I think most people thought that (bar) and (funcall (function bar)) were semantically equivalent (i.e., both are illegal). By your definition of FUNCTION (as being eqiv. to SYMBOL-FUNCTION in the case of a global function name), the former is still illegal but the latter is perfectly legal. Yecch! I'll stick with my reading of FUNCTION. Case A should be illegal, but CLtL does not explicitly exclude it. ... Agreed. ... I guess my point is that I think most implementors followed interpretation 2 which prevents the kind of confusion where C is legal but B is not; so we should clarify CLtL in that direction rather than towards interp 1. I don't think there is a case where C should be legal and B not. As I showed above, I think there is. Whatever interp. is finally chosen, APPLY should be clarified so that we known exactly what can be applied (and if a symbol is applied, what exactly can be legally the function definition). I agree that the definition of APPLY is deficient. For example, it seems to list explicitly all the things that might be functions and yet it never mentions closures. Compare this list to that on page 32. In general, my favorite pages for answering questions concerning what things are legal as functions are pages 32 (section 2.13) and 59 (section 5.2). Page 59 is, for example, the place where the distinction between the use of lambda-expressions and symbols as *names* for functions and their use as function objects is most clearly made. Thank you for pointing out pg 32. It states that "The result of evaluating a FUNCTION special form will always be a function." If we accept this statement. Then under interp. 2: (setf (symbol-function 'zap) 1.0) What does this return?: (function zap) => A) 1.0 ; According to your definition of FUNCTION. B) <>. C) Undefined by CL (implementations are encouraged to signal an error). I hope that I have made my point that interp. 2 is unintuitive (since most implementations didn't do it that way) and leads to confusion. -- Nick  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 10 Apr 86 12:13:35 EST Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 10 Apr 86 08:55:36 PST Date: 10 Apr 1986 11:55-EST Sender: NGALL@G.BBN.COM Subject: Re: Extent of function definition created by FLET/LABELS: ad... From: NGALL@G.BBN.COM To: gls@AQUINAS.THINK.COM Cc: common-lisp@SU-AI.ARPA Message-ID: <[G.BBN.COM]10-Apr-86 11:55:49.NGALL> In-Reply-To: <860410111533.3.GLS@THINK-THORLAC.ARPA> Date: Thu, 10 Apr 86 11:15 EST From: Guy Steele To: NGALL@G.BBN.COM, common-lisp@SU-AI.ARPA Subject: Extent of function definition created by FLET/LABELS: additional remark In-Reply-To: <[G.BBN.COM] 8-Apr-86 18:06:32.NGALL> Message-ID: <860410111533.3.GLS@THINK-THORLAC.ARPA> Date: 8 Apr 1986 18:06-EST From: NGALL@G.BBN.COM Is the following legal CL: (funcall (labels ((foo () (print "hello")) (bar () (foo))) #'bar)) If not, where is it forbidden? -- Nick P.S. It works in VaxLisp. Page 39 ought to state that bindings of function names, as well as variable bindings, have lexical scope and indefinite extent. Page 113 also ought to make explicit mention of this. --Guy My question really has nothing to do with the BINDING of a function name, otherwise I would have asked if the following were legal: (funcall (flet ((foo () (print "hello"))) #'(lambda () (foo)))) My question was really whether or not the actual function object created by FLET/LABELS has indefinite extent, and I take it that it is. The fact that it is should be mentioned in the appropriate places. -- Nick  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 10 Apr 86 11:27:46 EST Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 10 Apr 86 08:13:12 PST Received: from thorlac by GODOT.THINK.COM via CHAOS; Thu, 10 Apr 86 11:13:56 est Date: Thu, 10 Apr 86 11:15 EST From: Guy Steele Subject: Extent of function definition created by FLET/LABELS: additional remark To: NGALL@G.BBN.COM, common-lisp@SU-AI.ARPA Cc: gls@THINK-AQUINAS.ARPA In-Reply-To: <[G.BBN.COM] 8-Apr-86 18:06:32.NGALL> Message-Id: <860410111533.3.GLS@THINK-THORLAC.ARPA> Date: 8 Apr 1986 18:06-EST From: NGALL@G.BBN.COM Is the following legal CL: (funcall (labels ((foo () (print "hello")) (bar () (foo))) #'bar)) If not, where is it forbidden? -- Nick P.S. It works in VaxLisp. Page 39 ought to state that bindings of function names, as well as variable bindings, have lexical scope and indefinite extent. Page 113 also ought to make explicit mention of this. --Guy  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 10 Apr 86 11:27:32 EST Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 10 Apr 86 08:10:02 PST Received: from thorlac by GODOT.THINK.COM via CHAOS; Thu, 10 Apr 86 11:10:47 est Date: Thu, 10 Apr 86 11:12 EST From: Guy Steele Subject: Extent of function definition created by FLET/LABELS To: NGALL@G.BBN.COM, common-lisp@SU-AI.ARPA Cc: gls@THINK-AQUINAS.ARPA In-Reply-To: <[G.BBN.COM] 8-Apr-86 18:06:32.NGALL> Message-Id: <860410111224.2.GLS@THINK-THORLAC.ARPA> Date: 8 Apr 1986 18:06-EST From: NGALL@G.BBN.COM Is the following legal CL: (funcall (labels ((foo () (print "hello")) (bar () (foo))) #'bar)) If not, where is it forbidden? -- Nick P.S. It works in VaxLisp. This is certainly legal. I am glad that it works in VaxLisp. --Guy  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 10 Apr 86 10:25:15 EST Received: from CS.UCL.AC.UK by SU-AI.ARPA with TCP; 10 Apr 86 06:57:09 PST Received: from aiva.edinburgh.ac.uk by 44d.Cs.Ucl.AC.UK via Janet with NIFTP id a001807; 10 Apr 86 9:12 BST From: Jeff Dalton Date: Wed, 9 Apr 86 20:07:59 GMT Message-Id: <12612.8604092007@aiva.ed.ac.uk> To: NGALL@bbng.arpa, common-lisp@su-ai.arpa Subject: Re: Extent of function definition created by FLET/LABELS Date: 8 Apr 1986 18:06-EST From: NGALL@arpa.bbng Is the following legal CL: (funcall (labels ((foo () (print "hello")) (bar () (foo))) #'bar)) If not, where is it forbidden? I'm somewhat puzzled by this question. I sounds as if you think there's a pretty good chance that it isn't legal but a pretty poor chance that the Book says so. I would say that it's almost certainly legal, although the book's clarity on this point may still be in doubt. I can't find anything in CLtL that explicitly says the functions created by LABELS have indefinite extent, although it is reasonably clear that functions made from lambda-expressions do (see, e.g., the COMPOSE example on page 37). And named functions are explicitly connected to lambda-expressions in section 5.2.1 on page 59. That the FOO in the definition of BAR refers to the right local function should also be clear from the definition of LABELS in page 113 and 5.2.1 again. -- Jeff  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 10 Apr 86 10:18:07 EST Received: from CS.UCL.AC.UK by SU-AI.ARPA with TCP; 10 Apr 86 06:52:46 PST Received: from aiva.edinburgh.ac.uk by 44d.Cs.Ucl.AC.UK via Janet with NIFTP id a001492; 10 Apr 86 8:18 BST From: Jeff Dalton Date: Wed, 9 Apr 86 21:08:05 GMT Message-Id: <12977.8604092108@aiva.ed.ac.uk> To: NGALL@bbng.arpa, gls@aquinas.think.com Subject: Re: EVAL-WHEN (really symbol-function) Cc: common-lisp@su-ai.arpa, diamant@hplabs.arpa Date: 8 Apr 1986 17:34-EST From: NGALL@arpa.bbng 1. How many implementations interpreted CLtL the way Guy intended? In other words, How many implementations allow, for example, (setf (symbol-function 'foo) 1.0d0). VaxLisp does not allow this. I tried (setf (symbol-function 'foo) 'bar) in the two CLs within easy reach. Both signal errors, and not particularly nice ones either. (I'd expect something like "illegal value ~S for SYMBOL-FUNCTION", but I get things like "segmentation-violation".) 2... 3. Under interp 1. consider the following: (defun foo () (print "hello")) (setf (symbol-function 'bar) 'foo) Which of the following are legal?: (funcall 'bar) ; A (funcall #'bar) ; B (funcall (symbol-function 'bar)) ; C Case C is the only one I am sure is legal. The other two depend on the ambiguous description of function calling (pg. 58) and APPLY (pg. 107). Case C should be legal because it should be the same as (funcall 'foo). Case B should also be legal because #'bar == (function bar) should be equivalent to (symbol-function 'bar) in a context where bar refers to a global function (i.e., when there's no lexically enclosing flet or labels that binds bar), as it does in this case. Case A should be illegal, but CLtL does not explicitly exclude it. Cases B and C dereference 'bar one level in the evaluation of the argument form; here funcall would have to do both levels (from bar to foo and from foo to #'foo) itself. Nothing says that apply and funcall do repeated dereferencing in this case, but that would not be an unreasonable interpretation of pages 32 (section 2.13) and 107. Take page 107. If 'function' is a symbol, its global functional value is "used". Presumably, it is used as a function, in which case it is reasonable to suppose the global value might also be a symbol and that the same rule would be applied again. The reason I say that case A should be illegal is that Common Lisp does not in general repeatedly dereference symbols used as functions in this way. Some Lisps have done so, even if you just write (f x) instead of using FUNCALL or APPLY, but typically only in the interpreter. I guess my point is that I think most implementors followed interpretation 2 which prevents the kind of confusion where C is legal but B is not; so we should clarify CLtL in that direction rather than towards interp 1. I don't think there is a case where C should be legal and B not. Both should be legal if arbitrary values are allowed to be SYMBOL-FUNCTIONs; neither should be legal otherwise. (Except in those contexts where (FUNCTION x) does not just do (SYMBOL-FUNCTION x) -- but that does not depend on interp 1 vs interp 2.) Whatever interp. is finally chosen, APPLY should be clarified so that we known exactly what can be applied (and if a symbol is applied, what exactly can be legally the function definition). I agree that the definition of APPLY is deficient. For example, it seems to list explicitly all the things that might be functions and yet it never mentions closures. Compare this list to that on page 32. In general, my favorite pages for answering questions concerning what things are legal as functions are pages 32 (section 2.13) and 59 (section 5.2). Page 59 is, for example, the place where the distinction between the use of lambda-expressions and symbols as *names* for functions and their use as function objects is most clearly made. -- Jeff  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 10 Apr 86 04:05:05 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 10 Apr 86 00:50:38 PST Received: ID ; Thu 10 Apr 86 03:51:25-EST Date: Thu, 10 Apr 1986 03:51 EST Message-ID: From: Rob MacLachlan To: common-lisp@SU-AI.ARPA Subject: Successor to eval-when? If anyone has an idea for a replacement to eval-when, speak up. I don't have any idea of anything that would be better. There seem to be two main reasons people are upset with eval-when: 1] It is currently ill-defined. 2] It is hard to understand. I believe that the first problem is fairly easy to fix; I suspect that the second problem is inherent in the nature of the beast. Rob  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 10 Apr 86 03:18:56 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 10 Apr 86 00:04:07 PST Received: from RICKY.AI.MIT.EDU by OZ.AI.MIT.EDU via Chaosnet; 10 Apr 86 03:06-EST Date: Thu, 10 Apr 86 03:05 EST From: Christopher Fry Subject: Dave Moon's summary of EVAL-WHEN issues. To: Fahlman@C.CS.CMU.EDU, common-lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860410030502.2.CFRY@RICKY.AI.MIT.EDU> Received: from MC.LCS.MIT.EDU by OZ.AI.MIT.EDU via Chaosnet; 9 Apr 86 22:47-EST Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 9 Apr 86 22:46:46 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 9 Apr 86 19:21:07 PST Received: ID ; Wed 9 Apr 86 22:21:52-EST Date: Wed, 9 Apr 1986 22:21 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: common-lisp@SU-AI.ARPA Subject: Dave Moon's summary of EVAL-WHEN issues. In-reply-to: Msg of 4 Apr 1986 13:37-EST from Bobrow.pa at Xerox.COM I think that instead of worrying about changing the name, we need to completely replace the current Eval-When. We need to figure out what kinds of control we need over when things are to be evaluated, compiled, etc., and then we need good clean ways of expressing these directives in portable code files. This is all tied in with top-level forms and issues about what the compiler does to the compile-time and load-time environments. Once we know what sorts of operations we want to support, then we should worry about names. Assuming that these new controls are not equivalent to the current Eval-When, we will want new names for these things so that the cut-over fromt he old Eval-When can occur gradually. -- Scott As the instigator of this round of eval-when-wars, I was horrified at the volume of mail generated on the topic over the last couple of weeks. Scott is EXACTLY right! Perhaps a few coherent proposals could be passed out and/or expalined at the upcomming meeting.