Received: from CMU-CS-A by SU-AI with TCP/SMTP; 3 Jun 83 23:02:17 PDT Date: 4 June 1983 0200-EDT (Saturday) From: Guy.Steele@CMU-CS-A To: David A. Moon Subject: Copying a random-state CC: common-lisp@SU-AI In-Reply-To: "David A. Moon's message of 4 Jun 83 00:56-EST" If you give a random-state to MAKE-RANDOM-STATE, it will return a copy. I really did think all this out! Maybe an example is needed. --Guy  Received: from MIT-MC by SU-AI with TCP/SMTP; 3 Jun 83 23:02:11 PDT Date: 4 June 1983 02:04 EDT From: Alan Bawden Subject: Gaussian rationals To: Common-Lisp @ SU-AI, Moon @ SCRC-TENEX In-reply-to: Msg of 3 Jun 1983 17:27-EDT from David A. Moon Date: Friday, 3 June 1983, 17:27-EDT From: David A. Moon Having Gaussian rationals behave as an extension of the real rationals seems superficially plausible, but I don't consider myself competent to evaluate the implications. Let me ask the $64 question: will the result of any function, other than type-checking functions and transcendental functions, be affected by this change (i.e. are there other functions that treat complex numbers on the real line different from real numbers)? I just carefully checked the Laser manual. I'm fairly certain that the answer to your $64 question is: No. However, I am not 100% convinced we are all talking the same language here. Let me present a small dialog with a Common Lisp interpreter to demonstrate the behavior I think we are proposing here: (= (/ 4 2) 2) T ;whatever (/ 4 2) returns, it must be ;indistinguishable from 2. [Except perhaps by ;using EQ? I guess that doesn't matter.] (integerp (/ 4 2)) T ;Indistinguishable. (eql (/ 4 2) 2) T ;eql is defined to be = for numbers. (= (complex 2 0) 4/2) ;Typing "4/2" should be just like typing "2". T ;Again indistinguishable. (+ #C(2/3 0) 1/3) ;Typing "#C(2/3 0)" is just like typing "2/3". 1 (integerp *) T ;Whatever it is, it acts like an integer. (nth (+ #C(0/69 7/7) (* 3 (complex (/ 4 6) -1/3)) '(zero one two three)) TWO Now there is one issue that can go either way. Currently (according to page 24 of Laser) the complex type and the rational type are DISJOINT. I presume the idea is that the complex type is to consist of only those numbers with non-zero imaginary part. Unfortunately this is a mis-use of the mathematical term "complex", which is normally applied to a set of numbers that INCLUDES the real numbers. The predicate COMPLEXP should correctly be true of ALL Common Lisp number types, and should thus be useless. Better I think, would be to have a type named REAL, then where previously you would have written (COMPLEXP ...), now you would write (NOT (REALP ...)). I understand that there is a tendency in computer languages to mis-use the word "real" to mean "floating point", but it's a shame to introduce a new mis-use to cover for an old one. [ BTW, I just chased all over the Laser manual trying to find where the printed representation of complex numbers is set forth. I found it on page 15, but I looked first in the Numbers chapter, and second in the section of the I/O chapter titled "Printed representation...". All plausible places to find such information...]  Received: from MIT-MC by SU-AI with TCP/SMTP; 3 Jun 83 22:56:24 PDT Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Sat 4-Jun-83 01:57:53-EDT Date: Saturday, 4 June 1983, 01:56-EDT From: David A. Moon Subject: Addendum to my answers on ballot A To: Guy.Steele%CMU-CS-A@SU-DSN Cc: common-lisp@SU-AI In-reply-to: The message of 4 Jun 83 00:39-EDT from Guy.Steele at CMU-CS-A Date: 4 June 1983 0039-EDT (Saturday) From: Guy.Steele@CMU-CS-A While we're at it, let's reinstate ASET. ASET was flushed because it uses left-to-right data motion, whereas everything else in Common Lisp uses right-to-left data motion. Let's ignore the fact that I think ASET is right and everything else is wrong, and not put it back in. Regarding MAKE-RANDOM-STATE, I oppose the ability for the user to provide an integer seed. The laser edition specifies that an argument of T will cause MAKE-RANDOM-STATE to initialize the new state object in a "random" manner. The reason for this specification is that the implementor knows how many bits of state are in the state object and the user does not, so the user can't know whether his seed is "random enough"; the implementor can do a much better job of randomizing the state. If the user wants to be able to make several random-state objects that all begin with the same seed, he is advised to call (MAKE-RANDOM-STATE T) and then make several copies of the result. The object may be written out to a file and read back in (this is specified precisely so that you can get consistent random behavior in separate sessions). This argument would be more persuasive if there was a way provided to copy a random-state. There is no way to do it that doesn't involve I/O to a temporary file or a string.  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 3 Jun 83 22:30:23 PDT Date: 4 June 1983 0130-EDT (Saturday) From: Guy.Steele@CMU-CS-A To: common-lisp@SU-AI Subject: pervasiveness of declarations - - - - Begin forwarded message - - - - Received: from CMU-CS-PT by CMU-CS-A; 4 Jun 83 01:10:43 EDT Received: from MIT-MC by CMU-CS-PT; 4 Jun 83 01:07:44 EDT Date: 4 Jun 1983 0110-EDT From: RMS%MIT-OZ@MIT-MC Subject: Re: Simplifying local declarations To: Guy.Steele@CMU-CS-A In-Reply-To: Your message of 4-Jun-83 0031-EDT I believe all declarations should be pervasive. I allow arbitrary declarations that users can look at in their macro definitions; these are all pervasive. So my documentation would have to say, "all declarations are pervasive except for FOO and BAR," which I think is unclean. I'm sure I can manage to implement nonpervasive declarations, though it is much simpler this way, but I would be ashamed to admit it to the users. Anyone who really really wants a declaration not to be pervasive can do (LET (vars) (DECLARE (FOO ..)) (PROGN (DECLARE (UNFOO ...)) FOO not in effect here)) This is good enough for macros that may have to pay attention to this in order to work right in all cases. I would not expect hand-written code to ever need this. What advantage is there, ever, to a nonpervasive declaration? It may be that this issue is moot for me now. The only declarations that matter on the Lisp machine are SPECIAL and UNSPECIAL. If both of these are pervasive, I can say all declarations are pervasive because I will just ignore the others anyway. Regardless of what I do, making them all pervasive will still simplify your own design. I am disturbed to find out that this is not even being considered, at least according to the message you sent me. What do I have to do? I have explained it at least twice before. Each time, when I inquired after a period of time that I thought might suffice to consider the idea, I found it had not been considered and you had forgotten what I said. I hope you will at leat save this message so you will not have to ask me again "what is it you are suggesting for declarations?" Wrt PROCLAIM: I have no opinion on this. I can implement PROCLAIM easily enough. Of course, I am still going to support global use of DECLARE. ------- - - - - End forwarded message - - - -  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 3 Jun 83 21:48:00 PDT Date: 4 June 1983 0047-EDT (Saturday) From: Guy.Steele@CMU-CS-A To: common-lisp@SU-AI Subject: Array rank Actually, my memory differs from DLW's; I thought McCarthy suggested 63. Yes, that number is causing flak. I bet 7 would be acceptable. Indeed, if you write a portable program that has a function of 93 arguments and try to run it on an implementation that supports only 92 you will lose. If you write a portable program that does an FFT on a ten-gigabyte array and try to run it on an 8086, you will also lose. I'm not sure what is the best thing to write into the standard, which is why I wanted to re-raise the issue. --Guy  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 3 Jun 83 21:41:19 PDT Date: 4 June 1983 0039-EDT (Saturday) From: Guy.Steele@CMU-CS-A To: common-lisp@SU-AI Subject: Addendum to my answers on ballot A I was so busy being terse that I forgot these notes: For question 7, I favor flushing FSET and retaining SET. While we're at it, let's reinstate ASET. Regarding MAKE-RANDOM-STATE, I oppose the ability for the user to provide an integer seed. The laser edition specifies that an argument of T will cause MAKE-RANDOM-STATE to initialize the new state object in a "random" manner. The reason for this specification is that the implementor knows how many bits of state are in the state object and the user does not, so the user can't know whether his seed is "random enough"; the implementor can do a much better job of randomizing the state. If the user wants to be able to make several random-state objects that all begin with the same seed, he is advised to call (MAKE-RANDOM-STATE T) and then make several copies of the result. The object may be written out to a file and read back in (this is specified precisely so that you can get consistent random behavior in separate sessions).  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 3 Jun 83 21:23:49 PDT Date: 4 June 1983 0021-EDT (Saturday) From: Guy.Steele@CMU-CS-A To: common-lisp@SU-AI Subject: Reply to ballot A I favor all proposals except as noted otherwise below: 2, 4, 9, and 13 are okay by me, but I don't feel strongly about them. I oppose 5, 6, 8, 10, and 12. For question 3, I much prefer option (b).  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 3 Jun 83 21:15:09 PDT Date: 4 June 1983 0012-EDT (Saturday) From: Guy.Steele@CMU-CS-A To: David A. Moon Subject: Re: typep of array CC: common-lisp@SU-AI In-Reply-To: "David A. Moon's message of 3 Jun 83 01:13-EST" Yep, that's a problem all right. More abstractly, what you want is the union of all array types over various suitable finite sets (of which there are potentially infinitely many, though any given implementation will have only a finite number). Unfortunately, the notation (ARRAY INTEGER) means not a union of the arrays over{ infinitely many finite domains, but the array type over the union of the infinitely many finite domains. --Guy  Received: from MIT-MC by SU-AI with TCP/SMTP; 3 Jun 83 20:52:10 PDT Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Fri 3-Jun-83 23:51:49-EDT Date: Friday, 3 June 1983, 23:50-EDT From: David A. Moon Subject: Functions for taking apart floating-point numbers To: Common-Lisp@su-ai In-reply-to: The message of 3 Jun 83 14:47-EDT from Robert A. Cassels Date: Friday, 3 June 1983, 14:47-EDT From: Robert A. Cassels Proposal: Remove @f[float-exponent] and @f[float-integer-exponent], and return those numbers as the second values from @f[float-significand] and @f[float-integer-significand]. I think this was turned down last year, but I don't remember why. It sounds reasonable to me, except that one would probably want to choose better names for the two functions. I'm in favor of it. Proposal: Add new functions @f[float-digits] and @f[float-precision]. I don't understand the need for both of these. It sounds like float-precision is the only one you actually need; float-digits returns the same answer except for certain exceptional numbers. Proposal: Require the result of @f[float-integer-significand] to reflect the precision of the floating-point number. This sounds reasonable. The main competing proposal is that it return a result "normalized to the right" by removing trailing zeros. Your proposal seems slightly preferable to that. Proposal: Clarify the result of @f[(float-sign 0.0)], @f[(float-sign -0.0)]. I think this is just a clarification, since the manual indicates that float-sign with one argument never returns zero even if the argument is zero.  Received: from MIT-ML by SU-AI with TCP/SMTP; 3 Jun 83 20:49:55 PDT Date: 3 June 1983 23:51 EDT From: George J. Carrette Subject: Destructuring To: COMMON-LISP @ SU-AI I have a note talking about reasons for a destructure feature if anybody wants me to sent it to them. Suffice it to say that destructuring is used heavily in the evaluator, compiler, and macrology of NIL, and it has saved a lot of CAR/CDR'ing and control structure. The name I suggest for the special form is DESTRUCTURE. It isn't very difficult to implement entirely in lisp, with no restrictions on keyword placement etc. ;; Here is an example call: (defknown si:examine-byte (form) (destructure form (p &optional (i 0)) ...))) ;; Which is equivalent to: (defknown si:examine-byte (form) (dspread&apply (lambda (p i) ...) '(p &optional (i 0)) form)) ;; Which is a pretty good hint of how it is implemented in NIL. -GJC  Received: from MIT-ML by SU-AI with TCP/SMTP; 3 Jun 83 19:13:25 PDT Date: 3 June 1983 22:15 EDT From: Glenn S. Burke Subject: ballot A To: Fahlman @ CMU-CS-C cc: common-lisp @ SU-AI A1. Add parse-integer. Yes. A2. Proclaim. Yes. A3. [Package names] I could live with b or c. I have no strong objection to either. A4. vector-push arg order. Yes, fix it. A5. Add KMP's (NTH-VALUE n form) No objection if it is zero origined. A6. defstruct primitives I don't really care. The proposal was to supply an alternative to named arrays, which i do not approve of in the white pages as a mechanism for defining typed objects. A7. eliminate SET and FSET I am fairly neutral on this. A8. (apply '(lambda ...) ...) It should either be invoked in a null lexical environment, or be totally illegal. In NIL, I have experimented with it both being invoked in a null environment, and being invoked in the "current" environment. The latter makes (mapcar '(lambda ...) ...) work as a Maclisp user might expect, but is totally ridiculous otherwise. Also, I do not see how it can be tractable to interpret it as if it were #'(lambda ...), because by the time you see it you have lost the context. A9. Propose that we reinstate VREF. Shucks, i had just written documentation stating that this was obsolete. I don't really care. I would prefer to have primitives to access the simple array types. A10. Add an optional integer seed to MAKE-RANDOM-STATE. Yes. A11. Propose that we adopt the APPLYHOOK feture, as specified by Moon. Yes. A12. Add a simple form of destructuring LET macro. Not as proposed. I would like a destructuring primitive which provides exactly the functionality defmacro provides, including &mumbles. It should not be LET based; my experience with destructuring LET is that (besides grossness with LET*) the extra parentheses needed by LET syntax make it unreadable. The NIL compiler defines (defmacro debind-args (pattern call-form &body body) ...). This is also used by the interpreter. A13. A modification to INTERN and FIND-SYMBOL This sounds reasonable. A14: Proposed by KMP that we rename MULTIPLE-VALUE to MULTIPLE-VALUE-SETQ. Can we shorten these to MV-SETQ and MV-BIND? Instead of (multiple-value-setq (a b c) ...) it will be tempting to abbreviate to (setf (values a b c) ...), although i guess that is not supported. A15: Implementation limits Yes we should have constants with the values of those limits, but No, we SHOULD specify certain minimums within which portable code may blithely run correctly. A16. Guy proposes that we get rid of MACRO Yes, but (setf (macro-function ...) ...). A17. Reduction to canonical form For rationals, yes, definitely. For the complex case i am not so sure. I guess i will defer to others on this, but i feel uncomfortable with it.  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 3 Jun 83 18:50:47 PDT Date: 3 June 1983 2145-EDT (Friday) From: Walter van Roggen (C410WV50) To: Fahlman@cmu-cs-c Subject: Another ballot CC: Common-Lisp@SU-AI Message-Id: <03Jun83.214553.WV50@CMU-CS-A> A1: yes. But with PARSE-INTEGER to help read data, do we really need *READ-BASE* so much? A2: ok A3: option B. Lisp syntax is complex enough as it is. (perhaps a surprising thing to say, even discounting FORMAT.) A4: yes A5: ok, 0 based A6: no A7: yes, at least get rid of FSET, preferably both. I'd also like to see SETF renamed to SET, but that seems too much to ask for now. A8: yes A9: ok, though I'd prefer getting rid of CHAR and BIT as well A10: yes, though what arguments should MAKE-RANDOM-STATE take then? A11: ok A12: yes iff DEFMACRO has it. A13: ok A14: yes A15: ok, but rename CALL-VALUES-LIMIT to MULTIPLE-VALUES-LIMIT. We must agree on lower bounds for these values. There should be no bound on the number of arguments to a function, only on the number of named ones. A16: yes A17: yes ---Walter  Received: from MIT-MC by SU-AI with TCP/SMTP; 3 Jun 83 17:27:23 PDT Received: from SCRC-COLLIE by SCRC-TENEX with CHAOS; Fri 3-Jun-83 20:25:25-EDT Date: Friday, 3 June 1983, 20:24-EDT From: David A. Moon Subject: PROCLAIM and implicit EVAL-WHEN To: common-lisp@SU-AI In-reply-to: The message of 3 Jun 83 17:52-EDT from Dir LCSR Comp Facility Date: 3 Jun 83 17:52:01 EDT From: Dir LCSR Comp Facility A2. I think I am opposed to the details of the new PROCLAIM. I agree with most of what is proposed, but I do not like the idea of an implicit EVAL-WHEN, at least if I understand what is meant. I would like PROCLAIM to be evaluated in exactly the same way as DEFUN. That is, if you type it at the top level of Lisp, or it is at the top level of a file, it would work in the expected way. As I understand it, you are proposing that a PROCLAIM could occur in a random place in the middle of code, and it would still happen at COMPILE or LOAD time. I think this is a bad idea. The whole idea of restricting DECLARE to the beginning of blocks was to minimize this kind of thing. I guess this wasn't explained very well; probably my fault. The implicit EVAL-WHEN is to make PROCLAIM be evaluated in exactly the same way as DEFUN. In other words, when the compiler sees PROCLAIM "at top level" it evaluates it at compile time, rather than just pushing the form through into the "fasl" file to be evaluated at load time. There are a bunch of functions and special forms with this property, that the compiler knows to handle them at compile time; hopefully the next edition of the manual will list them. Precisely what "at top level" means seems to be still under discussion. But clearly it means at least real top-level, inside PROGN, and inside COMPILER-LET. It means inside some flavors of EVAL-WHEN too. But it doesn't mean at a random place in the middle of code; there PROCLAIM is just a function like any other. By the way, would you allow us to set CALL-VALUES-LIMIT to 1? No, for obvious reasons (there are functions in the manual that are defined to return two values).  Received: from RUTGERS by SU-AI with TCP/SMTP; 3 Jun 83 14:51:05 PDT Date: 3 Jun 83 17:52:01 EDT From: Dir LCSR Comp Facility Subject: Re: Another ballot To: Fahlman@CMU-CS-C.ARPA cc: common-lisp@SU-AI.ARPA In-Reply-To: Message from "Scott E. Fahlman " of 3 Jun 83 02:27:00 EDT A1. Yes, do PARSE-INTEGER. But no pound-signs or other hair, please. A2. I think I am opposed to the details of the new PROCLAIM. I agree with most of what is proposed, but I do not like the idea of an implicit EVAL-WHEN, at least if I understand what is meant. I would like PROCLAIM to be evaluated in exactly the same way as DEFUN. That is, if you type it at the top level of Lisp, or it is at the top level of a file, it would work in the expected way. As I understand it, you are proposing that a PROCLAIM could occur in a random place in the middle of code, and it would still happen at COMPILE or LOAD time. I think this is a bad idea. The whole idea of restricting DECLARE to the beginning of blocks was to minimize this kind of thing. A3. We can live with anything that you can implement, but would prefer B, to treat the package part just like the symbol part. MUCH easier for users to remember. A4. Yes, fix VECTOR-PUSH and VECTOR-PUSH-EXTEND. A5. No, we don't need more MV mechanisms. As always, I propose to simply MV's further by removing them. A6. No, I am satisfied with an almost-transportable DEFSTRUCT. A7. No, do not remove SET. While we are at it, CONS seems like an unnecessary relic. It is after all a special case of a structure.... A8. No, do not make it an error to do (APPLY '(LAMBDA ... That is, don't do just that. However I agree completely that the whole issue of what is a function object needs further thought. If a complete analysis of this results in (LAMBDA not being a function object and thus not allowing APPLY on it, I am willing to accept that. I suspect that it is too late to do such an analysis for this release of Common Lisp. A9. Abstain on VREF. A10. Yes, allow a seed in MAKE-RANDOM-STATE. A11. My concern with APPLYHOOK is whether we are ready to standardize that hook. If all of the implementors and potential implementors agree that these are the right hooks, then by all means. I defer to the Spice people on this, since we are using their evaluator. A12. Yes, allow simple destructuring. Do not destructure the family cat. A13. No, do not make INTERN return multiple values. I am willing to allow it for FIND-SYMBOL, however. A14: Yes, that name seems reasonable. Would you consider using MV-SETQ, etc.? While I am just as happy to discourage the use of all MV primitives, do we really want primitives with names that are that long? A15: In general I accept the proposal on bounds. I think some implementations might be able to live with arrays with a small maximum rank. However I do not believe that this is true for arguments for functions. I agree that it is a pain to implement large numbers of arguments for functions. I know. It has caused us real hassles. Nevertheless I believe it is necessary. I am willing to let implementors cop out on array ranks if they want to, but not on arguments. I believe that the only limits on number of arguments should be those imposed by the size of memory, stack space, etc. It is bad enough to have arbitrary limits in Pascal. In a language like Lisp it is unforgiveable. We probably need to set an actual number as the minimum maximum number of arguments. The number must be set large enough to make it impossible for an implementation to get away with any of the easy solutions, and small enough that we can still implement CLISP on a micro. By the way, would you allow us to set CALL-VALUES-LIMIT to 1? A16. OK, do what you want with MACRO. A17. Yes, reduce all numbers to their simplest form (but not floating point to integers...) -------  Received: from MIT-MC by SU-AI with TCP/SMTP; 3 Jun 83 14:30:40 PDT Received: from SCRC-COLLIE by SCRC-TENEX with CHAOS; Fri 3-Jun-83 17:29:13-EDT Date: Friday, 3 June 1983, 17:27-EDT From: David A. Moon Subject: Ballot A To: Common-Lisp@SU-AI A1. PARSE-INTEGER Yes A2. PROCLAIM is a function Yes A3. Package name lookup none of the above I agree that making the syntax of the package-name part of a qualified name exactly like the syntax of the symbol-name part is an improvement, and I'm willing to give in and allow vertical bars here. Note that this syntactic equivalence applies both to READ and to PRINT. Note that package names are given in three essentially different contexts: As prefixes in qualified names of symbols As arguments to functions that take a package object or name, e.g. USE-PACKAGE As the name when creating a package, e.g. MAKE-PACKAGE first argument. I am unhappy about any scheme that involves a string-based user interface to something that uses case-sensitive lookup. I have two proposals, the first being preferred: 1) Package-name lookup is case-insensitive; you cannot have two distinct packages whose names differ only in case. The case of the name given to MAKE-PACKAGE is remembered, thus if it is not all upper-case the package name will contain escape characters when printed in a qualified name. 1a) An acceptable variant says that MAKE-PACKAGE calls STRING-UPCASE if given a string (but not if given a symbol) as the name. 2) Package-name lookup is case-sensitive but the user interface is in terms of symbols rather than strings; thus MAKE-PACKAGE, USE-PACKAGE, EXPORT, etc. demand symbols as their package-name arguments. These symbols are compared with SAMEPNAMEP, not EQ, thus it doesn't matter what package they are in. The serious problem with this is: does PACKAGE-NAME return a symbol or a string, and if it returns a symbol, what package is the symbol in, or is it uninterned? A4. VECTOR-PUSH arg order Yes A5. NTH-VALUE Mildly in favor A6. Named-structure primitives Neutral I don't care whether the named-structure primitives are considered to be part of the language or part of defstruct, i.e. whether they appear in the White Pages or in the Implementor's Guide to Installing Defstruct. I am opposed to the :NAMED argument to MAKE-ARRAY and MAKE-VECTOR appearing in the white pages, although in fact it will exist in both Symbolics and Spice Common Lisp dialects. A7. Flush SET, SETF None of the above I favor the way Steele had it in the manual last time I looked, which was that SET is retained due to the grandfather clause, and its frequent usefulness, whereas FSET is removed due to confusion with SETF and lack of frequent usefulness. A8. (apply '(lambda ...)) is an error No I am opposed to this because it would be a break with the past whose implications are not well-understood. Later we can decide it is bad style and discourage it, if we like. I think there are good reasons to allow a function name to stand for a function object, when the function object contains no free lexical references. If there are free lexical references, it is an error. The NIL interpreter seems to do a nice job of warning about this error. It is already noted in the manual that APPLY with a symbol as the first argument looks up the functional value of that symbol in the global environment, not the caller's environment. (Of course, (APPLY 'FOO...) is exactly analogous to (EVAL 'FOO).) Even the latest version of the manual forgets to say this for FUNCALL, but surely FUNCALL and APPLY are supposed to be consistent. A9. Add VREF Neutral A10. Integer seed for MAKE-RANDOM-STATE Yes Stress that this gives you a -repeatable- sequence of random numbers, and that the implementation makes "an effort" not to give the same sequence for different seeds. A11. Add APPLYHOOK Yes A12. Add DLET No I think we should have destructuring, but not with this name and not with the syntax of LET. By voting against this it is incumbent on me to propose an alternative; I'll try to send out a proposal early next week. There are more issues than recognized by the simple proposition that DLET be added. I think it is probably a good idea to defer destructuring until the second edition of the manual because there is probably going to be a substantial amount of discussion. For now, let's have it only in DEFMACRO where the issues are very clear. A13. Two values from INTERN, FIND-SYMBOL Yes Flush FIND-EXTERNAL-SYMBOL A14. MULTIPLE-VALUE-SETQ Neutral If it is called ...-SETQ, it must accept any even number of subforms, not just 2. A15. Implementation limit constants Yes I agree with DLW and BSG about putting a floor under these. The constants are still valuable, e.g. for checking whether a program will work in an implementation without exhaustively testing all paths through the program. If you want suggestions for the floors, I'll suggest 3 dimensions, 50 arguments, and 10 values. The actual hard limits in my implementations are 7, 63, and 10 (easily raised to 63) in the LM-2, and something higher in the 3600 (7, 255, and 255 except that there are probably other limits that come into play a little below 255). Is the limit on number of arguments different for functions with &REST or &KEY than for fixed-maximum functions? Does the limit on number of arguments apply to the length of the last argument to APPLY? A16. Flush MACRO Yes, but I agree with EAK that it should be SETF of MACRO-FUNCTION. My objection to MACROP being a ps****predicate (i.e. returning the expander function), was that people should not be allowed to call that function directly; only EVAL and MACROEXPAND-1 may call it. This was for macro memoization and in the hope that checking of the length of the form could be centralized rather than done separately by each expander function. These aren't strong enough reasons to turn down the proposal, especially since we have *MACROEXPAND-HOOK* now. Checking of the length of the form is really subsumed into checking of the syntax of the form, and needs to be done separately by each expander function, I now believe. A17. Gaussian rationals No vote It is already the case that (integerp 4/2) is true. There was a slight braino about this somewhere in the Laser manual. Having Gaussian rationals behave as an extension of the real rationals seems superficially plausible, but I don't consider myself competent to evaluate the implications. Let me ask the $64 question: will the result of any function, other than type-checking functions and transcendental functions, be affected by this change (i.e. are there other functions that treat complex numbers on the real line different from real numbers)?  Received: from MIT-MC by SU-AI with TCP/SMTP; 3 Jun 83 14:03:15 PDT Received: from SCRC-CONNECTICUT by SCRC-SPANIEL with CHAOS; Fri 3-Jun-83 14:48:00-EDT Date: Friday, 3 June 1983, 14:47-EDT From: Robert A. Cassels Subject: Functions for taking apart floating-point numbers To: Common-Lisp at su-ai Proposal: Remove @f[float-exponent] and @f[float-integer-exponent], and return those numbers as the second values from @f[float-significand] and @f[float-integer-significand]. This would serve to make these functions more similar to the division functions, and emphasize the close relationship between the values. It also leads to slightly improved efficiency of implementation, particularly on systems with unnormalized (or denormalized) numbers, and those with "non-numeric" floating-point values [IEEE floating-point, anyone?] which must be checked. (I'm assuming that when one value is wanted, the other is almost always wanted also.) In addition, the comment: @Implementation{The typical implementation will be such that the difference between the values returned by @f[float-integer-exponent] and @f[float-exponent] will be equal to the number of internal-floating-radix digits used to represent the significand. However, @clisp programs should not assume this to be the case.} should either be removed or expanded to note that this is not true of unnormalized or denormalized numbers. --------- Proposal: Add new functions @f[float-digits] and @f[float-precision]. @f[(float-digits float)] would return the number of @f[(float-radix float)] digits used in the representation of a floating-point number. (Including the "hidden bit", if any.) For most implementations, this is really a property of the type of @f[float]. @f[(float-precision float)] would return the number of significant @f[(float-radix float)] digits present in @f[float]. @Implementation{For implementations using only normalized numbers, these functions would be identical. @f[(- (float-digits float) (float-precision float))] would reflect the degree of denormalization of @f[float].} These functions are needed to simplify the movement of floating-point numbers from one implementation to another. They are also needed to convert numbers from one base to another in a way which reflects the precision (doesn't print bogus digits). @f[float-digits] could be computed for most implementations by @f[(- (float-exponent 1.0) (float-exponent single-float-epsilon))] or something like that. But making it a function seems cleaner than some sort of typecase. --------- Proposal: Require the result of @f[float-integer-significand] to reflect the precision of the floating-point number. Currently, @f[float-integer-significand] is only required to satisfy the identity relating it to @f[float-integer-exponent]. That allows the result to be scaled by various powers of the radix, so long as the exponent is adjusted appropriately. So if @i[b] is @f[(float-radix float)] and @i[p] is @f[(float-precision float)], the result of @f[(float-integer-significand float)] for non-zero @f[float] should be between @f[(expt b p)] (exclusive) and @f[(expt b (1- p))] (inclusive). --------- Proposal: Clarify the result of @f[(float-sign 0.0)], @f[(float-sign -0.0)]. The possibility of signed zeros needs to be addressed. Presumably @lisp (float-sign 0.0) @EQ 1.0 (float-sign -0.0) @EQ -1.0 @endlisp  Received: from MIT-MC by SU-AI with TCP/SMTP; 3 Jun 83 13:38:25 PDT Date: 3 June 1983 16:32 EDT From: Kent M. Pitman Subject: Another Ballot To: Fahlman @ CMU-CS-C cc: Common-Lisp @ SU-AI A1 Yes PARSE-INTEGER is OK. A2 No I prefer that declarations be special forms. I would prefer to offer PROCLAIM with no argument evaluation and *PROCLAIM as a subr form such that (PROCLAIM form1 form2 ...) is the same as (EVAL-WHEN (EVAL COMPILE LOAD) (*PROCLAIM 'form1 'form2 ...)) That is, the subr form should not be "implicitly" in any EVAL-WHEN. I would like to keep the common, purely declarative, case simple. A3 B I strongly prefer B. I believe it to be maximally consistent with the rest of the Common-Lisp design. I also believe that current Lisp Users' models best support this view. I would also accept a hybrid B/C with syntax as per B, but with case-insensitive lookup. I slightly prefer B to this, however. I believe C is just barely acceptable, but I think this will do very bad things to users' models. Many users take a long time to understand what |...| and / are about already; I believe trying to separate contexts where they can be used will add undue conceptual overhead for novices. I strongly oppose A as inconsistent with the case-retention rules for the "other half" of symbols. I think novices would be confused silly by this. A4 Yes Consistency between VECTOR-PUSH,etc. and PUSH sounds good. A5 Yes I like NTH-VALUE. NTH was zero based and people can live with that. I find such an argument spurious. A6 --- I have no strong feelings on this named structure primitives issue. A7 Yes I strongly support this. Users read too much into the symmetry of names SET and SETQ. In a lexical lisp, this is far more dangerous than a dynamic lisp. ALAN should just type (SETQ #.+ ...) to the read-eval-print loop. A8 Yes I think (APPLY '(LAMBDA ...) ...) should be left undefined and implementors might be free to support it as an implementation- dependent upward compatible extension. This will save implementors from having to take any immediate action, but leave Common Lisp more flexibility later on. Users should be discouraged from doing this. A9 No If SVREF exists, then VREF maybe should exist for symmetry; otherwise, it seems like SVREF should be SAREF instead ... Alternatively, SVREF could be renamed VREF. I'm not sure any more what the full proposal for arrays/vectors looks like any more. I'd rather defer this issue until I can evaluate it more coherently. A10 Yes Extra arg to MAKE-RANDOM-STATE sounds harmless and potentially useful. A11 Yes Just this week I found the APPLYHOOK feature in the LispM and was able to clean up some very ugly code which was trying to replace it. The phrase "EVAL binds both *EVALHOOK* and *APPLYHOOK* to NIL around calls to either of them." has a very nebulous "them" referent. A12 No I like and use Destructuring LET a lot, but am sympathetic to peoples' arguments that it is a data abstraction violation in general. I do, however, agree with Weinreb's comments on DLET and suggest that he propose this DESTRUCTURING-BIND primitive as an alternative. A13 Yes Flush FIND-EXTERNAL-SYMBOL in favor of FIND-SYMBOL with extra value. The extra value would be needed in any case to disambiguate the case of FIND-SYMBOL of "NIL" ... A14 Yes MULTIPLE-VALUE => MULTIPLE-VALUE-SETQ A15 Yes Add ARRAY-RANK-LIMIT, etc. Even if these were the same values everywhere, having people compare to symbolic names would be good. A16 No This has certain SET/SETQ confusions about it that make me very uncomfortable. The issue of "scoped" macros doesn't now occur but might some day and I worry that if arg1 to SET-MACRO is ever anything besides 'something, it may be hard to statically resolve in a useful way. The minimal change that would make me happy is to call it SETQ-MACRO or MACRO-SETQ or some such, but all in all, I'd rather just flush this proposal. MACRO has other problems (like it's a pain for programs like ATSIGN and EMACS which may not realize it defines something). Why not just change its name to DEFINE-PRIMITIVE-MACRO. I think that would adequately discourage its use by novices while not introducing the SET/SETQ problem I mentioned about above. A17 --- This sounds superficially like a good idea, but I have done no significant programming in such areas so can't adequately evaluate the efficiency implications or the effect on the compiler of not being able to predict an exact datatype returned from one of these functions (potentially important on general purpose hardware). So I'll abstain and hope you others know what you're doing.  Received: from SU-DSN by SU-AI with PUP; 03-Jun-83 12:38 PDT Received: From MIT-XX by SU-DSN.ARPA; Fri Jun 3 12:39:32 1983 Date: Friday, 3 June 1983, 12:38-PDT From: BENSON at SPA-Nimbus Subject: Earlier message on function objects To: Common-Lisp at Sail Here is the message I sent about a month ago. The last paragraphs suggests some system-building tools. Purists may object to these as violating referential transparency. They are not essential for most users, but every system will need something like them, so they might as well be portable. -------------------- -*-Mode:Text-*- To: Common-Lisp%su-ai@usc-ecl Subject: Function objects The Laser Edition of the Common Lisp Reference Manual is inconsistent in its treatment of functions. This inconsistency is due to confusion between the name of a function and the actual function object. This confusion has been around for a long time, and is manifested in many Lisp implementations where the name of a function object and the object itself are the same. To quote from the Standard Lisp Report: "FUNCTION is like QUOTE but its argument may be affected by compilation." First, we need to state what we mean by a function object. The definition of the FUNCTIONP data type predicate says that it "is true if its argument is suitable for applying to arguments, using for example the FUNCALL or APPLY function." The definition of APPLY states that its argument "may be a compiled-code object, or a lambda expression, or a symbol; in the latter case the global functional value of that symbol is used." (Let's ignore compiled-code objects for the time being; we'll get back to them later.) This is the definition which confuses the name (symbol or lambda expression) and the function object. Conflicting with this definition is the Functions section of the Progam Structure chapter (Section 5.2, p. 42). It states that "Lambda-expressions and symbols as names of functions can appear only as the first element of a function-call form, or as the second element of the FUNCTION special form." The definition of the FUNCTION special form, where FN is the second element of the form, states that "if FN is a symbol, the functional value of the variable whose name is that symbol is returned. If FN is a lambda expression, then a lexical closure is returned." Notice that the definition of APPLY doesn't even mention lexical closures, yet these are the things which are produced by the FUNCTION special form, which is presumably the preferred means of obtaining a suitable object to use as an argument to APPLY! The key to understanding all of this is to realize that the CAR of a Lisp form (ignoring macros and special forms) is not "not evaluated," in fact it is a function name which is evaluated to produce a function object. In Scheme this evaluation is the same as that used to produce function arguments, i.e. the function EVAL. Common Lisp must use a different algorithm, because it permits symbols to have distinct variable and function values. The function which implements this algorithm is not mentioned in the Common Lisp manual. In fact I don't know of any Lisp implementations which provide it; it is usually open-coded (sometimes a no-op!) within EVAL. For the sake of discussion, let's call it FEVAL. In fact the one we are most interested in is *FEVAL, analogous to *EVAL, since this function must use the current lexical environment in its evaluation process. Evaluation of a form which represents an ordinary function call is thus: FEVAL the CAR of the form, EVAL all the other elements of the list, call the result of FEVAL with the EVALed arguments. FEVAL is useful to produce a function object which will not be called immediately. The FUNCTION special form says in effect: use FEVAL instead of EVAL to produce this argument. Conversely, EVAL is also useful in producing function objects. FUNCALL allows normal argument evaluation to return a function object to be called. Note that neither FUNCTION nor FUNCALL is needed in Scheme precisely because EVAL and FEVAL are the same. FEVAL is a very simple function. If its argument is a lambda expression, it returns a closure of the expression over the lexical environment. If it is a symbol, the "functional variable" value of the symbol in the lexical (or global) environment is returned. Anything else is an error. As an upward-compatible extension, function specs as provided in Zetalisp, such as (:PROPERTY FOO BAR), are treated essentially the same as symbols. They simply specify a place from which to fetch a function object. The semantics of compiled-code objects have not been described extensively in the Common Lisp manual. They are mentioned in the spurious definition of APPLY above, which might lead one to think of them as being "like lambda expressions, only faster." In fact the only sensible interpretation of a compiled-code object is "like FEVAL of a lambda expression, only faster." In other words, anything a lexical closure can do, a compiled-code object can do, except that the structure selector functions defined below would only be for lexical closures. This should be stated explicitly in the manual in the data type section. The argument to APPLY (and FUNCALL) can be a compiled-code object or a lexical closure; anything else is an error. A language standard which considers symbols or lambda expressions to be functions is perpetuating the confusion described above. To acheive the effect of using a symbol as a function as described above (and currently implemented in Zetalisp, for example), that is, using the global functional value at the time it is called, one must use a closure which calls the function, e.g. to give BAR as a functional argument to FOO, where BAR's definition may change between the call to FOO and the FUNCALL of its functional argument, use: (FOO #'(LAMBDA (X) (BAR X))) ;BAR is a function of one argument instead of (FOO 'BAR) In general, if the number of arguments is unknown: (FOO #'(LAMBDA (&REST X) (APPLY #'BAR X))) Or, if you really mean the global function value, not the lexical: (FOO #'(LAMBDA (&REST X) (APPLY (SYMBOL-FUNCTION 'BAR) X))) The current language definition does not provide either a function which takes a lambda expression and a lexical environment and returns a lexical closure (*FEVAL) or functions to extract these components from an existing lexical closure. These aren't strictly necessary, but without them many useful parts of a programming environment must be written non-portably. For example, GRINDEF is impossible in portable Common Lisp, since SYMBOL-FUNCTION must return either a lexical closure or a compiled-code object. A structure editor which can redefine a function requires both selector functions and the constructor function, since it must create a new closure with the modified function body. I recommend that lexical environments be included in the language as first-class objects. *EVAL and EVALHOOK would then be defined to take exactly two arguments. ENCLOSE (*FEVAL restricted to lambda expressions) takes a lambda expression and a lexical environment and returns a lexical closure. CLOSURE-EXPRESSION and CLOSURE-ENVIRONMENT take a lexical closure and return its components. The constant NULL-ENVIRONMENT, the empty lexical environment, should be defined. The structure of a lexical environment need not (indeed, should not) be specified. These additions are not major and would aid immensely in supporting a truly lexical Lisp.  Received: from SU-DSN by SU-AI with PUP; 03-Jun-83 12:23 PDT Received: From MIT-XX by SU-DSN.ARPA; Fri Jun 3 12:24:36 1983 Date: Friday, 3 June 1983, 12:22-PDT From: BENSON at SPA-Nimbus Subject: Function names and function objects To: Common-Lisp at Sail I had a feeling this would finally come up when we had to vote on it. Apparently several people missed my message on this subject about a month ago. I will resend it for the benefit of those people. Let me also restate some important points: Function names (lambda expressions and symbols) are not the same as function objects (lexical closures and compiled code objects). The special forms FUNCTION and QUOTE are only related by historical confusion. Function evaluation (the process which produces a function object from a function name) is entirely unrelated to function application. If the semantics of a function object depend on the environment in which a name is evaluated to produce it, the function name and the function object cannot be the same. It was an implementation convenience in dynamically-scoped Lisps, where the semantics of the function object depended only on the environment at function application time, to make function names and function objects the same. In a lexically-scoped Lisp, a single function name may be evaluated in different places or at different times to produce different function objects. This means that symbols as well as lambda expressions would be disallowed as function objects. It may be a bitter pill to swallow, but it would be extremely unfortunate if this confusion were to be continued in Common Lisp. If it is too hard to convert programs immediately, perhaps we can have a "phase-out" period, where symbols applied as functions will be evaluated via SYMBOL-FUNCTION, and lambda expressions when applied will be closed in the null lexical environment (certainly NOT in the enviroment of the call!). Implementations would warn that this usage is archaic, and at some agreed-upon time in the future the warning would change into an error. This is not simply a matter of being dogmatic. We would laugh at the suggestion that taking the CDR of a symbol, if it happened to be a special variable bound to a list, would return the CDR of the list it was bound to. Yet this is exactly analogous to using the dynamic function value of a symbol if it happens to get applied. We should not confuse function evaluation with function application just because they most commonly happen at about the same time in ordinary function calls. -- Eric  Received: from MIT-MC by SU-AI with TCP/SMTP; 3 Jun 83 11:53:01 PDT Date: 3 June 1983 14:53 EDT From: Alan Bawden Subject: Another ballot To: Fahlman @ CMU-CS-C cc: common-lisp @ SU-AI 1. Yes. 2. Yes. 3. C 4. Yes. 5. Yes. It should be zero-based as Moon points out. 6. As the implementor of defstruct, let me point out that it makes no difference which way this vote goes. Even if you don't write these functions into the Common Lisp spec, I am likely to write a portable defstruct that requires you to have them anyway. 7. Flush FSET, but keep SET. I type "(SET + ...)" to the read-eval-print loop all the time. FSET I never use, it has a poor name, and it isn't even a traditional function. 8. Abstain. 9. Don't care. 10. Yes. 11. Yes. 12. Yes. 13. Yes. 14. Yes. 15. I would suggest 5 as the largest array rank required to be supported. 16. Abstain. 17. Yes. I suggested this last December along with some other suggestions about Gaussian rationals. (I suggested that the functins GCD, NUMERATOR, and DENOMINATOR have their domains appropriately inlarged, for example.) Does this indicate that my other suggestions were lost or forgotten?  Received: from MIT-MC by SU-AI with TCP/SMTP; 3 Jun 83 10:48:52 PDT Received: from SCRC-BEAGLE by SCRC-TENEX with CHAOS; Fri 3-Jun-83 13:46:14-EDT Date: Friday, 3 June 1983, 13:45-EDT From: Bernard S. Greenberg Subject: Another ballot To: Fahlman%CMU-CS-C@SU-DSN, common-lisp@su-ai In-reply-to: The message of 3 Jun 83 02:27-EDT from Scott E. Fahlman Date: Fri, 3 Jun 1983 02:27 EDT From: Scott E. Fahlman A8. EAK has also asked that we vote on this: Propose that in Common Lisp it is an error to do (apply '(lambda ...) ...). What are we talking about anyway here, '(lambda ) vs. #'(lambda ), or funcall/apply'ing internal lambda expressions, or apply as opposed to funcall of internal lambdas? I don't remember EAK's original remark.  Received: from S1-C by SU-AI with TCP/SMTP; 3 Jun 83 10:14:24 PDT Date: 3 Jun 1983 10:12:51-PDT From: eak at s1-c To: Common-Lisp@sail Subject: compiled-function It is not at all clear to me what this type really is, or what its corresponding predicate does. Does a closure where the code is compiled qualify, or is it just a pointer to compiled code? If it is the latter, it may not even be an applicable object in S1 lisp, if I understand S1 lisp properly, because functions are always closures. That makes the word "function" misleading in its name. Anyway, clarification on this is needed. Also, as DLW points out, there the result of the function special form is not documented to be a function in the laser edition. This is presumably an oversight, but it raises the question, do we need a closure type and a closurep predicate?  Received: from S1-C by SU-AI with TCP/SMTP; 3 Jun 83 10:08:49 PDT Date: 3 Jun 1983 10:05:48-PDT From: eak at s1-c To: Common-Lisp@sail Subject: 2nd ballot A1. Yes A2. Yes A3. c or b A4. Yes A5. Yes A6. wait A7. Yes A8 [Lists with car eq lambda are functions]. Yes, there is no point in forcing an implementation to do this as it is unnecessary in writing portable Common Lisp programs. I'm not even sure that these are of any use at all; no one defended lists as functions when their removal was suggested in the mailing list months ago, which is why I asked for it to be on the ballot. A9. No A10 [Add optional integer argument to MAKE-RANDOM-STATE]. No. The statement in the ballot is incorrect -- according to the laser edition, (MAKE-RANDOM-STATE T) gets you a new state object "that has been `randomly' initialized by some means (such as by a time-of-day clock)." A11. Yes A12. No opinion. A13. Yes A14. Yes A15. I agree with BSG. A16. Wouldn't it be better to rename MACRO-P to MACRO-FUNCTION and then (MACRO-FUNCTION ) would get you the function, and (SETF (MACRO-FUNCTION ) #'(LAMBDA ...)) would set it? However, I seem to remember that Moon had objections to having MACRO-P return a function; was that resolved before the laser edition went out, or is the laser edition out-of-date on this? A17. Yes  Received: from MIT-MC by SU-AI with TCP/SMTP; 3 Jun 83 09:24:51 PDT Received: from SCRC-CONNECTICUT by SCRC-TENEX with CHAOS; Fri 3-Jun-83 12:24:18-EDT Date: Friday, 3 June 1983, 12:23-EDT From: Robert A. Cassels Subject: [Moon at SCRC-TENEX: short-float-negative-epsilon] To: Common-Lisp@su-ai Return-path: Received: from SCRC-BULLDOG by SCRC-TENEX with CHAOS; Wed 30-Mar-83 17:22:23-EST Date: Wednesday, 30 March 1983, 17:20-EST From: David A. Moon Subject: short-float-negative-epsilon To: Guy.Steele@CMU-CS-A Cc: common-lisp%su-ai@su-score, Cassels@SCRC-TENEX Am I correct in guessing that the arguments to - in the Lisp-code definition of short-float-negative-epsilon in the Laser edition are backwards? The code as it stands is clearly bogus. If the arguments to - are backwards, then negative-epsilon would be the smallest positive number that you can subtract from 1.0 and get a different answer than 1.0. ------ This hasn't been fixed in the latest version of the manual we have.  Received: from MIT-ML by SU-AI with TCP/SMTP; 3 Jun 83 09:06:04 PDT Received: from SCRC-BORZOI by SCRC-TENEX with CHAOS; Fri 3-Jun-83 12:03:58-EDT Date: Friday, 3 June 1983, 12:03-EDT From: Daniel L. Weinreb Subject: Another ballot To: Fahlman%CMU-CS-C@SU-DSN, common-lisp@su-ai In-reply-to: The message of 3 Jun 83 02:27-EDT from Scott E. Fahlman Sorry, I never got back to A8. I'm sure I don't understand the implications of all of this myself, either. However, on page 42 it says quite explicitly that a lambda expression is not a form and cannot be meaningfully evaluated. So you cannot turn (apply '(lambda ...) ...) into (apply (lambda ...) ...) and expect it to work. Perhaps the suggestion is that you have to turn it into (apply #'(lambda ...) ...)? Presumably the restriction would also apply to funcall, mapcar, and anything else that accepts a "function" as an argument? If you read section 2.13 (p 23), it doesn't even say that "lexical closures" are functions, even though the description of function (p 62) talks about returning lexical closures. In fact, Chapter 2 doesn't say much about lexical closures at all; it's not clear how they fit into the type system. 2.13 also says that lambda expressions are functions; A8 would change this as well. My gut feeling at this point is to say No to A8, continue to allow lambda-expressions to act as functions, but clear up the role of functions in the language by making 2.13 more correct and having the definitions of apply and funcall refer to 2.13. I think this is partly that I'm being conservative, and hoping the ease the conversion task ahead, but also that the implications just aren't clear enough.  Received: from MIT-MC by SU-AI with TCP/SMTP; 3 Jun 83 09:13:07 PDT Received: from SCRC-BORZOI by SCRC-TENEX with CHAOS; Fri 3-Jun-83 11:45:48-EDT Date: Friday, 3 June 1983, 11:44-EDT From: Daniel L. Weinreb Subject: The dogma killed ASET To: Moon%SCRC-TENEX%MIT-MC@SU-DSN Cc: common-lisp@su-ai In-reply-to: The message of 3 Jun 83 01:57-EDT from David A. Moon One thing's for sure: this is a nifty demo of the power of the new 5-values SETF scheme. My taste-buds are oscillating between calling this a kludge and calling it elegant; when two things can be put together in an unexpected way to produce a result that's unexpected but useful, it can be hard to say whether that constitutes a demonstration of inherent elegance or a programming trick. Certainly I don't think that there's anything better for (setf (apply #'aref ...) ...) to expand into. If nobody comes up with any real problem with this, I'd say it constitutes a solution to the problem. It's probably worth documenting explicitly somewhere since a lot of people would never guess that this might work.  Received: from MIT-MC by SU-AI with TCP/SMTP; 3 Jun 83 08:38:27 PDT Received: from SCRC-BORZOI by SCRC-TENEX with CHAOS; Fri 3-Jun-83 11:38:02-EDT Date: Friday, 3 June 1983, 11:37-EDT From: Daniel L. Weinreb Subject: Another ballot To: Fahlman%CMU-CS-C@SU-DSN, common-lisp@su-ai In-reply-to: The message of 3 Jun 83 02:27-EDT from Scott E. Fahlman A1: Yes. A2: Yes. A3: B and C are both OK; no real preference. A4: Yes. A5: Yes. It's not rare to want some single value other than the first. I see nothing non-intuitive about having it be 0-based; everything is 0-based. A6: (No opinion, I haven't been following this issue.) A7: No. I realize it's a highly arbitrary tradeoff. A8: A9: No. This is completely redundant; there's no need for it. A10: Yes. A11: Yes. A12: I am basically in favor of this. I am especially in favor of this if we allow list-oriented destructuring in DEFMACRO patterns (which I think we ought to) so that there's only one kind of destructuring floating around. The other kind of destructuring is a neato thing but I'd rather leave it in the yellow pages for now. You should figure out whether DLET has parallel syntax to LET, and therefore lets you bind several variables, or whether it's like our DESTRUCTURING-BIND, which only takes one variable and one destructuring pattern. I'd prefer the latter, but then the name DLET would suggest the wrong kind of syntax. (Also, if we keep the name DLET and make the syntax like LET then symmetry demands a DLET*, which I don't think is something we really need.) So I'd rather use the latter syntax (one variable), and change the name. I realize DESTRUCTURING-BIND isn't very good. In fact, the use of the word "structure" in this context isn't very consistent with the usual CL meaning of "structure", anyway. A13: Yes. A14: Yes. A15: I quite clearly remember the discussion in which this change was made. The point was, and still is, that if there is no minimum that every implementation must support, then no program that uses 2-D arrays is guarateed to be portable. I think this is a strong and obvious argument. What was all the flak about: was 63 too big? Steele just made up that number randomly and we all agreed. It's OK with me if we change it to 7 or even to 3, but let's keep some minimum. In fact, by the same reasoning, there ought to be a minimum on the values of call-arguments-limit and call-values-limit, for the same reason! Having the variables is probably a good idea anyway. A16: Yes. A17: Yes, definitely.  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 3 Jun 83 08:35:07 PDT Received: ID ; 3 Jun 83 11:35:02 EDT Date: 3 Jun 83 11:35:02 EDT From: Ginder@CMU-CS-C Subject: Re: Another ballot To: Fahlman@CMU-CS-C cc: common-lisp@SU-AI In-Reply-To: Your message of 3 Jun 83 02:41:25 EDT a1. don't care a2. OK a3. C, but could live with B grumblingly a4. yes a5. no a6. no a7. no a8. no a9. yes a10. yes a11. yes a12. weak no (could live with yes, again grumblingly) a13. yes a14. yes a15. yes a16. yes a17. yes --Joe -------  Received: from MIT-MC by SU-AI with TCP/SMTP; 3 Jun 83 06:49:18 PDT Received: from SCRC-BEAGLE by SCRC-TENEX with CHAOS; Fri 3-Jun-83 09:45:34-EDT Date: Friday, 3 June 1983, 09:44-EDT From: Bernard S. Greenberg Subject: Another ballot To: Fahlman%CMU-CS-C@SU-DSN, common-lisp@su-ai In-reply-to: The message of 3 Jun 83 02:27-EDT from Scott E. Fahlman Date: Fri, 3 Jun 1983 02:27 EDT From: Scott E. Fahlman A1. Proposed that we add BSG's PARSE-INTEGER function in place of the defunct PARSE-NUMBER. Yes. I'd like to modify the spec to say that it does not parse a Common Lisp , but a sequence of digits to produce a Common Lisp . The person writing the calling program and its documentation choose the input base, not the user. A2. Propose that PROCLAIM, the replacement for top-level DECLARE, will evaluate its arguments as a normal function. Note that PROCLAIM must be wrapped in an implicit (EVAL-WHEN (COMPILE LOAD EVAL)...) in order to work, so whatever the args are, they must be evaluable at compile time. Yes. A3. Indicate which of the following you could live with, and which you prefer: b. or c. A4. Moon has pointed out that VECTOR-PUSH and VECTOR-PUSH-EXTEND take their arguments in an order that is inconsistent with PUSH. Propose to fix this. Yes. What ever happened to my observation about SUBSTITUTE-IF's argument order inconsistency? A5. Add KMP's (NTH-VALUE n form) for picking up one value from a form that returns multiple values. In favor. [I am mildly opposed to this. As Moon points out, this would have to be 0-based and would be non-intuitive for that reason. Would 1-based be MORE intuitive if you know Common Lisp? In addition, it is rare to want some single value other than the first.] I disagree with this. This is precisely for that case where you do, and there is really no other way to handle it. --------------------------------------------------------------------------- A6. Propose to add GSB's proposal for a set of primitives to create named structures. (This was in recent mail -- I don;t want to repeat the whole thing here.) Mildly opposed. A7. EAK has asked that we vote on this: Propose to eliminate SET and FSET from Common Lisp in favor of (SETF (SYMBOL-VALUE ...) ...) and (SETF (SYMBOL-FUNCTION ...) ...). Can't say. I'm not wise enough to make a tradeoff between consistency and convenience on a case-by-case basis. I am reminded of the guy in "Life of Brian" who says, "*I'M* not different!": the consistent primitive-less setters are certainly consistent with each other, and with the rest they are inconsistent. If we really believe that SET and FSET are must-have's, I would wish the restoration of PUTPROP on identical grounds. A8. EAK has also asked that we vote on this: Propose that in Common Lisp it is an error to do (apply '(lambda ...) ...). Not sure. A9. Propose that we reinstate VREF. This is a fairly useless synonym for AREF with one index, but people keep expecting to find it there, even some who have not been through all the oscillation on this. Opposed. A10. Add an optional integer seed to MAKE-RANDOM-STATE. A given seed in a given implementation always creates a random state object that generates the same sequence of "random" numbers, but different seeds create random states that are unrelated. As it now stands, the only way to create distinct but repeatable random states is to start from copies of the same state and run RANDOM for (very) different numbers of cycles. In favor. A11. Propose that we adopt the APPLYHOOK feture, as specified by Moon. In favor. A12. Add a simple form of destructuring LET macro. DLET would allow arbitrary list or tree structures in place of the LET variables. The leaves would be symbols, the variables to bind. The LET values would be picked apart according to these patterns and the pieces assigned to the variables. I propose we hold off until we understand what we intend to do with destructuring, or make such a thing as proposed a yellow-pages extension. A13. A modification to INTERN and FIND-SYMBOL, suggested by Moon: Both of these functions return two values. The first is the symbol that was found or created. (FIND-SYMBOL does not create a new symbol, but returns NIL for the first value if no existing symbol was found.) The second argument is NIL if no existing symbol was found and takes on one of three values if a symbol was found: :INTERNAL :EXTERNAL :INHERITED (implies internal). We can now flush FIND-EXTERNAL-SYMBOL. If you want this, call FIND-SYMBOL and see if the second value is :EXTERNAL. In favor. A14: Proposed by KMP that we rename MULTIPLE-VALUE to MULTIPLE-VALUE-SETQ. Indeed! A15: Steele propose the following: There has been a lot of flak about the decision that every implementation must support arrays of rank up to 63. There are similar problems with numbers of arguments, and Moon has raised an objection concerning the equating of valid array dimensions with fixnums. I propose that we recant a bit, and set no hard limits, but realize that programs may not be portable by reason of pushing on those limits. So that programs may probe the environment, introduce these constants: This, to me, is not as transparently clear as it may seem. It is very hard to parameterize your program for variable limits on array rank. This is not the same as "maximum array size" or "maximum string size", against whose effects you can easily parameterize your program. While I am in favor of the new variables, which say what the implementation's limits are, I think that it is strongly in the interests of portability to impose SOME lower limit on maximum array rank, even if it is 3 or 4 or 10. A16. Guy proposes that we get rid of MACRO, which is a trap for unsuspecting users who ought to be enjoying the benfits of DEFMACRO. We need something for DEFMACRO to expand into. Guy proposes a function named SET-MACRO that takes two evaluated arguments: the symbol that is to be defined as a macro and the expansion function. So if we want to define a macro named FOO and its expansion function is (LAMBDA (CALLFORM) ...), we (or rather defmacro) would use (SET-MACRO 'FOO #'(lambda (callform) ...)) In effect, SET-MACRO does whatr one might express as (SETF (SYMBOL-FUNCTION 'FOO) (make-a-macro-object #'(LAMBDA (CALLFORM) ...))) except that SET-MACRO hides the existence of this odd macro-object (if indeed that is the way it is implemented internally). In favor. A17. Per EAK's suggestion, require (integerp 4/2) to be true and also require (integerp (complex 4 0)) to be true. That is, rationals always reduce to canonical form, and so do Gaussian rationals. Strongly in favor.  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 2 Jun 83 23:27:02 PDT Received: ID ; 3 Jun 83 02:27:07 EDT Date: Fri, 3 Jun 1983 02:27 EDT From: Scott E. Fahlman To: common-lisp@su-ai Subject: Another ballot Ballot A: This is a follow-up to the Memorial Day ballot, raising some issues that came up since the earlier ballot went out. Please respond by Saturday evening. (My apologies to those of you who don't work on weekends, if any such exist. You've still got all day Friday.) With some luck and a lot of hard work, we may be able to wrap this whole process up by early next week, and get an final manual out (minus proofreading and some work on the index). There are still some unresolved issues relating to the file-name stuff, so there may be a supplementary ballot making some proposals in that area. --------------------------------------------------------------------------- A1. Proposed that we add BSG's PARSE-INTEGER function in place of the defunct PARSE-NUMBER. [I am mildly in favor. It is easy to implement, and useful in writing user interfaces.] --------------------------------------------------------------------------- A2. Propose that PROCLAIM, the replacement for top-level DECLARE, will evaluate its arguments as a normal function. Note that PROCLAIM must be wrapped in an implicit (EVAL-WHEN (COMPILE LOAD EVAL)...) in order to work, so whatever the args are, they must be evaluable at compile time. [Several people, most notably Moon, proposed this in their response to the earlier ballot. One advantage is that you can now easily include constants declared earlier in the file in the body of a proclamation. The disadvantages are that you have to quote each proclamation in the usual case, and that it's a little harder to convert old DECLARE forms. I'm in favor or the proposal.] --------------------------------------------------------------------------- A3. Indicate which of the following you could live with, and which you prefer: a. The old scheme in which package names retain their case, but are matched in a case-insensitive way. We would have to outlaw :, \, |, other readmacro characters, and whitespace in package names. b. My proposal to treat the package name part of a qualified symbol EXACTLY like the symbol part, except that no symbol is created. This would allow things like |fOo|:|BaR|. It has the disadvantage that | can no longer be a macro returning a symbol but must be treated as a sort of escape character. This complicates the reader. It also means that when the package name is entered as a string, you have to be careful of case. c. A proposal by Moon to allow slashes (and therefore any character) in package names, but not vertical bars. Also to do symbol-like case conversion on package names (so that they can be read with a subset of the symbol-reading machinery) but case-insensitive lookup, so that users don't have to worry about case when typing in package names as strings. This would mean that two distinct packages could not have names that differ only in case. The effect is just like (a) above, except that you can get the weird characters in using the \ convention. [ I could live with any of these and have in fact oscillated between B and C. Right now I favor B. As KMP points out, people find it totally intuitive, and it's not THAT much extra work for the implementor.] --------------------------------------------------------------------------- A4. Moon has pointed out that VECTOR-PUSH and VECTOR-PUSH-EXTEND take their arguments in an order that is inconsistent with PUSH. Propose to fix this. [In favor, of course.] --------------------------------------------------------------------------- A5. Add KMP's (NTH-VALUE n form) for picking up one value from a form that returns multiple values. [I am mildly opposed to this. As Moon points out, this would have to be 0-based and would be non-intuitive for that reason. In addition, it is rare to want some single value other than the first.] --------------------------------------------------------------------------- A6. Propose to add GSB's proposal for a set of primitives to create named structures. (This was in recent mail -- I don;t want to repeat the whole thing here.) [I oppose this. A nearly portable DEFSTRUCT package can be created now that contains implementation-dependent forms in about three places. That doesn't seem like a sufficient maintenance headache to justify adding a whole new level of user-visible standardized machinery.] --------------------------------------------------------------------------- A7. EAK has asked that we vote on this: Propose to eliminate SET and FSET from Common Lisp in favor of (SETF (SYMBOL-VALUE ...) ...) and (SETF (SYMBOL-FUNCTION ...) ...). [I strongly oppose this. I just don't want to type that much stuff in order to get this job done.] --------------------------------------------------------------------------- A8. EAK has also asked that we vote on this: Propose that in Common Lisp it is an error to do (apply '(lambda ...) ...). [I am not sure of all the implications of this. My inclination is to leave this the way it is right now.] --------------------------------------------------------------------------- A9. Propose that we reinstate VREF. This is a fairly useless synonym for AREF with one index, but people keep expecting to find it there, even some who have not been through all the oscillation on this. [Mildly in favor.] --------------------------------------------------------------------------- A10. Add an optional integer seed to MAKE-RANDOM-STATE. A given seed in a given implementation always creates a random state object that generates the same sequence of "random" numbers, but different seeds create random states that are unrelated. As it now stands, the only way to create distinct but repeatable random states is to start from copies of the same state and run RANDOM for (very) different numbers of cycles. [I am in favor, unless there are implementation problems of which I am unaware.] --------------------------------------------------------------------------- A11. Propose that we adopt the APPLYHOOK feture, as specified by Moon. [I am in favor of this. It makes possible more refined forms of single-stepping, at the cost of some minor extra hassle for the implementor. (Our lexical EVAL does not actually do a real APPLY, but could arrange to if *APPLYHOOK* were non-null.) ] Rationale: When stepping through an interpreted program, it is desirable to be able to pause before each evaluation, to pause after each evaluation so that the value can be examined or changed. These operations can be done with the evalhook feature. It is also desirable to pause before invoking a function (whether a user function or a system function), so that the values of the arguments may be examined or modified. This requires the applyhook feature, or else requires duplicating an unnecessarily large part of the EVAL function. The applyhook feature catches only APPLY operations done by EVAL. It does not catch APPLY done in other parts of the interpreter (i.e. by special forms: CATCH-ALL and UNWIND-ALL are the only ones in Table 5-1 that would do an APPLY), nor does it catch APPLY or FUNCALL operations done by functions (MAPCAR for instance). Stepping through APPLY operations done by a function such as MAPCAR are best done by intercepting the call to MAPCAR, using the apply hook, and substituting a different first argument. Note: The writeups for APPLYHOOK and *APPLYHOOK* should be largely copied from the writeups for EVALHOOK and *EVALHOOK*. I have not made any attempt to do this, but have just indicated the differences. New variable *APPLYHOOK*: (analogous to *EVALHOOK*) When non-NIL, EVAL behaves in a special way. Whenever it is about to apply a function to the values of the function's arguments, which have already been evaluated, instead it calls the value of *APPLYHOOK* with two arguments: the function and its list of arguments. Whatever values the hook function returns are taken as the results. The list of arguments is just like an &rest argument in its volatility. If the hook function just calls APPLY on its first two arguments, EVAL would behave in its normal way except a little slower. (Of course the preceding sentence isn't true in a lexical interpreter, where the internal environment-taking APPLY isn't accessible to the user except through the APPLYHOOK function, below.) The apply hook function gets additional "env" arguments just like the eval hook function. EVAL binds both *EVALHOOK* and *APPLYHOOK* to NIL around calls to either of them. EVALHOOK takes an extra argument: *APPLYHOOK* is bound to the third argument (before the "&rest env"), a function or NIL. New function APPLYHOOK: (analogous to EVALHOOK) The arguments are function, arglist, evalhook, applyhook (&rest env). This function is completely analogous to EVALHOOK and is to be called by *APPLYHOOK* functions in the same way that EVALHOOK is to be called by *EVALHOOK* functions, to "jump back into the interpreter". Macros and special forms: *APPLYHOOK* does not affect the invocation of a macro expansion function. *APPLYHOOK* has no effect on the evaluation of special forms. --------------------------------------------------------------------------- A12. Add a simple form of destructuring LET macro. DLET would allow arbitrary list or tree structures in place of the LET variables. The leaves would be symbols, the variables to bind. The LET values would be picked apart according to these patterns and the pieces assigned to the variables. [ I propose this with some trepidation. I am in favor of destructuring if it goes just this far, but every time we've brought this up someone pops up with a proposal to destructure vectors, arrays, structures, character objects, bignums, and the family cat, and to let destructuring creep into all parts of the language. Can we vote on the proposal above and let people who want more complex destructuring do it as a non-standard extension or wait till the seond edition? ] --------------------------------------------------------------------------- A13. A modification to INTERN and FIND-SYMBOL, suggested by Moon: Both of these functions return two values. The first is the symbol that was found or created. (FIND-SYMBOL does not create a new symbol, but returns NIL for the first value if no existing symbol was found.) The second argument is NIL if no existing symbol was found and takes on one of three values if a symbol was found: :INTERNAL :EXTERNAL :INHERITED (implies internal). We can now flush FIND-EXTERNAL-SYMBOL. If you want this, call FIND-SYMBOL and see if the second value is :EXTERNAL. [I am in favor of this.] --------------------------------------------------------------------------- A14: Proposed by KMP that we rename MULTIPLE-VALUE to MULTIPLE-VALUE-SETQ. [ Yes!!! Long overdue. We don't want users to favor this over MULTIPLE-VALUE-BIND just because the name seems to imply that this is the canonical MV function. ] --------------------------------------------------------------------------- A15: Steele propose the following: There has been a lot of flak about the decision that every implementation must support arrays of rank up to 63. There are similar problems with numbers of arguments, and Moon has raised an objection concerning the equating of valid array dimensions with fixnums. I propose that we recant a bit, and set no hard limits, but realize that programs may not be portable by reason of pushing on those limits. So that programs may probe the environment, introduce these constants: ARRAY-RANK-LIMIT As before, the implementation only supports arrays of rank less than this constant. ARRAY-DIMENSION-LIMIT Limit on each array dimension. ARRAY-TOTAL-SIZE-LIMIT Limit on total size of an array. CALL-ARGUMENTS-LIMIT Limit on number of arguments in a function call. CALL-VALUES-LIMIT Limit on number of multiple values a call can return. We may think of other implementation parameters to make available as well. The intent is that no hard limit is set, but that each implementation should make these numbers as large as practicable. [ I'm in favor. ] --------------------------------------------------------------------------- A16. Guy proposes that we get rid of MACRO, which is a trap for unsuspecting users who ought to be enjoying the benfits of DEFMACRO. We need something for DEFMACRO to expand into. Guy proposes a function named SET-MACRO that takes two evaluated arguments: the symbol that is to be defined as a macro and the expansion function. So if we want to define a macro named FOO and its expansion function is (LAMBDA (CALLFORM) ...), we (or rather defmacro) would use (SET-MACRO 'FOO #'(lambda (callform) ...)) In effect, SET-MACRO does whatr one might express as (SETF (SYMBOL-FUNCTION 'FOO) (make-a-macro-object #'(LAMBDA (CALLFORM) ...))) except that SET-MACRO hides the existence of this odd macro-object (if indeed that is the way it is implemented internally). [ I'm in favor. ] --------------------------------------------------------------------------- A17. Per EAK's suggestion, require (integerp 4/2) to be true and also require (integerp (complex 4 0)) to be true. That is, rationals always reduce to canonical form, and so do Gaussian rationals. More specifically, any attempt to create a rational whose value is integral will in fact result in an integer; and any attempt to create a complex number whose real part is rational and whose imaginary part is the integer zero will result in a rational, namely the real part. If either part of a complex number is floating-point then the complex number must remain complex. Thus all Gaussian rationals have a unique canonical representation, while (totally or partially) floating-point numbers maintain their data type more distinctly (which is important for numerical reasons: in IEEE arithmetic it is very important to distinguish 1.0, 1.0+0.0i, and 1.0-0.0i !). [ Guy supports this. I'm indifferent. ]  Received: from MIT-MC by SU-AI with TCP/SMTP; 2 Jun 83 23:14:45 PDT Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Fri 3-Jun-83 02:14:16-EDT Date: Friday, 3 June 1983, 02:13-EDT From: David A. Moon Subject: typep of array To: Steele%CMU-CS-C@SU-DSN Cc: Common-Lisp@SU-AI The line that is commented out in the enclosed code fragment seems like a good example of a deficiency in the Common Lisp type system. There is no way in a single typecase to make this discrimination, i.e. to have a clause that handles all arrays whose elements are guaranteed to be integers. One has to have a typecase clause for plain array, inside of which are conditions using array-element-type and subtypep, which is ugly. (defun write-binary-object (object type binary-output-stream) (typecase object ... ; ((array integer) (write-binary-object-packed-array object binary-output-stream)) (array (write-binary-object-array object binary-output-stream)) ...))  Received: from MIT-MC by SU-AI with TCP/SMTP; 2 Jun 83 22:55:51 PDT Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Fri 3-Jun-83 01:58:43-EDT Date: Friday, 3 June 1983, 01:57-EDT From: David A. Moon Subject: The dogma killed ASET To: Bernard S. Greenberg Cc: common-lisp@su-ai In-reply-to: The message of 2 Jun 83 16:35-EDT from Bernard S. Greenberg Date: Thursday, 2 June 1983, 16:35-EDT From: Bernard S. Greenberg While writing some common lisp code today, I was reminded that ASET was removed because "You should be using SETF". Unfortunately, what I wanted to do was (apply #'aset value array list-of-subscripts), a very reasonable thing in a recursive array-processing program, and I find there is no way to do this in Common Lisp. Opinions? The following works and is in our implementation now. It isn't as complicated as it looks at first, since almost all of it is error-checking. I admit that it's rather a kludge, and maybe we should say that knowledge of APPLY has to be built into SETF (actually into GET-SETF-METHOD). But one way or the other it seems eminently reasonable for (SETF (APPLY #'AREF ARRAY SUBSCRIPTS) VALUE) to be defined to work. Opinions? Code: ;Pretend the last argument is only a single argument, get the setf method ;for that form, then stick APPLY back in. Since this doesn't understand ;the code it is generating in any deep way, it can be fooled into generating ;wrong code when it should have generated an error at macroexpansion time ;saying that it doesn't understand what it's doing. (DEFINE-SETF-METHOD APPLY (FUNCTION &REST ARGS) (IF (AND (LISTP FUNCTION) (= (LIST-LENGTH FUNCTION) 2) (MEMBER (FIRST FUNCTION) '(QUOTE FUNCTION)) (SYMBOLP (SECOND FUNCTION))) (SETQ FUNCTION (SECOND FUNCTION)) (FERROR "~S is not a constant function; APPLY of it is~@ not understood as a generalized variable" FUNCTION)) (MULTIPLE-VALUE-BIND (VARS VALS STORE-VARS STORE-FORM ACCESS-FORM) (GET-SETF-METHOD-MULTIPLE-VALUE (CONS FUNCTION ARGS)) (LET ((LIST-VAR (LOOP FOR VAR IN VARS AND VAL IN VALS WHEN (EQ VAL (CAR (LAST ARGS))) RETURN VAR))) (OR (AND LIST-VAR (EQ (CAR (LAST ACCESS-FORM)) LIST-VAR) (EQ (CAR (LAST STORE-FORM)) LIST-VAR)) (FERROR "APPLY of ~S not understood as a generalized variable" FUNCTION)) (VALUES VARS VALS STORE-VARS `(APPLY #',(FIRST STORE-FORM) . ,(REST STORE-FORM)) `(APPLY #',(FIRST ACCESS-FORM) . ,(REST ACCESS-FORM))))))  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 2 Jun 83 18:08:42 PDT Received: ID ; 2 Jun 83 21:09:17 EDT Date: Thu, 2 Jun 1983 21:09 EDT From: Scott E. Fahlman To: Earl A. Killian Cc: common-lisp@SU-AI Subject: format force-output In-reply-to: Msg of 2 Jun 1983 20:15 EDT from Earl A. Killian Is there any compelling reason why you can't do the FORMAT, then do a FORCE-OUTPUT? I hate to further complicate FORMAT for something so totally random, and I hate to use up a perfectly good character that we might someday need for aixelsyd mode or something. -- Scott  Received: from MIT-MC by SU-AI with TCP/SMTP; 2 Jun 83 17:13:52 PDT Date: 2 June 1983 20:15 EDT From: Earl A. Killian Subject: format force-output To: common-lisp @ SU-AI How about a format command for doing a force-output on the stream? How about ~!? This would be typicaly be used at the end of the string, of course.  Received: from MIT-MC by SU-AI with TCP/SMTP; 2 Jun 83 16:20:55 PDT Date: 2 June 1983 19:22 EDT From: Earl A. Killian Subject: grt optys in data proc To: Guy.Steele @ CMU-CS-A cc: common-lisp @ SU-AI In-reply-to: Msg of 2 Jun 1983 0100-EDT () from Guy.Steele at CMU-CS-A I think that sacrificing horizontal alignment is superior to losing the datum. Let's just specify that.  Received: from MIT-MC by SU-AI with TCP/SMTP; 2 Jun 83 15:22:41 PDT Received: from SCRC-EUPHRATES by SCRC-SPANIEL with CHAOS; Thu 2-Jun-83 01:03:25-EDT Date: Thursday, 2 June 1983, 00:58-EDT From: David A. Moon Subject: ~m,n@T in FORMAT To: common-lisp at su-ai The description of this in the Laser manual makes no sense. It says that ~colrel,colinc@T is equivalent to ~curcol+colrel,colincT where curcol is the current column. But assuming colrel isn't negative this never depends on the value of colinc. Instead, I implemented this to move at least colrel columns to the right, and as many additional columns (possibly none) as required to get to a multiple of colinc. Is this right?  Received: from MIT-MC by SU-AI with TCP/SMTP; 2 Jun 83 15:05:35 PDT Received: from SCRC-EUPHRATES by SCRC-SPANIEL with CHAOS; Wed 1-Jun-83 23:49:51-EDT Date: Wednesday, 1 June 1983, 23:44-EDT From: David A. Moon Subject: #+ hair To: Common-lisp at su-ai It's been suggested locally that #+ have some escape syntax by which one could get an arbitrary form evaluated, and read or skip the next form depending on whether the result was true or false. (The actual suggestion was that #? do this, but to me it seems clear that this should be a feature of #+). One way to do this would be to have any list whose car was not AND, OR, or NOT just be evaluated. There is an obvious problem with this. If anyone else has a suggestion I'd like to hear it; perhaps we'll implement it and if it works out propose it for inclusion in Common Lisp on the second go-around.  Received: from MIT-MC by SU-AI with TCP/SMTP; 2 Jun 83 15:05:59 PDT Received: from SCRC-EUPHRATES by SCRC-SPANIEL with CHAOS; Thu 2-Jun-83 00:25:02-EDT Date: Thursday, 2 June 1983, 00:19-EDT From: David A. Moon Subject: Non-yucky package names (I think) To: Scott E. Fahlman Cc: Common-Lisp at su-ai In-reply-to: The message of 31 May 83 03:14-EDT from Scott E. Fahlman Date: Tue, 31 May 1983 03:14 EDT From: Scott E. Fahlman New proposal: Flush the rules for package-name caseification that are found in the current package chapter. Replace it with the following: With respect to case, reading, and printing, package names are treated EXACTLY like symbol names: upcase by default, escape that using / or ||, observe *PRINT-CASE* on printing, look up using case-sensitive matching. Note, however, that package names do not become symbols, but are stashed away in the package object as a string, after case conversion paralleling that for symbol-names. So the reader reads a token in just as if it were a symbol. If it hits a : or #:, it doesn't call INTERN on the token just collected, but instead calls FIND-PACKAGE. Then it reads the following token, which had better be a symbol, and interns it. The various package functions that take package-name strings should probably take symbol-or-string. If a symbol, you get the case-conversion for free but create a random symbol in the current package; if a string, you have to be careful of case. All the above sounds completely right to me. So, |fOo:BaR| would be a symbol containing a colon, but |fOo|:|BaR| is symbol |BaR| in package |fOo|. Notice that I have nothing up my sleeves and at no time did my hands ever leave the keyboard. I'm not so sure about allowing vertical bars in package prefixes. It depends on whether you think of vertical bar as an alternate form of backslash or as a separate reader-macro whose output is by definition a symbol (not a token). I could stand this either way, but would slightly prefer to avoid the complexity of allowing vertical bar in package prefixes. What we lose is the cute preservation of original case in package names and the ability to toss around package-name strings without worrying about case. What we gain is a lot of uniformity: both halves of a symbol behave the same way. We could still do case-independent lookup of package names in FIND-PACKAGE (hence in USE-PACKAGE, export, etc.) and require that no two distinct packages have names that differ only in case. This would eliminate the need to be careful about case when typing package names as strings.  Received: from MIT-MC by SU-AI with TCP/SMTP; 2 Jun 83 15:03:56 PDT Received: from SCRC-EUPHRATES by SCRC-SPANIEL with CHAOS; Wed 1-Jun-83 23:48:03-EDT Date: Wednesday, 1 June 1983, 23:43-EDT From: David A. Moon Subject: NTH-VALUE To: Earl A. Killian Cc: common-lisp at SU-AI In-reply-to: The message of 1 Jun 83 22:42-EDT from Earl A. Killian Date: 1 June 1983 22:42 EDT From: Earl A. Killian I am in favor of this. I think it will be very very common, because (NTH-VALUE 2 (FLOOR A B)) is how you would do modular arithmetic. I'm not opposed to NTH-VALUE. But allow me to point out that (NTH-VALUE 2 (FLOOR A B)) is NIL and (NTH-VALUE 1 (FLOOR A B)) is (MOD A B). We are sure not going to have ONE function in this language that uses one-origin indexing, with everything else using zero-origin indexing!  Received: from MIT-MC by SU-AI with TCP/SMTP; 2 Jun 83 15:03:39 PDT Received: from SCRC-EUPHRATES by SCRC-SPANIEL with CHAOS; Wed 1-Jun-83 23:19:07-EDT Date: Wednesday, 1 June 1983, 23:14-EDT From: David A. Moon Subject: Issue 21: package of #+/#- features To: Common-lisp at su-ai I'd like to change my vote from "neutral" to "read features in the same package as anything else, and put the features associated with the standard language in the LISP package so they can be typed without prefixes." In the Maclisp world features are sometimes used to simulate what Common Lisp does with PROVIDE and REQUIRE. I'm not completely sure, but I believe that this won't work anymore if feature symbols are subject to packages. However, I think PROVIDE and REQUIRE are a more reasonable way to do it.  Received: from USC-ECL by SU-AI with TCP/SMTP; 2 Jun 83 13:51:25 PDT Received: from MIT-MC by USC-ECL; Thu 2 Jun 83 13:49:06-PDT Received: from SCRC-BEAGLE by SCRC-TENEX with CHAOS; Thu 2-Jun-83 16:35:20-EDT Date: Thursday, 2 June 1983, 16:35-EDT From: Bernard S. Greenberg Subject: The dogma killed ASET To: common-lisp%su-ai@usc-ecl While writing some common lisp code today, I was reminded that ASET was removed because "You should be using SETF". Unfortunately, what I wanted to do was (apply #'aset value array list-of-subscripts), a very reasonable thing in a recursive array-processing program, and I find there is no way to do this in Common Lisp. Opinions?  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 2 Jun 83 09:38:24 PDT Received: ID ; 2 Jun 83 12:38:44 EDT Date: Thu, 2 Jun 1983 12:38 EDT From: Scott E. Fahlman To: common-lisp@su-ai Subject: BSG /= GSB The PARSE-INTEGER proposal was submitted by Bernie Greenberg (BSG), not by Glenn Burke (GSB), though Glenn sent a message endorsing the proposal. My apologies to Bernie and Glenn for the confusion. .lanimret ym htiw gnorw gnihtemos ro aixelsyd eb tsuM ttocS --  Received: from MIT-MC by SU-AI with TCP/SMTP; 2 Jun 83 09:11:22 PDT Received: from SCRC-BEAGLE by SCRC-TENEX with CHAOS; Thu 2-Jun-83 12:10:51-EDT Date: Thursday, 2 June 1983, 12:10-EDT From: Bernard S. Greenberg Subject: The envelope please... To: Fahlman%CMU-CS-C@SU-DSN, common-lisp@su-ai In-reply-to: The message of 2 Jun 83 02:45-EDT from Scott E. Fahlman Date: Thu, 2 Jun 1983 02:45 EDT From: Scott E. Fahlman -------------------------------------------------------------------------- 1. Flush PARSE-NUMBER: APPROVED. Glenn Burke has proposed a much simpler PARSE-INTEGER function which does most of what PARSE-NUMBER would have been used for and which is trivial to implement. Did I miss something? Did Glenn offer a counter-proposal, or is this a GSB/BSG confusion problem, which has happened before?  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 1 Jun 83 23:44:43 PDT Received: ID ; 2 Jun 83 02:45:01 EDT Date: Thu, 2 Jun 1983 02:45 EDT From: Scott E. Fahlman To: common-lisp@su-ai Subject: The envelope please... Here is my interpretation of the results of the Memorial Day ballot. A number of new issues have been raised since this went out, so there will be another small ballot going out tomorrow. Note that the raw vote-count doesn't decide the issue here. One good argument pointing out why something is unworkable is stronger than any number of "OK, I'll go along with the proposal" votes, especially if those votes came before the argument. On questions of mechanics, people speaking for an implementation group carry more weight than others. On questions of taste, the process is pretty democratic, but perhaps weighted slightly for experience. Again, in matters of taste, a cogent argument carries extra weight. The result, then, must be somewhat subjective. My goal here is to come up with a solution that we all can live with and to do so with a minimum of futher iteration. If there's some wiggle room left within those bounds, then I try to find the solution that best satisfies the aggregate taste of the community. If any of the decisions made here strikes you as something that you just cannot live with, let me know right away. But before you complain, think about the fact that getting the manual completed and out very soon is extremely important to some of the implementation efforts. -- Scott -------------------------------------------------------------------------- 1. Flush PARSE-NUMBER: APPROVED. Glenn Burke has proposed a much simpler PARSE-INTEGER function which does most of what PARSE-NUMBER would have been used for and which is trivial to implement. This will be on tomorrow's ballot. -------------------------------------------------------------------------- 2. LOOP makes a BLOCK NIL: APPROVED. -------------------------------------------------------------------------- 3. Split GET-INTERNAL-TIME into two functions, one to get real time and one to get runtime. This was poorly explained on the original ballot, and there were some objections by people who clearly had misunderstood the proposal. Among the rest of the responses, there seemed to be no opposition to the proposal, but a number of people pointed out that my proposed names were losers. I'm going to treat the proposal as being APPROVED unless someone explodes. To reiterate, these functions are for low-level, fine-grained metering of perfomance. They need to be quick and do not want to be loaded down with keywords or other hair. Each returns an integer that is the real time or run time since some arbitrary starting point. The size of the tick is implementation-dependent and is indicated by the constant INTERNAL-TIME-UNITS-PER-SECOND. The best names I've heard so far are GET-INTERNAL-RUN-TIME and GET-INTERNAL-REAL-TIME. These are verbose, but that's not too bad since these are low-level functions that will seldom be typed at the terminal. The names evoke the familiar concepts of runtime and real time, but also emphasize the link to the INTERNAL-TIME-UNITS-PER-SECOND constant. Also, the names are similar in form, which is important for functions so similar to one another. If anyone comes up with a better pair of names in the next day or so, those will be used. Otherwise, these names will be used. --------------------------------------------------------------------------- 4. Built-in macros cannot expand into implementation-dependent special forms. REJECTED. This is one of the areas where negative comments by implementors carried extra weight. There was a lot of support for the view that this restriction, while not impossible, would cause considerable grief for implementors. There were also many comments that portable code-walkers just need some sort of mechanism for describing new special forms. --------------------------------------------------------------------------- 5. The :allow-other-keywords proposal: APPROVED. --------------------------------------------------------------------------- 6. NIL means "ignore this value" in MULTIPLE-VALUE: REJECTED. Basically a taste issue. There was some sentiment both ways, but more in favor of not doing this. (My vote has gone negative on this, on the grounds that MULTIPLE-VALUE will not be used much compared to MULTIPLE-VALUE-BIND. A little extra convenience in a few cases is not sufficient to justify a confusing exception.) --------------------------------------------------------------------------- 7. Flush CATCH-ALL and UNWIND-ALL: APPROVED. Nobody came up with a case in which these were clearly needed (modulo some confusion between THROW and condition signalling) and a substantial majority favored eliminating them. --------------------------------------------------------------------------- 8. Let DEFMACRO destructure: APPROVED. A couple of people objected on the grounds that destructuring can lead to confusing lambda-lists, and a couple of others suggested that destructuring should be applied to the lambda-lists of functions as well. (I am violently opposed to the latter suggestion.) Most people seemed to agree with Moon that destructuring makes sense in defmacro, since it is used to create macros that behave like special forms. I take it that the proposal most people favor is the one that allows destructuring (of lists or dotted lists, not vectors and other odd items) in any place where a regular lambda-list accepts a variable. --------------------------------------------------------------------------- 9. Moon's PROCLAIM proposal: APPROVED. A couple of people referred to an earlier demonstration that the split was not necessary if you were willing to forego error checking, but most favored the change. Some people suggested that PROCLAIM should be a function, not a special form. This will be an item on tomorrow's ballot. --------------------------------------------------------------------------- 10. Moon's Simple-Vector proposal: APPROVED. --------------------------------------------------------------------------- 11. Replace RESET-FILL-POINTER with SETF of FILL-POINTER: APPROVED. --------------------------------------------------------------------------- 12. Add :NAMED to MAKE-ARRAY: REJECTED. Withdrawn by Moon, who proposed it. A more complex proposal by GSB will appear on tomorrow's ballot. --------------------------------------------------------------------------- 13. *IBASE* to be reincarnated as *READ-BASE*: APPROVED. --------------------------------------------------------------------------- 14. SUB-READ: REJECTED. One or more replacement proposals will appear on tomorrow's ballot, since the current situation is unworkable. --------------------------------------------------------------------------- 15. *PRINmumble* => *PRINT-MUMBLE*: APPROVED. --------------------------------------------------------------------------- 16. Fortran-type ~E, ~F, ~G: APPROVED. I sense a general willingness to let Steele and Moon bash out the details on this (as long as overflowing fields don't go onto the next line). --------------------------------------------------------------------------- 17. Flush MAXPREFIX, MAXSUFFIX, and change the value returned by MISMATCH :FROM-END. APPROVED. --------------------------------------------------------------------------- 18. Allow vertical bars around qualified symbols: DEFERRED. The additional proposal to treat both halves of package:symbol the same with respect to case seems to be agreeable to most people, but I'll put this and some other suggestions on tomorrow's ballot. --------------------------------------------------------------------------- 19. ~:A and ~:S change the printing of NIL only for the whole argument, not for sub-forms: APPROVED. --------------------------------------------------------------------------- 20. Do not return the argunet as the value of PPRINT or APROPOS: APPROVED, but return no value instead of NIL. The choice of NIL was mine because I am still uncomfortable around functions that refuse to speak to me, except in the third person, but clearly the rest of you feel otherwise. --------------------------------------------------------------------------- 21. The symbols on the *FEATURES* should be keywords: REJECTED. People were generally indifferent to this issue until Benson made explicit the issue of either having to type #+:foo or fudging #+ to look things up in odd ways. Since then, sentiment has been running strongly in favor of allowing any symbol (or indeed any Lisp object, presumably assuming an EQ test) in this list. Several people (including me) have changed their earlier votes to this new position. I take this as latter proposal as being approved, and the original as being rejected.  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 1 Jun 83 21:56:06 PDT Date: 2 June 1983 0048-EDT (Thursday) From: Guy.Steele@CMU-CS-A To: Glenn S. Burke Subject: Re: randomness CC: common-lisp@SU-AI In-Reply-To: "Glenn S. Burke's message of 1 Jun 83 18:02-EST" The description of *random-state* in the Laser edition requires that it be possible to print out a RANDOM-STATE object and read it back in "suvvessfully". This wording is not as clear as it should be, but the intent was that you can use PRINT to squirrel away and READ to retrieve a RANDOM-STATE that would be good for multiple sessions of a single implementation. Does this accomplish what you want? --Guy  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 1 Jun 83 22:08:40 PDT Date: 2 June 1983 0100-EDT (Thursday) From: Guy.Steele@CMU-CS-A To: Scott E. Fahlman Subject: Re: grt optys in data proc CC: common-lisp@SU-AI In-Reply-To: "Scott E. Fahlman's message of 1 Jun 83 00:30-EST" "Too ugly for words": De gustibus non disputandum est. There is a problem with what to do if a quantity will not fit in the FORMAT field allotted to it. Some constraint has to give: (a) The FORTRAN solution is to sacrifice the requirement of printing the datum; instead, a field of asterisks is printed. (b) The current MacLISP/LISP Machine solution is to sacrifice horizontal alignment; the datum is allotted extra columns, and everything to the right gets pushed over. (c) The suggestion from the IEEE standard is to sacrifice vertical alignment, by pushing everything below the line down, in order to create room for the too-large datum without misaligning everything else to the right. It seems to be simply a matter of which two of the three constraints seem more important than the third. I don't much care; I just wanted to offer this unusual alternative. I find that it doesn't look too bad in practice. "A beast to implement": I didn't think it was that bad. Given that you're trying to right-justify some data in a fixed-width field anyway, you must have calculated the needed width ahead of time anyway in order to pad on the left. It is just a couple of conditional tests, that I supplied in my note, to determine what action to take. The success of the action depends only upon being able to detect the current column position; i.e., it can win iff a ~T command could win. If a ~T command could not win, then you just punt this strategy and revert to strategy (b) above. I don't much care, but would like to know whether other people find this idea interesting. Too bad Moon used up the : and @ flags for something else. (Say! I was going to suggest a third flag character "!" because ~C needs more than four variants. For ~F, ~E, ~G it could specify whether you want to preserve vertical and horizontal alignment. And just think of what an extra flag character could do for ~[ ! ~:![ could be an unwind-protect: ~:![aaa~;bbb~] outputs bb even if a ~^ happens within aaa. And here I go off the deep end ! --Guy  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 1 Jun 83 21:51:35 PDT Received: ID ; 2 Jun 83 00:51:29 EDT Date: Thu, 2 Jun 1983 00:51 EDT From: Scott E. Fahlman To: David A. Moon Cc: Common-Lisp@su-ai Subject: Non-yucky package names (I think) In-reply-to: Msg of 2 Jun 1983 00:19-EDT from David A. Moon Well, the big advantage of my package-name proposal was that it doesn't create yet another set of case rules. All that the user has to remember is that package names are treated EXACTLY like symbols with regard to case and escape conventions. Both your proposals -- forbidding veritical bars and doing case-insensitive lookup -- have some merit, but violate this uniformity. I would prefer not to diverge in this way. -- Scott  Received: from MIT-MC by SU-AI with TCP/SMTP; 1 Jun 83 19:40:14 PDT Date: 1 June 1983 22:42 EDT From: Earl A. Killian Subject: NTH-VALUE To: common-lisp @ SU-AI I am in favor of this. I think it will be very very common, because (NTH-VALUE 2 (FLOOR A B)) is how you would do modular arithmetic.  Received: from MIT-MC by SU-AI with TCP/SMTP; 1 Jun 83 19:13:33 PDT Date: 1 June 1983 22:15 EDT From: Kent M. Pitman Subject: NTH-VALUE, some examples To: Fahlman @ CMU-CS-C cc: Common-Lisp @ SU-AI I think the main argument is that it's fine to want to bind values coming back, but I don't think multiple values will ever have "first class" state in the language until the set of primitives is rich enough that you aren't forced to do clumsy things to use them. I currently prefer (LET ((VSIZE (CADR (MULTIPLE-VALUE-LIST (SEND TERMINAL-IO ':SIZE))))) ...) to using MULTIPLE-VALUE-BIND for implementing a selector such as this, and I am very saddened that this conses. I feel that this has the word "cliche" written all over it. Style issues aside, this case could be written with MULTIPLE-VALUE-BIND but the case of (LET ((X (NTH-VALUE N (FOO)))) ...) can in fact not be written without consing in any form. Note further that allowing an NTH-VALUE primitive lends itself to more portable abstractions. Macros can be written which syntactically appear to reference a structure, allowing efficient implementation in dialects supporting multiple values and slightly slower implementations in those dialects which don't. A quickie poll of the LispM around now users showed that just under half (~4) thought it was obvious that there should be an NTH-VALUE to handle common cases like: (LET ((VSIZE (NTH-VALUE 1. (SEND TERMINAL-IO ':SIZE)))) ...) ;or :EDGES (COND ((NTH-VALUE 1. (CATCH-ERROR (EVAL FORM))) ;for effect ...)) About as many (~4) had never wanted such a feature, but these people admitted not using multiple values much. 1 claimed not to have ever wanted it but said that it sounded useful, and 2 hit me with arguments about how people don't want multiple values anyway, they want structures, and only the compiler should ever know...  Received: from RUTGERS by SU-AI with TCP/SMTP; 1 Jun 83 18:14:54 PDT Date: 1 Jun 83 21:17:40 EDT From: Dir LCSR Comp Facility Subject: our votes in the Memorial Day Ballot To: fahlman@CMU-CS-C.ARPA cc: common-lisp@SU-AI.ARPA 1. Yes, delete PARSE-NUMBER. We like the idea of a simpler PARSE-INTEGER. 2. Yes, LOOP should create BLOCK NIL 3. Yes, we favor GET-INTERNAL-TIME and GET-REAL-TIME, however: - we would like better names, e.g. GET-RUN-TIME and GET-CLOCK-TIME - we would like a function or read-only variable that gives the number of ticks per second 4. Yes, we agree that macros should not expand to undocumented special forms. 5. We abstain on :ALLOW-OTHER-KEYS 6. No, we do not want to complicate MULTIPLE-VALUES. (Actually, we would strongly favor simplifying it by removal.) 7. Yes, we agree to eliminate CATCH-ALL and UNWIND-ALL. If Moon can't think of any use for them, we are sure we won't be able to. 8. Yes, we agree to adding destructuring to DEFMACRO. We are persuaded that documentation and other program-understanding functions could be helped if they can easily see what is going on in the macro. 9. Yes, restrict DECLARE and add PROCLAIM. (Alternatively, we would be happy to forget PROCLAIM. Make DECLARE typed at top level act like PROCLAIM.) 10. Yes, restrict SIMPLE-VECTOR. 11. Yes, use (FILL-POINTER) and (SETF (FILL-POINTER... 12. No, we oppose named vectors. They appear to be a half-baked compromise that we think you will regret. I am sympathetic with the idea of defining how DEFSTRUCT is to be implemented. We think that you should either make these a full type, or a documented programming convention. Named vectors seem to be half-way in between and to share the disadvantages of both. 13. Yes, put in *READ-BASE* 14. No, we oppose SUB-every read function. There has to be a better way. And not keywords.... If the combined wisdom of this list can't come up with a better way, then maybe a month from now... 15. Yes, rename *PRINfoo* 16. Yes, do what Guy wants with floating point formats. (I give him my proxy to make minor adjustments latter if he has better ideas.) 17. Yes, eliminate MAXPREFIX and MAXSUFFIX. 18. We favor Scott's ideas on package names. 19. Yes, ~:A and ~:S should affect only top-level NIL's. 20. We would accept makig APROPOS and PPRINT return NIL, but would prefer having them return no values. 21. Yes, make features keywords. -------  Received: from SU-SCORE by SU-AI with TCP/SMTP; 1 Jun 83 17:48:46 PDT Received: from PARC-MAXC.ARPA by SU-SCORE.ARPA with TCP; Wed 1 Jun 83 17:52:19-PDT Date: Wed, 1 Jun 83 17:51 PDT From: JonL.pa@PARC-MAXC.ARPA Subject: Spread Uniformity and Auto-Doc -- your comments To: Moon%scrc-tenex@MC.ARPA cc: Common-Lisp%SU-AI@SCORE.ARPA Dave, I'm not sure we're talking about the same issues -- I've marked a ! in front of the lines with your replies to my comments. re: Spread Uniformity Date: Tue, 31 May 83 21:40 EDT From: David A. Moon Subject: Memorial Day Ballot: comments on other people's entries To: common-lisp@su-ai.ARPA . . . Spread Uniformity: The meaning of a lambda-list for DEFUN, for lambda forms, and for DEFMACRO ought to be perceptually the same . . . ! I am in very strong disagreement with this. Functions and special forms ! are fundamentally different. "Destructuring" in the lambda list of a ! function refers to taking apart THE VALUE OF AN ARGUMENT AT RUN ! TIME. "Destructuring" in the "lambda" list of a macro refers to taking apart ! THE SYNTACTIC STRUCTURE OF THE INVOKING FORM AT COMPILE ! TIME. These are as different as can be. WHAT? "COMPILE TIME"?? You mean I can't run my macros interpretively at "run time" in CommonLisp? Or, have you just overlooked that the macro expansion function has its own place in the sun, its own "run time". Seriously, though, the relevant issue is separating out the syntax of function definition from the reason why, or goal towards which that function is defined. It should come as no surprise that there are functions which do S-expression to S-expression translations ** and which serve the dual purpose ** of being the support for a named macro in one context, and merely a function called by some automated code analyzers in another context. This situation arises frequently when one writes a translator which "compiles" from a Lisp-like language into some standard-subset Lisp. DEFMACRO is merely a succinct way of saying "assign this function to be the code-expander for that macro". re: Auto-Documentation . . . Especially is this matter of uniformity [for arg-list destructuring] important for auto-documentation. Wouldn't it be nice if you could write (DEFUN FOO ((A B) C) ...) rather than (DEFUN FOO (L C) (PROG ((A (CAR L)) (B (CADR L))) ...)) so that ?= type of helpers would show you more about the syntax of input arguments? . . . What a loss if such facility worked for DEFUN definitions, but not for DEFMACRO definitions (and vice-versa)! ! Of course you can always get the auto-documentation to say anything ! you like, by using (DECLARE (ARGLIST ...)), at least on the Lisp machine. No doubt this declaration was inspired by the Interlisp ARGLIST function. But surely you don't mean to imply that installing special information "by hand" is "automatic" documentation. Or, maybe you do. The Interlisp function SMARTARGLIST goes out and consults an on-line manual, which is fine documentation for the system functions at least (or rather, those system functions for which someone bothered to write manual documentation).  Received: from MIT-MC by SU-AI with TCP/SMTP; 1 Jun 83 16:55:32 PDT Date: 1 Jun 1983 1954-EDT From: Howard I. Cannon Subject: Re: defstruct, and the :named option To: Moon%SCRC-TENEX%MIT-MC@SU-DSN cc: common-lisp@SU-AI In-Reply-To: The message of Wednesday, 1 June 1983, 17:22-EDT from David A. Moon In regards to non-portable vs. portable programs like Defstruct, it seems to me that it's not an all or nothing decision. When thinking about the Flavor stuff, I came to the conclusion that what I'd supply would be a piece of portable code that implemented most of the Flavor system, and a set of well defined and documented functions that were machine dependent, and had to be reproduced for the particular machine/implementation. I guess what I'm saying is that the abstract structure creation primitives don't necessarily have to be in the language definition -- they can be in the Defstruct package definition. I suspect that there will be many "portable" programs that use this approach. -------  Received: from MIT-ML by SU-AI with TCP/SMTP; 1 Jun 83 16:01:27 PDT Date: 1 June 1983 19:02 EDT From: Glenn S. Burke Subject: randomness To: Fahlman @ CMU-CS-C cc: common-lisp @ SU-AI (Yes, really, randomness. Nothing to do with the ballot.) There should be a clearly defined way in which one can create a random-state which has a "consistent" state; that is, from which one will get the same sequence of random numbers. Saving a copy of *random-state* is not sufficient, because then one has to depend on being able to get the same one in what might be different debugging sessions. One possibility is to allow make-random-state to be given a seed (an integer? integer or float?), and having it defined to use that seed in such a way that the random-state will always be the same for the given implementation when given the same seed.  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 1 Jun 83 15:54:36 PDT Received: ID ; 1 Jun 83 18:54:44 EDT Date: Wed, 1 Jun 1983 18:54 EDT From: Scott E. Fahlman To: Kent M. Pitman Cc: Common-Lisp@SU-AI Subject: (MULTIPLE-VALUE (NIL ...) ...) In-reply-to: Msg of 1 Jun 1983 16:53 EDT from Kent M. Pitman I question the general usefulness KMP's proposed NTH-VALUE form. In most cases where the user wants just one value, he wants the first one. If he wants some interior value, he is likely to be using MULTIPLE-VALUE-BIND instead of MULTIPLE-VALUE. So it seems to me that there would be very few places where NTH-VALUE would be useful. -- Scott  Received: from MIT-MC by SU-AI with TCP/SMTP; 1 Jun 83 14:46:36 PDT Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Wed 1-Jun-83 17:29:02-EDT Date: Wednesday, 1 June 1983, 17:22-EDT From: David A. Moon Subject: defstruct, and the :named option To: common-lisp@su-ai In-reply-to: The message of 1 Jun 83 10:17-EDT from Scott E. Fahlman Glenn has a point, which is that the Common Lisp language has no business assuming that the default defstruct type is a vector. Hence my suggestion that a :named keyword be added to make-array and make-vector was a bad suggestion and I withdraw it. We can do one of two things: put in the new "abstract" structure creation primitives GSB suggested, which in implementations that use vectors for structures are macros that turn into the usual vector primitives (and those implementations do have a :named option in their make-vector and make-array functions, presumably). Or we can give up on having defstruct be a portable program and require every implementation to write their own (perhaps by munging a copy of someone else's). It's an issue of extra language complexity versus maintenance headaches.  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 1 Jun 83 14:10:34 PDT Date: 1 June 1983 1546-EDT (Wednesday) From: Walter van Roggen (C410WV50) To: Fahlman@cmu-cs-c Subject: Memorial Day Ballot CC: common-lisp@su-ai Message-Id: <01Jun83.154637.WV50@CMU-CS-A> [1] ok [2] ok [3] yes. GET-INTERNAL-TIME and GET-REAL-TIME might return different values even for a personal machine. Return values should be in units of INTERNAL-TIME-UNITS-PER-SECOND. Some implementations might want to return multiple-values to separate out GC time. [4] ok [5] yes [6] maybe: why not in all lambda lists? [7] no and yes. I don't know why people have been talking about using CATCH-ALL to handle errors in particular. It seems the natural way to detect, and perhaps intercept, throws of any kind, particularly unknown ones. Say you have a large program with many different "top-levels", and corresponding different interrupt characters (like ^G). At some level, you might want to restrict which levels one might pop up to. You need to know what the throw tag is. But given both UNWIND-PROTECT and CATCH-ALL, UNWIND-ALL doesn't seem so useful. Also, is CATCH-ALL so much harder to implement than UNWIND-PROTECT? [8] no. I presume you don't really mean that DEFMACRO is used by users to define special forms. Lisp implementors' use of DEFMACRO for special forms doesn't have to be nice looking. Furthermore, list destructuring in parameter lists is visually confusing and conceptually confusing because of the difference with normal lambda lists. I often find it convenient to convert from DEFUN to DEFMACRO. On the other hand, destructuring can be very convenient. This is a separate issue, but I would like to see a more general destructuring LET as a facility in its own right, with which it would be easy to implement destructuring defmacros. This would apply not only to lists, but to structures also. One annoyance I've noticed with lots of defstructs is that it's tedious to have to write all those (foo-slot x) forms. It would be nice to have something equivalent to the PASCAL WITH. SETF would have to be smarter, though. [9] ok [10] ok. It's good to get rid of SGVREF. Looking at the array chapter I thought there was no way to reference a non-simple vector while observing the fill-pointer, since AREF doesn't and things like CHAR are defined in terms of AREF. But I presume ELT does; there need to be cross-references both ways. So implementations have to duplicate the array referencing mechanism for vectors (e.g., for declared strings). It would also be good to state for THE, examples like (THE (VECTOR CHARACTER n) (THE (SIMPLE-ARRAY STRING-CHAR n) foo)). I presume also that MAKE-SIMPLE-VECTOR no longer takes an :ELEMENT-TYPE keyword, and therefore VECTOR changes. My main complaint is that we are encouraging a proliferation of accessing types. Much as there is no VREF, let's get rid of CHAR and BIT. Since we think there will be much use of SVREF, keep SCHAR and SBIT. Finally, we should consider renaming those three without the "S". [11] yes [12] ok. But can't DEFSTRUCT always assume the first slot is used if named? [13] yes, *READ-BASE*. How about changing *PRINT-RADIX* to mean "whenever *BASE* isn't 10." Perhaps also then change its default value to T. [14] ok with keywords [15] yes [16] I don't even want to think about it. [17] yes [18] ok. why can't package prefixes be treated exactly like symbols, except that they aren't interned? #\: terminates unless quoted. Package names are backslashified or ||'d on printing. So |aBC|:|Foo| or |:|:|:| or |temp|#:G0001 [19] ok [20] no. TIME, DESCRIBE, APROPOS, and ROOM are all similar; they all are most commonly used interactively at top-level. I suggest an optional keyword arg that specifies which stream to output to, just like FORMAT. Since these functions will be so implementation-dependent, we shouldn't restrict what they do nor what they return. As a general rule, 0 values sounds reasonable when just printing. Implementations should be able to add their own keyword args, and return whatever lists (or ?) appropriate. For APROPOS, you might be interested in defined symbols only; APROPOS-LIST is too specific (and it's easy to write anyway). APROPOS, might want to capitalize the string first, also. [21] no, you may want to check for symbols in particular packages. ---Walter  Received: from MIT-MC by SU-AI with TCP/SMTP; 1 Jun 83 13:51:48 PDT Date: 1 June 1983 16:53 EDT From: Kent M. Pitman Subject: (MULTIPLE-VALUE (NIL ...) ...) To: Common-Lisp @ SU-AI By the way, I have carefully watched my code over the last year and in easily three quarters of the cases where I wanted to ignore arguments, it was because I in fact only wanted one value back. In Moon's example, I agree that (LET (TEM) (MULTIPLE-VALUE (NIL TEM) ...) ...) is not as nice as (MULTIPLE-VALUE-BIND (NIL TEM) ... ...) but I would prefer (LET ((TEM (NTH-VALUE 2 ...))) ...) myself. On the other hand, I think the point of Benson's note was to point out that the compiler should be able to handle (MULTIPLE-VALUE-BIND (IGNORE TEM) ... ...) if IGNORE isn't used, without needing to make something special about NIL. I am sympathetic to such an argument. In any case, in addition to (not in place of) anything that is decided along these lines, what would people think about adding NTH-VALUE to the list of available primitives? From my experience, it's frequently just the right thing. --kmp  Received: from MIT-MC by SU-AI with TCP/SMTP; 1 Jun 83 12:58:27 PDT Date: 1 June 1983 14:23 EDT From: Kent M. Pitman To: Common-Lisp @ SU-AI Having watched the mail coming in, I wish to change my vote on 21 (#+/#-) to concur with EAK and Benson, that features should be allowed to be any symbol and packageness should matter. Certain important initial features might want to be global (LISP), I'm not sure about this. But in thinking back over the problems that happened in the past where several string packages existed, it seems to me the only reasonable way to handle this is to allow everyone to name their feature "STRING" and allow the package prefix to have meaning. This is considerably better than resorting to subtle differences in keyword name such as were eventually tried (STRING, STRINGS, ...) and hoping that no one else tried the same trick you tried. The problem is nearly the same as the gensym problem in that you want unique IDs for features, and it is worse than the gensym problem in that you want to be able to type the names in. This is one case where, in spite of my dislike for packages in general, I think they have a place.  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 1 Jun 83 07:17:32 PDT Received: ID ; 1 Jun 83 10:17:43 EDT Date: Wed, 1 Jun 1983 10:17 EDT From: Scott E. Fahlman To: Glenn S. Burke Cc: common-lisp@SU-AI Subject: defstruct, and the :named option In-reply-to: Msg of 1 Jun 1983 03:35 EDT from Glenn S. Burke The solution you propose for the :named problem looks to me like the old "cycle of reincarnation": the "primitives" grow more and more hair, until pretty soon someone decides that it would be nice to have a portable implementation of them, if only someone would define the right primitives. If we're going to put in all the stuff you suggest, we might as well just say that DEFSTRUCT itself is a primitive that works by implementation-dependent magic and let it go at that. The original pont was to add one tiny operation so that all the rest of DEFSTRUCT could be portable. -- Scott  Received: from MIT-ML by SU-AI with TCP/SMTP; 1 Jun 83 00:34:27 PDT Date: 1 June 1983 03:35 EDT From: Glenn S. Burke Subject: defstruct, and the :named option To: common-lisp @ SU-AI I have developed the impression that the issue concerning the :named option to make-array is misguided. The object is to be able to have defstruct produce implementation-independent code for the important default case where the structure is typed. To specify that this is necessarily within the domain of arrays is needlessly constraining. There are three basic functions needed to define a typed structure. One must define the type, create a structure, and reference the structure. The type definition may be done with define-structure: (define-structure []). This is a macro, which expands into whatever is needed by the implementation to actually define so that it may be used as a type specifier, and for its use with make-structure. The "arguments" are not evaluated. For instance, the astronaut defstruct in the Laser edition would produce (define-structure astronaut person). (make-structure ) creates an empty (uninitialized?) structure for . Perhaps is not really needed here, but would save looking up in implementations where no other information is needed. (structure-ref ) returns the th slot of , and works with setf. The indexing is zero origined. Obviously the compiler can increment the index if it is a compile-time constant and that is necessary for the implementation. Checking for such things as :read-only, and hacking with types (in whatever way), are done by defstruct before the structure-ref stage is reached. ---------------------------------------------------------------- Additional changes/documentation modifications: The :named vector type should be specified as not necessarily being the same as the normal typed structure type, and thus probably not distinguishable with typep. It may not be different, however, depending on the implementation! The predicate defined by the :predicate option should be documented as being only a heuristic unless the structure is defined in the default manner. (Should there be a name for this default :type? How about :typed? :typed-structure? Just :structure?) The vector type should NOT be :named by default. The :unnamed option should be eliminated. It only makes sense for the explicitly specified types (list and vector), which are not named by default. (Additionally, if the vector has an element-type specified, it may not, in fact probably will not, be possible to make the vector be :named. The documentation should point this out, if not make :named illegal for all but (vector t).) :initial-offset ??? Presumably this is more reasonable than ever if we have structure-ref. It might be a good idea to define the order in which defstruct allocates slots for linear structures (which all of the Common-Lisp ones are, since there is no :type :tree). ---------------------------------------------------------------- There are a couple alternatives for make-structure which might want to be considered. For instance, it may be reasonable for make-structure to be given a template structure to initialize the created structure to. That way, constant slot initializations will have been done at structure creation type. This is beneficial in implementations where data creation needs for some reason or another to initialize the contents to something. We use this in NIL for flavor instance initialization now; it speeds things up measurably. If this kind of thing is added, then possibly the size and/or name might not need to be given to make-structure. My feeling, however, is that the cleanest and safest interface would be for a template to be an optional third argument to make-structure, and be of type (simple-vector t). Another possibility is for make-structure to take an &rest argument which specifies the slot initializations, in order. This would have the advantage of not forcing defstruct to produce a string of setfs to do the initializations.  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 31 May 83 22:30:29 PDT Received: ID ; 1 Jun 83 01:30:39 EDT Date: Wed, 1 Jun 1983 01:30 EDT From: Scott E. Fahlman To: Guy.Steele@CMU-CS-A Cc: common-lisp@SU-AI Subject: grt optys in data proc In-reply-to: Msg of 1 Jun 1983 0105-EDT () from Guy.Steele at CMU-CS-A The suggestion that you break the line if a number doesn't fit is too ugly for words and would be a beast to implement. Anything but that -- back up and overstrike, maybe, for as many passes as it takes. That'll teach the bloody user to overflow... Seriously, this is going too far. -- Scott  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 31 May 83 22:10:04 PDT Date: 1 June 1983 0105-EDT (Wednesday) From: Guy.Steele@CMU-CS-A To: common-lisp@SU-AI Subject: Moon's remarks on ~F,~E,~G,~$ First, namy thanks to Dave for typing all that stuff in from the FORTRAN-77 standard. Second, I agree with substantially all of his remarks and proposed modifications and clarifications. Regarding fields full of asterisks, there is an interesting suggestion in the appendixes to the IEEE proposed standard: if a number is too big to fit in an output field, then the line gets broken. The best way to see this is by example: (FORMAT T "~%xxxxx~6,3Fzzzzz" 12345.6789) xxxxx 12345.6789yyyy The idea is that if N columns are specified and you need N+K columns to print the number, and the cursor is at absolute column P, then you do one of two things: (a) If you want to keep the right-hand end aligned, output a return and then tab to column P-K; then output the N+K characters. (b) If you want to keep the left-hand end aligned, or if P-K is negative, you output the N+K characters, then a return, then tab to column P+N. The advantage of this is that it is easy to see what happened, and columns of numbers stay aligned. Indeed, we might want to consider this strategy for all fixed-width cases in FORMAT. --Guy  Received: from MIT-ML by SU-AI with TCP/SMTP; 31 May 83 21:49:13 PDT Date: 1 June 1983 00:50 EDT From: Glenn S. Burke Subject: mem. day ballot To: common-lisp @ SU-AI 1. Eliminate parse-number. Have parse-integer, as bernie suggested. This will eliminate all those dumb loops everyone seems to write all the time, and will also presumably have less overhead than a general read. 2. BLOCK NIL for LOOP Yes. 3. get-internal-time/get-real-time Sure, but i find the names (the contrast between them) disconcerting. It sounds like they are different units. ("internal" sounds like an internal representation, whereas "real" does not.) I have no alternate suggestion, and don't care all that much. 4. Eliminate implementation-dependent special-forms in macro-expansion. I guess i can accept this, although i would prefer to have a template-driven code-walker so that this would not be necessary. (As it is, i have many special forms which aren't even defined in the interpreter; they exist only to get the compiler to do some fancy things for special low-level code which never runs interpreted.) 5. :allow-other-keys OK. 6. NIL in multiple-value[-bind] Yes. 7. Eliminate CATCH-ALL and UNWIND-ALL. No opinion, i haven't thought about them or implemented them. 8. defmacro destructuring The whole thing should be subject to destructuring, including those positions in &mumbles which are unambiguous variable positions. I strongly suggest that we standardize on a primitive to do a destructuring bind in this manner, with syntax (name pattern value . body). I can't think up a good name, but it should not be rooted in LET. My experience with having LET do this type of destructuring is that it is a pain to do multiple "parallel" destructurings, and also that they are much much harder to read with those extra parentheses. 9. DECLARE/PROCLAIM. Sure. 10. simple-vector Yes. 11. Flush RESET-FILL-POINTER, add FILL-POINTER. Sure. 12. :named keyword to make-array/make-simple-vector I will send this out separately. It bothers me and leaves too many things unspecified. 13. Reintroduce *IBASE*... Yes, but *READ-BASE*. 14. sub-read I really don't care. There is not really a problem with defining functions in pairs; for instance, in NIL, we have (defun readline (&restv v) (read-apply ':readline #'readline-raw v)) (defun read (&restv v) (read-apply ':read #'read-raw v)) where read-raw and readline-raw are the simpler versions. 15. Propose that we rename *PRINfoo* to *PRINT-foo* for all foo... Yes. 16. floating-point in format... Probably the right thing to do. I have not thought about it. 17. Eliminate MAXPREFIX and MAXSUFFIX,... Sure. 18. vertical bars around a symbol following : or #: We should definitely allow that. For this, or in fact any pervasiveness attributable to a package prefix, one only needs to define the "token" as the characters up to and including the colon. I do not believe that this is hard to implement. As to whether the package name may be enclosed in vertical bars, or have funny hacks with case, really don't care, although i do think that this will be harder. 19. ~:A and ~:S should only affect the printing of NIL given directly as an argument, not the printing of NILs inside a printed list. This is because these are for printing an object that is known to be a list, not for printing data so it can be read compatibly into a N.I.L system. Yes. I never did notice that this change had been introduced; certainly this kludge has never been supported in my lisp implementation. Who is responsible for this N.I.L. system you mention which necessitates such grotesqueries? 20. APROPOS and PPRINT should return NIL... I like zero values, but don't particularly care about that or NIL. 21. *features*... Put them in the keyword package, and ensure that however the test after #+/#- is read, it works without colons. (Whether this be interning them there initially, or doing package-independent comparison to test the features.)  Received: from MIT-MC by SU-AI with TCP/SMTP; 31 May 83 21:20:11 PDT Received: from SPA-NIMBUS by SCRC-TENEX with CHAOS; Wed 1-Jun-83 00:21:45-EDT Date: Tuesday, 31 May 1983, 21:20-PDT From: BENSON%SPA-NIMBUS%MIT-MC@SU-DSN Subject: Memorial Day Ballot: comments on other people's entries To: David A. Moon , Common-Lisp@SU-AI In-reply-to: The message of 31 May 83 18:40-PDT from David A. Moon 14. No. I don't think the user needs to be concerned with whether a call to READ is at top level or not, since READ has to use a special variable to keep track of its state. The issue is how do you know when to re-bind this special variable? What if a reader macro, while reading from a file, asks for some input from the terminal for some reason? What if the same reader macro does the same thing while reading from the terminal? What if the reason it asked for input wasn't that it was programmed to, but that it got an error? READ can't tell whether it was called with the intent of being a recursive call or the intent of being a top-level call, although there are ways it can guess that work a lot of the time. I guess I have to go along with this. The solution proposed in the ballot still isn't good enough though, because reader macros have to know whether they're being called at the top level or not so that they in turn will know whether to call READ or SUB-READ. I would like to propose the following instead: Reader macros take three arguments: the input stream, the macro character, and the reader state. The third argument is an object which holds the state of the reading process at the point where the macro character was encountered. READ and READ-PRESERVING-WHITESPACE take an optional fourth (and READ-DELIMITED-LIST an optional third) READER-STATE argument. If a reader macro calls any of these three functions it should supply its third argument as the callee's READER-STATE argument. In the case of READ and READ-PRESERVING-WHITESPACE, a NIL value for EOF-ERRORP in this call may be overridden by a non-NIL value supplied by (or defaulted in) a dynamically enclosing call and encoded in the reader state object. This doesn't require any new functions, and it means that the reader doesn't have to keep any global state. On the other hand, it does add another data type, READER-STATE, which is similar to RANDOM-STATE, i.e. at the user level it's just a token that gets passed around. It also means that READ takes four optional arguments, but the fourth is only used in very unusual circumstances. Allowing user hooks into processes like reading, printing and evaluation (and even macro expansion, as in COMPILER-LET) tends to lead to problems like these. For example, there are a bunch of special variables which act as flags to control the behavior of the printer. There is also a function, WRITE, which takes keyword arguments for these flags. However, a function given as an argument to the :PRINT-FUNCTION option of DEFSTRUCT is supposed to observe the values of the variables in its behavior. Therefore, WRITE must bind all those special variables to the values supplied for the keywords (which by default of course are the values of the special variables). I can't wait to see the lambda list for that one! Luckily that only infringes on the implementor, not the user, but it is an unexpected consequence of allowing that hook. And as I look at it, I see that in order for *PRINPRETTY* (make that *PRINT-PRETTY*) to be useful, the :PRINT-FUNCTION should be supplied with a "horizontal position" argument, which should also be passed to recursive calls to the printer. What units, you say? I have discovered the general solution to this problem, but unfortunately there isn't enough space in this editor buffer to fully descr  Received: from MIT-MC by SU-AI with TCP/SMTP; 31 May 83 20:42:56 PDT Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Tue 31-May-83 23:42:20-EDT Date: Tuesday, 31 May 1983, 23:41-EDT From: David A. Moon Subject: floating-point format To: Common-Lisp@SU-AI I went and read the Fortran-77 standard, so now I understand Guy's proposal. This mess consists of several sections, separated by rows of dashes: Guy's proposal (from the memorial day ballot); a condensed form of the Fortran FORMAT-statement documentation; my suggestions; and the documentation for ~$ as its exists now in the Lisp machine (Scribe commands and all). ---------------- 16. Guy proposes the following treatment of floating point in FORMAT: ~w,d,pF ~w,d,x,pE ~w,d,pG The meanings of the arguments are exactly as for the FORTRAN-77 language as described in chapter 13 of the FORTRAN-77 standard, with the following exceptions and extensions: (a) The scale factor p is an explicit parameter, rather than being established be a separate preceding directive. For ~F, p defaults to 0, and for ~E and ~G it defaults to 1. (In FORTRAN p always defaults to 0.) (b) If w is omitted, then the output is variable-width, and never produces a field of asterisks; the other parameters are observed, however. So "~,2F" will always print exactly two digits after the decimal point, and prints as many as necessary to the left of the decimal point. (c) If d is omitted then as many digits are produced as necessary to preserve the information content of the number, except that if w is specified then the width constraint it imposes overrides this consideration. (Thus if both are omitted we get free-format output.) (d) The format operation formerly called ~G will henceforth be called ~@*. ---------------- From ANSI X3.9 1978 (selected highlights from chapter 13) SP requires + to be output. SS forbids + to be output. S restores the default, which gives the processor the option of outputting or not outputting + in I, F, E, D, and G editing. With a scale factor p: On output, with E editing, the basic real constant part of the quantity is multiplied by (expt 10 p) and the exponent is reduced by p. On F output editing the scale factor effect is that the externally represented number equals the internally represented number multiplied by (expt 10 p). On output, with G editing, the effect of the scale factor is suspended unless the use of E editing is required. The processor must not produce a negative signed zero in a formatted output record. On output the representation is right-justified in the field. On output, if the number of characters produced exceeds the field width or if an exponent exceeds its specified length, the processor will fill the entire field with asterisks. However the processor must not produce asterisks if the field width is not exceeded when optional characters are omitted. Plus sign is not optional when SP is in effect. F editing: Optional blanks, optional sign, and a string of digits that contains a decimal point, rounded to d fractional digits. Leading zeros are not permitted except for an optional zero immediately to the left of the decimal point if the magnitude is less than one. The optional zero must appear if there would otherwise be no digits in the output field. [It says nothing about trailing zeros.] E editing: ~w,d,x,pE The form of the output field for a scale factor p of zero is optional-sign optional-zero decimal-point d-digits exp where exp is a decimal exponent of one of the following forms: x unspecified, (abs exponent) <= 99: E plus/minus digit digit or plus/minus zero digit digit x unspecified, (< 99 (abs exponent) 1000): plus/minus digit digit digit x specified, (< (abs exponent) (1- (expt 10 x))): E plus/minus x-digits The sign in the exponent is required. A plus sign must be used if the exponent value is zero. x must not be unspecified if the absolute value of the exponent exceeds 999. If -d < p <= 0, the output field contains exactly -p leading zeros and d-(-p) significant digits after the decimal point. If 0= (expt 10 d): use E format with same parameters >= (expt 10 (1- a)) and < (expt 10 a): ~(w-n),(d-a)F ~n@T where n = x+2 or 4 if x is unspecified and (<= 0 a d). Thus if F format is used, d significant digits are printed, of which d-a are fractional, and the overall field width is the same, with some spaces on the right. ---------------- I like all four exceptions/extensions in Guy's proposal. On signs: The @ modifier forces a plus sign to be printed, as in ~D. Without an @, a plus sign is never printed. In either case a minus sign is printed if the number is negative. Fortran's prohibition against negative zero is overruled by the proposed IEEE standard. On arguments: ~F should not allow a scale factor, since it actually changes the magnitude of the represented number. (I am amenable to allowing it anyway, since it's optional and the last argument, if anyone has a use for it). ~w,d,x,pG (note the added x) because it has to pass this on to ~E if the number is large or small, and if the number is intermediate it has to use x to line up the columns. On exponent markers: should the exponent marker always be E? Always be the same type-dependent exponent marker that PRINT would use? Or should the : modifier switch between always using E as the exponent marker and using the type-dependent exponent markers that PRINT uses? On optional characters: the exponent marker should never be optional. The sign and leading zeros in the exponent should not be required. But there is an issue here of trying to line things up in columns. How about if x is specified then the exponent occupies exactly x+2 columns, consisting of the E (or other marker), a required sign, and x digits with leading zeros, whereas if x is unspecified then the exponent consists of an E (or other marker) followed by a free-format integer. On trailing zeros: if d is specified, trailing zeros are printed. If d is unspecified, trailing zeros are suppressed, except that at least one digit is printed to the right of the decimal point. On field overflow: we aren't dealing with 80-column cards here, and I don't think asterisk fill is ever appropriate. I'd rather see Common Lisp specify either: (1) If a number doesn't fit in a field then it is printed in as wide a field as required to represent it. If a number printed in F format is too large, E format may be used. or (2) If a number doesn't fit in a field then the results are whatever the implementation finds easiest or most tasteful. On G format: the essential features of G format as compared with F format are that small numbers are represented exponentially, rather than underflowing to zero, and that when no exponent is printed blank space is left where the exponent would be so that the numbers line up (I suggest we do this only if x is specified). On type errors: if any of these format operators see a rational number, they float it and proceed. If any of these format operators see a non-number, they output it in ~wA format, with *BASE* decimal. I don't know what is best for complex numbers here. ---------------- The following is the documentation for ~$ as it currently exists. @subsection(~$ @L[format] directive for floating point) @L[~$] is a previously undocumented @L[format] directive for floating point values. @IndexEntry[Entry={~$},Key={$},Number] @Index[~$] @Index[floating point values] @IndexEntry[Entry/{@L[format] directive},Key/{format directive},Number] The format for using it follows: @display{@L[~@i[rdig],@i[ldig],@i[field],@i[padchar]$]} It expects a flonum argument. The modifiers for @L[~$] are all optional. @begin(desplay) @I[rdig]@\The number of digits after the decimal point. The default is 2. @I[ldig]@\The minimum number of digits before the decimal point. The default is 1. It pads on the left with leading zeros. @I[field]@\The full width of the field to print in. The default is the number of characters in the output. The field is padded to the left with @I[padchar] if necessary. @I[padchar]@\The character for padding the field if the field is wider than the number. The default is @L[#\space]. @i[:]@\The sign character is to be at the beginning of the field, before the padding, rather than just to the left of the number. @i[@@]@\The number must always appear signed. @end(desplay) @verbatim[@OK[]@~ (format t "~&Pi is ~$" (atan 0 -1)) => Pi is 3.14 (format t "~&Pi is ~8$" (atan 0 -1)) => Pi is 3.14159265 (format t "~&Pi is ~8,2@@:$" (atan 0 -1)) => Pi is +03.14159265 (format t "~&Pi is ~8,2,20$" (atan 0 -1)) => Pi is 03.14159265 (format t "~&Pi is ~8,,20,'x@@$" (atan 0 -1)) => Pi is xxxxxxxxx+3.14159265 ] It uses free format (@L[~@@A]) for very large values of the argument. @Index[@L{~@@A}]  Received: from MIT-MC by SU-AI with TCP/SMTP; 31 May 83 20:39:21 PDT Date: 31 May 1983 23:37 EDT From: Earl A. Killian Subject: read top-level discussion To: common-lisp @ SU-AI Another possibility that I don't really like, but I'll suggest anyway, is to have a form for the user to specify when to start a new read top-level. The error handler and special reader hacks would use this. This could be as simple as binding *READ-LEVEL* to (+ *READ-LEVEL* 1).  Received: from MIT-MC by SU-AI with TCP/SMTP; 31 May 83 20:30:29 PDT Date: 31 May 1983 23:30 EDT From: Earl A. Killian Subject: Memorial Day Ballot To: Fahlman @ CMU-CS-C cc: common-lisp @ SU-AI In-reply-to: Msg of Mon 30 May 1983 02:18 EDT from Scott E. Fahlman 3. [GET-INTERNAL-TIME, GET-REAL-TIME] Certainly both both forms of time are needed. The whole set of time functions needs improving. I'll send another message later. 4. [white page macros expand into implementation-independent code] I am in favor of this. I am also in favor of adding enough functionality to Common Lisp to make this possible. I don't think the language is currently portable enough. 9. [PROCLAIM] I am strongly in favor of a PROCLAIM function. A PROCLAIM special form is not useful. 11. [FILL-POINTER] I am strongly in favor of this. 12. [:NAMED] How about :NAMED-TYPE or :TYPE-NAME? 13. [*IBASE*] Yes, but rename it *READ-BASE*. 15. [renaming i/o variables etc.] Yes. 20. [APROPOS, PPRINT return value] 0 values sounds good to me. 21. [package for features] I prefer allowing feature variables to be in any package, and to be read normally.  Received: from MIT-MC by SU-AI with TCP/SMTP; 31 May 83 18:42:05 PDT Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Tue 31-May-83 21:41:56-EDT Date: Tuesday, 31 May 1983, 21:40-EDT From: David A. Moon Subject: Memorial Day Ballot: comments on other people's entries To: common-lisp@su-ai In-reply-to: The message of 31 May 83 15:35-EDT from BENSON at SPA-NIMBUS, The message of 31 May 83 15:01-EDT from Dave Dyer , The message of 31 May 83 05:35-EDT from JONL.PA at PARC-MAXC.ARPA Date: Tuesday, 31 May 1983, 12:35-PDT From: BENSON at SPA-NIMBUS 6. No. NIL already has too much attached to it. A decent compiler will detect variables which are set but not used. It's not important enough to add another "keyword" usage to NIL. The issue here is the difference between (MULTIPLE-VALUE (NIL X) (FOO)) and (LET (TEM) (MULTIPLE-VALUE (TEM X) (FOO))). In other words it's not an attempt to get increased efficiency, but an attempt to increase clarity by avoiding the need to introduce unnecessary "fake" variables. It's not a big deal but I thought an explanation might be helpful. 14. No. I don't think the user needs to be concerned with whether a call to READ is at top level or not, since READ has to use a special variable to keep track of its state. The issue is how do you know when to re-bind this special variable? What if a reader macro, while reading from a file, asks for some input from the terminal for some reason? What if the same reader macro does the same thing while reading from the terminal? What if the reason it asked for input wasn't that it was programmed to, but that it got an error? READ can't tell whether it was called with the intent of being a recursive call or the intent of being a top-level call, although there are ways it can guess that work a lot of the time. 21. Put them in the GLOBAL (excuse me, LISP) package, instead of KEYWORD. Otherwise, users will be typing #+:FOO. Of course if the things in *FEATURES* are required to be keywords then the #+ and #- macros will read in the keyword package or use string-equal or otherwise arrange for you not to have to type a colon every time. Actually, there's no need to specify. One ought to be able to push any symbol onto *FEATURES*. The object after #+ and #- should be read just like any other. Remember, it can be a list, too. This is a reasonable position. In other words, MACSYMA:INTEGRATION and CIVIL-RIGHTS:INTEGRATION could be two different features from two different packages, that you might want to test for separately. Saying that features should be keywords, i.e. that packages lead to too much complexity here, is a reasonable position, also. The Lisp machine does the latter currently, but that doesn't mean much. I'm still neutral. But I'm not sure everyone has seen the point of both sides. Date: 31 May 1983 1201-PDT From: Dave Dyer 7. Flush CATCH-ALL, UNWIND-ALL NO! Otherwise there is no way to escape the predefined error semantics. These provide the essential gross hook that allows implementation of whatever variant is necessary. Example: The oly kind of CATCH Interlisp HAS is effectively CATCH-ALL Conditions are not throws. I think Fahlman sent a message in the past few days that explained this pretty well. I'll be proposing a condition system for Common Lisp in a few weeks (which could stretch into months, of course). 20. APROPOS, PPRINT return NIL Ok. Rather than a separate family to specify type of results, I'd prefer an optional argument to specify what to do. I usually use NIL->PRINT T-> return list otherwise (APPLY* X --) and return list of non-nil results This seems like a good idea, at least for APROPOS. Better than introducing a new function. Both APROPOS and PPRINT already take an optional argument, so they may need to be converted to keywords. The default should be to print out and return nothing. Date: 31 MAY 83 02:35 PDT From: JONL.PA@PARC-MAXC.ARPA Why "but ..." 5 - What about functions that don't pass their keylist on; e.g. MAKE-ARRAY ? Is it really true that :allow-other-keys will have the proposed meaning in *every* keyword-taking function? Yes. What if someone passes his keylist on -to- MAKE-ARRAY? Spread Uniformity: The meaning of a lambda-list for DEFUN, for lambda forms, and for DEFMACRO ought to be perceptually the same I am in very strong disagreement with this. Functions and special forms are fundamentally different. "Destructuring" in the lambda list of a function refers to taking apart THE VALUE OF AN ARGUMENT AT RUN TIME. "Destructuring" in the "lambda" list of a macro refers to taking apart THE SYNTACTIC STRUCTURE OF THE INVOKING FORM AT COMPILE TIME. These are as different as can be. Beginners have enough trouble understanding this without our throwing additional roadblocks in their way. Especially is this matter of uniformity important for auto-documentation. Wouldn't it be nice if you could write (DEFUN FOO ((A B) C) ...) rather than (DEFUN FOO (L C) (PROG ((A (CAR L)) (B (CADR L))) ...)) so that ?= type of helpers would show you more about the syntax of input arguments? What if I wanted to say that L was a list and C was an integer? What if I wanted to say that the first argument was a date and the second argument was a string which was the name of someone on the Common Lisp mailing list? What a loss if such facility worked for DEFUN definitions, but not for DEFMACRO definitions (and vice-versa)! Of course you can always get the auto-documentation to say anything you like, by using (DECLARE (ARGLIST ...)), at least on the Lisp machine.  Received: from SU-DSN by SU-AI with PUP; 31-May-83 13:58 PDT Received: From MIT-XX by SU-DSN.ARPA; Tue May 31 13:44:45 1983 Date: Tuesday, 31 May 1983, 13:40-PDT From: BENSON at SPA-NIMBUS Subject: Fahlman's latest package printing proposal To: Common-Lisp at SAIL Bravo! I knew it wasn't as hard as everyone thought. If we just accept the fact that packages really are a lot like symbols, everything works out OK. Now then, suppose we want to change the namespace of packages. Just bind *PACKAGE-OBARRAY* to :-) ! --Eric  Received: from MIT-MC by SU-AI with TCP/SMTP; 31 May 83 13:40:27 PDT Received: from SCRC-BORZOI by SCRC-TENEX with CHAOS; Tue 31-May-83 16:26:49-EDT Date: Tuesday, 31 May 1983, 16:26-EDT From: Daniel L. Weinreb Subject: Re: *prindepth* and *prinlength* versus *prinarray* To: Guy.Steele%CMU-CS-A@SU-DSN Cc: common-lisp@SU-AI In-reply-to: The message of 30 May 83 15:42-EDT from Guy.Steele at CMU-CS-A Date: 30 May 1983 1542-EDT (Monday) From: Guy.Steele@CMU-CS-A Page 241 of the Laser manual, under "vectors" and "arrays", specifically states that printing of vectors and arrays is affected by *prinlevel* and *prinlength*. Should I put cross-references to this fact elsewhere? Quite right, sorry about that. But, yes, it would be nice if it were mentioned on p 242 in the description of *prinlevel* and *prinlength* that arrays and vectors are affected. Thanks.  Received: from SU-DSN by SU-AI with PUP; 31-May-83 12:47 PDT Received: From MIT-XX by SU-DSN.ARPA; Tue May 31 12:36:57 1983 Date: Tuesday, 31 May 1983, 12:35-PDT From: BENSON at SPA-NIMBUS Subject: Memorial Day Ballot To: Fahlman at CMU-CS-C, common-lisp at su-ai In-reply-to: The message of 29 May 83 23:18-PDT from Scott E. Fahlman 1. Yes. 2. Yes. 3. This needs some better justification. It doesn't appear to be useful in portable code. Are the things returned by these functions integers? 4. Yes. 5. Yes. Be very careful in explaining this in the manual; it is tricky. 6. No. NIL already has too much attached to it. A decent compiler will detect variables which are set but not used. It's not important enough to add another "keyword" usage to NIL. 7. Yes. 8. Yes, with a style hint in the manual that mixing & keywords and destructuring is poor form. I would like to see a way to use DEFMACRO-style list groveling (both kinds) in places other than DEFMACRO. I recently wanted to use it in an assembler, for defining macros. DLET and/or DESETQ would be very useful. 9. Yes. 10. Yes. 11. Yes. 12. Yes, approximately. Remember, the NAME of the vector is the TYPE of the DEFSTRUCT (not to be confused with the element type), the thing returned by TYPE-OF. :NAMED is really the wrong name for this option. This would in fact be the only place where objects of a new user-defined type can be created. Perhaps it should be called :TYPE-OF, although that might cause some confusion with :ELEMENT-TYPE. 13. Yes, call it *READ-BASE*. 14. No. I don't think the user needs to be concerned with whether a call to READ is at top level or not, since READ has to use a special variable to keep track of its state. READ can look at that variable to see if it is being called recursively; if so, then it would do SUB-READ. This global state will still be needed, even if SUB-READ is defined. The only way to avoid it would be to add a third READER-STATE argument to read macros, which would have to be passed to recursive READs or SUB-READs. Notice that the example given under READ-DELIMITED-LIST now has no way of knowing whether to call READ-DELIMITED-LIST or SUB-READ-DELIMITED-LIST. Rather than adding this hair, let's leave it up to the system to tell whether it's being called recursively. A side issue: are dots allowed in READ-DELIMITED-LIST? I would say no; the manual should specify either way. 15. Yes. 16. Yes. 17. Yes. 18. Yes. I can't understand why anyone would think it was hard in the first place. 19. Yes. 20. Yes, but make it T instead. (NIL is so negative!) 21. Put them in the GLOBAL (excuse me, LISP) package, instead of KEYWORD. Otherwise, users will be typing #+:FOO. Actually, there's no need to specify. One ought to be able to push any symbol onto *FEATURES*. The object after #+ and #- should be read just like any other. Remember, it can be a list, too.  Received: from USC-ISIB by SU-AI with TCP/SMTP; 31 May 83 12:05:12 PDT Date: 31 May 1983 1201-PDT Subject: memorial ballot From: Dave Dyer To: common-lisp@SU-AI 1. Eliminate PARSE-NUMBER Yes. 2. LOOP => BLOCK NIL Yes. 3. GET-INTERNAL/REAL-TIME Yes. 4. Macro expansions are portable. Yes. 5. :allow-other-keys No opinion 6. (multiple-value (...nil...)...) Yes, and YES for multiple valuebind as Why should I have write my own LET when i want to ignore one of the values? 7. Flush CATCH-ALL, UNWIND-ALL NO! Otherwise there is no way to escape the predefined error semantics. These provide the essential gross hook that allows implementation of whatever variant is necessary. Example: The oly kind of CATCH Interlisp HAS is effectively CATCH-ALL 8. DEFMACRO destructuring. Yes. 9. PROCLAIM No, if it is really unnecessary. 10. SIMPLE-VECTOR holds any object I suppose. Do I hear a proposal for "SIMPLE SIMPLE VECTORS"? 11. FILL-POINTER Yes. 12. :NAMED in MAKE-ARRAY, MAKE-VECTOR Yes. Element 0 holds the name. 13. *READ-BASE* Yes. 14. SUB-READ, SUB-R-D-L No opinion 15. *PRINfoo* => *PRINT-foo* Yes. 16. ~E,~F,~G like in Fortran Yes. 17. Flush MAXPREFIX,MAXSUFFIX Yes. 18. | : interaction No. 19. ~:A vs NIL vs () Yes. 20. APROPOS, PPRINT return NIL Ok. Rather than a separate family to specify type of results, I'd prefer an optional argument to specify what to do. I usually use NIL->PRINT T-> return list otherwise (APPLY* X --) and return list of non-nil results 21. *features* are keywords No opinion. -------  Received: from USC-ECL by SU-AI with TCP/SMTP; 31 May 83 08:57:27 PDT Received: from MIT-MC by USC-ECL; Tue 31 May 83 08:58:37-PDT Received: from SCRC-BULLDOG by SCRC-TENEX with CHAOS; Tue 31-May-83 11:56:40-EDT Date: Tuesday, 31 May 1983, 11:58-EDT From: Bernard S. Greenberg Subject: A memorial day issue To: Fahlman@CMU-CS-C Cc: common-lisp%su-ai@USC-ECL In-reply-to: The message of 31 May 83 09:37-EDT from Scott E. Fahlman Date: Tue, 31 May 1983 09:37 EDT From: Scott E. Fahlman Send a specific proposal for PARSE-INTEGER and then we can consider it. My specific proposal is that we flush it. I still don't see any function in here that would be broadly and generally useful and not trivial for the user to write, but you've written more user interfaces than I, and if there's a good idea in here trying to get out, I'd like to see it. @Defun[Fun {parse-integer}, Args {@i[string]}, Keys {[start][end][radix][junk-allowed]}] This function examines the substring of @i[string] delimited by @kwd[start] and @kwd[end] (which default to the beginning and end of the string). It skips over whitespace characters and then attempts to parse an integer. The @kwd[radix] parameter defaults to @f[10], and must be an integer between 2 and 36. If @i[junk-allowed] is not @false, then the first value returned is the integer parsed, or @false if no syntactically correct number was seen. The second value is the index into the string of the delimiter that terminated the parse, or the index beyond the substring if the parse terminated at the end of the substring. If @kwd[junk-allowed] is @false (the default), then the entire substring is scanned. An error is signalled if the substring does not consist entirely of the representation of an integer, possibly surrounded on either side by whitespace characters. The returned value is the number parsed, or @false if no syntactically valid integer was found. It is an error if the substring is blank (@false will be returned in this case). @Enddefun I note in passing that a lot of interfaces from MIT have been strongly influenced by the syntactic style of TECO and DDT: 123x, etc. This style has its place (in programs like TECO and DDT), but there are much better user interface styles around for most things, or at least a lot of variety in people's taste. I dislike that style of interface intensely, too. PARSE-INTEGER, although it supports such activity, is not designed primarily with that in mind. so if the proposed PARSE-INTEGER were primarily intended to make it easier to parse the "abutted numeric prefix" style of argument, I think it would be a great candidate for the yellow pages but I would oppose its inclusion in the white pages. There is no strict need for a lot of functions. Yet, this particular little piece of functionality seems like a white pages candidate because, as I have said, almost any conceivable user interface will require it. The abutted-number feature is a very small aspect. I am not sure if whitespace around the number being allowed is right.  Received: from RANDOM-PLACE by SU-AI with TCP/SMTP; 31 May 83 07:53:46 PDT Date: Tuesday, 31 May 1983 10:49:13 EDT From: Joseph.Ginder@CMU-CS-SPICE To: fahlman@cmuc cc: common-lisp@su-ai Subject: Memorial Day Ballot Message-ID: <1983.5.31.14.5.18.Joseph.Ginder@CMU-CS-SPICE> 1. Y 2. Y 3. Y; with unit keywords (eg. microseconds) 4. Y 5. Y 6. no opinion 7. Y 8. Y (shudder) 9. Y 10. Y (It seems a shame to make "simple" denote "any lisp object but no bells and whistles"; however, I don't have a better idea other than equating "vector" with "no bells and whistles". Sigh.) 11. Y 12. Y 13. Y 14. recursive-p version 15. Y 16. no opinion 17. Y 18. Y (I detest losing input case information; but agree that symbols' halves should be treated the same. Note that I did not say I wanted case sensitivity!) 19. no opinion 20. Y 21. no opinion  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 31 May 83 06:43:26 PDT Received: ID ; 31 May 83 09:42:23 EDT Date: Tue, 31 May 1983 09:42 EDT From: Scott E. Fahlman To: Bernard S. Greenberg Cc: common-lisp@su-ai Subject: A memorial day issue Send a specific proposal for PARSE-INTEGER and then we can consider it. My specific proposal is that we flush it. I still don't see any function in here that would be broadly and generally useful and not trivial for the user to write, but you've written more user interfaces than I, and if there's a good idea in here trying to get out, I'd like to see it. I note in passing that a lot of interfaces from MIT have been strongly influenced by the syntactic style of TECO and DDT: 123x, etc. This style has its place (in programs like TECO and DDT), but there are much better user interface styles around for most things, or at least a lot of variety in people's taste. So if the proposed PARSE-INTEGER were primarily intended to make it easier to parse the "abutted numeric prefix" style of argument, I think it would be a great candidate for the yellow pages but I would oppose its inclusion in the white pages. -- Scott  Received: from USC-ECL by SU-AI with TCP/SMTP; 31 May 83 06:42:26 PDT Received: from CMU-CS-C by USC-ECL; Tue 31 May 83 06:39:09-PDT Received: ID ; 31 May 83 09:37:41 EDT Date: Tue, 31 May 1983 09:37 EDT From: Scott E. Fahlman To: Bernard S. Greenberg Cc: common-lisp%su-ai@USC-ECL Subject: A memorial day issue In-reply-to: Msg of 31 May 1983 08:43-EDT from Bernard S. Greenberg Send a specific proposal for PARSE-INTEGER and then we can consider it. My specific proposal is that we flush it. I still don't see any function in here that would be broadly and generally useful and not trivial for the user to write, but you've written more user interfaces than I, and if there's a good idea in here trying to get out, I'd like to see it. I note in passing that a lot of interfaces from MIT have been strongly influenced by the syntactic style of TECO and DDT: 123x, etc. This style has its place (in programs like TECO and DDT), but there are much better user interface styles around for most things, or at least a lot of variety in people's taste. So if the proposed PARSE-INTEGER were primarily intended to make it easier to parse the "abutted numeric prefix" style of argument, I think it would be a great candidate for the yellow pages but I would oppose its inclusion in the white pages. -- Scott  Received: from USC-ECL by SU-AI with TCP/SMTP; 31 May 83 05:48:10 PDT Received: from MIT-MC by USC-ECL; Tue 31 May 83 05:44:43-PDT Date: 31 May 1983 0843-EDT From: Bernard S. Greenberg Subject: A memorial day issue To: common-lisp%su-ai@USC-ECL Although the current PARSE-NUMBER is unworkable, the original idea has a legitimate place, and satisfies a legitimate need, in the language. Before coming to the Lisp Machine (which has a PARSE-NUMBER which is really PARSE-INTEGER), every program that interacted with a user which I had written required writing such a routine. It seems inevitable that any program that reads strings from a user would require such a routine, so, thus, it ought be part of the language. READ will not do the trick. READ cannot implement a subsystem's contract on what the subsystem's legal input is. Syntactic errors in typing a number should be detectable in a portable fashion without recourse to trapping READ errors (e.g., unbalanced parens in read-from-string). READ can be forced to produce odd side-effects via #. . Rename and respecify PARSE-NUMBER to PARSE-INTEGER. -------  Received: from SU-SCORE by SU-AI with TCP/SMTP; 31 May 83 02:40:05 PDT Received: from PARC-MAXC.ARPA by SU-SCORE.ARPA with TCP; Tue 31 May 83 02:43:41-PDT Date: 31 MAY 83 02:35 PDT From: JONL.PA@PARC-MAXC.ARPA Subject: Holiday Ballot To: Fahlman@CMUC.ARPA cc: Common-Lisp%SU-AI@SCORE.ARPA Summary: YES -- 2,4,7,14,16,18 YES, but ... -- 5,6,8 NO -- 9,17,20 No comment on remainder Why "NO": 9 - PROCLAIM is still unnecessary -- our discussions showed that it is a trivial matter of programming for Evaluator, Compiler, and code analyzers to detect the DECLARE as a syntactic part of a binding context (e.g., LAMBDA or PROG). Do we need more ways to do the same thing just because some system implementor couldn't think of how to do this S.M.O.P.? (Small Matter Of ...) 17 - There are two completely independent items here, and they should *not* be bundled into one ballot question. Eliminating the redundant MAXmumbles hardly needs a ballot, since it has been in the mails and no one seems to object to their demise. 20 - I think the 0-return-values solution is better. Why "but ..." 5 - What about functions that don't pass their keylist on; e.g. MAKE-ARRAY ? Is it really true that :allow-other-keys will have the proposed meaning in *every* keyword-taking function? 6 - I like KMP's arguments; the issue is one of uniformity. See the note "Spread Uniformity" below. Focusing on MULTIPLE-VALUE is far to limited a perspective -- I'd prefer this were extended to all LAMBDA position, just like MacLisp. 8 - Same comments as for 6. Additional comments on "YES" 2 - Is this actually a change from the current implementation of LOOP? I wonder, why wasn't RPG's suggestion about the MAP series of functions added to the ballot here; it would imply a somewhat incompatible change the way MAP etc are implemented in MacLisp, and as such is certainly deserving of a place on the ballot. 14 - I've written a number of readers in Lisp, and found the SUB-READ functionality just the thing for improving efficiency of macro characters (and similar things in the # repetoire). Upon entry to READ, a number of items may be checked for consistency, and some particular values may want to be "cached" in global variables; there is no reason for the recursive-entries to do this. Spread Uniformity: The meaning of a lambda-list for DEFUN, for lambda forms, and for DEFMACRO ought to be perceptually the same, namely it represents a way to take a sequence/list of items and "spread" them out into "slots". Historically, these slots were non-NIL symbols; in late 1978, MacLisp (and later NIL) extended the notion of "slot" to admit NIL, meaning "ignore", and any descendable S-expression, meaning "destructure" the item spread into this slot. The competitor to this plan was the "Program-oriented destructuring"; although it has some good points, it seems to have dropped out of view during the past several years In case you don't remember, the "Data-oriented" version says that the "slot" is a pattern whose non-NIL leaves are symbols to be bound to the corresponding value selected from the data item; the "Program-oriented version" says that the "slot" is a program which would build up the data item if all its accessor parts had the right value. Example (LET (((A B) X)) ...) ;Data, or pattern, oriented (LET ((`(LIST ,A ,B) X)) ...) ;Program oriented version both would bind A to (CAR X) and B to (CADR X). Note that the Data-oriented version is not limited to lists: (LET ((#(A (B . #(C D)) F) X)) ...) But the "Program-oriented version is even more general: (LET ((`(GET ,B 'MUMBLE) X)) ...) That is, it would be possible to indicating a binding to *any* LOCFable place, and not just to symbol values. [Apologies if I've mistated the format, or capabilities of the "Program-oriented version", but I don't think the actual details matter that much] The point of bringing all this up again is that to "fix" one of the places that does "spreading" and not "fix" the other places correspondingly is to perpretate a fairly gross and pointless inconsistency. [MacLisp failed to generalize SETQ, but instead provided the macro DESETQ; as it turned out, all the "destructuring" was done essentially by macro-expansions which used very primitive operations.] Especially is this matter of uniformity important for auto-documentation. Interlisp has an extremely useful capability in its reader -- the ?= macro -- which access the argument list of the function you are about to type arguments to; e.g., typing (CONS 3 ?= causes the informative typeout (CONS CarArgumentName = 3 CdrArgumentName ) so that you can see the names in the lambda list. (actually, the argument names for CONS are typically X and Y, but witht he use of SMARTARGLIST . . . ). Wouldn't it be nice if you could write (DEFUN FOO ((A B) C) ...) rather than (DEFUN FOO (L C) (PROG ((A (CAR L)) (B (CADR L))) ...)) so that ?= type of helpers would show you more about the syntax of input arguments? What a loss if such facility worked for DEFUN definitions, but not for DEFMACRO definitions (and vice-versa)!  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 31 May 83 00:14:25 PDT Received: ID ; 31 May 83 03:14:34 EDT Date: Tue, 31 May 1983 03:14 EDT From: Scott E. Fahlman To: Common-Lisp@su-ai Subject: Non-yucky package names (I think) In-reply-to: Msg of 31 May 1983 0225-EDT () from Guy.Steele at CMU-CS-A New proposal: Flush the rules for package-name caseification that are found in the current package chapter. Replace it with the following: With respect to case, reading, and printing, package names are treated EXACTLY like symbol names: upcase by default, escape that using / or ||, observe *PRINT-CASE* on printing, look up using case-sensitive matching. Note, however, that package names do not become symbols, but are stashed away in the package object as a string, after case conversion paralleling that for symbol-names. So the reader reads a token in just as if it were a symbol. If it hits a : or #:, it doesn't call INTERN on the token just collected, but instead calls FIND-PACKAGE. Then it reads the following token, which had better be a symbol, and interns it. The various package functions that take package-name strings should probably take symbol-or-string. If a symbol, you get the case-conversion for free but create a random symbol in the current package; if a string, you have to be careful of case. So, |fOo:BaR| would be a symbol containing a colon, but |fOo|:|BaR| is symbol |BaR| in package |fOo|. Notice that I have nothing up my sleeves and at no time did my hands ever leave the keyboard. What we lose is the cute preservation of original case in package names and the ability to toss around package-name strings without worrying about case. What we gain is a lot of uniformity: both halves of a symbol behave the same way. -- Scott  Received: from MIT-MC by SU-AI with TCP/SMTP; 31 May 83 00:08:17 PDT Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Tue 31-May-83 03:09:17-EDT Date: Tuesday, 31 May 1983, 03:02-EDT From: David A. Moon Subject: yucky package names To: common-lisp@SU-AI Perhaps I haven't grasped the point of the recent discussion, but I don't see why what the Lisp machine reader does now doesn't satisfy everyone's needs. What it does is extremely simple: slashes are allowed in package names. That's it. Any sequence of constituent characters, including slashified characters, ending in a colon is a package prefix. The other thing it does is that anything that is a symbol by itself is still a symbol if it follows a colon. That is why :|foo| works. Okay, I admit it: there's a bug. The printer doesn't remember to put the slashes in on output, so if you make a package with funny characters in its name, print symbols from that package with qualified names, and try to read them back in, you lose. This should be fixed, of course.  Received: from MIT-MC by SU-AI with TCP/SMTP; 30 May 83 23:35:38 PDT Date: 31 May 1983 02:35 EDT From: Kent M. Pitman Subject: Package names To: Fahlman @ CMU-CS-C cc: Common-Lisp @ SU-AI In my view, if we do this cleverly, users will never see the funny syntax and will never know the difference. There is no reason not to handle the general case. Mind you, I'm not trying to protect people, I'm trying to protect programs. No human should ever write package prefixes with funny chars, but it's easy (for me at least) to imagine a program doing so and the seed it uses for package names may for some reason not want to be constrained in this way. In this case, as in others, I advocate full generality precisely so that programs which write programs will not have to have ugly special cases to get around language glitches. Practically speaking, though, programs which write programs are becoming more and more common and the more general the language features, the better we will be supporting that. Certainly no tasteful programmer would write (MAPC #'FOO) when he meant NIL, would he? That's not why we support such; we support it, for the most part, to save special cases in programs that might output it. I am firm in my belief on this general issue that language design has an obligation to be as regular and general as possible. To avoid going in circles on this point, I won't bother commenting further on this issue unless I have something substantively different to say. Mine is just one person's vote, but it strongly opposes any outcome which disallows certain characters in an attempt to make up for ideosyncracies of the particular read syntax chosen. -kmp  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 30 May 83 23:28:24 PDT Date: 31 May 1983 0225-EDT (Tuesday) From: Guy.Steele@CMU-CS-A To: common-lisp@SU-AI Subject: Yucky proposed | syntax I certainly agree that the proposed | syntax is yucky. That a keyword named "foo" (lowercase) would come out |:foo| instead of :|foo| is very yucky. Like the "foo#:bar" syntax, it was intende to be quite grossly yucky. It is indeed beyond the bounds of reasonable taste to purposely invent package names with odd characters in them -- at least for human consumption. However, time and time again someone has reason to compute a purposely distasteful thing to be "sure" that no one will bump into it. That GENSYM names have leading zeros "G0001" is an example of this. Moreover, it will certainly be possible to compute package names. You can compute an arbitrary string and feed it to MAKE-PACKAGE. It is important, for debugging reasons if no other, to have a standard way to print in the resulting bizarre situation. But it doesn't have to be a nice way, and indeed should be awful to discourage such mucking about. The advantage of my proposal is that it keeps the tokenizing model very simple. That's all. Any other proposal I have seen makes the model for where you break between tokens very complicated. (For similar reasons I tend to prefer "foo::bar" to "foo#:bar", but I also agree with Moon that :: is perhaps not yucky enough.) It is not intended that it be easy, merely possible, to tell what |S P A C E S:\:\:=| means. Anyone who invents a package named "S P A C E S" or a symbol named "::=" deserves what he gets. Before non-terminating macro characters were introduced, the tokenizer was very simple. Escape characters make things into consituents; whitespace is ignored; macro characters get executed; and otherwise gobble constituents until a non-constituent is hit. Period. N-T macro characters complicated things only slightly. The proposed syntaxes such as |...|:|...| will require a much more complex model for the sake of some syntactic prettiness in situations that shouldn't have to be pretty. --Guy  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 30 May 83 22:52:30 PDT Received: ID ; 31 May 83 01:52:08 EDT Date: Tue, 31 May 1983 01:52 EDT From: Scott E. Fahlman To: Kent M. Pitman Cc: Common-Lisp@SU-AI Subject: Package names In-reply-to: Msg of 31 May 1983 01:34-EDT from Kent M. Pitman I disagree totally with your view of what would constitute an unreasonable restriction in package names. There is no parallel here with what things should be legal in strings. It is no additional cognitive load on real users to remember that package names are supposed to look like names: alphanumeric characters stuck together. Only users who want to poke around beyond the limits of good taste would have to remember to avoid /, :, |, and whitespace. I prefer the very simple scheme proposed in my earlier message. I would go along with a decision to treat package names EXACTLY like symbols with respect to case and escape conventions. I am adamantly opposed to introducing yet another set of hairy case conventions for string names. -- Scott  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 30 May 83 22:34:04 PDT Received: ID ; 31 May 83 01:33:58 EDT Date: Tue, 31 May 1983 01:33 EDT From: Scott E. Fahlman To: MOON%SCRC-TENEX@mit-mc Cc: common-lisp@su-ai Subject: Ballot clarifications In-reply-to: Msg of 30 May 1983 16:44-EDT from MOON at SCRC-TENEX A couple of things that you asked about in your ballot: You ask whether, if *IBASE* (or *READ-BASE*) is > 10, some things that would otherwise be symbols would be read in as numbers. I think that the guiding philosophy here should be the one you proposed: *IBASE* is for reading in data files through the Lisp reader (and maybe for compatibility packages) and not for code. In a compatibility package (for code from Maclisp or @i[Cadropithecus robustus]), the issue does not arise, since the IBASE in question is octal. In reading data, the rule should be that if it can be parsed into a number in the current *IBASE*, it will be; else it is a symbol. On the GET-REAL-TIME proposal, I'm afraid I didn't explain this very well. GET-UNIVERSAL-TIME is meant to produce a number that can be decoded to find the current date and time in absolute terms. This might take a while to get, so it's useful for finding the current time of day but not for fine-grained measurement of elapsed time. GET-INTERNAL-TIME and GET-REAL-TIME are relative times expressed in "internal-time" format. These are for timing various executions but do not give you any absolute time. You call one of them twice, subtract, and then divide by INTERNAL-TIME-UNITS-PER-SECOND to get the elapsed time in seconds. The number of units per second is chosen to give a reasonable balance between clock accuracy and fixnum size on a given implementation: the S1 needs a granularity of picoseconds and the Perq can get by with seconds. My proposal is simply that sometimes you want elapsed runtime and sometimes you want elapsed clock-on-the-wall time. I was going to propose calling these GET-ELAPSED-RUNTIME and GET-ELAPSED-REALTIME, but each call to these functions returns only a single point, not an interval, so that would be misleading also. -- Scott  Received: from MIT-MC by SU-AI with TCP/SMTP; 30 May 83 22:32:31 PDT Date: Tuesday, 31 May 1983, 01:34-EDT From: Kent M. Pitman Subject: Package names To: Common-Lisp at SAIL I dislike restrictions on what can go into package names. Tradition in Lisp syntax is to not restrict the language due to the syntax. Restrictions should not be made on what characters may appear in a package name any more than they should be made about what can go into a string. Can you imagine the irritation of being told you can't use NUL in a string because it's being used for an end of string designator. Having to remember which N chars can't be used in package names would be very irritating and would drip too much of yielding to a particular syntax when a strong premise of Lisp is that syntax is not wired. How about if we say that the tokenizer scans the package id just as any symbol (allowing vbars) so that |()|:FOO is legal. It will then look up the package (using case insensitive lookup of (SYMBOL-NAME the-package-symbol-thing-we-just-read)). You can declare a package using a string so case can be designated at that time. On output, the exact case of that declared name will be used and a special hack will be put in the printer such that |...| will be removed from mixed-case things where they would normally be retained. eg, |Abc|:|Abc| would print as Abc:|Abc| (same as ABC:|Abc| and abc:|Abc| and a/bc:A/b/c, etc. assuming the package was declared with "Abc" as its name). Are there any problems with such a scheme? I really think it's essential that we not get cornered into prohibiting certain chars as people seem to be suggesting. -kmp  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 30 May 83 21:58:31 PDT Received: ID ; 31 May 83 00:58:44 EDT Date: Tue, 31 May 1983 00:58 EDT From: Scott E. Fahlman To: steele@CMU-CS-C Cc: common-lisp@su-ai Subject: ballot issues Guy, I like the spirit of your proposal to distinguish internal and top-level calls to READ through the use of flags passed in through EOF-ERRORP, but there are a couple of problems. First, EOF-ERRORP is no longer a "p" -- there are three values, and the action comes from two non-null flags. Second, EOF-ERRORP is no longer just about errors. As you point out, top-levelness controls a couple of other issues as well. So I think that leaving the name as it is would be very confusing. What about the following: Leave all the read forms just as is, but add a new optional argument RECURSIVE-P at the end. (This goes on all the read functions that currently have EOF-ERRORP and EOF-VALUE.) If non-null, this indicates a recursive (non-"top-level") call. In such cases, the function's EOF-ERRORP and EOF-VALUE are ignored and should be NIL. The top-level call's arguments determine the EOF action. This makes it possible to get the desired effect without new functions and without going to keywords in all of these functions. As a general rule, a function with this many flags would want to be converted to keywords, but the casual user would almost always take the default for the last arg, or even the last three args. As for your vertical bar proposal, I don't like it much. I see no reason for package names to sprout all the syntactic hair that symbols have. It seems to me that the reader gobbles down the characters forming a token, treats any unslashed : or #: as terminating the token, and if these particular terminators are seen, it takes the token-so-far and treats it (verbatim) as a package-name string rather than doing the slashified upcasing and treating it as a symbol. If the reader wants to do the symbol-upcasing as it reads in the characters, this means that it has to stash away the original characters as well -- not too bad. Just to avoid any confusion, I would forbid package names to contain |, \, : or any whitespace. If you see any of those, and then the : or #: terminator, signal an error. Why go to the trouble of providing the user with a way to get these into package names, just so that horribly confusing situations can be created? The alternative would be to treat case identically in all parts of a qualified symbol: upcase things not slashified and do a case-sensitive match. Then |'s around the whole thing or around either half would be OK. But since there is no tradition of using package names for pseudo-strings and other randomness, I would prefer to keep them free of this machinery. -- Scott  Received: from MIT-MC by SU-AI with TCP/SMTP; 30 May 83 17:18:29 PDT Date: 30 May 1983 20:18 EDT From: Alan Bawden Subject: Steele's |:foo| suggestion. To: common-lisp @ SU-AI, Guy.Steele @ CMU-CS-A, fahlman @ CMU-CS-C In-reply-to: Msg of 30 May 1983 1459-EDT () from Guy.Steele at CMU-CS-A Sorry, I don't find the |S P A C E S:\:\:=| proposal at all tastefull. The difference between |S P A C E S:\:\:=| and |S P A C E S\:\:\:=| requires a microscopic examination of the characters to discover. Given that the common case requires no quoting of the package prefix (on the LispMachine we went for 6 years before anyone discovered that PRINT had a deficiency in printing package prefixes that required quoting), I find the visual distinction between SI:|::=| and |SI:::=| much clearer than that between |SI:\:\:=| and |SI\:\:\:=|. I'm sure that if I tried hard enough I could find some problem with Steele's proposal having to do with the way the case of the quoted package prefix is treated. Note that his proposal FORCES us to address this issue, whereas if we keep the package name outside the vbars the issue ONLY arises with respect to funny characters in package names. Since people seem to think that it is important to have some rule about package names with funny characters, I propose that (Common Lisp portable) packages MUST have names that are composed of letters (case insensitive), digits, !, $, %, &, *, +, -, <, >, ?, {, }, @, [, ], ^, _, and ~. (Or some suitable similar restriction.) I do not buy any argument that says SI:|::=| is hard to tokenize. After the reader has read "SI:" (in fact, immediately after reading ANY unquoted ":") the next thing in the input stream must be the printed representation of a symbol. In my mind the "token" ended with the reading of the ":", I realize that this means that you can't just gobble a symbol token, and then check for occurances of ":", and thus the table on page 222 of the laser manual needs a new type of syntax. Tough. The extra hours work it takes to implement it is worth it in my opinion.  Received: from MIT-MC by SU-AI with TCP/SMTP; 30 May 83 17:07:41 PDT Date: Monday, 30 May 1983 19:50-EDT From: MOON at SCRC-TENEX To: common-lisp at su-ai Subject: Issue of macro expansion portability I went through all the macros in the Common Lisp Summary at the back of the Laser edition. I know this list is not up to date, and incomplete, but it's all I have. Almost all the macros there need not expand into implementation-dependent special-forms, only imp-dep functions and imp-dep macros that themselves don't expand into imp-dep special forms. COMPILER-LET, MACRO, and LOCALLY are exceptions, but I believe we already decided that these are special forms, not macros, and the Laser edition is in error. MULTIPLE-VALUE, MULTIPLE-VALUE-BIND, and MULTIPLE-VALUE-LIST are documented as macros. I guess the intention (contrary to the second to last paragraph on page 89) must be that these are macros expanding into MULTIPLE-VALUE-CALL of a lambda-expression, which the compiler then recognizes as a special case and optimizes. We could do this, but I would greatly prefer not to have to go through such a song-and-dance in the compiler. Currently in the Lisp machine DEFVAR expands into code that includes an implementation-dependent special form. The reason for this, rather than generating some sort of interpretive code such as (OR (BOUNDP 'var) (SETQ var val)), has to do with system bootstrapping: DEFVAR has to expand into code that the cold-load generator can understand, and it is easier to add a new special form that it understands than to make it parse some idiom such as OR-BOUNDP-SETQ. This one is only a matter of convenience and simplicity. WITH-INPUT-FROM-STRING, WITH-OUTPUT-TO-STRING, and the future condition-handling macros need to generate data structure of dynamic extent in the stack. This could be done using functions, but that would involve horrendous gyrations in the compiler, because it would have to look for uses of those functions inside of LET, recognizing the particular cases that work and giving an error for all other cases. Instead, what we did in the Lisp machine was to add two new special forms, WITH-STACK-LIST and WITH-STACK-LIST*, which provide a general mechanism for making dynamic-extent data structures (trees, not arrays). Because these are special forms the compiler can understand them and generate code for them very easily. The other benefit of this is that there are a number of user applications that can take advantage of these to get more efficient execution when they know that a certain data structure is only going to be used in a dynamic-extent way. Other implementations might prefer to implement WITH-INPUT-FROM-STRING in a different way, not involving any data of dynamic-extent, but some implementations will want to do it this way, so there is a problem. We could conform to the letter, but not the spirit, of the proposed rule of no implementation-dependent special forms, by making all of these special forms into macros with a special kludgey check in the compiler so that it would not expand them. We could probably come up with some sort of expansion for them that would satisfy a code-walking program, even though it would not produce correct code if compiled. I don't really like any sort of approach along these lines, because suppose you run some code through a code-walking program which, as a side-effect, expands all macros in the code. You would naturally be surprised if you discovered that the resulting fully macro-expanded program did not compile correctly. Even if it produced correct, but much less efficient, code, you would not be happy. I would prefer to introduce a handful of additional special forms. An interesting point to ponder is that all of these special forms are of the simple sort that my template-driven meta-evaluator (or code-walker) can understand merely on the basis of templates. They all involve evaluation, setq'ing, and variable-binding, but they don't involve any unusual flow of control, other than not processing subforms in left-to-right order (e.g. MULTIPLE-VALUE evaluates the second subform before it setq's the variables in the first subform). Opinions?  Received: from MIT-MC by SU-AI with TCP/SMTP; 30 May 83 16:02:16 PDT Date: Monday, 30 May 1983 19:01-EDT From: MOON at SCRC-TENEX to: Common-Lisp at SU-AI Subject: Memorial Day Ballot comments In-reply-to: The message of 30 May 1983 16:54 EDT from Kent M. Pitman Date: 30 May 1983 16:54 EDT From: Kent M. Pitman 6. No Actually, if NIL is allowed in place of any variable to be bound or set meaning IGNORE, I support the proposal. I think I'd prefer to limit this strictly to MULTIPLE-VALUE, and not try to allow NIL in place of a variable in MULTIPLE-VALUE-BIND. When I suggested the latter I hadn't thought through the implications. Making this strictly a MULTIPLE-VALUE feature should limit the irregularity. 8. (DEFMACRO FOO (&OPTIONAL ((FOO . BAR) '(A . B)) ...) ...) to work. This, too, can be useful. Then the restriction wouldn't be "left of &" but would rather be "any place that is unambiguously reserved for variable names" or some such. This is a good way to explain it. DEFMACRO, and its underlying primitive macro DESTRUCTURING-BIND, accept lambda-list syntax except that any tree can be used where a variable is allowed. Ambiguity, which occurs only after &OPTIONAL and &KEY, is uniformly resolved in favor of lambda-list syntax. If our present implementation contains any deviation from this (the only one I know of is not recognizing &KEY) it is broken and we will fix it. 12. Yes I dispute the claim that DEFSTRUCT can't already work in a site- independent way. You could put a unique marker in slot0 of the defstruct (eg, a gensym whose plist pointed at the real name of the structure (which would in turn point back at the gensym)). The reason this doesn't work is that the type system is required to understand named structures, and the type system is built into each implementation. 15. Yes With regard to *PRINT-READABLY*, etc., the manual should give explicit advice to users saying that they must test this flag when writing print methods for things that print with #<...>, otherwise this flag will be of less value. There's a macro in the Lisp machine to aid in this. I mailed documentation on it to Fahlman and Steele, perhaps they can make it stylistically consistent with Common Lisp and put it on a ballot.  Received: from MIT-MC by SU-AI with TCP/SMTP; 30 May 83 14:12:17 PDT Date: 30 May 1983 16:54 EDT From: Kent M. Pitman Subject: Memorial Day Ballot To: Fahlman @ CMU-CS-C cc: Common-Lisp @ SU-AI Summary YES on 1-2, 4, 7-16, 19, 21. NO on 3, 6, 18, 20. no opinion on 5, 17. Comments 3. No Do not add GET-INTERNAL-TIME and/or GET-REAL-TIME without specifying the format of the time. My experience with code that hacks times says this is frequently worthless and often dangerous. If the units are unspecified, code may appear to run while in fact producing bogus results. I might accept a modified proposal where these functions were keyworded and implementations could optionally signal an error for keywords they didn't handle. eg, (GET-INTERNAL-TIME :MILLISECONDS), etc. 4. Yes Constrain system-provided macros to not expand to system-dependent special forms. Be careful to word this such that it's understood that system-dependent macros can be part of the expansion as long as those macros will eventually bottom out as system-independent special forms and/or any kind of function(s). 6. No Actually, if NIL is allowed in place of any variable to be bound or set meaning IGNORE, I support the proposal. In the absence of such a restriction, I am swayed by Steele's comments about irregularity. Maclisp gets much power from allowing NIL in some forms to mean an ignored argument, but programs which transform code suffer problems of irregularity in what can go in which binding lists. 7. Yes In fact, if Common Lisp had primitives for creating and manipulating processes, I would claim that CATCH-ALL and UNWIND-ALL in some form might be needed. Perhaps, too, if it specified the implementation of debuggers, complex error handlers, etc. In the absence of such, however, I have seen no valid applications for such primitives. Many internal facilities will be implemented with CATCH/THROW and users will not be able to recognize what kinds of tags do what things in order to not screw themselves or thwart important system functionality. Something like CATCH-ALL or UNWIND-ALL may be needed internally by a given implementation, but since each implementation will almost surely use it differently, no attempt should be made to export or standardize this feature at this time. 8. Yes This is quite useful. Many people prefer destructuring to &keywords. I recommend, in fact, allowing (DEFMACRO FOO (A . B) ...) to mean (DEFMACRO FOO (A &REST B) ...) and even (DEFMACRO FOO X ...) to mean (DEFMACRO FOO (&REST X) ...) as I'm pretty sure the Maclisp family now allows. Maclisp even allows (DEFMACRO FOO (&OPTIONAL ((FOO . BAR) '(A . B)) ...) ...) to work. This, too, can be useful. Then the restriction wouldn't be "left of &" but would rather be "any place that is unambiguously reserved for variable names" or some such. 9. Yes This sounds harmless and might do some good. 10. Yes I probably agree with all this. A picture of the type hierarchy this proposes would be helpful so I'd feel more sure. 12. Yes I dispute the claim that DEFSTRUCT can't already work in a site- independent way. You could put a unique marker in slot0 of the defstruct (eg, a gensym whose plist pointed at the real name of the structure (which would in turn point back at the gensym)). However, having a primitive named-array facility of some sort would be fine also. 15. Yes With regard to *PRINT-READABLY*, etc., the manual should give explicit advice to users saying that they must test this flag when writing print methods for things that print with #<...>, otherwise this flag will be of less value. 16. Yes The change to ~G breaks a lot of code, but I suppose the eventual result is for the better. It will certainly ease the chore of mechanical translation. 18. No I would like to see a more coherent description of what this means before I say yes. In general this sounds right, but I'm increasingly bothered by the off-and-on way we seem to treat package prefixes as either strings or symbols. There's an argument that says "...", not |...| should be what's allowed. There are also reasons for believing |...|:FOO should denote package "/|.../|":FOO, etc. -- at least, under this vague proposal. I will probably vote yes on this eventually when a complete, coherent proposal is made. 19. Yes Both styles are occasionally useful, but the only thing you can usually guarantee the correctness of is the toplevel case. ~:A and ~:S should not be pervasive. 20. No The return value should be left undefined and implementors should be encouraged not to return anything `big'. On the LispM, it works well for these sorts of things to return 0 values, since they then don't clobber the value of "*", and one can do things like (GET 'FOO 'BAR) (GPRINT *) ;GPRINT is a pretty printer (CAR *) ;refers to (CAR (GET 'FOO 'BAR)) If GPRINT returned NIL, * would be clobbered with a useless value. Specifying that these functions return no values and specifying that this feature of the read-eval-print-loop happens might be a win. 21. Yes This problem may be more general than just FEATURES, but this is a good start.  Received: from MIT-MC by SU-AI with TCP/SMTP; 30 May 83 13:42:07 PDT Date: Monday, 30 May 1983 16:44-EDT From: MOON at SCRC-TENEX to: common-lisp at su-ai Subject: Memorial Day Ballot In-reply-to: The message of Mon 30 May 1983 02:18 EDT from Scott E. Fahlman 1. Eliminate PARSE-NUMBER Okay. Maybe a new proposal in the future. 2. LOOP => BLOCK NIL Yes. 3. GET-INTERNAL/REAL-TIME Yes, but query below. 4. Macro expansions are portable. I'm going to reserve my vote on this one until I've studied whether any CL builtin macros need to expand into imp-dep special forms, at least in our implementation. 5. :allow-other-keys Yes. 6. (multiple-value (...nil...)...) Yes. Maybe not for MULTIPLE-VALUE-BIND. 7. Flush CATCH-ALL, UNWIND-ALL Yes. Could be put back later if needed. 8. DEFMACRO destructuring. Yes. 9. PROCLAIM Yes. I assume PROCLAIM is a function, not a special form? 10. SIMPLE-VECTOR holds any object Yes. also SIMPLE-STRING, SIMPLE-BIT-VECTOR, SIMPLE-ARRAY exist 11. FILL-POINTER Yes. 12. :NAMED in MAKE-ARRAY, MAKE-VECTOR Yes. Element 0 holds the name. 13. *READ-BASE* Yes. If >10, some things that would be symbols will read as numbers? 14. SUB-READ, SUB-R-D-L I'm reserving my vote while I study GLS's 15. *PRINfoo* => *PRINT-foo* Yes. 16. ~E,~F,~G like in Fortran Yes. You may hear from me after I go read the Fortran manual to figure out how ~G differs from ~F. 17. Flush MAXPREFIX,MAXSUFFIX Yes. 18. | : interaction I'm reserving my vote while I study GLS's 19. ~:A vs NIL vs () Yes. 20. APROPOS, PPRINT return NIL Yes. I'd prefer no values, but NIL is okay 21. *features* are keywords Neutral. --- 3. How does GET-REAL-TIME differ from GET-UNIVERSAL-TIME? How are GET-INTERNAL-TIME and GET-REAL-TIME supposed to be used? Are they intended for user-interface purposes, in which case they should be in fairly coarse units, such as seconds, or are they intended for metering purposes, in which case they should be in rather fine units (same order of magnitude as the instruction-processing time of the machine, so that small changes in the performance of a function are visible)? How is the conflict between trying to keep these numbers small, so that they are fixnums and arithmetic on them does not noticeably interfere with the performance of the program being measured, and trying to make them well behaved numbers that don't "wrap around" to be resolved? Or are all such issues supposed to be taken care of by the TIME special form, in which case I have to complain that it prints its output instead of putting it somewhere where it can be processed by programs? I don't think we're prepared to design an elaborate Common Lisp instrumentation system here, but some guidelines would be helpful.  Received: from MIT-MC by SU-AI with TCP/SMTP; 30 May 83 13:16:59 PDT Date: Monday, 30 May 1983 16:16-EDT From: MOON at SCRC-TENEX to: common-lisp at su-ai Subject: Memorial Day Ballot comments In-reply-to: The message of Mon 30 May 1983 15:28 EDT from Skef Wholey Date: Mon, 30 May 1983 15:28 EDT From: Skef Wholey 8. Why must destructing live in lambda lists? I think a destructing form would be much more useful (if you can do destructuring in defmacro's, why not other places like compiler transforms?). How about a macro DESTRUCTURE... It's important for documentation reasons that the destructuring in a DEFMACRO be up at the top, not buried inside the body somewhere. To give a simple example, we have an editor command that prints the argument list of the form that that the cursor is in. For a macro with complex syntax, you certainly want this command to tell you about the syntax. However, you are quite right that the destructuring operation is useful by itself. We call it DESTRUCTURING-BIND, a rather terrible name. DEFMACRO is nothing but a convenient packaged combination of MACRO and DESTRUCTURING-BIND. I haven't proposed DESTRUCTURING-BIND for Common Lisp recently, because of the name (although it is analogous to MULTIPLE-VALUE-BIND I guess) and because it might seem too complicated. 12. Where would the name be stored? Our DEFSTRUCT uses a special subtype code to say that the thing's a named structure, and stashes the name in slot 0 of the vector. So the slots are all "moved up one" into the vector. It seems that the manual would have to specify something about the implementation, i.e. where the name is stored. Indeed for DEFSTRUCT to be a portable program it has to know whether the name of a named-vector takes up space in the vector. If the only named type in the common language is simple (general) vector, then I see no problems with legislating that the name goes in slot 0. And surely most implementations would rather do it that way, rather than having named vectors take on a different storage representation than ordinary vectors. Of course if you wanted named bit-vectors this wouldn't work, but I see no need for that by DEFSTRUCT. Scott, shall we have an auxiliary mini-ballot on these two things?  Received: from RUTGERS by SU-AI with TCP/SMTP; 30 May 83 13:10:18 PDT Date: Mon 30 May 83 16:13:49-EDT From: Mgr DEC-20s/Dir LCSR Comp Facility Subject: SUB-READ and friends To: common-lisp@SU-AI.ARPA I propose removing this from the ballot pending further discussion. I agree that the distinction is important. I don't think having two versions of every function is a delightful way to do it. We have a similar problem in Elisp. E.g. if a user types ^F anywhere in the form, he is supposed to get into the editor to edit it when he finishes typing all the )))'s. Also there is the EOF problem that has already been mentioned. What we do is have a separate form READ-CONTEXT. This is sort of a special-purpose CATCH: it establishes the context to which EOF should exit and where ^F should activate. A recursive call to READ-CONTEXT is a no-op (more or less). This allows us to write things like READLINE in Lisp. I am not sure that this solves the problems for Common Lisp, but I do believe we should look for something better than SUB-READ. -------  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 30 May 83 12:44:53 PDT Date: 30 May 1983 1542-EDT (Monday) From: Guy.Steele@CMU-CS-A To: Daniel L. Weinreb Subject: Re: *prindepth* and *prinlength* versus *prinarray* CC: common-lisp@SU-AI In-Reply-To: "Daniel L. Weinreb's message of 21 Apr 83 10:47-EST" Page 241 of the Laser manual, under "vectors" and "arrays", specifically states that printing of vectors and arrays is affected by *prinlevel* and *prinlength*. Should I put cross-references to this fact elsewhere? [Sorry for the delay; I'm just nopw catching up on the May mail deluge.] --Guy  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 30 May 83 12:28:05 PDT Received: ID ; 30 May 83 15:28:34 EDT Date: Mon, 30 May 1983 15:28 EDT From: Skef Wholey To: Scott E. Fahlman CC: common-lisp@su-ai Subject: Memorial Day Ballot I agree with all your recommendations except for the following issues: 8. Why must destructing live in lambda lists? I think a destructing form would be much more useful (if you can do destructuring in defmacro's, why not other places like compiler transforms?). How about a macro DESTRUCTURE, which could be used like this: (defmacro new-control-construct (foo &optional bar &rest baz) (destructure foo (var init iterate-clause) ...)) instead of: (defmacro new-control-construct ((var init iterate-clause) &optional bar &rest baz) ...) ? 12. Where would the name be stored? Our DEFSTRUCT uses a special subtype code to say that the thing's a named structure, and stashes the name in slot 0 of the vector. So the slots are all "moved up one" into the vector. It seems that the manual would have to specify something about the implementation, i.e. where the name is stored. --Skef  Received: from USC-ECL by SU-AI with TCP/SMTP; 30 May 83 12:05:42 PDT Received: from MIT-ML by USC-ECL; Mon 30 May 83 12:01:45-PDT Date: 30 May 1983 15:01 EDT From: George J. Carrette Subject: special characters in package names To: common-lisp @ SU-AI Something like |;;|: is easy enough to parse as a package prefix. I would implement this in the NIL reader by putting a PEAK-CHAR case on the char-macro for |. Of course, a user could already have typed this in as \;\;: so there is no need to have | behave in this way. Another thing is that truly-funny package names are likey to be extremely troublesome in file mode-lines. On the other hand, presently (INTERN "FOO" (PKG-CREATE-PACKAGE "()")) prints out as |()|:FOO so for completeness I'd have to go along with it.  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 30 May 83 12:02:36 PDT Date: 30 May 1983 1459-EDT (Monday) From: Guy.Steele@CMU-CS-A To: fahlman@CMU-CS-C Subject: My replies to Memorial Day Ballot CC: common-lisp@SU-AI I am in favor of all the proposed changes except numbers 6, 14, and 18. I also have a remark on issue 7. 6: I am not convinced that the bit of convenience in MULTIPLE-VALUE is worth the odd exception in the syntax, particularly if it is allowed to propagate to MULTIPLE-VALUE-BIND. Also, just as LET is in many cases preferable to SETQ anyway, so MULTIPLE-VALUE-BIND is often preferable to MULTIPLE-VALUE anyway, in which case IGNORE declarations do the job. Therefore I am opposed to this proposal, though not strongly. 7: CATCH-ALL and UNWIND-ALL are currently the only means for trapping any throw and being able to decide what it is. (UNWIND-PROTECT does not have the latter property.) However, it may be best to omit these until we have yet more experience with what we really want. UNWIND-PROTECT does 90% of the job. 14: There are at least three reasons to distinguish a "top-level" read from an "internal" call: (a) A top-level call establishes the "preserve whitespace" flag, and an internal call does not modify it. (b) A top-level call establishes a scope for the #n= and #n# syntax. (c) A top-level call establishes the exit point for EOF errors. While introducing two new functions (copies of the "READ-like" functions) solves the first two problems, it does not solve the third. It is also necessary to distinguish betwene top-level and internal calls to READ-CHAR and READ-LINE and others for the purposes of EOF handling. Also, it is undesirable for new user-written parsing functions to have to come intwo flavors. I think it is better to have a standard simple protocol for distinguishing between top-level and internal calls. It does seem rather unpleasant to have to go to keyword syntax for all the input functions. Here is another possibility: let the eof-errorp parameter take on one oif three values. NIL means it is an internal call. :VALUE means that EOF causes the eof-value to be returned. :ERROR means an error should be signalled. If an "internal call" is performed when there is no surrounding "top-level" call, then it is as if :ERROR had been specified. NIL is the default value for eof-errorp. 18: I agree that it is desirable to allow | syntax in package-prefixed names, but this proposal does not cover all the cases. What about odd characters in package names? May | syntax be used there too? I have a counter-proposal. | syntax may surround the *entire name* of a symbol. It is as if every character between the vertical bars had been preceded by a \, except for the characters |, \, and (here is the proposed change!) :. Any occurrence of any of these three characters must nevertheless always be preceded by a \. It may seem awful to require any : to be preceded by a \. It would have been in MacLISP, where |-symbols were also used as strings. This is not a problem in COmmon LISP. As an example, the symbol in package "S P A C E S" whose name is "::=" could be written as |S P A C E S:\:\:=| The advantage of this proposal is that it allows | to continue to be an ordinary macro character with screwing up the tokenizer. Note that that keyword whose name was "foo" (lowercase) would be written |:foo|, not :|foo|. Vertical bars would always completely surround the entire other syntax for the symbol, and are described by the simple rule of quoting every character except |, \, and :. --Guy  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 30 May 83 08:07:01 PDT Received: ID ; 30 May 83 11:07:36 EDT Date: Mon, 30 May 1983 11:07 EDT From: Scott E. Fahlman To: Martin.Griss Cc: Common-Lisp@su-ai Subject: Memorial Day Ballot In-reply-to: Msg of 30 May 1983 08:36-EDT from Martin.Griss Date: Monday, 30 May 1983 08:36-EDT From: Martin.Griss To: Fahlman cc: Griss at UTAH-20 Re: Memorial Day Ballot Two things concern me: a) CATCH-ALL. If flushed, how do we trap a THROW and determine what its TAG was, so that we can write fancy handlers. We use this in PSL to trap and resignal Errors etc in the Break loop and some compiler loops. The manual no longer talks about handlers, but let's assume that you want something similar to what was described in Laser, perhaps with extra hair to classify error types heirarchically and catch whole classes of them at once. You almost certainly want to allow for a thing that will catch ALL errors and do some specified thing -- throw to the top-level or whatever. It seems to me that there needs to be a piece of machinery to keep track of the current condition-to-handler mapping, and to invoke the proper handler code for each condition that might be signalled. This might be as simple as an A-list, with (T . universal-handler) being the "catch-all-errors" widget. In any event, this mapping determines the proper handler, the system invokes it IN THE DYNAMIC CONTEXT OF THE ERROR, and it is the handler that does any throwing. If throw/catch/catch-all is used to do the mapping, then critical context is lost before the handler ever gets a crack at it. So I don't think that this is a place where CATCH-ALL is going to be useful. b) Name vector for DEFSTRUCT suport. Will this actually be a diffeernt TYPE? I don't think named vectors would be a full-fledged type, unless you define a type to be anything you can test for. All we are suggesting is that there would be a :named keyword to create these critters and a NAMED-P test to see if this is what you have. This would be completely orthogonal to SIMPLE and all of the other hairy properties that vectors and arrays can have. -- Scott  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 30 May 83 00:21:11 PDT Received: ID ; 30 May 83 02:18:55 EDT Date: Mon, 30 May 1983 02:18 EDT From: Scott E. Fahlman To: common-lisp@su-ai Subject: Memorial Day Ballot Memorial Day Ballot: I was going to send these out in smaller doses, but a bunch of issues built up and I decided that a real ballot would be easier. A few more issues will be sent out for consideration as soon as we have come up with some coherent proposals and analyses. Please reply by Wednesday afternoon to FAHLMAN@CMUC and/or Common Lisp. Recommendations in square brackets are by Scott Fahlman. --------------------------------------------------------------------------- 1. It is proposed that we eliminate PARSE-NUMBER from the manual. [I am strongly in favor of this. This function is hard to document properly, hard to implement in its full generality, and useless. Most of what this function does can be handled simply by calling READ on the string. Other cases, such as Teco-like integer prefixes, can easily be handled by application-specific user functions to scan a string for the first non-digit, etc.] --------------------------------------------------------------------------- 2. LOOP should create a BLOCK NIL around the TAGBODY, so that RETURN works. [I am strongly in favor. If LOOP doesn't do this, the user will almost always have to, and any future complex LOOP package would have to create such blocks as well.] --------------------------------------------------------------------------- 3. Define GET-INTERNAL-TIME to get some implementation-dependent form of runtime. Add a second function, GET-REAL-TIME that returns some measure of elapsed real time in the same internal-time format. On some machines, especially personal ones, these times will be identical, and implementations may not be able to supply one or the other, but where both are available (as on the Vax), there are legitimate needs for both. [I am strongly in favor.] --------------------------------------------------------------------------- 4. The manual currently specifies (page 42, top) that the macros defined in the white pages macros may expand into implementation-dependent code. Some of them cannot be written without this freedom, but we don't want these macros to expand into things that will preclude the writing of portable code-walkers. Therefore, it is proposed that this wording be changed to allow implementation-specific functions to be produced, but not new special forms. [I am strongly in favor, unless someone comes up with a case where this restriction would cause serious trouble for an implementation.] --------------------------------------------------------------------------- 5. If the special :allow-other-keys keyword is present in a call to a keyword-taking function, it suppresses any unrecognized-keyword errors. This is necessary so that pre-checked keyword lists can be passed through a keyword-taking function to some other function that is called by the first one without causing an error. [I'm in favor.] --------------------------------------------------------------------------- 6. In MULTIPLE-VALUE it is useful to have a way to discard unwanted values. Since you aren't binding, using and ignored variable is inconvenient. It is proposed that we follow the Lisp Machine here and use NIL in place of a variable to mean "ignore this value". For consistency, this would work in MULTIPLE-VALUE-BIND as well, although it is less useful there. [Moon proposed this. I'm mildly in favor, though I've oscillated on this several times.] --------------------------------------------------------------------------- 7. Eliminate CATCH-ALL and UNWIND-ALL. [Moon argues that these are worthless and should be flushed. I agree. These forms make a LOT of trouble for the implementor and are never used. Does anyone have an example of some real situation in which you would need these? If not, let's punt them.] --------------------------------------------------------------------------- 8. Since DEFMACRO is used to define special forms, some of which have complex formats, it is proposed that we add destructuring to DEFMACRO variable lists. This would have to coexist with the current &mumble indicators. Destructuring works only to the left of the first & word; from that point on, the varlist is parsed like a lambda list. [My conservative instincts rebel at having destructuring and & words in the same varlist, but I have gradually come around to the position that this feature is worth any extra confusion it might cause (plus the trouble of implementing it). The simple cases that would really be used will not be confusing. So I favor this.] --------------------------------------------------------------------------- 9. It is proposed that DECLARE will be legal only at the start of particular special forms, and that a new form, PROCLAIM, will be used at top-level and in other places. DECLARE will be undefined if encountered in random places (though it may be defined as part of a compatibility package). The SPECIAL declaration is global if it appears within PROCLAIM; it applies only to a particular binding and to references within the scope of the form if it appears within a DECLARE. [This issue (how to detect when a SPECIAL declaration is "top-level") was debated on the Common Lisp list awhile back. The proposal above, by Moon, seemed the least objectionable to most of us at the time, and is what we have implemented in the new Spice Lisp evaluator. I favor it.] --------------------------------------------------------------------------- 10. The following was proposed by Moon: The SVREF function and the (SIMPLE-VECTOR *) type are essentially useless. On stock hardware you cannot open-compile these, because an implementation is required to provide (SIMPLE-VECTOR T), (SIMPLE-VECTOR STRING-CHAR), and (SIMPLE-VECTOR BIT) types; hence SVREF, without additional declarations, must do a run-time type dispatch. The useful function is SGVREF and the useful type is (SIMPLE-VECTOR T), because these can be open-coded (and the only distinction between VECTOR and SIMPLE-VECTOR is efficiency). The SIMPLE-STRING and SIMPLE-BIT-VECTOR types are also useful, but don't have special accessor functions. Another way of putting this is that whether or not MAKE-ARRAY returns a "simple" object should be allowed to depend on the :ELEMENT-TYPE as well as the other keywords. The phrase "simple general vector" is not euphonious. Here's the proposal: Retain the identity between the types (VECTOR type length) and (ARRAY type (length)). In other words, "vector" continues to be a synonym for "1-dimensional array." Eliminate SVREF and rename SGVREF to SVREF. Eliminate the type (SIMPLE-VECTOR type length), replacing it with (SIMPLE-VECTOR length). In other words, define a SIMPLE-VECTOR to be a one-dimensional array of Lisp objects, creatable by calling MAKE-ARRAY with only one dimension and with -none- of its keywords except for :initial-element/:initial-contents. In particular use of :element-type (other than T) makes it non-simple (or, rather, permits the implementation to return a non-simple-vector object but doesn't require it to. Most implementations would do the same thing for :element-type 'common as for :element-type t). In addition to SIMPLE-VECTOR we have SIMPLE-STRING and SIMPLE-BIT-VECTOR. Add auto-declaring accessor functions with names SCHAR and SBIT (or something less horrid), to increase the symmetry. SIMPLE-STRING is no longer a subtype of SIMPLE-VECTOR, even though STRING is a subtype of VECTOR. I don't believe this is a problem. The type-specifier (SIMPLE-ARRAY element-type dimensions) refers to an array created without the use of the :ADJUSTABLE, :FILL-POINTER, :DISPLACED-TO, or :DISPLACED-INDEX-OFFSET keywords. Such arrays are implemented more efficiently in some implementations; thus a SIMPLE-ARRAY type declaration may be used to get better code for array accesses. Example: (DEFUN FFT (A) (DECLARE (TYPE (SIMPLE-ARRAY SINGLE-FLOAT 2) A)) ...) (SIMPLE-VECTOR n) == (SIMPLE-ARRAY T (n)) (SIMPLE-STRING n) == (SIMPLE-ARRAY STRING-CHAR (n)) (SIMPLE-BIT-VECTOR n) == (SIMPLE-ARRAY BIT (n)) The subtle note about declaration vs discrimination on page 33 of the Laser edition applies. SAREF probably shouldn't exist, since it would need to include the element-type as an extra pseudo-argument, which would make the syntax confusing. Some implementations will choose to make the extension that :FILL-POINTER is allowed when making a 1-dimensional simple array, so that they can have SIMPLE-STRINGs with fill-pointers. I don't know whether the manual ought to mention this (probably not). [ Despite my fear of re-opening the array debate, I believe that this is such a win that it is worth that risk. I am strongly in favor of this proposal. I just can't bring myself to type SGVREF. ] --------------------------------------------------------------------------- 11. Flush RESET-FILL-POINTER. Add a new function FILL-POINTER, which returns the active length of any vector that has a fill pointer. This is the same as what LENGTH returns, but it signals an error if the object in question doesn't have a fill pointer. SETF works on FILL-POINTER. The new value must be a non-negative integer not greater than the dimension of the vector. [I favor this. RESET-FILL-POINTER is ugly. SETF of LENGTH would be confusing, since it would only work on a small fraction of the objects on which LENGTH works.] --------------------------------------------------------------------------- 12. DEFSTRUCT must often created named vectors that are recognizable as such. There is currently no portable mechanism to do this, so DEFSTRUCT must use implementation-dependent magic. It would be nice if DEFSTRUCT could be written entirely within Common Lisp. It is proposed that we add a :NAMED keyword to MAKE-ARRAY and MAKE-SIMPLE-VECTOR. The argument is the name itself, a symbol. This argument is only legal if the array is 1-D. [I'm in favor.] --------------------------------------------------------------------------- 13. Reintroduce *IBASE*, but with a note that this should be used only for compatibility packages and for reading files of data with the Lisp reader. Portable code should contain no regions of non-decimal radix; individual non-decimal symbols may be read in using #O and friends. We may want to rename this to *READ-BASE* if proposal 15 is adopted. [I'm in favor, given these warnings. There will be times when we really need this.] --------------------------------------------------------------------------- 14. There are a few places where READ and READ-DELIMITED-LIST need to behave differently according to whether or not they are "top-level" calls to read. For example, the scope of a set of #n# and #n= bindings (or is it the extent?) is one top-level call to READ, so READ needs to know whether it was called at top level or by a read-macro. I propose that we add two new functions, SUB-READ and SUB-READ-DELIMTED-LIST that exactly parallel their counterparts, but that indicate non-top-level calls to read -- such calls do not rebind the ## context, etc. [I'm in favor. An alternative proposal was to turn all the read functions into keyword functions and add a :recursive keyword, but this gets into some efficiency and clarity issues that I would prefer to avoid.] --------------------------------------------------------------------------- 15. Propose that we rename *PRINfoo* to *PRINT-foo* for all foo, and that *BASE* be renamed to *PRINT-BASE*. In addition, the names of the keyword arguments for WRITE would be changed from :PRINfoo to :foo. So one could say (WRITE X :BASE 8 :LEVEL 3 :LENGTH 5 :PRETTY T :RADIX T) Finally, introduce *PRINT-READABLY*, a flag that when true causes an error to be signalled if the LEVEL or LENGTH cutoff is about to be applied or if #< syntax is about to be used. That is, it refuses to print something that cannot be read back in. [I am strongly in favor of this. The sole virtue of the old names was Maclisp compatibility, and we blew that when we went for the asterisks.] --------------------------------------------------------------------------- 16. Guy proposes the following treatment of floating point in FORMAT: ~w,d,pF ~w,d,x,pE ~w,d,pG The meanings of the arguments are exactly as for the FORTRAN-77 language as described in chapter 13 of the FORTRAN-77 standard, with the following exceptions and extensions: (a) The scale factor p is an explicit parameter, rather than being established be a separate preceding directive. For ~F, p defaults to 0, and for ~E and ~G it defaults to 1. (In FORTRAN p always defaults to 0.) (b) If w is omitted, then the output is variable-width, and never produces a field of asterisks; the other parameters are observed, however. So "~,2F" will always print exactly two digits after the decimal point, and prints as many as necessary to the left of the decimal point. (c) If d is omitted then as many digits are produced as necessary to preserve the information content of the number, except that if w is specified then the width constraint it imposes overrides this consideration. (Thus if both are omitted we get free-format output.) (d) The format operation formerly called ~G will henceforth be called ~@*. (e) A separate proposal regarding ~$ is being developed. [Looks good to me. Something for everyone, just like Esperanto.] --------------------------------------------------------------------------- 17. Eliminate MAXPREFIX and MAXSUFFIX, which are redundant with MISMATCH. MISMATCH with non-null :FROM-END returns one plus the index of the first position (from the right) in which the two sequences do not match. (The "one plus" is the new part.) [I am strongly in favor.] --------------------------------------------------------------------------- 18. Moon proposes that we allow vertical bars around a symbol that follows a : or #: package qualifier. [I am in favor, unless this is a lot harder to implement than I think it should be. Do any of you reader-hackers out there have a strong opinion?] --------------------------------------------------------------------------- 19. ~:A and ~:S should only affect the printing of NIL given directly as an argument, not the printing of NILs inside a printed list. This is because these are for printing an object that is known to be a list, not for printing data so it can be read compatibly into a N.I.L system. [Proposed by Moon. I'm mildly in favor of this.] --------------------------------------------------------------------------- 20. APROPOS and PPRINT should return NIL so that they can be used at top level from the terminal without having the returned value clobber the stuff just printed. Add a new function APROPOS-LIST that hands you a list of the APROPOS symbols but prints nothing. [I'm in favor.] --------------------------------------------------------------------------- 21. We need to indicate what package contains the symbols that are used as elements of *features*. It is proposed that we make these keywords. [I'm in favor.]  Received: from MIT-MC by SU-AI with TCP/SMTP; 29 May 83 11:22:46 PDT Date: 29 May 1983 14:07 EDT From: George J. Carrette To: COMMON-LISP @ SU-AI Does anybody have a LIST (i.e. a file with "(CAR CDR CONS ...)" in it) of all common-lisp defined functions and variables in it? (Perhaps some code to parse the SCRIBE source of the manual?)  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 26 May 83 19:47:51 PDT Received: ID ; 26 May 83 22:49:13 EDT Date: Thu, 26 May 1983 22:49 EDT From: Scott E. Fahlman To: steele@CMU-CS-C Cc: common-lisp@su-ai Subject: ENDP Guy, In the DTYPES chapter (May 10) you say that functions that require lists expect to be given true lists, but that "whether a function that requires a true list will behave reasonably when given a dotted list depends on the implementation". I agree with the sentiment, but I would like to propose a rewording: "It is an error to pass a dotted list to a function that is specified as requiring a list argument. Implementors are encouraged to check for this error by using ENDP (ref) to check for the end of the loop. However, since this test is often part of an inner loop, it must be efficient. Some implementations may choose to use ATOM for such tests, quietly ignoring any non-null terminating atom." Or something like that. All of our implementations are reasonable, but on a Vax there's a limit to how reasonable you can be. -- Scott  Received: from MIT-MC by SU-AI with TCP/SMTP; 26 May 83 21:01:32 PDT Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Fri 27-May-83 00:03:48-EDT Date: Thursday, 26 May 1983, 23:56-EDT From: David A. Moon Subject: ENDP To: common-lisp@su-ai In-reply-to: The message of 26 May 83 22:49-EDT from Scott E. Fahlman I like Scott's wording better. However, I surmise that the use of the vague expression "whether ... will behave reasonably ... depends on the implementation" was intended to convey the idea that some implementations will use a NULL check (rather than an ATOM check) and hence will behave most unreasonably, cdr'ing off into randomness, when given a dotted list. Of course this is discouraged, but the manual should say explicitly whether it is allowed or forbidden. To summarize: 1. ENDP check (or NULL check plus always-error-checking CDR) Error if given a dotted list and end of it reached 2. ATOM check Dotted list simply behaves like an undotted one 3. NULL check Dotted list causes unpredictable behavior.  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 26 May 83 19:47:51 PDT Received: ID ; 26 May 83 22:49:13 EDT Date: Thu, 26 May 1983 22:49 EDT From: Scott E. Fahlman To: steele@CMU-CS-C Cc: common-lisp@su-ai Subject: ENDP Guy, In the DTYPES chapter (May 10) you say that functions that require lists expect to be given true lists, but that "whether a function that requires a true list will behave reasonably when given a dotted list depends on the implementation". I agree with the sentiment, but I would like to propose a rewording: "It is an error to pass a dotted list to a function that is specified as requiring a list argument. Implementors are encouraged to check for this error by using ENDP (ref) to check for the end of the loop. However, since this test is often part of an inner loop, it must be efficient. Some implementations may choose to use ATOM for such tests, quietly ignoring any non-null terminating atom." Or something like that. All of our implementations are reasonable, but on a Vax there's a limit to how reasonable you can be. -- Scott  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 26 May 83 07:53:00 PDT Received: ID ; 26 May 83 09:55:06 EDT Date: Thu, 26 May 1983 09:55 EDT From: Scott E. Fahlman To: common-lisp@su-ai Subject: Manual update For reasons too complicated to discuss here, progress on the Common Lisp Manual has been rather slow lately. Guy and I have discussed how to fix this, and we have decided that the best way to converge quickly is for him to concentrate on editing in the relatively non-controversial things and those items on which decisions have been reached, and for me to orchestrate the arpanet-intensive process of reaching some sort of consensus (or at least a decision) on those issues that still require some debate. I will keep some sort of file on the decisions that have been reached to date -- more on this in a later message. Guy will be watching these debates and commenting where appropriate, but will not be doing the day-to-day message answering. Given the need to move fast on this, I do not propose to do this via a single moby ballot. Instead, I will raise issues one by one or in small groups, and will in most cases attach a strong recommendation or proposal to each. People will have 48 hours or so to object or raise counter proposals -- longer, of course, for the more complex issues. Then a decision will be announced, will be put in some sort of file, and will be turned over to Guy for inclusion in the manual. Implementors should feel fairly safe in treating the things in this file as settled. It will be possible to re-open issues after the gavel has come down, or for that matter to re-open any old wounds, but the threshold for getting a change adopted or even a fair hearing will be very much higher in such cases. At that point, mere tastefulness (or lack thereof) will probably not suffice -- only arguments of the form "The language cannot possibly work if we retain X" or "X is unimplementable" or "X will be devastating to potential users of Common Lisp" will be entertained at that point. I will endeavor to strike a reasonable balance between speed and decisiveness, on the one hand, and giving everyone a fair hearing, on the other. If anyone thinks I'm drifting too far in either direction, apply feedback. Does anyone object violently to this new scheme? If so, speak now, but be sure to include a viable counter-proposal. -- Scott  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 26 May 83 07:53:00 PDT Received: ID ; 26 May 83 09:55:06 EDT Date: Thu, 26 May 1983 09:55 EDT From: Scott E. Fahlman To: common-lisp@su-ai Subject: Manual update For reasons too complicated to discuss here, progress on the Common Lisp Manual has been rather slow lately. Guy and I have discussed how to fix this, and we have decided that the best way to converge quickly is for him to concentrate on editing in the relatively non-controversial things and those items on which decisions have been reached, and for me to orchestrate the arpanet-intensive process of reaching some sort of consensus (or at least a decision) on those issues that still require some debate. I will keep some sort of file on the decisions that have been reached to date -- more on this in a later message. Guy will be watching these debates and commenting where appropriate, but will not be doing the day-to-day message answering. Given the need to move fast on this, I do not propose to do this via a single moby ballot. Instead, I will raise issues one by one or in small groups, and will in most cases attach a strong recommendation or proposal to each. People will have 48 hours or so to object or raise counter proposals -- longer, of course, for the more complex issues. Then a decision will be announced, will be put in some sort of file, and will be turned over to Guy for inclusion in the manual. Implementors should feel fairly safe in treating the things in this file as settled. It will be possible to re-open issues after the gavel has come down, or for that matter to re-open any old wounds, but the threshold for getting a change adopted or even a fair hearing will be very much higher in such cases. At that point, mere tastefulness (or lack thereof) will probably not suffice -- only arguments of the form "The language cannot possibly work if we retain X" or "X is unimplementable" or "X will be devastating to potential users of Common Lisp" will be entertained at that point. I will endeavor to strike a reasonable balance between speed and decisiveness, on the one hand, and giving everyone a fair hearing, on the other. If anyone thinks I'm drifting too far in either direction, apply feedback. Does anyone object violently to this new scheme? If so, speak now, but be sure to include a viable counter-proposal. -- Scott  Received: from USC-ECL by SU-AI with TCP/SMTP; 25 May 83 14:09:45 PDT Received: from MIT-ML by USC-ECL; Wed 25 May 83 14:10:20-PDT Received: from SCRC-BORZOI by SCRC-TENEX with CHAOS; Wed 25-May-83 17:09:58-EDT Date: Wednesday, 25 May 1983, 17:08-EDT From: Bernard S. Greenberg Subject: REDUCE Change To: Wholey@CMU-CS-C Cc: common-lisp%su-ai@usc-ecl, common-lisp-implementors%SCRC-TENEX@MIT-ML In-reply-to: The message of 25 May 83 16:33-EDT from Skef Wholey Date: Wed, 25 May 1983 16:33 EDT From: Skef Wholey My intuition about and implementation of REDUCE are exactly opposite yours, I guess, since this special case does fall nicely out of my code. I retract every(previous)thing I have said on the subject. You (and Moon) are right, it falls out of my code too, I have been away from my function too long...  Received: from USC-ECL by SU-AI with TCP/SMTP; 25 May 83 13:03:48 PDT Received: from MIT-ML by USC-ECL; Wed 25 May 83 13:04:27-PDT Received: from SCRC-BORZOI by SCRC-TENEX with CHAOS; Wed 25-May-83 13:31:22-EDT Date: Wednesday, 25 May 1983, 13:29-EDT From: Bernard S. Greenberg Subject: REDUCE Change To: common-lisp%su-ai@usc-ecl Cc: common-lisp-implementors%SCRC-TENEX@MIT-ML What is the reason for this new wart in the definition of REDUCE, i.e., REDUCE of a one-element subsequence does not invoke the function? It is not at all consistent with the rest of the definition of the function. The specific (reduce '(foo) #'+) example in the manual seems to me counterintuitive. I guess my big complaint is that this "feature" does not fall out of the code nicely at all, and the amount of code spent worrying about it, given indefinite list ends, :from-end, etc., is almost equal to that of the rest of the function.  Received: from USC-ECL by SU-AI with TCP/SMTP; 25 May 83 13:46:28 PDT Received: from MIT-ML by USC-ECL; Wed 25 May 83 13:04:52-PDT Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Wed 25-May-83 14:26:32-EDT Date: Wednesday, 25 May 1983, 14:20-EDT From: David A. Moon Subject: REDUCE Change To: Bernard S. Greenberg Cc: common-lisp%su-ai@usc-ecl In-reply-to: The message of 25 May 83 13:29-EDT from Bernard S. Greenberg Date: Wednesday, 25 May 1983, 13:29-EDT From: Bernard S. Greenberg What is the reason for this new wart in the definition of REDUCE, i.e., REDUCE of a one-element subsequence does not invoke the function? Since the function is required to take two arguments, how could it be invoked when there is only one thing to give it? The bug here (I just looked at a recent version of KSEQUE.MSS) is that the clarification note about one-element (sub)sequences should have said that it only applies to the case where no :initial-value is specified. If a :initial-value is specified, then the function is not invoked in the case where the subsequence contains -zero- elements. So far as I know none of this is new, it's just that the manual doesn't explain it at all clearly.  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 24 May 83 13:27:08 PDT Date: 24 May 1983 1536-EDT (Tuesday) From: David.Dill@CMU-CS-A (L170DD60) To: common-lisp@su-ai Subject: EXPORT after USE Message-Id: <24May83.153655.DD60@CMU-CS-A> Received: from CMU-CS-PT by CMU-CS-A; 24-May-83 12:23:13-EDT It is really not clear to me why the effects of EXPORT after USE have to be the same in all common lisp implementations. It is not hard to imagine debugging tools that can track down and help resolve symbol conflicts caused by this in various ways for various implementations. The proposed scheme is not the only way to do this. I'm not complaining about this because I want to implement a "copy" system in Spice Lisp. It just seems to me that there is a natural division between a common subset of the current proposal requiring that all symbols be exported before the package is used, and the wizard-level hacking necessary during development, which can be implementation-dependent (it is clearly not going to be possible to move code to another dialect of common lisp when it would take two or three weeks to rebuild it from sources). This seems to be consistent with the principles just applied to the error system revisions. -Dave  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 25 May 83 10:33:00 PDT Date: 25 May 1983 1252-EDT (Wednesday) From: David.Dill@CMU-CS-A (L170DD60) To: common-lisp@su-ai Subject: EXPORT after USE Message-Id: <25May83.125226.DD60@CMU-CS-A> Since we all believe that exporting from a used package is a debugging operation, there should definitely be something in the package chapter that makes this clear -- "finished" systems should not screw around with export lists after a package has been used. A second suggestion is that we leave the results of messing around with the implementation internals of a common lisp dialect up to that dialect, in this case by not specifying the exact behavior when export lists are changed after a package has been used (although maybe the manual should allude to the existence of mechanisms for dealing with this sort of operation). This will allow room to experiment, in order to find the best behavior when export lists are diddled, and to find more efficient implementations of INTERN. I fully support the notion that individual implementations should be aware of the need for changing export lists for debugging and patching -- but it shouldn't be a part of common lisp. Except for this issue, I'm happy with the current proposal. -Dave  Received: from USC-ECL by SU-AI with TCP/SMTP; 25 May 83 14:24:55 PDT Received: from CMU-CS-C by USC-ECL; Wed 25 May 83 14:24:54-PDT Received: ID ; 25 May 83 16:33:34 EDT Date: Wed, 25 May 1983 16:33 EDT From: Skef Wholey To: Bernard S. Greenberg Cc: common-lisp%su-ai@usc-ecl, common-lisp-implementors%SCRC-TENEX@MIT-ML Subject: REDUCE Change Date: Wednesday, 25 May 1983, 13:29-EDT From: Bernard S. Greenberg Re: REDUCE Change It is not at all consistent with the rest of the definition of the function. The specific (reduce '(foo) #'+) example in the manual seems to me counterintuitive. I guess my big complaint is that this "feature" does not fall out of the code nicely at all, and the amount of code spent worrying about it, given indefinite list ends, :from-end, etc., is almost equal to that of the rest of the function. My intuition about and implementation of REDUCE are exactly opposite yours, I guess, since this special case does fall nicely out of my code. If no initial value is supplied, I grab the first (or last if we're :from-ending it) element from the specified subsequence and restrict the bounds by one. Then I enter a loop calling the function until the subsequence is exhausted. So the function is never called. The case of passing in a null sequence with no initial value is handled entirely separately. So (reduce #'+ '(2)) <==> (reduce #'+ '() :initial-value 2). --Skef  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 24 May 83 20:35:35 PDT Received: ID ; 24 May 83 23:36:36 EDT Date: Tue, 24 May 1983 23:36 EDT From: Scott E. Fahlman To: David.Dill@CMU-CS-A (L170DD60) Cc: common-lisp@su-ai Subject: EXPORT after USE In-reply-to: Msg of 24 May 1983 1536-EDT () from David.Dill at CMU-CS-A (L170DD60) Well, we could leave this unbound, or we could restrict EXPORT after USE to signal an error, but the proposal as it now stands looks OK to me, the problems with inheritance semantics seem to have been overcome, and I would need a really compelling reason to change it now. -- Scott  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 24 May 83 13:27:08 PDT Date: 24 May 1983 1536-EDT (Tuesday) From: David.Dill@CMU-CS-A (L170DD60) To: common-lisp@su-ai Subject: EXPORT after USE Message-Id: <24May83.153655.DD60@CMU-CS-A> Received: from CMU-CS-PT by CMU-CS-A; 24-May-83 12:23:13-EDT It is really not clear to me why the effects of EXPORT after USE have to be the same in all common lisp implementations. It is not hard to imagine debugging tools that can track down and help resolve symbol conflicts caused by this in various ways for various implementations. The proposed scheme is not the only way to do this. I'm not complaining about this because I want to implement a "copy" system in Spice Lisp. It just seems to me that there is a natural division between a common subset of the current proposal requiring that all symbols be exported before the package is used, and the wizard-level hacking necessary during development, which can be implementation-dependent (it is clearly not going to be possible to move code to another dialect of common lisp when it would take two or three weeks to rebuild it from sources). This seems to be consistent with the principles just applied to the error system revisions. -Dave  Received: from MIT-MC by SU-AI with TCP/SMTP; 24 May 83 14:26:58 PDT Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Tue 24-May-83 16:30:15-EDT Date: Tuesday, 24 May 1983, 16:28-EDT From: David A. Moon Subject: maphash and do-hash To: common-lisp@su-ai In-reply-to: The message of 24 May 83 01:31-EDT from Scott E. Fahlman Well, we can certainly implement either maphash or do-hash or both with no problems. So we'll wait and see what's in the manual.  Received: from MIT-MC by SU-AI with TCP/SMTP; 24 May 83 13:08:50 PDT Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Tue 24-May-83 15:24:16-EDT Date: Tuesday, 24 May 1983, 15:21-EDT From: David A. Moon Subject: One last diddle to my error proposal To: Scott E. Fahlman Cc: David A. Moon , common-lisp@su-ai In-reply-to: The message of 24 May 83 12:09-EDT from Scott E. Fahlman Date: Tue, 24 May 1983 12:09 EDT From: Scott E. Fahlman I don't feel passionately about this switch, [switch of the order of the first two arguments to CERROR] but to me it seems much more intuitive to have the "error message" string come before the "and if you proceed" string. They will presumably appear in the original order in the error dialogue. I bet if we switch it, lots of users will get burned the first few times they use it. This could be a problem, and indeed that's the reasoning I followed originally that caused me to put the continue-message string first. On the other hand, since it's called "C ERROR" the "C" part should come before the "ERROR" part. We can't win. You don't say why you want to make the switch -- just so it looks more like ERROR if you cover up the function name and the first arg? Exactly. Now, the reason why that is important will not appear until Common Lisp has conditions. I'm not going to send out a proposal for conditions until after the first edition of the manual is out, to avoid distraction from more important things. But I'm thinking about it a little.  Received: from MIT-MC by SU-AI with TCP/SMTP; 24 May 83 13:15:18 PDT Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Tue 24-May-83 15:24:16-EDT Date: Tuesday, 24 May 1983, 15:21-EDT From: David A. Moon Subject: One last diddle to my error proposal To: Scott E. Fahlman Cc: David A. Moon , common-lisp@su-ai In-reply-to: The message of 24 May 83 12:09-EDT from Scott E. Fahlman Date: Tue, 24 May 1983 12:09 EDT From: Scott E. Fahlman I don't feel passionately about this switch, [switch of the order of the first two arguments to CERROR] but to me it seems much more intuitive to have the "error message" string come before the "and if you proceed" string. They will presumably appear in the original order in the error dialogue. I bet if we switch it, lots of users will get burned the first few times they use it. This could be a problem, and indeed that's the reasoning I followed originally that caused me to put the continue-message string first. On the other hand, since it's called "C ERROR" the "C" part should come before the "ERROR" part. We can't win. You don't say why you want to make the switch -- just so it looks more like ERROR if you cover up the function name and the first arg? Exactly. Now, the reason why that is important will not appear until Common Lisp has conditions. I'm not going to send out a proposal for conditions until after the first edition of the manual is out, to avoid distraction from more important things. But I'm thinking about it a little.  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 24 May 83 09:10:03 PDT Received: ID ; 24 May 83 12:09:46 EDT Date: Tue, 24 May 1983 12:09 EDT From: Scott E. Fahlman To: David A. Moon Cc: common-lisp@su-ai Subject: One last diddle to my error proposal In-reply-to: Msg of 24 May 1983 02:47-EDT from David A. Moon I don't feel passionately about this switch, but to me it seems much more intuitive to have the "error message" string come before the "and if you proceed" string. They will presumably appear in the original order in the error dialogue. I bet if we switch it, lots of users will get burned the first few times they use it. You don't say why you want to make the switch -- just so it looks more like ERROR if you cover up the function name and the first arg? -- Scott  Received: from SU-DSN by SU-AI with PUP; 23-May-83 23:47 PDT Received: From MIT-XX by SU-DSN.ARPA; Mon May 23 23:49:22 1983 Received: from SCRC-EUPHRATES by SCRC-SPANIEL with CHAOS; Tue 24-May-83 02:47:27-EDT Date: Tuesday, 24 May 1983, 02:47-EDT From: David A. Moon Subject: One last diddle to my error proposal To: common-lisp at su-ai I want to interchange the first two arguments to CERROR, so that the description of what happens when you continue (or rather the FORMAT string that builds that description) comes first, and then the rest of the arguments are just like the arguments to ERROR. Any problems with this?  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 23 May 83 23:04:18 PDT Received: ID ; 24 May 83 02:04:44 EDT Date: Tue, 24 May 1983 02:04 EDT From: Scott E. Fahlman To: BENSON%SPA-NIMBUS@mit-mc Cc: Common-Lisp@SU-AI Subject: Return of the Packages Strikes Back In-reply-to: Msg of 23 May 1983 16:39-PDT from BENSON at SPA-NIMBUS I tried to answer this earlier, but SPA-NIMBUS is not a real host, and our local mailer cleverly puts such messages into the dumpster. What is "SPA" anyway? Moon is right: the package name description means what it says about cases, and not what you imagine it is trying to say. I'll put in some phrase about "unlike the way case is handled in symbols" to emphasize this. -- Scott  Received: from SU-DSN by SU-AI with PUP; 23-May-83 22:31 PDT Received: From CMU-CS-C by SU-DSN.ARPA; Mon May 23 22:33:18 1983 Received: ID ; 24 May 83 01:31:20 EDT Date: Tue, 24 May 1983 01:31 EDT From: Scott E. Fahlman To: David A. Moon Cc: common-lisp%su-ai@SU-DSN Subject: Maphash In-reply-to: Msg of 23 May 1983 23:35-EDT from David A. Moon Well, if we assume an implementation in which the lexical-binding problems have been solved (as we must in these discussions, I guess) I must admit that both forms look about equally "elegant", since they are nearly identical. I have three reasons for preferring the DO form: 1. A lingering feeling that MAP forms are flaky and are generally to be avoided, probably left over from the days in which the binding issues were not worked out. So this is not terribly rational, but it's still a pretty strong aversion with me. 2. A lingering feeling that MAP forms are inherently less efficient, since they require an extra function call. Of course, a sufficiently wily compiler could eliminate this call, but I bet that the inefficiency will be showing up in a lot of implementations for some time to come. 3. Perhaps strongest: the observation that we have gone to DO-SYMBOL, etc., and that we should try to use the same style everywhere. (I hope that this will not lead to the counter-proposal that we should go to MAP-forms everywhere, but I probably hope in vain.) I guess I'm not adamant about this, but for the reasons listed above I would prefer the DO-HASH form. -- Scott  Received: from MIT-MC by SU-AI with TCP/SMTP; 23 May 83 20:46:59 PDT Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Mon 23-May-83 23:38:50-EDT Date: Monday, 23 May 1983, 23:35-EDT From: David A. Moon Subject: Maphash To: Scott E. Fahlman Cc: common-lisp@su-ai In-reply-to: The message of 19 May 83 00:23-EDT from Scott E. Fahlman Date: Thu, 19 May 1983 00:23 EDT From: Scott E. Fahlman Since MAPHASH returns NIL, there is no elegant way to turn the contents of a hashtable into a list. What would people think of flushing MAPHASH and replacing it with DO-HASH ? Is (defun hash-table-to-alist (ht) (let ((alist nil)) (do-hash ((key value) ht) (push (cons key value) alist)) alist)) more elegant than (defun hash-table-to-alist (ht) (let ((alist nil)) (maphash #'(lambda (key value) (push (cons key value) alist)) ht) alist)) ? You aren't allowed to base your decision on the fact that both your CL implementation and my CL implementation are currently in violation of the standard, such that the latter version doesn't work unless alist is declared special. You also aren't allowed to base your decision on the fact that the best way to do this operation is with LOOP.  Received: from MIT-MC by SU-AI with TCP/SMTP; 23 May 83 17:13:51 PDT Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Mon 23-May-83 20:16:57-EDT Date: Monday, 23 May 1983, 20:14-EDT From: David A. Moon Subject: EXPORT after USE-PACKAGE To: common-lisp@su-ai In-reply-to: <23May83.192214.DD60@CMU-CS-A> Date: 23 May 1983 1922-EDT (Monday) From: David.Dill@CMU-CS-A (L170DD60) I have been operating under the assumption that the only legitimate reason to do this is during debugging or development, to recover from a mistake in setting up a package or to "remove the back" from a package in order to poke around inside conveniently. Does everyone else believe this (Moon in particular)? Yes. Also to alter a package that has already been created in a suspended environment, when it would be too expensive to re-create the suspended environment from the ground up. The terminal behind my back is connected to a machine containing such an environment that was made more than six months ago and would take a couple of weeks effort to reconstruct. If this is the case, then saying so in the manual could simplify some of the explanations of lookup rules, and also allow more flexibility in individual implementations (e.g. copy vs. search rules). But it's important that no matter how it is implemented, and no matter whether it is fast or slow, it works. If the implementation has a separate hash table for every package, and USE-PACKAGE makes entries in that hash table, so that INTERN never does more than one hash lookup, then EXPORT must make multiple hash insertions--one in every package on the package-used-by list, except for those that shadow.  Received: from MIT-MC by SU-AI with TCP/SMTP; 23 May 83 17:12:39 PDT Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Mon 23-May-83 20:11:36-EDT Date: Monday, 23 May 1983, 20:08-EDT From: David A. Moon Subject: Alphabetic case in package names To: BENSON%SPA-NIMBUS%MIT-MC@SU-DSN Cc: Common-Lisp@SU-AI In-reply-to: The message of 23 May 83 19:39-EDT from BENSON at SPA-NIMBUS Date: Monday, 23 May 1983, 16:39-PDT From: BENSON at SPA-NIMBUS ...Instead, I suggest leaving out any mention of retention of case, since the same issues apply here as in the case of symbols. Not so. Symbols are created implicitly, on first reference. Packages are created explicitly, with MAKE-PACKAGE (or whatever it's called now). Except this isn't completely true, since if you use IN-PACKAGE (or whatever it's called now) you don't know whether you are creating a package or adding to an existing package. Also, for historical reasons, and perhaps even good reasons, you are allowed to have distinct symbols A and |a|. I see no good reason to allow anything of the sort for packages. Presumably the intention is that the casification of the "name" argument to MAKE-PACKAGE and IN-PACKAGE is remembered the first time it is seen, and given back to you by PACKAGE-NAME, by the printed representation of the package, when the package appears as a prefix in a qualified name, and by whatever user-interface things talk about packages (they get it from PACKAGE-NAME). It may turn out that in practice it looks better for the casification of package prefixes in qualified names to be controlled by *PRINCASE* rather than to reflect the way it was originally written.  Received: from SU-DSN by SU-AI with PUP; 23-May-83 16:39 PDT Received: From MIT-XX by SU-DSN.ARPA; Mon May 23 16:40:39 1983 Date: Monday, 23 May 1983, 16:39-PDT From: BENSON at SPA-NIMBUS Subject: Return of the Packages Strikes Back To: Fahlman at CmuC Cc: Common-Lisp at SU-AI The latest package.mss looks great. I hate to be late with this, but there is one very minor clarification that should go in. In the section "Package Names" there is a sentence that reads: Package name strings retain whatever mixture of upper and lower case characters the user supplies, but the translation from names to packages is case- insensitive, so users can generally refer to packages without worrying about case. The meaning of "retain" in this context is not entirely clear. Clearly it must refer to the string returned by PACKAGE-NAME; that's the only way to get a string back from a package. That should be stated explicitly. Instead, I suggest leaving out any mention of retention of case, since the same issues apply here as in the case of symbols. Is the case retained that of the string given when the package was created, or that of the last call to FIND-PACKAGE? How does this affect printing? If anything, it should be stated that the string returned by PACKAGE-NAME is always upper case, to match the treatment of symbols by READ. Of course, FIND-PACKAGE is really analogous to INTERN, which is sensitive to case... As long as we're on the subject, the printing process for package prefixes should be described, probably in the Input and Output chapter. I guess what's expected is that package prefixes get printed "like" symbols, w.r.t. slashifying special characters and the effect of *PRINCASE*, except perhaps it's impossible to "really" have a lower case character in a package name like in a symbol. Just when you thought it was safe to go back in the water...  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 23 May 83 16:23:13 PDT Date: 23 May 1983 1922-EDT (Monday) From: David.Dill@CMU-CS-A (L170DD60) To: common-lisp@su-ai Subject: EXPORT after USE-PACKAGE Message-Id: <23May83.192214.DD60@CMU-CS-A> It seems to me that the issue that has caused the most grief, directly or indirectly, in the design of the package system has been what to do when a package decides to change its export list after it has been used by another package. I have been operating under the assumption that the only legitimate reason to do this is during debugging or development, to recover from a mistake in setting up a package or to "remove the back" from a package in order to poke around inside conveniently. Does everyone else believe this (Moon in particular)? If this is the case, then saying so in the manual could simplify some of the explanations of lookup rules, and also allow more flexibility in individual implementations (e.g. copy vs. search rules).  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 22 May 83 15:07:34 PDT Received: ID ; 22 May 83 18:08:15 EDT Date: Sun, 22 May 1983 18:08 EDT From: Scott E. Fahlman To: common-lisp@su-ai Subject: Last call for nits I have changed the language of the package proposal slightly to incorporate most of KMP's suggestions on wording. None of this changes anything substantive in the proposal. I will spare the ARPANET mail servers another moby transmission of the whole thing -- if anyone wants to look at the changes, they're on CMUC as package.mss. The latest proposal has been out almost a week and nobody has complained about anything substantive. If I hear no objections within the next 24 hours, I will turn this over to Guy for inclusion in the manual (once he has converted it to a stylistically consistent form) and we can chalk up one more small victory for Federalism. Though I was a bit overwhelmed by the volume of criticism that came in, I think that the discussion was a healthy one and that the result is a much better package system than we would have had without this process. Thanks to all who participated. -- Scott  Received: from MIT-MC by SU-AI with TCP/SMTP; 19 May 83 14:57:29 PDT Date: Thursday, 19 May 1983, 18:00-EDT From: Kent M. Pitman Subject: Comments on wording in "Revenge of the Packages" To: Fahlman at CMUC Cc: Common-Lisp at SAIL These comments refer only to wording that I think should be cleared up; not to semantic problems in the spec. I think that A symbol that is uninterned (has no home package) is printed preceded by ``@b[#:]''. It is possible, by the clever use of import and unintern, to create a symbol that has no recorded home package, but that in fact is interned in some package. The system does not check for this. would be far less confusing as If the symbol's home package is NIL, it will be printed preceded by ``@b[#:]''. Uninterned symbols, such as those created by GENSYM, are the most common example. It may be possible through `clever' combinations of @b[import] and @b[unintern] to create a symbol which has no recorded home package, but which is in fact interned in some package; for efficiency reasons, this pathological case is not checked for, and such symbols will also be printed preceded by ``@b[#:]''. I think we should try to avoid statements which if read out of context will have strong implications that are not strictly true. Also, your descriptions of the syntaxes should take one of two moods, but not be split. Either you should describe why a symbol prints a certain way, or you should describe what the reader does when it encounters a certain symbol, or both separately, but not both mixed together as you do in: @b[foo:bar] @\Look up "bar" among the external symbols available in the package named "foo". @b[foo#:bar] @\Look up "bar" among the external and internal symbols available in the package named "foo". @b[:bar] @\The symbol named "bar" is a self-evaluating keyword. @b[#:bar] @\The symbol named "bar" is uninterned. I would suggest either describing the meaning of a symbol printing a certain way, as in: @b[foo:bar] @\The symbol "bar" is among the external symbols available in the package named "foo". @b[foo#:bar] @\The symbol "bar" has a home package of "foo", but is not an exported symbol of that package. @b[:bar] @\The symbol named "bar" is on the keyword package. @b[#:bar] @\The symbol named "bar" has no home package information. or the meaning to the reader of the given syntaxes, as in: @b[foo:bar] @\Expect to find an external symbol named "bar" in the "foo" package and use that. @b[foo#:bar] @\If there is a symbol "bar" on the "foo" package, whether external or not, use that. If there is no such symbol, create one and use it. @b[:bar] @\If there is an external symbol on the keyword package named "bar", use it. Otherwise, create such a symbol (binding it to itself), and use that. @b[#:bar] @\Create a symbol named "bar" but do not intern it on any package. or some such. --kmp