Date: 9 November 1982 0245-EST (Tuesday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: Remarks on mini-ballot So far, the vote looks like it favors Lisp-Machine-style function specs if any, and no asterisks around names of constants. If it will set anyone's mind at rest about constants, the compiler can detect accidental attempts to bind a constant locally and warn you, but obviously can't do that for variables that are meant to be bound. Thus, from a robustness point of view, it is important to flag variables visually, but less so to flag constants. As for runction specs, I find persuasive the remark that if (DEFUN (GET FOO BAR) ...) => (SETF (GET FOO BAR) ...) then (DEFUN FOO ...) => (SETF FOO ...) but the latter isn't right. I formerly favored SETF-style function specs, but now see how wrong-headed I was. However, the analogy above also indicates to me that function specs like (:PROPERTY FOO BAR) really are a kind of generalized name for a function. If so, orthogonality demands that they be permissible in a lot of places where currently I believe they are not in Lisp Machine LISP: (a) In FUNCTION: #'(:PROPERTY FOO BAR) ought to be legal. (b) As an argument to APPLY: (APPLY '(:PROPERTY FOO BAR) args). (c) In ordinary function calls! ((:PROPERTY FOO BAR) 5 7 :START 3 :END 5) --Guy  Date: 9 November 1982 0245-EST (Tuesday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: Remarks on mini-ballot So far, the vote looks like it favors Lisp-Machine-style function specs if any, and no asterisks around names of constants. If it will set anyone's mind at rest about constants, the compiler can detect accidental attempts to bind a constant locally and warn you, but obviously can't do that for variables that are meant to be bound. Thus, from a robustness point of view, it is important to flag variables visually, but less so to flag constants. As for runction specs, I find persuasive the remark that if (DEFUN (GET FOO BAR) ...) => (SETF (GET FOO BAR) ...) then (DEFUN FOO ...) => (SETF FOO ...) but the latter isn't right. I formerly favored SETF-style function specs, but now see how wrong-headed I was. However, the analogy above also indicates to me that function specs like (:PROPERTY FOO BAR) really are a kind of generalized name for a function. If so, orthogonality demands that they be permissible in a lot of places where currently I believe they are not in Lisp Machine LISP: (a) In FUNCTION: #'(:PROPERTY FOO BAR) ought to be legal. (b) As an argument to APPLY: (APPLY '(:PROPERTY FOO BAR) args). (c) In ordinary function calls! ((:PROPERTY FOO BAR) 5 7 :START 3 :END 5) --Guy  Date: 9 Nov 1982 0152-EST From: HEDRICK at RUTGERS (Mgr DEC-20s/Dir LCSR Comp Facility) Subject: Re: function specs To: MOON at SCRC-TENEX at MIT-MC cc: common-lisp at SU-AI In-Reply-To: Your message of 8-Nov-82 2121-EST I am perfectly willing to go with options A or B for DEFUN. They seem equally undesireable syntax. However I would like to have someone define what the construct for MACRO's, FEXPR's (if Common Lisp has such things), and any other odd things that DEFUN can generate. If it is not possible to do that, then I think we would be better off using (PUTPROP 'FOO 'BAR '#(LAMBDA ... Furthermore, I would like to request that the this definition include a specification of the actual data structure to be used for interpreted functions. There are two good reasons for this: - One good thing about Lisp is supposed to be that programs can manipulate code, it seems bad to have functional objects (except for compiled code and possibly FUNARG's) be system-dependent. (The traditional representation is, of course, LAMBDA expressions.) - It is one thing to hide the representation used by (DEFUN FOO, since the user can't directly access function definitions (unless he happens to know that EXPR properties are used in his implementation). However by definition (DEFUN (:PROPERTY FOO BAR) .. is creating a user-visible data structure. It would be a good practice to define what that data structure is. Clearly in some cases (compiled code) it is not reasonable to do so, but for interpreted code I claim it is. I think that in meeting this request you will find it necessary to define either an MLAMBDA (a lambda for macro's) or a syntax like either (LAMBDA (%MACRO L)... or (MACRO LAMBDA (L) .... and the equivalent for FEXPR's, etc. (if they exist). This is the reason why I expessed some scepticism about the construct initially. -------  Date: 9 Nov 1982 0152-EST From: HEDRICK at RUTGERS (Mgr DEC-20s/Dir LCSR Comp Facility) Subject: Re: function specs To: MOON at SCRC-TENEX at MIT-MC cc: common-lisp at SU-AI In-Reply-To: Your message of 8-Nov-82 2121-EST I am perfectly willing to go with options A or B for DEFUN. They seem equally undesireable syntax. However I would like to have someone define what the construct for MACRO's, FEXPR's (if Common Lisp has such things), and any other odd things that DEFUN can generate. If it is not possible to do that, then I think we would be better off using (PUTPROP 'FOO 'BAR '#(LAMBDA ... Furthermore, I would like to request that the this definition include a specification of the actual data structure to be used for interpreted functions. There are two good reasons for this: - One good thing about Lisp is supposed to be that programs can manipulate code, it seems bad to have functional objects (except for compiled code and possibly FUNARG's) be system-dependent. (The traditional representation is, of course, LAMBDA expressions.) - It is one thing to hide the representation used by (DEFUN FOO, since the user can't directly access function definitions (unless he happens to know that EXPR properties are used in his implementation). However by definition (DEFUN (:PROPERTY FOO BAR) .. is creating a user-visible data structure. It would be a good practice to define what that data structure is. Clearly in some cases (compiled code) it is not reasonable to do so, but for interpreted code I claim it is. I think that in meeting this request you will find it necessary to define either an MLAMBDA (a lambda for macro's) or a syntax like either (LAMBDA (%MACRO L)... or (MACRO LAMBDA (L) .... and the equivalent for FEXPR's, etc. (if they exist). This is the reason why I expessed some scepticism about the construct initially. -------  Date: 8 November 1982 23:49-EST From: Glenn S. Burke Subject: Mini-ballot To: Guy.Steele at CMU-10A cc: common-lisp at SU-AI (1) A. (2) Mostly i just want a decision made on this. My feelings are, approximately in decreasing order of strength: Specials should be textually distinguishable from non-specials; this significantly helps the case of a user blundering into a system variable (or worse, constant) just by using it as a LOCAL variable; this problem is much more common than "redefining" it with DEFVAR. Those which are constants should be textually distinguishable from those which are parameters. I've gotten rather accustomed to the "*" package of NIL in this regard. Using SYS: simply limits the scope of naming conflicts (as above) to those things which inherit from SYS by default (depending on how such things work of course). I could see SYS:*MOST-POSITIVE-SINGLE-FLOAT* though, for something (parameter or constant) which is system-dependent. Lastly, i feel rather badly about breaking the Maclisp system parameters like BASE, IBASE, *NOPOINT, PRINLEVEL, etc. It was only the possibility that these would break anyway which has kept me from dyking out SI:STANDARD-INPUT-RADIX and SI:STANDARD-OUTPUT-RADIX from NIL and reinstalling IBASE and BASE.  Date: Monday, 8 November 1982 23:05-EST From: Scott E. Fahlman To: common-lisp at SU-AI Subject: Revised Mini-Ballot I find KMP's arguments against option B to be fairly convincing. It does not bother me much to have symbols be a special case, but the business about quoting is serious. I also believe that the function specs should be statically analyzable, so we would have to constrain the SETF forms to be compile-time constant, and that is pretty ugly. There is also the problem, mentioned by someone earlier, that the SETF form makes the user see a level of implementation detail that the function-spec proposal hides, namely where the function object really goes. C has two disadvantages: first, it does not provide for the common case of wanting to store a compiled function under a property; second, it will give rise to all sorts of incompatible ad hoc solutions. So that leaves A. Things like (defun (:property foo bar) ...) actually look pretty good to me -- the intent is clear -- and it makes sense for trace and friends to accept these forms. I still resist the notion that these are names, but that is just an issue of how they are explained, not what the mechanism is. I guess it also makes sense to make this facility extensible, and for that we need something like the set of machinery that Moon proposes. (This extension stuff should be documented in such a way that our canonical naive user understands that he can safely ignore it.) Of the pre-defined types in the Chine Nual, we need only :PROPERTY and maybe :INTERNAL. :LOCATION is clearly out and :WITHIN and :METHOD should be extensions defined by non-white-pages packages. So, if it is kept as simple as possible and explained properly, I guess I am now prepared to believe that A is best way to go. (Moon is still wrong-headed and unacceptable, however -- that HAS to be the wrong head!) On the issue of asterisks for constants, I have decided that I really don't care at all, as long as the issue is settled quickly and decisively. I give Guy my proxy to choose between stars and no stars. I would not like to see a new character convention introduced just for constants, though. -- Scott  Date: Monday, 8 November 1982 21:16-EST From: MOON at SCRC-TENEX To: HEDRICK at RUTGERS (Mgr DEC-20s/Dir LCSR Comp Facility) Cc: common-lisp at SU-AI Subject: function specs In-reply-to: The message of 8 Nov 1982 1958-EST from HEDRICK at RUTGERS (Mgr DEC-20s/Dir LCSR Comp Facility) The issues you raise in your message, about system dependence of the representation of functions, are PRECISELY the reason why there should be function specs in the language, so that the user need not be aware of the representation of functions. Surely the :PROPERTY function spec must mean none other than "if you do a GET, you will get something you can APPLY and FUNCALL."  Date: Monday, 8 November 1982 21:16-EST From: MOON at SCRC-TENEX To: HEDRICK at RUTGERS (Mgr DEC-20s/Dir LCSR Comp Facility) Cc: common-lisp at SU-AI Subject: function specs In-reply-to: The message of 8 Nov 1982 1958-EST from HEDRICK at RUTGERS (Mgr DEC-20s/Dir LCSR Comp Facility) The issues you raise in your message, about system dependence of the representation of functions, are PRECISELY the reason why there should be function specs in the language, so that the user need not be aware of the representation of functions. Surely the :PROPERTY function spec must mean none other than "if you do a GET, you will get something you can APPLY and FUNCALL."  Date: Monday, 8 November 1982 21:40-EST From: MOON at SCRC-TENEX To: Scott E. Fahlman Cc: common-lisp at SU-AI Subject: asterisks around variables In-reply-to: The message of 8 Nov 1982 20:56-EST from Scott E. Fahlman Date: Monday, 8 November 1982 20:56-EST From: Scott E. Fahlman (2) To me, the purpose of the asterisks is to flag those variables that are "property of Lisp" so that the user doesn't accidentally blunder into them. Hmm, that's an interesting and novel idea. We handle that by having DEFVAR complain if you define the same variable in more than one file, and by using packages to decrease the likelihood of that. The asterisks are not there to distinguish the system's variables from the user's variables. My philosophy is "the fewer magic distinctions between the system and the user the better; anything the system can do the user should be able to understand and to change."  Date: 8 November 1982 20:54-EST From: Kent M. Pitman Subject: Mini-ballot To: Guy.Steele at CMU-10A cc: common-lisp at SU-AI (1) My experience with LispM function specs leads me to believe that something along these lines is worthwhile. I waver between saying "yes" to (c) because I am not firm on the details and it might be better to wait and (a) because I know it's a valuable tool and I've seen what happens when you don't have it. With regard to (b), I object rather strongly on the following counts: * I would prefer that they be statically analyzable. I can figure out at code analysis time (eg, compile time or at the time I'm reading someone else's code) what (DEFUN (GET 'FOO 'BAR) ...) means. And have a pretty good idea of what the code is trying to say. But if the person does (DEFUN (GET FOO BAR) ...), I can analyze this code only formally and have no good feeling for what it's going to do. I think definitional forms should try to stay simple and the programmer should write (SETF (GET FOO BAR) #'(LAMBDA ...)) in the few cases where he needs it. I would be uncomfortable with special-casing (ie, requiring) QUOTE in this kind of form, so restricting things to the (GET 'FOO 'BAR) case will not make me feel better. * If (DEFUN (GET 'FOO 'BAR) (X) X) means (SETF (GET 'FOO 'BAR) #'(LAMBDA (X) X)) then (DEFUN F (X) X) should mean (SETF F #'(LAMBDA (X) X)) and not (SETF #'F #'(LAMBDA (X) ...)). This incompatibility bothers me. I'd like to see a concrete proposal for exactly what LispM style stuff we'd put in before I vote for (a) over (c), however. A more conservative alternative is to go the Maclisp route and say that the useful case of DEFUN'ing properties can be done by (DEFUN (sym prop) bvl . body) and not go for either the function spec or the SETF approach for now until more thinking has been done. This syntax would be fairly easily upgraded later if people were encouraged to never use a sym which was on the keyword package in such a DEFUN so that later upgrading if desired could be done in an upward compatible fashion. This is preferable in my mind to HEDRICK's (DEFUN-PROP ...) proposal because it is not as verbose and it is upward compatible in a way that doesn't introduce arbitrarily many new operators. (2) I guess I buy the argument that constants oughtn't have *'s around them. Knowing by looking at a thing whether it's intended to be bound is certainly a useful property.  Date: 8 November 1982 20:53-EST From: Kent M. Pitman To: Benson at UTAH-20 cc: Common-Lisp at SU-AI In most current Lisp implementations, one cannot write (SETF (GET 'FOO 'BAR) #'(LAMBDA ...)) unless he doesn't mind #'(LAMBDA ...) not being compiled. Toplevel non-definitional forms are not compiled in Maclisp or LispM, for example. Hence, without the existence of (DEFUN (:PROPERTY FOO BAR) ...), one would have to write (DEFUN something ...) (SETF (GET 'FOO 'BAR) #'something) which is a bit tedious. I don't know if Common-Lisp has taken a stand on whether toplevel LAMBDAs like this one get compiled. Discussion came up about it before. It's related to the (PROGN 'COMPILE ...) issue and should probably be defined. I'm personally in favor of avoiding a (PROGN 'COMPILE ...) primitive and compiling all toplevel forms. In such case, the SETF you show would be technically correct, but it lacks the declarative appeal of being integrated into a DEFUN. The question, I guess, comes down to whether you think of what you're doing as defining a function with a complex name or creating an anonymous function and putting it in a complex place. I think there is need for both and the two issues should be kept separate.  Date: Monday, 8 November 1982 20:56-EST From: Scott E. Fahlman To: common-lisp at SU-AI Subject: Mini-ballot (1) (b) is the right thing. (c) is okay for now if we can't get agreement. (a) Still looks needlessly complex to me, though I could swallow it with a few simplifications and the elimination of the locative pointer business. (MOON) is wrong-headed and unacceptable. (2) To me, the purpose of the asterisks is to flag those variables that are "property of Lisp" so that the user doesn't accidentally blunder into them. I don't need to be reminded which things it makes sense to bind, once I see that the variable is part of the Lisp system, since that is obvious from the name of the variable. I could live with the opposite decision, to have no stars on Lisp constants, but would really hate to see them sprout additional syntax.  Date: 8 November 1982 20:54-EST From: Kent M. Pitman Subject: Mini-ballot To: Guy.Steele at CMU-10A cc: common-lisp at SU-AI (1) My experience with LispM function specs leads me to believe that something along these lines is worthwhile. I waver between saying "yes" to (c) because I am not firm on the details and it might be better to wait and (a) because I know it's a valuable tool and I've seen what happens when you don't have it. With regard to (b), I object rather strongly on the following counts: * I would prefer that they be statically analyzable. I can figure out at code analysis time (eg, compile time or at the time I'm reading someone else's code) what (DEFUN (GET 'FOO 'BAR) ...) means. And have a pretty good idea of what the code is trying to say. But if the person does (DEFUN (GET FOO BAR) ...), I can analyze this code only formally and have no good feeling for what it's going to do. I think definitional forms should try to stay simple and the programmer should write (SETF (GET FOO BAR) #'(LAMBDA ...)) in the few cases where he needs it. I would be uncomfortable with special-casing (ie, requiring) QUOTE in this kind of form, so restricting things to the (GET 'FOO 'BAR) case will not make me feel better. * If (DEFUN (GET 'FOO 'BAR) (X) X) means (SETF (GET 'FOO 'BAR) #'(LAMBDA (X) X)) then (DEFUN F (X) X) should mean (SETF F #'(LAMBDA (X) X)) and not (SETF #'F #'(LAMBDA (X) ...)). This incompatibility bothers me. I'd like to see a concrete proposal for exactly what LispM style stuff we'd put in before I vote for (a) over (c), however. A more conservative alternative is to go the Maclisp route and say that the useful case of DEFUN'ing properties can be done by (DEFUN (sym prop) bvl . body) and not go for either the function spec or the SETF approach for now until more thinking has been done. This syntax would be fairly easily upgraded later if people were encouraged to never use a sym which was on the keyword package in such a DEFUN so that later upgrading if desired could be done in an upward compatible fashion. This is preferable in my mind to HEDRICK's (DEFUN-PROP ...) proposal because it is not as verbose and it is upward compatible in a way that doesn't introduce arbitrarily many new operators. (2) I guess I buy the argument that constants oughtn't have *'s around them. Knowing by looking at a thing whether it's intended to be bound is certainly a useful property.  Date: 8 November 1982 20:53-EST From: Kent M. Pitman To: Benson at UTAH-20 cc: Common-Lisp at SU-AI In most current Lisp implementations, one cannot write (SETF (GET 'FOO 'BAR) #'(LAMBDA ...)) unless he doesn't mind #'(LAMBDA ...) not being compiled. Toplevel non-definitional forms are not compiled in Maclisp or LispM, for example. Hence, without the existence of (DEFUN (:PROPERTY FOO BAR) ...), one would have to write (DEFUN something ...) (SETF (GET 'FOO 'BAR) #'something) which is a bit tedious. I don't know if Common-Lisp has taken a stand on whether toplevel LAMBDAs like this one get compiled. Discussion came up about it before. It's related to the (PROGN 'COMPILE ...) issue and should probably be defined. I'm personally in favor of avoiding a (PROGN 'COMPILE ...) primitive and compiling all toplevel forms. In such case, the SETF you show would be technically correct, but it lacks the declarative appeal of being integrated into a DEFUN. The question, I guess, comes down to whether you think of what you're doing as defining a function with a complex name or creating an anonymous function and putting it in a complex place. I think there is need for both and the two issues should be kept separate.  Date: Monday, 8 November 1982 20:39-EST Sender: ZVONA at MIT-OZ From: ZVONA at MIT-MC To: Eric Benson Cc: common-lisp at SU-AI, Guy.Steele at CMU-10A Subject: Mini-ballot In-reply-to: The message of 8 Nov 1982 20:10-EST from Eric Benson Date: Monday, 8 November 1982 20:10-EST From: Eric Benson To: Guy.Steele at CMU-10A, common-lisp at SU-AI Re: Mini-ballot (1) It should not be necessary to extend DEFUN in this manner. (SETF (GET 'FOO 'BAR) #'(LAMBDA ...)) should do exactly what you want. Is there a problem with this? You might as well say that DEFUN should be flushed in favor of (SETF (FSYMEVAL 'FOO) #'(LAMBDA ...)) I like the SETF proposal 1(b). It decreases the amount of syntactic hair in the language and SETF seems to do exactly what is needed. Since all my friends dislike it, I must be missing something.  Date: 8 November 1982 20:43-EST From: Earl A. Killian Subject: Mini-ballot To: MOON at SCRC-TENEX cc: common-lisp at SU-AI Date: Monday, 8 November 1982 18:10-EST From: MOON at SCRC-TENEX (1) (a) is the right thing. (c) is okay for now if we can't get agreement. (b) is wrong-headed and unacceptable. This isn't very helpful without an explanation. It may be that adding a new mechanism for something (a) instead of using an old one (b) is right, but since no one has given any motivation for doing so, I am unsure what's right about it.  Date: 8 Nov 1982 1810-MST From: Eric Benson Subject: Re: Mini-ballot To: Guy.Steele at CMU-10A, common-lisp at SU-AI In-Reply-To: Your message of 8-Nov-82 1449-MST (1) It should not be necessary to extend DEFUN in this manner. (SETF (GET 'FOO 'BAR) #'(LAMBDA ...)) should do exactly what you want. Is there a problem with this? -------  Date: 8 Nov 1982 1958-EST From: HEDRICK at RUTGERS (Mgr DEC-20s/Dir LCSR Comp Facility) Subject: Re: Mini-ballot To: Guy.Steele at CMU-10A cc: common-lisp at SU-AI In-Reply-To: Your message of 8-Nov-82 1649-EST 1) I think I want to vote 3. I would prefer a separate function, e.g. (DEFUN-PROP FOO BAR ...), if this is something we really want to support. However you ought to consider whether this can be done in a system-independent fashion. Presumably you don't define the way DEFUN is implemented. Thus you may use EXPR properties or function definition cells. So if I specify (:PROPERTY FOO BAR), what is the value? A LAMBDA form? Or possibly something to indicate whether it is EXPR or MACRO, e.g. (EXPR LAMBDA ...)? Unless you want to define the internal form of a function definition (which I would strongly oppose), the value is likely to be installation dependent. If so, then you had better define what it can be used for. Do you gurantee that we can always do (APPLY (GET 'FOO 'BAR) args)? (Not very good if the property is (EXPR LAMBDA ...)) It is one thing to hide the implementation of DEFUN. But it is not good to have a property whose exact form is undefined. Thus I recommend against considering this feature to be part of the white pages. 2) I vote for using a different special character for constants. I think somebody proposed # #. I consider it good programming practice to use a special character to begin all specials, even ones that the user defines, just so it is immediately obvious to anyone reading the code. In addition to that general consideration, it is helpful to emphasize that this is a system variable. At a minimum it prevents the user from choosing the same name himself... -------  Date: Monday, 8 November 1982 19:17-EST From: Skef Wholey To: Guy.Steele at CMU-10A CC: Common-Lisp at SU-AI Subject: Mini-ballot (A) for #1, the Lisp Machine function specs look OK to me. I am attracted to the use of *'s because they emphasize the important events of binding and refering to dynamic variables. This emphasis would be lost if system constants were named in a like manner. The convention is one that is certainly worth imitating in user code, as a matter of style. Constants should not be named with the * convention for the reason that their values ARE constant -- no one is likely to clobber them. Surrounding a name with *'s makes it possible to determine at a glance whether someone could be clobbering a variable of yours, or whether you could be tweaking something you shouldn't. --Skef  Date: Monday, 8 November 1982 18:10-EST From: MOON at SCRC-TENEX To: Guy.Steele at CMU-10A Cc: common-lisp at SU-AI Subject: Mini-ballot In-reply-to: The message of 8 Nov 1982 1649-EST () from Guy.Steele at CMU-10A (1) (a) is the right thing. (c) is okay for now if we can't get agreement. (b) is wrong-headed and unacceptable. (2) I do not feel strongly that constants should not have asterisks, but I would prefer that they don't so that there is a visual distinction between constants and variables. Sometimes it is hard to decide what it is a constant and what it is a variable, but the Common-Lisp defined constants such as PI would be better without asterisks. We could consider a prefix convention for the system-dependent constants such as MOST-POSITIVE-SINGLE-FLOAT. I would prefer a package prefix such as SYS: over the Lisp machine's % or NIL's *: for these. No prefix would also be okay.  Date: 8 November 1982 1649-EST (Monday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: Mini-ballot Here are a few questions that I would like to have answers back on *** no later than Wednesday evening, November 10 ***. (1) On the question of function-specs (for things like like being able to DEFUN a function directly onto a property): Shall we adopt: (a) LISP Machine's style of function specs Example: (DEFUN (:PROPERTY FOO BAR) ...) (b) SETF-style function specs Example: (DEFUN (GET 'FOO 'BAR) ...) (c) No function specs ? (2) This is a repetition of issue 11 on the October ballot. On issue 10 we agreed that global variables shall by convention have names that begin and end with an asterisk (for example, *prinlevel*). Issue 11 was the same question for constants, and the results were less conclusive, with myself, Moon, Wholey, and Dyer being the prime opposition to using asterisks. There is a question as to whether the asterisks are meant to mean "this is global" or "this is bindable". Fahlman points out that when referring to a global object he doesn't want to have to remember whether it is bindable or not. My main objection to surrounding names of constants with asterisks is that T and NIL would obviously have to be exceptions to the rule, and secondarily that I prefer to make the distinction between variables and constants in a visual manner. Anyway, I'd like to get further feedback on this. --Guy  Date: 8 November 1982 1649-EST (Monday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: Mini-ballot Here are a few questions that I would like to have answers back on *** no later than Wednesday evening, November 10 ***. (1) On the question of function-specs (for things like like being able to DEFUN a function directly onto a property): Shall we adopt: (a) LISP Machine's style of function specs Example: (DEFUN (:PROPERTY FOO BAR) ...) (b) SETF-style function specs Example: (DEFUN (GET 'FOO 'BAR) ...) (c) No function specs ? (2) This is a repetition of issue 11 on the October ballot. On issue 10 we agreed that global variables shall by convention have names that begin and end with an asterisk (for example, *prinlevel*). Issue 11 was the same question for constants, and the results were less conclusive, with myself, Moon, Wholey, and Dyer being the prime opposition to using asterisks. There is a question as to whether the asterisks are meant to mean "this is global" or "this is bindable". Fahlman points out that when referring to a global object he doesn't want to have to remember whether it is bindable or not. My main objection to surrounding names of constants with asterisks is that T and NIL would obviously have to be exceptions to the rule, and secondarily that I prefer to make the distinction between variables and constants in a visual manner. Anyway, I'd like to get further feedback on this. --Guy  Date: 8 November 1982 1649-EST (Monday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: Mini-ballot Here are a few questions that I would like to have answers back on *** no later than Wednesday evening, November 10 ***. (1) On the question of function-specs (for things like like being able to DEFUN a function directly onto a property): Shall we adopt: (a) LISP Machine's style of function specs Example: (DEFUN (:PROPERTY FOO BAR) ...) (b) SETF-style function specs Example: (DEFUN (GET 'FOO 'BAR) ...) (c) No function specs ? (2) This is a repetition of issue 11 on the October ballot. On issue 10 we agreed that global variables shall by convention have names that begin and end with an asterisk (for example, *prinlevel*). Issue 11 was the same question for constants, and the results were less conclusive, with myself, Moon, Wholey, and Dyer being the prime opposition to using asterisks. There is a question as to whether the asterisks are meant to mean "this is global" or "this is bindable". Fahlman points out that when referring to a global object he doesn't want to have to remember whether it is bindable or not. My main objection to surrounding names of constants with asterisks is that T and NIL would obviously have to be exceptions to the rule, and secondarily that I prefer to make the distinction between variables and constants in a visual manner. Anyway, I'd like to get further feedback on this. --Guy  Date: Saturday, 6 November 1982 16:12-EST From: Scott E. Fahlman To: Daniel L. Weinreb Cc: common-lisp at SU-AI Subject: Destructuring I believe that there are currently no destructuring operations in the white pages, though implementations are free to add these as non-standard extensions (or to retain what they already have, if it is consistent with the current white pages). I think that the opposition to destructuring in existing forms such as LAMBDA and LET was (and is) both strong and deep-rooted. Most of the opponents would go along with adding a few new forms that do destructuring (DLET or whatever), but these never got added. Suggestions along these lines might make it into next year's edition of the white pages, but it's too late for the current go-round, I think -- it would take us awhile to converge on exactly what destructuring should be used where. -- Scott  Date: Thursday, 4 November 1982, 10:59-EST From: Daniel L. Weinreb Subject: Destructuring To: common-lisp at su-ai Did Common Lisp ever make any desicions regarding destructuring? In particular, do any forms do any destructuring at all, and, if so, do they use the list-directed or evaluation-directed kind?  Date: Thursday, 4 November 1982, 10:59-EST From: Daniel L. Weinreb Subject: Destructuring To: common-lisp at su-ai Did Common Lisp ever make any desicions regarding destructuring? In particular, do any forms do any destructuring at all, and, if so, do they use the list-directed or evaluation-directed kind?  Date: Thursday, 4 November 1982, 10:59-EST From: Daniel L. Weinreb Subject: Destructuring To: common-lisp at su-ai Did Common Lisp ever make any desicions regarding destructuring? In particular, do any forms do any destructuring at all, and, if so, do they use the list-directed or evaluation-directed kind?  Date: Thursday, 4 November 1982, 10:59-EST From: Daniel L. Weinreb Subject: Destructuring To: common-lisp at su-ai Did Common Lisp ever make any desicions regarding destructuring? In particular, do any forms do any destructuring at all, and, if so, do they use the list-directed or evaluation-directed kind?  Date: Wednesday, 27 October 1982 10:03-EDT From: Scott E. Fahlman To: Guy.Steele at CMU-10A Cc: common-lisp at SU-AI Subject: Macros and TAGBODY tags Only if it expands into the whole TAGBODY. -- Scott  Date: 27 October 1982 04:35-EDT From: Kent M. Pitman Subject: No. Don't let macros expand into prog tags. To: Guy.Steele at CMU-10A cc: COMMON-LISP at SU-AI No. Macros shouldn't be able to expand to prog tags. An example hopefully suffices: (defmacro do-something-returning-*foo* (&rest ignore) ;dummy definition ; just return *foo* for now until we figure out how to implement the something '*foo*) (defun huh? () (prog () (do-something-returning-*foo*) ;supposedly for side-effect ...)) this PROG should not be able to be said to have a *FOO* tag. There are probably many macros that expand into symbols and macro writers should not have to take the odd context of a prog body expansion into account. note that this is not contradictory with the idea of letting macros expand into declare forms because we allow macros to expand only into declare forms or normal code, but never a mixture. so it's in the semantics of the macro already that it will be used in a declare position or it won't. macro writers will not be "surprised" by the context `declare-macros' expand in. the user will know he has such a macro and will use it right. this could be better worded but i'm tired. i hope what i'm saying is sufficiently obvious that clarification won't be needed. -kmp ps macros expanding into prog tags would also thwart people who wanted to implement interpreted go by just doing memq in the relevant prog bodies.  Date: Wednesday, 27 October 1982 04:18-EDT From: MOON at SCRC-TENEX to: common-lisp at SU-AI Subject: Macros and TAGBODY tags In-reply-to: The message of 27 Oct 1982 0308-EDT () from Guy.Steele at CMU-10A Date: 27 October 1982 0308-EDT (Wednesday) From: Guy.Steele at CMU-10A Shall it be permissible for a macro call to expand into a PROG tag? Absolutely not.  Date: Wednesday, 27 October 1982 04:15-EDT From: MOON at SCRC-TENEX To: Guy.Steele at CMU-10A Cc: common-lisp at SU-AI Subject: SCALE-FLOAT and friends In-reply-to: The message of 27 Oct 1982 0310-EDT () from Guy.Steele at CMU-10A Date: 27 October 1982 0310-EDT (Wednesday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: SCALE-FLOAT and friends It was my brain-damage that caused the specification of FLOAT-FRACTION as returning a number between 1/b (inclusive) and 1 (inclusive). The latter word obviously should have been "exclusive". Were both bounds inclusive, I would have mentioned the qualifier only once. I will make appropriate amends. I think you're wrong here. In some floating-point formats, 2's-complement for instance, the magnitude of the fraction can take on both endpoint values. Better to leave it inclusive than to require an implementation to put in special hair to avoid returning 1.  Date: 27 October 1982 0310-EDT (Wednesday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: SCALE-FLOAT and friends It was my brain-damage that caused the specification of FLOAT-FRACTION as returning a number between 1/b (inclusive) and 1 (inclusive). The latter word obviously should have been "exclusive". Were both bounds inclusive, I would have mentioned the qualifier only once. I will make appropriate amends. --Guy  Date: 27 October 1982 0308-EDT (Wednesday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: Macros and TAGBODY tags Shall it be permissible for a macro call to expand into a PROG tag? (This question arises because macro calls may now expand into declarations.) I am inclined to say no.  Date: 20 October 1982 20:40-EDT From: Earl A. Killian Subject: Proposed evaluator for Common LISP To: HEDRICK at RUTGERS cc: common-lisp at SU-AI I wasn't asking whether it was doable, but whether anyone was working on the Common Lisp design for debugging with lexical scoping. If you're familiar with an existing winning design, perhaps you should just submit it as a proposal.  Date: 20 Oct 1982 1959-EDT From: HEDRICK at RUTGERS (Mgr DEC-20s/Dir LCSR Comp Facility) Subject: Re: Proposed evaluator for Common LISP To: EAK at MIT-MC cc: STEELE at CMU-20C, common-lisp at SU-AI In-Reply-To: Your message of 20-Oct-82 1907-EDT Given proper functions to access scopes up the stack, it is just as easy to do a debugger for a lexical language as a dynamic language. We know this from personal experience, having done a lexically-bound UCI Lisp. Certainly some adaptation had to be done, but the results were just as good, and the code wasn't really much worse. -------  Date: 20 October 1982 19:07-EDT From: Earl A. Killian Subject: Proposed evaluator for Common LISP To: STEELE at CMU-20C cc: common-lisp at SU-AI Common Lisp has not yet, to my knowledge, addressed the problem of debugging. With lexical scoping, it is no longer possible to simply reference variables from a read-eval-print debugging loop, the standard el cheapo lisp debugger, unless something more is going on than your proposed evaluator is letting on. Has this been thought about yet? If so, what is being proposed? It would be nice if sufficient functionality were provided that *simple* portable debuggers could be written.  Date: 19 October 1982 15:14-EDT From: George J. Carrette To: common-lisp at SU-AI I was wondering..., could AREF and ASET be defined to work on hashtables? Right now we have at least three conventions defined for referencing an object via a key or index. We have "properties" working on symbols and conveniently defined for lists, then arrays, and now hashtables. (Am I leaving out anything? Alists?) Needing all of these for historical reasons or otherwise is ok, but it sure would be nice to have ONE fully generic way of accessing a "table," especially since other languages make it a point of providing such a thing. -gjc  Date: Monday, 18 October 1982, 16:20-EDT From: Daniel L. Weinreb Subject: STRING-OUT, LINE-OUT and READLINE To: Guy.Steele at CMU-10A, common-lisp at SU-AI In-reply-to: The message of 18 Oct 82 00:19-EDT from Guy.Steele at CMU-10A Yes, they should be renamed as you say.  Date: Monday, 18 October 1982, 02:01-EDT From: David A. Moon Subject: STRING-OUT -> WRITE-STRING, etc. To: Guy.Steele at CMU-10A Cc: common-lisp at SU-AI In-reply-to: The message of 18 Oct 82 00:19-EDT from Guy.Steele at CMU-10A We certainly must do this, or forfeit any claim to consistency. I guess it just got left off the ballot accidentally, since it was put in at the last minute at the most recent meeting. I was probably against it, too.  Date: 18 October 1982 0019-EDT (Monday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: STRING-OUT, LINE-OUT and READLINE How would people feel about renaming these to WRITE-STRING, WRITE-LINE, and READ-LINE? This is in line with other renamings such as WRITE-CHAR. --Guy  Date: 17 October 1982 1553-EDT (Sunday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: What can I say? - - - - Begin forwarded message - - - - Mail-From: ARPANET host MIT-MC received by CMU-10A at 16-Oct-82 23:47:31-EDT Date: Saturday, 16 October 1982 23:44-EDT From: MOON at SCRC-TENEX To: Guy.Steele at CMU-10A Subject: Re: Overconservatism in extensions In-reply-to: The message of 16 Oct 1982 1351-EDT () from The Great Quux at CMU-10A I presume your latest message was a typo for #1= (GARBAGEP #1#) right? - - - - End forwarded message - - - -  Date: 16 October 1982 1351-EDT (Saturday) From: The Great Quux at CMU-10A To: Alan Bawden Subject: Re: Overconservatism in extensions CC: common-lisp at SU-AI Sender: Guy.Steele at CMU-10A Reply-To: Guy.Steele at CMU-10A In-Reply-To: Alan Bawden's message of 16 Oct 82 02:01-EST Okay, how about: (GARBAGEP "(GARBAGEP \"I think GCD should accept complex numbers...\") => T") => T ? Now is everybody happy? --Quux  Date: 16 October 1982 1351-EDT (Saturday) From: The Great Quux at CMU-10A To: Alan Bawden Subject: Re: Overconservatism in extensions CC: common-lisp at SU-AI Sender: Guy.Steele at CMU-10A Reply-To: Guy.Steele at CMU-10A In-Reply-To: Alan Bawden's message of 16 Oct 82 02:01-EST Okay, how about: (GARBAGEP "(GARBAGEP \"I think GCD should accept complex numbers...\") => T") => T ? Now is everybody happy? --Quux  Date: 16 October 1982 03:01-EDT From: Alan Bawden Subject: Overconservatism in extensions To: Common-Lisp at SU-AI Date: 15 October 1982 1513-EDT (Friday) From: The Great Quux at CMU-10A Sender: Guy.Steele at CMU-10A Perhaps we need a predicate GARBAGEP that takes a string. For example, (GARBAGEP "I think GCD should accept complex numbers...") => T. NO! This is not a garbage string! GCD should certainly work on complex integers. It is completely consistent to extend GCD in this manner, and I certainly expected that we would. It's not even hard. Or is there some more subtle joke here that I don't understand? You'll pardon my confusion, but it seems equally plausible that this is a joke that I don't appreciate, or that Steele didn't think too hard about an example of a braindamaged idea.  Date: 15 October 1982 1513-EDT (Friday) From: The Great Quux at CMU-10A To: common-lisp at SU-AI Subject: Conservatism in extensions Sender: Guy.Steele at CMU-10A Reply-To: Guy.Steele at CMU-10A Perhaps we need a predicate GARBAGEP that takes a string. For example, (GARBAGEP "I think GCD should accept complex numbers...") => T. --Quux  Date: 15 October 1982 1516-EDT (Friday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: Tried Quux vindicated Hmm, I see... while REMAINDER and MOD are different in general, they agree on what is zero. But in the presence of IEEE floating-point arithmetic, perhaps (MOD -6.0 3.0) => 0.0 and (REMAINDER -6.0 3.0) => -0.0, so I think I just barely wiggle out of that one. It's a pretty flimsy argument. (Yes, I was very tired.)  Date: 15 October 1982 1516-EDT (Friday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: Tried Quux vindicated Hmm, I see... while REMAINDER and MOD are different in general, they agree on what is zero. But in the presence of IEEE floating-point arithmetic, perhaps (MOD -6.0 3.0) => 0.0 and (REMAINDER -6.0 3.0) => -0.0, so I think I just barely wiggle out of that one. It's a pretty flimsy argument. (Yes, I was very tired.)  Date: Friday, 15 October 1982, 04:50-EDT From: David A. Moon Subject: Here is a tired quux, I think To: Guy.Steele at CMU-10A Cc: common-lisp at SU-AI In-reply-to: The message of 15 Oct 82 00:40-EDT from Guy.Steele at CMU-10A Date: 15 October 1982 0040-EDT (Friday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: Here is a terrible idea, I think One advantage of making the user type (ZEROP (MOD ...)) is that it makes clear that he is doing that and not (ZEROP (REMAINDER ...)), which might also be a distinct useful operation. Did you really just say that?  Date: 15 October 1982 04:10-EDT From: Kent M. Pitman Subject: conservatism in extensions To: hedrick at RUTGERS cc: common-lisp at SU-AI i agree. we should be very skeptical of extending things when there is wide variety of opinion on the direction that extension should go. certainly at this phase, extensions of this class are not advisable at all. we can always later add such functionality in an upward-compatible way; it will be harder to go back on wrong decisions. right now, we need to get any hard issues ironed out that are needed to get initial implementations up and running. once people have played with implementations for a while and we get back feedback about actual use, then is the time to extend an operation...  Date: 15 Oct 1982 0218-EDT From: HEDRICK at RUTGERS To: common-lisp at SU-AI Subject: A bunch of lousy ideas Message-ID: <"MS10(2107)+GLXLIB1(1130)" 11863919900.50.19.85746 at RUTGERS> There is already enough of extending functions by adding extra arguments. ROUND that does division if you give it an extra argument, etc. I know this all sounds clever, and it even looks harmless when you first see it, since the old function does continue to work. But I think it is a lousy idea to make ROUND do division, to make SIGN do whatever it is that we agreed it would do, and to make EVENP do mod. This sounds too much like the classic kludges of the following sort: (IO-OP FOO-FLAG [COUNT]) if FOO-FLAG is true, this prints its argument if FOO-FLAG is false, it rewinds the nearest magtape the number of frames specified by the argument COUNT except if COUNT is non-numeric it is the name of the tape drive, and the number of frames to be rewound will be found in the global variable *FRAMES* I think we are better off having a one to one mapping between conceptual functions and names. --------  Date: 15 Oct 1982 0218-EDT From: HEDRICK at RUTGERS To: common-lisp at SU-AI Subject: A bunch of lousy ideas Message-ID: <"MS10(2107)+GLXLIB1(1130)" 11863919900.50.19.85746 at RUTGERS> There is already enough of extending functions by adding extra arguments. ROUND that does division if you give it an extra argument, etc. I know this all sounds clever, and it even looks harmless when you first see it, since the old function does continue to work. But I think it is a lousy idea to make ROUND do division, to make SIGN do whatever it is that we agreed it would do, and to make EVENP do mod. This sounds too much like the classic kludges of the following sort: (IO-OP FOO-FLAG [COUNT]) if FOO-FLAG is true, this prints its argument if FOO-FLAG is false, it rewinds the nearest magtape the number of frames specified by the argument COUNT except if COUNT is non-numeric it is the name of the tape drive, and the number of frames to be rewound will be found in the global variable *FRAMES* I think we are better off having a one to one mapping between conceptual functions and names. --------  Date: 15 October 1982 01:02-EDT From: Alan Bawden Subject: Here is a good idea, I think To: common-lisp at SU-AI Date: 15 October 1982 0010-EDT (Friday) From: Guy.Steele at CMU-10A Re: Here is a good idea, I think Presumably (EVENP x y) <=> (ZEROP (MOD x y)) ? My mathematical training makes me think it more natural to define: (ZEROP x y) <=> (ZEROP (MOD x y)) So that you can think of the second argument to ZEROP as specifing the ring that you are considering the first argument a member of. In fact, if it wasn't about 20 years too late, I might suggest (PLUS x y m) <=> (MOD (PLUS x y) m) and so forth for all the other arithmetic functions. There are some real benefits to be gained from knowing the modulus before you start to compute some functions (EXPT for example). Or do we already have a meaning for the second argument to ZEROP?  Date: 15 October 1982 01:02-EDT From: Alan Bawden Subject: Here is a good idea, I think To: common-lisp at SU-AI Date: 15 October 1982 0010-EDT (Friday) From: Guy.Steele at CMU-10A Re: Here is a good idea, I think Presumably (EVENP x y) <=> (ZEROP (MOD x y)) ? My mathematical training makes me think it more natural to define: (ZEROP x y) <=> (ZEROP (MOD x y)) So that you can think of the second argument to ZEROP as specifing the ring that you are considering the first argument a member of. In fact, if it wasn't about 20 years too late, I might suggest (PLUS x y m) <=> (MOD (PLUS x y) m) and so forth for all the other arithmetic functions. There are some real benefits to be gained from knowing the modulus before you start to compute some functions (EXPT for example). Or do we already have a meaning for the second argument to ZEROP?  Date: 15 October 1982 0040-EDT (Friday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: Here is a terrible idea, I think One advantage of making the user type (ZEROP (MOD ...)) is that it makes clear that he is doing that and not (ZEROP (REMAINDER ...)), which might also be a distinct useful operation. --Sigh, Guy  Date: Friday, 15 October 1982 00:36-EDT From: Scott E. Fahlman To: Guy.Steele at CMU-10A Cc: common-lisp at SU-AI Subject: Here is a good idea, I think Terrible idea! Actually, I have no objection to having this function around, except that is one more built-in function, but you can't be serious about wanting to call it EVENP/ODDP? You really want to have code around containing (evenp 51 17) => T ??? I've been looking at even numbers for most of my life, and 51 is not one, whatever that other silly argument says. Pythagoras would turn over in his triangle if he saw this. If this has to happen, call it ZEROP-MOD or some such. Better yet, make the users type (zerop (mod ...)). -- Scott  Date: 15 October 1982 0010-EDT (Friday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: Here is a good idea, I think Presumably (EVENP x y) <=> (ZEROP (MOD x y)) ? - - - - Begin forwarded message - - - - Mail-From: ARPANET host PARC-MAXC received by CMU-10A at 14-Oct-82 20:51:44-EDT Date: 14-Oct-82 17:52:08 PDT (Thursday) From: Masinter at PARC-MAXC Subject: optional argument for EVENP? To: Guy.Steele@CMU-10A cc: , Masinter.PA We've found a need in our system for two-argument EVENP, (EVENP n &optional divisor) divisor defaults to 2. Predicate returns true if n is an integral multiple of divisor. (ODDP n &optional divisor) is merely (NOT (EVENP n divisor)). This seems to be a logical extension of MOD. - - - - End forwarded message - - - -  Date: 13 Oct 1982 1608-EDT From: STEELE at CMU-20C Subject: Ballot results To: common-lisp at SU-AI ????????????????????????????????????????????????????????????????????????????? ? %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ? ? % ================================================================= % ? ? % = $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ = % ? ? % = $ +++++++++++++++++++++++++++++++++++++++++++++++++++++ $ = % ? ? % = $ + ############################################### + $ = % ? ? % = $ + # ///////////////////////////////////////// # + $ = % ? ? % = $ + # / The October 1982 Common LISP Ballot / # + $ = % ? ? % = $ + # / RESULTS / # + $ = % ? ? % = $ + # ///////////////////////////////////////// # + $ = % ? ? % = $ + ############################################### + $ = % ? ? % = $ +++++++++++++++++++++++++++++++++++++++++++++++++++++ $ = % ? ? % = $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ = % ? ? % ================================================================= % ? ? %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ? ????????????????????????????????????????????????????????????????????????????? Here are the tabulated votes on the October 1982 Common LISP Ballot. For each issue the summary vote shown between "***" is what I take to be a consensus, with a "?" added if I am a bit uncertain. I will edit the manual according to these guidelines unless someone screams loudly and soon over some issue. A few of the issues had a very mixed response; these I have labeled "Controversial" and will take no immediate action on. --Guy 1. How shall the case for a floating-point exponent specifier output by PRINT and FORMAT be determined? (a) upper case, for example 3.5E6 (b) lower case, for example 3.5e6 (c) a switch (d) implementation-dependent Issue 1: *** B? *** Hedrick: B Wholey: - Fahlman: B Weinreb: B Killian: B Zubkoff: C Moon: B van Roggen: D Masinter: A RMS: B Dyer: B Bawden: - Feinberg: B Ginder: B Burke et al.: B Brooks: - Gabriel: A DECLISP: B Steele: C Dill: D Scherlis: - Pitman: B Anderson: B 2. Shall we change the name SETF to be SET? (y) yes (n) no Issue 2: *** N *** Hedrick: N Wholey: N Fahlman: N Weinreb: N Killian: X Zubkoff: Y Moon: N van Roggen: Y Masinter: N RMS: N Dyer: N Bawden: N Feinberg: N Ginder: N Burke et al.: N Brooks: N Gabriel: N DECLISP: N Steele: N Dill: N Scherlis: Y Pitman: N Anderson: N Killian: I have been convinced that renaming SETF to SET would be wrong because it would require changing lots of old code. But, you seem to have ignored the rest of my suggestion in your ballot, namely eliminating those horrid "F"s at the end of several function names (INCF, GETF etc.). If you don't do this, then you're being inconsistent by not naming PUSH PUSHF, etc. The "F" at the end of "SETF" would then be there purely for compatibility, and could be renamed when another Lisp dialect is designed, years hence. Pitman: I think we should do this, but not at this time. RMS: I very strongly do not want to have to change uses of the traditional function SET in the Lisp machine system. Feinberg: A better name than SETF (or SET) should be found. 3. Shall there be a type specifier QUOTE, such that (QUOTE x) = (MEMBER x)? Then MEMBER can be eliminated; (MEMBER x y z) = (OR 'x 'y 'z). Also one can write such things as (OR INTEGER 'FOO) instead of (OR INTEGER (MEMBER FOO)). (y) yes (n) no Issue 3: *** Y? *** Hedrick: X Wholey: Y Fahlman: N Weinreb: Y Killian: Y Zubkoff: Y Moon: Y van Roggen: N Masinter: Y RMS: - Dyer: X Bawden: Y Feinberg: Y Ginder: - Burke et al.: Y Brooks: Y Gabriel: Y DECLISP: N Steele: Y Dill: Y Scherlis: Y Pitman: Y Anderson: - 4. Shall MOON's proposal for LOAD keywords, revised as shown below, be used? (y) yes (n) no Issue 4: *** Y *** Hedrick: Y Wholey: Y Fahlman: Y Weinreb: Y Killian: Y Zubkoff: Y Moon: Y van Roggen: Y Masinter: X RMS: - Dyer: Y Bawden: Y Feinberg: Y Ginder: Y Burke et al.: Y Brooks: Y Gabriel: Y DECLISP: Y Steele: Y Dill: X Scherlis: Y Pitman: X Anderson: - Moon: I thought we agreed to make LOAD take a stream as its first argument, instead of a pathname, and flush the :STREAM keyword. :ERROR should control only "file does not exist" errors, not "host down", "directory does not exist", "illegal character in file name", "no access to file", and "file cannot be read because of disk error". Nor should it affect errors due to evaluation of forms in the file. So I think it needs a better name; how about :NONEXISTENT-OK? Masinter: :ERROR, :SET-DEFAULT-PATHNAME options to LOAD should be rationalized with OPEN; the handling here of search paths should logically be handled by passing on some of the options from LOAD to OPEN rather than having LOAD do special path-name processing. This is because users who manipulate files want to do similar hacking, and the mechanism should be common. Pitman: I would vote YES except: As suggested by someone when it was proposed, any mention of packages should be stricken pending the release of a package system specification. Dill: :PACKAGE & :VERBOSE should be flushed, since they are package system dependent. 5. Shall closures over dynamic variables be removed from Common LISP? (y) yes (n) no Issue 5: *** Y? *** Hedrick: Y Wholey: Y Fahlman: Y Weinreb: N Killian: - Zubkoff: - Moon: - van Roggen: Y Masinter: - RMS: - Dyer: X Bawden: - Feinberg: Y Ginder: Y Burke et al.: - Brooks: - Gabriel: N DECLISP: Y Steele: Y Dill: Y Scherlis: Y Pitman: N Anderson: - 6. Shall LOOP, as summarized below, be included in Common LISP? (y) yes (n) no Issue 6: Controversial Hedrick: N Wholey: N Fahlman: N Weinreb: Y Killian: Y Zubkoff: X Moon: - van Roggen: N Masinter: X RMS: N Dyer: Y Bawden: Y Feinberg: N Ginder: N Burke et al.: Y Brooks: N Gabriel: X DECLISP: Y Steele: N Dill: N Scherlis: N Pitman: N Anderson: N Fahlman: I am in favor of adding the LOOP package as described (once it is completed) to the language as a portable yellow pages module. I feel rather strongly that it is premature to add LOOP to the white pages. Zubkoff: The LOOP macro should be kept in the yellow pages until we've had a chance to use it for a while and determine whether or not it is the "right" thing. Masinter: I feel strongly that the white pages SHOULD include a LOOP construct. I care less about which one, but I like most of Moon's proposal better than DO and what I saw of LetS. I'd get rid of AND and ELSE. I don't understand if the "COLLECT" lexical scoping includes scoping under macro expansion. Pitman: As a yellow-pages extension is ok by me. I strongly oppose its placement in the white pages. Feinberg: We should carefully examine all iteration construct proposals before committing to any particular one. I feel strongly about this. I would very much like to see complete documentation on Loop and any other loop construct which might be included in Common Lisp, especially before we decide to incorporate them into the white pages. Gabriel: I believe that a LOOP construct of some sort is needed: I am constantly bumping into the limitations of MacLisp-style DO. The Symbolics people claim that LOOP, as defined in the current proposal, is well thought-out and indispensible. Not having used it particularly, I cannot pass judgement on this. I advocate putting LOOP into the hottest regions of the Yellow Pages, meaning that people should use it immediately so that any improvements to clarity can be made rapidly. The best possible LOOP should then be moved to the White Pages. My prejudice is that LOOP code is very difficult to understand. On the other hand, closures are difficult for many people to understand, and perhaps the difficulty is due to unfamiliarity in the LOOP case as it is in the closure case. In my current programming I do not define my own iteration construct (though I have in the past) because I've found that other people (such as myself at a later date) do not readily understand my code when it contains idiosyncratic control structures. If we do not standardize on a LOOP construct soon we will be faced with the fact of many people defining their own difficult-to-understand control structures. 7. Regardless of the outcome of the previous question, shall CYCLE be retained and be renamed LOOP, with the understanding that statements of the construct must be non-atomic, and atoms as "statements" are reserved for extensions, and any such extensions must be compatible with the basic mening as a pure iteration construct? (y) yes (n) no Issue 7: *** Y? *** Hedrick: Y Wholey: - Fahlman: Y Weinreb: Y Killian: Y Zubkoff: - Moon: Y van Roggen: N Masinter: Y RMS: - Dyer: Y Bawden: Y Feinberg: N Ginder: - Burke et al.: Y Brooks: Y Gabriel: Y DECLISP: N Steele: Y Dill: X Scherlis: Y Pitman: Y Anderson: N Feinberg: I don't think we should make any commitment at all, even to this extent. Loop is too nice a word to give up before we even agree about installing it into the language. 8. Shall ARRAY-DIMENSION be changed by exchanging its arguments, to have the array first and the axis number second, to parallel other indexing operations? (y) yes (n) no Issue 8: *** Y *** Hedrick: Y Wholey: Y Fahlman: Y Weinreb: Y Killian: Y Zubkoff: Y Moon: Y van Roggen: Y Masinter: - RMS: Y Dyer: Y Bawden: - Feinberg: Y Ginder: Y Burke et al.: Y Brooks: Y Gabriel: Y DECLISP: Y Steele: Y Dill: X Scherlis: - Pitman: Y Anderson: Y 9. Shall MACROEXPAND, as described below, replace the current definition? (y) yes (n) no Issue 9: *** Y *** Hedrick: Y Wholey: - Fahlman: Y Weinreb: Y Killian: Y Zubkoff: - Moon: Y van Roggen: Y Masinter: Y RMS: - Dyer: Y Bawden: Y Feinberg: - Ginder: - Burke et al.: Y Brooks: Y Gabriel: Y DECLISP: Y Steele: Y Dill: X Scherlis: Y Pitman: X Anderson: - Killian: This is ok as far as it goes, but I intend to suggest additions when I find the time. Masinter: This seems right but not quite fully specified, e.g. LAMBDA-MACRO. Pitman: I would vote YES except: I am uncomfortable with saying that a form returns two values and then returning only one (letting the rest default to NIL). Does Common-Lisp specify anything on this? In any case, I would ammend the (cond ((and (pairp ...) ...) (values (...) t)) (t form)) to (cond (...) (t (values form nil))) to make it clear that two values are always returned. If this modification is made, I am happy with this proposal. 10. Shall all global system-defined variables have names beginning and ending with "*", for example *PRINLEVEL* instead of PRINLEVEL and *READ-DEFAULT-FLOAT-FORMAT* instead of READ_DEFAULT-FLOAT-FORMAT? (y) yes (n) no Issue 10: *** Y *** Hedrick: Y Wholey: Y Fahlman: Y Weinreb: Y Killian: N Zubkoff: Y Moon: Y van Roggen: Y Masinter: Y RMS: X Dyer: N Bawden: N Feinberg: Y Ginder: Y Burke et al.: X Brooks: Y Gabriel: Y DECLISP: Y Steele: Y Dill: X Scherlis: Y Pitman: Y Anderson: Y RMS: I would prefer a character other than *, such as "-". It is easier to type, and easier to type correctly. Bawden: I am in favor of variables named *FOO* over variables named FOO only when that doesn't introduce an incompatibility with existing Lisps. That is why I voted NO on 10, because it involved an incompatible change to variables like PRINLEVEL. I voted YES for 11 because currently we have no named constants as far as I know so there is no incompatibility. Burke et al.: I really like only ONE "*" at the beginning of the name. I got tired of shifting for two years ago, but conversely couldn't stand to not have the specialness of the variable not be obvious. 11. Same question for named constants (other than T and NIL), such as *PI* for PI and *MOST-POSITIVE-FIXNUM* for MOST-POSITIVE-FIXNUM. (y) yes (n) no (o) yes, but use a character other than "*" Issue 11: Controversial Hedrick: Y Wholey: N Fahlman: Y Weinreb: Y Killian: N Zubkoff: Y Moon: N van Roggen: Y Masinter: Y RMS: X Dyer: N Bawden: Y Feinberg: Y Ginder: Y Burke et al.: X Brooks: O Gabriel: Y DECLISP: Y Steele: N Dill: X Scherlis: - Pitman: Y Anderson: Y Fahlman: Whatever is done about global vars, global constants should be the same. I oppose option 3 or any plan to make them look syntactically different. Moon: I like to use the stars to mean "someone may bind this" rather than "don't use this as a local variable name", which is why I voted no on putting stars around constants. However, others might disagree with me and I will defer to the majority. I do think stars around variable names are important. 12. Shall a checking form CHECK-TYPE be introduced as described below? (y) yes (n) no Issue 12: *** Y *** Hedrick: Y Wholey: Y Fahlman: Y Weinreb: Y Killian: Y Zubkoff: Y Moon: Y van Roggen: Y Masinter: Y RMS: - Dyer: Y Bawden: Y Feinberg: - Ginder: Y Burke et al.: Y Brooks: Y Gabriel: Y DECLISP: Y Steele: Y Dill: Y Scherlis: Y Pitman: Y Anderson: Y 13. Shall a checking form CHECK-SUBSEQUENCE be introduced as described below? (y) yes (n) no Issue 13: Controversial Hedrick: N Wholey: - Fahlman: N Weinreb: - Killian: Y Zubkoff: Y Moon: Y van Roggen: Y Masinter: - RMS: - Dyer: N Bawden: - Feinberg: N Ginder: Y Burke et al.: N Brooks: - Gabriel: Y DECLISP: Y Steele: Y Dill: N Scherlis: Y Pitman: Y Anderson: Y Feinberg: It seems like we're taking this type checking stuff a little too far. Let the user write his own type checking code, or make a yellow pages package called Carefully (or Lint) or something. Dill: There should be a succinct way about talking about the contents of sequences, but this particular one doesn't have the right functionality. I prefer a regular-expression notation of some form, but don't have it well enough worked out to propose one. Lets leave it out of the language until someone figures out how to do it well. 14. Shall the functions LINE-OUT and STRING-OUT, eliminated in November, be reinstated? (y) yes (n) no Issue 14: *** Y *** Hedrick: N Wholey: Y Fahlman: Y Weinreb: Y Killian: Y Zubkoff: - Moon: - van Roggen: Y Masinter: - RMS: - Dyer: X Bawden: - Feinberg: Y Ginder: - Burke et al.: Y Brooks: - Gabriel: - DECLISP: Y Steele: Y Dill: X Scherlis: - Pitman: Y Anderson: - 15. Shall the REDUCE function be added as described below? (y) yes (n) no Issue 15: *** Y *** Hedrick: N Wholey: - Fahlman: Y Weinreb: Y Killian: Y Zubkoff: Y Moon: Y van Roggen: Y Masinter: Y RMS: - Dyer: Y Bawden: - Feinberg: Y Ginder: Y Burke et al.: Y Brooks: Y Gabriel: Y DECLISP: Y Steele: Y Dill: Y Scherlis: Y Pitman: - Anderson: N Moon: Should the name be REDUCE, or something else? Hearn aside, the name doesn't instantly convey to me what it does. I haven't come up with an alternative suggestion, however. Pitman: I have no use for this but have no strong objection. 16. Shall the Bawden/Moon solution to the "invisible block" problem be accepted? The solution is to define (RETURN x) to mean precisely (RETURN-FROM NIL x), and to specify that essentially all standard iterators produce blocks named NIL. A block with a name other than NIL cannot capture a RETURN, only a RETURN-FROM with a matching name. (y) yes (n) no Issue 16: *** Y *** Hedrick: Y Wholey: - Fahlman: Y Weinreb: Y Killian: Y Zubkoff: Y Moon: Y van Roggen: Y Masinter: - RMS: N Dyer: Y Bawden: Y Feinberg: Y Ginder: Y Burke et al.: Y Brooks: Y Gabriel: Y DECLISP: Y Steele: Y Dill: X Scherlis: Y Pitman: Y Anderson: - RMS: I am strongly opposed to anything that would require me to find all the named PROGs in the Lisp machine system which have simple RETURNs that return from them. This would make a lot of extra work for me. Please don't impose this on me. Dill: It seems to me that it ought to be possible to exploit lexical scoping to solve problems like this in a more general way. If this is possible, then this proposeal is redundant. 17. Shall the TAGBODY construct be incorporated? This expresses just the behavior of the GO aspect of a PROG. Any atoms in the body are not evaluated, but serve as tags that may be specified to GO. Tags have lexical scope and dynamic extent. TAGBODY always returns NIL. (y) yes (n) no Issue 17: *** Y *** Hedrick: N Wholey: - Fahlman: Y Weinreb: Y Killian: Y Zubkoff: Y Moon: Y van Roggen: Y Masinter: Y RMS: X Dyer: Y Bawden: Y Feinberg: Y Ginder: Y Burke et al.: Y Brooks: Y Gabriel: Y DECLISP: Y Steele: Y Dill: N Scherlis: - Pitman: Y Anderson: Y RMS: Why must GOBODY [sic] always return NIL just because PROG does? It is just as easy to make GOBODY return the value of the last form in it. We can consider a PROG to expand into a GOBODY followed by a NIL. Feinberg: A better name than TAGBODY should be found. 18. What shall be done about RESTART? The following alternatives seem to be the most popular: (a) Have no RESTART form. (b) RESTART takes the name of a block. What happens when you say (RESTART NIL) must be clarified for most iteration constructs. (c) There is a new binding form called, say, RESTARTABLE. Within (RESTARTABLE FOO . body), (RESTART FOO) acts as a jump to the top of the body of the enclosing, matching RESTARTABLE form. RESTART tags have lexical scope and dynamic extent. Issue 18: *** A *** Hedrick: A Wholey: A Fahlman: A Weinreb: A Killian: A Zubkoff: A Moon: A van Roggen: A Masinter: A RMS: C Dyer: A Bawden: A Feinberg: A Ginder: A Burke et al.: A Brooks: A Gabriel: B DECLISP: A Steele: C Dill: X Scherlis: - Pitman: C Anderson: A Fahlman: I now believe that RESTART is more trouble than it is worth. I am strongly opposed to any plan, such as option 3, that would add a RESTART form but make it impossible to use this with the implicit block around a DEFUN. If you have to introduce a RESTARTABLE block, you may as well use PROG/GO. 19. Shall there be a built-in identity function, and if so, what shall it be called? (c) CR (i) IDENTITY (n) no such function Issue 19: *** I *** Hedrick: I Wholey: I Fahlman: I Weinreb: I Killian: - Zubkoff: I Moon: I van Roggen: I Masinter: I RMS: I Dyer: X Bawden: I Feinberg: I Ginder: I Burke et al.: I Brooks: I Gabriel: - DECLISP: I Steele: I Dill: X Scherlis: I Pitman: I Anderson: - RMS: The canonical identity function is now called PROG1, but the name IDENTITY is ok by me. 20. Shall the #*... bit-string syntax replace #"..."? That is, shall what was before written #"10010" now be written #*10010 ? (y) yes (n) no Issue 20: *** Y *** Hedrick: Y Wholey: - Fahlman: Y Weinreb: Y Killian: Y Zubkoff: Y Moon: Y van Roggen: Y Masinter: Y RMS: - Dyer: X Bawden: Y Feinberg: Y Ginder: Y Burke et al.: Y Brooks: Y Gabriel: N DECLISP: Y Steele: Y Dill: Y Scherlis: Y Pitman: Y Anderson: Y 21. Which of the two outstanding array proposals (below) shall be adopted? (s) the "simple" proposal (r) the "RPG memorial" proposal (m) the "simple" proposal as amended by Moon Issue 21: *** M? *** Hedrick: M Wholey: - Fahlman: M Weinreb: M Killian: M Zubkoff: M Moon: M van Roggen: M Masinter: - RMS: M Dyer: - Bawden: M Feinberg: M Ginder: M Burke et al.: M Brooks: R Gabriel: X DECLISP: M Steele: M Dill: M Scherlis: M Pitman: M Anderson: M Brooks: if not "r" then I prefer "m". Gabriel: I prefer the "RPG memorial", but I do not feel so strong about this that I would sink the Common Lisp effort over it. 22. Shall the following proposal for the OPTIMIZE declaration be adopted? (y) yes (n) no Issue 22: *** Y *** Hedrick: Y Wholey: - Fahlman: Y Weinreb: Y Killian: N Zubkoff: Y Moon: Y van Roggen: Y Masinter: N RMS: - Dyer: Y Bawden: - Feinberg: N Ginder: Y Burke et al.: Y Brooks: - Gabriel: Y DECLISP: Y Steele: - Dill: X Scherlis: N Pitman: X Anderson: X Pitman: I would vote YES except: The use of numbers instead of keywords bothers me. The section saying which numbers can be which values and how those values will be interpreted seems to FORTRANesque to me. I think these values should be just keywords or the tight restrictions on their values should be lifted. The only use for numbers would be to allow users a fluid range of possibilities. Feinberg: Keywords instead of numbers would be nicer. How about :dont-care, :low, :medium, :high? Dill: I don't think that we need an optimize declaration in common lisp. It's not necessary for portability, and intensely dependent on compiler implementations. If we must have one, I strongly favor the Fahlman proposal over proposals that would have symbolic specifications. 23. Shall it be permitted for macros calls to expand into DECLARE forms and then be recognized as valid declarations? This would not allows macros calls *within* a DECLARE form, only allow macros to expand into a DECLARE form. (y) yes (n) no Issue 23: *** Y *** Hedrick: Y Wholey: Y Fahlman: Y Weinreb: Y Killian: Y Zubkoff: Y Moon: Y van Roggen: Y Masinter: Y RMS: - Dyer: Y Bawden: Y Feinberg: Y Ginder: - Burke et al.: Y Brooks: Y Gabriel: Y DECLISP: Y Steele: Y Dill: X Scherlis: Y Pitman: Y Anderson: Y Pitman: I also support allowing multiple declare forms at the top of a bind form. ie, (LAMBDA (X Y) (DECLARE (SPECIAL X)) (DECLARE (SPECIAL Y)) for ease in macros. Steele's proposed evaluator did this and it wasn't notably expensive. 24. Shall there be printer control variables ARRAY-PRINLEVEL and ARRAY-PRINLENGTH to control printing of arrays? These would not limit the printing of strings. (y) yes (n) no Issue 24: Controversial Hedrick: N Wholey: Y Fahlman: N Weinreb: Y Killian: Y Zubkoff: Y Moon: Y van Roggen: Y Masinter: N RMS: - Dyer: Y Bawden: Y Feinberg: Y Ginder: Y Burke et al.: Y Brooks: - Gabriel: N DECLISP: Y Steele: Y Dill: X Scherlis: Y Pitman: N Anderson: Y 25. Shall lambda macros, as described below, be incorporated into the language, and if so, shall they occupy the function name space or a separate name space? (f) function name space (s) separate name space (n) no lambda macros Issue 25: Controversial Hedrick: N Wholey: - Fahlman: N Weinreb: Y Killian: F Zubkoff: - Moon: S van Roggen: S Masinter: D RMS: S Dyer: S Bawden: S Feinberg: N Ginder: - Burke et al.: S Brooks: N Gabriel: F DECLISP: S Steele: N Dill: N Scherlis: - Pitman: S Anderson: N Fahlman: I seem to be unable to locate any explanation of why Lambda macros are useful enough to be worth the bother. Looks like needless hair to me, but I seem to dimly recall some arguments for why they were needed. I'm not passionately opposed, but every page full of hairy stuff in the manual hurts us. Masinter: Spec here not consistent with MACROEXPAND proposal. Feinberg: Once again, hair that I don't think needs to be standardized on. I think most users would never need this, and perhaps a better way to do this can be thought of. 26. Shall the floating-point manipulations described below be adopted? (y) as described by MOON (a) as amended (FLOAT-SIGN changed) by GLS (n) do not adopt them Issue 26: *** A *** Hedrick: A Wholey: A Fahlman: A Weinreb: A Killian: A Zubkoff: A Moon: Y van Roggen: A Masinter: - RMS: - Dyer: - Bawden: - Feinberg: - Ginder: A Burke et al.: - Brooks: - Gabriel: A DECLISP: A Steele: A Dill: X Scherlis: - Pitman: - Anderson: Y Killian: Since TRUNC was renamed TRUNCATE at the last meeting, the FTRUNC in this proposal would have to become FTRUNCATE. 27. Shall DEFMACRO, DEFSTRUCT, and other defining forms also be allowed to take documentation strings as possible and appropriate? (y) yes (n) no Issue 27: *** Y *** Hedrick: Y Wholey: Y Fahlman: Y Weinreb: Y Killian: Y Zubkoff: Y Moon: Y van Roggen: Y Masinter: Y RMS: Y Dyer: Y Bawden: Y Feinberg: Y Ginder: Y Burke et al.: Y Brooks: Y Gabriel: Y DECLISP: Y Steele: Y Dill: X Scherlis: Y Pitman: Y Anderson: Y 28. Shall the following proposed revision of OPEN keywords be accepted? (y) yes (n) no Issue 28: *** Y *** Hedrick: Y Wholey: Y Fahlman: Y Weinreb: Y Killian: Y Zubkoff: Y Moon: Y van Roggen: Y Masinter: Y RMS: - Dyer: Y Bawden: Y Feinberg: Y Ginder: Y Burke et al.: Y Brooks: Y Gabriel: Y DECLISP: Y Steele: Y Dill: X Scherlis: - Pitman: X Anderson: Y DECLISP: Either READ-ALTER, READ-WRITE OR UPDATE should replace the :OVERWRITE keyword for :DIRECTION. Overwrite suggests that an existing file will be destroyed by having new data written into the same space. -------  Date: Monday, 11 October 1982 22:58-EDT From: MOON at SCRC-TENEX To: Common-Lisp at SU-AI Subject: Re: macro expansion In-reply-to: The message of 2 Sep 1982 18:09 PDT from JonL at PARC-MAXC Date: 2 Sep 1982 18:09 PDT From: JonL at PARC-MAXC In-reply-to: Moon at SCRC-TENEX's message of Sunday, 29 August 1982, 21:26-EDT Sorry for the slow response, I am behind on my mail. There seemed to be a couple things in this message that shouldn't be left hanging. 1) Why not have MACROEXPAND return the second value, as obtained from MACROEXPAND-1 ? That would be all right with me, I just overlooked it when writing the sample code. It might even be worthwhile for this second return value, when non-null, to distinguish between the case of having actually run the expansion function and having found the expansion in some "memoization" facililty. I can't see any point to this one. 2) We saw the need for a function called FIND-MACRO-DEFINITION, Having this would be fine with me. I think the committee decided that this should not be in the portable language, because only MACROEXPAND-1 should be calling it, and removed this functionality from MACROP or MACRO-P. I'd stick with that unless there is a good reason to put it back in. 3) ocasionally there is a macro which wants to say "don't memoize me at all". I don't see the use for this, since the macro can't control when the interpreter or compiler remembers the macro expansion of a form versus when it calls MACROEXPAND again. Or was this only an effiency hack, for macros that somehow knew that memoization took longer than expanding them? I'd say that there is a lacuna in your proposal in that you don't exhibit code for the case of traditional memoizing by hashtable -- that will show how the macroexpansion function is selectively called depending on the hashtable entry. I think I don't understand this; perhaps you could elaborate. If a hash table entry is absent, you call the expansion function, otherwise you don't. 4) we often felt the need for an additional argument to the expansion function which tells *why* this macro call is being expanded -- e.g., EVAL, or COMPILE, or FOR-VALUE, or FOR-EFFECTS etc. I can't characterise all such cases, but GSB, KMP, and RWK may have some good inputs here. That would be nice, but perhaps hard to do in general and consistently across implementations. Is there a way to leave room for it for the future? (I wouldn't like to do this by passing an extra argument which everyone is supposed to ignore!) Point 3 brings up another possibililty -- maybe your current definition of *MACROEXPAND-HOOK* is an over-generalization. That is, why not have two hooks, one for testing whether or not a "memoization" is present for the macro call in question (and returning it if present), and another hook of three arguments namely: i) a pointer to the original cell (macro call), ii) the already-computed expansion form, and iii) a symbol to indicate the reason why the macro call was "expanded" I realise that iii) will require more discussion, so maybe now is not the time to put it into CommonLisp; also the memoization hook would have to return a second value to indicate whether a memo was present. I don't see what advantage is gained by splitting the hook in half. Don't forget that Common Lisp provides a variety of built-in table mechanisms, including hash tables, so the user doesn't have to implement the table lookup himself the way he might in Maclisp. In any case, I'd rather see the default value for these macro hooks be NIL, so that one didn't have to understand the complexities of expansions and memoizations just to get the default case (that is, unless someone plans to allow NIL as a valid function name and . . . ) Surely each implementation provides the default functions as the initial values of these variables, rather than each implementation being required to test explicitly for NIL in the variable. Actually we could leave the implementation free to do it either way, and guarantee nothing about the initial values except that they provide a certain behavior.  Date: Monday, 11 October 1982, 17:49-EDT From: Daniel L. Weinreb Subject: Re: keyword pairs and OPEN To: HEDRICK at RUTGERS Cc: Masinter at PARC-MAXC, common-lisp at SU-AI In-reply-to: The message of 8 Oct 82 20:42-EDT from Mgr DEC-20s/Dir LCSR Comp Facility Thank you for your summary. My analysis is that your :RECOG is just the same thing as my :IF-EXISTS and :IF-DOES-NOT-EXIST except that I like my names more, and a few minor details are different. I intentionally omitted :IMAGE since I could not think of any definition that would be portable and aid in the writing of portable programs. Certainly many implementations will have their own :OPEN options. You're quite right that we must specify which values of the defined options are required for all implementations and which are optional. I should probably have done this, but I'll leave it to GLS since he knows more about the restrictions of the VAX, S-1, and Spice implementations than I do.  Date: 8 Oct 1982 2042-EDT From: HEDRICK at RUTGERS (Mgr DEC-20s/Dir LCSR Comp Facility) Subject: Re: keyword pairs and OPEN To: dlw at SCRC-TENEX at MIT-MC cc: Masinter at PARC-MAXC, common-lisp at SU-AI In-Reply-To: Your message of 8-Oct-82 1837-EDT Here is an attempt to flesh out the meanings of the flags you mentioned. :ACCESS This flag indicates what kind of I/O you intend to do with the file. Unless otherwise specified, I/O operations will begin at the beginning of the file. input - you are only going to read from it. output - you want to start with an empty file, and write new data to it. (Some operating systems allow two modes of writing to a file, one of which clears the file beforehand and one of which does not. Typically "output" means that you want a file which is clear. Indeed the alternative may be so bizaare that we don't even want to worry about it.) write-only - you are only going to write to it, but any existing data should not be cleared. (This is the one that is so bizaare you may choose to ignore it. Probably it would be enough to have update mode.) append - like write-only, but if the file already exists, writing will start from the end of the existing data. (Logically, this is not required, as it is equivalent to a write-only open followed by random access to the end of file. However a number of operating systems make special provisions for append access to files where you would not normally be able to open for output and then position to the end of file. Thus it is a useful distinction.) update - you are going to do both input and output. :RECOG This flag indicates attributes of the file that may help in finding it. old - file must exist, the existing version is used new - file must not exist, it is created old-version - file need not exist. If it does, the existing version is used. If it does not, the file is created. new-version - file need not exist. If it does, a new version is created. If it does not, the file is created. Lest you think I have designed this specifically for Tops-20, which allows multiple versions, these distinctions are also meaningful on Tops-10, which does not. On Tops-10, if the file exists, old-version would update the existing file and new-version would supercede it with a new one. Defaults are: input - old output - new-version write-only - old-version append - old-version update - old-version Certain combinations are meaningless. Others may not be allowed by the operating system. Exactly which combinations are allowed is implementation-dependent. However every implementation is required to support the following combinations input, old output, new-version and all implementations are strongly urged to implement all 5 default combinations, plus append/old and update/old. :RANDOM-ACCESS This flag indicates that the file will be accessed in some manner other than sequentially. I don't need it for Tops-20, but I think some operating systems may. In my opinion we should include it if any system of interest requires it. Does any? :IMAGE Most runtime systems end up doing various character processing such as removing null characters, turning CRLF into LF, removing the parity bit, turning control characters into representations with ^, turning two-character CDC "ASCII" into actual ASCII (if anyone is going to do a CDC implementation). This turns all of that off and give you characters unchanged. No doubt implementors will choose their own extensions to control behavior appropriate for the operating system, but this one option seems generally useful enough to put in the language. INPUT, NEW - this is generally meaningless. Some implementations would probably create a zero-length file and give immediate end of file. Others might call it an error. (Do we want to try to define exactly what happens? Does anyone understand I/O well enough to try to make a model at that level of detail?) OUTPUT, OLD - this one supercedes an existing file. It guarantees that the file must exist. It is possible that some implementations would not allow it, but I would think it would be meaningful for most. -------  Date: 8 Oct 1982 2042-EDT From: HEDRICK at RUTGERS (Mgr DEC-20s/Dir LCSR Comp Facility) Subject: Re: keyword pairs and OPEN To: dlw at SCRC-TENEX at MIT-MC cc: Masinter at PARC-MAXC, common-lisp at SU-AI In-Reply-To: Your message of 8-Oct-82 1837-EDT Here is an attempt to flesh out the meanings of the flags you mentioned. :ACCESS This flag indicates what kind of I/O you intend to do with the file. Unless otherwise specified, I/O operations will begin at the beginning of the file. input - you are only going to read from it. output - you want to start with an empty file, and write new data to it. (Some operating systems allow two modes of writing to a file, one of which clears the file beforehand and one of which does not. Typically "output" means that you want a file which is clear. Indeed the alternative may be so bizaare that we don't even want to worry about it.) write-only - you are only going to write to it, but any existing data should not be cleared. (This is the one that is so bizaare you may choose to ignore it. Probably it would be enough to have update mode.) append - like write-only, but if the file already exists, writing will start from the end of the existing data. (Logically, this is not required, as it is equivalent to a write-only open followed by random access to the end of file. However a number of operating systems make special provisions for append access to files where you would not normally be able to open for output and then position to the end of file. Thus it is a useful distinction.) update - you are going to do both input and output. :RECOG This flag indicates attributes of the file that may help in finding it. old - file must exist, the existing version is used new - file must not exist, it is created old-version - file need not exist. If it does, the existing version is used. If it does not, the file is created. new-version - file need not exist. If it does, a new version is created. If it does not, the file is created. Lest you think I have designed this specifically for Tops-20, which allows multiple versions, these distinctions are also meaningful on Tops-10, which does not. On Tops-10, if the file exists, old-version would update the existing file and new-version would supercede it with a new one. Defaults are: input - old output - new-version write-only - old-version append - old-version update - old-version Certain combinations are meaningless. Others may not be allowed by the operating system. Exactly which combinations are allowed is implementation-dependent. However every implementation is required to support the following combinations input, old output, new-version and all implementations are strongly urged to implement all 5 default combinations, plus append/old and update/old. :RANDOM-ACCESS This flag indicates that the file will be accessed in some manner other than sequentially. I don't need it for Tops-20, but I think some operating systems may. In my opinion we should include it if any system of interest requires it. Does any? :IMAGE Most runtime systems end up doing various character processing such as removing null characters, turning CRLF into LF, removing the parity bit, turning control characters into representations with ^, turning two-character CDC "ASCII" into actual ASCII (if anyone is going to do a CDC implementation). This turns all of that off and give you characters unchanged. No doubt implementors will choose their own extensions to control behavior appropriate for the operating system, but this one option seems generally useful enough to put in the language. INPUT, NEW - this is generally meaningless. Some implementations would probably create a zero-length file and give immediate end of file. Others might call it an error. (Do we want to try to define exactly what happens? Does anyone understand I/O well enough to try to make a model at that level of detail?) OUTPUT, OLD - this one supercedes an existing file. It guarantees that the file must exist. It is possible that some implementations would not allow it, but I would think it would be meaningful for most. -------  Date: Friday, 8 October 1982, 18:06-EDT From: Daniel L. Weinreb Subject: Re: keyword pairs and OPEN To: Masinter at PARC-MAXC, common-lisp at SU-AI In-reply-to: The message of 5 Oct 82 23:31-EDT from Masinter at PARC-MAXC Date: 5-Oct-82 20:31:36 PDT (Tuesday) From: Masinter at PARC-MAXC :ACCESS - one of :INPUT, :OUTPUT, :APPEND (or ...) no default :RECOG - one of :OLD, :NEW, :OLD/NEW (or ...) default depends on :ACCESS I don't understand this. Please tell me what each combination means. For example, what if access is INPUT and recog is NEW? What if access is OUTPUT (in the sense of create) and recog is OLD? It is quite important that the semantics of OPEN be clearly defined so that every implementation can be consistent. The existing definition of the Lisp Machine OPEN function looks rather similar to what you are proposing; its general complexity and overgenerality have made it incomprehensible, and so the system has several completely misimplementations, none of which work right. I was trying to counter this by keeping things simple and obvious.  Date: Friday, 8 October 1982, 17:54-EDT From: Daniel L. Weinreb Subject: Hash tables => Hashing functions To: Wholey at CMU-20C, Common-Lisp at SU-AI In-reply-to: The message of 8 Oct 82 14:00-EDT from Skef Wholey No, because it is very hard/expensive to provide a function that hashes on EQ (and EQL) in a Lisp with a copying GC. That's why we provide hash tables: the system can deal with this but the user can't. For example, Lisp Machine hash tables all include a little variable that gets compared against a global how-many-flips-have-happened counter, and if there has been a flip since last time, the hash table has to be completely rehashed. The user should not see this counter, especially not as part of the C.L. definition.  Date: Friday, 8 October 1982 14:00-EDT From: Skef Wholey To: Common-Lisp at SU-AI Subject: Hash tables => Hashing functions Since Common Lisp provides three kinds of hash tables (eq, eql, and equal), shouldn't it provide three kinds of hashing functions? It currently provides only SXHASH (i.e. EQUAL-HASH).  Date: Friday, 8 October 1982 14:00-EDT From: Skef Wholey To: Common-Lisp at SU-AI Subject: Hash tables => Hashing functions Since Common Lisp provides three kinds of hash tables (eq, eql, and equal), shouldn't it provide three kinds of hashing functions? It currently provides only SXHASH (i.e. EQUAL-HASH).  Date: 8 October 1982 0251-EDT (Friday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: Documentation and errors, etc. Moon is absolutely right that how to handle errors and documentation in generality is a very difficult aspect of user interface design. Now that I've got everyone aware of the issues, I propose to retract my proposal are far as serious discussion of immediate adoption is concerned. Les us press on towards the near goal first. --Guy  Date: 8 October 1982 01:23-EDT From: Glenn S. Burke Subject: [Re: MIT VAX/VMS Lisp Implementors, Ballot] To: Common-Lisp at SU-AI Date: Thursday, 7 October 1982 21:29-EDT From: Scott E. Fahlman To: MIT VAX/VMS Lisp Implementors It is nice to know that you speak for the NIL group, but it would also be nice to know who is doing the speaking. ---- Oops. In rapidly decreasing order of significance: me, George Carrette, and various other innocent bystanders in the immediate environment who i flame at on occasion.  Date: 7 Oct 1982 2203-EDT From: BROOKS at MIT-OZ at MIT-MC Subject: /BALLOT/ To: guy.steele at CMU-10A cc: common-lisp at SU-AI ~ - n y y - n y y y y o y - - y y y a i y r - y - n - y y 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 Note: On 21 if not "r" then I prefer "m". -------  Date: Thursday, 7 October 1982 21:13-EDT From: Scott E. Fahlman To: David A. Moon Cc: common-lisp at SU-AI Subject: Documentation and error messages ... That word "DEFUN" is telling you how to interpret the name of the thing whose documentation you are retrieving; it is the name of a "name space". It is 100% wrong to multiply the number of name spaces by the number of kinds of documentation you might want, and have as many symbols for documentation as we used to have for sequence functions. The level of documentation you want should be a separate argument to the DOCUMENTATION function. Well, I seem to have misunderstod Moon's proposal on this, but his position seems rather doctrinaire. The point, as I see it, is that simply saying (documentation 'foo) might get you any of several things, so another argument is required to specify what you really want. I don't think we'll end up with 600 of these. I agree, however, that this whole documentation thing is getting too hairy, and that for now we probably shouldn't try to put too many user-environment things into the white pages. In addition to Moon's name spaces and this short/long business, we have the whole unresolved business of reformatting doc strings. Maybe we should forget the whole thing. All that the white pages really need to say is that DEFUN optionally contains a string that is meant to be documentation, and that these should not choke your implementation. Such strings, along with those from DEFVAR and friends, get printed somehow via the semi-standard function DESCRIBE, and they may be accessible in other ways. Maybe in this case less is more. -- Scott  Date: 7 October 1982 21:05-EDT From: MIT VAX/VMS Lisp Implementors Subject: /BALLOT/ To: Guy.Steele at CMU-10A cc: common-lisp at SU-AI ~ b n y y - y y y y x x y n y y y y a i y m y y y s - y y 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 (10) I really like only ONE "*" at the beginning of the name. I got tired of shifting for two years ago, but conversely couldn't stand to not have the specialness of the variable not be obvious. (11) Whatever we decide for 10.  Date: Thursday, 7 October 1982, 19:19-EDT From: David A. Moon Subject: Documentation and error messages To: common-lisp at SU-AI In-reply-to: The message of 7 Oct 82 01:37-EDT from Guy.Steele at CMU-10A, The message of 7 Oct 82 13:16-EDT from Fahlman at Cmu-20c Date: 7 October 1982 0137-EDT (Thursday) From: Guy.Steele at CMU-10A First, some people have recognized a need for both short and long forms of documentation for functions, variables, and other things. Here is a quicky solution: in DEFUN, for example, let more than one documentation string appear, in order of increasing detail.... This solution is not great. No it's not. But it would be acceptable. I think I still prefer special-casing the first line over this solution, even though it means that the short documentation string really has to be short (to fit on a line). The extra complexity doesn't seem to buy anything, and isn't enough complexity to do anything really hairy. There is a similar problem with error messages, trying to strike a balance between conciseness and helpfulness.... Your suggested schemes for this fit much more nicely into the Lisp machine "New error system" than into the bare Lisp you're trying to put them into. Since Common Lisp is not prepared to adopt such a hairy error system right now, I suggest that this issue be dropped until next year, rather than trying to standardize on some kludge. I certainly do not propose that it be dropped forever. Date: Thursday, 7 October 1982 13:16-EDT From: Scott E. Fahlman These fit nicely into Moon's proposal for documentation retrieval: in addition to having a DEFUN documentation accessor, we would also have a SHORT-DEFUN. No! No! No! Absolutely not. That word "DEFUN" is telling you how to interpret the name of the thing whose documentation you are retrieving; it is the name of a "name space". It is 100% wrong to multiply the number of name spaces by the number of kinds of documentation you might want, and have as many symbols for documentation as we used to have for sequence functions. The level of documentation you want should be a separate argument to the DOCUMENTATION function. (Actually, like many others, I prefer FUNCTION and VARIABLE to DEFUN and DEFVAR, but that is a separate issue.) In case I haven't stated my case on this before, I will again, and I'll try to be crystal clear. I agree with you. FUNCTION is better than DEFUN, and VARIABLE is better than DEFVAR. The problem is that this does not generalize well to the many other things you would like to document. Many classes of named thing that you can define do not have a name for the class, separate from the name of the defining special form, except perhaps by deleting the three letters "DEF" from the latter name. Furthermore if you have names used only for this, there is a serious problem with remembering abbreviations. You probably won't have much trouble remembering whether it's a VARIABLE or a VAR, and might even be able to remember whether it's a STRUCTURE or a STRUCT, but when there are 10 or 20 of these, you will not be able to remember two sets of names for the same thing. It's even worse when you put in packages. Also, don't forget that this naming system necessarily has to be extensible to user-defined classes of things. This discussion worries me. The problem is that it looks like we are getting away from language design per se, and trying to design a standard user interface. Certainly you want some standardization there, on the simple things that everybody understands and agrees on. But the whole user interface field can be an impenetrable morass. There are issues of personal taste and esthetics. The ground rules for many user interface issues are dictated entirely by implementation considerations, such as whether you support only bitmap terminals, only fast displays, or all kinds of terminals. Even worse, they are dictated by what sort of users your system is intended for. It can be extremely difficult to come to any sort of agreement on this kind of thing, because everyone has a different unstated set of assumptions (model in their head) for what the discussion is about. In any case I am certain that the Common Lisp working group, or whatever we are called, is barely able to keep the language design orderly, and certainly does not have the resources to design a user interface, too. I feel quite strongly that we need to buckle down and finish the job of getting a standard language defined, and not get diverted into a lot of side-issues. I want to start serious planning of how the Lisp machine system is going to make the transition to Common Lisp, and there are still an enormous number of loose ends as well as areas where the language has diverged from the Colander edition of the manual, but has not yet reached a final conclusion. Once we have several actual, working Common Lisp implementations and the ability to exchange code routinely, we will be in a much better position to work constructively on user interfaces and other things at that level.  Date: Thursday, 7 October 1982 13:16-EDT From: Scott E. Fahlman To: Guy.Steele at CMU-10A Cc: common-lisp at SU-AI Subject: Documentation and error messages Despite my earlier opposition to one-line documentation strings, I now see the need for them. I agree with Guy that we need short and medium forms of built-in documentation for functions and short, medium, and "return value" forms for errors. These fit nicely into Moon's proposal for documentation retrieval: in addition to having a DEFUN documentation accessor, we would also have a SHORT-DEFUN. (Actually, like many others, I prefer FUNCTION and VARIABLE to DEFUN and DEFVAR, but that is a separate issue.) Guy's proposal for supplying these strings to the error forms sounds OK. I worry about adding more hair to DEFUN. Putting the doc string into DEFUN is cute, and it has had the psychological effect of encouraging people to use these strings, but it may be time to create a separate documentation-defining form. With enough good examples and social pressure -- nothing gets into the yellow pages unless every user-visible function and special variable is documented -- we would still get compliance. (document foo 'short-function "Short documentation for FOO goes here." 'function "Long documentation for FOO goes here and just to make this longer I will include this useless extra clause." 'algorithm "Uses the bubbly-quick-foo algorithm, which is O(n log n). See Knuth, volume 5. For small N, you are better off using BAR." 'bugs "With an argument of 0, destructively rewinds the disk.") (defun foo ...) We probably don't want to go for this many flavors of doc right now, but it gives us some room to grow in the future. Of course, for awhile we would support embedded doc strings in DEFUN as a compatibility measure. The embedded string would be FUNCTION (or DEFUN) documentation. -- Scott  Date: 7 October 1982 0137-EDT (Thursday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: Documentation and error messages I am a bit concerned about a couple of issues relating to English prose that the LISP spits out to one. I am primarily concerned that messages be of an appropriate length and level of detail for the situation. (No, I am *not* about to propose variables MSGLEVEL and MSGLENGTH! But something perhaps close to that.) First, some people have recognized a need for both short and long forms of documentation for functions, variables, and other things. For APROPOS applications or a quick reminder, a line or a sentence is sufficient, and you don't want APROPOS to belch 100 3-paragraph descriptions at you instead of 100 lines. On the other hand, for DESCRIBE and so on, one wants to see a relatively detailed description. Here is a quicky solution: in DEFUN, for example, let more than one documentation string appear, in order of increasing detail, thus: (DEFUN LENGTH (X) "Returns the length of the argument as an integer." "LENGTH accepts any sequence (a list or a one-dimensional array) and returns its length as a non-negative integer (in fact, as a fixnum). If the argument is an array with a fill pointer, LENGTH returns the size of the active region of the array, not that of the total memory allocated for the array." (TYPECASE ...)) This solution is not great. There is a similar problem with error messages, trying to strike a balance between conciseness and helpfulness. It would be better if it were possible to signal an error with up to three different messages: a short (one-line) error message, a longer discourse explaining the nature of the error and possible likely causes, and a description of how to recover from the error if it is possible, particularly in the case of correctable errors. For certain software that I want to be useable by non-experts, I would be willing to define a separate function for each possible error, just so that I would feel free to write lots of helpful information about an error condition. Here's an example of what I have in mind: (DEFUN UNBOUND-VARIABLE-ERROR (VAR) (HERROR ("~S unbound variable" VAR) ("The special variable ~S is currently unbound (has no value). Perhaps the variable ~S is supposed to have a value and does not, or perhaps the name of the correct variable was misspelled." VAR VAR) ("If you return a correction value, it should be the correct symbol naming the variable whose value should be used. If ther name was correctly spelled, give that variable a value first and then return that name by typing ~:@C. Otherwise, return the correct name for the variable." #\Hyper-Return))) Maybe I've gone overboard here, but I want it to be possible to provide a great amount of on-line help to the user so he doesn't have to scurry to the manual. On the other hand, the first thing you see should be short and crisp, to avoid annoying knowledgeable users. Comments? --Guy  Date: 6 October 1982 22:18-EDT From: Kent M. Pitman Subject: /BALLOT/ To: Guy.Steele at CMU-10A cc: Common-Lisp at SU-AI ~bnyxnnyyx yyyyy-yyci ymxyns-yx Notes? * * * * * ** * * (see below) Sequencing 123456789 0123456789 012345678 (2) SETF -> SET. I think we should do this, but not at this time. (4) Load Keywords. I would vote YES except: As suggested by someone when it was proposed, any mention of packages should be stricken pending the release of a package system specification. (5) LOOP. As a yellow-pages extension is ok by me. I strongly oppose its placement in the white pages. (9) MACROEXPAND. I would vote YES except: I am uncomfortable with saying that a form returns two values and then returning only one (letting the rest default to NIL). Does Common-Lisp specify anything on this? In any case, I would ammend the (cond ((and (pairp ...) ...) (values (...) t)) (t form)) to (cond (...) (t (values form nil))) to make it clear that two values are always returned. If this modification is made, I am happy with this proposal. (15) I have no use for this but have no strong objection. (22) OPTIMIZE. I would vote YES except: The use of numbers instead of keywords bothers me. The section saying which numbers can be which values and how those values will be interpreted seems to FORTRANesque to me. I think these values should be just keywords or the tight restrictions on their values should be lifted. The only use for numbers would be to allow users a fluid range of possibilities. (23) DECLARE. I also support allowing multiple declare forms at the top of a bind form. ie, (LAMBDA (X Y) (DECLARE (SPECIAL X)) (DECLARE (SPECIAL Y)) for ease in macros. Steele's proposed evaluator did this and it wasn't notably expensive. (26) I haven't thought enough about floating point to comment usefully. (28) OPEN keywords. I'm postponing judgment on this issue until the currently active CL discussion on this issue subsides.  Date: Wednesday, 6 October 1982 21:27-EDT From: Scott E. Fahlman To: common-lisp at SU-AI Subject: suggestions on floating point numbers and hash tables I was about to comment on Hedrick's suggestions when Moon popped up and said exactly what I was going to (except that I was going to be apalled rather than obnoxed at the first suggestion). So I second all of Moon's comments on these items.  Date: 6-Oct-82 17:33:19 PDT (Wednesday) From: Masinter at PARC-MAXC Subject: Re: /BALLOT/ In-reply-to: STEELE's message of 5 Oct 1982 0041-EDT To: Steele@cmu-20c cc: common-lisp@su-ai ~anyx-xy-yyyy--y-yaiy-nynd-yy 1234567890123456789012345678 4) :ERROR, :SET-DEFAULT-PATHNAME options to LOAD should be rationalized with OPEN; the handling here of search paths should logically be handled by passing on some of the options from LOAD to OPEN rather than having LOAD do special path-name processing. This is because users who manipulate files want to do similar hacking, and the mechanism should be common. 6) I feel strongly that the white pages SHOULD include a LOOP construct. I care less about which one, but I like most of Moon's proposal better than DO and what I saw of LetS. I'd get rid of AND and ELSE. I don't understand if the "COLLECT" lexical scoping includes scoping under macro expansion. 9) this seems right but not quite fully specified, e.g. LAMBDA-MACRO 25) spec here not consistent with MACROEXPAND proposal  Date: Wednesday, 6 October 1982 17:43-EDT From: MOON at SCRC-TENEX To: common-lisp at SU-AI Subject: suggestions on floating point numbers and hash tables In-reply-to: The message of 5 Oct 1982 0030-EDT from HEDRICK at RUTGERS (Mgr DEC-20s/Dir LCSR Comp Facility) Date: 5 Oct 1982 0030-EDT From: HEDRICK at RUTGERS (Mgr DEC-20s/Dir LCSR Comp Facility) When you see 1.0, it is hard to know what the precision is. We would like to make sure that if you write something out and read it back in, it is EQUAL to what you started with. Thus you should consider doing one of the following: - adopt a convention where you can tell the precision based on the number of digits printed. E.g. 1.00000 would be single, but 1.000000000000000 would be double. This obnoxes me. - always print an exponent marker, or maybe always print it when the it is not the same as READ-DEFAULT-FLOAT-FORMAT. (At the moment, we are always supplying an exponent marker when it is different from the default.) Printing an exponent marker if the format is not the default is the right alternative, I think. It also happens to be what the Lisp machine does now (which doesn't matter since we're willing to do anything reasonable). No matter what you do you can't solve the problem of trying to get the same precision on a different machine. We do not notice any way to write out hash tables. We suggest that you adopt a # syntax for that. In my opinion, it should be possible to write out and read back in as many kinds of user data structures as is possible. I certainly do not want to see hash tables vomited out at me on the terminal. But I do agree that is reasonable to have a way to put a hash table in a file. I don't think it is necessary to add a new # syntax; all that is necessary is a new keyword argument to MAKE-HASH-TABLE that provides the initial contents (as an alist or something). #. can then be used to include a hash table in other data structure being read (i.e. to put one in a place that is not a form to be evaluated). You specify a default packing factor of .8 for hash tables. I wonder whether you really want this number to be defined in the manual. You are absolutely right. Common Lisp has no business standardizing this. Finally, we wonder whether having separate MAKE-xxx-HASH-TABLE functions but the same PUT-HASH and GET-HASH for all types is the right way to go. I have complained about this before. There should be one function named MAKE-HASH-TABLE that takes keywords defining the type of hash table you want, and one set of functions for accessing. We (the Lisp machine) screwed up by ever having multiple functions for different kinds of hash tables. Although I don't quite know how one would use it, in principle it would make sense to put different kinds of items into the same hash table using different functions. Do you really mean this? I don't see how it can possibly be meaningful.  Date: 6 October 1982 17:21-EDT From: Kent M. Pitman Subject: defun semantics To: EAK at MIT-MC, Guy.Steele at CMU-10A cc: common-lisp at SU-AI Yet another thing to think about is the (DEFUN FACT (X) (COND ... (T ... (FACT ...) ... ))) (SETF #'FOO #'FACT) (SETF #'FACT #'BAR) phenomenon. My suspicion is that very few people ever want the behavior where the recursive call to FACT gets BAR's definition. It would be nice if functions were more easily renamed in this way. GLS is right that this thwarts TRACE in its current form, but perhaps a scheme can be found for making TRACE do the right thing. I have some ideas which I'll talk to people about off this list and maybe suggest later when they're better thought out. But if this could be worked out, I think having definitions closed over their original name is a good idea.  Date: 6 October 1982 15:24-EDT From: Kent M. Pitman Subject: insults To: zvona at MIT-OZ, common-lisp at SU-AI it seems to me that expressions like "knee-jerk anti-LOOPist" are highly unprofessional and have no place in this discussion. they only serve to divide people into two camps and do very little good. in discussions like these, where people have taken very strong stands on things, one would sometimes like a person to ber able to to accept others' views and change "sides" rapidly. if one "side" or the other is marked by having been called names, it can only serve to weaken the ability of that person to correctly make the technically right decision because s/he has to worry about a host of personal issues that never should have been involved: will i be branded a LOOPist? will the community no longer like me or listen to my ideas?... ALAN's remark about the "knee-jerk anti-LOOPist" does worse than imply that the person condemns LOOP without supplying an alternative, it suggests that some people obejct to LOOP as a reflex action and implicit in that is that they do not use their higher brain functions in the decision. It is, in my estimation, possible to "correctly condemn" a primitive or feature without being able to propose an adequate alternative. Certainly it has happened many times in Common-Lisp discussions. i don't even mind the clear sarcasm/humor of ALAN's paranoia because no one's likely to be hurt by that; it's not very pointed. but, please, resist the urge to do name-calling. with the general level of passion the individuals in this group have on particular issues, we just can't afford to lose track of that we're working together, not against each other. thanks,  Date: 6 Oct 1982 1222-PDT From: Dave Dyer Subject: votes To: common-lisp at SU-AI ~b n x y x y y y y n n y n x y y y a x x - y y y s - y y 0 1 2 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 -------  Date: Wednesday, 6 October 1982 14:00-EDT Sender: ZVONA at MIT-OZ From: ZVONA at MIT-MC To: common-lisp at sail I wasn't suggesting flushing LOOP, merely postponing its inclusion in the white pages until people have had time to compare LetS. I suspect that almost every LOOP expression can be re-written more perspicuously with LetS, but this may not be true; in which case both might be supported, and people could use whichever is appropriate to a problem. Or it might be decided that since a new iteration macro comes along every once in a while, none should be set in concrete. Well I think we should flush DO from Common Lisp because in spite of its utility, it is not "based on a strong theory of what loops really are". Well, if there were something that did more-or-less the same things as DO, but had a clearer theory of what is going on, wouldn't you consider flushing DO in favor of it? At least in your own code? Seriously, I doubt very much that LetS will totally replace LOOP among the tools I use any more than LOOP replaced DO. I am sick to death of knee-jerk anti-LOOPism and I am beginning to irrationally regard it as a plot to disable me as a programmer by excommunicating my most useful tools. A knee-jerk anti-LOOPist is someone that says "LOOP is a crock" and doesn't suggest an alternative. I am not a knee-jerk anti-LOOPist. I would use it in preference to DO if that was all that was available. But I would still rather use something better. DO&, which I wrote, had the advantage that the syntax was uniform and modeled on something understood (DO), whereas LOOP's syntax is higgledy-piggledy and alien to LISP. LetS is better because its syntax is exactly that of PURE LISP EXPRESSIONS. Examples for flavor: (defun copylist (list) (Rlist (Elist list))) (defun sum-first-n-integers (n) (Rsum (Eint 1 n))) -------  Date: 6 October 1982 1029-EDT (Wednesday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: FLOAT-SIGN and SIGNUM Extending FLOAT-SIGN to two arguments is useful for the same reasons as extending SIGNUM (though I'm not sure we really voted for the latter). The handling of -0.0 is the crux, as Moon points out. I would assume that (SIGNUM 0.0) => 0.0 (FLOAT-SIGN 0.0) => 1.0 (SIGNUM -0.0) => -0.0 (FLOAT-SIGN -0.0) => -1.0 (SIGNUM 0.0 x) => 0.0 (FLOAT-SIGN 0.0 x) => |x| (SIGNUM -0.0 x) => -0.0 (FLOAT-SIGN -0.0 x) => -|x| which are distinct useful behaviors, I think. --Guy  Date: 6 October 1982 1007-EDT (Wednesday) From: Guy.Steele at CMU-10A To: Earl A. Killian Subject: Re: defun semantics CC: common-lisp at SU-AI In-Reply-To: Earl A. Killian's message of 5 Oct 82 17:51-EST Defining DEFUN to make self-recursive calls not go through the function cell would making TRACE much less useful on recursive functions. --Guy  Date: Wednesday, 6 October 1982, 04:19-EDT From: David A. Moon Subject: GLS's change to Moon's floating-point extractors proposal To: common-lisp at SU-AI In-reply-to: The message of 4 Oct 82 23:55-EDT from Guy.Steele at CMU-10A Date: 4 October 1982 2355-EDT (Monday) From: Guy.Steele at CMU-10A I support Moon's proposal, but would like to suggest that FLOAT-SIGN be modified to (FLOAT-SIGN x &optional (y (float 1 x))) returns z such that x and z have same sign and (= (abs y) (abs z)). In this way (FLOAT-SIGN x) returns 1.0 or -1.0 of the same format as x, and FLOAT-SIGN of two arguments is what the IEEE proposal calls COPYSIGN, a useful function indeed in numerical code. This is the SIGNUM function, which already exists on page 125 of the Colander. If my memory of the past 2 months' discussion is accurate, it was extended to the 2-argument case; the Colander only allows one argument. FLOAT-SIGN was intended to be something else, and would return 0 or 1 rather than 1.0 or -1.0. Perhaps FLOAT-SIGN is redundant given the existence of SIGNUM. There is only one problem with this, which I think I pointed out in my message: the minus zero in the proposed IEEE standard. I'm sure that SIGNUM of this has to be -0.0 rather than -1.0 (although possibly it has to be +0.0). And MINUSP of -0.0 has to be NIL. Furthermore the standard specially specifies that (= -0.0 0.0) => T. So if you're writing a portable floating point number printer, you need some way to know to print a minus sign for minus zero. If EQ worked on numbers you could use it.  Date: Wednesday, 6 October 1982, 04:03-EDT From: David A. Moon Subject: Re: keyword pairs and OPEN To: common-lisp at SU-AI In-reply-to: The message of 5 Oct 82 23:31-EDT from Masinter at PARC-MAXC Date: 5-Oct-82 20:31:36 PDT (Tuesday) From: Masinter at PARC-MAXC Is the :DIRECTION :PROBE a proper function of "OPEN"? It seems semantically quite different; e.g., :BYTE-SIZE, :CHARACTERS etc seem pretty meaningless. Well, this is a debatable point. In terms of message passing, a probe stream has about half the messages that a real-open stream does, and doesn't have any messages that a real-open stream does not have. These messages are operations such as getting and setting attributes of the file. So you it's reasonable to think of probing as a subset of opening, or as a separate function. The Lisp machine happened to choose the former. Tenex/Tops-20 allows for "give me name of new file"; is that generally useful? Without actually creating it, how could it be? If someone else does the same thing they'll get the same name. If it does actually create it, is this different in any way from opening in OUTPUT direction? Interlisp separates out the "direction" (ACCESS method) from the "recognition mode" in its OPENFILE. (The Interlisp VM is the best description of OPENFILE). Thus, an alternative to consider would have key words: :ACCESS - one of :INPUT, :OUTPUT, :APPEND (or ...) no default :RECOG - one of :OLD, :NEW, :OLD/NEW (or ...) default depends on :ACCESS This is just the way it works now in the Lisp machine, and it proved to be totally hard to understand and use. Having separate keywords for if-exists and if-does-not-exist was a good idea on Dan's part, in my opinion. :TYPE - one of :TEXT or :BINARY or :DEFAULT (or ...) (default :TEXT) :BYTE-SIZE (only meaningful and implies :TYPE :BINARY) I'd then fold in the :IF-EXISTS and :IF-DOES-NOT-EXIST with different recognition modes. What most people then want is some notion of a search-path algorithm on recognition mode :INPUT. This sometimes takes the form of hacking with the name which is supplied, which perhaps Common Lisp should avoid. If you mean recognition in the sense of filename completion, that CERTAINLY does not belong as part of OPEN. It should be a separate function, but probably Common Lisp is not prepared to standardize things like this yet. However, I may not have understood your last paragraph.  Date: Wednesday, 6 October 1982, 01:55-EDT From: David A. Moon Subject: arrays To: common-lisp at SU-AI In-reply-to: The message of 5 Oct 82 19:24-EDT from Earl A. Killian Date: 5 October 1982 19:24-EDT From: Earl A. Killian Suggestion: Now that :TYPE to MAKE-ARRAY is :ELEMENT-TYPE, shouldn't ARRAY-TYPE be ARRAY-ELEMENT-TYPE? Yes, definitely. Or perhaps just ELEMENT-TYPE, in which case it would work for any sequence? Not clear that the concept is very useful for generalized sequences (e.g. ELEMENT-TYPE of a cons would always be T), though it might find some use in writing new sequence functions. Probably this is too random, although I wouldn't mind it. Question 1: was ARRAY-RESET-FILL-POINTER eliminated by the decision at the last meeting to use SETF exclusively? I.e. is it subsumed by (SETF (ARRAY-ACTIVE-LENGTH A) L)? (SETF (FILL-POINTER surely.  Date: 5-Oct-82 20:31:36 PDT (Tuesday) From: Masinter at PARC-MAXC Subject: Re: keyword pairs and OPEN In-reply-to: dlw at SCRC-TENEX's message of Monday, 4 October 1982, 17:08-EDT To: common-lisp at SU-AI Is the :DIRECTION :PROBE a proper function of "OPEN"? It seems semantically quite different; e.g., :BYTE-SIZE, :CHARACTERS etc seem pretty meaningless. Tenex/Tops-20 allows for "give me name of new file"; is that generally useful? Interlisp separates out the "direction" (ACCESS method) from the "recognition mode" in its OPENFILE. (The Interlisp VM is the best description of OPENFILE). Thus, an alternative to consider would have key words: :ACCESS - one of :INPUT, :OUTPUT, :APPEND (or ...) no default :RECOG - one of :OLD, :NEW, :OLD/NEW (or ...) default depends on :ACCESS :TYPE - one of :TEXT or :BINARY or :DEFAULT (or ...) (default :TEXT) :BYTE-SIZE (only meaningful and implies :TYPE :BINARY) I'd then fold in the :IF-EXISTS and :IF-DOES-NOT-EXIST with different recognition modes. What most people then want is some notion of a search-path algorithm on recognition mode :INPUT. This sometimes takes the form of hacking with the name which is supplied, which perhaps Common Lisp should avoid.  Date: 5 October 1982 22:18-EDT From: Alan Bawden Subject: ZVONA: ~xxxxxnxxxxxxxxxxxxxxxxxxxxxx To: ZVONA at MIT-MC cc: common-lisp at SU-AI Date: Tuesday, 5 October 1982 08:32-EDT From: ZVONA ~xxxxxnxxxxxxxxxxxxxxxxxxxxxx Explanation: Dick Waters' LetS, which he will release imminently, is far superior to LOOP. Unlike LOOP, which is basically a hack, it is based on a strong theory of what loops really are and what their structure is. Basically it is a compiler which takes code written in terms of streams and compiles it into efficient iterative code. Well I think we should flush DO from Common Lisp because in spite of its utility, it is not "based on a strong theory of what loops really are". Seriously, I doubt very much that LetS will totally replace LOOP among the tools I use any more than LOOP replaced DO. I am sick to death of knee-jerk anti-LOOPism and I am beginning to irrationally regard it as a plot to disable me as a programmer by excommunicating my most useful tools.  Date: 5 October 1982 22:18-EDT From: Alan Bawden Subject: ZVONA: ~xxxxxnxxxxxxxxxxxxxxxxxxxxxx To: ZVONA at MIT-MC cc: common-lisp at SU-AI Date: Tuesday, 5 October 1982 08:32-EDT From: ZVONA ~xxxxxnxxxxxxxxxxxxxxxxxxxxxx Explanation: Dick Waters' LetS, which he will release imminently, is far superior to LOOP. Unlike LOOP, which is basically a hack, it is based on a strong theory of what loops really are and what their structure is. Basically it is a compiler which takes code written in terms of streams and compiles it into efficient iterative code. Well I think we should flush DO from Common Lisp because in spite of its utility, it is not "based on a strong theory of what loops really are". Seriously, I doubt very much that LetS will totally replace LOOP among the tools I use any more than LOOP replaced DO. I am sick to death of knee-jerk anti-LOOPism and I am beginning to irrationally regard it as a plot to disable me as a programmer by excommunicating my most useful tools.  Date: 5 October 1982 19:24-EDT From: Earl A. Killian Subject: arrays To: common-lisp at SU-AI Suggestion: Now that :TYPE to MAKE-ARRAY is :ELEMENT-TYPE, shouldn't ARRAY-TYPE be ARRAY-ELEMENT-TYPE? Or perhaps just ELEMENT-TYPE, in which case it would work for any sequence? Not clear that the concept is very useful for generalized sequences (e.g. ELEMENT-TYPE of a cons would always be T), though it might find some use in writing new sequence functions. Question 1: was ARRAY-RESET-FILL-POINTER eliminated by the decision at the last meeting to use SETF exclusively? I.e. is it subsumed by (SETF (ARRAY-ACTIVE-LENGTH A) L)? Question 2: I'm not sure what resulted from the displaced array discussion. My memory tells me that every proposed use of displaced arrays was countered with an appropriate access function. Has anyone a proposed set of new access functions? Or are even these deemed unnecessary?  Date: Tuesday, 5 October 1982 19:11-EDT From: Brian G. Milnes To: STEELE at CMU-20C Cc: b.steele at CMU-10A, common-lisp at SU-AI Subject: /BALLOT/ 12345678912345678912345678 ~ayxyyynyynnyyxyxxiymyysyyx  Date: 5 October 1982 18:51-EDT From: Earl A. Killian Subject: defun semantics To: common-lisp at SU-AI Does defun add the function name to the lexical environment of the body? Should it? For example, in (defun revappend (a b) (if (null a) b (revappend (cdr a) (cons (car a) b)))) is the tail recursion implementable as a simple GO, or must the system consult the function cell of the symbol REVAPPEND? I vote for allowing the GO, i.e. adding REVAPPEND to the lexical function environment, in effect, defining DEFUN in terms of LABELS instead of LAMBDA.  Date: 5 Oct 1982 1530-PDT From: Dave Dyer Subject: comment on lambda macros To: Fahlman at CMU-20C cc: common-lisp at SU-AI In-Reply-To: Your message of Tuesday, 5 October 1982 18:16-EDT LAMBDA macros in zetalisp were borrowed from Interlisp to make it possible to extend lambda-expression syntax to accomodate Interlisp semantics. In general, LAMBDA macros allow an arbitrary translation step before application of a function. Very useful for embedded languages. There is no hair, just a few simple taps before errors are declared. -------  Date: Tuesday, 5 October 1982 18:16-EDT From: Scott E. Fahlman To: steele at CMU-20C Cc: common-lisp at SU-AI Subject: /BALLOT/ ~ b n n y y n y y y y y y n y y y y a i y m y y n n a y y 1 3 1 - 3 * 1 2 - 1 * 2 2 2 1 2 2 * 3 2 2 - 1 1 * 1 2 - Intensity 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 Issue # I have included an indication of how much I care about each issue in a way that I hope will not choke Guy's voting machine. 1 means that I will happily abide by the will of the majority; 2 means that I have a definite preference; 3 means that this issue is very important to me; 4 means that this is a non-negotiable issue. (There are no 4's here.) - means that there is no other choice presented, and the one that is presented seems OK. A * means "see below". The numbers on the third line are just index numbers so that I can see what I'm doing. 6: I am in favor of adding the LOOP package as described (once it is completed) to the language as a portable yellow pages module. I feel rather strongly that it is premature to add LOOP to the white pages. 11: Whatever is done about global vars, global constants should be the same. I oppose option 3 or any plan to make them look syntactically different. 18. I now believe that RESTART is more trouble than it is worth. I am strongly opposed to any plan, such as option 3, that would add a RESTART form but make it impossible to use this with the implicit block around a DEFUN. If you have to introduce a RESTARTABLE block, you may as well use PROG/GO. 25: I seem to be unable to locate any explanation of why Lambda macros are useful enough to be worth the bother. Looks like needless hair to me, but I seem to dimly recall some arguments for why they were needed. I'm not passionately opposed, but every page full of hairy stuff in the manual hurts us.  Date: 5 October 1982 1257-EDT (Tuesday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: Addendum to voting procedure I forgot to provide a way to indicate "no vote" on a question. Use "-" for this purpose. So a response might look like: ~ xabyb n-xxb arn-- --ax- xxa-- -x- Second, I want to emphasize again that this ballot, as with all previous ballots, is not necessarily a majority-rules vote, but an attempt to determine for each question whether there is a general consensus or not. If there is consensus, I take that as a mandate to edit the document accordingly; if not, the question remains open for discussion. --Guy  Date: Tuesday, 5 October 1982 08:32-EDT Sender: ZVONA at MIT-OZ From: ZVONA at MIT-MC To: Guy.STEELE at CMU-20C Cc: b.steele at CMU-10A, common-lisp at SU-AI Subject: /BALLOT/ ~xxxxxnxxxxxxxxxxxxxxxxxxxxxx Explanation: Dick Waters' LetS, which he will release imminently, is far superior to LOOP. Unlike LOOP, which is basically a hack, it is based on a strong theory of what loops really are and what their structure is. Basically it is a compiler which takes code written in terms of streams and compiles it into efficient iterative code. I'm not involved in common lisp. I probably don't get a vote, but this is one I really care about. -------  Date: 5 Oct 1982 0041-EDT From: STEELE at CMU-20C Subject: /BALLOT/ To: common-lisp at SU-AI cc: b.steele at CMU-10A ????????????????????????????????????????????????????????????????????????????? ? %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ? ? % ================================================================= % ? ? % = $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ = % ? ? % = $ +++++++++++++++++++++++++++++++++++++++++++++++++++++ $ = % ? ? % = $ + ############################################### + $ = % ? ? % = $ + # ///////////////////////////////////////// # + $ = % ? ? % = $ + # / The October 1982 Common LISP Ballot / # + $ = % ? ? % = $ + # ///////////////////////////////////////// # + $ = % ? ? % = $ + ############################################### + $ = % ? ? % = $ +++++++++++++++++++++++++++++++++++++++++++++++++++++ $ = % ? ? % = $$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$ = % ? ? % ================================================================= % ? ? %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ? ????????????????????????????????????????????????????????????????????????????? Here is what you have all been waiting for! I need an indication of consensus or lack thereof on the issues that have been discussed by network mail since the August 1982 meeting, particularly on those issues that were deferred for proposal for which proposals have now been made. There are 28 questions, each requiring only a one-letter answer. As always, if you don't like any of the choices, answer "x". To make my life easier by permitting mechanical collation of responses, please respond as follows: (a) send a reply message to Guy.Steele @ CMU-10A. (b) *PLEASE* be sure the string "/BALLOT/" is in the subject line, as it is in this message (the double quotes, not the slashes, are metasyntactic!). (c) The very first non-blank line of your message should have exactly 29 non-blank characters on it. The first should be a tilde ("~") and the rest should be your votes. You may put spaces between the letters to improve readability. (d) Following the first non-blank line, place any remarks about issues on which you voted "x". Thank you for your help. I would appreciate response by Friday, October 8. --Guy 1. How shall the case for a floating-point exponent specifier output by PRINT and FORMAT be determined? (a) upper case, for example 3.5E6 (b) lower case, for example 3.5e6 (c) a switch (d) implementation-dependent 2. Shall we change the name SETF to be SET? (y) yes (n) no 3. Shall there be a type specifier QUOTE, such that (QUOTE x) = (MEMBER x)? Then MEMBER can be eliminated; (MEMBER x y z) = (OR 'x 'y 'z). Also one can write such things as (OR INTEGER 'FOO) instead of (OR INTEGER (MEMBER FOO)). (y) yes (n) no 4. Shall MOON's proposal for LOAD keywords, revised as shown below, be used? (y) yes (n) no ---------------------------------------------------------------- Date: Wednesday, 25 August 1982, 14:01-EDT From: David A. Moon [slightly revised] Here is a revised proposal: Keyword Default Meaning :PACKAGE NIL NIL means use file's native package, non-NIL is a package or name of package to load into. :VERBOSE *LOAD-VERBOSE* T means print a message saying what file is being loaded into which package. :PRINT NIL T means print values of forms as they are evaluated. :ERROR T T means handle errors normally; NIL means that a file-not-found error should return NIL rather than signalling an error. LOAD returns the pathname (or truename??) of the file it loaded otherwise. :SET-DEFAULT-PATHNAME *LOAD-SET-DEFAULT-PATHNAME* T means update the pathname default for LOAD from the argument, NIL means don't. :STREAM NIL Non-NIL means this is an open stream to be loaded from. (In the Lisp machine, the :CHARACTERS message to the stream is used to determine whether it contains text or binary.) The pathname argument is presumed to be associated with the stream, in systems where that information is needed. The global variables' default values are implementation dependent, according to local conventions, and may be set by particular users according to their personal taste. I left out keywords to allow using a different set of defaults from the normal one and to allow explicit control over whether a text file or a binary file is being loaded, since these don't really seem necessary. If we put them in, the consistent names would be :DEFAULT-PATHNAME, :CHARACTERS, and :BINARY. ---------------------------------------------------------------- 5. Shall closures over dynamic variables be removed from Common LISP? (y) yes (n) no 6. Shall LOOP, as summarized below, be included in Common LISP? (y) yes (n) no ---------------------------------------------------------------- Date: 26 August 1982 18:51-EDT From: David A. Moon Here is an extremely brief summary of the proposed new LOOP design, which has not yet been finalized. Consult the writeup on LOOP in the Lisp Machine manual or MIT LCS TM-169 for background information. Constructive comments are very welcome, but please reply to BUG-LOOP at MIT-ML, not to me personally. (LOOP form form...) repeatedly evaluates the forms. In general the body of a loop consists of a series of clauses. Each clause is either: a series of one or more lists, which are forms to be evaluated for effect, delimited by a symbol or the end of the loop; or a clause-introducing symbol followed by idiosyncratic syntax for that kind of clause. Symbols are compared with SAMEPNAMEP. Atoms other than symbols are in error, except where a clause's idiosyncratic syntax permits. 1. Primary clauses 1.1 Iteration driving clauses These clauses run a local variable through a series of values and/or generate a test for when the iteration is complete. REPEAT FOR/AS ... CYCLE ... I won't go into the full syntax here. Features include: setting to values before starting/on the first iteration/on iterations after the first; iterating through list elements/conses; iterating through sequence elements, forwards or backwards, with or without sequence-type declaration; iterating through arithmetic progressions. CYCLE reverts to the beginning of the series when it runs out instead of terminating the iteration. It is also possible to control whether or not an end-test is generated and whether there is a special epilogue only evaluated when an individual end-test is triggered. 1.2 Prologue and Epilogue INITIALLY form form... forms to be evaluated before starting, but after binding local variables. FINALLY form form... forms to be evaluated after finishing. 1.3 Delimiter DO a sort of semicolon needed in odd situations to terminate a clause, for example between an INITIALLY clause and body forms when no named clause (e.g. an iteration-driving clause) intervenes. We prefer this over parenthesization of clauses because of the general philosophy that it is more important to make the simple cases as readable as possible than to make micro-improvements in the complicated cases. 1.4 Blockname NAMED name Gives the block generated by LOOP a name so that RETURN-FROM may be used. This will be changed to conform with whatever is put into Common Lisp for named PROGs and DOs, if necessary. 2. Relevant special forms The following special forms are useful inside the body of a LOOP. Note that they need not appear at top level, but may be nested inside other Lisp forms, most usefully bindings and conditionals. (COLLECT [USING ] [INTO ] [BACKWARDS] [FROM ] [IF-NONE ] [[TYPE] ]) This special form signals an error if not used lexically inside a LOOP. Each time it is evaluated, is evaluated and accumulated in a way controlled by ; the default is to form an ordered list. The accumulated values are returned from the LOOP if it is finished normally, unless INTO is used to put them into a variable (which gets bound locally to the LOOP). Certain accumulation modes (boolean AND and OR) cause immediate termination of the LOOP as soon as the result is known, when not collecting into a variable. Collection modes are extensible by the user. A brief summary of predefined ones includes aggregated boolean tests; lists (both element-by-element and segment-by-segment); commutative/associative arithmetic operators (plus, times, max, min, gcd, lcm, count); sets (union, intersection, adjoin); forming a sequence (array, string). Multiple COLLECT forms may appear in a single loop; they are checked for compatibility (the return value cannot both be a list of values and a sum of numbers, for example). (RETURN value) returns immediately from a LOOP, as from any other block. RETURN-FROM works too, of course. (LOOP-FINISH) terminates the LOOP, executing the epilogue and returning any value defined by a COLLECT special form. [Should RESTART be interfaced to LOOP, or only be legal for plain blocks?] 3. Secondary clauses These clauses are useful abbreviations for things that can also be done using the primary clauses and Lisp special forms. They exist to make simple cases more readable. As a matter of style, their use is strongly discouraged in complex cases, especially those involving complex or nested conditionals. 3.1 End tests WHILE (IF (NOT ) (LOOP-FINISH)) UNTIL (IF (LOOP-FINISH)) 3.2 Conditionals WHEN The clause is performed conditionally. IF synonymous with WHEN UNLESS opposite of WHEN AND May be suffixed to a conditional. These two ELSE might be flushed as over-complex. 3.3 Bindings WITH ... Equivalent to wrapping LET around the LOOP. This exists to promote readability by decreasing indentation. 3.4 Return values RETURN synonymous with (RETURN ) COLLECT ... synonymous with (COLLECT ...) NCONC ... synonymous with (COLLECT ... USING NCONC) APPEND, SUM, COUNT, MINIMIZE, etc. are analogous ALWAYS, NEVER, THEREIS abbreviations for boolean collection 4. Extensibility There are ways for users to define new iteration driving clauses which I will not go into here. The syntax is more flexible than the existing path mechanism. There are also ways to define new kinds of collection. 5. Compatibility The second generation LOOP will accept most first-generation LOOP forms and execute them in the same way, although this was not a primary goal. Some complex (and unreadable!) forms will not execute the same way or will be errors. 6. Documentation We intend to come up with much better examples. Examples are very important for developing a sense of style, which is really what LOOP is all about. ---------------------------------------------------------------- 7. Regardless of the outcome of the previous question, shall CYCLE be retained and be renamed LOOP, with the understanding that statements of the construct must be non-atomic, and atoms as "statements" are reserved for extensions, and any such extensions must be compatible with the basic mening as a pure iteration construct? (y) yes (n) no 8. Shall ARRAY-DIMENSION be changed by exchanging its arguments, to have the array first and the axis number second, to parallel other indexing operations? (y) yes (n) no 9. Shall MACROEXPAND, as described below, replace the current definition? (y) yes (n) no ---------------------------------------------------------------- Date: Sunday, 29 August 1982, 21:26-EDT From: David A. Moon Here is my promised proposal, with some help from Alan. MACRO-P becomes a predicate rather than a pseudo-predicate. Everything on pages 92-93 (29July82) is flushed. Everything, including the compiler, expands macros by calling MACROEXPAND or MACROEXPAND-1. A variable, *MACROEXPAND-HOOK*, is provided to allow implementation of displacing, memoization, etc. The easiest way to show the details of the proposal is as code. I'll try to make it exemplary. (DEFVAR *MACROEXPAND-HOOK* 'FUNCALL) (DEFUN MACROEXPAND (FORM &AUX CHANGED) "Keep expanding the form until it is not a macro-invocation" (LOOP (MULTIPLE-VALUE (FORM CHANGED) (MACROEXPAND-1 FORM)) (IF (NOT CHANGED) (RETURN FORM)))) (DEFUN MACROEXPAND-1 (FORM) "If the form is a macro-invocation, return the expanded form and T. This is the only function that is allowed to call macro expander functions. *MACROEXPAND-HOOK* is used to allow memoization." (DECLARE (VALUES FORM CHANGED-FLAG)) (COND ((AND (PAIRP FORM) (SYMBOLP (CAR FORM)) (MACRO-P (CAR FORM))) (LET ((EXPANDER (---get expander function--- (CAR FORM)))) ---check for wrong number of arguments--- (VALUES (FUNCALL *MACROEXPAND-HOOK* EXPANDER FORM) T))) (T FORM))) ;You can set *MACROEXPAND-HOOK* to this to get traditional displacing (DEFUN DISPLACING-MACROEXPAND-HOOK (EXPANDER FORM) (LET ((NEW-FORM (FUNCALL EXPANDER FORM))) (IF (ATOM NEW-FORM) (SETQ NEW-FORM `(PROGN ,NEW-FORM))) (RPLACA FORM (CAR NEW-FORM)) (RPLACD FORM (CDR NEW-FORM)) FORM)) The above definition of MACROEXPAND-1 is oversimplified, since it can also expand other things, including lambda-macros (the subject of a separate proposal that has not been sent yet) and possibly implementation-dependent things (substs in the Lisp machine, for example). The important point here is the division of labor. MACROEXPAND-1 takes care of checking the length of the macro-invocation to make sure it has the right number of arguments [actually, the implementation is free to choose how much of this is done by MACROEXPAND-1 and how much is done by code inserted into the expander function by DEFMACRO]. The hook takes care of memoization. The macro expander function is only concerned with translating one form into another, not with bookkeeping. It is reasonable for certain kinds of program-manipulation programs to bind the hook variable. I introduced a second value from MACROEXPAND-1 instead of making MACROEXPAND use the traditional EQ test. Otherwise a subtle change would have been required to DISPLACING-MACROEXPAND-HOOK, and some writers of hooks might get it wrong occasionally, and their code would still work 90% of the time. Other issues: On page 93 it says that MACROEXPAND ignores local macros established by MACROLET. This is clearly incorrect; MACROEXPAND has to get called with an appropriate lexical context available to it in the same way that EVAL does. They are both parts of the interpreter. I don't have anything to propose about this now; I just want to point out that there is an issue. I don't think we need to deal with the issue immediately. A related issue that must be brought up is whether the Common Lisp subset should include primitives for accessing and storing macro-expansion functions. Currently there is only a special form (MACRO) to set a macro-expander, and no corresponding function. The Lisp machine expedient of using the normal function-definition primitive (FDEFINE) with an argument of (MACRO . expander) doesn't work in Common Lisp. Currently there is a gross way to get the macro expander function, but no reasonable way. I don't have a clear feeling whether there are programs that would otherwise be portable except that they need these operations. ---------------------------------------------------------------- 10. Shall all global system-defined variables have names beginning and ending with "*", for example *PRINLEVEL* instead of PRINLEVEL and *READ-DEFAULT-FLOAT-FORMAT* instead of READ_DEFAULT-FLOAT-FORMAT? (y) yes (n) no 11. Same question for named constants (other than T and NIL), such as *PI* for PI and *MOST-POSITIVE-FIXNUM* for MOST-POSITIVE-FIXNUM. (y) yes (n) no (o) yes, but use a character other than "*" 12. Shall a checking form CHECK-TYPE be introduced as described below? (y) yes (n) no ---------------------------------------------------------------- Date: Thursday, 26 August 1982, 03:04-EDT From: David A. Moon See p.275 of the 29 July Common Lisp manual and p.275 of the revision handed out at the Lisp conference. I suggest that we include CHECK-ARG-TYPE in the language. Although CHECK-ARG, CHECK-ARG-TYPE, and ASSERT have partially-overlapping functionality, each has its own valuable uses and I think all three ought to be in the language. Note that CHECK-ARG and CHECK-ARG-TYPE are used when you want explicit run-time checking, including but not limited to writing the interpreter (which of course is written in Lisp, not machine language!). The details: CHECK-ARG-TYPE arg-name type &OPTIONAL type-string [macro] If (TYPEP arg-name 'type) is false, signal an error. The error message includes arg-name and a "pretty" English-language form of type, which can be overridden by specifying type-string (this override is rarely used). Proceeding from the error sets arg-name to a new value and makes the test again. Currently arg-name must be a variable, but it should be generalized to any SETF'able place. type and type-string are not evaluated. This isn't always used for checking arguments, since the value of any variable can be checked, but it is usually used for arguments and there isn't an alternate name that more clearly describes what it does. Date: 2 Sep 1982 12:30 PDT From: JonL at PARC-MAXC PDP10 MacLisp and VAX/NIL have had the name CHECK-TYPE for several years for essentially this functionality (unless someone has recently renamed it). Since it is used to certify the type of any variable's value, it did not include the "-ARG" part. The motivation was to have a "checker" which was more succinct than CHECK-ARGS, but which would generally open-code the type test (and hence introduce no delay to the non-error case). I rather prefer the semantics you suggested, namely that the second argument to CHECK-TYPE be a type name (given the CommonLisp treatment of type hierarchy). At some level, I'd think a "promise" of fast type checking should be guaranteed (in compiled code) so that persons will prefer to use this standardized facililty; without some indication of performance, one would be tempted to write his own in order not to slow down the common case. ---------------------------------------------------------------- 13. Shall a checking form CHECK-SUBSEQUENCE be introduced as described below? (y) yes (n) no ---------------------------------------------------------------- Date: 2 Sep 1982 12:30 PDT From: JonL at PARC-MAXC If the general sequence functions continue to thrive in CommonLisp, I'd like to suggest that the corresponding CHECK-SUBSEQUENCE macro (or whatever renaming of it should occur) be included in CommonLisp. CHECK-SUBSEQUENCE ( ) &optional ) provides a way to certify that holds a sequence datum of the type , or of any suitable sequence type (e.g., LIST, or STRING or VECTOR etc) if is null; and that the indicated subsequence in it is within the size limits. [GLS: probably is more appropriate than for Common LISP.] ---------------------------------------------------------------- 14. Shall the functions LINE-OUT and STRING-OUT, eliminated in November, be reinstated? (y) yes (n) no 15. Shall the REDUCE function be added as described below? (y) yes (n) no ---------------------------------------------------------------- Date: 3 September 1982 1756-EDT (Friday) From: Guy.Steele at CMU-10A I would like to mildly re-propose the REDUCE function for Common LISP, now that adding it would require only one new function, not ten or fifteen: REDUCE function sequence &KEY :START :END :FROM-END :INITIAL-VALUE The specified subsequence of "sequence" is reduced, using the "function" of two arguments. The reduction is left-associative, unless :FROM-END is not false, in which case it is right-associative. If the an :INITIAL-VALUE is given, it is logically placed before the "sequence" (after it if :FROM-END is true) and included in the reduction operation. If no :INITIAL-VALUE is given, then the "sequence" must not be empty. (An alternative specification: if no :INITIAL-VALUE is given, and "sequence" is empty, then "function" is called with zero arguments and the result returned. How about that? This idea courtesy of Dave Touretzky.) (REDUCE #'+ '(1 2 3 4)) => 10 (REDUCE #'- '(1 2 3 4)) => -8 (REDUCE #'- '(1 2 3 4) :FROM-END T) => -2 ;APL-style (REDUCE #'LIST '(1 2 3 4)) => (((1 2) 3) 4) (REDUCE #'LIST '(1 2 3 4) :FROM-END T) => (1 (2 (3 4))) (REDUCE #'LIST '(1 2 3 4) :INITIAL-VALUE 'FOO) => ((((FOO 1) 2) 3) 4) (REDUCE #'LIST '(1 2 3 4) :FROM-END T :INITIAL-VALUE 'FOO) => (1 (2 (3 (4 FOO)))) ---------------------------------------------------------------- 16. Shall the Bawden/Moon solution to the "invisible block" problem be accepted? The solution is to define (RETURN x) to mean precisely (RETURN-FROM NIL x), and to specify that essentially all standard iterators produce blocks named NIL. A block with a name other than NIL cannot capture a RETURN, only a RETURN-FROM with a matching name. (y) yes (n) no 17. Shall the TAGBODY construct be incorporated? This expresses just the behavior of the GO aspect of a PROG. Any atoms in the body are not evaluated, but serve as tags that may be specified to GO. Tags have lexical scope and dynamic extent. TAGBODY always returns NIL. (y) yes (n) no 18. What shall be done about RESTART? The following alternatives seem to be the most popular: (a) Have no RESTART form. (b) RESTART takes the name of a block. What happens when you say (RESTART NIL) must be clarified for most iteration constructs. (c) There is a new binding form called, say, RESTARTABLE. Within (RESTARTABLE FOO . body), (RESTART FOO) acts as a jump to the top of the body of the enclosing, matching RESTARTABLE form. RESTART tags have lexical scope and dynamic extent. 19. Shall there be a built-in identity function, and if so, what shall it be called? (c) CR (i) IDENTITY (n) no such function 20. Shall the #*... bit-string syntax replace #"..."? That is, shall what was before written #"10010" now be written #*10010 ? (y) yes (n) no 21. Which of the two outstanding array proposals (below) shall be adopted? (s) the "simple" proposal (r) the "RPG memorial" proposal (m) the "simple" proposal as amended by Moon ---------------------------------------------------------------- *********** "Simple" proposal ********** Date: Thursday, 16 September 1982 23:27-EDT From: Scott E. Fahlman Here is a revision of my array proposal, fixed up in response to some of the feedback I've received. See if you like it any better than the original. In particular, I have explictly indicated that certain redundant forms such as MAKE-VECTOR should be retained, and I have removed the :PRINT keyword, since I now believe that it causes more trouble than it is worth. A revised printing proposal appears at the end of the document. Arrays can be 1-D or multi-D. All arrays can be created by MAKE-ARRAY and can be accessed with AREF. Storage is done via SETF of an AREF. The term VECTOR refers to any array of exactly one dimension. Vectors are special, in that they are also sequences, and can be referenced by ELT. Also, only vectors can have fill pointers. Vectors can be specialized along several distinct axes. The first is by the type of the elements, as specified by the :ELEMENT-TYPE keyword to MAKE-ARRAY. A vector whose element-type is STRING-CHAR is referred to as a STRING. Strings, when they print, use the "..." syntax; they also are the legal inputs to a family of string-functions, as defined in the manual. A vector whose element-type is BIT (alias (MOD 2)), is a BIT-VECTOR. These are special because they form the set of legal inputs to the boolean bit-vector functions. (We might also want to print them in a strange way -- see below.) Some implementations may provide a special, highly efficient representation for simple vectors. A simple vector is (of course) 1-D, cannot have a fill pointer, cannot be displaced, and cannot be altered in size after its creation. To get a simple vector, you use the :SIMPLE keyword to MAKE-ARRAY with a non-null value. If there are any conflicting options specified, an error is signalled. If an implementation does not support simple vectors, this keyword/value is ignored except that the error is still signalled on inconsistent cases. We need a new set of type specifiers for simple things: SIMPLE-VECTOR, SIMPLE-STRING, and SIMPLE-BIT-VECTOR, with the corresponding type-predicate functions. Simple vectors are referenced by AREF in the usual way, but the user may use THE or DECLARE to indicate at compile-time that the argument is simple, with a corresponding increase in efficiency. Implementations that do not support simple vectors ignore the "simple" part of these declarations. Strings (simple or non-simple) self-eval; all other arrays cause an error when passed to EVAL. EQUAL descends into strings, but not into any other arrays. EQUALP descends into arrays of all kinds, comparing the corresponding elements with EQUALP. EQUALP is false if the array dimensions are not the same, but it is not sensitive to the element-type of the array, whether it is simple, etc. In comparing the dimensions of vectors, EQUALP uses the length from 0 to the fill pointer; it does not look at any elements beyond the fill pointer. The set of type-specifiers required for all of this is ARRAY, VECTOR, STRING, BIT-VECTOR, SIMPLE-VECTOR, SIMPLE-STRING, SIMPLE-BIT-VECTOR. Each of these has a corresponding type-P predicate, and each can be specified in list from, along with the element-type and dimension(s). MAKE-ARRAY takes the following keywords: :ELEMENT-TYPE, :INITIAL-VALUE, :INITIAL-CONTENTS, :FILL-POINTER, and :SIMPLE. There is still some discussion as to whether we should retain array displacement, which requires :DISPLACED-TO and :DISPLACED-INDEX-OFFSET. The following functions are redundant, but should be retained for clarity and emphasis in code: MAKE-VECTOR, MAKE-STRING, MAKE-BIT-VECTOR. MAKE-VECTOR takes the same keywords as MAKE-ARRAY, but can only take a single integer as the dimension argument. MAKE-STRING and MAKE-BIT-VECTOR are like MAKE-VECTOR, but do not take the :ELEMENT-TYPE keyword, since the element-type is implicit. Similarly, we should retain the forms VREF, CHAR, and BIT, which are identical in operation to AREF, but which declare their aray argument to be VECTOR, STRING, or BIT-VECTOR, respectively. If the :SIMPLE keyword is not specified to MAKE-ARRAY or related forms, the default is NIL. However, vectors produced by random forms such as CONCATENATE are simple, and vectors created when the reader sees #(...) or "..." are also simple. As a general rule, arrays are printed in a simple format that, upon being read back in, produces a form that is EQUALP to the original. However, some information may be lost in the printing process: element-type restrictions, whether a vector is simple, whether it has a fill pointer, whether it is displaced, and the identity of any element that lies beyond the fill pointer. This choice was made to favor ease of interactive use; if the user really wants to preserve in printed form some complex data structure containing non-simple arrays, he will have to develop his own printer. A switch, SUPPRESS-ARRAY-PRINTING, is provided for users who have lots of large arrays around and don't want to see them trying to print. If non-null, this switch causes all arrays except strings to print in a short, non-readable form that does not include the elements: #. In addition, the printing of arrays and vectors (but not of strings) is subject to PRINLEVEL and PRINLENGTH. Strings, simple or otherwise, print using the "..." syntax. Upon read-in, the "..." syntax creates a simple string. Bit-vectors, simple or otherwise, print using the #"101010..." syntax. Upon read-in, this format produces a simple bit-vector. Bit vectors do observe SUPPRESS-ARRAY-PRINTING. All other vectors print out using the #(...) syntax, observing PRINLEVEL, PRINLENGTH, and SUPPRESS-ARRAY-PRINTING. This format reads in as a simple vector of element-type T. All other arrays print out using the syntax #nA(...), where n is the number of dimensions and the list is a nest of sublists n levels deep, with the array elements at the deepest level. This form observes PRINLEVEL, PRINLENGTH, and SUPPRESS-ARRAY-PRINTING. This format reads in as an array of element-type T. Query: I am still a bit uneasy about the funny string-like syntax for bit vectors. Clearly we need some way to read these in that does not turn into a type-T vector. An alternative might be to allow #(...) to be a vector of element-type T, as it is now, but to take the #n(...) syntax to mean a vector of element-type (MOD n). A bit-vector would then be #2(1 0 1 0...) and we would have a parallel notation available for byte vectors, 32-bit word vectors, etc. The use of the #n(...) syntax to indicate the length of the vector always struck me as a bit useless anyway. One flaw in this scheme is that it does not extend to multi-D arrays. Before someone suggests it, let me say that I don't like #nAm(...), where n is the rank and m is the element-type -- it would be too hard to remember which number was which. But even with this flaw, the #n(...) syntax might be useful. ********** "RPG memorial" proposal ********** Date: Thursday, 23 September 1982 00:38-EDT From: Scott E. Fahlman Several people have stated that they dislike my earlier proposal because it uses the good names (VECTOR, STRING, BIT-VECTOR, VREF, CHAR, BIT) on general 1-D arrays, and makes the user say "simple" when he wants one of the more specialized high-efficiency versions. This makes extra work for users, who will want simple vectors at least 95% of the time. In addition, there is the argument that simple vectors should be thought of as a first-class data-type (in implementations that provide them) and not as a mere degenerate form of array. Just to see what it looks like, I have re-worked the earlier proposal to give the good names to the simple forms. This does not really eliminate any of the classes in the earlier proposal, since each of those classes had some attributes or operations that distinguished it from the others. Since there are getting to be a lot of proposals around, we need some nomencalture for future discussions. My first attempt, with the user-settable :PRINT option should be called the "print-switch" proposal; the next one, with the heavy use of the :SIMPLE switch should be the "simple-switch" proposal; this one can be called the "RPG memorial" proposal. Let me know what you think about this vs. the simple-switch version -- I can live with either, but I really would like to nail this down pretty soon so that we can get on with the implementation. Arrays can be 1-D or multi-D. All arrays can be created by MAKE-ARRAY and can be accessed with AREF. Storage is done via SETF of an AREF. 1-D arrays are special, in that they are also of type SEQUENCE, and can be referenced by ELT. Also, only 1-D arrays can have fill pointers. Some implementations may provide a special, highly efficient representation for simple 1-D arrays, which will be of type VECTOR. A vector is 1-dimensional, cannot have a fill pointer, cannot be displaced, and cannot be altered in size after its creation. To get a vector, you use the :VECTOR keyword to MAKE-ARRAY with a non-null value. If there are any conflicting options specified, an error is signalled. The MAKE-VECTOR form is equivalent to MAKE-ARRAY with :VECTOR T. A STRING is a VECTOR whose element-type (specified by the :ELEMENT-TYPE keyword) is STRING-CHAR. Strings are special in that they print using the "..." syntax, and they are legal inputs to a class of "string functions". Actually, these functions accept any 1-D array whose element type is STRING-CHAR. This more general class is called a CHAR-SEQUENCE. A BIT-VECTOR is a VECTOR whose element-type is BIT, alias (MOD 2). Bit-vectors are special in that they print using the #*... syntax, and they are legal inputs to a class of boolean bit-vector functions. Actually, these functions accept any 1-D array whose element-type is BIT. This more general class is called a BIT-SEQUENCE. All arrays can be referenced via AREF, but in some implementations additional efficiency can be obtained by declaring certain objects to be vectors, strings, or bit-vectors. This can be done by normal type-declarations or by special accessing forms. The form (VREF v n) is equivalent to (AREF (THE VECTOR v) n). The form (CHAR s n) is equivalent to (AREF (THE STRING s) n). The form (BIT b n) is equivalent to (AREF (THE BIT-VECTOR b) n). If an implementation does not support vectors, the :VECTOR keyword is ignored except that the error is still signalled on inconsistent cases; The additional restrictions on vectors are not enforced. MAKE-VECTOR is treated just like the equivalent make-array. VECTORP is true of every 1-D array, STRINGP of every CHAR-SEQUENCE, and BIT-VECTOR of every BIT-SEQUENCE. CHAR-SEQUENCEs, including strings, self-eval; all other arrays cause an error when passed to EVAL. EQUAL descends into CHAR-SEQUENCEs, but not into any other arrays. EQUALP descends into arrays of all kinds, comparing the corresponding elements with EQUALP. EQUALP is false if the array dimensions are not the same, but it is not sensitive to the element-type of the array, whether it is a vector, etc. In comparing the dimensions of vectors, EQUALP uses the length from 0 to the fill pointer; it does not look at any elements beyond the fill pointer. The set of type-specifiers required for all of this is ARRAY, VECTOR, STRING, BIT-VECTOR, SEQUENCE, CHAR-SEQUENCE, and BIT-SEQUENCE. Each of these has a corresponding type-P predicate, and each can be specified in list from, along with the element-type and dimension(s). MAKE-ARRAY takes the following keywords: :ELEMENT-TYPE, :INITIAL-VALUE, :INITIAL-CONTENTS, :FILL-POINTER, :DISPLACED-TO, :DISPLACED-INDEX-OFFSET, and :VECTOR. The following functions are redundant, but should be retained for clarity and emphasis in code: MAKE-VECTOR, MAKE-STRING, MAKE-BIT-VECTOR. MAKE-VECTOR takes a single length argument, along with :ELEMENT-TYPE, :INITIAL-VALUE, and :INITIAL-CONTENTS. MAKE-STRING and MAKE-BIT-VECTOR are like MAKE-VECTOR, but do not take the :ELEMENT-TYPE keyword, since the element-type is implicit. If the :VECTOR keyword is not specified to MAKE-ARRAY or related forms, the default is NIL. However, sequences produced by random forms such as CONCATENATE are vectors. Strings always are printed using the "..." syntax. Bit-vectors always are printed using the #*... syntax. Other vectors always print using the #(...) syntax. Note that in the latter case, any element-type restriction is lost upon readin, since this form always produces a vector of type T when it is read. However, the new vector will be EQUALP to the old one. The #(...) syntax observes PRINLEVEL, PRINLENGTH, and SUPPRESS-ARRAY-PRINTING. The latter switch, if non-NIL, causes the array to print in a non-readable form: #. CHAR-SEQUENCEs print out as though they were strings, using the "..." syntax. BIT-SEQUENCES print out as BIT-STRINGS, using the #*... syntax. All other arrays print out using the #nA(...) syntax, where n is the number of dimensions and the list is actually a list of lists of lists, nested n levels deep. The array elements appear at the lowest level. The #A syntax also observes PRINLEVEL, PRINLENGTH, and SUPPRESS-ARRAY-PRINTING. The #A format reads in as a non-displaced array of element-type T. Note that when an array is printed and read back in, the new version is EQUALP to the original, but some information about the original is lost: whether the original was a vector or not, element type restrictions, whether the array was displaced, whether there was a fill pointer, and the identity of any elements beyond the fill-pointer. This choice was made to favor ease of interactive use; if the user really wants to preserve in printed form some complex data structure containing more complex arrays, he will have to develop his own print format and printer. ********** Moon revision of "simple" proposal ********** Date: Thursday, 30 September 1982 01:59-EDT From: MOON at SCRC-TENEX I prefer the "simple switch" to the "RPG memorial" proposal, with one modification to be found below. The reason for this preference is that it makes the "good" name, STRING for example, refer to the general class of objects, relegating the efficiency decision to a modifier ("simple"). The alternative makes the efficiency issue too visible to the casual user, in my opinion. You have to always be thinking "do I only want this to work for efficient strings, which are called strings, or should it work for all kinds of strings, which are called arrays of characters?". Better to say, "well this works for strings, and hmm, is it worth restricting it to simple-strings to squeeze out maximal efficiency"? Lest this seem like I am trying to sabotage the efficiency of Lisp implementations that are stuck with "stock" hardware, consider the following: In the simple switch proposal, how is (MAKE-ARRAY 100) different from (MAKE-ARRAY 100 :SIMPLE T)? In fact, there is only one difference--it is an error to use ADJUST-ARRAY-SIZE on the latter array, but not on the former. Except for this, simpleness consists, simply, of the absence of options. This suggests to me that the :SIMPLE option be flushed, and instead a :ADJUSTABLE-SIZE option be added (see, I pronounce the colons). Even on the Lisp machine, where :ADJUSTABLE-SIZE makes no difference, I think it would be an improvement, merely for documentation purposes. Now everything makes sense: if you don't ask for any special features in your arrays, you get simple ones, which is consistent with the behavior of the sequence functions returning simple arrays always. And if some implementation decides they need the sequence functions to return non-simple arrays, they can always add additional keywords to them to so specify. The only time you need to know about the word "simple" at all is if you are making type declarations for efficiency, in which case you have to decide whether to declare something to be a STRING or a SIMPLE-STRING. And it makes sense that the more restrictive declaration be a longer word. This also meets RPG's objection, which I think boils down to the fact that he thought it was stupid to have :SIMPLE T all over his programs. He was right. I'm fairly sure that I don't understand the portability issues that KMP brought up (I don't have a whole lot of time to devote to this). But I think that in my proposal STRINGP and SIMPLE-STRINGP are never the same in any implementation; for instance, in the Lisp machine STRINGP is true of all strings, while SIMPLE-STRINGP is only true of those that do not have fill-pointers. If we want to legislate that the :ADJUSTABLE-SIZE option is guaranteed to turn off SIMPLE-STRINGP, I expect I can dig up a bit somewhere to remember the value of the option. This would in fact mean that simple-ness is a completely implementation-independent concept, and the only implementation-dependence is how much (if any) efficiency you gain by using it, and how much of that efficiency you get for free and how much you get only if you make declarations. Perhaps the last sentence isn't obvious to everyone. On the LM-2 Lisp machine, a simple string is faster than a non-simple string for many operations. This speed-up happens regardless of declarations; it is a result of a run-time dispatch to either fast microcode or slow microcode. On the VAX with a dumb compiler and no tuning, a simple string is only faster if you make declarations. On the VAX with a dumb compiler but some obvious tuning of sequence and string primitives to move type checks out of inner loops (making multiple copies of the inner loop), simple strings are faster for these operations, but still slow for AREF unless you make a type declaration. On the VAX with a medium-smart compiler that does the same sort of tuning on user functions, simple strings are faster for user functions, too, if you only declare (OPTIMIZE SPEED) [assuming that the compiler prefers space over speed by default, which is the right choice in most implementations], and save space as well as time if you go whole hog and make a type declaration. On the 3600 Lisp machine, you have sort of a combination of the first case and the last case. I also support the #* syntax for bit vectors, rather than the #" syntax. It's probably mere temporal accident that the simple switch proposal uses #" while the RPG memorial proposal uses #*. To sum up: A vector is a 1-dimensional array. It prints as #(foo bar) or # depending on the value of a switch. A string is a vector of characters. It always prints as "foo". Unlike all other arrays, strings self-evaluate and are compared by EQUAL. A bit-vector is a vector of bits. It always prints as #*101. Since as far as I can tell these are redundant with integers, perhaps like integers they should self-evaluate and be compared by EQUAL. I don't care. A simple-vector, simple-string, or simple-bit-vector is one of the above with none of the following MAKE-ARRAY (or MAKE-STRING) options specified: :FILL-POINTER :ADJUSTABLE-SIZE :DISPLACED-TO :LEADER-LENGTH, :LEADER-LIST (in implementations that offer them) There are type names and predicates for the three simple array types. In some implementations using the type declaration gets you more efficient code that only works for that simple type, which is why these are in the language at all. There are no user-visible distinctions associated with simpleness other than those implied by the absence of the above MAKE-ARRAY options. ---------------------------------------------------------------- 22. Shall the following proposal for the OPTIMIZE declaration be adopted? (y) yes (n) no ---------------------------------------------------------------- Date: Wednesday, 15 September 1982 20:51-EDT From: Scott E. Fahlman At the meeting I volunteered to produce a new proposal for the OPTIMIZE declaration. Actually, I sent out such a proposal a couple of weeks ago, but somehow it got lost before reaching SU-AI -- both that machine and CMUC have been pretty flaky lately. I did not realize that the rest of you had not seen this proposal until a couple of days ago. Naturally, this is the one thing I did not keep a copy of, so here is my reconstruction. I should say that this proposal is pretty ugly, but it is the best that I've been able to come up with. If anyone out there can do better, feel free. Guy originally proposed a format like (DECLARE (OPTIMIZE q1 q2 q3)), where each of the q's is a quality from the set {SIZE, SPEED, SAFETY}. (He later suggested to me that COMPILATION-SPEED would be a useful fourth quality.) The ordering of the qualities tells the system which to optimize for. The obvious problem is that you sometimes want to go for, say, SPEED above all else, but usually you want some level of compromise. There is no way in this scheme to specify how strongly the system should favor one quality over another. We don't need a lot of gradations for most compilers, but the simple ordering is not expressive enough. One possibility is to simply reserve the OPTIMIZE declaration for the various implementations, but not to specify what is done with it. Then the implementor could specify in the red pages whatever declaration scheme his compiler wants to follow. Unfortunately, this means that such declarations would be of no use when the code is ported to another Common Lisp, and users would have no portable way to flag that some function is an inner loop and should be super-fast, or whatever. The proposal below tries to provide a crude but adequate optimization declaration for portable code, while still making it possible for users to fine-tune the compiler's actions for particular implementations. What I propose is (DECLARE (OPTIMIZE (qual1 value1) (qual2 value2) ...), where the qualities are the four mentioned above and each is paired with a value from 0 to 3 inclusive. The ordering of the clauses doesn't matter, and any quality not specified gets a default value of 1. The intent is that {1, 1, 1, 1} would be the compiler's normal default -- whatever set of compromises the implementor believes is appropriate for his user community. A setting of 0 for some value is an indication that the associated quality is unimportant in this context and may be discrimintaed against freely. A setting of 2 indicates that the quality should be favored more than normal, and a setting of 3 means to go all out to favor that quality. Only one quality should be raised above 1 at any one time. The above specification scheme is crude, but sufficiently expressive for most needs in portable code. A compiler implementor will have specific decisions to make -- whether to suppress inline expansions, whether to type-check the arguments to CAR and CDR, whether to check for overflow on arithmetic declared to be FIXNUM, whether to run the peephole optimizer, etc. -- and it is up to him to decide how to tie these decisions to the above values so as to match the users expressed wishes. These decision criteria should be spelled out in that implementation's red pages. For example, it might be the case that the peephole optimizer is not run if COMPILER-SPEED > 1, that type checking for the argument to CAR and CDR is suppressed if SPEED > SAFETY+1, etc. ---------------------------------------------------------------- 23. Shall it be permitted for macros calls to expand into DECLARE forms and then be recognized as valid declarations? For example: (DEFMACRO CUBOIDS (&REST VARS) `(DECLARE (TYPE (ARRAY SHORT-FLONUM 3) ,@VARS) (SPECIAL ,@VARS) (OPTIMIZE SPEED) (INLINE HACK-CUBOIDS))) (DEFUN CUBOID-EXPERT (A B C D) (CUBOIDS A C) ...) This would not allows macros calls *within* a DECLARE form, only allow macros to expand into a DECLARE form. (y) yes (n) no 24. Shall there be printer control variables ARRAY-PRINLEVEL and ARRAY-PRINLENGTH to control printing of arrays? These would not limit the printing of strings. (y) yes (n) no 25. Shall lambda macros, as described below, be incorporated into the language, and if so, shall they occupy the function name space or a separate name space? (f) function name space (s) separate name space (n) no lambda macros ---------------------------------------------------------------- Date: Wednesday, 22 September 1982, 02:27-EDT From: Howard I. Cannon This is the documentation I wrote for lambda-macros as I implemented them on the Lisp Machine. Please consider this a proposed definition. Lambda macros may appear in functions where LAMBDA would have previously appeared. When the compiler or interpreter detects a function whose CAR is a lambda macro, they "expand" the macro in much the same way that ordinary Lisp macros are expanded -- the lambda macro is called with the function as its argument, and is expected to return another function as its value. Lambda macros may be accessed with the (3:lambda-macro* 2name*) function specifier. defspec lambda-macro function-spec lambda-list &body body Analagously with 3macro*, defines a lambda macro to be called 2function-spec*. 2lambda-list* should consist of one variable, which will be the function that caused the lambda macro to be called. The lambda macro must return a function. For example: lisp (lambda-macro ilisp (x) `(lambda (&optional ,@(second x) &rest ignore) . ,(cddr x))) end_lisp would define a lambda macro called 3ilisp* which would cause the function to accept arguments like a standard Interlisp function -- all arguments are optional, and extra arguments are ignored. A typical call would be: lisp (fun-with-functional-arg #'(ilisp (x y z) (list x y z))) end_lisp Then, any calls to the functional argument that 3fun-with-functional-arg* executes will pass arguments as if the number of arguments did not matter. end_defspec defspec deflambda-macro 3deflambda-macro* is like 3defmacro*, but defines a lambda macro instead of a normal macro. end_defspec defspec deflambda-macro-displace 3deflambda-macro-displace* is like 3defmacro-displace*, but defines a lambda macro instead of a normal macro. end_defspec defspec deffunction function-spec lambda-macro-name lambda-list &body body 3deffunction* defines a function with an arbitrary lambda macro instead of 3lambda*. It takes arguments like 3defun*, expect that the argument immediatly following the function specifier is the name of the lambda macro to be used. 3deffunction* expands the lambda macro immediatly, so the lambda macro must have been previously defined. For example: lisp (deffunction some-interlisp-like-function ilisp (x y z) (list x y z)) end_lisp would define a function called 3some-interlisp-like-function*, that would use the lambda macro called 3ilisp*. Thus, the function would do no number of arguments checking. end_defspec ---------------------------------------------------------------- 26. Shall the floating-point manipulations described below be adopted? (y) as described by MOON (a) as amended (FLOAT-SIGN changed) by GLS (n) do not adopt them ---------------------------------------------------------------- Date: Thursday, 30 September 1982 05:55-EDT From: MOON at SCRC-TENEX I am not completely happy with the FLOAT-FRACTION, FLOAT-EXPONENT, and SCALE-FLOAT functions in the Colander edition. At the meeting in August I was assigned to make a proposal. I am slow. A minor issue is that the range of FLOAT-FRACTION fails to include zero (of course it has to), and is inclusive at both ends, which means that there are two possible return values for some numbers. I guess that this ugliness has to stay because some implementations require this freedom for hardware reasons, and it doesn't make a big difference from a numerical analysis point of view. My proposal is to include zero in the range and to add a note about two possible values for numbers that are an exact power of the base. A more major issue is that some applications that break down a flonum into a fraction and an exponent, or assemble a flonum from a fraction and an exponent, are best served by representing the fraction as a flonum, while others are best served by representing it as an integer. An example of the former is a numerical routine that scales its argument into a certain range. An example of the latter is a printing routine that must do exact integer arithmetic on the fraction. In the agenda for the August meeting it was also proposed that there be a function to return the precision of the representation of a given flonum (presumably in bits); this would be in addition to the "epsilon" constants described on page 143 of the Colander. A goal of all this is to make it possible to write portable numeric functions, such as the trigonometric functions and my debugged version of Steele's totally accurate floating-point number printer. These would be portable to all implementations but perhaps not as efficient as hand-crafted routines that avoided bignum arithmetic, used special machine instructions, avoided computing to more precision than the machine really has, etc. Proposal: SCALE-FLOAT x e -> y y = (* x (expt 2.0 e)) and is a float of the same type as x. SCALE-FLOAT is more efficient than exponentiating and multiplying, and also cannot overflow or underflow unless the final result (y) cannot be represented. x is also allowed to be a rational, in which case y is of the default type (same as the FLOAT function). [x being allowed to be a rational can be removed if anyone objects. But note that this function has to be generic across the different float types in any case, so it might as well be generic across all number types.] UNSCALE-FLOAT y -> x e The first value, x, is a float of the same type as y. The second value, e, is an integer such that (= y (* x (expt 2.0 e))). The magnitude of x is zero or between 1/b and 1 inclusive, where b is the radix of the representation: 2 on most machines, but examples of 8 and 16, and I think 4, exist. x has the same sign as y. It is an error if y is a rational rather than a float, or if y is an infinity. (Leave infinity out of the Common Lisp manual, though). It is not an error if y is zero. FLOAT-MANTISSA x -> f FLOAT-EXPONENT x -> e FLOAT-SIGN x -> s FLOAT-PRECISION x -> p f is a non-negative integer, e is an integer, s is 1 or 0. (= x (* (SCALE-FLOAT (FLOAT f x) e) (IF (ZEROP S) 1 -1))) is true. It is up to the implementation whether f is the smallest possible integer (zeros on the right are removed and e is increased), or f is an integer with as many bits as the precision of the representation of x, or perhaps a "few" more. The only thing guaranteed about f is that it is non-negative and the above equality is true. f is non-negative to avoid problems with minus zero. s is 1 for minus zero even though MINUSP is not true of minus zero (otherwise the FLOAT-SIGN function would be redundant). p is an integer, the number of bits of precision in x. This is a constant for each flonum representation type (except perhaps for variable-precision "bigfloats"). [I am amenable to converting these four functions into one function that returns four values if anyone can come up with a name. EXPLODE-FLOAT is the best so far, and it's not very good, especially since the traditional EXPLODE function has been flushed from Common Lisp. Perhaps DECODE-FLOAT.] [I am amenable to adding a function that takes f, e, and s as arguments and returns x. It might be called ENCODE-FLOAT or MAKE-FLOAT. It ought to take either a type argument or an optional fourth argument, the way FLOAT takes an optional second argument, which is an example of the type to return.] FTRUNC x -> fp ip The FTRUNC function as it is already defined provides the fraction-part and integer-part operations. These functions exist now in the Lisp machines, with different names and slightly different semantics in some cases. They are very easy to write. Comments? Suggestions for names? Date: 4 October 1982 2355-EDT (Monday) From: Guy.Steele at CMU-10A I support Moon's proposal, but would like to suggest that FLOAT-SIGN be modified to (FLOAT-SIGN x &optional (y (float 1 x))) returns z such that x and z have same sign and (= (abs y) (abs z)). In this way (FLOAT-SIGN x) returns 1.0 or -1.0 of the same format as x, and FLOAT-SIGN of two arguments is what the IEEE proposal calls COPYSIGN, a useful function indeed in numerical code. --Guy ---------------------------------------------------------------- 27. Shall DEFMACRO, DEFSTRUCT, and other defining forms also be allowed to take documentation strings as possible and appropriate? (y) yes (n) no 28. Shall the following proposed revision of OPEN keywords be accepted? (y) yes (n) no ---------------------------------------------------------------- Date: Monday, 4 October 1982, 17:08-EDT From: Daniel L. Weinreb OPEN takes a filename as its first argument. The rest of its arguments are keyword/value pairs. WITH-OPEN-STREAM's first subform is a list of a variable (to be bound to a stream), a filename, and the rest of the elements are keyword/value pairs. The keywords are as follows, with their possible values and defaults: :DIRECTION :INPUT (the default), :OUTPUT, :APPEND, :OVERWRITE, :PROBE :INPUT - The file is expected to exist. Output operations are not allowed. :OUTPUT - The file is expected to not exist. A new file is created. Input operations are not allowed. :APPEND - The file is expected to exist. Input operations are not allowed. New characters are appened to the end of the existing file. :OVERWRITE - The file is expected to exist. All operations are allowed. The "file pointer" starts at the beginning of the file. :PROBE - The file may or may not exist. Neither input nor output operations are allowed. Furthermore, it is not necessary to close the stream. :CHARACTERS T (the default), NIL, :DEFAULT T - Open the file for reading/writing of characters. NIL - Open the file for reading/writing of bytes (non-negative integers). :DEFAULT - Let the file system decide, based on the file it finds. :BYTE-SIZE a fixnum or :DEFAULT (the default) a fixnum - Use this byte size. :DEFAULT - Let the file system decide, based on the file it finds. :IF-EXISTS :ERROR (the default), :NEW-VERSION, :RENAME, :RENAME-AND-DELETE, :OVERWRITE, :APPEND, :REPLACE Ignored if direction is not :OUTPUT. This tells what to do if the file that you're trying to create already exists. :ERROR - Signal an error. :NEW-VERSION - Create a file with the same filename except with "latest" version. :RENAME - Rename the existing file to something else and proceed. :RENAME-AND-DELETE - Rename the existing file and delete (but don't expunge, if your system has undeletion) it, and proceed. :OVERWRITE - Open for :OVERWRITE instead. (If your file system doesn't have this, use :RENAME-AND-DELETE if you have undeletion and :RENAME otherwise.) :APPEND - Open for :APPEND instead. :REPLACE - Replace the existing file, deleting it when the stream is closed. :IF-DOES-NOT-EXIST :ERROR (the default), :CREATE Ignored if direction is neither :APPEND nor :OVERWRITE :ERROR - Signal an error. :CREATE - Create the file and proceed. Notes: I renamed :READ-ALTER to :OVERWRITE; :READ-WRITE might also be good. The :DEFAULT values are very useful, although some systems cannot figure out this information. :CHARACTERS :DEFAULT is especially useful for LOAD. Having the byte size come from the file only when the option is missing, as the latest Common Lisp manual says, is undesirable because it makes things harder for programs that are passing the value of that keyword argument as computed from an expression. Example of OPEN: (OPEN "f:>dlw>lispm.init" :DIRECTION :OUTPUT) Example of WITH-OPEN-FILE: (WITH-OPEN-FILE (STREAM "f:>dlw>lispm.init" :DIRECTION :OUTPUT) ...) OPEN can be kept Maclisp compatible by recognizing whether the second argument is a list or not. Lisp Machine Lisp does this for the benefit of old programs. The new syntax cannot be mistaken for the old one. I removed :ECHO because we got rid of MAKE-ECHO-STREAM at the last meeting. Other options that the Lisp Machine will probably have, and which might be candidates for Common Lisp, are: :INHIBIT-LINKS, :DELETED, :PRESERVE-DATES, and :ESTIMATED-SIZE. ---------------------------------------------------------------- -------  Date: 4 October 1982 2355-EDT (Monday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: Moon's floating-point extractors proposal I support Moon's proposal, but would like to suggest that FLOAT-SIGN be modified to (FLOAT-SIGN x &optional (y (float 1 x))) returns z such that x and z have same sign and (= (abs y) (abs z)). In this way (FLOAT-SIGN x) returns 1.0 or -1.0 of the same format as x, and FLOAT-SIGN of two arguments is what the IEEE proposal calls COPYSIGN, a useful function indeed in numerical code. --Guy  Date: Tuesday, 5 October 1982 00:37-EDT From: Scott E. Fahlman To: Ginder at CMU-20C Cc: common-lisp at SU-AI Subject: White, red, and yellow pages There are a number of operating systems that will not be able to support :APPEND to files. Where it is clear that there will be some differences between implementations, the white pages should mention this: "Note: not all implementations will be able to support :APPEND." Or some such. In general, it is impossible for the white pages to flag all extensions made by all current and future Common Lisp implementations, so you will indeed have to be familiar with the red pages for your implementation. Most of the extensions will be easy to remember, or will be things you never want to use anyway; for the others, an obvious techniques is to mark the passage in the white pages that are modified in the red. I assume that Zetalisp will continue to have a separate manual, so their very extensive supersetting will not be a problem. -- Scott  Date: 5 Oct 1982 0030-EDT From: HEDRICK at RUTGERS (Mgr DEC-20s/Dir LCSR Comp Facility) Subject: suggestions on floating point numbers and hash tables To: common-lisp at SU-AI We have just finished most of the code needed to support Common Lisp numbers, and are working on hash tables. In the process, we have noticed a few things: When you see 1.0, it is hard to know what the precision is. We would like to make sure that if you write something out and read it back in, it is EQUAL to what you started with. Thus you should consider doing one of the following: - adopt a convention where you can tell the precision based on the number of digits printed. E.g. 1.00000 would be single, but 1.000000000000000 would be double. If you follow such a convention in both READ and PRINT, it should be possible to preserve the type. (This would replace the READ-DEFAULT-FLOAT-FORMAT flag.) This has the advantage of being to some extent machine-independent, in that 1.0000 might be single-precision on the VAX and short on the DEC-20. - always print an exponent marker, or maybe always print it when the it is not the same as READ-DEFAULT-FLOAT-FORMAT. (At the moment, we are always supplying an exponent marker when it is different from the default.) We do not notice any way to write out hash tables. We suggest that you adopt a # syntax for that. In my opinion, it should be possible to write out and read back in as many kinds of user data structures as is possible. You specify a default packing factor of .8 for hash tables. I wonder whether you really want this number to be defined in the manual. It seems to me that the best packing factor may well be implementation-dependent, because it will depend upon the way the implementors have taken certain space-time tradeoffs. For various reasons we are looking at using a algorithm where resolving clashes will be fairly expensive. Thus we intend to use a much lower default packing factor. (The method involved would use less storage space per item, so we could afford the larger tables implied.) Finally, we wonder whether having separate MAKE-xxx-HASH-TABLE functions but the same PUT-HASH and GET-HASH for all types is the right way to go. At least in our implementation, the structure of all hash tables is identical. What is different among the tables is how you compare entries. We think it would make more sense to have one MAKE-HASH-TABLE and separate access functions. Since the user supplies to hash table type when he creates it, we just have to save it somewhere in the table, and then use it behind his back to change the meaning of the access functions. Although I don't quite know how one would use it, in principle it would make sense to put different kinds of items into the same hash table using different functions, something that is ruled out by your proposal. Also, if there were only one kind of hash table, it would be slightly easier to PRINT and READ them. -------  Date: 4 October 1982 23:46-EDT From: Howard I. Cannon Subject: HIC lambda macros To: Guy.Steele at CMU-10A cc: common-lisp at SU-AI Date: 4 October 1982 2341-EDT (Monday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Re: HIC lambda macros I have a question about the proposed lambda macros: do they occupy the function name space, or a separate name space? That is, can I have a lambda macro and also an ordinary macro with the same name? Or a function and a lambda-macro with the same name? They occupy a different namespace. On the Lisp Machine, lambda macros reside on the LAMBDA-MACRO property of their name. However, there is a function-spec to reference them by, so you don't need to know this.  Date: 4 October 1982 2341-EDT (Monday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: HIC lambda macros I have a question about the proposed lambda macros: do they occupy the function name space, or a separate name space? That is, can I have a lambda macro and also an ordinary macro with the same name? Or a function and a lambda-macro with the same name?  Date: 4 October 1982 2250-EDT (Monday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: Explanation of "Sesame" Sesame is the Spice file system, to which Spice LISP must eventually interface. If we are lucky, they'll let us tell them what we need.  Date: 4 Oct 1982 1940-EDT From: Ginder at CMU-20C Subject: dlw's OPEN proposal To: steele at CMU-20C cc: common-lisp at SU-AI The :APPEND keyword may be misleading in conjuction with Sesame's "write once" files. I suppose you could copy the contents of the :APPEND'ed file into a new one and start from there and consider this an implementation detail. Where would stuff like this be explained in the manual? Where would the LM people's extensions be explained? I realize that these explanations are to be in the "red pages", but does that mean that I have to look up both the white pages and red pages documentation for a system fun? What if it's also extended in the yellow pages? Will red and yellow pages be inserted into the middle of the white pages at "appropriate" places? Pointers to them? -Joe -------  Date: Monday, 4 October 1982, 17:08-EDT From: Daniel L. Weinreb Subject: keyword pairs and OPEN To: Guy.Steele at CMU-10A, common-lisp at SU-AI In-reply-to: The message of 2 Oct 82 12:40-EDT from Guy.Steele at CMU-10A Speaking of OPEN being the biggest thorn, I owe you a proposal. Here it is. OPEN takes a filename as its first argument. The rest of its arguments are keyword/value pairs. WITH-OPEN-STREAM's first subform is a list of a variable (to be bound to a stream), a filename, and the rest of the elements are keyword/value pairs. The keywords are as follows, with their possible values and defaults: :DIRECTION :INPUT (the default), :OUTPUT, :APPEND, :OVERWRITE, :PROBE :INPUT - The file is expected to exist. Output operations are not allowed. :OUTPUT - The file is expected to not exist. A new file is created. Input operations are not allowed. :APPEND - The file is expected to exist. Input operations are not allowed. New characters are appened to the end of the existing file. :OVERWRITE - The file is expected to exist. All operations are allowed. The "file pointer" starts at the beginning of the file. :PROBE - The file may or may not exist. Neither input nor output operations are allowed. Furthermore, it is not necessary to close the stream. :CHARACTERS T (the default), NIL, :DEFAULT T - Open the file for reading/writing of characters. NIL - Open the file for reading/writing of bytes (non-negative integers). :DEFAULT - Let the file system decide, based on the file it finds. :BYTE-SIZE a fixnum or :DEFAULT (the default) a fixnum - Use this byte size. :DEFAULT - Let the file system decide, based on the file it finds. :IF-EXISTS :ERROR (the default), :NEW-VERSION, :RENAME, :RENAME-AND-DELETE, :OVERWRITE, :APPEND, :REPLACE Ignored if direction is not :OUTPUT. This tells what to do if the file that you're trying to create already exists. :ERROR - Signal an error. :NEW-VERSION - Create a file with the same filename except with "latest" version. :RENAME - Rename the existing file to something else and proceed. :RENAME-AND-DELETE - Rename the existing file and delete (but don't expunge, if your system has undeletion) it, and proceed. :OVERWRITE - Open for :OVERWRITE instead. (If your file system doesn't have this, use :RENAME-AND-DELETE if you have undeletion and :RENAME otherwise.) :APPEND - Open for :APPEND instead. :REPLACE - Replace the existing file, deleting it when the stream is closed. :IF-DOES-NOT-EXIST :ERROR (the default), :CREATE Ignored if direction is neither :APPEND nor :OVERWRITE :ERROR - Signal an error. :CREATE - Create the file and proceed. Notes: I renamed :READ-ALTER to :OVERWRITE; :READ-WRITE might also be good. The :DEFAULT values are very useful, although some systems cannot figure out this information. :CHARACTERS :DEFAULT is especially useful for LOAD. Having the byte size come from the file only when the option is missing, as the latest Common Lisp manual says, is undesirable because it makes things harder for programs that are passing the value of that keyword argument as computed from an expression. Example of OPEN: (OPEN "f:>dlw>lispm.init" :DIRECTION :OUTPUT) Example of WITH-OPEN-FILE: (WITH-OPEN-FILE (STREAM "f:>dlw>lispm.init" :DIRECTION :OUTPUT) ...) OPEN can be kept Maclisp compatible by recognizing whether the second argument is a list or not. Lisp Machine Lisp does this for the benefit of old programs. The new syntax cannot be mistaken for the old one. I removed :ECHO because we got rid of MAKE-ECHO-STREAM at the last meeting. Other options that the Lisp Machine will probably have, and which might be candidates for Common Lisp, are: :INHIBIT-LINKS, :DELETED, :PRESERVE-DATES, and :ESTIMATED-SIZE.  Date: Monday, 4 October 1982 10:49-EDT From: Scott E. Fahlman To: Alan Bawden Cc: common-lisp at SU-AI Subject: Documentation strings in defstruct The use of a :DOCUMENTATION keyword in DEFSTRUCT looks OK, modulo the auto-fill issues discussed earlier. -- Scott  Date: Monday, 4 October 1982 10:49-EDT From: Scott E. Fahlman To: Alan Bawden Cc: common-lisp at SU-AI Subject: Documentation strings in defstruct The use of a :DOCUMENTATION keyword in DEFSTRUCT looks OK, modulo the auto-fill issues discussed earlier. -- Scott  Date: 4 October 1982 03:45-EDT From: Alan Bawden Subject: Documentation strings in defstruct To: common-lisp at SU-AI Date: Sunday, 3 October 1982 14:03-EDT From: Scott E. Fahlman Gary Brown noticed that DEFMACRO and DEFSTRUCT are not documented as taking documentation strings. DEFMACRO certainly should, since its form parallels that of DEFUN, and adding this to DEFSTRUCT seems to be a good idea as well. Any problems with this? How about: (defstruct (spaceman (:include person) (:documentation "A spaceman. The definition of a spaceman includes the definition of a person. Additionally a spaceman has a helmit-size and a favorite-beverage. The default favorite-beverage is Tang (tm).")) helmet-size (favorite-beverage 'tang))  Date: Sunday, 3 October 1982 14:03-EDT From: Scott E. Fahlman To: common-lisp at SU-AI Subject: Documentation strings Gary Brown noticed that DEFMACRO and DEFSTRUCT are not documented as taking documentation strings. DEFMACRO certainly should, since its form parallels that of DEFUN, and adding this to DEFSTRUCT seems to be a good idea as well. Any problems with this? -- Scott  Date: 2 October 1982 1240-EDT (Saturday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: keyword pairs and DEFSTRUCT I am in sympathy with leaving DEFSTRUCT as is. Indeed, there may be something odd about DEF-forms. OPEN was the biggest thorn, to my mind.  Date: 2 October 1982 1229-EDT (Saturday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: Apalled A marvelous word, this. Perhaps KMP meant that Common LISP is in danger of being "APPLEd", that is, forced into the Procrustean bed of an APPLE's memory size. This danger can be avoided by making the language so large that it cannot possiblt be shoehorned into an APPLE. However, I think this is already the case without RESTART being added. Or perhaps Common LISP is being "APL'd", but better to blame that on REDUCE and MAP than on RESTART. But most likely is that he simply wished to "applaud" the RESTART form. (Sorry, KMP, don't mean to tease, but it's wonderful how this typo landed splat between four or five applicable words.) --Quux  Date: Saturday, 2 October 1982 03:30-EDT From: MOON at SCRC-TENEX To: Common-Lisp at SU-AI Subject: DEFSTRUCT options syntax In-reply-to: The message of 1 Oct 1982 08:48-EDT from Scott E. Fahlman Date: Friday, 1 October 1982 08:48-EDT From: Scott E. Fahlman .... my point is just that OPEN is pretty much like the others. Except that it is a function. I'm uneasy about making special forms too special, and creating forms that the user cannot duplicate with macros or some such. No one proposes to make forms that the user cannot duplicate with macros. Indeed, I can think of no possible way to do that. Perhaps we can extend the basic keyword mechanism to allow keyword/value, but also allow calling forms like (foo :key1 value1 (:key2 value2a value2b) ...) However, coming up with an attractive way to specify this in a macro's lambda-list will be pretty tough. I assume you don't mean doing this for functions. That would be utterly wrong. We could easily add another & word to DEFMACRO if we decide it is desirable to have an even more trivial way to accept such syntax in macros than the straightforward way of looping over the form checking LISTP and CAR.  Date: 01 Oct 1982 1642-PDT From: John McCarthy Subject: setf  set To: common-lisp at SU-AI A serious objection to setf  set is that Lisp needs x s.t. x is to setf as set is to setq.  Date: Friday, 1 October 1982 08:48-EDT From: Scott E. Fahlman To: Alan Bawden Cc: Common-Lisp at SU-AI Subject: DEFSTRUCT options syntax I guess I could go either way on forcing DEFSTRUCT and friends to be consistent with the rest of the language. Consistency is nice, and important enough that the change is not gratuitous, but should be abandoned if it really is screwing things up. "...the hobgoblin of little minds" and all that. As a piece of additional food for thought, Gary Brown of DEC has been working out the details of a red-pages extension to the Vax Common Lisp that would allow the Lisp user to access the more complex file types (especially record-oriented ones) in RMS. The obvious thing to do is to add a bunch of new options to OPEN and WITH-OPEN-FILE to specify the additional attributes that RMS needs to know about -- record size, buffering strategy, etc. This, too, would look much cleaner if some of the keywords could take multiple args. Note that OPEN is really "DEF-STREAM", sort of -- all the open-ended requirements for specifying a complicated new object, albeit a volatile one, are present. There are other ways to do this for OPEN, I guess, as there are for the other "defs"; my point is just that OPEN is pretty much like the others. I'm uneasy about making special forms too special, and creating forms that the user cannot duplicate with macros or some such. Perhaps we can extend the basic keyword mechanism to allow keyword/value, but also allow calling forms like (foo :key1 value1 (:key2 value2a value2b) ...) However, coming up with an attractive way to specify this in a macro's lambda-list will be pretty tough. -- Scott  Date: 1 October 1982 04:06-EDT From: Alan Bawden Subject: DEFSTRUCT options syntax To: Common-Lisp at SU-AI From the last meeting: 17. Can we standardize on keywords always being used as name-value pairs? The worst current deviants are WITH-OPEN-FILE and DEFSTRUCT options. Yes. The Lisp Machine LISP group will make a proposal soon for OPEN, WITH-OPEN-FILE, and DEFSTRUCT. While everyone agrees that OPEN and WITH-OPEN-FILE should be fixed (and they already have been fixed on the Lisp Machine), the case for DEFSTRUCT is not as clear. In my opinion the change is gratuitous since the options list in a defstruct is NOT a function call. Furthermore it is more than a non-trivial incompatible change since each option has to be re-thought in light of the fact that it can now be given only one argument rather than any number. (Note that the :CONSTRUCTOR and :INCLUDE options take advantage of this multiple-argument ability.) I asked Moon and DLW if they agreed with me on this subject. Moon replied: Date: Thursday, 30 September 1982 00:44-EDT From: MOON at SCRC-TENEX To: DLW at SCRC-TENEX cc: Alan Re: gratuitous change to defstruct syntax. I've changed my mind about this since August, and am now in agreement with Alan. Partly this was caused by thinking about what it would mean to change DEFFLAVOR to use alternating keywords and values; it seems very clear that it would make it much worse. Thinking about this more made me decide that some special forms have syntax that looks something like a function call, but many are totally unrelated to function calls and trying to wedge them into the same mold is just confused (and confusing). Certainly the way OPEN used to be was wrong, and fixing it was a big win. But I think DEFSTRUCT should stay with "option" or "(option args...)" syntax, as should DEFFLAVOR, DEFSYSTEM, DEFSITE, and who knows what else. It probably is not a coincidence that these are all "defining" forms. DLW is also in agreement with me on this. How about it folks, can we keep DEFSTRUCT parsing its options the way it is now?  Date: 30 September 1982 18:57-EDT From: Earl A. Killian Subject: arrays and vectors (long carefully-thought-out message) To: MOON at SCRC-TENEX cc: common-lisp at SU-AI Having :ADJUSTABLE-SIZE is obviously right, regardless of the rest of the vector/array design.  Date: Thursday, 30 September 1982 18:45-EDT From: Scott E. Fahlman To: Kent M. Pitman Cc: common-lisp at SU-AI Subject: RESTART Well, as long as we're being apalled (or even appalled, for those of you who are into traditional spelling), I am apalled by the concept of "malicious edits". If your system (meaning the combination of code and social conventions) allows such things, fix the system, not the programming language. I would hate to think what Common Lisp would look like if we were to eliminate every feature that might tempt some idiot to stick in a line of unclean code. This is a powerful langauge, and it cannot possibly be made vandal-proof. There might be some good arguments for adding a RESTARTABLE form, but this isn't one. -- Scott  Date: 30 September 1982 18:20-EDT From: Kent M. Pitman Subject: RESTART To: common-lisp at SU-AI I agree with Moon that RESTARTing DEFUNs is confusing. I was apalled by Fahlman's intended application. Nevertheless, I have found that certain people I know would be happy to "take advantage" of the fact that I had provided them with a PROG or TAGBODY even if I were using it in a structured way only to go back to the top. I think therefore that having an explicit RESTARTABLE special form is a good idea and would discourage people from "malicious" edits that added extra tags. Also, there's something visually nice about signalling this constrained use of PROG with a special name. If it's something that we'd expect to happen a lot, we might as well give it a common name so people can read each others' code rather than have everyone write the macro themselves and give it a different name. -kmp  Date: 30 September 1982 18:20-EDT From: Kent M. Pitman Subject: RESTART To: common-lisp at SU-AI I agree with Moon that RESTARTing DEFUNs is confusing. I was apalled by Fahlman's intended application. Nevertheless, I have found that certain people I know would be happy to "take advantage" of the fact that I had provided them with a PROG or TAGBODY even if I were using it in a structured way only to go back to the top. I think therefore that having an explicit RESTARTABLE special form is a good idea and would discourage people from "malicious" edits that added extra tags. Also, there's something visually nice about signalling this constrained use of PROG with a special name. If it's something that we'd expect to happen a lot, we might as well give it a common name so people can read each others' code rather than have everyone write the macro themselves and give it a different name. -kmp  Date: Thursday, 30 September 1982 17:47-EDT From: Scott E. Fahlman To: Alan Bawden Cc: Common-Lisp at SU-AI Subject: Down with RESTART Alan, When I said that re-initializing the variables is almost never the right thing to do, I had several things in mind: 1. In an iterative situation, where the variables are counting or accumulating something and the problem occurs after several iterations, you usually want to restart where you left off (if anywhwere), and not re-init such variables. 2. In the case of optionals, you probably have no way to tell whether the value came from the user or was computed. Even if it was computed, you probably don't want to zap it unless it is a function of whatever it was that you changed to correct the error. I would claim that having things in the arglist depend on one another in this way is relatively rare compared to constant inits or inits taken from some external special variable. 3. It bothers me to have RESTART cut in between elements in an arglist. Anyway, you have made your point: RESTART is confusing and we are better off without it. There is no point in putting in a special RESTARTABLE-BLOCK form -- if I can't take advantage of the implicit block in a defun, I may as well write a PROG and GO as a RESTARTABLE-BLOCK and a RESTART. I can make my code perspicuous by using RESTART as the tag name, something we have all been doing for years anyway. -- Scott  Date: Thursday, 30 September 1982 17:04-EDT From: Scott E. Fahlman To: Common-Lisp at SU-AI Subject: Issue 82 comment It is not necessarily the case that larger-format floats will always have larger exponents. It is also not clear to me that quietly rolling over into the next-larger float is the right thing to do on exponent overflow, or that such rollover is efficiently implementable on all machines. On the Vax, users will often have declared a single type of float for efficiency, and compiled this in; in such cases, we clearly want a runtime error rather than a "helpful" coercion. I think that it is probably best for the white pages to specify that floating-exponent overflows always signal an error. Ideally, the error handler should get enough info so that the user can supply a quietly-size-expanding handler if he wants to. This means that, if possible (can we require this?) it should be a correctable error, which is passed the operation name and the original args; the handler can then return the "answer", computed however it likes and in any format it likes. -- Scott  Date: Thursday, 30 September 1982 05:55-EDT From: MOON at SCRC-TENEX To: Common-Lisp at sail Subject: Issue #97, Colander page 134: floating-point assembly and disassembly I am not completely happy with the FLOAT-FRACTION, FLOAT-EXPONENT, and SCALE-FLOAT functions in the Colander edition. At the meeting in August I was assigned to make a proposal. I am slow. A minor issue is that the range of FLOAT-FRACTION fails to include zero (of course it has to), and is inclusive at both ends, which means that there are two possible return values for some numbers. I guess that this ugliness has to stay because some implementations require this freedom for hardware reasons, and it doesn't make a big difference from a numerical analysis point of view. My proposal is to include zero in the range and to add a note about two possible values for numbers that are an exact power of the base. A more major issue is that some applications that break down a flonum into a fraction and an exponent, or assemble a flonum from a fraction and an exponent, are best served by representing the fraction as a flonum, while others are best served by representing it as an integer. An example of the former is a numerical routine that scales its argument into a certain range. An example of the latter is a printing routine that must do exact integer arithmetic on the fraction. In the agenda for the August meeting it was also proposed that there be a function to return the precision of the representation of a given flonum (presumably in bits); this would be in addition to the "epsilon" constants described on page 143 of the Colander. A goal of all this is to make it possible to write portable numeric functions, such as the trigonometric functions and my debugged version of Steele's totally accurate floating-point number printer. These would be portable to all implementations but perhaps not as efficient as hand-crafted routines that avoided bignum arithmetic, used special machine instructions, avoided computing to more precision than the machine really has, etc. Proposal: SCALE-FLOAT x e -> y y = (* x (expt 2.0 e)) and is a float of the same type as x. SCALE-FLOAT is more efficient than exponentiating and multiplying, and also cannot overflow or underflow unless the final result (y) cannot be represented. x is also allowed to be a rational, in which case y is of the default type (same as the FLOAT function). [x being allowed to be a rational can be removed if anyone objects. But note that this function has to be generic across the different float types in any case, so it might as well be generic across all number types.] UNSCALE-FLOAT y -> x e The first value, x, is a float of the same type as y. The second value, e, is an integer such that (= y (* x (expt 2.0 e))). The magnitude of x is zero or between 1/b and 1 inclusive, where b is the radix of the representation: 2 on most machines, but examples of 8 and 16, and I think 4, exist. x has the same sign as y. It is an error if y is a rational rather than a float, or if y is an infinity. (Leave infinity out of the Common Lisp manual, though). It is not an error if y is zero. FLOAT-MANTISSA x -> f FLOAT-EXPONENT x -> e FLOAT-SIGN x -> s FLOAT-PRECISION x -> p f is a non-negative integer, e is an integer, s is 1 or 0. (= x (* (SCALE-FLOAT (FLOAT f x) e) (IF (ZEROP S) 1 -1))) is true. It is up to the implementation whether f is the smallest possible integer (zeros on the right are removed and e is increased), or f is an integer with as many bits as the precision of the representation of x, or perhaps a "few" more. The only thing guaranteed about f is that it is non-negative and the above equality is true. f is non-negative to avoid problems with minus zero. s is 1 for minus zero even though MINUSP is not true of minus zero (otherwise the FLOAT-SIGN function would be redundant). p is an integer, the number of bits of precision in x. This is a constant for each flonum representation type (except perhaps for variable-precision "bigfloats"). [I am amenable to converting these four functions into one function that returns four values if anyone can come up with a name. EXPLODE-FLOAT is the best so far, and it's not very good, especially since the traditional EXPLODE function has been flushed from Common Lisp. Perhaps DECODE-FLOAT.] [I am amenable to adding a function that takes f, e, and s as arguments and returns x. It might be called ENCODE-FLOAT or MAKE-FLOAT. It ought to take either a type argument or an optional fourth argument, the way FLOAT takes an optional second argument, which is an example of the type to return.] FTRUNC x -> fp ip The FTRUNC function as it is already defined provides the fraction-part and integer-part operations. These functions exist now in the Lisp machines, with different names and slightly different semantics in some cases. They are very easy to write. Comments? Suggestions for names?  Date: Thursday, 30 September 1982 15:52-EDT From: MOON at SCRC-TENEX To: Brian G. Milnes Cc: fahlman at CMU-20C at MIT-MC, steele at CMU-20C at MIT-MC, wholey at CMU-20C at MIT-MC, common-lisp at sail, rlb at SCRC-TENEX Subject: Issue 82 comment, your reply and number crunching In-reply-to: The message of 30 Sep 1982 14:59-EDT from Brian G. Milnes Your point boils down to this, if I understand it: Different floating point formats may have not only different precisions, but also different exponent ranges. You don't care about the precision, but only want the smallest floating point format that has enough exponent range to hold the number you're floating. I see a couple problems with this. One is that you have to decide somehow which format is the smallest you use. If you have an integer that you are floating which is small enough that it would fit in the tiniest floating-point format (say it's 1), you don't want FLOAT to use that format because then the precision would be too small. FLOAT has to extend upwards, but not downwards. The other is that you are assuming automatic conversion to larger formats, with more exponent range, on overflow or underflow by all floating-point arithmetic operations. Just putting it in FLOAT is no good; you might FLOAT a number that barely fits, then add 1 to it and get an overflow. I'm not sure whether all Common Lisp implementations want to commit to this. I have no vested interest in precision, by the way, and am not a big user of floating-point numbers, just an implementor. I have learned enough about it to be feel concern for trying to keep Common Lisp away from some known pitfalls. It sounds like more discussion by more people is called for.  Date: Thursday, 30 September 1982 05:55-EDT From: MOON at SCRC-TENEX To: Common-Lisp at sail Subject: Issue #97, Colander page 134: floating-point assembly and disassembly I am not completely happy with the FLOAT-FRACTION, FLOAT-EXPONENT, and SCALE-FLOAT functions in the Colander edition. At the meeting in August I was assigned to make a proposal. I am slow. A minor issue is that the range of FLOAT-FRACTION fails to include zero (of course it has to), and is inclusive at both ends, which means that there are two possible return values for some numbers. I guess that this ugliness has to stay because some implementations require this freedom for hardware reasons, and it doesn't make a big difference from a numerical analysis point of view. My proposal is to include zero in the range and to add a note about two possible values for numbers that are an exact power of the base. A more major issue is that some applications that break down a flonum into a fraction and an exponent, or assemble a flonum from a fraction and an exponent, are best served by representing the fraction as a flonum, while others are best served by representing it as an integer. An example of the former is a numerical routine that scales its argument into a certain range. An example of the latter is a printing routine that must do exact integer arithmetic on the fraction. In the agenda for the August meeting it was also proposed that there be a function to return the precision of the representation of a given flonum (presumably in bits); this would be in addition to the "epsilon" constants described on page 143 of the Colander. A goal of all this is to make it possible to write portable numeric functions, such as the trigonometric functions and my debugged version of Steele's totally accurate floating-point number printer. These would be portable to all implementations but perhaps not as efficient as hand-crafted routines that avoided bignum arithmetic, used special machine instructions, avoided computing to more precision than the machine really has, etc. Proposal: SCALE-FLOAT x e -> y y = (* x (expt 2.0 e)) and is a float of the same type as x. SCALE-FLOAT is more efficient than exponentiating and multiplying, and also cannot overflow or underflow unless the final result (y) cannot be represented. x is also allowed to be a rational, in which case y is of the default type (same as the FLOAT function). [x being allowed to be a rational can be removed if anyone objects. But note that this function has to be generic across the different float types in any case, so it might as well be generic across all number types.] UNSCALE-FLOAT y -> x e The first value, x, is a float of the same type as y. The second value, e, is an integer such that (= y (* x (expt 2.0 e))). The magnitude of x is zero or between 1/b and 1 inclusive, where b is the radix of the representation: 2 on most machines, but examples of 8 and 16, and I think 4, exist. x has the same sign as y. It is an error if y is a rational rather than a float, or if y is an infinity. (Leave infinity out of the Common Lisp manual, though). It is not an error if y is zero. FLOAT-MANTISSA x -> f FLOAT-EXPONENT x -> e FLOAT-SIGN x -> s FLOAT-PRECISION x -> p f is a non-negative integer, e is an integer, s is 1 or 0. (= x (* (SCALE-FLOAT (FLOAT f x) e) (IF (ZEROP S) 1 -1))) is true. It is up to the implementation whether f is the smallest possible integer (zeros on the right are removed and e is increased), or f is an integer with as many bits as the precision of the representation of x, or perhaps a "few" more. The only thing guaranteed about f is that it is non-negative and the above equality is true. f is non-negative to avoid problems with minus zero. s is 1 for minus zero even though MINUSP is not true of minus zero (otherwise the FLOAT-SIGN function would be redundant). p is an integer, the number of bits of precision in x. This is a constant for each flonum representation type (except perhaps for variable-precision "bigfloats"). [I am amenable to converting these four functions into one function that returns four values if anyone can come up with a name. EXPLODE-FLOAT is the best so far, and it's not very good, especially since the traditional EXPLODE function has been flushed from Common Lisp. Perhaps DECODE-FLOAT.] [I am amenable to adding a function that takes f, e, and s as arguments and returns x. It might be called ENCODE-FLOAT or MAKE-FLOAT. It ought to take either a type argument or an optional fourth argument, the way FLOAT takes an optional second argument, which is an example of the type to return.] FTRUNC x -> fp ip The FTRUNC function as it is already defined provides the fraction-part and integer-part operations. These functions exist now in the Lisp machines, with different names and slightly different semantics in some cases. They are very easy to write. Comments? Suggestions for names?  Date: 30 September 1982 1329-EDT (Thursday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: Clarification TAGBODY was not intended to be a RETURN-BODY, only BLOCK. The proposed evaluator reflects this, I am sure. --Guy  Date: 30 September 1982 12:23-EDT From: Glenn S. Burke Subject: vectors/arrays To: common-lisp at SU-AI I had been feeling uncomfortable for some time with not being able to have something with a fill pointer that could be called a STRING, even though i had been a proponent of keeping the STRING/VECTOR/BITwhatevers simple. Moon's proposal sounds good.  Date: Thursday, 30 September 1982 05:55-EDT From: MOON at SCRC-TENEX To: Common-Lisp at sail Subject: Issue #97, Colander page 134: floating-point assembly and disassembly I am not completely happy with the FLOAT-FRACTION, FLOAT-EXPONENT, and SCALE-FLOAT functions in the Colander edition. At the meeting in August I was assigned to make a proposal. I am slow. A minor issue is that the range of FLOAT-FRACTION fails to include zero (of course it has to), and is inclusive at both ends, which means that there are two possible return values for some numbers. I guess that this ugliness has to stay because some implementations require this freedom for hardware reasons, and it doesn't make a big difference from a numerical analysis point of view. My proposal is to include zero in the range and to add a note about two possible values for numbers that are an exact power of the base. A more major issue is that some applications that break down a flonum into a fraction and an exponent, or assemble a flonum from a fraction and an exponent, are best served by representing the fraction as a flonum, while others are best served by representing it as an integer. An example of the former is a numerical routine that scales its argument into a certain range. An example of the latter is a printing routine that must do exact integer arithmetic on the fraction. In the agenda for the August meeting it was also proposed that there be a function to return the precision of the representation of a given flonum (presumably in bits); this would be in addition to the "epsilon" constants described on page 143 of the Colander. A goal of all this is to make it possible to write portable numeric functions, such as the trigonometric functions and my debugged version of Steele's totally accurate floating-point number printer. These would be portable to all implementations but perhaps not as efficient as hand-crafted routines that avoided bignum arithmetic, used special machine instructions, avoided computing to more precision than the machine really has, etc. Proposal: SCALE-FLOAT x e -> y y = (* x (expt 2.0 e)) and is a float of the same type as x. SCALE-FLOAT is more efficient than exponentiating and multiplying, and also cannot overflow or underflow unless the final result (y) cannot be represented. x is also allowed to be a rational, in which case y is of the default type (same as the FLOAT function). [x being allowed to be a rational can be removed if anyone objects. But note that this function has to be generic across the different float types in any case, so it might as well be generic across all number types.] UNSCALE-FLOAT y -> x e The first value, x, is a float of the same type as y. The second value, e, is an integer such that (= y (* x (expt 2.0 e))). The magnitude of x is zero or between 1/b and 1 inclusive, where b is the radix of the representation: 2 on most machines, but examples of 8 and 16, and I think 4, exist. x has the same sign as y. It is an error if y is a rational rather than a float, or if y is an infinity. (Leave infinity out of the Common Lisp manual, though). It is not an error if y is zero. FLOAT-MANTISSA x -> f FLOAT-EXPONENT x -> e FLOAT-SIGN x -> s FLOAT-PRECISION x -> p f is a non-negative integer, e is an integer, s is 1 or 0. (= x (* (SCALE-FLOAT (FLOAT f x) e) (IF (ZEROP S) 1 -1))) is true. It is up to the implementation whether f is the smallest possible integer (zeros on the right are removed and e is increased), or f is an integer with as many bits as the precision of the representation of x, or perhaps a "few" more. The only thing guaranteed about f is that it is non-negative and the above equality is true. f is non-negative to avoid problems with minus zero. s is 1 for minus zero even though MINUSP is not true of minus zero (otherwise the FLOAT-SIGN function would be redundant). p is an integer, the number of bits of precision in x. This is a constant for each flonum representation type (except perhaps for variable-precision "bigfloats"). [I am amenable to converting these four functions into one function that returns four values if anyone can come up with a name. EXPLODE-FLOAT is the best so far, and it's not very good, especially since the traditional EXPLODE function has been flushed from Common Lisp. Perhaps DECODE-FLOAT.] [I am amenable to adding a function that takes f, e, and s as arguments and returns x. It might be called ENCODE-FLOAT or MAKE-FLOAT. It ought to take either a type argument or an optional fourth argument, the way FLOAT takes an optional second argument, which is an example of the type to return.] FTRUNC x -> fp ip The FTRUNC function as it is already defined provides the fraction-part and integer-part operations. These functions exist now in the Lisp machines, with different names and slightly different semantics in some cases. They are very easy to write. Comments? Suggestions for names?  Date: Thursday, 30 September 1982 06:17-EDT From: MOON at SCRC-TENEX To: common-lisp at sail Subject: RESTART The recent discussion of the interaction of the RESTART feature with the implicit block created by DEFUN has convinced me that the RESTART feature is a crock whose semantics cannot be made both precise and obvious. It should be flushed, or at least paired with an explicit RESTARTABLE marker.  Date: Thursday, 30 September 1982 05:55-EDT From: MOON at SCRC-TENEX To: Common-Lisp at sail Subject: Issue #97, Colander page 134: floating-point assembly and disassembly I am not completely happy with the FLOAT-FRACTION, FLOAT-EXPONENT, and SCALE-FLOAT functions in the Colander edition. At the meeting in August I was assigned to make a proposal. I am slow. A minor issue is that the range of FLOAT-FRACTION fails to include zero (of course it has to), and is inclusive at both ends, which means that there are two possible return values for some numbers. I guess that this ugliness has to stay because some implementations require this freedom for hardware reasons, and it doesn't make a big difference from a numerical analysis point of view. My proposal is to include zero in the range and to add a note about two possible values for numbers that are an exact power of the base. A more major issue is that some applications that break down a flonum into a fraction and an exponent, or assemble a flonum from a fraction and an exponent, are best served by representing the fraction as a flonum, while others are best served by representing it as an integer. An example of the former is a numerical routine that scales its argument into a certain range. An example of the latter is a printing routine that must do exact integer arithmetic on the fraction. In the agenda for the August meeting it was also proposed that there be a function to return the precision of the representation of a given flonum (presumably in bits); this would be in addition to the "epsilon" constants described on page 143 of the Colander. A goal of all this is to make it possible to write portable numeric functions, such as the trigonometric functions and my debugged version of Steele's totally accurate floating-point number printer. These would be portable to all implementations but perhaps not as efficient as hand-crafted routines that avoided bignum arithmetic, used special machine instructions, avoided computing to more precision than the machine really has, etc. Proposal: SCALE-FLOAT x e -> y y = (* x (expt 2.0 e)) and is a float of the same type as x. SCALE-FLOAT is more efficient than exponentiating and multiplying, and also cannot overflow or underflow unless the final result (y) cannot be represented. x is also allowed to be a rational, in which case y is of the default type (same as the FLOAT function). [x being allowed to be a rational can be removed if anyone objects. But note that this function has to be generic across the different float types in any case, so it might as well be generic across all number types.] UNSCALE-FLOAT y -> x e The first value, x, is a float of the same type as y. The second value, e, is an integer such that (= y (* x (expt 2.0 e))). The magnitude of x is zero or between 1/b and 1 inclusive, where b is the radix of the representation: 2 on most machines, but examples of 8 and 16, and I think 4, exist. x has the same sign as y. It is an error if y is a rational rather than a float, or if y is an infinity. (Leave infinity out of the Common Lisp manual, though). It is not an error if y is zero. FLOAT-MANTISSA x -> f FLOAT-EXPONENT x -> e FLOAT-SIGN x -> s FLOAT-PRECISION x -> p f is a non-negative integer, e is an integer, s is 1 or 0. (= x (* (SCALE-FLOAT (FLOAT f x) e) (IF (ZEROP S) 1 -1))) is true. It is up to the implementation whether f is the smallest possible integer (zeros on the right are removed and e is increased), or f is an integer with as many bits as the precision of the representation of x, or perhaps a "few" more. The only thing guaranteed about f is that it is non-negative and the above equality is true. f is non-negative to avoid problems with minus zero. s is 1 for minus zero even though MINUSP is not true of minus zero (otherwise the FLOAT-SIGN function would be redundant). p is an integer, the number of bits of precision in x. This is a constant for each flonum representation type (except perhaps for variable-precision "bigfloats"). [I am amenable to converting these four functions into one function that returns four values if anyone can come up with a name. EXPLODE-FLOAT is the best so far, and it's not very good, especially since the traditional EXPLODE function has been flushed from Common Lisp. Perhaps DECODE-FLOAT.] [I am amenable to adding a function that takes f, e, and s as arguments and returns x. It might be called ENCODE-FLOAT or MAKE-FLOAT. It ought to take either a type argument or an optional fourth argument, the way FLOAT takes an optional second argument, which is an example of the type to return.] FTRUNC x -> fp ip The FTRUNC function as it is already defined provides the fraction-part and integer-part operations. These functions exist now in the Lisp machines, with different names and slightly different semantics in some cases. They are very easy to write. Comments? Suggestions for names?  Date: 30 September 1982 06:08-EDT From: Kent M. Pitman Subject: RESTART To: Common-Lisp at SU-AI ALAN's position on RESTART seems valid. It seems to me conceptually right that a function begins at the time the jump is done to its code. Any computation which is done after that time should be redone when you do a restart of the function. Although seemingly part of the bound variable list, optional and aux args are really just shorthand for code that is conceptually part of the body. After all, it would be useful to preserve the property that things like (DEFUN F (X &OPTIONAL (Y 3)) (LIST X Y)) can be re-written as (DEFUN F (X &REST G0001) (LET ((Y (IF (NOT (NULL G0001)) (CAR G0001) 3))) (LIST X Y))) If you RESTART didn't re-execute the &optional inits, then you couldn't do this re-write without doing a code analysis to verify that either RESTART wasn't called or that the inits were constant with respect to the preceding arguments. Certainly people will expect &AUX things to be redone since they think (DEFUN F (X &AUX (Y (...X...))) is the same as (DEFUN F (X) (LET ((Y ...X...)) ...)). This re-write will also be unsafe without careful code analysis if at least &aux variables at least are not re-run with a (RESTART F).  Date: 30 September 1982 05:42-EDT From: Kent M. Pitman Subject: Vectors/Arrays To: Common-Lisp at SU-AI Having pondered the subject for a few days now, I'm pretty convinced by DLW's and Moon's comments that the "simple" proposal is the best. Moon's modified "simple" proposal seems fine to me; my vote goes with that.  Date: Thursday, 30 September 1982 01:59-EDT From: MOON at SCRC-TENEX To: common-lisp at sail Subject: arrays and vectors (long carefully-thought-out message) I prefer the "simple switch" to the "RPG memorial" proposal, with one modification to be found below. The reason for this preference is that it makes the "good" name, STRING for example, refer to the general class of objects, relegating the efficiency decision to a modifier ("simple"). The alternative makes the efficiency issue too visible to the casual user, in my opinion. You have to always be thinking "do I only want this to work for efficient strings, which are called strings, or should it work for all kinds of strings, which are called arrays of characters?". Better to say, "well this works for strings, and hmm, is it worth restricting it to simple-strings to squeeze out maximal efficiency"? Lest this seem like I am trying to sabotage the efficiency of Lisp implementations that are stuck with "stock" hardware, consider the following: In the simple switch proposal, how is (MAKE-ARRAY 100) different from (MAKE-ARRAY 100 :SIMPLE T)? In fact, there is only one difference--it is an error to use ADJUST-ARRAY-SIZE on the latter array, but not on the former. Except for this, simpleness consists, simply, of the absence of options. This suggests to me that the :SIMPLE option be flushed, and instead a :ADJUSTABLE-SIZE option be added (see, I pronounce the colons). Even on the Lisp machine, where :ADJUSTABLE-SIZE makes no difference, I think it would be an improvement, merely for documentation purposes. Now everything makes sense: if you don't ask for any special features in your arrays, you get simple ones, which is consistent with the behavior of the sequence functions returning simple arrays always. And if some implementation decides they need the sequence functions to return non-simple arrays, they can always add additional keywords to them to so specify. The only time you need to know about the word "simple" at all is if you are making type declarations for efficiency, in which case you have to decide whether to declare something to be a STRING or a SIMPLE-STRING. And it makes sense that the more restrictive declaration be a longer word. This also meets RPG's objection, which I think boils down to the fact that he thought it was stupid to have :SIMPLE T all over his programs. He was right. I'm fairly sure that I don't understand the portability issues that KMP brought up (I don't have a whole lot of time to devote to this). But I think that in my proposal STRINGP and SIMPLE-STRINGP are never the same in any implementation; for instance, in the Lisp machine STRINGP is true of all strings, while SIMPLE-STRINGP is only true of those that do not have fill-pointers. If we want to legislate that the :ADJUSTABLE-SIZE option is guaranteed to turn off SIMPLE-STRINGP, I expect I can dig up a bit somewhere to remember the value of the option. This would in fact mean that simple-ness is a completely implementation-independent concept, and the only implementation-dependence is how much (if any) efficiency you gain by using it, and how much of that efficiency you get for free and how much you get only if you make declarations. Perhaps the last sentence isn't obvious to everyone. On the LM-2 Lisp machine, a simple string is faster than a non-simple string for many operations. This speed-up happens regardless of declarations; it is a result of a run-time dispatch to either fast microcode or slow microcode. On the VAX with a dumb compiler and no tuning, a simple string is only faster if you make declarations. On the VAX with a dumb compiler but some obvious tuning of sequence and string primitives to move type checks out of inner loops (making multiple copies of the inner loop), simple strings are faster for these operations, but still slow for AREF unless you make a type declaration. On the VAX with a medium-smart compiler that does the same sort of tuning on user functions, simple strings are faster for user functions, too, if you only declare (OPTIMIZE SPEED) [assuming that the compiler prefers space over speed by default, which is the right choice in most implementations], and save space as well as time if you go whole hog and make a type declaration. On the 3600 Lisp machine, you have sort of a combination of the first case and the last case. I also support the #* syntax for bit vectors, rather than the #" syntax. It's probably mere temporal accident that the simple switch proposal uses #" while the RPG memorial proposal uses #*. To sum up: A vector is a 1-dimensional array. It prints as #(foo bar) or # depending on the value of a switch. A string is a vector of characters. It always prints as "foo". Unlike all other arrays, strings self-evaluate and are compared by EQUAL. A bit-vector is a vector of bits. It always prints as #*101. Since as far as I can tell these are redundant with integers, perhaps like integers they should self-evaluate and be compared by EQUAL. I don't care. A simple-vector, simple-string, or simple-bit-vector is one of the above with none of the following MAKE-ARRAY (or MAKE-STRING) options specified: :FILL-POINTER :ADJUSTABLE-SIZE :DISPLACED-TO :LEADER-LENGTH, :LEADER-LIST (in implementations that offer them) There are type names and predicates for the three simple array types. In some implementations using the type declaration gets you more efficient code that only works for that simple type, which is why these are in the language at all. There are no user-visible distinctions associated with simpleness other than those implied by the absence of the above MAKE-ARRAY options.  Date: Thursday, 30 September 1982 00:35-EDT From: MOON at SCRC-TENEX To: common-lisp at SU-AI Subject: Issue 82 of the last CL meeting In-reply-to: The message of 29 Sep 1982 19:01-EDT from Brian G. Milnes Date: Wednesday, 29 September 1982 19:01-EDT From: Brian G. Milnes Issue 82 of the last common lisp committe meeting states that : one argument float should always return a single-float. This was to fix the previous travesty, where FLOAT could return a number of smaller precision than expected, if you happened to hand it an integer with only a few bits on (such as a power of two), since it would fit exactly. Then if you took the square root of that (for example), you would get a result with less precision than you expected. This is not orthogonal with the rest of the numeric functions, because although the default float result type is that of the most precise argument overflows from one float format roll onto the float format of the next greater precision. This is not the way I read the bottom paragraph on page 117 of the 29July Colander edition, which is the only thing I can find in a quick search that might be relevant to this. I think it is probably best for the system to do as few behind your back "smart", "helpful" tricks in the area of floating point numbers as possible. Certainly the 2 or 3 books on the subject I have seen are against this sort of thing. On the other hand, the proposed IEEE standard has some hand waving in it that seems to be aimed at providing for switching to an alternate number representation when overflow occurs. I don't have an expert opinion about this, but my uninformed opinion is that it would be better to signal exponent overflow than to switch to a bigger number representation. I -am- certain that it is better to signal inexact result than to switch to a bigger number representation (in the proposed IEEE standard, inexact result is the usually-disabled exception that is signalled when low-order bits of the fraction are lost.) If the user wants float to return only single-float, and cause an error if the argument will not fit can't he simple use (float x 0.0s0) ? But, if the user wants to return any convenient float, but not overflow or get bogged down in a high precision shouldn't he be able to do this with single argument float This is a tough one. Certainly it sounds plausible that FLOAT should work rather than giving you an error. On the other hand, in many implementations the floating-point number format with the biggest precision and range is substantially more expensive than the "standard one", so it may not be a good idea to use it unexpectedly, and it certainly is not a good idea to make FLOAT use it all the time. Whatever FLOAT does, READ should do the same thing for floating-point number syntaxes that don't explicitly specify a float type (e.g. ones with no exponent or an E exponent). If I have to vote, I will vote for leaving FLOAT the way it is: i.e. it always returns "single" format. By the way, 0.0s0 is "short" format, not "single" format. See page 18 of the colander.  Date: 30 September 1982 02:23-EDT From: Alan Bawden Subject: What is this RESTART kludge? To: Fahlman at CMU-20C cc: Common-Lisp at SU-AI Date: Wednesday, 29 September 1982 20:53-EDT From: Scott E. Fahlman For use in error recovery, it is important to have the implicit BLOCK surround the body, but NOT the variable initializations. Re-doing the inits is hardly ever what you want to do, not to mention the fact that this would tend to clobber any repairs the user has made to variable values. Can you provide examples to back up the claim that "re-doing the inits is hardly ever what you want to do"? Suppose: (defun foo (l &optional (y (1+ (car l)))) ... (when (oddp (car l)) (cerror :bad-argument "Odd car: ~S" l) (restart foo)) ...) Can you really argue that it is wrong to recompute the value of Y in GENERAL if it wasn't given by the caller and the list L has been given a new car? (Granted you can probably construct an INSTANCE in which it is wrong to recompute the value of Y.) A good reason to make the restart redo the inits is that it would otherwise be impossible for the programmer to ask for that behavior, whereas if he doesn't want them redone he can always explicitly add a restart block around the body of his defun. Given that in general you are going to have to think about this problem when you write a RESTART, I think it best to give the option of having it either way by having the built in restart do something that would be impossible to do otherwise. [Actually I think this is also a fairly good argument against the whole restart kludge. No matter what we do here people are going to be fooled into believing that RESTART is something that it isn't.]  Date: Wednesday, 29 September 1982 23:07-EDT From: Scott E. Fahlman To: Skef Wholey Cc: Common-Lisp at SU-AI Subject: MAKE as a new name for SETF (gasp!) Gasp, indeed. MAKE is used throughout Common Lisp as a prefix indicating the creation (allocation) of a new data structure. To use MAKE for an operation that alters a slot in an existing data structure would be terribly confusing. I like this even less than changing SETF to SET. -- Scott  Date: 30 September 1982 00:01-EDT From: Kent M. Pitman To: Wholey at CMU-20C cc: Common-Lisp at SU-AI I don't like the name MAKE because it suggests a constructor, not a mutator. eg, I would expect MAKE-PAIR to mean CONS, not DISPLACE. For the sake of those at CMU trying to get the first system out the door, I would suggest that we not spend a lot of time on non-critical naming issues until we get some of the more major issues worked out. The change you suggest is an upward compatible one which can safely be discussed later. The existence of the name SETF will not significantly impair existing programming since the operator's functionality is at least stable. At an appropriate later time, it would probably be worth reviving this issue as in the long run, I too feel that SETF is not desirable. -kmp  Date: Wednesday, 29 September 1982 23:36-EDT From: Scott E. Fahlman To: Kent M. Pitman Cc: Common-Lisp at SU-AI KMP is right. I was thinking of the new "progbody" form as the thing that implements the entire body of a PROG, but I went back to the original proposal and realized that the body of a PROG is really this new widget surrounded by a couple of blocks. So PROGBODY would be a misleading name, and TAGBODY or nearly anything else would be better. I still think TAGBODY is somewhat grotesque, but I don't have a better suggestion right now. -- Scott  Date: Wednesday, 29 September 1982 22:50-EDT From: Skef Wholey To: Common-Lisp at SU-AI Subject: MAKE as a new name for SETF (gasp!) Although there was already a round of mail on the subject of changing the name of SETF (to SET), I am re-suggesting that the name of SETF be changed. The two arguments against the name change were 1) The time-honored SET would be clobbered, and 2) A name change at this point would be absurd, since there are many other badly-named things in the language. To the first, I suggest a new name, MAKE. This not only enchances the clarity of code (e.g. (MAKE (SPACE-SHIP-SPEED ENTERPRISE) 'WARP-7)), but frees us from having to explain yet another bad choice of names to the next generation of LISPers. This brings us to the second point: that of changing a name at this stage of the game. Because this point has received so much discussion, and because SETF will now appear so prominently in every program, it is clear that this particular name change deserves some thought. I urge you to think one more time before closing the issue forever. --Skef  Date: Wednesday, 29 September 1982 22:50-EDT From: Skef Wholey To: Common-Lisp at SU-AI Subject: MAKE as a new name for SETF (gasp!) Although there was already a round of mail on the subject of changing the name of SETF (to SET), I am re-suggesting that the name of SETF be changed. The two arguments against the name change were 1) The time-honored SET would be clobbered, and 2) A name change at this point would be absurd, since there are many other badly-named things in the language. To the first, I suggest a new name, MAKE. This not only enchances the clarity of code (e.g. (MAKE (SPACE-SHIP-SPEED ENTERPRISE) 'WARP-7)), but frees us from having to explain yet another bad choice of names to the next generation of LISPers. This brings us to the second point: that of changing a name at this stage of the game. Because this point has received so much discussion, and because SETF will now appear so prominently in every program, it is clear that this particular name change deserves some thought. I urge you to think one more time before closing the issue forever. --Skef  Date: 29 September 1982 22:45-EDT From: Kent M. Pitman To: Fahlman at CMU-10A cc: Common-Lisp at SU-AI Your point that PROGBODYs are also RETURN-BODYs is what makes the strongest argument for TAGBODY. The name PROGBODY is most suggestive of "having the functionality one expects in a PROG's body" which includes the ability to RETURN. ie, that (PROG (...) . body) might mean (LET (...) (PROGBODY ...)) which we obviously don't intend. Hence, any name not including the name PROG would be better because it would not suggest functionality we don't intend it to provide. Hence, I think the name TAGBODY is fine.  Date: Wednesday, 29 September 1982 20:53-EDT From: Scott E. Fahlman To: Alan Bawden Cc: Common-Lisp at SU-AI Subject: What is this RESTART kludge? Fine, let's require RESTART to take a block name, but not outlaw (RESTART NIL). I'm not sure I'd ever use (RESTART NIL), but if it is not really screwing anyone, it's less confusing to leave it in. Let me raise a related issue. Since (DEFUN FOO ...) includes an implicit restart block (implemented in either way). Where does that restart block lie with respect to the code in &OPTIONAL and &AUX variables? For use in error recovery, it is important to have the implicit BLOCK surround the body, but NOT the variable initializations. Re-doing the inits is hardly ever what you want to do, not to mention the fact that this would tend to clobber any repairs the user has made to variable values. I agree with GLS that TAGBODY is a better name. PROG has nothing to do with it. Well, it's the body of a PROG (or PROG-like construct), not the body of a tag. All sorts of things are documented as having a body like a prog, so this seems a natural way to describe what's going on at least to those who already know Lisp. Why pick on tags? It's also a RETURN-BODY and a SYMBOLS-ENCOUNTERED-AT-TOP-LEVEL-ARE-NOT-EVALUATED-BODY. -- Scott  Date: Wednesday, 29 September 1982 19:01-EDT From: Brian G. Milnes To: common-lisp at SU-AI Subject: Issue 82 of the last CL meeting Issue 82 of the last common lisp committe meeting states that : one argument float should always return a single-float. This is not orthogonal with the rest of the numeric functions, because although the default float result type is that of the most precise argument overflows from one float format roll onto the float format of the next greater precision. I am not sure if this is what is actually intended by the CL manual, but it is the way SpiceLisp has been implemented. Perhaps it would be nice if on the next pass over the numeric chapter, Guy would specify exactly how overflow is handled, or say that it is implementation specific. If the user wants float to return only single-float, and cause an error if the argument will not fit can't he simple use (float x 0.0s0) ? But, if the user wants to return any convenient float, but not overflow or get bogged down in a high precision shouldn't he be able to do this with single argument float ? - Brian G. Milnes (SpiceLisp NumberHacker)  Date: 29 September 1982 19:06-EDT From: Alan Bawden Subject: What is this RESTART kludge? To: Common-Lisp at SU-AI Date: Monday, 27 September 1982 23:14-EDT From: Scott E. Fahlman I agree with Alan Bawden that RESTART should not have a value-returning subform, and that RESTART-FROM is silly. It is probably also OK to flush (RESTART NIL) and require a non-null block-name. Slight misunderstanding here. I was not proposing that "(RESTART NIL)" be disallowed, only that "(RESTART)" be disallowed. But I won't object if you really want to go this far, as long as we at least take the step of requiring a block name. I guess I am convinced that having RESTART built into the language is a good idea, if only so that DEFUN can produce one. I still think that using BLOCK as the thing to restart is a poor idea, and I wish someone would take my idea of having a separate RESTARTABLE form and a separate namespace of restart tags seriously (option #2 in my last message). (DEFUN can produce BOTH so that you can both RETURN-FROM and RESTART any function.) I really think is is a bad mistake to build an implicit loop into every BLOCK. Let me raise a related issue. Since (DEFUN FOO ...) includes an implicit restart block (implemented in either way). Where does that restart block lie with respect to the code in &OPTIONAL and &AUX variables? By the way, are we converging toward the name TAGBODY? I much prefer PROGBODY for this use. I agree with GLS that TAGBODY is a better name. PROG has nothing to do with it.  Date: Wednesday, 29 September 1982 19:01-EDT From: Brian G. Milnes To: common-lisp at SU-AI Subject: Issue 82 of the last CL meeting Issue 82 of the last common lisp committe meeting states that : one argument float should always return a single-float. This is not orthogonal with the rest of the numeric functions, because although the default float result type is that of the most precise argument overflows from one float format roll onto the float format of the next greater precision. I am not sure if this is what is actually intended by the CL manual, but it is the way SpiceLisp has been implemented. Perhaps it would be nice if on the next pass over the numeric chapter, Guy would specify exactly how overflow is handled, or say that it is implementation specific. If the user wants float to return only single-float, and cause an error if the argument will not fit can't he simple use (float x 0.0s0) ? But, if the user wants to return any convenient float, but not overflow or get bogged down in a high precision shouldn't he be able to do this with single argument float ? - Brian G. Milnes (SpiceLisp NumberHacker)  Date: Wednesday, 29 September 1982 09:54-EDT From: Scott E. Fahlman To: common-lisp at SU-AI Subject: Arrays and Vectors Guy will be preparing a ballot on the recent flurry of issues pretty soon, but I would like to jump the gun on one of them. I would really like us to come to some sort of conclusion on the array/vector business. Because this is a large issue and is pervasive, a lot of coding is being delayed until this gets settled. It would be very useful to see if there is anything like a consensus out there. If so, we can wrap this up; if not, we may need another face-to-face meeting to bash out the details in finite time -- I really don't want this to hang for another month or two. It seems to me that the live options are 1. Simple-switch. 2. RPG memorial. 3. Neither of the above. Please let me know which of these options you prefer and which of the others you would be willing to live with. If you vote for 3, please include a coherent counter-proposal, or at least a clear indication of what you are unhappy about. As for my vote, I could live with either 1 or 2. I have a slight preference for 1 (surprise!) because the nomenclature seems much less confusing -- I think the added clarity outweighs the disadvantage of having to write "simple" in some declarations. -- Scott  Date: Wednesday, 29 September 1982, 16:09-EDT From: Daniel L. Weinreb Subject: Re: Arrays and vectors (again) To: Ginder at CMU-20C Cc: common-lisp at SU-AI In-reply-to: The message of 29 Sep 82 11:26-EDT from Ginder at CMU-20C Good try but I really don't think it works. (typep thing '(array string-char 1)) is just too verbose, especially for programs that use strings in any heavy kind of way. I have been using a Lisp with real strings for many years now, and STRINGP is a function that gets reasonably heavy use. Scott, I apologize for not reading your proposal carefully enough. It does indeed answer all my questions. Now that I understand what's going on, I still don't like it. The problem is just that the naming is too complex and inconsistent. I think you and I agree on this point, at least in sign if not in magnitude. One clear problem is that the criterion for acceptability to STRING- functions is not the same as STRINGP-, and so it's not really clear what STRING means. A more serious (but more debatable, I guess) problem is just a conceptual one for me; I think of a string with a leader as being a string, not a one-d-char-array, and that's why it prints out with double quotes instead of #. I just have a feeling for what a string is, and I'm quite certain that even a string with "hairy" features like having an array-leader is still a string. So (no surprise) I am in favor of the "simple-switch" proposal, with about three exclamation points (in the November terminology).  Date: 29 Sep 1982 1127-PDT From: Dick Gabriel Subject: Proposals To: common-lisp at SU-AI Both the Simple Switch and ``RPG Memorial'' array proposals are on the file ARRAY[COM,LSP], which can be FTPed away without login. -rpg-  Date: 29 September 1982 1254-EDT (Wednesday) From: Guy.Steele at CMU-10A To: common-lisp at SU-AI Subject: Design of Common LISP I am very grateful to Hedrick for his vote of confidence, but I must point out that I am no less fallible than anyone else on the committee. Two items that come to mind are the useless extensions to GCD and to the ENDP predicate, lapses of taste I am glad have been corrected through committee interaction. This is, however, why we prefer consensus to voting; presumably a unified committee will produce a more or less unified and consistent design, while a design whose different aspects are supported by different 51%-subsets of the committee is less likely to be consistent. --Guy  Date: 29 Sep 1982 1241-EDT From: HEDRICK at RUTGERS (Mgr DEC-20s/Dir LCSR Comp Facility) Subject: Re: Arrays and Vectors To: Fahlman at CMU-20C cc: common-lisp at SU-AI In-Reply-To: Your message of 29-Sep-82 1019-EDT My vote on this, as most other issues, is that I would like Guy to design the language, keeping in mind the goals that it should be as compatible with Maclisp and as simple as possible. I am very concerned about the results of having a language designed by a committee. I guess I am saying that I am giving Guy my proxy. -------  Date: 29 Sep 1982 1126-EDT From: Ginder at CMU-20C Subject: Re: Arrays and vectors (again) To: Fahlman at CMU-20C cc: common-lisp at SU-AI In-Reply-To: Your message of 29-Sep-82 0940-EDT Perhaps we need devote no name to the notion denoted as char(bit)-sequence in the RPG memorial proposal. Wouldn't it just be OK to say that "string functions" accept those things that satisfy : (typep THING '(array string-char 1)) People would probably refer to these things as "1 dimensional character arrays" or something when talking about them, but it's not clear to me that we need devote a special type specifier to them. If naming is a problem, then maybe the simple-switch version is the win. -Joe -------  Date: Wednesday, 29 September 1982 09:54-EDT From: Scott E. Fahlman To: common-lisp at SU-AI Subject: Arrays and Vectors Guy will be preparing a ballot on the recent flurry of issues pretty soon, but I would like to jump the gun on one of them. I would really like us to come to some sort of conclusion on the array/vector business. Because this is a large issue and is pervasive, a lot of coding is being delayed until this gets settled. It would be very useful to see if there is anything like a consensus out there. If so, we can wrap this up; if not, we may need another face-to-face meeting to bash out the details in finite time -- I really don't want this to hang for another month or two. It seems to me that the live options are 1. Simple-switch. 2. RPG memorial. 3. Neither of the above. Please let me know which of these options you prefer and which of the others you would be willing to live with. If you vote for 3, please include a coherent counter-proposal, or at least a clear indication of what you are unhappy about. As for my vote, I could live with either 1 or 2. I have a slight preference for 1 (surprise!) because the nomenclature seems much less confusing -- I think the added clarity outweighs the disadvantage of having to write "simple" in some declarations. -- Scott  Date: Wednesday, 29 September 1982 09:54-EDT From: Scott E. Fahlman To: common-lisp at SU-AI Subject: Arrays and Vectors Guy will be preparing a ballot on the recent flurry of issues pretty soon, but I would like to jump the gun on one of them. I would really like us to come to some sort of conclusion on the array/vector business. Because this is a large issue and is pervasive, a lot of coding is being delayed until this gets settled. It would be very useful to see if there is anything like a consensus out there. If so, we can wrap this up; if not, we may need another face-to-face meeting to bash out the details in finite time -- I really don't want this to hang for another month or two. It seems to me that the live options are 1. Simple-switch. 2. RPG memorial. 3. Neither of the above. Please let me know which of these options you prefer and which of the others you would be willing to live with. If you vote for 3, please include a coherent counter-proposal, or at least a clear indication of what you are unhappy about. As for my vote, I could live with either 1 or 2. I have a slight preference for 1 (surprise!) because the nomenclature seems much less confusing -- I think the added clarity outweighs the disadvantage of having to write "simple" in some declarations. -- Scott  Date: Wednesday, 29 September 1982 09:35-EDT From: Scott E. Fahlman To: Ginder at CMU-20C Cc: common-lisp at SU-AI Subject: Arrays and vectors (again) Sigh! Well, I suppose we could call these things GENERAL-CHAR-1-D-ARRAYS, but that's pretty awful. I must say that on the grounds of cleanliness of nomenclature, the simple-switch proposal seems to dominate the RPG memorial. -- Scott  Date: 29 Sep 1982 0815-EDT From: Ginder at CMU-20C Subject: Re: Arrays and vectors (again) To: Fahlman at CMU-20C cc: common-lisp at SU-AI In-Reply-To: Your message of 28-Sep-82 2103-EDT Does the notion of char-sequence include lists of characters? If it does not, then using char-SEQUENCE to denote it will be confusing to new users. If we go the whole route and fully generalize the notion of char-sequence, someone will probably propose that we include the notion of bit-sequence. I don't know if this is reasonable or not. -Joe -------