Received: from CMU-CS-A.ARPA by SU-AI.ARPA with TCP; 6 Jul 84 23:17:09 PDT Date: 7 Jul 84 0202 EDT (Saturday) From: Guy.Steele@CMU-CS-A.ARPA To: AS%hp-labs.csnet@csnet-relay.arpa Subject: Re: Query about IN-PACKAGE CC: common-lisp@SU-AI.ARPA In-Reply-To: <8407062349.AA00673@HP-VENUS> I am having trouble finding what parts of the manual answer your question "YES". Could you cite specific passages, with page numbers, so I can study the question more carefully? --Guy  Received: from CMU-CS-A.ARPA by SU-AI.ARPA with TCP; 6 Jul 84 23:01:42 PDT Date: 7 Jul 84 0152 EDT (Saturday) From: Guy.Steele@CMU-CS-A.ARPA To: AS%hp-labs.csnet@csnet-relay.arpa Subject: Re: &REST in DEFMACRO CC: common-lisp@SU-AI.ARPA In-Reply-To: <8407021704.AA00732@HP-VENUS> Well, this is what I would call a "curprising consequence", but yes, I would say that (defmacro foo (&optional a b &rest (c d)) ...) in effect makes a, b, c, and d all be required, else the parameters c and d could never be satisfied. You can get the effect you seem to want by writing (defmacro foo (&optional a b &rest (&optional c d) ...) ... --Guy  Received: from CMU-CS-C.ARPA by SU-AI.ARPA with TCP; 6 Jul 84 20:13:39 PDT Received: ID ; Fri 6 Jul 84 23:13:25-EDT Date: Fri, 6 Jul 1984 23:13 EDT Message-ID: Sender: FAHLMAN@CMU-CS-C.ARPA From: "Scott E. Fahlman" To: AS%hp-labs.csnet@CSNET-RELAY.ARPA Cc: Common-Lisp@SU-AI.ARPA Subject: Query about IN-PACKAGE In-reply-to: Msg of 6 Jul 1984 19:49-EDT from AS%hp-labs.csnet at csnet-relay.arpa The intent was that if package "FOO" already exists, (IN-PACKAGE "FOO") would make it the current package but would not alter the USE list. However, if a :USE argument is present, any new packages it contains would be merged in. Until you brought it up, it hadn't occurred to me that this might be read as requiring the LISP package to be used if there is no explicit :USE argument -- something to clarify in the second edition. -- Scott  Received: from CSNET-RELAY.ARPA by SU-AI.ARPA with TCP; 6 Jul 84 17:45:59 PDT Received: From hp-labs.csnet by csnet-relay; 6 Jul 84 20:18 EDT Received: by HP-VENUS id AA00673; Fri, 6 Jul 84 16:49:20 pdt Message-Id: <8407062349.AA00673@HP-VENUS> Date: 6 Jul 1984 1649-PDT From: AS%hp-labs.csnet@csnet-relay.arpa Subject: Query about IN-PACKAGE To: Common-Lisp@su-ai.arpa Cc: AS@csnet-relay.arpa Source-Info: From (or Sender) name not authenticated. If the statement (IN-PACKAGE "FOO") is executed in a context where the package "FOO" exists but does not USE the "LISP" package, should the "LISP" package be added to the use-list of the package "FOO"? A literal reading of the CL book says YES. My intuition says NO. I had assumed that using IN-PACKAGE with one argument is the recommended way to "enter" a package, but such usage assumes no side-effects on the package itself. Am I misinterpreting the intent of the definition? -------  Received: from CSNET-RELAY.ARPA by SU-AI.ARPA with TCP; 2 Jul 84 15:26:20 PDT Received: From hp-labs.csnet by csnet-relay; 2 Jul 84 18:11 EDT Received: by HP-VENUS id AA00732; Mon, 2 Jul 84 10:04:53 pdt Message-Id: <8407021704.AA00732@HP-VENUS> Date: 2 Jul 1984 0942-PDT From: AS%hp-labs.csnet@csnet-relay.arpa Subject: &REST in DEFMACRO To: common-lisp@su-ai.arpa Cc: AS@csnet-relay.arpa Source-Info: From (or Sender) name not authenticated. The book says that a lambda-list may appear in place of a parameter name in DEFMACRO. Was this meant to apply to a &REST parameter as well? This seems like a bad idea. For example: (defmacro foo (&optional a b &rest (c d)) ...) Does this mean that a, b, c, and d are all required? Or is &rest (c d) ==> &optional c d? Please tell me that it is illegal! -------  Received: from UTAH-20.ARPA by SU-AI.ARPA with TCP; 30 Jun 84 15:24:02 PDT Date: Sat 30 Jun 84 16:24:43-MDT From: Stan Shebs Subject: Pathname Questions To: common-lisp@SU-AI.ARPA (Pardon this if it's been fixed since Excelsior, we don't have anything more recent here) Excelsior defines the pathname merging operation as taking a pathname, a defaults pathname, default type, and default version, while the merge-pathnames function does not take a default type as an option. Is this a mistake? If not, then how does one specify a default type for merging? Also, *load-pathname-defaults* is supposedly only a single pathname, however, it's very convenient to have a list of pathnames to search. This is very handy in PSL for loading modules, since you can search your own directory, the directory of new hacks, and the standard load module directory, in that order. Does the CL spec preclude using a list of pathnames in *load-pathname-defaults*? adTHANXvance, stan shebs -------  Received: from RUTGERS.ARPA by SU-AI.ARPA with TCP; 24 Jun 84 20:14:12 PDT Date: 24 Jun 84 23:13:51 EDT From: Charles Hedrick Subject: [HAUTIN@RUTGERS.ARPA: common lisp] To: common-lisp@SU-AI.ARPA I decided you might be interested in the full text of the request that I alluded to before. In case any of your are curious, the answer to the first question is that Tops-20 Common Lisp runs. It is fairly complete. However currently there is no compiler. It should be finished by late fall. It will probably compile the full language by the end of the summer, but without doing the sorts of optimizations one would like. The Tops-20 implementation is based on CMU's Spice Lisp, as is DEC's VAX implementation. At the moment it looks like we will support it from here. We are a bit uncertain what sort of demand there is for a new DEC-20 language at this late date. If a significant number of customers want (and will pay for) real support, we and DEC would be happy to arrange that. We just don't know whether there will be sufficient demand for this to set up a real support organization. DEC-20 Lisp is not based on the VAX sources. However we are looking at what the VAX implementors have done, and will try to supply a reasonable degree of compatibility in the language. --------------- Mail-From: HAUTIN created at 22-Jun-84 09:32:06 Date: 22 Jun 84 09:32:06 EDT From: HAUTIN@RUTGERS.ARPA Subject: common lisp To: hedrick@RUTGERS.ARPA cc: hautin@RUTGERS.ARPA Original-language: French Translated-by: hedrick@RUTGERS.ARPA Hello, I would like to ask some questions about Common Lisp. 1) How is your project going? Does your compiler work yet? Will there be DEC support? (DEC keeps pushing back availability for VAX Common Lisp.) 2) What will be the impact of Common Lisp on other American research groups, for example Yale, Berkeley, Xerox, and BBN? 3) We here at CNET would like to standardize on a Lisp for VAX 11/780 IBM 3083 with VM/CMS and/or UNIX/UTS SM90 UNIX/68000 (This is a multi-processor machine developed by CNET) 4) At the moment we use NIL from MIT on the VAX. We are generally quite pleased with it. For IBM we don't have anything For the SM90 we have LELISP from INRIA, but it has a few problems (separate compilation, an enviornment that is not as good as NIL's) 5) Would it be possible to get a Common Lisp compiler that we could port to these machines? or if not, at least a compiler that we could look at that is based on the Common Lisp specification? I would be very grateful if you could help us with these various problems. Do you know of a bboard about Smalltalk? At the University of Brest a group has implemented Smalltalk for our SM90 system. They would be quite interested in comparing their implementation with others. Their implementation currently works. They are now working on performance improvements. Thank you, F Hautin ------- -------  Received: from RUTGERS.ARPA by SU-AI.ARPA with TCP; 22 Jun 84 13:42:19 PDT Date: 22 Jun 84 16:41:38 EDT From: Charles Hedrick Subject: request for information about implementations To: common-lisp@SU-AI.ARPA One of our users is interested in finding implementations of Common Lisp for IBM 3083 under VM/CMS and/or UNIX (alias UTS), 68000 under Unix Implementations for other Unix systems that could reasonably be ported would also be interesting to them. They would also like to have access to a compiler that they could look at, and preferably use as the basis for their own compiler. -------  Received: from CMU-CS-A.ARPA by SU-AI.ARPA with TCP; 20 Jun 84 21:52:02 PDT Date: 21 Jun 84 0050 EDT (Thursday) From: Guy.Steele@CMU-CS-A.ARPA To: masinter.pa@XEROX.ARPA Subject: "ANSI Lisp" rumor CC: common-lisp@SU-AI.ARPA In-Reply-To: "masinter.pa@XEROX.ARPA's message of 2 Jun 84 20:55-EST" I do not know of any official effort within ANSI to do anything at all about LISP. Here is what I do know: I have been told that a group in China has suggested that perhaps an ISO standard for LISP should be promulgated. I know nothing more about it than that. However, at the request of David Wise and J.A.N. Lee, I have sent a copy of the Common LISP Manual to J.A.N. Lee, who has been involved with standards of various kinds at ACM. (David Wise is a member of the SIGPLAN council, or whatever it is called, and is the LISP expert within that body.) The idea is that if either an ISO or ANSI standards effort were to be undertaken, Wise and Lee feel that such an effort should certainly take the work done on Common LISP into account, and they want people in the standards organizations to be aware of the Common LISP work. I sent a copy of the Table of Contents to Lee several months ago, and it was my understanding that he might choose to circulate copies of it to, for example, members of the SIGPLAN council. That's where it stands. I repeat, I know of no effort actually to start a standards effort; Wise and Lee merely want certain people to be prepared by already having information about Common LISP if any of a number of possible developments should unfold. --Guy  Received: from RUTGERS.ARPA by SU-AI.ARPA with TCP; 15 Jun 84 22:08:05 PDT Date: 16 Jun 84 01:08:52 EDT From: Charles Hedrick Subject: request for list of changes To: common-lisp@SU-AI.ARPA Does anyone have a list of substantive changes between Mary Poppins and the published manual? I am thinking of actual differences in the language, not just editorial improvements. I just got my copy of the printed manual. My first use of it was debugging the handling of syntax classes in our READ. The main bug was that we had not implemented an illegal character type. Much to my surprise, there is now an illegal syntax class, as well as an illegal attribute for constituents. Let's hope I was just unlucky that the first thing I looked up had changed. I don't really want to reimplement the language, nor to check the manual line by line. -------  Received: from CMU-CS-C.ARPA by SU-AI.ARPA with TCP; 14 Jun 84 20:39:27 PDT Received: ID ; Thu 14 Jun 84 23:38:08-EDT Date: Thu, 14 Jun 1984 23:38 EDT Sender: FAHLMAN@CMU-CS-C.ARPA From: Scott E. Fahlman To: common-lisp@SU-AI.ARPA Subject: Last-minute change Before Flag Day ends at midnight, there's one little change I'd like to get into Defsetf.... Oh, never mind.  Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 13 Jun 84 09:53:19 PDT Received: from SCRC-CHICOPEE by SCRC-STONY-BROOK via CHAOS with CHAOS-MAIL id 46522; Mon 11-Jun-84 07:15:50-EDT Date: Mon, 11 Jun 84 07:14 EDT From: "Daniel L. Weinreb" Subject: Re: Leakiness and Kernels To: HEDRICK@RUTGERS.ARPA, SHEBS@UTAH-20.ARPA Cc: common-lisp@SU-AI.ARPA In-reply-to: The message of 9 Jun 84 17:36-EDT from Charles Hedrick Message-ID: <840611071410.4.DLW@CHICOPEE.SCRC.Symbolics> Gold Hill Computers in Cambridge hopes to do a Common Lisp for the IBM/PC. You could talk to them.  Received: from UTAH-20.ARPA by SU-AI.ARPA with TCP; 9 Jun 84 13:12:08 PDT Date: Sat 9 Jun 84 11:11:10-MDT From: Stan Shebs Subject: Leakiness and Kernels To: common-lisp@SU-AI.ARPA (Thanx for the replies to my question about io buffering) As far as I can tell, the CL spec does not say anything about how much an implementation is allowed to "leak", that is, how much and what sort of space does not have to be reclaimed within a running Lisp process. Seems like an implementation-dependent thing, but then one has to worry about whether a 3-hour running time program that does 1K or more GCs will be able to run on different machines. I suppose stack depths and so forth are also portability barriers of the same sort. What's the story? Also, I've heard much discussion around at Utah about how a CL kernel must be gigantic, and that Hedrick@Rutgers had done a kernel that took up an entire segment on the 20, and so forth. Is there some deep reason why this must be true? Much of CL can be (inefficiently) implemented as macros, and even some of the datatypes could be done as structures defined by loadable modules. Exactly what *must* be in the kernel? stan shebs -------  Received: from CMU-CS-C.ARPA by SU-AI.ARPA with TCP; 9 Jun 84 15:57:50 PDT Received: ID ; Sat 9 Jun 84 18:57:09-EDT Date: Sat, 9 Jun 1984 18:57 EDT Sender: FAHLMAN@CMU-CS-C.ARPA From: Scott E. Fahlman To: Stan Shebs Cc: common-lisp@SU-AI.ARPA Subject: Leakiness and Kernels In-reply-to: Msg of Sat 9 Jun 84 11:11:10-MDT from Stan Shebs The Perq implemenation of Common Lisp weighs in at 2.5 megabytes as it sits out there on the disk. That includes the Compiler, the Hemlcok text editor, debugging aids, documentation strings, and all of Common Lisp. For just the language itself, and flushing the doc strings, I think we'd come in at a megabyte or maybe somewhat less, but of course you would not want to use such a system. There's a lot of stuff in Common Lisp that doesn't have to be there -- hyperbolic arctan, Roman numeral output in Format, etc. We put that stuff in because most of the designers felt that, starting now, any machine without virtual memory is not interesting for serious work. Given that people were going to add these things anyway, we figured that they may as well be built in so that they are done in a standard way. Of course, the last generation of microcomputer chips (and the current generation of low-end personal computers) does not support virtual memory. Any Common Lisps on them will have to either go for a subset or get very clever about overlays and such. But this is a temporary phase that won't be with us for long, and it seemed a shame to ruin the language in order to accommodate these transitional machines. Storage-management is completely up to the implementation, but in my opinion any implementation that leaks storage at all is broken. A Xerox-style reference-count GC is OK as long as it is backed up with a real garbage collector, but not otherwise. Most Common Lisp implementations will use some sort of copying GC, since strings and other ragged-length data structures are so important in this language. In GC's of this sort, there is no reason for any leaking -- it's easy enough to do it right. -- Scott  Received: from MIT-ML.ARPA by SU-AI.ARPA with TCP; 9 Jun 84 11:23:14 PDT Date: 8 Jun 1984 2210-EDT From: Daniel L. Weinreb Subject: Manuals To: common-lisp@SU-AI A carton of Common Lisp manuals arrived at Symbolics today, from Digital Press. We were all very happy to see them! It looks like we turned Common Lisp from an initial conception to a final published standards document (Release 1.0) in under three years, which I think is something we can all be proud of. Congratulations to everybody, esspecially Guy Steele! -------  Received: from RUTGERS.ARPA by SU-AI.ARPA with TCP; 9 Jun 84 14:37:26 PDT Date: 9 Jun 84 17:36:14 EDT From: Charles Hedrick Subject: Re: Leakiness and Kernels To: SHEBS@UTAH-20.ARPA cc: common-lisp@SU-AI.ARPA In-Reply-To: Message from "Stan Shebs " of 9 Jun 84 13:11:10 EDT It is certainly true that Common Lisp is more complex than the Lisps I know and love. But it's not *that* big. Our current kernel is 40312 words (79 pages). The whole thing takes 559 pages, which is somewhat more than a section. But that's not the kernel: that's the whole implementation. And we don't have a compiler yet, so that is interpreted code. I assume the compiled version will be smaller. Note that our "kernel" is in fact somewhat larger than necessary. I have handcoded everything that I thought would improve performance. This includes EVAL, most of READ and PRINT, and various other things. There are also complications such as an EMACS interface, and code to save a core image without using the SSAVE JSYS. These are not part of the Common Lisp definition. (And in fact the save code is no longer needed, as SSAVE now works with multi-section programs.) If you wanted to do an implementation on a microcomputer, using a minimal kernel, I don't think the kernel for Common Lisp would be any bigger than the kernel for any other modern dialect. The things I object to most are complexities in lambda binding, multiple values, and the way the sequence functions are designed. But only multiple values are really needed in the kernel, and the amount of code for them is minimal. -------  Received: from CMU-CS-C.ARPA by SU-AI.ARPA with TCP; 5 Jun 84 07:07:19 PDT Received: ID ; Tue 5 Jun 84 10:06:06-EDT Date: Tue, 5 Jun 1984 10:06 EDT Sender: FAHLMAN@CMU-CS-C.ARPA From: Scott E. Fahlman To: "Daniel L. Weinreb" Cc: common-lisp@SU-AI.ARPA Subject: Kyoto Common Lisp In-reply-to: Msg of 5 Jun 1984 00:26-EDT from "Daniel L. Weinreb" A group within Data General is using our Common Lisp sources for a project that I'm not allowed to describe, but whose general goals are probably not hard to guess. They passed our code (a rather old version, I'm afraid) along to Nippon Data General, who collaborated with the Kyoto people to bring up a quick implementation on the Eclipse MV. My source at DG tells me that this is a rather thorough implementation, but rather slow as well -- the point was to get an implementation up, not to produce a production-quality system. As the note from Kyoto says, they use C as the compiler back-end. That's all I know, and since we have no Eclipses around here, we have no way of taking a closer look. I will be interested in hearing what Weinreb can learn first-hand when he's over there. -- Scott  Received: from DEC-MARLBORO.ARPA by SU-AI.ARPA with TCP; 5 Jun 84 06:19:20 PDT Date: Tue 5 Jun 84 09:19:09-EDT From: "Walter van Roggen" Subject: Re: macroexpansion environments To: Moon@SCRC-RIVERSIDE.ARPA cc: common-lisp@SU-AI.ARPA, WVANROGGEN@DEC-MARLBORO.ARPA In-Reply-To: Message from ""David A. Moon" " of Mon 4 Jun 84 15:45:39-EDT What the examples do when compiled isn't the point. They needn't even print anything at compile time (and also needn't cause an error). I agree that the examples constitute programs whose semantics aren't well-defined. What bothers me is how innocuously similar the two cases are and that macros expanding into declarations ought to work "like you'd expect", but don't and can't. ---Walter -------  Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 5 Jun 84 04:01:51 PDT Received: from SCRC-CHICOPEE by SCRC-STONY-BROOK via CHAOS with CHAOS-MAIL id 44212; Tue 5-Jun-84 00:27:34-EDT Date: Tue, 5 Jun 84 00:26 EDT From: "Daniel L. Weinreb" Subject: Kyoto Common Lisp To: common-lisp@SU-AI.ARPA Message-ID: <840605002611.2.DLW@CHICOPEE.SCRC.Symbolics> Presumably many of you got the same letter as I did, from Dr. Yuasa of Kyoto University, about Kyoto Common Lisp for the Data General Eclipse MV under AOS/VS. Does anybody know more about this than the letter says? I will be at Kyoto University on July 11, and perhaps I will be able to learn more then.  Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 4 Jun 84 12:38:41 PDT Received: from SCRC-EUPHRATES by SCRC-STONY-BROOK via CHAOS with CHAOS-MAIL id 43975; Mon 4-Jun-84 15:38:52-EDT Date: Mon, 4 Jun 84 15:38 EDT From: "David A. Moon" Subject: macroexpansion environments To: Walter van Roggen Cc: common-lisp@SU-AI.ARPA In-reply-to: The message of 4 Jun 84 10:47-EDT from Walter van Roggen Message-ID: <840604153807.3.MOON@EUPHRATES.SCRC.Symbolics> Date: Mon 4 Jun 84 10:47:30-EDT From: "Walter van Roggen" Here's an interesting problem with Common Lisp: (defvar x 1) (defmacro m () (print x) `(list ,x x)) (let ((x 2)) (m)) ;case A (let ((x 2)) () (m)) ;case B In case A it will print a 1 and return the list (1 2). In case B it will print a 2 and return the list (2 2). Think about what will happen when you compile this code. Both cases will print a 1 AT COMPILE TIME and include the list (1 2) in the expanded code. Or, if you don't put an eval-when compile around the defvar of x, it will blow out at compile time. I don't think this is a very interesting problem: you have simply constructed a program whose semantics cannot possibly be well-defined.  Received: from DEC-MARLBORO.ARPA by SU-AI.ARPA with TCP; 4 Jun 84 07:47:40 PDT Date: Mon 4 Jun 84 10:47:30-EDT From: "Walter van Roggen" Subject: macroexpansion environments To: common-lisp@SU-AI.ARPA Here's an interesting problem with Common Lisp: (defvar x 1) (defmacro m () (print x) `(list ,x x)) (let ((x 2)) (m)) ;case A (let ((x 2)) () (m)) ;case B In case A it will print a 1 and return the list (1 2). In case B it will print a 2 and return the list (2 2). The problem is that special forms such as LET have to expand at least the first form of the body in order to find out if it returns a declaration. (More may have to be expanded if it does expand into a declaration.) The question is what environment does the macro call get expanded in. You'd expect that they'd have to be expanded inside the bindings set up by the LET itself, but this isn't possible if the macro returns a declaration, which might affect the binding. In the example above, all instances of X are special, but that needn't have been the case. What's disconcerting is that the results are different for the seemingly identical cases. Now since one isn't supposed to depend on when macros get evaluated, nor how often they get evaluated, it might be possible ignore the problem of having different side effects, and one could implement the special forms to re-expand the macro if it didn't expand into a declaration and the environment has changed. That might "resolve" the issues for the example above, but I'm still concerned. For example: (setq y 1) (defmacro decl () `(declare (special y))) (defmacro m () (print y) `(list ,y y))) (let ((y 2)) (decl) (m)) I don't think it would be reasonable to disallow macros expanding into declarations. Ideas? ---Walter -------  Received: from XEROX.ARPA by SU-AI.ARPA with TCP; 2 Jun 84 18:57:14 PDT Received: from Salvador.ms by ArpaGateway.ms ; 02 JUN 84 18:57:06 PDT From: masinter.pa@XEROX.ARPA Date: 2 Jun 84 18:55:30 PDT Subject: ANSI Lisp To: common-lisp@SU-AI.ARPA I've just heard an odd rumor about an ANSI Lisp group. Anybody know anything about it? The folks at ANSI, by the way, claim not to know anything about it at all.  Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 1 Jun 84 05:26:29 PDT Received: from SCRC-CHICOPEE by SCRC-STONY-BROOK via CHAOS with CHAOS-MAIL id 42545; Fri 1-Jun-84 00:37:37-EDT Date: Fri, 1 Jun 84 00:37 EDT From: "Daniel L. Weinreb" Subject: Meeting at the ACM Symposium To: common-lisp@SU-AI.ARPA Message-ID: <840601003736.3.DLW@CHICOPEE.SCRC.Symbolics> Many of the Common Lisp designers and implementors will be present at the ACM Symposium on Lisp and Functional Programming in Austin this August. I propose a short meeting of any of us on this list, on Tuesday August 7 at 6:15 (during the "break before banquet"). The main agenda item (there's only time for one item, anyway) is what to do about ambiguities or inclarities that come up in the published Common Lisp definition: how do we keep all the implementations compatible? I don't know where this meeting will occur (I don't know anything about the local arrangements), but I presume we'll find something acceptable.  Received: from DEC-MARLBORO.ARPA by SU-AI.ARPA with TCP; 8 May 84 14:56:06 PDT Date: Tue 8 May 84 17:57:04-EDT From: "Walter van Roggen" Subject: REQUIRE To: AS%hp-labs.csnet@CSNET-RELAY.ARPA cc: common-lisp@SU-AI.ARPA The Vax version of Common Lisp also evaluates a REQUIRE form seen at top-level when compiling, but the action taken is different from (EVAL-WHEN (COMPILE) (REQUIRE ...)), since REQUIRE will try to do COMPILE-FILE's (with :OUTPUT-FILE NIL) on the files constituting the module if it isn't already on the provided list. There's a similar list for modules already compiled (but not loaded). The reasoning is that one wants to avoid altering the lisp environment, since the normal use is to get macro definitions and special proclamations for the compiler. If one really needs functions defined in the lisp, the required functions will need EVAL-WHENs around them, or you can put the EVAL-WHEN around the REQUIRE. ---Walter -------  Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 4 May 84 17:41:50 PDT Received: from SCRC-EUPHRATES by SCRC-QUABBIN via CHAOS with CHAOS-MAIL id 50396; Fri 4-May-84 20:40:34-EDT Date: Fri, 4 May 84 20:41 EDT From: "David A. Moon" Subject: question about REQUIRE To: AS%hp-labs.csnet@CSNET-RELAY.ARPA Cc: Common-Lisp@SU-AI.ARPA, AS@CSNET-RELAY.ARPA In-reply-to: <8405031507.AA17342@HP-VENUS> Date: 3 May 1984 0806-PDT From: AS%hp-labs.csnet@csnet-relay.arpa Does REQUIRE get evaluated by default by the compiler? The Common Lisp manual does not say that it does, but I find it difficult to understand how the package system example could work otherwise. I would appreciate any clarification you could make. Thank you. I'm not sure why you're asking me, but I agree that it would be senseless for the compiler of files not to evaluate at compile time any REQUIRE form that it comes across at top level. That's what our implementation does.  Received: from ISI-VAXA.ARPA by SU-AI.ARPA with TCP; 4 May 84 11:40:24 PDT Date: Friday, 4 May 1984 11:35-PDT TO: common-lisp at SU-AI FROM: Wile at ISI-VAXA SUBJECT: I'd like on mailing list SENT: Friday, 5/4/84 at 10:33:50 PST I would like on this mailing list. I hope this message is not automatically distributed to everyone on the list! We are developing a Common Lisp "framework" here and would like to track all Common Lisp developments. Thanks. David S. Wile Information Sciences Institute WILE@ISI  Received: from CMU-CS-C.ARPA by SU-AI.ARPA with TCP; 24 Apr 84 18:52:45 PST Received: ID ; Tue 24 Apr 84 21:54:30-EST Date: Tue, 24 Apr 1984 21:54 EST Sender: FAHLMAN@CMU-CS-C.ARPA From: Scott E. Fahlman To: Stan Shebs Cc: common-lisp@SU-AI.ARPA Subject: Stream Buffering Question In-reply-to: Msg of 24 Apr 1984 21:04-EST from "David A. Moon" I agree with Dave Moon: stream buffering, either on the input or output side, is outside the scope of the current Common Lisp definition. The only hooks into buffering are FORCE-OUTPUT and related functions that give the user some control over output buffering if any buffering is in fact being done. -- Scott  Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 24 Apr 84 18:17:37 PST Received: from SCRC-EUPHRATES by SCRC-STONY-BROOK via CHAOS with CHAOS-MAIL id 20969; Tue 24-Apr-84 21:05:26-EST Date: Tue, 24 Apr 84 21:04 EST From: "David A. Moon" Subject: Stream Buffering Question To: Stan Shebs Cc: common-lisp@SU-AI.ARPA In-reply-to: The message of 24 Apr 84 14:59-EST from Stan Shebs Date: Tue 24 Apr 84 12:59:11-MST From: Stan Shebs Excelsior says nothing about how streams are to be buffered. This is important when building editors etc. The presence of listen and read-char-no-hang (pp 293-294) would seem to imply that unbuffered I/O is possible, but I couldn't find anything that could be used to declare whether a given stream is to be buffered or not. What's the official propaganda? I believe the official propaganda is that Common Lisp does not provide I/O facilities for building editors. In order to read control characters one at a time from the keyboard, you have to go outside of Common Lisp and do something implementation-dependent. You have to do the same in order to maintain a display on a screen. These operations seem like good candidates for standardization in a future second revision of Common Lisp, but obviously there are a lot more implementation issues and choices surrounding them than with CAR or REPLACE. Incidentally, the Excelsior edition of the manual was superseded five months ago by the Mary Poppins edition of the manual. I believe the First edition is supposed to be in the bookstores "soon", like in six weeks, but I don't know whether my information is accurate.  Received: from UTAH-20.ARPA by SU-AI.ARPA with TCP; 24 Apr 84 11:59:57 PST Date: Tue 24 Apr 84 12:59:11-MST From: Stan Shebs Subject: Stream Buffering Question To: common-lisp@SU-AI.ARPA Excelsior says nothing about how streams are to be buffered. This is important when building editors etc. The presence of listen and read-char-no-hang (pp 293-294) would seem to imply that unbuffered I/O is possible, but I couldn't find anything that could be used to declare whether a given stream is to be buffered or not. What's the official propaganda? stan shebs -------  Received: from CMU-CS-A.ARPA by SU-AI.ARPA with TCP; 23 Mar 84 22:48:17 PST Date: 24 Mar 84 0130 EST (Saturday) From: Guy.Steele@CMU-CS-A To: common-lisp@SU-AI Subject: Common Lisp Reference Manual The publisher of the Common Lisp Reference Manual is Digital Press. I understand that they may be negotiating with manufacturers to allow them to reprint the manual in various ways as part of their product documentation. I am leaving the business and legal aspects of this up to Digital Press, and referring all corporate inquiries to them. My goal is primarily to ensure that (a) no one publishes a manual that claims to be about Common Lisp when it doesn't satisfy the Common Lisp specifications, and (b) to make sure that everyone involved in the Common Lisp effort is properly credited. I certainly do not want to block anyone from implementing or using Common Lisp, or even a subset, superset, or side-set of Common Lisp, as long as any differences are clearly and correctly stated in the relevant documentation, and as long as the Common Lisp Reference Manual is recognized and credited as the definitive document on Common Lisp. This requires a certain balance between free permission and tight control. This is why I am letting the publisher handle it; they almost certainly have more experience with such things than I do. I have asked the editor at Digital Press to arrange for complimentary copies to be sent to everyone who has contributed substantially to the Common Lisp effort. This will include most of the people on this mailing list, I imagine. The set of people I have in mind is listed in the acknowledgements of the book--seventy or eighty persons altogether--so if you see a copy of the book and find your name in that list, you might want to wait a bit for your complimentary copy to show up before buying one. (Because of the large number of copies involved, they aren't really complimentary, which is to say the publisher isn't footing the cost: the cost of them will be paid out of the royalties. I estimate that the royalties from the entire first print run will just about cover these free copies. It seems only fair to me that everyone who contributed to the language design should get a copy of the final version!) The nominal schedule calls for the typesetter to take about five weeks to produce camera-ready copy from the files I sent to them on magnetic tape. The process of printing, binding, and distribution will then take another four to five weeks. So at this point we're talking availability at about the end of May. This is a tight and optimistic schedule; don't blame Digital Press if it slides. (I'm certainly not about to cast any stones!) Unless you're an implementor wanting to order a thousand copies to distribute with your system, please don't bother the folks at Digital Press until then; they've got enough problems. I'll send more information to this mailing list as the date approaches. One last note. The book is about 400 pages of 8.5" by 11" Dover output. Apparently the publisher and typesetter decided that this made the lines too wide for easy reading, so they will use a 6" by 9" format. This will make the shape of the book approximately cubical. Now, there are 26 chapters counting the index, and a Rubik's cube has 26 exterior cubies. I'll let you individually extrapolate and fantasize from there. --Guy  Received: from CMU-CS-A.ARPA by SU-AI.ARPA with TCP; 21 Mar 84 18:49:57 PST Date: 21 Mar 84 2149 EST (Wednesday) From: Guy.Steele@CMU-CS-A To: common-lisp@SU-AI Subject: Can you dig it Today I have sent off mag tapes with the (by definition) final manuscripts for the Common Lisp Reference Manual, First Edition, to the typesetter. Excepting possibly last-minute corrections by telephone to the typesetter, it's out of my hands now. The publishing schedule nominally called for copies to be available about nine weeks after deleivery of the tapes, but it may be that the typesetter, printer, or binder may make up some time in that schedule. I am very grateful to everyone who sent in comments, questions, and corrections over the last three years. I've done a lot of editing and coordinating, but allof you have done a lot of the thinking. I want to apologize again for often seeming unresponsive. While I have not always had the time to respond individually to every bug report and typographical error, I assure you that no report has been lost. I have them all on paper, and every one was checked twice. Yes, I fixed the inconsistencies about SPECIAL in the declarations chapter. Yes, I fixed the screwy example of SETF of LDB. Yes, I fixed the "version version" typo. Thanks to the dedication of many of you who have read through this book several times, I think it is in very good shape, highly polished and reasonably consistent. (The copy editor for the publisher reported that she found only very light editing necessary, mostly to correct various grammatical confusions I had introduced and occasional use of the wrong font.) I think this is a book we can all be proud of. --Guy  Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 12 Mar 84 13:54:37 PST Date: Mon, 12 Mar 84 13:50 PST From: Eric Benson Subject: ARRAY-DIMENSIONS To: Common-Lisp@SU-AI.ARPA Is it reasonable to assume that the list returned by ARRAY-DIMENSIONS is modifiable? It is conceivable that an implementation could actually keep this list in the array object, so that modifying it would have the sort of disastrous consequences that modifying a symbol's print name has.  Received: from DEC-MARLBORO by SU-AI with TCP/SMTP; 23 Feb 84 16:38:45 PST Date: Thu 23 Feb 84 19:11:21-EST From: "Walter van Roggen" Subject: Re: 1.0e+6 vs 1.0E+6, more food for thought To: Cassels%SCRC-TENEX@MIT-MC.ARPA cc: GSB@MIT-MC.ARPA, kmp%MIT-OZ@MIT-MC.ARPA, common-lisp@SU-AI.ARPA, BUG-LISPM%MIT-OZ@MIT-MC.ARPA, KBE-I-FILE%MIT-OZ@MIT-MC.ARPA, WVANROGGEN@DEC-MARLBORO.ARPA In-Reply-To: Message from ""Robert A. Cassels" " of Thu 23 Feb 84 12:48:05-EST Vax Lisp prints long-floats with an uppercase "L", the others lowercase. People may be surprised by the format, but they're never confused. ---Walter -------  Received: from MIT-MC by SU-AI with TCP/SMTP; 23 Feb 84 09:38:54 PST Received: from SCRC-ASSABET by SCRC-STONY-BROOK with CHAOS; Thu 23-Feb-84 12:32:15-EST Date: Thu, 23 Feb 84 12:36 EST From: "Robert A. Cassels" Subject: 1.0e+6 vs 1.0E+6, more food for thought To: GSB@MIT-MC.ARPA, kmp%MIT-OZ@MIT-MC.ARPA Cc: common-lisp@SU-AI.ARPA, BUG-LISPM%MIT-OZ@MIT-MC.ARPA, KBE-I-FILE%MIT-OZ@MIT-MC.ARPA In-reply-to: The message of 22 Feb 84 21:47-EST from Glenn S. Burke Date: 22 February 1984 21:47-EST From: Glenn S. Burke Received: from MIT-AVATAR by MIT-OZ via Chaosnet; 22 Feb 84 17:22-EST Date: Wednesday, 22 February 1984, 17:22-EST From: Kent M Pitman In Release 4.5 on PA Lisp Machine Avatar: It would be nice if there were an advertised switch variable controlling whether floating point numbers printed with the "e" in complemented case. In particular, we use the Lisp floating point number printer to display floating point numbers in the PL/1 component of our system and since PL/1 is, in most implementations, case sensitive, we'd prefer in that context to see the E in the same case as the rest of the code. Is this reasonable or should we just use ~ ? In release 5, I completely redid the floating-point reader and printer. They are now "completely accurate" and more modular. So Fortran and Pascal, which have different notions from Lisp about how formatting should be done, use the lower-level routines. I suggest you do the same for PL/I, so you can get the semantics exactly right (the way you want them). You can follow pointers from SI:PRINT-FLONUM and SI:XR-READ-FLONUM or just look in SYS: SYS2; NUMER. It should be obvious how to use upper-case exponent marks. If you have trouble understanding the other (myriad) options, let me know. If it'll help, ask and I'll send you copies of the Fortran and/or Pascal floating-point printers. NIL had been printing floating point exponents in lower case by default, but i changed it back to upper case because most people got confused by long floats with the lower case "l" exponent marker embedded in the output. (I haven't done the common-lisp printing stuff yet.) Anyone else out there in CL land have this experience, or suggestions? It certainly occurred to me when I was doing the Common Lisp printer that "l" would be a loser. Since we don't have long floating-point numbers, we'll never print them. The feeling here was that lower-case is easier to read for "e", "d", and "s", so we left it printing lower-case. If we ever implement longs, we'll have to reconsider.  Received: from MIT-MC by SU-AI with TCP/SMTP; 22 Feb 84 18:47:26 PST Date: 22 February 1984 21:47-EST From: Glenn S. Burke Subject: 1.0e+6 vs 1.0E+6, more food for thought To: kmp @ MIT-OZ cc: common-lisp @ SU-AI, BUG-LISPM @ MIT-OZ, KBE-I-FILE @ MIT-OZ Received: from MIT-AVATAR by MIT-OZ via Chaosnet; 22 Feb 84 17:22-EST Date: Wednesday, 22 February 1984, 17:22-EST From: Kent M Pitman In Release 4.5 on PA Lisp Machine Avatar: It would be nice if there were an advertised switch variable controlling whether floating point numbers printed with the "e" in complemented case. In particular, we use the Lisp floating point number printer to display floating point numbers in the PL/1 component of our system and since PL/1 is, in most implementations, case sensitive, we'd prefer in that context to see the E in the same case as the rest of the code. Is this reasonable or should we just use ~ ? NIL had been printing floating point exponents in lower case by default, but i changed it back to upper case because most people got confused by long floats with the lower case "l" exponent marker embedded in the output. (I haven't done the common-lisp printing stuff yet.) Anyone else out there in CL land have this experience, or suggestions?  Received: from MIT-ML by SU-AI with TCP/SMTP; 6 Feb 84 20:50:27 PST Received: from SCRC-EUPHRATES by SCRC-QUABBIN with CHAOS; Mon 6-Feb-84 23:53:04-EST Date: Mon, 6 Feb 84 23:49 EST From: "David A. Moon" Subject: Request for clarification of DECODE-UNIVERSAL-TIME To: Common-Lisp@SU-AI.ARPA The Mary Poppins edition specifies that the optional time-zone argument to ENCODE-UNIVERSAL-TIME, if specified, suppresses checking for daylight savings time. It does not say that it does the same thing for DECODE-UNIVERSAL-TIME, and it does not deny that. Which is right? Currrently our implementation treats the two functions consistently, which may be in violation of the manual.  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 2 Feb 84 21:27:06 PST Received: from TARTAN by CMU-CS-C with TLnet; 3 Feb 84 00:24:42-EST Received: ID ; Fri 3 Feb 84 00:24:30-EST Date: Fri 3 Feb 84 00:24:28-EST From: STEELE%TARTAN@CMU-CS-C.ARPA Subject: 1984 LISP Conference submissions deadline moved back To: ailist-request@SRI-AI.ARPA, prolog-request@SU-SCORE.ARPA, franz-friends-request@UCB-VAX.ARPA, common-lisp@SU-AI.ARPA, lisp-discussion@MIT-MC.ARPA, bts%unc@UDEL-RELAY.ARPA Because of delays that occurred in getting out the call for papers, the deadline for submissions to the 1984 ACM Symposium on LISP and Functional Programming (to be held August 5-8, 1984) has been moved back from February 6 to February 15. The date for notification of acceptance or rejection of papers is now March 20 (was March 12). The date for return of camera-ready copy is now May 20 (was May 15). Please forward this message to anyone who may find it of interest. --Thanks, Guy L. Steele Jr. Program Chairman, 1984 ACM S. on L. and F.P. Tartan Laboratories Incorporated 477 Melwood Avenue Pittsburgh, Pennsylvania 15213 (412)621-2210 -------  Received: from MIT-ML by SU-AI with TCP/SMTP; 17 Jan 84 18:35:03 PST Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Tue 17-Jan-84 21:33:21-EST Date: Tue, 17 Jan 84 21:20 EST From: "David A. Moon" Subject: Query about definition of COMMON data type To: Steele%Tartan@CMU-CS-C.ARPA Cc: Common-Lisp@SU-AI.ARPA A strict reading of the last two paragraphs on page 28 of the Mary Poppins edition says that STRING is not a subtype of COMMON. This is because STRING is (ARRAY STRING-CHAR 1), and STRING-CHAR is neither T nor a subtype of COMMON. STANDARD-CHAR is a subtype of COMMON, but STRING-CHAR is not, and is not necessarily a subtype of STANDARD-CHAR. I assume this was not intentional, and STRING should be a subtype of COMMON for the same reason that (ARRAY T) is a subtype of COMMON. I agree that STRING-CHAR should not be a subtype of COMMON; that makes sense.  Received: from DEC-MARLBORO by SU-AI with TCP/SMTP; 11 Jan 84 17:20:39 PST Date: Wed 11 Jan 84 20:21:27-EST From: GREEK@DEC-MARLBORO.ARPA Subject: COERCE To: common-lisp@SU-AI.ARPA I agree with Scott that we could open a real can of worms here. If COERCE is generalized, then DEFTYPE needs a whole new hack to allow the specification of how objects of the new type are coerced to other types. And that means that DEFSTRUCT needs the same extension. Let's just drop it now. - Paul -------  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 11 Jan 84 08:13:32 PST Received: ID ; Wed 11 Jan 84 11:14:08-EST Date: Wed, 11 Jan 1984 11:14 EST From: Scott E. Fahlman To: "David A. Moon" Cc: Common-Lisp@SU-AI.ARPA Subject: Questions about COERCE In-reply-to: Msg of 10 Jan 1984 23:47-EST from "David A. Moon" I believe that we currently treat all of your examples as errors also. Coerce says it will do certain particular conversions, and that's all we provided, using a narrow reading for such phrases as "other sequence type". Since Coerce pretty much has to be coded as an N*M dispatch (with some few opportunities for folding), and all of those dispatch cases want to be optimized at compile-time if the args are of known type, we would really like to keep M reasonably small. So I argue that we should use COERCE just to move between major types, as enumerated in the manual, and should use more specific functions to change the length of vectors or trim off control bits. If we try to make coerce be the universal unary operator, we're going to need DEFCOERCE and god knows what else. -- Scott  Received: from MIT-ML by SU-AI with TCP/SMTP; 10 Jan 84 20:47:27 PST Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Tue 10-Jan-84 23:46:32-EST Date: Tue, 10 Jan 84 23:47 EST From: "David A. Moon" Subject: Questions about COERCE To: Common-Lisp@SU-AI.ARPA Are the following examples of calls to COERCE legal, illegal, or permissible but not required extensions? The manual isn't very explicit on this point. (coerce '(1 2 3) '(vector t 3)) ;length specified (coerce '(1 2 3) '(vector t 4)) ;length specified and doesn't match (coerce x '(array single-float 2)) ;not a subtype of sequence (coerce #\A 'string-char) ;subtype of character (coerce #\c-A 'string-char) ;type mismatch: error or discard bits? (coerce 22/7 '(float 0 10)) ;range specified Currently each of these expressions signals an error in our implementation, although none of them would be difficult to implement if I knew what they were supposed to do. It's okay with me to leave them illegal.  Received: from MIT-MC by SU-AI with TCP/SMTP; 9 Jan 84 12:30:34 PST Date: 9 January 1984 15:31 EST From: Kent M Pitman Subject: Structures, documentation To: PGS @ MIT-OZ cc: Common-Lisp @ SU-AI References: , Msg of 5 Jan 1984 21:00-EST from GREEK at DEC-MARLBORO.ARPA This message is speculative. I doubt if it's something we're in a position to do right now with the manual frozen and all, but i figured it was worth laying on the table anyway... Date: Sun, 8 Jan 1984 21:01 EST From: PGS%MIT-OZ at MIT-MC.ARPA To: GREEK at DEC-MARLBORO.ARPA cc: common-lisp at SU-AI.ARPA ... The documentation strings for slots could be printed by DESCRIBE, and the accessor could have a documentation string created from the slot description. The documentation string could be specified as a third object in each slot description: (defstruct (elephant :conc-name) (color 'GRAY "The elephant's color, should be one of GRAY, BROWN, or PINK.") ...) The documentation string for ELEPHANT-COLOR could look like: "The accessor for the COLOR slot of the ELEPHANT structure. The COLOR slot's documentation is: The elephant's color, should be one of GRAY, BROWN, or PINK." Well, it's certainly outside of Common Lisp's domain to dictate the specifics of what gets printed, but just to let me rest easier, let me point out that nothing bothers me more than little noise lines like the middle one above. I would prefer to see something more like "The accessor for the COLOR slot of the ELEPHANT structure: The elephant's color, should be one of GRAY, BROWN, or PINK." When you have to get 50 of them printed out for a structure, you get bored with the one that doesn't provide additional bits. Anyway, it's also the case that you cannot do anything useful mechanically with this comment string. It would be very nice if this sort of thing could provide data in a form that programs could manipulate. I would recommend the following kinds extensions: * Specify something about the shape of the documentation string. For example, should fit in a noun phrase after a determiner such as "the" or "this". In normal circumstances, the string should be in lower case so it will fit naturally into sentences. Examples: "elephant", "space ship", "red box". This would allow FORMAT calls like: (format t "Select another ~A from the menu" ...) (format t "Do you want me to describe this ~A?") * Specify that the slot documentation should not mention the thing of which it is a part. That way, if you :include one struct into another, you get more abstract slot documentation. * Specify the fillers as objects. This allows one to distinguish objects with the same printed representation (eg, symbols on differing packages, etc). Possibly also specify an alist of names. This sort of constraint will allow one to interface nicely to things akin to the LispM's TV:CHOOSE-VARIABLE-VALUES, for example. The result would be something like: (defstruct (elephant :conc-name (:include four-legged-mammal) (:documentation "elephant")) (color `COLOR:GRAY "color" '(("gray" . ,COLOR:GRAY) ("brown" . ,COLOR:BROWN) ("pink" . ,COLOR:PINK)))) ELEPHANT (describe (make-elephant color color:pink)) The elephant # has the following features: Its color is pink. Its number of legs is 3. Its name is Clyde. (describe-structure 'elephant) An instance of elephant has 3 properties. Its color may be gray, brown, or pink. Its number of legs may be any positive integer. Its name may be a string. (describe-structure 'elephant :show-internals t) An instance of ELEPHANT has 3 slots: The COLOR slot holds its color, which may be one of: COLOR:GRAY, COLOR:BROWN, COLOR:PINK The N-LEGS slot (inherited from structure type FOUR-LEGGED-MAMMAL) holds its number of legs, which may be any positive integer. The NAME slot (inherited from structure ANIMAL) holds its name, which may be a string. (edit-structure-instance-with-menu (make-elephant)) The object being edited is #. Use the mouse to select new values: Color: gray brown PINK Number of legs: 3 Name: Clyde The point of this last example is not to say these are the operations or formats I would like to see so much as to say that with just a little more specification of the form of the documentation in the struct, you can achieve a much more flexible output format.  Received: from MIT-ML by SU-AI with TCP/SMTP; 9 Jan 84 12:04:37 PST Received: from SCRC-EUPHRATES by SCRC-QUABBIN with CHAOS; Mon 9-Jan-84 15:08:50-EST Date: Mon, 9 Jan 84 15:01 EST From: "David A. Moon" Subject: Documenting defstruct slots To: PGS%MIT-OZ@MIT-MC.ARPA Cc: GREEK@DEC-MARLBORO.ARPA, common-lisp@SU-AI.ARPA In-reply-to: Date: Sun, 8 Jan 1984 21:01 EST From: PGS%MIT-OZ@MIT-MC.ARPA I think that documenting the slots themselves, as opposed to documenting anything that was generated automatically (especially the vanilla print handler), is more like what one would want to do. The documentation strings for slots could be printed by DESCRIBE, and the accessor could have a documentation string created from the slot description. The documentation string could be specified as a third object in each slot description: (defstruct (elephant :conc-name) (color 'GRAY "The elephant's color, should be one of GRAY, BROWN, or PINK.") ...) The documentation string for ELEPHANT-COLOR could look like: "The accessor for the COLOR slot of the ELEPHANT structure. The COLOR slot's documentation is: The elephant's color, should be one of GRAY, BROWN, or PINK." This is fine, but is not the syntax of Common Lisp defstruct. If you don't have a copy of the Common Lisp manual (Mary Poppins edition) you should obtain one.  Received: from DEC-MARLBORO by SU-AI with TCP/SMTP; 9 Jan 84 11:44:19 PST Date: Mon 9 Jan 84 14:40:12-EST From: GREEK@DEC-MARLBORO.ARPA Subject: Doc Strings for DEFSTRUCT To: common-lisp@SU-AI.ARPA Concerning doc strings for structure slots: You might want to add that feature also, although I'd rather document slots in the main documentation for the structure. You'll have difficulty in integrating that into the DOCUMENTATION function. I want to document the generated functions because I don't want the user to know the thing is implemented as a structure. For example, any common data type implemented as a structure falls into that category. They just look like functions. I suggest we not add a doc string for the print function, as the user doesn't often call it directly. - Paul -------  Received: from MIT-MC by SU-AI with TCP/SMTP; 8 Jan 84 18:06:23 PST Date: Sun, 8 Jan 1984 21:01 EST Message-ID: From: PGS%MIT-OZ@MIT-MC.ARPA To: GREEK@DEC-MARLBORO.ARPA Cc: common-lisp@SU-AI.ARPA Subject: suggestion for the future. In-reply-to: Msg of 5 Jan 1984 21:00-EST from GREEK at DEC-MARLBORO.ARPA Date: Thursday, 5 January 1984 21:00-EST From: GREEK at DEC-MARLBORO.ARPA To: common-lisp at SU-AI.ARPA Re: A nit and a suggestion for the future. ...A suggestion for future enhancements to DEFSTRUCT. There is no way to attach doc strings to anything but the structure itself. I can't hang a doc string on the accessors, SETF forms, print function, copier, etc. I'm afraid DEFSTRUCT needs a host of additional options. I think that documenting the slots themselves, as opposed to documenting anything that was generated automatically (especially the vanilla print handler), is more like what one would want to do. The documentation strings for slots could be printed by DESCRIBE, and the accessor could have a documentation string created from the slot description. The documentation string could be specified as a third object in each slot description: (defstruct (elephant :conc-name) (color 'GRAY "The elephant's color, should be one of GRAY, BROWN, or PINK.") ...) The documentation string for ELEPHANT-COLOR could look like: "The accessor for the COLOR slot of the ELEPHANT structure. The COLOR slot's documentation is: The elephant's color, should be one of GRAY, BROWN, or PINK."  Received: from DEC-MARLBORO by SU-AI with TCP/SMTP; 5 Jan 84 18:05:41 PST Date: Thu 5 Jan 84 21:00:58-EST From: GREEK@DEC-MARLBORO.ARPA Subject: A nit and a suggestion for the future. To: common-lisp@SU-AI.ARPA First the nit. What happened to the proposal that the time zone ought to be a rational so that folks in Newfoundland will be happy? A suggestion for future enhancements to DEFSTRUCT. There is no way to attach doc strings to anything but the structure itself. I can't hang a doc string on the accessors, SETF forms, print function, copier, etc. I'm afraid DEFSTRUCT needs a host of additional options. Does anyone have a good idea for a return value from SET-SYNTAX-FROM-CHAR? - Paul -------  Received: from CMU-CS-SPICE by SU-AI with TCP/SMTP; 5 Jan 84 07:11:44 PST Date: Thursday, 5 January 1984 09:11:36 EST From: Joseph.Ginder@CMU-CS-SPICE To: common-lisp@su-ai Subject: extending or correcting common lisp Message-ID: <1984.1.5.13.59.28.Joseph.Ginder@CMU-CS-SPICE> How are we going to distribute info. about such things as Moon's type description proposal between manual editions? Moon's type stuff, in particular, seems like an important correction to the spec (we really should have done something like that to start with). I assume it's too late for inclusion in the first edition of the manual, but too important to hold off until the second. Is the rumored "Common Lisp Institute" or whatever really going to happen? Will it do this sort of thing? --Joe  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 3 Jan 84 20:09:58 PST Received: ID ; Tue 3 Jan 84 23:10:40-EST Date: Tue, 3 Jan 1984 23:10 EST From: Scott E. Fahlman To: Cc: Common-Lisp@SU-AI.ARPA Subject: Proposed new type expression In-reply-to: Msg of 3 Jan 1984 17:36-EST from It looks to me like this fills a real need and does so rather elegantly. I think this would be a useful thing to include in the second edition, and maybe to adopt as an informal standard before that, if any mechanism for doing this is set up. I don't much like the looks of DECLARE in this role, but at present I have nothing better to propose. It does have a certain logic to it. -- Scott  Received: from MIT-ML by SU-AI with TCP/SMTP; 3 Jan 84 15:56:22 PST Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Tue 3-Jan-84 17:37:05-EST Date: Tuesday, 3 January 1984, 17:36-EST From: Subject: Proposed new type expression To: Common-Lisp at su-ai Here is an extension to the Common Lisp type system that people might want to keep in mind. It didn't take me very long to implement this (10 minutes plus about 3 hours of improvements to the type implementation that I got stimulated to do while looking at it). (DECLARE ) is a type expression that can be used for discrimination. It treats the way it would be treated for declaration, instead of the normal way it is treated for discrimination. For most types this makes no difference, but for ARRAY and COMPLEX types, and types built on them such as VECTOR, it does make a difference and furthermore it hides implementation-dependent knowledge of what specialized types are provided by the particular implementation. cannot be (FUNCTION ...) [although I think an implementation could provide this as an extension if it has the ability to check arg/value types.] Example of use: (defun foo (image) (declare (type (array (signed-byte 12)) image)) (when *enable-type-checking* (check-type image (declare (array (signed-byte 12))))) ...) In an implementation that has only the minimum specialized arrays required by Common Lisp, (DECLARE (ARRAY (SIGNED-BYTE 12))) is equivalent to (ARRAY T) while (ARRAY (SIGNED-BYTE 12)) is equivalent to NIL. In another implementation that has specialized arrays of 16-bit twos-complement integers, (DECLARE (ARRAY (SIGNED-BYTE 12))) is equivalent to (ARRAY (SIGNED-BYTE 16)) but (ARRAY (SIGNED-BYTE 12)) is still equivalent to NIL. In a third implementation that has specialized arrays of 12-bit twos-complement integers, (DECLARE (ARRAY (SIGNED-BYTE 12))) and (ARRAY (SIGNED-BYTE 12)) are equivalent.  Received: from MIT-ML by SU-AI with TCP/SMTP; 3 Jan 84 14:16:46 PST Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Tue 3-Jan-84 17:17:41-EST Date: Tuesday, 3 January 1984, 17:17-EST From: Subject: Order of arguments to :test functions To: Steele%Tartan at cmu-cs-c Cc: Common-Lisp at su-ai p.209: I assume it is intended that remove-duplicates and delete-duplicates will not change the order of elements in the sequence, unlike intersection (for example). This is implied but not stated explicitly. It's particularly important when the :test function is something that is not commutative, subtypep to take a real example. Of course the ability to use subtypep as a :test function also relies on a reading of pp.202-203 that may perhaps be stricter than what you intended. In our implementation the order of arguments to the test function is always strictly guaranteed; informally the rule is "the order of arguments to the test function is the same as the order of arguments to the original function." For things that take one sequence argument and compare two elements of that sequence, e.g. remove-duplicates, the order of arguments to the test function is the same as the order of elements in the sequence. The manual might want to take a stronger stand on this, or else state clearly that it does not take a stand on this. Users will rely on anything they discover about an implementation that they aren't explicitly told not to rely on. Actually I think guaranteeing the order of arguments to the :test function is quite worthwhile.  Received: from MIT-ML by SU-AI with TCP/SMTP; 2 Jan 84 12:26:52 PST Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Mon 2-Jan-84 15:20:04-EST Date: Mon, 2 Jan 84 15:26 EST From: "David A. Moon" Subject: query about make-broadcast-stream To: "Scott E. Fahlman" Cc: Common-Lisp@SU-AI.ARPA In-reply-to: The message of 2 Jan 84 12:02-EST from Scott E. Fahlman Date: Mon, 2 Jan 1984 12:02 EST From: Scott E. Fahlman From Moon: What does the last phrase in the description of make-broadcast-stream ("every operation results in nil") mean? This phrase was not present in the Excelsior edition. The values returned by the Common Lisp stream functions are defined with each function and are not up to the stream. There isn't (in Common Lisp) anything else that could be called an "operation." Since nobody else has popped up to answer this question, I'll try. It seems very clear to me that the "every operation results in NIL" business is a slip-up and should not be there. In case there is not really an output stream you want all output to be discarded, but write operations should return whatever they would normally return. Perhaps Guy was trying to say that any operation whose return value is undefined if there is no real stream, such as STREAM-ELEMENT-TYPE, would return NIL for this type of stream. It seems clear to me that if it is defined at all, STREAM-ELEMENT-TYPE of such a stream should be (AND), otherwise known as T. It's the intersection of the stream-element-types of the streams it broadcasts to. If Guy really intends this phrase to be taken seriously, which implies special-casing every stream operation to handle this case, then some more motivation and discussion is needed. In the absence of such, we are treating this as an error. I agree with you. In our implementation (make-broadcast-stream) returns a stream that accepts all output and throws it away.  Received: from MIT-MC by SU-AI with TCP/SMTP; 2 Jan 84 09:41:31 PST Date: 2 January 1984 12:42 EST From: Kent M Pitman Subject: Sad historical sidelights: Return values -- NIL vs undefined To: Fahlman @ CMU-CS-C cc: Common-Lisp @ SU-AI References: Msg of 30 Dec 83 17:45-EST from "David A. Moon" In-reply-to: Msg of Mon 2 Jan 1984 12:02 EST from Scott E. Fahlman Date: Mon, 2 Jan 1984 12:02 EST From: Scott E. Fahlman ... If Guy really intends this phrase to be taken seriously, which implies special-casing every stream operation to handle this case, then some more motivation and discussion is needed. In the absence of such, we are treating this as an error... Looking at people's code over the years, I've noticed (as I'm sure others have) it's generally much better to leave undefined values explicitly undefined rather than to say NIL is returned. Not only does it cause the compiler to do extra work and produce shoddier code, but I have actually seen people write things like: (AND (PRED1 X) (NOT (TERPRI)) (PRINC FOO) (PRED2 X)) I've seen real Maclisp code that did this sort of silliness. Whenever you needlessly define return values for things, you just set yourself up for bitching from people who've taught themselves to depend on things they should never have even considered using in the first place. In general, I would say the return value of no function, operation, or whatever should be defined unless we are prepared to be happy with people picking up and using that value shamelessly.  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 2 Jan 84 09:03:04 PST Received: ID ; Mon 2 Jan 84 12:02:58-EST Date: Mon, 2 Jan 1984 12:02 EST From: Scott E. Fahlman To: "David A. Moon" Cc: Common-Lisp@SU-AI.ARPA Subject: query about make-broadcast-stream In-reply-to: Msg of 30 Dec 1983 17:45-EST from "David A. Moon" From Moon: What does the last phrase in the description of make-broadcast-stream ("every operation results in nil") mean? This phrase was not present in the Excelsior edition. The values returned by the Common Lisp stream functions are defined with each function and are not up to the stream. There isn't (in Common Lisp) anything else that could be called an "operation." Since nobody else has popped up to answer this question, I'll try. It seems very clear to me that the "every operation results in NIL" business is a slip-up and should not be there. In case there is not really an output stream you want all output to be discarded, but write operations should return whatever they would normally return. Perhaps Guy was trying to say that any operation whose return value is undefined if there is no real stream, such as STREAM-ELEMENT-TYPE, would return NIL for this type of stream. If Guy really intends this phrase to be taken seriously, which implies special-casing every stream operation to handle this case, then some more motivation and discussion is needed. In the absence of such, we are treating this as an error. -- Scott  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 30 Dec 83 21:44:19 PST Received: from [128.2.254.192] by CMU-CS-PT with CMUFTP; 31 Dec 83 00:28:58 EST Date: 31 Dec 83 0042 EST (Saturday) From: Guy.Steele@CMU-CS-A To: common-lisp@SU-AI Subject: UNION and friends I had intended that UNION and friends be able to share structure and not be required to make completely fresh lists. This is in line with many of the non-destructive sequence functions. I will clarify this in the prose for publication.  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 30 Dec 83 16:21:41 PST Received: ID ; Fri 30 Dec 83 19:22:46-EST Date: Fri, 30 Dec 1983 19:22 EST From: Scott E. Fahlman To: Common-Lisp@SU-AI.ARPA Subject: Union and friends In-reply-to: Msg of 30 Dec 1983 18:48 EST from Kent M Pitman I agree with KMP that Union and friends would be much more useful if shared substructure is allowed. Usually you want the efficiency and don't care about the purity of the list, and if you do care you can copy the list with little loss of efficiency. (Note that NUNION and friends are still different, in that they allow the arguments to be clobbered and not merely shared.) Despite this preference, I note that whoever implemented our version of UNION interpreted the manual as requiring a fresh copy. In any event, a clarification is needed. -- Scott  Received: from MIT-MC by SU-AI with TCP/SMTP; 30 Dec 83 16:02:54 PST Date: 30 December 1983 18:48 EST From: Kent M Pitman To: Common-Lisp @ SU-AI In-Reply-To: The message of Thu, 29 Dec 83 22:00-EST from "David A. Moon" If this is really still subject to interpretation, I encourage the shared-structure approach. For the simple cases, it would be best not to scare people away from using these set operations because they believe them to be too inefficient. Odds are you wouldn't feel as bad about the possible redundant consing in (COPYLIST (UNION X Y)) if you need a full copy as you would feel about the unnecessary consing in (UNION X Y) if you didn't want a full copy. In general, I think the burden should be on those who want to do side-effects to assure that they have taken appropriate safety precautions. Also, writing (COPYLIST (UNION X Y)) makes an important assumption explicit in the code. If (UNION X Y) is always copying, it is harder to tell from inspection when the programmer plans to take advantage of the fact. -kmp  Received: from MIT-ML by SU-AI with TCP/SMTP; 30 Dec 83 14:45:26 PST Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Fri 30-Dec-83 17:47:25-EST Date: Fri, 30 Dec 83 17:45 EST From: "David A. Moon" Subject: query about make-broadcast-stream To: Common-Lisp@SU-AI.ARPA What does the last phrase in the description of make-broadcast-stream ("every operation results in nil") mean? This phrase was not present in the Excelsior edition. The values returned by the Common Lisp stream functions are defined with each function and are not up to the stream. There isn't (in Common Lisp) anything else that could be called an "operation."  Received: from MIT-ML by SU-AI with TCP/SMTP; 29 Dec 83 19:02:27 PST Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Thu 29-Dec-83 22:01:00-EST Date: Thu, 29 Dec 83 22:00 EST From: "David A. Moon" Subject: Query about UNION To: Common-Lisp@SU-AI.ARPA The Mary Poppins manual does not make clear whether UNION is permitted to share structure with one of its arguments. For example, a possible implementation technique (assuming for clarity that all keyword arguments default) would be: (defun union (list1 list2) (dolist (item list2) (unless (member item list1) (push item list1))) list1) Is this permissible or impermissible? Near the top of page 202 the manual says "returns a new list", and "new" may mean that every cons in the backbone of the list is newly-created, or it might mean simply that the list is the result of a computation. A related query applies to the other three non-destructive set-construction operations: if their result is to be EQUAL to one of their arguments, or some nthcdr of one of their arguments, are they permitted to return the argument, or the tail of it, or are they guaranteed always to return a freshly-constructed list?  Received: from MIT-ML by SU-AI with TCP/SMTP; 27 Dec 83 21:52:13 PST Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Wed 28-Dec-83 00:53:36-EST Date: Wed, 28 Dec 83 00:48 EST From: "David A. Moon" Subject: single-float-epsilon To: Steele%Tartan@CMU-CS-C.ARPA Cc: Common-Lisp@SU-AI.ARPA This message supersedes previous copies; please forgive the duplication. Sorry I didn't notice this before, but I'm not sure that the definition of single-float-epsilon given in the manual is really what you intended. Specifically, on most machines (those that do rounding to nearest) this number is -not- a power of 2, rather it is one unit in the least significant place more than a power of 2. I would think that most applications of this would prefer to have a power of 2. Is it possible that the definition you wanted was "the largest positive floating-point number e such that the expression (= (float 1 e) (+ (float 1 e) e)) is false when actually evaluated."? In the meantime I've fixed our implementation to conform to the manual instead of having a value that was off by a factor of a hair less than 2 (the person computing the value clearly must have assumed that it was meant to be a power of 2 and didn't consider other numbers).  Received: from MIT-ML by SU-AI with TCP/SMTP; 27 Dec 83 21:51:46 PST Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Wed 28-Dec-83 00:52:56-EST Date: Wed, 28 Dec 83 00:47 EST From: "David A. Moon" Subject: single-float-epsilon To: Steele%Tartan@CMU-CS-C.ARPA Cc: Common-Lisp@SU-AI.ARPA Sorry I didn't notice this before, but I'm not sure that the definition of single-float-epsilon given in the manual is really what you intended. Specifically, on most machines (those that do rounding to nearest) this number is -not- a power of 2, rather it is one unit in the least significant place more than a power of 2. I would think that most applications of this would prefer to have a power of 2. Is it possible that the definition you wanted was "the largest positive floating-point number e such that the expression (= (float 1 e) (+ (float 1 e) e)) is false when actually evaluated."? In the meantime I've fixed our implementation to conform to the manual instead of having a value that was off by a hair less than a power of 2 (the person computing the value clearly must have assumed that it was meant to be a power of 2 and didn't consider other numbers).  Received: from MIT-MC by SU-AI with TCP/SMTP; 23 Dec 83 05:10:26 PST Date: 23 December 1983 08:10 EST From: Glenn S. Burke Subject: Unrelated issue re: special declarations To: Benson @ SPA-NIMBUS cc: common-lisp @ SU-AI I'm too burned out now to recreate any arguments, but as i remember it even with blintz vectors i was perfectly pleased to eliminate the unspecial declaration, and doing so was one of the first ways i changed the nil interpreter to be common-lisp compatible wrt declarations. I've got the implementation details of this, including explanation of exactly the simplifications i could make by eliminating unspecial, written down somewhere and will dig them up if necessary.  Received: from MIT-MC by SU-AI with TCP/SMTP; 22 Dec 83 22:21:36 PST Received: from SCRC-ANNISQUAM by SCRC-QUABBIN with CHAOS; Fri 23-Dec-83 01:15:15-EST Date: Fri, 23 Dec 83 01:19 EST From: Subject: Unrelated issue re: special declarations To: common-lisp@SU-AI.ARPA Is it true that it was a design decision rather than an oversight that there is no UNSPECIAL declaration? I seem to remember this had something to do with making the interpreter easier, avoiding the need for BLINTZ vectors or such. If this is in fact the case, it should be mentioned in the manual. If it is a part of the language design, there are several consequences. An implementation which includes an UNSPECIAL declaration is violating the standard, not extending it. Portable code analysis programs must make some assumptions about the semantics of the code they are looking at. It is legitimate for a macro to substitute the value of a symbol defined by DEFCONSTANT (assuming EQLness is preserved), since they are proclaimed special and cannot be shadowed by an UNSPECIAL declaration. Notice this depends critically on the previous statement.  Received: from MIT-MC by SU-AI with TCP/SMTP; 21 Dec 83 20:21:38 PST Date: 21 December 1983 23:21 EST From: Alan Bawden Subject: must be wrong To: Guy.Steele @ CMU-CS-A cc: common-lisp @ SU-AI In-reply-to: Msg of 21 Dec 83 2153 EST () from Guy.Steele at CMU-CS-A Date: 21 Dec 83 2153 EST (Wednesday) From: Guy.Steele at CMU-CS-A To recapitulate: ... (LET* ((A B) (B A)) (DECLARE (SPECIAL A B)) ...) Clearly both bindings should be special. Should either initializer be special? Knotty problems lurk here, ... They certainly do. I do not assert that I have an answer to this problem that I think is acceptable to introduce into Common Lisp at this point. I do think that the current situation is quite clearly broken. (Moon's recent proposal makes me least unhappy, but that is not the same things as happyness.) In the example above I see two variables named A and two variables named B. Each variable occurs exactly once in the fragment (ignoring the DECLARE). You assert that according to Mary Poppins (!) the special declaration refers to all four occurences, even though only two names are mentioned in the DECLARE. I claim that this is ugly and a symptom of a confusion between variables, and occurrences of the names of variables. I would like special declarations to allow me to talk about variables themselves, not about occurrences of their names. Moon's proposal at least has the feature that if I know where a variable is bound I can attach declarations to the variable itself.  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 21 Dec 83 18:58:33 PST Received: from [128.2.254.192] by CMU-CS-PT with CMUFTP; 21 Dec 83 21:39:35 EST Date: 21 Dec 83 2153 EST (Wednesday) From: Guy.Steele@CMU-CS-A To: Alan Bawden Subject: Re: must be wrong CC: common-lisp@SU-AI In-Reply-To: "Alan Bawden's message of 19 Dec 83 22:11-EST" To recapitulate: the reason declarations affect initializer formsis that we discovered anomalies in the handling of declarations in such sequential-binding forms as LET* and DO*. For example: (LET* ((A B) (B A)) (DECLARE (SPECIAL A B)) ...) Clearly both bindings should be special. Should either initializer be special? Knotty problems lurk here, and it was somehow decided that all initializers should be affected in all cases. It is a simple rule, at least, even though the old explanations of LET in terms of macro expansion no longer always work.  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 21 Dec 83 18:46:28 PST Received: from [128.2.254.192] by CMU-CS-PT with CMUFTP; 21 Dec 83 21:29:01 EST Date: 21 Dec 83 2143 EST (Wednesday) From: Guy.Steele@CMU-CS-A To: common-lisp@SU-AI Subject: Interchange of interest - - - - Begin forwarded messages - - - - Received: from CMU-CS-PT by CMU-CS-A; 19 Dec 83 21:15:42 EST Received: from MIT-MC by CMU-CS-PT; 19 Dec 83 21:01:42 EST Date: 19 December 1983 21:14 EST From: Glenn S. Burke Subject: Special declarations To: Guy.Steele @ CMU-CS-A If (DEFUN FOO (A) (LET ((A A)) (DECLARE (SPECIAL A)) ...) is rewritten as (defun foo (a) ((lambda (a) (declare (special a)) ...) a)) is it equivalent? If it is, then there is the interesting consequence that it is not equivalent to (defun foo (a) (funcall #'(lambda (a) (declare (special a)) ...) a)) If it is not, as i presume is the case, perhaps more effort should have been put in to emphasize the non-equivalence of LET with its "obvious" macro expansion, which is something which people (and compilers!) that think they know LET will blow. I can understand the reasoning that leads up to all of this, i guess my problem is that it leaves me feeling uncomfortable. About four years ago i started writing the front-end part for a lisp compiler, and one thing i couldn't decide how to handle was declaration scoping with sequential binding (let*, &optional). - - - - - - - - - Date: 21 Dec 83 2142 EST (Wednesday) From: Guy.Steele@CMU-CS-A To: Glenn S. Burke Subject: Re: Special declarations In-Reply-To: "Glenn S. Burke's message of 19 Dec 83 21:14-EST" I feel that the current declaration semantics are a bit awkward, too, but I think it's the best we can do. You are quite correct that (LET ((A A)) (DECLARE (SPECIAL A)) ...) and ((LAMBDA (A) (DECLARE (SPECIAL A)) ...) A) are not equivalent, because the A in the initialization form is special in the first case, but the A that is the argument (not the formal parameter) to the lambda expression is not special in the second case. Indeed, the interpretation of a LET containing declarations is not trivial, and that is the main reason why it is documented as a special form, not as a macro, in Common LISP. --Guy - - - - End forwarded messages - - - -  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 21 Dec 83 18:47:03 PST Received: from [128.2.254.192] by CMU-CS-PT with CMUFTP; 21 Dec 83 21:30:11 EST Date: 21 Dec 83 2144 EST (Wednesday) From: Guy.Steele@CMU-CS-A To: common-lisp@SU-AI Subject: Forwarded mail - - - - Begin forwarded message - - - - Received: from CMU-CS-PT by CMU-CS-A; 19 Dec 83 22:12:40 EST Received: from MIT-MC by CMU-CS-PT; 19 Dec 83 21:58:53 EST Date: 19 December 1983 22:11 EST From: Alan Bawden Subject: must be wrong To: GLS @ MIT-MC (DEFUN FOO (A) (LET ((A A)) (DECLARE (SPECIAL A)) ...) the reference to A within the initialization of the LET is indeed subject to the SPECIAL declaration and therefore does not refer to the parameter named A. This sounds like nonsense to me. If the theory of Common Lisp special declarations really works out this way, then it is broken. There is no reason for declarations found in the body of LET or DO to effect any aspect of the initial-value forms. - - - - End forwarded message - - - -  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 20 Dec 83 18:48:56 PST Received: ID ; Tue 20 Dec 83 21:48:51-EST Date: Tue, 20 Dec 1983 21:48 EST From: Scott E. Fahlman To: Moon%SCRC-TENEX@MIT-ML.ARPA Cc: Common-Lisp@SU-AI.ARPA Subject: Comments on Mary Poppins Chapter 9 In-reply-to: Msg of 19 Dec 1983 01:36-EST from Moon%SCRC-TENEX at MIT-ML From MOON: When does COMPILE-FILE recognize PROCLAIM as a top-level form in the file? (1) Never: put (EVAL-WHEN (COMPILE LOAD EVAL) ...) around it. (2) Always: make sure non-constant arguments are evaluable at compile time. (3) Only when the argument is quoted. (4) Only when the compiler, by analysis, can prove the argument is constant. Even if the answer is 1, the manual should say so explicitly, since people reasoning by analogy from Maclisp will expect something else. I can think of good arguments in support of each of the above four possible answers. I guess I ought to argue in favor of 1 since it's the simplest; but it will also lead users to commit the most careless errors. I would favor choice 2 and could live with 3 or 4. I am strongly opposed to choice 1. In practice the argument will always be quoted and always wants to be noticed at all three times. It is horrible to contemplate having to put EVAL-WHEN's around all PROCLAIM forms in order to get this effect. -- Scott  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 20 Dec 83 18:26:23 PST Received: ID ; Tue 20 Dec 83 21:26:09-EST Date: Tue, 20 Dec 1983 21:26 EST From: Scott E. Fahlman To: "David A. Moon" Cc: Common-Lisp@SU-AI.ARPA Subject: Declarations In-reply-to: Msg of 20 Dec 1983 15:50-EST from "David A. Moon" Dave, I like your proposal for special declarations and would gladly have supported it if you had proposed it last June. I have never felt too strongly one way or the other about the effect of SPECIAL declarations on init forms, and your scheme has the merit of clarity. However, I feel that it is much too late now for any changes in the fundamental binding mechanisms of the language. Despite some minor inconsistencies in the manual, it seemed very clear to me from the description in Excelsior that SPECIAL declarations were supposed to include the init forms, and that is what we implemented. The finishing touches are now being added to our system here and to the version at DEC, and I am totally unwilling to go back and change the compiler and interpreter in fundamental ways at this time. Even a name change at this point would be a major hassle. -- Scott  Received: from MIT-ML by SU-AI with TCP/SMTP; 20 Dec 83 12:52:05 PST Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Tue 20-Dec-83 15:53:04-EST Date: Tue, 20 Dec 83 15:50 EST From: "David A. Moon" Subject: Declarations To: Common-Lisp@SU-AI.ARPA I have an alternate proposal for declarations. It is mainly intended as an easier-to-understand way of explaining things that gives the same semantics, but it also resolves the inconsistencies in the manual (Mary Poppins and Excelsior editions) in a way that is probably inconsistent with the intent of the manual, but is more consistent with the Laser edition and with the practice in previous lisps such as Maclisp and Lisp Machine Lisp. I realize it is rather late for this kind of thing, but given that the manual is inconsistent with itself and that some people were surprised by the change from last year's version of the language, maybe we can reconsider. In any case this way of explaining things seems to be easier to understand. The basic problem is the SPECIAL declaration, which falls into both categories of declarations: it both concerns the binding of variables and is pervasive. This is not well explained in the manual and seems to be a great source of confusion. I propose to flush the idea that SPECIAL declarations are pervasive. Read on before judging. There are two disjoint classes of declaration: those that are attached to a particular variable binding, and those that are not. Note that I am not discussing proclamations here; they have their own scoping rules which are different from the rules for declarations. The scoping rule for the first kind of declaration is that it applies to precisely the text that is in the lexical scope of the variable binding with which it is associated. Such declarations are shadowed by a variable binding for the same name inside their scope. Since the lexical scoping rules are very well and precisely defined, we already understand everything about this kind of declaration. The scoping rule for the second kind of declaration is that it is pervasive. The declaration is attached to a lambda-expression or to a form (one of the special forms listed on page 125). The declaration applies to all text inside that expression or form; there are no special cases such as init-forms of LET or DO. Such declarations are shadowed by a conflicting declaration inside their scope. Possible names for the two kinds of declaration are "lexical" and "pervasive" or "variable" and "non-variable." None of this is new. What about SPECIAL declarations? I propose that SPECIAL declarations be put entirely into the first category, in the following way: When a declaration, (SPECIAL X), is attached to a form (or lambda-expression) it creates a -lexical- binding of the name X in that form. Unlike all other bindings, this binding does not associate a value with the name X. Instead, it associates a "special" marker with the name. Any text that is in the lexical scope of this binding, and uses the variable X, refers to the dynamic binding of X, because it sees the "special" marker. The scope of a SPECIAL declaration is precisely defined by the scope of this binding. Note how close this definition is to the way that some interpreters actually work internally. In addition to creating this lexical binding, a (SPECIAL X) declaration also changes the meaning of a binding, if there is one, of the variable X in the form to which the declaration is attached; it causes that binding to be a dynamic binding rather than a lexical binding. This applies only to the form to which the declaration is directly attached, not to any subforms of it. (This is not new.) The declaration-allowing forms FLET, LABELS, LOCALLY, and MACROLET do not normally create bindings of variable names (only function names), so we have a slight exception, permitting SPECIAL declarations inside them to create such bindings. We now understand completely how the SPECIAL declaration works in LET. Three examples: (defun foo (x) (let ((x x)) (declare (special x)) (bar x))) Reading from left to right, there are five occurrences of x. The declaration causes the second and fifth to refer to a dynamic variable, while the first and third refer to a lexical variable. (The fourth occurrence is the one in the declaration itself). The third occurrence of x does not refer to the dynamic variable, because it is not in the scope of the lexical binding of the name x created by the special declaration, because of the way LET defines scoping in its subforms. (defun foo () (declare (special x)) (bar x)) The declaration causes the second occurrence of x to refer, freely, to a dynamic variable, because this x is inside the lexical scope of a binding of the name x attached to the defun. (defun foo () (let ((x (quux))) (mumble x) (locally (declare (special x)) (bar x)))) Here the first and second occurrences of x refer to a lexical variable, while the fourth refers to a dynamic variable. The binding of the name x in the LOCALLY shadows the binding of the name x in the LET. There remains the issue of how sequential binding forms such as LET* and DEFUN should work. (DEFUN uses sequential binding with respect to initial value forms for &optional, &key, and &aux variables). When a SPECIAL declaration creates a lexical binding of a name in such a form, at what position in the sequence of bindings should it be inserted? This makes a difference because it affects whether the scope of the declaration includes or excludes the initial value forms. Clearly if the form includes a (dynamic) binding of the name being declared, then the (lexical) binding created by the declaration should be inserted at that point. Otherwise we can either insert the declaration's binding at the beginning of the sequence of bindings, giving it the largest possible scope, or at the end, giving it the smallest possible scope. I suggest putting it at the beginning, because that is what people seem to expect with DEFUN (see the example at the bottom of page 126.) Two examples: (defun foo (x) (let* ((x (bar x)) (y (quu x))) (declare (special x)) ...)) The first and third occurrences of x refer to a lexical variable, while the second and fourth refer to a dynamic variable. (bar x) is outside the scope of the special declaration while (quu x) is inside its scope. (defun foo (x) (let* ((w (bar x)) (y (quu x))) (declare (special x)) ...)) The first occurrence of x refers to a lexical variable, while the second and third refer, freely, to a dynamic variable. Both (bar x) and (quu x) are inside the scope of the special declaration. If let had been used instead of let*, neither of them would be inside the scope of the declaration. For explanatory purposes, the above two examples could be written on paper as (defun foo (x) (let* ((x (bar x)) (x @I[special]) (y (quu x))) (declare (special x)) ...)) (defun foo (x) (let* ((x @I[special]) (w (bar x)) (y (quu x))) (declare (special x)) ...))  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 16 Dec 83 20:14:23 PST Received: from [128.2.254.192] by CMU-CS-PT with CMUFTP; 16 Dec 83 23:01:48 EST Date: 16 Dec 83 2314 EST (Friday) From: Guy.Steele@CMU-CS-A To: Richard M. Stallman Subject: Special declarations CC: common-lisp@SU-AI In-Reply-To: "Richard M. Stallman's message of 15 Dec 83 17:05-EST" Thank you for pursuing this bug. There are at least two gross internal contradictions in the manual with respect to declarations, as a result of editing errors on my part. I am very sorry for the confusion. Let me clarify matters. In your example (DEFUN FOO (A) (LET ((A A)) (DECLARE (SPECIAL A)) ...) the reference to A within the initialization of the LET is indeed subject to the SPECIAL declaration and therefore does not refer to the parameter named A. This sentence in the first paragraph on page 127 of the Mary Poppins edition: However, the reference to x in the first call to foo is a local reference, not a special one. is in error and must be rewritten; that reference to x is in fact special. Martin Griss has also pointed out that the parenthetical remark (but not the init forms) that appears in paragraph 2, page 102, of the Mary Poppins edition (and paragraph 3, page 95, of the Excelsior edition), in the description of do and do*, is also in error; it should be replaced by a non-parenthetical to the init forms, That is, the init forms in do and do* are in fact subject to declarations in the body in exactly the same way as init forms are in let and let*. --Guy  Received: from MIT-ML by SU-AI with TCP/SMTP; 9 Dec 83 21:20:11 PST Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Sat 10-Dec-83 00:19:41-EST Date: Sat, 10 Dec 83 00:18 EST From: "David A. Moon" Subject: Comments on changes in Mary Poppins edition To: Common-Lisp@SU-AI.ARPA If we agree that the following are mistakes in the manual they should go into an errata file to be distributed to readers of the book. p.245: I don't like the specification that VECTOR-PUSH-EXTEND returns NIL if given a non-adjustable array whose fill-pointer is equal to its length. I think it would be more tasteful to say that this signals an error, or at least that it is an error. I don't think user programs should have to check the value returned by VECTOR-PUSH-EXTEND to make sure that it worked. p.270: It says that if a form typed at top-level returns no values, * is set to NIL and the *,**,*** and /,//,/// histories are updated. The last mail I have about this says that the history variables would be unchanged in this case: Date: 2 Sep 83 0047 EDT (Friday) From: Guy.Steele@CMU-CS-A [Comments by GLS are in square brackets.] p. 257 (second and fourth paragraphs, and parentheses in the first paragraph): We agreed to change the rules for * to be consistent with what was printed, rather than aligned with +, but the manual wasn't updated. [I remember what was agreed to. + is as before. *, **, *** are updated every time a result is printed, whether it is the only result or one of -> several. If an evaluation produces zero values, then * does not change. /, //, /// are updated when the results of an evaluation are printed, however many (possibly zero) there are; if the computation is aborted, / is not updated.] Maybe we later agreed to change the no-values case and I just forgot and didn't save that mail. p.289: A consequence of the description of how #+ and #- interact with *read-suppress* is that "#+foo #+bar 1 #-bar 2" is not consistently skipped if "foo" is false; it reads as the number "2" if "foo" and "bar" are both false. I think it should always read as nothing. I think the last bulleted paragraph on page 289 should simply be deleted; #+ and #- while in *read-suppress* mode behave normally, except of course they do not turn -off- *read-suppress* mode. p.310: The example of the ' macro character should be supplying T as the second argument to READ (eof-error-p). p.335: There's part of some other document on this page. p.341: The host argument to parse-namestring would almost never be used (normally the host would come from the defaults), so it would have been better to make this argument a keyword argument rather than an optional argument. Probably it would have been more consistent to make both optional arguments into keyword arguments. Is it too late? p.343: The bottom paragraph didn't get updated for the loosening up of structured pathname components. p.344: In the explanation of the meaning of ENOUGH-NAMESTRING, I believe that should be supplied in the call to PARSE-NAMESTRING. Otherwise PARSE-NAMESTRING might parse the string relative to the host of *DEFAULT-PATHNAME-DEFAULTS*, which could be the wrong host; this means that ENOUGH-NAMESTRING would be required always to include a host in its output, which is probably not what you intended.  Received: from MIT-XX by SU-AI with TCP/SMTP; 9 Dec 83 11:12:22 PST Received: from SCRC-EUPHRATES by SCRC-QUABBIN with CHAOS; Fri 9-Dec-83 14:17:00-EST Date: Fri, 9 Dec 83 14:12 EST From: "David A. Moon" Subject: Copy-Seq To: Dan Pierson Cc: common-lisp@SU-AI.ARPA In-reply-to: The message of 8 Dec 83 15:52-EST from Dan Pierson Date: Thu, 8 Dec 83 15:52 EST From: Dan Pierson What should Copy-Seq of a vector with fill-pointer return? The following are some options: Return a vector with fill-pointer and copy the elements up to the fill pointer. Return a vector with fill-pointer and copy all the elements. Return a vector without fill pointer with the length set by the fill pointer. Your third possibility is the way I read the documentation (Excelsior edition), since COPY-SEQ is equivalent to SUBSEQ and copies sequences, not general objects with all their arbitrary attributes. We will leave aside the fact that under COPY-SEQ it says EQUAL where it means EQUALP and that the manual is silent on interaction between EQUAL/EQUALP and FILL-POINTER; page 63 implies that EQUAL ignores the FILL-POINTER, which is probably wrong, while page 234 implies that EQUAL respects the FILL-POINTER.  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 8 Dec 83 22:21:49 PST Received: ID ; Fri 9 Dec 83 01:21:53-EST Date: Fri, 9 Dec 1983 01:21 EST From: Skef Wholey To: Dan Pierson Cc: common-lisp@SU-AI.ARPA Subject: Copy-Seq In-reply-to: Msg of 8 Dec 1983 15:52-EST from Dan Pierson The Common Lisp Manual says (at the beginning of the sequence functions chapter) that Whenever a sequence function must construct and return a new vector, it always returns a @i[simple] vector. Similarly, any strings constructed will be simple strings.  Received: from CSNET-CIC by SU-AI with TCP/SMTP; 8 Dec 83 22:03:31 PST Date: Thu, 8 Dec 83 15:52 EST From: Dan Pierson Return-Path: Subject: Copy-Seq To: common-lisp@SU-AI Via: Digital; 8 Dec 83 23:50-EST What should Copy-Seq of a vector with fill-pointer return? The following are some options: Return a vector with fill-pointer and copy the elements up to the fill pointer. Return a vector with fill-pointer and copy all the elements. Return a vector without fill pointer with the length set by the fill pointer. dan  Received: from MIT-MC by SU-AI with TCP/SMTP; 7 Dec 83 09:28:28 PST Received: from SCRC-YANGTZE by SCRC-RIVERSIDE with CHAOS; Mon 5-Dec-83 14:29:41-EST Date: Mon, 5 Dec 83 14:32 EST From: Carl Hoffman Subject: :IF-EXISTS :SUPERSEDE vs. :NEWEST To: BSG%SCRC-TENEX@MIT-MC.ARPA, Wholey@CMU-CS-C.ARPA, Fahlman@CMU-CS-C.ARPA, Common-Lisp@SU-AI.ARPA Cc: file-protocol%SCRC-TENEX@MIT-MC.ARPA, moon%SCRC-TENEX@MIT-MC.ARPA, jwalker%SCRC-TENEX@MIT-MC.ARPA In-reply-to: The message of 5 Dec 83 11:25-EST from Bernard S. Greenberg , The message of 5 Dec 83 12:20-EST from Skef Wholey , The message of 5 Dec 83 12:26-EST from Scott E. Fahlman As I understand :IF-EXISTS :SUPERSEDE and :TRUNCATE, these two options should be identical except with respect to the amount of available storage in the file system while the file is open, and to what action is taken if writing to the file is aborted. But, most importantly, they should be identical with respect to whether or not a new file is created. The only reason I would use :TRUNCATE instead of :SUPERSEDE is if the amount of data being written was a sizable fraction of the amount of available space in the filesystem. Currently, in LMFS, (OPEN "a.b.newest" ... :IF-EXISTS :SUPERSEDE) will always create a new file, but (OPEN "a.b.newest" ... :IF-EXISTS :TRUNCATE) will only create a new file if no versions of a.b already exist. Regardless of what is decided for :SUPERSEDE, I would like to see :TRUNCATE work the same way. The current LMFS behavior is asymmetric and difficult to document. I feel that either of the proposed behaviors for :SUPERSEDE of a newest version are reasonable. I can see arguments for either one. Therefore, which definition is chosen should depend upon how easy it is to get the other behavior from the chosen one, and what the implications are for the implementor. I can't comment on the latter issue, but here is an example of the former. Given the current LMFS definition for :SUPERSEDE, if I want to supersede the newest version, I must (in Symbolics Release 5.0) do: (DEFUN OPEN-SUPERSEDE (PATH) (IF (NOT (EQ (SEND PATH :VERSION) :NEWEST)) (OPEN PATH :DIRECTION :OUTPUT :IF-EXISTS :SUPERSEDE) (LET ((FILES (CDR (FS:DIRECTORY-LIST (SEND PATH :NEW-VERSION :WILD) :SORTED :FAST)))) (IF (NULL FILES) (OPEN PATH :DIRECTION :OUTPUT) (OPEN (CAAR (LAST FILES)) :DIRECTION :OUTPUT :IF-EXISTS :SUPERSEDE))))) I believe this is what Scott Fahlman suggested I do. Given the current LMFS definition for :TRUNCATE, if I do not want to truncate the newest version, I must do: (DEFUN OPEN-TRUNCATE (PATH) (OPEN PATH :DIRECTION :OUTPUT :IF-EXISTS (IF (EQ (SEND PATH :VERSION) :NEWEST) :TRUNCATE :CREATE))) In other words, if you know that the version of PATH is :NEWEST, then it is a simple matter to say :IF-EXISTS :CREATE instead of :IF-EXISTS :SUPERSEDE. But if you really do want to supersede the newest version, then you must first list the directory. The issue I feel strongly about is that :SUPERSEDE and :TRUNCATE should behave similarly with respect to file creation. I think I convinced Bernie that this isn't hard to do in LMFS. Date: Monday, 5 December 1983, 11:25-EST From: Bernard S. Greenberg Argument #1: Imagine a program that took user input for a file name, and wrote out to that file. (Can't argue with that, right?). Suppose further that this program did not like the CL default of :error, and wanted you to be able to write out to a.b.3 if that's what you said. So it might open its file with :IF-EXISTS :SUPERSEDE. Well, suppose you said a.b.newest to it? You CERTAINLY don't want it looking up what the latest version is and superseding it! You want it to create a new version. If that is how you wish to define your user-interface, then you should say :IF-EXISTS :CREATE if the user has specified a pathname with .newest. One can imagine a user interface which would supersede the newest version. Argument #2: Given the primitives available to the file server in versionated operating systems, it is impossible to implement this as proposed without a window between determining the version number and opening it for superseding. Given what it is that the programmer is trying to do, the window will always exist. You are just moving the window into user code, as in the OPEN-SUPERSEDE function defined above.  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 6 Dec 83 20:02:04 PST Received: ID ; Tue 6 Dec 83 23:02:00-EST Date: Tue, 6 Dec 1983 23:01 EST From: Scott E. Fahlman To: "David A. Moon" Cc: common-lisp@SU-AI.ARPA Subject: Exporting Structures In-reply-to: Msg of 6 Dec 1983 22:40-EST from "David A. Moon" By "semi-official extension" I mean something like the following: From time to time we will discover shortcomings in the language that can be fixed in an upward-compatible way. If the fix is just to add more functions, then a yellow-pages package is the proper vehicle. But if the fix is to extend existing things by adding new keyword options or handling cases that were illegal before, and we all agree that the change is worthy of inclusion in the next edition of the manual, then we all just happen to make the same extension to our implementations at the same time and this change is registered in some central place. That way we (and our users) will not be wandering off in 27 different directions that will be incompatible with the change that is going to be adopted. I suppose that it is not legal for packages to claim portability if they use such changes prior to their official adoption, but at least people who jump the gun will be heading in the right direction. All these bureaucratic mechanisms need to be worked out in greater detail one of these days. -- Scott  Received: from MIT-MC by SU-AI with TCP/SMTP; 6 Dec 83 19:39:42 PST Received: from SCRC-EUPHRATES by SCRC-QUABBIN with CHAOS; Tue 6-Dec-83 22:43:47-EST Date: Tue, 6 Dec 83 22:40 EST From: "David A. Moon" Subject: Exporting Structures To: "Scott E. Fahlman" Cc: common-lisp@SU-AI.ARPA In-reply-to: The message of 6 Dec 83 17:34-EST from Scott E. Fahlman Date: Tue, 6 Dec 1983 17:34 EST From: Scott E. Fahlman We now have some real Common Lisp users around here, and they are finding the holes at a steady pace. One, found by Mike Jones, concerns the interaction of packages and DEFSTRUCT. Unless I'm missing something, the language currently has no way to tell a DEFSTRUCT to export all of the various accessors and other forms it defines. You don't want exporting by default -- the majority of structures are for internal use within a subsystem -- but when you do want to export all of the handles on some structure it is a pain to do this for each accessor. Proposal: add an :EXPORT option to DEFSTRUCT that causes each of the defined forms to be exported from the current package. (If people like this solution, it could become one of the "semi-official extensions" until the second edition of the Common Lisp Book of the Dead takes shape. There are currently no automatic exportation things at all. The language design assumes that you will always list the symbols you want to export in one place, e.g. in a single call to the function EXPORT. It is probably reasonable to have some auto-export things, although as we know this can be dangerous if over-used. DEFSTRUCT is only one application. Making a "semi official extension" (I assume you really mean it would be a yellow pages package except that it is inextricably intertwined with DEFSTRUCT proper) seems like a reasonable idea. I hope the documentation will be less vague than "causes each of the defined forms to be exported from the current package." I don't even know what a defined form is.  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 6 Dec 83 18:32:21 PST Received: ID ; Tue 6 Dec 83 21:32:15-EST Date: Tue, 6 Dec 1983 21:32 EST From: Scott E. Fahlman To: "Bernard S. Greenberg" Cc: Bug-Lispm%SCRC-TENEX@MIT-MC.ARPA, Common-Lisp@SU-AI.ARPA, CWH%SCRC-TENEX@MIT-MC.ARPA, file-protocol%SCRC-TENEX@MIT-MC.ARPA, jwalker%SCRC-TENEX@MIT-MC.ARPA, Moon%SCRC-TENEX@MIT-MC.ARPA, ROM%SCRC-TENEX@MIT-MC.ARPA, Wholey@CMU-CS-C.ARPA Subject: :IF-EXISTS :SUPERSEDE In-reply-to: Msg of 6 Dec 1983 10:28-EST from "Bernard S. Greenberg" OK, I went back and looked at the text and I agree that it is unambiguous, as Moon says. Any ambiguity comes not from the text but from the expectations of the reader. I think that we probably could have come up with something a bit safer, but it is workable as it stands and we should not mess with this until we start thinking about the next round of improvements. -- Scott  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 6 Dec 83 14:35:13 PST Received: ID ; Tue 6 Dec 83 17:34:22-EST Date: Tue, 6 Dec 1983 17:34 EST From: Scott E. Fahlman To: common-lisp@SU-AI.ARPA Subject: Exporting Structures We now have some real Common Lisp users around here, and they are finding the holes at a steady pace. One, found by Mike Jones, concerns the interaction of packages and DEFSTRUCT. Unless I'm missing something, the language currently has no way to tell a DEFSTRUCT to export all of the various accessors and other forms it defines. You don't want exporting by default -- the majority of structures are for internal use within a subsystem -- but when you do want to export all of the handles on some structure it is a pain to do this for each accessor. Proposal: add an :EXPORT option to DEFSTRUCT that causes each of the defined forms to be exported from the current package. (If people like this solution, it could become one of the "semi-official extensions" until the second edition of the Common Lisp Book of the Dead takes shape. -- Scott  Received: from MIT-MC by SU-AI with TCP/SMTP; 6 Dec 83 12:56:11 PST Received: from SCRC-EUPHRATES by SCRC-QUABBIN with CHAOS; Tue 6-Dec-83 15:58:21-EST Date: Tue, 6 Dec 83 15:54 EST From: "David A. Moon" Subject: :IF-EXISTS :SUPERSEDE To: "Bernard S. Greenberg" Cc: CWH%SCRC-TENEX@MIT-MC.ARPA, Wholey@CMU-CS-C.ARPA, Fahlman@CMU-CS-C.ARPA, Common-Lisp@SU-AI.ARPA, Bug-Lispm%SCRC-TENEX@MIT-MC.ARPA, ROM%SCRC-TENEX@MIT-MC.ARPA, file-protocol%SCRC-TENEX@MIT-MC.ARPA, jwalker%SCRC-TENEX@MIT-MC.ARPA In-reply-to: The message of 6 Dec 83 10:30-EST from Bernard S. Greenberg Date: Tuesday, 6 December 1983, 10:30-EST From: Bernard S. Greenberg Date: Monday, 5 December 1983, 23:12-EST From: David A. Moon Argument #2: Given the primitives available to the file server in versionated operating systems, it is impossible to implement this as proposed without a window between determining the version number and opening it for superseding. This argument is false. The Tops-20/Tenex Chaosnet file server has no problem doing this without windows. During the time between opening and closing, the old file is in an "open for reading" state that prevents anyone else from superseding it or renaming it. Presumably other versionated operating systems may have comparable primitives. Could you detail the sequence of operations? The above is not sufficiently clear. When do you open the second file? Under what name? Sure. Here's the sequence of operations, translated from Midas to English: Do a GTJFN to look up the file name specified. The options specified are one of the following cases: - direction is not output => tell the system to look up an existing version, complain if no file is found, and never create a new file. - direction is output (no bidirectional support yet); if append, overwrite, or truncate is set and create is not => tell the system to barf if no file is found and to look up an existing version if newest is specified. - if any of supersede, append, overwrite, truncate, rename, rename-and-delete, or if-exists-error is set => tell the system to look up an existing version if the version is newest, rather than creating a new version, and tell it to barf if an existing file is found. - otherwise => tell it to create a new file if the version is newest and to barf if an existing file is found. The result of this GTJFN is # cases: (1) A file is found/created with no error => use it (2) An error other than file-already-exists, or any error if if-exists-error was specified => return error to user (3) File-already-exists error => GTJFN again, telling the system to look up the existing file. [An error here is just signalled to the user, and means someone changed something, e.g. deleted the existing file out from under you. Probably should start over rather than erring out.] Now if append, overwrite, or truncate is set, use that file. Otherwise save that file, along with a flag saying whether rename, rename-and-delete, or supersede was specified. Open the file for input with the "restricted" option so that no one else can mess with it; if this fails return an error; Tops-20 doesn't allow you to supersede a file that someone is using, unlike some other systems that will hold onto the file until all users of it close. Now open a temporary file in the same directory and use it. At non-abort close time, rename the temporary file on top of the other file, superseding it. (For rename/rename-and-delete, the other file is renamed out of the way first). Hopefully I haven't perpetrated too many typographical errors in the above. I don't think the Tops-20 strangeness of having separate system calls to get a handle on a file and to open a file is depended on in any fundamental way.  Received: from MIT-MC by SU-AI with TCP/SMTP; 6 Dec 83 07:29:56 PST Received: from SCRC-CONCORD by SCRC-QUABBIN with CHAOS; Tue 6-Dec-83 10:33:57-EST Date: Tue, 6 Dec 83 10:30 EST From: "Bernard S. Greenberg" Subject: :IF-EXISTS :SUPERSEDE To: Moon%SCRC-TENEX@MIT-MC.ARPA, CWH%SCRC-TENEX@MIT-MC.ARPA, Wholey@CMU-CS-C.ARPA, Fahlman@CMU-CS-C.ARPA Cc: Common-Lisp@SU-AI.ARPA, Bug-Lispm%SCRC-TENEX@MIT-MC.ARPA, ROM%SCRC-TENEX@MIT-MC.ARPA, file-protocol%SCRC-TENEX@MIT-MC.ARPA, jwalker%SCRC-TENEX@MIT-MC.ARPA In-reply-to: The message of 5 Dec 83 23:12-EST from David A. Moon Date: Monday, 5 December 1983, 23:12-EST From: David A. Moon Argument #2: Given the primitives available to the file server in versionated operating systems, it is impossible to implement this as proposed without a window between determining the version number and opening it for superseding. This argument is false. The Tops-20/Tenex Chaosnet file server has no problem doing this without windows. During the time between opening and closing, the old file is in an "open for reading" state that prevents anyone else from superseding it or renaming it. Presumably other versionated operating systems may have comparable primitives. Could you detail the sequence of operations? The above is not sufficiently clear. When do you open the second file? Under what name?  Received: from MIT-MC by SU-AI with TCP/SMTP; 6 Dec 83 07:27:50 PST Received: from SCRC-CONCORD by SCRC-QUABBIN with CHAOS; Tue 6-Dec-83 10:31:56-EST Date: Tue, 6 Dec 83 10:28 EST From: "Bernard S. Greenberg" Subject: :IF-EXISTS :SUPERSEDE To: Moon%SCRC-TENEX@MIT-MC.ARPA, CWH%SCRC-TENEX@MIT-MC.ARPA, Wholey@CMU-CS-C.ARPA, Fahlman@CMU-CS-C.ARPA Cc: Common-Lisp@SU-AI.ARPA, Bug-Lispm%SCRC-TENEX@MIT-MC.ARPA, ROM%SCRC-TENEX@MIT-MC.ARPA, file-protocol%SCRC-TENEX@MIT-MC.ARPA, jwalker%SCRC-TENEX@MIT-MC.ARPA In-reply-to: The message of 5 Dec 83 23:12-EST from David A. Moon Date: Monday, 5 December 1983, 23:12-EST From: David A. Moon It seems to me that what we must do is quite clear and there are no choices to be made. I "fixed" the Lisp machine, LMFS and COPYF to act in accordance with the non-ambiguity you observe (patched). COPYF now works to extant, numeric-versioned targets again. The Common Lisp manual should contain the following quote from the new COPYF (OPEN.... ':IF-EXISTS (IF (EQ (SEND TO-PATHNAME ':VERSION) ':NEWEST) ':NEW-VERSION ':SUPERSEDE).. under the description of :SUPERSEDE, and state that unless you include it in your program, if you use :SUPERSEDE, you will stop having a versionated file system. Yes, it is consistent, and yes, I still believe there is a language problem. I call to rememberance the PL/I addition operator...... Perhaps :IF-EXISTS :SUPERSEDE should be the default for a non-:NEWEST version on output (as it used to be, de facto, around here), removing the temptation to fall into the above hole.  Received: from MIT-ML by SU-AI with TCP/SMTP; 5 Dec 83 20:15:13 PST Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Mon 5-Dec-83 22:55:01-EST Date: Mon, 5 Dec 83 23:12 EST From: "David A. Moon" Subject: :IF-EXISTS :SUPERSEDE To: Carl Hoffman , "Bernard S. Greenberg" , Skef Wholey , "Scott E. Fahlman" Cc: Common-Lisp@SU-AI.ARPA, Bug-Lispm%SCRC-TENEX@MIT-MC.ARPA, ROM%SCRC-TENEX@MIT-MC.ARPA, file-protocol%SCRC-TENEX@MIT-MC.ARPA, jwalker%SCRC-TENEX@MIT-MC.ARPA In-reply-to: The message of 4 Dec 83 16:57-EST from Carl Hoffman , The message of 5 Dec 83 11:25-EST from Bernard S. Greenberg , The message of 5 Dec 83 11:25-EST from Bernard S. Greenberg , The message of 5 Dec 83 12:20-EST from Skef Wholey , The message of 5 Dec 83 12:20-EST from Skef Wholey , The message of 5 Dec 83 12:26-EST from Scott E. Fahlman , The message of 5 Dec 83 12:26-EST from Scott E. Fahlman , The message of 5 Dec 83 14:32-EST from Carl Hoffman Date: Monday, 5 December 1983, 11:25-EST From: Bernard S. Greenberg Subject: :IF-EXISTS :SUPERSEDE vs. :NEWEST We are having a little dispute here about the intended semantics of :IF-EXISTS :SUPERSEDE on output, when the file version of the pathname to be opened is :NEWEST. The manual is not specific on what this means. It (Excelsior edition) says "This differs from :NEW-VERSION in that :SUPERSEDE creates a new file with the same name as the old one". That seems quite specific to me. If you write a.b.newest in :IF-EXISTS :SUPERSEDE mode, you create a new file with the same version number as the newest existing version of a.b, replacing (superseding) that existing file. It might be valuable for the manual to contain a note such as "if the version component of the pathname is :NEWEST, then one of two rules for developing a specific version number is used. If the value of :DIRECTION is :OUTPUT or :IO and the value of :IF-EXISTS is :NEW-VERSION, then a version number one higher than the highest existing version is used. In all other cases, the highest existing version is used." Argument #1: Imagine a program that took user input for a file name, and wrote out to that file. (Can't argue with that, right?). Suppose further that this program did not like the CL default of :error, and wanted you to be able to write out to a.b.3 if that's what you said. So it might open its file with :IF-EXISTS :SUPERSEDE. Well, suppose you said a.b.newest to it? You CERTAINLY don't want it looking up what the latest version is and superseding it! You want it to create a new version. This is a good point; a program with such a user interface needs to check pathname-version of its pathname to decide what :IF-EXISTS option to use, since we failed to provide one that implements that behavior. Argument #2: Given the primitives available to the file server in versionated operating systems, it is impossible to implement this as proposed without a window between determining the version number and opening it for superseding. This argument is false. The Tops-20/Tenex Chaosnet file server has no problem doing this without windows. During the time between opening and closing, the old file is in an "open for reading" state that prevents anyone else from superseding it or renaming it. Presumably other versionated operating systems may have comparable primitives. It seems to me that what we must do is quite clear and there are no choices to be made.  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 5 Dec 83 09:26:42 PST Received: ID ; Mon 5 Dec 83 12:26:34-EST Date: Mon, 5 Dec 1983 12:26 EST From: Scott E. Fahlman To: Bernard S. Greenberg Cc: Common-Lisp@SU-AI.ARPA, cwh%SCRC-TENEX@MIT-ML.ARPA, file-protocol%SCRC-TENEX@MIT-ML.ARPA, jwalker%SCRC-TENEX@MIT-ML.ARPA, moon%SCRC-TENEX@MIT-ML.ARPA Subject: :IF-EXISTS :SUPERSEDE vs. :NEWEST In-reply-to: Msg of 5 Dec 1983 11:25-EST from Bernard S. Greenberg Bernie's arguments sound good to me. Generating a newer file instead of clobbering the old one seems like the least treacherous option. If I really do want to clobber the newest file, that's easy to do -- just find it and ask for exactly that version to be superseded. I might even go farther and outlaw the use of any wild-cardish things in the pathname given to a supersede. After a couple of years of forced confinement on a Tops-10 system, I have a very healthy respect for the number of subtle ways that superseding can screw you. To answer the specific question, CMU's Spice file-name server currently does not provide file versions, though that will be changing any week now. Until we get the new name-server in Spice, we have only made a rather half-hearted effort to implement all these options in a temporary way -- we've done only what we need most and have not worried a lot about the funny combinations. So I'm afraid we provide no precedent. I've lost track of just what the VMS implementation does on this. By the way, we probably want to start up some sort of "Rulings on Ambiguities" file in a generally accessible place. Once the manual is in print, there will still be issues like this that come up, that we reach some sort of consensus on, and that we want to chisel into some sort of stone (probably soapstone, not granite). This should not contain all the random discussion, but just the questions, answers, and maybe some rationale. Guy seems the obvious choise to maintain this, unless he wants to pass the baton to someone else. -- Scott  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 5 Dec 83 09:21:18 PST Received: ID ; Mon 5 Dec 83 12:20:59-EST Date: Mon, 5 Dec 1983 12:20 EST From: Skef Wholey To: Bernard S. Greenberg Cc: Common-Lisp@SU-AI.ARPA, cwh%SCRC-TENEX@MIT-ML.ARPA, file-protocol%SCRC-TENEX@MIT-ML.ARPA, jwalker%SCRC-TENEX@MIT-ML.ARPA, moon%SCRC-TENEX@MIT-ML.ARPA Subject: :IF-EXISTS :SUPERSEDE vs. :NEWEST From: Bernard S. Greenberg Has CMU implemented this combination? With what interpretation? Fortunately for implementors (and unfortunately for users), the Spice file system does not yet support version numbers other than 1. So we haven't had to deal with this stuff in any deep way.  Received: from MIT-MC by SU-AI with TCP/SMTP; 5 Dec 83 08:43:32 PST Received: from SCRC-CONCORD by SCRC-QUABBIN with CHAOS; Mon 5-Dec-83 11:30:50-EST Date: Monday, 5 December 1983, 11:25-EST From: Bernard S. Greenberg Subject: :IF-EXISTS :SUPERSEDE vs. :NEWEST To: Common-Lisp at SU-AI Cc: file-protocol at SCRC-TENEX, cwh at SCRC-TENEX, moon at SCRC-TENEX, jwalker at SCRC-TENEX We are having a little dispute here about the intended semantics of :IF-EXISTS :SUPERSEDE on output, when the file version of the pathname to be opened is :NEWEST. The manual is not specific on what this means. It seems as though it says, "Well, if there are any versions, find out what the latest version is, and make believe you were attempting to create that version with :IF-EXISTS :SUPERSEDE." I contend that this combination of arguments with :newest is sheer combinatorial fallout from the spec, and is not only not useful, but this interpretation is negatively useful. First of all, :SUPERSEDE is intended for creating specific versions and non-versionated file systems. On non-versionated file systems, it is usually the only file regeneration option you get. If you say :SUPERSEDE, you want to create a.b.3 no matter what. If you say :SUPERSEDE with a.b.newest, you want to create a.b.newest, which is done by creating a new version, no matter what. Argument #1: Imagine a program that took user input for a file name, and wrote out to that file. (Can't argue with that, right?). Suppose further that this program did not like the CL default of :error, and wanted you to be able to write out to a.b.3 if that's what you said. So it might open its file with :IF-EXISTS :SUPERSEDE. Well, suppose you said a.b.newest to it? You CERTAINLY don't want it looking up what the latest version is and superseding it! You want it to create a new version. Argument #2: Given the primitives available to the file server in versionated operating systems, it is impossible to implement this as proposed without a window between determining the version number and opening it for superseding. Carl Hoffman says, "I have an application which periodically dumps some data to the file a.b. Each time it makes such a dump, the previous data is no longer interesting to me, so I dump the data to the same file repeatedly, rather than filling up the directory with unwanted versions. But, sometimes, I want to save one of the dumps, so I create a new version of a.b, and the program will begin writing to that new version instead. If there are no versions of a.b in the directory at all, then I want a new version to be created, of course. :IF-DOES-NOT-EXIST :CREATE is assumed." He should write his data to a.b.1 and copy it when he wants to. Has CMU implemented this combination? With what interpretation? Does anyone else have feelings about the rightness or wrongness of either, or any other, interpretation? How do :OVERWRITE/:TRUNCATE shed any light on this, if any  Received: from MIT-MC by SU-AI with TCP/SMTP; 12 Nov 83 14:32:29 PST Date: Sat 12 Nov 83 17:33:00-EST From: KMP%MIT-OZ@MIT-MC.ARPA Subject: SELECTQ commentary To: Moon%SCRC-TENEX@MIT-MC.ARPA cc: common-lisp@SU-AI.ARPA Reply-To: KMP@MIT-MC In-Reply-To: Message from ""David A. Moon" " of Sat 12 Nov 83 16:29:30-EST Date: Sat, 12 Nov 83 16:24 EST From: David A. Moon Re: :otherwise in selectq References: Msg of 11 Nov 83 14:41-EST from David Chapman I'm not sure why Kent redistributed the enclosed message, since several people had already replied to it pointing out the nonsensicalness of the third paragraph, Sorry, I hadn't forwarded it for that part, which I agree was not realistic. and I (and maybe others?) had already replied to it explaining that magic syntactic words in special forms, such as OTHERWISE, are treated like function names rather than as keywords. As you probably know from previous discussions, I disagree with the decision that was made on OTHERWISE vs :OTHERWISE. Since we're not in a position to consider changing this, it would be pointless to try to reopen that discussion here and now. Nevertheless, it's hard to do language design in a vacuum. It is important, for example, to follow up on decisions you've made by seeing whether your guesses about things like users' intuitions were correct. It might not even affect the current language, but you might some day design another. By the way, in spite of the explicit CC to me, I didn't put Zvona up to this bug report. Anyway, I did find the note interesting, and thought others on CL might also. Especially since it's only in the first few days that a Common Lisp compatible package system available here that people are starting to evolve strong feelings about these things. Perhaps in a few years when it's time to contemplate major evolutionary changes to Common Lisp, there will be a place for a little rabble rousing. For now, that's not what I'd intended; just wanted to quietly pass on what I saw as an interesting data point. In the future I'll try to remember to mark such messages with an "FYI" in the subject line or some such so it doesn't look so much like people should want to reply to them. -------  Received: from MIT-ML by SU-AI with TCP/SMTP; 12 Nov 83 13:43:56 PST Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Sat 12-Nov-83 16:24:40-EST Date: Sat, 12 Nov 83 16:24 EST From: "David A. Moon" Subject: :otherwise in selectq To: kmp@MIT-OZ.ARPA Cc: common-lisp@SU-AI.ARPA References: The message of 11 Nov 83 14:41-EST from David Chapman I'm not sure why Kent redistributed the enclosed message, since several people had already replied to it pointing out the nonsensicalness of the third paragraph, and I (and maybe others?) had already replied to it explaining that magic syntactic words in special forms, such as OTHERWISE, are treated like function names rather than as keywords. Date: Friday, 11 November 1983, 14:41-EST From: David Chapman Subject: :otherwise To: lisp-designers at SCRC-TENEX Cc: kmp at MIT-OZ ReSent-date: Sat 12 Nov 83 14:17:38-EST ReSent-from: KMP%MIT-OZ@MIT-MC.ARPA ReSent-to: common-lisp@SU-AI.ARPA It seems bogus to me that I can't write :otherwise in a selectq. I think that :otherwise should be required. There are reasonable arguments against this. However, I can't see arguments against :otherwise being *allowed*. If the idea is that it doesn't matter what package the ``magic keyword'' (what are these things called, anyway?) is in, then that should extend to the keyword package, too. Unless we are moving toward the view that keywords aren't really symbols. Speaking of which: Why are keywords bound to themselves? Why not rather have EVAL and the compiler special-case them as self-quoting? (Presumably the compiler already does this for T and NIL.) Surely this would be less overhead.  Received: from MIT-MC by SU-AI with TCP/SMTP; 12 Nov 83 11:17:27 PST Date: Friday, 11 November 1983, 14:41-EST From: David Chapman Subject: :otherwise To: lisp-designers at SCRC-TENEX Cc: kmp at MIT-OZ ReSent-date: Sat 12 Nov 83 14:17:38-EST ReSent-from: KMP%MIT-OZ@MIT-MC.ARPA ReSent-to: common-lisp@SU-AI.ARPA It seems bogus to me that I can't write :otherwise in a selectq. I think that :otherwise should be required. There are reasonable arguments against this. However, I can't see arguments against :otherwise being *allowed*. If the idea is that it doesn't matter what package the ``magic keyword'' (what are these things called, anyway?) is in, then that should extend to the keyword package, too. Unless we are moving toward the view that keywords aren't really symbols. Speaking of which: Why are keywords bound to themselves? Why not rather have EVAL and the compiler special-case them as self-quoting? (Presumably the compiler already does this for T and NIL.) Surely this would be less overhead.  Received: from RAND-RELAY by SU-AI with TCP/SMTP; 20 Oct 83 17:10:12 PDT Date: 20 Oct 1983 1341-PDT From: AS.HP-HULK@Rand-Relay Return-Path: Subject: character names Received: by HP-VENUS via CHAOSNET; 20 Oct 1983 13:43:08-PDT To: Common-Lisp@SU-AI Cc: AS%AS.HP-LABS@Rand-Relay Message-Id: <435530590.19147.hplabs@HP-VENUS> Via: HP-Labs; 20 Oct 83 15:07-PDT I could not find the answers to these questions in the Excelsior edition: In which package do the character name symbols returned by the function CHAR-NAME reside? [I would guess the Lisp package.] How does the function NAME-CHAR compare its argument to the known character-name symbols? Does it use EQ or does it examine the print-name and do something fancy like #\ (treat a single character print-name case-sensitively, but treat a longer print-name case-insensitively). [I would guess the latter.] -------  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 13 Oct 83 21:55:21 PDT Received: from [128.2.254.192] by CMU-CS-PT with CMUFTP; 14 Oct 83 00:40:05 EDT Date: 14 Oct 83 0050 EDT (Friday) From: Guy.Steele@CMU-CS-A To: William Galway Subject: SETF and LAMBDAs CC: common-lisp@SU-AI In-Reply-To: "William Galway's message of 13 Oct 83 20:52-EST" Yes, you have certainly hit upon an interesting class of ideas. You might want to explore the literature on "declarative" and "relational" languages, check out the PROLOG language, and perhaps look at a couple of papers Sussman and I wrote on constraint languages (one is in the proceedings of APL '79, and another in the AI Journal a couple of years ago). These all have some related notions, though not exactly what you have suggested. You might ponder the notions that your idea requires (1) a general method for inverting functions calls to which appear as lambda parameters, and (2) some means of dealing with multiple solutions when the inverses turn out to be one-many relations. --Guy  Received: from PARC-MAXC by SU-AI with TCP/SMTP; 13 Oct 83 21:33:01 PDT Date: 13 OCT 83 21:25 PDT From: JONL.PA@PARC-MAXC.ARPA Subject: SETF madness To: Galway@UTAH-20.ARPA cc: Common-Lisp@SAIL.ARPA Sometime during the 1930s or 1940s it was proven that general recursion equtions were turing equivalent . . . But in my lifetime, they haven't been taken too seriously as a computation model by anyone who actually has to get work done "in real time" (Yes, PROLOG is an exception, but I'll comment on that later. Maybe.) What all the partially-facetious, somewhat-wishful, nearly-serious suggestions about extending SETF are leading up to is a re-introduction of recursion equations as a programming paradigm. To be realistic, there must be some limit on the paradigms used. MacLisp's limit was simply that 1) variables would be bound, to 2) values obtained from CAR/CDR sequences over the input [VAX/NIL, which I think still has some remnant of the destructing LET idea, also permits vector-referencing in addition to CAR/CDRing.] This led to the very-compact description of how to "spread" the computed values of a LET into a bunch of variables: namely, a data structure whose form was to match that of an argument, and whose symbols were the variables to be bound. That's actually a very limited paradigm; but I stress that those of us who used it found it most convenient. Another serious proposal would have extended the limitation in point 1) by including any LOCF'able place; this was coupled with a paradigm that used a "program", rather than merely a data structure, to indicate how to destructure the data. Thus (LET ((`(,X ,Y) (MUMBLE))) ...) instead of (LET (((X Y) (MUMBLE))) ...) That is, the "evaluable" places in the program would be places were the destructured value would be "put". Note that (LET (((GET 'X 'SOMEPROP) (MUMBLE))) ...) ;"Program paradigm" would bind the result of (MUMBLE) to a spot on the property list of the symbol X; nothing at all in the "data paradigm" can express this. In fact, we just couldn't see how to do such binding efficiently in PDP10 MacLisp (variables were easy -- they were built-in from antiquity), so that is one reason we didn't try it out. On the other hand, the LispMachine apparently is capable of binding any random cell just as easily as binding a varialbe, so it would have made more sense to attempt it there. I believe it was Rich Stallman's insight that this "program paradigm" was a super-set of the "data paradigm", and could be implemented straight-forwardly; however, I don't believe anyone ever did go to the trouble of building a prototype and trying it out. Now, back to the snipe at PROLOG. It is true that PROLOG as a programming language resembles recursion equations very much, and it is also true that there are rumors of some PROLOG implementations running "in real time". Furthermore, I admit that some problems are very succinctly stated in PROLOG, and their re-formulation into one of the more classic programming languages is a "hard" problem; so it's tempting to hope that some automating of the conversion process will make programming a lot easier. But I don't buy it, yet. As you probe deeper into the use of PROLOG, you find that you really can't do much without significant use of "cuts" and "directions", which are in fact the serializers which tend to convert an apparently descriptive program into a prescriptive one [i.e., rather than a program which says "I would like such-and-such an efffect" into one that says "First, do this, then do that, then do something else, then . . . "] Except for all this madness about SETF, I'm fairly confident that the Lisp community has it's head screwed on straight about avoiding paradigms that trap the unwary into an exponentially-worse performance. If - - - If Prolog really makes it big, it will have to make it possible to express simple things like, say, (for I from 1 to 100 sum (AREF A I)) in such a way that the loop-overhead doesn't take an order of magnitude more time than the array referencing. SIgh, and again, if it "makes it big", then the prolog manual will probably expand in size from a small thin phamplet into something the size of the ZetaLisp or Interlisp tomes.  Received: from UTAH-20 by SU-AI with TCP/SMTP; 13 Oct 83 18:51:18 PDT Date: Thu 13 Oct 83 19:52:53-MDT From: William Galway Subject: Whoops (SETF and LAMBDAs) To: Common-Lisp@SU-AI.ARPA I guess I didn't make myself very clear in my previous message, so I'll try again. First, I'm talking about two related but distinct things, namely 1.) the lambda calculus 2.) Lisp. I picked a rather miserable example to illustrate what I want to do in the lambda calculus, so here's another try. The way I'd assign a value to an expression like ((lambda (x) (plus x 1)) 2) is to "evaluate (plus x 1) in an environment where `x' has the value 2". What I want to do is to extend this to the case where x isn't an atom. So to evaluate ((lambda ((sin x)) (cos x)) 1) I'd "evaluate (cos x) in an environment where the non-atomic expression `(sin x)' has the value 1". (I'm not necessarily claiming that "plus", "sin", "cos", "2", "1", have their typical meanings--I suppose it depends on what they're bound to.) With the usual meanings, I'd expect the value of the expression to be zero, and if we plugged 0 instead of 1 into the lambda, the result would be ambiguous, but either +1 or -1 should be valid "interpretations". In the case of Lisp, I was just thinking of LET as being a convenient shorthand for LAMBDA. So (let ( ((elt v 0) (length v))) v) is equivalent to ((lambda ((elt v 0)) v) (length v)) (or should that be a "(function (lambda ...))"? Anyway...) So, is that roughly what MacLisp's "destructuring LET" did? Something like SETF for lambdas, only without the idea that the LET actually expanded to a lambda? Let me also repeat that I'm not seriously suggesting implementation of this stuff (or non-implementation for that matter). I'm just interested in toying with the ideas (for now). Hope that clarifies what I was trying to get across. -- Will -------  Received: from MIT-MC by SU-AI with TCP/SMTP; 13 Oct 83 12:32:01 PDT Date: Thursday, 13 October 1983 14:39-EDT From: MOON at SCRC-TENEX To: William Galway Cc: Common-Lisp at SU-AI.ARPA Subject: SETF and LAMBDAs (semi-serious?) In-reply-to: The message of Thu 13 Oct 83 11:53:06-MDT from William Galway This was implemented in Maclisp under the name of "destructuring LET". It raises a number of complicated issues that I don't think we should get involved in right now. Note, as just one example, that you were not consistent with yourself in the examples you give of what it might do. Your first example (lambda (x) ((lambda ((y x)) (y x)) x)) seems to expect the argument to be a list of two elements, where y is bound to the first element and x is bound to the second. In other words the "pattern" in the lambda-expression is a piece of data acting as a template. Unless I misunderstand the example completely, which is possible since it certainly isn't written in Common Lisp. In your second example, (let ( ((elt v 0) (length v))) v) the "pattern" in the lambda-expression (a let this time) is a piece of code describing a location to be stored into. I won't even go into the deeper semantic issues raised by your second example; the syntactic issues are enough to show that it is complicated. Note that if you add a new special form (a macro) to the language, rather than redefining existing things such as let and lambda, you can experiment with various versions of such things in any Common Lisp implementation, or any other reasonable Lisp implementation, without any need to change the compiler, interpreter, or run-time.  Received: from UTAH-20 by SU-AI with TCP/SMTP; 13 Oct 83 10:51:37 PDT Date: Thu 13 Oct 83 11:53:06-MDT From: William Galway Subject: SETF and LAMBDAs (semi-serious?) To: Common-Lisp@SU-AI.ARPA All this discussion about the power of SETF has reminded me of an idea that I've been toying with for awhile. Basically, I'd like to modify the lambda calculus to allow non-atomic "arguments" for the lambda. So, in addition to things like: (lambda (x) (lambda (y) x)) (the K combinator, I think), it would also be legitimate to have things like: (lambda (x) ((lambda ((y x)) (y x)) x)) (which I think would be the identity function). I don't claim that there's any good reason for doing this--it just seemed like a natural thing to do during one of my weirder moments. If anyone knows if work has already been done with this funny variant of the lambda calculus, I'd be interested in hearing about it. On the other hand, if we leave the world of pure mathematical systems and enter the world of Lisp, it does kind of appeal to me to be able to write code like: (let ( ((elt v 0) (length v))) v) but, I'm not seriously suggesting that it be implemented... -- Will Galway -------  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 12 Oct 83 10:52:54 PDT Received: ID ; Wed 12 Oct 83 13:54:38-EDT Date: Wed 12 Oct 83 13:54:37-EDT From: LES@CMU-CS-C.ARPA Subject: Re: SETF and Prolog To: Meehan@YALE.ARPA cc: common-lisp@SU-AI.ARPA In-Reply-To: Message from "Jim Meehan " of Wed 12 Oct 83 09:50:24-EDT Assuming that x has the structure of a person, i.e. that you use a defstruct to define what a person is, then the setf form for the grandfather field is well defined. Something like: (defstruct person (:conc-name nil ...) . . (grandfather-of nil) . . ) Will make the supplied setf form entirely valid. -Lee -------  Received: from YALE by SU-AI with TCP/SMTP; 12 Oct 83 06:42:04 PDT Received: by YALE-BULLDOG via CHAOS; Wed, 12 Oct 83 09:45:40 EDT Date: Wed, 12 Oct 83 09:39:39 EDT From: Jim Meehan Subject: SETF and Prolog To: common-lisp@SU-AI.ARPA As long as you're doing (SETF (+ X 3) 10), why not use SETF as a notation for Prolog-style assertions? E.g., (SETF (GRANDFATHER-OF X) 'THOMAS). (-: There. We embedded it again. :-) -------  Received: from DEC-MARLBORO by SU-AI with TCP/SMTP; 8 Oct 83 07:28:42 PDT Date: Sat 8 Oct 83 10:29:44-EDT From: WVANROGGEN@DEC-MARLBORO.ARPA Subject: SETF madness To: Guy.Steele@CMU-CS-A.ARPA cc: common-lisp@SU-AI.ARPA This is going a bit too far. I can put up with a lot of the cute features Common Lisp has, but these last suggestions are just going to be too difficult to implement (at least on a Vax). I'd strongly recommend *against* these changes to the Excelsior edition. Instead, we ought to consider what users would really want. If Common Lisp is supposed to be a general, common language usable by everyone, we should provide something like: (setf (eval `(let* ((pretime (get-internal-real-time)) (precond <>)) ,@x (and precond <> (< pretime (+ (get-internal-real-time) <>))))) t) for user-supplied <>, <>, and <>. Implementors should be encouraged to design SETF so that it also meets these conditions (of course). ---Walter -------  Received: from MIT-XX by SU-AI with TCP/SMTP; 7 Oct 83 15:31:24 PDT Received: from SPA-RUSSIAN by SPA-Nimbus with CHAOS; Fri 7-Oct-83 15:29:53-PDT Date: Friday, 7 October 1983, 15:29-PDT From: Eric Benson Subject: SETF madness :-) To: Guy.Steele at CMU-CS-A, common-lisp at SU-AI In-reply-to: The message of 7 Oct 83 01:00-PDT from Guy.Steele at CMU-CS-A Date: 7 Oct 83 0400 EDT (Friday) From: Guy.Steele@CMU-CS-A Who needs DELETE-FILE? Just (MAKUNBOUND (TRUENAME stream)) ... (Clearly we need MAKUNBOUNDF.) No, we don't need MAKUNBOUNDF. Just make a small change in the definition of multiple values so that storing zero values is the same as making something unbound. Thus (MAKUNBOUND 'FOO) becomes (SETF (SYMBOL-VALUE 'FOO) (VALUES)) (FMAKUNBOUND 'FOO) becomes (SETF (SYMBOL-FUNCTION 'FOO) (VALUES)) (REMPROP 'FOO 'BAR) becomes (SETF (GET 'FOO 'BAR) (VALUES)) And another thing, why are multiple values restricted to come in non-negative integral quantities? We shouldn't unduly restrict users who may desire fractional, negative or complex numbers of values. Why is RANDOM restricted to numbers? I think it should be defined to return an arbitrary Lisp object at random. (For those of you with 3600s, try (%MAKE-POINTER (RANDOM 63.) (RANDOM (^ 2 28.))). Don't do it if you have any active buffers, though.)  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 6 Oct 83 04:32:38 PDT Delivery-Notice: While sending this message to SU-AI.ARPA, the CMU-CS-C.ARPA mailer was obliged to send this message in 50-byte individually Pushed segments because normal TCP stream transmission timed out. This probably indicates a problem with the receiving TCP or SMTP server. See your site's software support if you have any questions. Received: ID ; Thu 6 Oct 83 07:33:44-EDT Date: Thu 6 Oct 83 07:33:44-EDT From: Nedved@CMU-CS-C.ARPA Subject: please route To: Common-Lisp@SU-AI.ARPA Sigh. No "-Request" to send changes to without cluttering people's mail boxes. --------------- Date: Thu 6 Oct 83 02:21:54-EDT From: The Mailer Daemon To: NEDVED@CMU-CS-C.ARPA Subject: Message of 6-Oct-83 02:21:04 Message failed for the following: Common-Lisp-Request@SU-AI.ARPA: 550 I don't know anybody named Common-Lisp-Request ------------ Received: ID ; Thu 6 Oct 83 02:21:05-EDT Date: Thu 6 Oct 83 02:21:04-EDT From: Nedved@CMU-CS-C.ARPA Subject: please route To: Common-Lisp-Request@SU-AI.ARPA cc: Feinberg@CMU-CS-C.ARPA Please change Feinberg@CMU-CS-C to Feinberg%scrc-vixen@MIT-MC. Thanks! -Rudy A CMU Postmaster ------- ------- -------  Received: from MIT-ML by SU-AI with TCP/SMTP; 5 Oct 83 22:29:07 PDT Date: 6 October 1983 01:28 EDT From: Alan Bawden Subject: No No! Flush it!! To: HEDRICK @ RUTGERS cc: Common-Lisp @ SU-AI In-reply-to: Msg of 5 Oct 83 23:45:46 EDT from Charles Hedrick I wasn't sure whether I was kidding or not originally. I took a poll of those Lisp programmers who just happened to be here in the building, and recieved the mixed reviews you might expect. (Everything from "I like it! I like it!" to "You're crazy Bawden, it's a total loss", about evenly split.) I think I am now convinced that the idea could fly. BUT... I took a close look at the SETF method protocol documented on page 80 of the manual, and I believe that the mechanism is not powerful enought to cover a case like this one. It says: "The value returned by the accessing form is (of course) affected by execution of the storing form, but otherwise either of these forms may be evaluated any number of times, and therefore should be free of side effects (other than the storing action of the storing form)." All implementations that I have seen of this so far, including my own original one, have the property that they depend on this clause of the contract of a SETF method. I don't see how to implement SETF of POP without violating this clause. I DO think that I could redesign this stuff to handle this case, but I DON'T think Common Lisp should consider this extension at this time. You can all relax now.  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 6 Oct 83 01:26:31 PDT Received: from [128.2.254.192] by CMU-CS-PT with CMUFTP; 6 Oct 83 04:17:46 EDT Date: 6 Oct 83 0426 EDT (Thursday) From: Guy.Steele@CMU-CS-A To: common-lisp@SU-AI Subject: Really kidding, now (defsetf logand (x y) (newval) `(if (= (logand y newval) newval) (progn (setf ,x (logior newval (logand (random (expt 2 (max (integer-length ,newval) (integer-length ,y)))) (lognot y)))) ,newval) (error "Impossible setf."))) So then when you say (setf (logand x 12) 8) x will get set to some random value such that when it is anded with 12 you will get 8. (X might get set to 9 or 10, for example.) --Guy  Received: from MIT-ML by SU-AI with TCP/SMTP; 5 Oct 83 20:20:15 PDT Date: 5 October 1983 23:11 EDT From: Alan Bawden Subject: No No! Flush it!! To: Common-Lisp @ SU-AI It is a Common Lisp philosophy that we shold flush any storing functions where a SETF of an accessor will suffice. Well I suggest that we flush PUSH for this reason. Instead of (PUSH X (CAR Y)) programmers should be encouraged to write (SETF (POP (CAR Y)) X)!  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 6 Oct 83 00:13:38 PDT Received: ID ; Thu 6 Oct 83 03:15:34-EDT Date: Thu, 6 Oct 1983 03:15 EDT From: Scott E. Fahlman To: Guy.Steele@CMU-CS-A.ARPA Cc: common-lisp@SU-AI.ARPA Subject: You thought you were kidding In-reply-to: Msg of 6 Oct 83 0248 EDT () from Guy.Steele at CMU-CS-A Well, now I know how the Sorcerer's Apprentice felt when the brooms started schlepping water. (Or was that Mickey Mouse?) Please, nobody make any jokes about how to use SETF to launch the nuclear missiles -- Guy will try it and it will work. This is scary.  Received: from MIT-ML by SU-AI with TCP/SMTP; 5 Oct 83 21:12:38 PDT Date: 6 October 1983 00:06 EDT From: Glenn S. Burke Subject: No No! Flush it!! To: Fahlman @ CMU-CS-C cc: Common-Lisp @ SU-AI, ALAN @ MIT-MC Ahh, but if we use (setf (pop ...) ...) then we don't have to commit ourselves to the order of arguments to PUS, because we don't have one. p.s. When alan and i were talking about this, Carrette walked into the room and asked what kind of drugs were in the tea. I don't think Alan knows if he is serious.  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 7 Oct 83 01:01:15 PDT Received: from [128.2.254.192] by CMU-CS-PT with CMUFTP; 7 Oct 83 03:51:28 EDT Date: 7 Oct 83 0400 EDT (Friday) From: Guy.Steele@CMU-CS-A To: common-lisp@SU-AI Subject: SETF madness :-) Who needs UNREAD-CHAR? Just (SETF (READ-CHAR stream) char) and then (READ-CHAR stream) will return the char. Who needs RENAME-FILE? Just (SETF (TRUENAME stream) newname) ... Who needs DELETE-FILE? Just (MAKUNBOUND (TRUENAME stream)) ... (Clearly we need MAKUNBOUNDF.) And, of course, if you need to make the sun stand still for a while, you do (LET ((NOW (GET-UNIVERSAL-TIME))) (LOOP (SETF (GET-UNIVERSAL-TIME) NOW))) until you hit ^G. Who needs CHAR-UPCASE? Just put the character into the variable X, and then do (SETF (UPPER-CASE-P X) T). Presto change-o! What some implementations call KWOTE [ (DEFUN KWOTE (X) (LIST 'QUOTE X)) ] can be done as (SETF (EVAL X) Y) <=> (SETQ X (KWOTE Y)). Finally, who needs PARSE-INTEGER??? If X is a string, and you want to know what it means as an octal integer, just say (SETF (FORMAT NIL "~O" VAL) X) Simple, eh? --Quux  Received: from RUTGERS by SU-AI with TCP/SMTP; 5 Oct 83 20:44:11 PDT Date: 5 Oct 83 23:45:46 EDT From: Charles Hedrick Subject: Re: No No! Flush it!! To: ALAN%MIT-MC@MIT-ML.ARPA cc: Common-Lisp@SU-AI.ARPA In-Reply-To: Message from "Alan Bawden " of 5 Oct 83 23:11:00 EDT One of the reasons that I am suspicious about Common Lisp's design is that I can never be sure when people are serious and when they are spoofing me. I would like to think that the idea of turning PUSH into (SETF (POP was a joke. But there is enough doubt that I am going to answer it as if it were serious. I think of SETF as being used to put values into "fields" of data structures. I am prepared to think of (CAR X) as being a field, and I can even imagine (GET X Y) as one, though I think that is pushing it. (Certainly our Common Lisp will have PUTPROP.) But PUSH simply pushes me beyond my ability to think in those terms. Among other things, it has sideeffects. And (SETF (POP suggests the wrong sideeffects, unless you think hard. Please tell me you weren't serious. -------  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 5 Oct 83 20:52:30 PDT Received: ID ; Wed 5 Oct 83 23:53:55-EDT Date: Wed, 5 Oct 1983 23:53 EDT From: Scott E. Fahlman To: Alan Bawden Cc: Common-Lisp@SU-AI.ARPA Subject: No No! Flush it!! In-reply-to: Msg of 5 Oct 1983 23:11 EDT from Alan Bawden Bawden is misinformed. Common Lisp has no philosophy. We are held together only by a shared disgust for all the alternatives. -- Scott  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 5 Oct 83 22:52:28 PDT Received: ID ; Thu 6 Oct 83 01:53:56-EDT Date: Thu, 6 Oct 1983 01:53 EDT From: Scott E. Fahlman To: Alan Bawden Cc: Common-Lisp@SU-AI.ARPA Subject: No No! Flush it!! In-reply-to: Msg of 6 Oct 1983 01:28 EDT from Alan Bawden (-: Gee, and while we're at it we can flush things like (setq x (sqrt 2)) and just go for (setf (* x x) 2). Now if I can figure out how to do matrix inversion by feeding this thing multiple values... :-)  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 5 Oct 83 23:51:21 PDT Received: from [128.2.254.192] by CMU-CS-PT with CMUFTP; 6 Oct 83 02:39:54 EDT Date: 6 Oct 83 0248 EDT (Thursday) From: Guy.Steele@CMU-CS-A To: Scott E. Fahlman Subject: You thought you were kidding CC: common-lisp@SU-AI In-Reply-To: "Scott E. Fahlman's message of 6 Oct 83 00:53-EST" )-: Well, maybe we can't use setf to get sqrt, but: (defsetf * (x &rest y) (newval) `(progn (setf ,x (/ ,newval ,@y)) ,newval)) (setf (* x 4) 24) => 24 and now x => 6 I just tried this in VAX Common LISP. It works fine. --Guy  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 28 Sep 83 20:17:03 PDT Received: from [128.2.254.192] by CMU-CS-PT with CMUFTP; 28 Sep 83 23:07:53 EDT Date: 28 Sep 83 2321 EDT (Wednesday) From: Guy.Steele@CMU-CS-A To: Glenn S. Burke Subject: Burke's remarks on THROW and MAP CC: common-lisp@SU-AI In-Reply-To: "Glenn S. Burke's message of 28 Sep 83 14:41-EST" I believe that it would be acceptable to perform THROW in the following order: (1) evaluate tag (2) search for catcher (3) evaluate results (4) perform unwind However, this order would not be acceptable: (1) evaluate tag (2) search for catcher (3) perform unwind (4) evaluate results The point is that the results are calculated in the dynamic environment (that includes special variables and catchers) of the THROW, bot that of the CATCH. (Sorry, "not" that of the CATCH.) --Guy  Received: from MIT-ML by SU-AI with TCP/SMTP; 28 Sep 83 13:52:12 PDT Date: 28 September 1983 15:41 EDT From: Glenn S. Burke Subject: THROW, and MAP To: Moon%SCRC-TENEX @ MIT-MC cc: Common-Lisp @ SU-AI, JonL.pa @ PARC-MAXC Received: from MIT-MC by SU-AI with TCP/SMTP; 27 Sep 83 16:49:07 PDT Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Tue 27-Sep-83 19:29:12-EDT Date: Tuesday, 27 September 1983, 19:50-EDT From: David A. Moon In-reply-to: The message of 27 Sep 83 18:51-EDT from JonL.pa at PARC-MAXC The syntax (you mean semantics?) of THROW is not the same as of functions, since it sees all the values resulting from evaluating its second subform. I vote for the subforms both being evaluated before the search for a matching tag commences, since it seems simpler for both user-understanding and implementation ease. . . . In my implementation of multiple values, it may be beneficial for me to do the search first in order to find the eventual destination of the values. I'm haven't gotten into this stuff enough to know whether i actually would want to do it this way even if given the liberty, however.  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 28 Sep 83 08:29:11 PDT Received: from [128.2.254.192] by CMU-CS-PT with CMUFTP; 28 Sep 83 11:18:46 EDT Date: 28 Sep 83 1127 EDT (Wednesday) From: Guy.Steele@CMU-CS-A To: JonL.pa@PARC-MAXC Subject: THROW, again CC: common-lisp@SU-AI In-Reply-To: "JonL.pa@PARC-MAXC.ARPA's message of 27 Sep 83 17:51-EST" Scratch my explanations of why THROW is a special form. Moon had the right answer (multiple values from a single argument form). I feel silly for neglecting that point.  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 28 Sep 83 08:28:29 PDT Received: from [128.2.254.192] by CMU-CS-PT with CMUFTP; 28 Sep 83 11:18:27 EDT Date: 28 Sep 83 1124 EDT (Wednesday) From: Guy.Steele@CMU-CS-A To: JonL.pa@PARC-MAXC Subject: Re: THROW, and MAP CC: common-lisp@SU-AI In-Reply-To: "JonL.pa@PARC-MAXC.ARPA's message of 27 Sep 83 17:51-EST" Your point about THROW is well-taken, and I will try to improve the prose. I think that THROW was made into a special form because, although all arguments are evaluated and thus from that point of view it could be treated as a function, THROW has some bizarre side effects (namely transfer of control) and most program-processing programs will probably need to treat it as a special form anyway. (Maybe that's wrong; maybe it just happened somewhat accidentally as we gyrated through various versions of throws and catches.) As for MAP, I honestly don't see what being a macro or a function has to do with pinning down its behavior when a list being mapped over is modified; either a macro or a function could have the surprising behavior, and in either case the desription must be more precise. Now, the question of whether MAP should be a function or a macro is in itself an interesting and debatable question. It doesn't need to be a macro for the sake of compiled code, because a compiler is free to compile it inline unless specifically directed not to do so (with a notinline declaration). MacLISP does this kind of inline compilation already. As you pointed out, the RETURN-FROM technology allows Common LISP to avoid some of the PROG-capture anomalies that occurred in MacLISP. I will point out that in some styles of programming it is useful to be able to APPLY MAP (or even to MAP a MAP)! Concerning LOOP, the Common LISP LOOP construct is compatible with the LISP Machine LOOP construct. There is a sentence which carefully makes the semantics of Common LISP's LOOP undefined if any form in the construct is a symbol (it should say atom). So every valid Common LISP LOOP must contain only non-atomic forms, and in this case the LISP Machine LOOP has the same semantics as the Common LISP LOOP. So any implementation is free to implement the entire LISP Machine LOOP stuff and claim it is compatible with Common LISP; it just won't necessarily be portable if you use the hairier features.  Received: from PARC-MAXC by SU-AI with TCP/SMTP; 27 Sep 83 19:42:32 PDT Date: 27 SEP 83 19:38 PDT From: JONL.PA@PARC-MAXC.ARPA Subject: Re: THROW, and MAP To: Moon%SCRC-TENEX@MC.ARPA, JonL.pa@MC.ARPA cc: Common-Lisp@SAIL.ARPA, JONL.PA@PARC-MAXC.ARPA In response to the message sent Tue, 27 Sep 83 19:50 EDT from Moon%SCRC-TENEX@MIT-MC.ARPA Syntax/Semantics -- either way I had overlooked the multiple-value thing (being confined to a system which, for the moment, doesn't have them). Yes, I'd like to see the evaluation question settled that way -- that's how I've already implemented an Interlisp version -- but I'd be quite happy to go the other way if the majority so voted.  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 27 Sep 83 17:21:58 PDT Received: ID ; Tue 27 Sep 83 20:24:23-EDT Date: Tue, 27 Sep 1983 20:24 EDT From: Scott E. Fahlman To: Common-Lisp@SU-AI.ARPA Subject: THROW, and MAP In-reply-to: Msg of 27 Sep 1983 19:50-EDT from David A. Moon I agree with Moon on both counts: THROW shold eval both its args before searching for the tag (it is very awkward to implement it the other way), and we all are eager to see Moon's new polished LOOP proposal rather than rushing to implement the old one. Even we reactionaries are about ready to accept something along these lines, but I'd like it to be as uncluttered as possible. -- Scott  Received: from MIT-MC by SU-AI with TCP/SMTP; 27 Sep 83 16:49:07 PDT Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Tue 27-Sep-83 19:29:12-EDT Date: Tuesday, 27 September 1983, 19:50-EDT From: David A. Moon Subject: THROW, and MAP To: JonL.pa@PARC-MAXC Cc: Common-Lisp@SU-AI In-reply-to: The message of 27 Sep 83 18:51-EDT from JonL.pa at PARC-MAXC Date: Tue, 27 Sep 83 15:51 PDT From: JonL.pa@PARC-MAXC.ARPA Excelsior edition's commentary on THROW doesn't make clear whether the evaluation of the 'result' form is to take place before or after the tag-search. If before, then the syntax of THROW is merely that of 'function'. If after, then that must be spelled out, so that side-effects in the 'result' computation won't occur when there is a tag-search failure. The syntax (you mean semantics?) of THROW is not the same as of functions, since it sees all the values resulting from evaluating its second subform. I vote for the subforms both being evaluated before the search for a matching tag commences, since it seems simpler for both user-understanding and implementation ease. LOOP in its current definition (p93) seems to preclude the nice MacLisp/LispM LOOP macro. In the excelsior edition LOOP was fixed to not preclude that macro. (It used to be defined in such a way that the hairy LOOP macro was not a consistent extension of Common Lisp's simple builtin one.) But the hair LOOP macro is not included in the white pages. This is partly my fault since years ago I promised to come up with a second generation of LOOP that would fix a lot of the problems people have complained about. In fact I did most of the design and circulated it to a number of people, but the thing has been on the back burner for a long time due to other responsibilities. It probably wouldn't be hard to make the existing LOOP run in Common Lisp as a yellow pages package, although I for one would much rather have the nicer new one. The motivation for finishing this project (either by me or by someone else, I don't care) will probably become a lot higher in a half year or so as we start to see some "real live" Common Lisp implementations with actual users. I agree that it is quite impractical to try to do without some form of complex iteration generator, whether it be the Interlisp one, the Maclisp one, or my pie in the sky new one. Dick Water's LetS package should definitely be made to run in Common Lisp as well.  Received: from PARC-MAXC by SU-AI with TCP/SMTP; 27 Sep 83 16:20:33 PDT Date: Tue, 27 Sep 83 15:51 PDT From: JonL.pa@PARC-MAXC.ARPA Subject: THROW, and MAP To: Common-Lisp@SU-AI.ARPA THROW Excelsior edition's commentary on THROW doesn't make clear whether the evaluation of the 'result' form is to take place before or after the tag-search. If before, then the syntax of THROW is merely that of 'function'. If after, then that must be spelled out, so that side-effects in the 'result' computation won't occur when there is a tag-search failure. MAP All the recent discussion about "what happens if the mapped function updates the list it is mapping over" points up the non-primitive nature of the map series of "functions". Admittedly, the WhitePages aren't the place to try to distinguish a truly-primitive kernel from the common, portable subset, but a simple change from [Function] to [Macro] on the map entries would forclose a lot misguided babbling. Given that CommonLisp has RETURN-FROM and named BLOCKs, a macro- expansion of the mappers need not be concerned with "prog context". Is there any reason for continuing to push the primality of the map series over a reasonable macro definition? More to the point, sigh, is the lack of any reasonable iteration control structure. MacLisp DO just doesn't "cut the mustard". DOTIMES and DOLIST are too-little, too-late. LOOP in its current definition (p93) seems to preclude the nice MacLisp/LispM LOOP macro. Foo. Having used Interlisp's I.S.OPRS for some time now, I often wonder how one can get along without it. The objection to a reasonable form of LOOP can hardly be that it is "new", since it is essentially a modest variant of Interlisp's I.S.OPRS which has had 10-years of extensive use. Nor should the objection be that old "cop out" that its syntax isn't "Lispy" enough [or, as the last paragraph on page 99 almost says, "... as if it were impossible to write programs without Lots-of-Interminable-Silly-Parentheses"]  Received: from MIT-MC by SU-AI with TCP/SMTP; 22 Sep 83 20:49:32 PDT Date: 22 September 1983 23:52 EDT From: Alan Bawden Subject: behavior of mapping To: Common-Lisp @ SU-AI, HEDRICK @ RUTGERS In-reply-to: Msg of 22 Sep 83 17:51:30 EDT from Charles Hedrick Date: 22 Sep 83 17:51:30 EDT From: Charles Hedrick ... But there are some assumptions that we know from experience are made so universally that we ought to at least consider that the users might be right and we might be wrong.... it would be irresponsible to leave in something I know will cause most users to write untransportable programs, ... I can tell you from experience that users do in fact depend upon the exact semantics of mapping functions.... "will cause MOST users to write untransportable programs"? I don't think I have EVER met a user who depended this closely on the exact semantics of any function that takes a functional argument. In fact, my experience has been that users generally exhibit good sense about such issues. I suggest that that good sense be reinforced by inserting a paragraph in the manual explaining briefly that functions that take functional arguments generally will behave unpredictable if their arguments are diddled before they are done with them.  Received: from RUTGERS by SU-AI with TCP/SMTP; 22 Sep 83 14:49:39 PDT Date: 22 Sep 83 17:51:30 EDT From: Charles Hedrick Subject: behavior of mapping To: common-lisp@SU-AI.ARPA Yes, I realize that it is possible to carry transportability to an extreme. Obviously we cannot protect users against every possible assumption they might make. But there are some assumptions that we know from experience are made so universally that we ought to at least consider that the users might be right and we might be wrong. I agree that I can't possibly guarantee that all code will be transportable. But it would be irresponsible to leave in something I know will cause most users to write untransportable programs, unless there are very strong reasons indeed. I have been involved in Lisp development and support for a number of years. I can tell you from experience that users do in fact depend upon the exact semantics of mapping functions. I believe this is one of the cases where the users' expectations are so universal that the implementors should bow to them. -------  Received: from MIT-ML by SU-AI with TCP/SMTP; 22 Sep 83 14:23:45 PDT Received: from SPA-LOS-TRANCOS by SPA-Nimbus with CHAOS; Thu 22-Sep-83 14:24:41-PDT Date: Thursday, 22 September 1983, 14:24-PDT From: Eric Benson Subject: Re: implied contracts in the mapping functions? To: Daniel L. Weinreb , HEDRICK at RUTGERS, kmp%MIT-MC at MIT-ML Cc: Cassels%SCRC-TENEX at MIT-ML, Fahlman%CMU-CS-C at MIT-ML, Common-Lisp%SAIL at MIT-ML In-reply-to: The message of 22 Sep 83 12:27-PDT from Daniel L. Weinreb Date: Thursday, 22 September 1983, 15:27-EDT From: Daniel L. Weinreb Date: 19 Sep 83 16:07:49 EDT From: Charles Hedrick It is dangerous to have a feature that obviously ought to be in a language not be there, or be there in only half the implementations. No matter what you say in the manual, people will use it where it works. I strongly disagree. It is completely unavoidable that some people will depend on the peculiarities of any implementation. It does not follow that every peculiarity should be a defined part of Common Lisp that every implementation must follow. If we are to belive what you are saying, then EVERY place in the manual that says "it is an error" should be changed to either say "it signals an error" or else be precisely defined. And of course that's only the beginning. The only way to ensure that every implementation has exactly the same behavior is to define a very low-level virtual machine and write the entire system in terms of it. Then there would truly be one Common Lisp, and any program which ran on one version would run on any other. This is how UCSD Pascal is defined, for example. Programs can be compiled on Z80's and run on 6502's. This is not the goal of the Common Lisp language definition as I understand it, however. I believe the intention is similar to that of Standard Lisp, to define an @i(interchange subset). Programs which rely only on the behavior described in the manual will run on any Common Lisp implementation. No machine can enforce the Common Lisp standard, although automated tools can of course aid the programmer in adhering to it.  Received: from MIT-ML by SU-AI with TCP/SMTP; 22 Sep 83 12:25:00 PDT Received: from SCRC-SHEPHERD by SCRC-TENEX with CHAOS; Thu 22-Sep-83 15:26:39-EDT Date: Thursday, 22 September 1983, 15:27-EDT From: Daniel L. Weinreb Subject: Re: implied contracts in the mapping functions? To: HEDRICK@RUTGERS, kmp%MIT-MC@MIT-ML Cc: Cassels%SCRC-TENEX@MIT-ML, Fahlman%CMU-CS-C@MIT-ML, Common-Lisp%SAIL@MIT-ML In-reply-to: The message of 19 Sep 83 16:07-EDT from Charles Hedrick Date: 19 Sep 83 16:07:49 EDT From: Charles Hedrick It is dangerous to have a feature that obviously ought to be in a language not be there, or be there in only half the implementations. No matter what you say in the manual, people will use it where it works. I strongly disagree. It is completely unavoidable that some people will depend on the peculiarities of any implementation. It does not follow that every peculiarity should be a defined part of Common Lisp that every implementation must follow. If we are to belive what you are saying, then EVERY place in the manual that says "it is an error" should be changed to either say "it signals an error" or else be precisely defined.  Received: from PARC-MAXC by SU-AI with TCP/SMTP; 21 Sep 83 15:05:52 PDT Date: 21 Sep 83 15:07 PDT From: masinter.pa@PARC-MAXC.ARPA Subject: Portability and performance, standards and change To: Common-Lisp@SU-AI.ARPA The multiple goals in language design of portability and high performance, standard definitions and the ability to change system definitions are often in conflict. You sometimes have to give up one to get the other. The primary goal of Common-Lisp (above and beyond Franz, NIL, LispM etc) was to be COMMON. Further along the road to allowing each implementor to decide the exact semantics of MAPC lies the current proliferation of MacLisp dialects. Nailing down what the mapping functions do in the presence of structure modification on the argument list may (a) result in performance degradations in some cases and (b) tie you to design decisions that you will wish later that you could change, but those are in fact the real costs of standardization and portability. If standardization and portability are precisely the problem with Interlisp (as Moon put it), they are also its strengths. If you have a STANDARD, then you can't go off and change the semantics of your implementation without in fact changing the STANDARD. Leaving it unspecified or saying "it is an error" does not avoid the issue. It merely increases the number of programs which will not transfer from one "common" lisp to another (or even from one release to the next, if Moon really meant what I thought he did) without tracking down dependence on features which are not detectable by static or runtime analysis.  Received: from MIT-MC by SU-AI with TCP/SMTP; 21 Sep 83 14:00:48 PDT Date: 21 September 1983 17:02 EDT From: Kent M. Pitman Subject: definition/errors/... To: DLW @ MIT-MC cc: Common-Lisp @ SU-AI I spoke with ALAN at length about this the other day. He made a point which I think is significant -- We should not be worrying about whether this particular feature is good/bad or and error or undefined. We should be worrying about why. Otherwise, we'll be doomed to simply repeat this sort of discussion ad nauseum every time someone encounters someone with poor or questionable programming style using any powerful operator. So while I respect that you think it's an error, I think the only really relevant question is "What in the language spec makes it so, and how can we write future specs to try to avoid this sort of problem without precluding creative and reasonable uses of powerful operators?"  Received: from MIT-MC by SU-AI with TCP/SMTP; 21 Sep 83 13:36:43 PDT Received: from SCRC-SHEPHERD by SCRC-TENEX with CHAOS; Wed 21-Sep-83 16:40:39-EDT Date: Wednesday, 21 September 1983, 16:41-EDT From: Daniel L. Weinreb Subject: implied contracts in the mapping functions? To: common-lisp@SU-AI Cc: GSB@MIT-ML I agree: it is an error. Programs should not be depending on the internals of mapping functions.  Received: from USC-ISIB by SU-AI with TCP/SMTP; 19 Sep 83 14:15:35 PDT Date: 19 Sep 1983 1416-PDT Subject: Re: "optimizations" From: Dave Dyer To: Bernard S. Greenberg , DDYER@USC-ISIB.ARPA, common-lisp@SU-AI.ARPA In-Reply-To: Your message of Monday, 19 September 1983, 11:07-EDT From: Dave Dyer There should be only ONE implementation of the mapping functions, From: Bernard S. Greenberg I disagree with this view fairly strongly. Different implementations have different instruction sets and primitives, and what appears to be an optimal macro expansion for one implementation is often not so for another. If a different actual implementation is better for some machine, then the implementor is free to substitute an equivalent one, provided it is really equivalent. It is exactly the desire to optimize each implementation at the expense of "minor" incompatability that in aggregate makes putatively compatable languages incompatable, be it Lisp of Fortran. I don't really believe that specification by implementation is ideal, just that it is the only reliable mechanism. No prose specification can capture the full subtlety of MAPCAR. To be sure, there should be a prose specification first, and the prose should remain the ultimate arbiter of what is correct; but ONE program, written to be faithful to the spec, should be the arbiter of what is an acceptable implementation. If two implementations of the same specification behave differently in ways not explicitly permitted by the specification, then at least one of them is wrong. The laser edition of the manual states in its description of MAP: "... The result sequence is as long as the shortest of the input sequences. If the FUNCTION has side effects, it can count on being called first with all elements numbered zero, and then on all elements numbered one and so on. ..." Now, I can see that the natural behavior when FUNCTION modifies one of the input sequences will be quite different when the input sequence is an array verses when it is a list; In fact there are too many to ennumerate. (examples: an array-type sequence probably has a known length. Is it legal to assume the length won't change? Mapping over a list-type sequence is "naturally" unaffected by changes to the elements already processed, whereas array-type sequences might "naturally" skip or repeat elements if a new element is removed or added at the beginning.) Confronted with this variability, the current spec is inadequate. One extreme position to correct the spec would be to make it read: "Side effects which change the number of elements in a sequence have unpredictable effects on the execution sequence." Which would simply define a large grey area. An opposite extreme might read "Side effects which change the number of elements in a sequence are immediately effective; The N'th call to the user's function will be with the elements which are N'th in the source sequences at the time of the call." Which would define an explicit descipline: one quite different from the customary MAP but possibly more appropriate for arrays. A third proposal might read: "Side effects which change the number of elements are well defined provided that only elements not yet encountered by the iteration are changed." This would allow adding or dropping elements from the REST of the list but not changing the part already processed. Finally, one might have: "Side effects which change the number of elements in a sequence are immediately effective; the iteration proceeds by using the the successor of element used on the previous iteration" Which corresponds to the usual definition of MAP, but might be inconvenient for sequences implemeted by arrays. ---- I have two conclusion points. First, that given this discovery of a hole in the specification, we have to change the specification to correct it, even if that is to simply mark the hole. Second, that given the subtle ways that reasonable implementations might vary, there should be a standard implementation that meets the spec and that all the implementors agree to use (or at least be compatable with). This naturally constrains implementors freedom to choose representation and algorithm, and will sometimes extract significant performance penalties, but is part of the price of portability. Implementors are free to provide nonstandard extensions they consider to be better, but only in upward compatable ways. -------  Received: from MIT-ML by SU-AI with TCP/SMTP; 19 Sep 83 13:07:32 PDT Date: 19 Sep 83 16:07:49 EDT From: Charles Hedrick Subject: Re: implied contracts in the mapping functions? To: kmp%MIT-MC@MIT-ML.ARPA cc: Cassels%SCRC-TENEX@MIT-ML.ARPA, Fahlman%CMU-CS-C@MIT-ML.ARPA, Common-Lisp%SAIL@MIT-ML.ARPA In-Reply-To: Message from "Kent M. Pitman " of 18 Sep 83 20:37:17 EDT It is dangerous to have a feature that obviously ought to be in a language not be there, or be there in only half the implementations. No matter what you say in the manual, people will use it where it works. You should either define what NCONC to a list being mapped does, or strongly suggest that its use be made an error that is detected. Since I don't know how to do the latter, I suggest the former. -------  Received: from MIT-MC by SU-AI with TCP/SMTP; 19 Sep 83 12:31:33 PDT Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Mon 19-Sep-83 15:24:45-EDT Date: Monday, 19 September 1983, 15:23-EDT From: David A. Moon Subject: Implicit contracts To: Rob MacLachlan Cc: common-lisp@SU-AI In-reply-to: The message of 19 Sep 83 08:50-EDT from Rob MacLachlan Date: Mon, 19 Sep 1983 08:50 EDT From: Rob MacLachlan I think that the specification of a language by implementation as implied by Dyer's message is an extremely bad idea. If it is legal to depend on any possible behavior of a function then it becomes impossible to ever change any function because someone might depend on a particular idiosyncratic behavior. Precisely the problem that Interlisp has. It seems to me that the best approach in Common Lisp is to have that manual describe every important behavior of an operation, and for any code which depends on something not guaranteed by the manual to be considered erroneous. As far as assuring agreement with the manual, I think that the best solution would be to have a comprehensive validation suite, or lacking that, a number of large portable applications. I am in complete agreement with this. We should definitely have a comprehensive validation suite. Even one that isn't comprehensive would be helpful. I wrote one for the division-related functions (/, mod, floor, etc.), but that is hardly a drop in the bucket.  Received: from MIT-MC by SU-AI with TCP/SMTP; 19 Sep 83 08:11:49 PDT Received: from SCRC-BEAGLE by SCRC-TENEX with CHAOS; Mon 19-Sep-83 11:08:25-EDT Date: Monday, 19 September 1983, 11:07-EDT From: Bernard S. Greenberg Subject: "optimizations" To: DDYER@USC-ISIB, common-lisp@SU-AI In-reply-to: The message of 19 Sep 83 06:31-EDT from Dave Dyer Date: 19 Sep 1983 0331-PDT From: Dave Dyer There should be only ONE implementation of the mapping functions, written in unambiguous primitives, shared by all common lisp implementations. Likewise for the largest possible subset of the core language. This is the best way to make sure that the zillion+1 small implementation choices one has to make, even working from the tightest specification, are made the same way by all the implementations. I disagree with this view fairly strongly. Different implementations have different instruction sets and primitives, and what appears to be an optimal macro expansion for one implementation is often not so for another. It is best to specify the contracts of one of these goddamn things by documentation, driven from need of what problem the function or form at hand was supposed to solve, not by code that nails its implementation so that you can find delightful and challenging ways to undercut its intended purpose.  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 19 Sep 83 05:47:58 PDT Received: ID ; Mon 19 Sep 83 08:50:49-EDT Date: Mon, 19 Sep 1983 08:50 EDT From: Rob MacLachlan To: common-lisp@SU-AI.ARPA Subject: Implicit contracts I think that the specification of a language by implementation as implied by Dyer's message is an extremely bad idea. If it is legal to depend on any possible behavior of a function then it becomes impossible to ever change any function because someone might depend on a particular idiosyncratic behavior. It seems to me that the best approach in Common Lisp is to have that manual describe every important behavior of an operation, and for any code which depends on something not guaranteed by the manual to be considered erroneous. As far as assuring agreement with the manual, I think that the best solution would be to have a comprehensive validation suite, or lacking that, a number of large portable applications. Rob  Received: from USC-ISIB by SU-AI with TCP/SMTP; 19 Sep 83 03:35:19 PDT Date: 19 Sep 1983 0331-PDT Subject: "optimizations" From: Dave Dyer To: common-lisp@SU-AI.ARPA I agree strongly that vague arguments about optimizatons are a bad idea. The only optimizations permitted should be those proven to not affect the semantics of the program. I have seen too many cases where seemingly harmless optimizations cause subtle bugs when the user's program does something unusual. In the current case, mapping functions should certainly be required to conform to the reasonale expectation of the user that a NCONC will work. If permitted, this kind of incompatability is exactly what will make common lisp non-portable. Saving a cycle or two just isn't worth the dirtyness of explaining to the user why a NCONC won't always work and what to avoid. I am reminded of Larry Masinter's golden words: "I don't believe in portability in the absence of porting" There should be only ONE implementation of the mapping functions, written in unambiguous primitives, shared by all common lisp implementations. Likewise for the largest possible subset of the core language. This is the best way to make sure that the zillion+1 small implementation choices one has to make, even working from the tightest specification, are made the same way by all the implementations. -------  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 18 Sep 83 21:57:53 PDT Received: ID ; Mon 19 Sep 83 01:00:28-EDT Date: Mon, 19 Sep 1983 01:00 EDT From: Scott E. Fahlman To: Kent M. Pitman Cc: Common-Lisp@SU-AI.ARPA Subject: implied contracts in the mapping functions? In-reply-to: Msg of 18 Sep 1983 19:50-EDT from Kent M. Pitman Vague arguments about possible optimizations are also a bad idea. I disagree. It should be clear that this sort of thing rules out a very large class of possible optimizations -- basically, all those optimizations that would depend on some property of the input list, such as its length or the type of elements present. If we allow the user's functionals to mutilate this list after it is passed in, any highly optimizing compiler would have to check these functionals for destructive side-effects on the list, a much more difficult task in most cases. Generally, I would like to see optimizations shaped by linguistic considerations, not linguistic considerations shaped by optimizations. OK, how about the following: When you pass an object to a Common Lisp function or special form whose job it is to process that object in some coherent manner, it HAS to be undefined what happens if you somehow regain control (perhaps because the form is executing a function on your behalf) and destructively modify that object in the middle of the operation. I see no way to make this coherent in general. Therefore to allow a few simple cases of it (chewing only on the as-yet-unprocessed tail of a list being chewed linearly) would be an ugly hack. Multi-processing is not addressed by the Common Lisp design and trying to imagine what it would look and use that as a basis for argument seems much more bizarre to me than worrying about what "vague optimizations" some future super-compiler for the existing language would want to employ. -- Scott  Received: from MIT-ML by SU-AI with TCP/SMTP; 18 Sep 83 16:24:05 PDT Received: from SCRC-EUPHRATES by SCRC-TENEX with CHAOS; Sun 18-Sep-83 19:12:49-EDT Date: Sunday, 18 September 1983, 18:47-EDT From: David A. Moon Subject: implied contracts in the mapping functions? To: Glenn S. Burke Cc: common-lisp@SU-AI In-reply-to: The message of 17 Sep 83 21:12-EDT from Glenn S. Burke Date: 17 September 1983 21:12 EDT From: Glenn S. Burke I would appreciate comments on the following "bug report" i just received. I am iterating over a list and simultaneously adding things to the end of the list with NCONC. It works fine until I get down to the final iteration. I don't think the language should define what happens in this case (even though it "works" in my implementation, as it happens). Such iterations should be written in terms of lower-level primitives, such as DO or TAGBODY+SETQ.  Received: from MIT-ML by SU-AI with TCP/SMTP; 18 Sep 83 17:32:09 PDT Date: Sunday, 18 September 1983, 19:50-EDT From: Kent M. Pitman Subject: implied contracts in the mapping functions? To: Cassels at SCRC-TENEX, "Fahlman%CMU-CS-C" at MIT-ML Cc: "Common-Lisp%SAIL" at MIT-ML In-reply-to: The message of 17 Sep 83 23:08-EDT from Robert A. Cassels , The message of 17 Sep 83 21:23-EDT from Scott E. Fahlman , The message of 17 Sep 83 21:12-EDT from Glenn S. Burke Date: Saturday, 17 September 1983, 23:08-EDT From: Robert A. Cassels Date: Sat, 17 Sep 1983 21:23 EDT From: Scott E. Fahlman I think that "it is an error" to destructively mess around with a list after it has been fed to MAPCAR or even to DOLIST. The fact that most implementations would do this in a certain way and the user can guess what that way is should not matter. If we let people twiddle hidden state and count on the results, there will be no safe optimizations left, and all Common Lisp implementations will slow down by a considerable factor. I agree that it ought to be "an error" or left undefined (implementation-dependent). Other languages with looping constructs have run into this problem, and most have decided to admit that there is "hidden state" which is implementation-dependent. I disagree. Arguments that other languages do x or y prove nothing. Many other languages are just plain afraid of anything. Or they may have sufficiently different data structures and types that this is reasonable. I'd want concrete examples of design criteria from specific languages before buying a follow-the-leader argument. Vague arguments about possible optimizations are also a bad idea. I would like to hear such arguments. Generally, I would like to see optimizations shaped by linguistic considerations, not linguistic considerations shaped by optimizations. Certainly without specific examples of the kinds of optimizations you want to make, how can I understand the consequences of those optimizations... While programmers are prone to occassional errors in judgment, I think it is important to recognize systematic "errors" that they make and ask why they make them. For example, it was never a documented feature of APPEND that it would copy its first N arguments, but people still used to write (APPEND x NIL) to cause copying to happen. There is the small issue of whether the program was going to do (IF (NULL Y) X) (REALLY-APPEND X Y)) because that would screw them but that was their only `real' error. The other assumption (that REALLY-APPEND would really copy X) was not really just an assumption; it was pretty much forced by the contract of APPEND. So it isn't as unsafe as it looks at first glance. Likewise, I think, for MAPCAR, etc. The bug GSB mentioned was one where the guy lost because he let the NCONC get too close to the point you were scanning with the map, but the basic theory that you could bash something farther down the line was sound. Now in the case of (APPEND x NIL), people got smart and just made a subroutine, COPYLIST, for what really needed to be done. But in the case of this NCONCing onto lists that are being mapped, I don't really think we can package it quite so simply... Also, I don't think it is ever an ERROR (signalled or otherwise) for a user to modify later structure. At worst, it should be nondeterministic with respect to the algorithm. I could imagine a case with mapping down a list of integers numbers which you are simulataneously NCONCing with new integers and splicing non-primes out of and using as a sieve where it might actually be reasonable to not worry whether the mapping operator actually noticed the splice. In one case, it might take slightly longer because more numbers might be tested than were really necessary, but in the case I'm thinking of, it would not and should not affect the correctness of the algorithm and the programmer shouldn't take grief from other programmers about how it was an "error" to think that way. And I really think that there may be cases where efficiency considerations may call for me to write something which has a tail which is known to be more than a threshold distance from the list which is being mapped. I only think we should even say it is undefined for the programmer to try to modify the current cell (ie, if I am looking at the D in (A B C D), I should not expect that NCONCing the list would matter), but I think it is reasonable for a programmer to assume that if he's looking at the C, that the list can be NCONC'd. This is important to the Lisp programmer's view of lists as modifiable, shared structure. I think we should carefully define the unusual situations, but I think it's overly restrictive to really define that modifying any part of the list after the part under inspection is an error... One side light -- Any system with multi-processing is fairly likely at one time or another to have GET going on in one process while PUTPROP is going on in another process for the same symbol -- perhaps not for the same indicator. We surely don't want people claiming this is erroneous and that we need to lock property lists since for most applications, the programmer will (at least should) hand-lock any cases that matter and the rest should just take what comes.  Received: from MIT-MC by SU-AI with TCP/SMTP; 17 Sep 83 20:10:11 PDT Received: from SCRC-MUDDY by SCRC-TENEX with CHAOS; Sat 17-Sep-83 23:09:56-EDT Date: Saturday, 17 September 1983, 23:08-EDT From: Robert A. Cassels Subject: implied contracts in the mapping functions? To: Fahlman@CMU-CS-C, GSB@MIT-ML Cc: common-lisp@SU-AI In-reply-to: The message of 17 Sep 83 21:23-EDT from Scott E. Fahlman Date: Sat, 17 Sep 1983 21:23 EDT From: Scott E. Fahlman I think that "it is an error" to destructively mess around with a list after it has been fed to MAPCAR or even to DOLIST. The fact that most implementations would do this in a certain way and the user can guess what that way is should not matter. If we let people twiddle hidden state and count on the results, there will be no safe optimizations left, and all Common Lisp implementations will slow down by a considerable factor. I agree that it ought to be "an error" or left undefined (implementation-dependent). Other languages with looping constructs have run into this problem, and most have decided to admit that there is "hidden state" which is implementation-dependent.  Received: from MIT-ML by SU-AI with TCP/SMTP; 17 Sep 83 18:09:47 PDT Date: 17 September 1983 21:12 EDT From: Glenn S. Burke Subject: implied contracts in the mapping functions? To: common-lisp @ SU-AI I would appreciate comments on the following "bug report" i just received. ---------------- Date: 17 Sep 83 11:59-EST (Sat) Subject: bug in mapc To: bug-nil@mit-mc I am iterating over a list and simultaneously adding things to the end of the list with NCONC. It works fine until I get down to the final iteration. If I then NCONC something on to the end of the list, MAPC exits without looking at the newly added list elements. . . . ---------------- The manual neither implies that this should work, nor that it might not. My impression on this is that using a mapping function is inappropriate here, and the (unintentional) optimization which causes his case to fail is allowable with the mapping functions. On the other hand, since it is so likely for this to actually work (i bet it does in most other implementations, and in fact it only fails in NIL in the interpreter when there is exactly one list argument to the MAPC, MAPCAN, and MAPCAR), it may not be worth the conceptual overhead to disallow this sort of hacking when it seems so "obvious" that it should work.  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 17 Sep 83 18:21:31 PDT Received: ID ; Sat 17 Sep 83 21:23:50-EDT Date: Sat, 17 Sep 1983 21:23 EDT From: Scott E. Fahlman To: Glenn S. Burke Cc: common-lisp@SU-AI.ARPA Subject: implied contracts in the mapping functions? In-reply-to: Msg of 17 Sep 1983 21:12 EDT from Glenn S. Burke I think that "it is an error" to destructively mess around with a list after it has been fed to MAPCAR or even to DOLIST. The fact that most implementations would do this in a certain way and the user can guess what that way is should not matter. If we let people twiddle hidden state and count on the results, there will be no safe optimizations left, and all Common Lisp implementations will slow down by a considerable factor. -- Scott  Received: from MIT-MC by SU-AI with TCP/SMTP; 18 Aug 83 10:06:04 PDT Date: Thursday, 18 August 1983 11:54-EDT From: dlw at SCRC-TENEX, benson at SCRC-TENEX Subject: What to do next To: fahlman at cmuc Cc: common-lisp at su-ai Scott, I appreciated your summary of pending issues in Common Lisp, and I certainly think we should proceed to work on these things. However, I think that the "next things to do", after we get out the initial real Common Lisp manual, are: (1) Create a Common Lisp Virtual Machine specification, and gather a body of public domain Lisp code which, when loaded into a proto-Lisp that meets the spec, produces a complete Common Lisp interpreter that meets the full language spec. (This doesn't address the portable compiler problem.) (2) Establish an official Common Lisp subset, suitable for implementation on 16-bit microcomputers such as the 68000 and the 8088. I understand that Gabriel is interested in 68000 implementations, and I am trying to interest Bob Rorscharch (who implemented IQLISP, which is an IBM PC implementation of a UCILISP subset) in converting his product into a Common Lisp implementation. There are a lot of problems with subsetting. You can't leave out multiple values, beacuse several primitives return multiple values and you don't want to omit all of these primitives (and you don't want to discourage the addition of new primitives that return multiple values, in future versions of Common Lisp). You can't leave out packages, at least not entirely, because keywords are essential to many functions. And many things, if removed, would have to be replaced by something significantly less clean. We'd ideally like to remove things that (a) can be removed without creating the need for an unclean simpler substitute, and (b) aren't used by the rest of the system. In other words, we have to find modular chunks to break off. And, of course, any problem that works in the subset has to work and do exactly the same thing in full Common Lisp, unless the program has some error (in the "it is an error" sense). The decision as to what goes in and what goes out should be made in light of the fact that an implementation might be heavily into "autoloading". Complex numbers can easily be omitted. The requirement for all the floating point precisions can be omitted. Of course, Common Lisp is flexiable in this regard anyway. Rational numbers could be left out. They aren't hard, per se, but they're just another thing to do. The "/" function on two integers would have to signal an error. Packages could be trimmed down to only be a feature that supplies keywords; most of the package system might be removable. Lexical scoping might possibly be removable. You could remove support for LABELS, FLET, and MACROLET. You can't remove internal functions entirely (i.e. MAPCAR of a lambda-expression can't be removed) but they might have some restrictions on them. Adjustable arrays could be removed. Fill pointers could go too, although it's not clear that it's worth it. In the extreme, you could only have simple arrays. You could even remove multi-D arrays entirely, or only 1-D and 2-D. Several functions look like they might be big, and aren't really required. Some candidates: COERCE, TYPE-OF, the hard version of DEFSETF (whatever you call it), LOOP, TYPEP and SUBTYPEP are hard to do, but it's hard to see how to get rid of the typing system! SUBTYPEP itself might go. Multiple values would be a great thing to get rid of in the subset, but there are the Common Lisp primitives that use multiple values. Perhaps we should add new primitives that return these second values only, for the benefit of the subset, or something. Catch, throw, and unwind-protect could be removed, although they're sure hard to live without. Lots of numeric stuff is non-critical: GCD, LCM, CONJUGATE, the exponentials and trascendentals, rationalize, byte manipulation, random numbers. The sequence functions are a lot of work and take a lot of room in your machine. It would be nice to do something about this. Unfortunately, simply omitting all the sequence functions takes away valuable basic functionality such as MEMQ. Perhaps the subset could leave out some of the keywords, like :test and :test-not and :from-end. Hash tables are not strictly necessary, although the system itself are likely to want to use some kind of hash tables somewhere, maybe not the user-visible ones. Maybe some of the defstruct options could be omitted, though I don't think that getting rid of defstruct entirely would be acceptable. Some of the make-xxx-stream functions are unnecessary. Some of the hairy reader syntax is not strictly necessary. The circular structure stuff and load-time evaluation are the main candidates. The stuff to allow manipulation of readtables is not strictly necessary, or could be partially restricted. Some of the hairy format options could be omitted. I won't go into detail on this. Some of the hairy OPEN options could go, although I'd hate to be the one to decide which options are the non-critical ones. Also some of the file operations (rename, delete, attribute manipulation) could go. The debugging tools might be optional although probably they just get autoloaded anyway.  Received: from MIT-MC by SU-AI with TCP/SMTP; 18 Aug 83 13:49:26 PDT Date: Thursday, 18 August 1983 16:40-EDT From: MOON at SCRC-TENEX To: common-lisp at sail Subject: subsetting One last comment. Inexpensive machines with ~ 1 megabyte main memory, ~ 40-80 megabyte disk, and VAX-class processors will be here sooner than we think. They may be limited by software and marketing more than by technology. So maybe by the time a subset was defined there wouldn't be much demand for it.  Received: from RUTGERS by SU-AI with TCP/SMTP; 18 Aug 83 12:26:45 PDT Date: 18 Aug 83 15:23:50 EDT From: Charles Hedrick Subject: Re: subsetting To: MOON%SCRC-TENEX@MIT-MC.ARPA cc: dlw%SCRC-TENEX@MIT-MC.ARPA, benson%SCRC-TENEX@MIT-MC.ARPA, common-lisp@SU-AI.ARPA In-Reply-To: Message from "MOON at SCRC-TENEX" of 18 Aug 83 14:26:00 EDT Another approach is to use byte code instead of real machine code. This can allow a significant space saving. -------  Received: from RUTGERS by SU-AI with TCP/SMTP; 18 Aug 83 12:24:32 PDT Date: 18 Aug 83 15:20:26 EDT From: Charles Hedrick Subject: Re: What to do next To: dlw%SCRC-TENEX@MIT-MC.ARPA, benson%SCRC-TENEX@MIT-MC.ARPA cc: fahlman@CMU-CS-C.ARPA, common-lisp@SU-AI.ARPA In-Reply-To: Message from "dlw at SCRC-TENEX, benson at SCRC-TENEX" of 18 Aug 83 11:54:00 EDT In general I agree with you. However let me point out: 1) that you can simplify MV's to the point that implementation is trivial. All you have to do is require that the caller of a function never asks for more MV's than there really are. (In particular, that he never asks for MV's when there aren't any.) This handles the most useful cases. Certainly it handles the case of calling system functions that return MV's. Then you require only a couple of primitives, probably MV-SETQ and MV-BIND. You certainly do not do MV-LIST (because you can't) nor MV-CALL. The result is that you can implement MV's by putting the values in the AC's or in global variables. No additional mechanisms are needed. I believe this is the right thing to have done in the first place. (Indeed I think the whole subset is probably going to be more useful than the real language.) 2) we do have a compiler that is probably about as portable as you are going to get. We use CMU's Spice Lisp compiler. It produces code for a stack-oriented microcoded machine. We transform this into code for a register-oriented machine. The instruction set we use is an extended version of Utah's CMACS, the final intermediate representation used in PSL. It is close enough to machine code that we produce the actual machine code in LAP. I am sure there ae machines that we might have trouble with, but for the ones I am used to, a couple of days playing with LAP should allow our code to be loaded on any register-oriented machine. The origial Spice Lap code could probably be loaded on any stack-oriented machine. -------  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 18 Aug 83 12:20:52 PDT Received: ID ; Thu 18 Aug 83 15:21:42-EDT Date: Thu, 18 Aug 1983 15:21 EDT From: Scott E. Fahlman To: dlw%SCRC-TENEX@MIT-MC.ARPA, benson%SCRC-TENEX@MIT-MC.ARPA Cc: common-lisp@SU-AI.ARPA Subject: What to do next In-reply-to: Msg of 18 Aug 1983 11:54-EDT from dlw at SCRC-TENEX, benson at SCRC-TENEX Date: Thursday, 18 August 1983 11:54-EDT (1) Create a Common Lisp Virtual Machine specification, and gather a body of public domain Lisp code which, when loaded into a proto-Lisp that meets the spec, produces a complete Common Lisp interpreter that meets the full language spec. (This doesn't address the portable compiler problem.) Our Spice Lisp implementation is currently serving exactly this need for about 6 implementation efforts. Instead of specifying a little Lisp kernel that has to be implemented, we specify a byte-coded instruction set, then provide Common Lisp written in Common Lisp (with some of these byte-coded primitives sprinkled in), plus a compiler written in Common Lisp that produces these byte codes. All a prospective user has to supply are either microcode for the byte-codes or a post-processor from byte codes to their machine's native instruction set, plus the byte-code primitives, GC, I/O, and the system interface stuff. Of course, once that is done, it is worth putting about a man-year of tuning into any given implementation to make it run as well as possible. So our SLGUTS document, along with our public-domain Lisp code and compiler, do most of what the blue pages are supposed to do. We are currently polishing our system up so that it is legal, and in the process we are cleaning up our compiler so that it will be easier to replace the whole code-generator, if people would rather do that than work from byte-codes. We also plan a substantial cleanup on our byte-code set, which is by now quite obsolete and creaky. The next obvious step is to take all of this and turn it into a cleanly packaged "implementor's kit". That would reduce the amount of hand-holding we would have to do and make the whole thing look more portable. I don't have much interest in taking this additional (largely cosmetic) step, but would cooperate with anyone else who wants to do it. Of course, if someone wants to build a better compiler/kit (ours is more stack-oriented than is optimal on conventional architectures and does not have all those hairy optimizations in it that real compiler hackers love), that would be a good thing to do. So I guess I see this as a mostly-solved problem and therefore not a high-priority issue. (2) Establish an official Common Lisp subset, suitable for implementation on 16-bit microcomputers such as the 68000 and the 8088. I'm a little dubious about this subsetting business. It is true that one could get rid of maybe half the virtual core image by judicious trimming, though including a compiler or Hemlockish editor would push you back up there. Rather than worry a lot about trimming the Lisp and about going from a big core image to autoload, maybe the time should be spent figuring out how to fake a decent virtual memory system on these machines. It would be nice to have things like Format lurking out on the floppies but virtually there, rather than gone but autoloadable. A whole generation of people learned to hate Lisp because they tried to prehistoric implementations without good debugging tools, pretty-printing editors,and the other things that make Lisp a decent programming environment. Let's not repeat this and expose high-school kids to the result. One thing we might do, if we want Common Lisp programs to be deliverable on micros with the minimum of memory, is to work on a system that goes over a set of compiled files and builds a Lisp core image with only these things and the Lisp facilities that they call included. You would develop on your Vax or 3600, but the turnkey expert system might then run on a 68000-based machine with minimal disk. Anyway, to respond to your suggestions: Complex numbers can easily be omitted. [ Yep. Should ahve been omitted from the real thing, and may still be if nobody works up the enthusiasm to implement them.] The requirement for all the floating point precisions can be omitted. Of course, Common Lisp is flexiable in this regard anyway. [ Yeah. The high-school version could leave them out altogether, and all the trascendental functions, for a big saving. ] Rational numbers could be left out. They aren't hard, per se, but they're just another thing to do. The "/" function on two integers would have to signal an error. [ This wouldn't save much -- GCD is all you need and that's not too big. Maybe leave out the Float/rational conversions.] Packages could be trimmed down to only be a feature that supplies keywords; most of the package system might be removable. [ Yeah. Again it doesn't save much. ] Lexical scoping might possibly be removable. You could remove support for LABELS, FLET, and MACROLET. You can't remove internal functions entirely (i.e. MAPCAR of a lambda-expression can't be removed) but they might have some restrictions on them. [ Lexical scoping doesn't cost much in space, but it slows down the interpreter and adds much hair to the compiler. If you want to save on compiler space, let GO and RETURN be confined in the traditional way (only to a cleanly surrounding block and not from a position that leaves crud on the stack) and eliminate lexical closures and the FLET stuff.] Adjustable arrays could be removed. Fill pointers could go too, although it's not clear that it's worth it. In the extreme, you could only have simple arrays. You could even remove multi-D arrays entirely, or only 1-D and 2-D. [ This would save a fair amound in dispatching hair. Not trying to super-optimize for speed would also save a lot of space -- whether that's a good trade depends on the machine and the applications.] Several functions look like they might be big, and aren't really required. Some candidates: COERCE, TYPE-OF, the hard version of DEFSETF (whatever you call it), LOOP, [Yup.] TYPEP and SUBTYPEP are hard to do, but it's hard to see how to get rid of the typing system! SUBTYPEP itself might go. [Got to have TYPEP, but not the hairy compund types and booleans. Subtypep is needed by the compiler but not much by user code.] Multiple values would be a great thing to get rid of in the subset, but there are the Common Lisp primitives that use multiple values. Perhaps we should add new primitives that return these second values only, for the benefit of the subset, or something. [If you're willing to cons when passing back multiples, or to limit the number to, say, 3 values, it becomes easy to do. I believe that only our unfortunate time functions return more than a few values.] Catch, throw, and unwind-protect could be removed, although they're sure hard to live without. [No, you've got to keep these. They become easy to do if you don't have to pass multiple back on the stack.] Lots of numeric stuff is non-critical: GCD, LCM, CONJUGATE, the exponentials and trascendentals, rationalize, byte manipulation, random numbers. [Leave in hyperbolic arctan, though -- every language needs at least one function that nobody has ever tried.] The sequence functions are a lot of work and take a lot of room in your machine. It would be nice to do something about this. Unfortunately, simply omitting all the sequence functions takes away valuable basic functionality such as MEMQ. Perhaps the subset could leave out some of the keywords, like :test and :test-not and :from-end. [Again, these are simple if you're willing to do everything with ELT and FUNCALL and are not going for tenseness. It is checking for 53 special cases that blow things up. If you don't have them in, people will write DO's and their code will balloon.] Hash tables are not strictly necessary, although the system itself are likely to want to use some kind of hash tables somewhere, maybe not the user-visible ones. [Again, if you want tiny but slow, an A-list can do anything a hash-table can.] Maybe some of the defstruct options could be omitted, though I don't think that getting rid of defstruct entirely would be acceptable. Some of the make-xxx-stream functions are unnecessary. Some of the hairy reader syntax is not strictly necessary. The circular structure stuff and load-time evaluation are the main candidates. The stuff to allow manipulation of readtables is not strictly necessary, or could be partially restricted. Some of the hairy format options could be omitted. I won't go into detail on this. Some of the hairy OPEN options could go, although I'd hate to be the one to decide which options are the non-critical ones. Also some of the file operations (rename, delete, attribute manipulation) could go. [All of the above sounds OK.] The debugging tools might be optional although probably they just get autoloaded anyway. [For an educational system on cheap machines, you don't skimp here. For a delivery vehicle, you don't need these.]  Received: from MIT-MC by SU-AI with TCP/SMTP; 18 Aug 83 11:33:52 PDT Date: Thursday, 18 August 1983 14:26-EDT From: MOON at SCRC-TENEX To: dlw at SCRC-TENEX, benson at SCRC-TENEX Cc: common-lisp at su-ai Subject: subsetting In-reply-to: The message of 18 Aug 1983 11:54-EDT from dlw at SCRC-TENEX, benson at SCRC-TENEX Most (by no means all) of the things you suggest omitting are quite inexpensive to include in an implementation that is optimized for space rather than speed. I don't think it is a good idea to have something called "Common Lisp" that omits large portions of the language. All the special forms should be included. Two good ways to fit into a smaller machine without sacraficing functionality are to use "autoloading" for little-used functions and to not include things only needed at compile time in the run-time environment (they can be "autoloaded" when needed for debugging or interpretive execution, of course). I think both of these categories are probably very large in Common Lisp.  Received: from MIT-MC by SU-AI with TCP/SMTP; 18 Aug 83 10:06:04 PDT Date: Thursday, 18 August 1983 11:54-EDT From: dlw at SCRC-TENEX, benson at SCRC-TENEX Subject: What to do next To: fahlman at cmuc Cc: common-lisp at su-ai Scott, I appreciated your summary of pending issues in Common Lisp, and I certainly think we should proceed to work on these things. However, I think that the "next things to do", after we get out the initial real Common Lisp manual, are: (1) Create a Common Lisp Virtual Machine specification, and gather a body of public domain Lisp code which, when loaded into a proto-Lisp that meets the spec, produces a complete Common Lisp interpreter that meets the full language spec. (This doesn't address the portable compiler problem.) (2) Establish an official Common Lisp subset, suitable for implementation on 16-bit microcomputers such as the 68000 and the 8088. I understand that Gabriel is interested in 68000 implementations, and I am trying to interest Bob Rorscharch (who implemented IQLISP, which is an IBM PC implementation of a UCILISP subset) in converting his product into a Common Lisp implementation. There are a lot of problems with subsetting. You can't leave out multiple values, beacuse several primitives return multiple values and you don't want to omit all of these primitives (and you don't want to discourage the addition of new primitives that return multiple values, in future versions of Common Lisp). You can't leave out packages, at least not entirely, because keywords are essential to many functions. And many things, if removed, would have to be replaced by something significantly less clean. We'd ideally like to remove things that (a) can be removed without creating the need for an unclean simpler substitute, and (b) aren't used by the rest of the system. In other words, we have to find modular chunks to break off. And, of course, any problem that works in the subset has to work and do exactly the same thing in full Common Lisp, unless the program has some error (in the "it is an error" sense). The decision as to what goes in and what goes out should be made in light of the fact that an implementation might be heavily into "autoloading". Complex numbers can easily be omitted. The requirement for all the floating point precisions can be omitted. Of course, Common Lisp is flexiable in this regard anyway. Rational numbers could be left out. They aren't hard, per se, but they're just another thing to do. The "/" function on two integers would have to signal an error. Packages could be trimmed down to only be a feature that supplies keywords; most of the package system might be removable. Lexical scoping might possibly be removable. You could remove support for LABELS, FLET, and MACROLET. You can't remove internal functions entirely (i.e. MAPCAR of a lambda-expression can't be removed) but they might have some restrictions on them. Adjustable arrays could be removed. Fill pointers could go too, although it's not clear that it's worth it. In the extreme, you could only have simple arrays. You could even remove multi-D arrays entirely, or only 1-D and 2-D. Several functions look like they might be big, and aren't really required. Some candidates: COERCE, TYPE-OF, the hard version of DEFSETF (whatever you call it), LOOP, TYPEP and SUBTYPEP are hard to do, but it's hard to see how to get rid of the typing system! SUBTYPEP itself might go. Multiple values would be a great thing to get rid of in the subset, but there are the Common Lisp primitives that use multiple values. Perhaps we should add new primitives that return these second values only, for the benefit of the subset, or something. Catch, throw, and unwind-protect could be removed, although they're sure hard to live without. Lots of numeric stuff is non-critical: GCD, LCM, CONJUGATE, the exponentials and trascendentals, rationalize, byte manipulation, random numbers. The sequence functions are a lot of work and take a lot of room in your machine. It would be nice to do something about this. Unfortunately, simply omitting all the sequence functions takes away valuable basic functionality such as MEMQ. Perhaps the subset could leave out some of the keywords, like :test and :test-not and :from-end. Hash tables are not strictly necessary, although the system itself are likely to want to use some kind of hash tables somewhere, maybe not the user-visible ones. Maybe some of the defstruct options could be omitted, though I don't think that getting rid of defstruct entirely would be acceptable. Some of the make-xxx-stream functions are unnecessary. Some of the hairy reader syntax is not strictly necessary. The circular structure stuff and load-time evaluation are the main candidates. The stuff to allow manipulation of readtables is not strictly necessary, or could be partially restricted. Some of the hairy format options could be omitted. I won't go into detail on this. Some of the hairy OPEN options could go, although I'd hate to be the one to decide which options are the non-critical ones. Also some of the file operations (rename, delete, attribute manipulation) could go. The debugging tools might be optional although probably they just get autoloaded anyway.  Received: from MIT-MC by SU-AI with TCP/SMTP; 17 Aug 83 08:48:03 PDT Date: 17 Aug 1983 1049-EDT From: Daniel L. Weinreb Subject: Re: Things to do To: Moon%SCRC-TENEX%MIT-MC@SU-DSN cc: Fahlman%CMU-CS-C@SU-DSN, common-lisp@SU-AI In-Reply-To: The message of Tuesday, 16 August 1983, 01:56-EDT from David A. Moon I have done 90% of the work of rewriting GPRINT completely in modern Lisp style, which also makes it perform better. I still have to do the "last 10%" with all that that implies. Converting it to Common Lisp also has to be done but it clearly easy. I don't think when I'll have time to work on this more, though. Keep in touch. -------  Received: from RUTGERS by SU-AI with TCP/SMTP; 16 Aug 83 23:24:15 PDT Date: 17 Aug 83 00:43:32 EDT From: Charles Hedrick Subject: Re: Things to do To: HIC%SCRC-TENEX@MIT-MC.ARPA cc: Fahlman@CMU-CS-C.ARPA, common-lisp@SU-AI.ARPA In-Reply-To: Message from "Howard I. Cannon " of 17 Aug 83 00:36:25 EDT An alternative might be movei n,2 pushj p,@[fadr block] where the address in the fadr block was indexed by N. That would still save testing and dispatching within the function itself, but would avoid adding 4 words to the FADR block. What do you think? -------  Received: from MIT-MC by SU-AI with TCP/SMTP; 16 Aug 83 21:31:41 PDT Received: from SCH-STYX by SCRC-TENEX with CHAOS; Wed 17-Aug-83 00:25:26-EDT Date: Tuesday, 16 August 1983, 21:30-PDT From: Howard I. Cannon Subject: Things to do To: Fahlman at CMU-CS-C.ARPA Cc: common-lisp at SU-AI.ARPA In-reply-to: The message of 14 Aug 83 12:16-PDT from Scott E. Fahlman 3. At one point HIC offered to propose a minimal set of white-pages support for efficient implementation of a portable flavor system, and to supply the portable part. The white-pages support would also be usable by other object-oriented paradigms with different inheritance schemes (that's the controversial part). After a brief exchange of messages, HIC got super-busy on other matters and we haven't heard much since then. Either HIC or someone else needs to finish this proposal, so that we can put in the low-level support and begin playing with the portable implementation of flavors. Only after more Common Lisp users have had some opportunity to play with flavors will it make sense to consider including them (or some variation) in the white pages. There is a lot of interest in this out in user-land. My schedule is too unpredictable at this point to make a comitment, but I intend to be doing some new development on Flavors this fall, and can likely finish up a reasonable proposal within the next few months. If there's a 90% chance I can get something through, then I'll schedule it...  Received: from MIT-MC by SU-AI with TCP/SMTP; 16 Aug 83 00:38:21 PDT Received: from SCRC-MENOTOMY by SCRC-TENEX with CHAOS; Tue 16-Aug-83 03:35:30-EDT Date: Tuesday, 16 August 1983, 03:35-EDT From: Robert A. Cassels Subject: Things to do To: Fahlman at CMU-CS-C.ARPA, Moon%SCRC-TENEX%MIT-MC at SU-DSN.ARPA Cc: common-lisp at SU-AI.ARPA In-reply-to: The message of 16 Aug 83 02:42-EDT from Scott E. Fahlman Date: Tue, 16 Aug 1983 02:42 EDT From: Scott E. Fahlman I'll have to look at our floating read and print, but I doubt that they are easy to make portable. Ours can be made portable without too much trouble (at some loss of efficiency). It probably wants a few extra features. I figured I'd wait for Steele's, in the hope that he's figured out more elegant solutions to the problems than I did.  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 15 Aug 83 23:42:04 PDT Received: ID ; Tue 16 Aug 83 02:42:18-EDT Date: Tue, 16 Aug 1983 02:42 EDT From: Scott E. Fahlman To: David A. Moon Cc: common-lisp@SU-AI.ARPA Subject: Things to do In-reply-to: Msg of 16 Aug 1983 01:56-EDT from David A. Moon Dave, Glad to hear that you folks are interested in doing a number of things on the list. Nobody is expecting super-quick action on any of this. As I said, this is just a bit of pre-planning for things to do once our respective implementations are stable. Of the things on your shopping list, STEP, TRACE, and DEFSTRUCT are all working here and could be made portable easily enough. They may not be hairy enough (or featureful enough) for everyone's taste. I'll have to look at our floating read and print, but I doubt that they are easy to make portable. -- Scott  Received: from MIT-MC by SU-AI with TCP/SMTP; 15 Aug 83 23:05:47 PDT Received: from SCRC-YAMASKA by SCRC-TENEX with CHAOS; Tue 16-Aug-83 02:01:39-EDT Date: Tuesday, 16 August 1983, 01:56-EDT From: David A. Moon Subject: Things to do To: Scott E. Fahlman Cc: common-lisp@SU-AI In-reply-to: The message of 14 Aug 83 15:16-EDT from Scott E. Fahlman I think we plan to contribute to this, but I at least will not have time to get near this stuff for at least a couple of months. 3. Portable flavor system / white-pages message-passing substrate. I think we will find one or more people at Symbolics interested in finishing the proposal HIC made long ago and implementing it on our machines. 4. LOOP and LetS We should have both of these available in Common Lisp, and both of them should be reimplemented. I've intended for almost two years now to do this for LOOP, so you know how much to believe me when I say I will get back to this soon. As CL implementations become available at MIT in a few months someone will no doubt be found to fix LetS. 5. Pretty-printing DLW is interested in rewriting Waters' GPRINT. I'll let him speak for himself on what the status of this is. 6. Taxonomic event handling. I have a proposal for this, which is suffiently abstract that it could be implemented on something other than flavors (although clearly the right substrate for it is flavors). The proposal is not at all finished, but I will send it out in a couple of months. 8. Macro-writer's aids. I have most of this stuff, written in something pretty close to straight Common Lisp. The one thing I don't have is type-analysis, although I expect that would be easy to build on top of the other tools. In a couple of months I'll see about making this stuff portable and available. To add to your list: A portable interpreted-code stepper that uses *EVALHOOK* and *APPLYHOOK*. A portable or near-portable TRACE package. A variety of macro memoization schemes, using *MACROEXPAND-HOOK*. These aren't as trivial as they seem at first blush. More general destructuring facilities (I have an unfinished proposal). A portable defstruct implemementation. Portable floating-point read and print.  Received: from MIT-MC by SU-AI with TCP/SMTP; 15 Aug 83 12:50:58 PDT Date: Monday, 15 August 1983, 12:29-PDT From: Eric Benson Subject: Looping constructs To: Scott E. Fahlman , common-lisp at SU-AI.ARPA In-reply-to: The message of 14 Aug 83 12:16-PDT from Scott E. Fahlman Okay, I'll jump right in... I believe that LOOP and LetS can coexist peacefully in the same world. They deal with two different problems in very different ways. LetS allows APL-style processing of "sequences," (unrelated to the Common Lisp sequence concept) with an expression based syntax. It is designed so that sequences are not actually created as data structures, rather existing conceptually as intermediate values. Such operations as merging, sorting and concatentation do not fit within its paradigm. LOOP, on the other hand, is intended to extend (all) the iteration constructs found in other languages to Lisp, with a keyword based syntax. This kitchen-sink-ism and non-Lispy syntax seems to offend some purists, but there are many iterative programs which could not be expressed at all using LetS, and only painfully using DO, which are quite amenable to treatment with LOOP. Chacun a son gout. (LOOP FOR EVERYONE IN COMMON-LISP DO (SEND EVERYONE :THIS-MESSAGE))  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 14 Aug 83 12:16:28 PDT Received: ID ; Sun 14 Aug 83 15:16:47-EDT Date: Sun, 14 Aug 1983 15:16 EDT From: Scott E. Fahlman To: common-lisp @ SU-AI.ARPA Subject: Things to do A bunch of things were put off without decisions or were patched over in the effort to get agreement on the first edition. Most of the people who have been intensively involved in the language design will be tied up for another couple of months getting their implementations up to spec and tweaking them for performance. However, it is perhaps not too soon to begin thinking about what major additions/changes we want to get into the second edition, so that those who want to make proposals can begin preparing them and so that people can make their plans in light of what is likely to be coming. Here's a list of the major things that I see on the agenda for the next year or so. Some are yellow-pages packages, some have deep roots and require white-pages support, and some are so pervasive that they will probably migrate into the white pages after a probationary period in yellow-land. I'm sure I'm forgetting a few things that have already been suggested. I'm also sure that people will have some additional proposals to make. I am not including very minor and trivial changes that we might want to make in the language as we gain some experience with it. 1. Someone needs to implement the transcendental functions for complex numbers in a portable way so that we can all use these. The functions should be parameterized so that they will work for all the various floating-point precisions that implementations might offer. The design should be uncontroversial, since it is already specified in the manual. I don't think we have any volunteers to do this at present. 2. We need to re-think the issue of function specs, and agree on what should go into the white pages next time around. Moon's earlier proposal, or some subset of it, is probably what we want to go with. 3. At one point HIC offered to propose a minimal set of white-pages support for efficient implementation of a portable flavor system, and to supply the portable part. The white-pages support would also be usable by other object-oriented paradigms with different inheritance schemes (that's the controversial part). After a brief exchange of messages, HIC got super-busy on other matters and we haven't heard much since then. Either HIC or someone else needs to finish this proposal, so that we can put in the low-level support and begin playing with the portable implementation of flavors. Only after more Common Lisp users have had some opportunity to play with flavors will it make sense to consider including them (or some variation) in the white pages. There is a lot of interest in this out in user-land. 4. We need some sort of iteration facility more powerful than DO. The existing proposals are some extensively cleaned-up revision of LOOP and Dick Waters' LETS package. There may be some other ideas out there as well. Probably the best way to proceed here is for the proponents of each style to implement their package portably for the yellow pages and let the customers decide what they like. If a clear favorite emerges, it will probably be absorbed into the white pages, though this would not preclude personal use of the other style. None of these things requires white-pages support -- it is just a matter of what we want to encourage users to use, and how strongly. 5. A good, portable, user-modifiable pretty printer is needed, and if it were done well enough I see no reason not to put the user-visible interface in the white pages next time around. Waters' GPRINT is one candidate, and is being adopted as an interim pretty-printer by DEC. The last time I looked, the code for that package was impenetrable and the interface to it was excessively hairy, but I've heard that it has been simplified. Maybe this is what we want to go with. Other options? 6. We need to work out the business of taxonomic error-handling. Moon has a proposal in mind, I believe. A possible problem is that this wants to be white-pages, so if it depends on flavors it gets tied up with the issue of making flavors white-pages as well. 7. The Hemlock editor, a public-domain Emacs-clone written in portable Common Lisp, is now running on the Perq and Vax implementations. We have a lot of additional commands and modes to implement and some tuning to do, but that should happen fairly rapidly over the next few months. Of course, this cannot just be moved verbatim to a new implementation and run there, since it interacts closely with screen-management and with the file system. Once Hemlock is polished, it will provide a reasonable minimum editing/top-level environment for any Common Lisp implementation that takes the trouble to adapt it to the local system. This should eliminate the need for hairy rubout-handlers, interlispy top-levels, S-expression editors, and some other "environment" packages. We plan to add some version of "info mode" at some point and to get the Common Lisp Manual and yellow pages documents set up for tree-structured access by this package, but that won't happen right away. 8. Someone ought to put together a reasonable package of macro-writer's aids: functions that know which things can be evaluated multiple times without producing side-effects, type-analysis hacks, and other such goodies. If you have items to add to this list, let me know. -- Scott  Received: from USC-ECL by SU-AI with TCP/SMTP; 9 Aug 83 08:09:27 PDT Received: from MIT-XX by USC-ECL; Tue 9 Aug 83 08:07:50-PDT Received: from SCRC-BEAGLE by SCRC-SPANIEL with CHAOS; Tue 9-Aug-83 11:04:41-EDT Date: Tuesday, 9 August 1983, 11:04-EDT From: Bernard S. Greenberg Subject: File opening, :TRUNCATE To: Common-Lisp%SU-AI at USC-ECL Cc: File-protocol at SCRC-TENEX Was it ever proposed or rejected that there be a :IF-EXISTS :TRUNCATE, being like :OVERWRITE, except that the file content is effectively set to empty before writing starts? There is need for such a thing, and it is a natural behavior on many systems. The default :IF-EXISTS of :ERROR is not useful on file systems that do not have versions (note that a version of :NEWEST changes the default to :NEW-VERSION). We propose that the default :IF-EXISTS be changed to :SUPERSEDE for file sytems that do not have versions. Is there any reason why :IF-EXISTS is ignored in :OUTPUT/:IO instead of generating an error?  Received: from USC-ECL by SU-AI with TCP/SMTP; 5 Aug 83 13:09:01 PDT Received: from MIT-XX by USC-ECL; Fri 5 Aug 83 13:09:30-PDT Received: from SCRC-BEAGLE by SCRC-SPANIEL with CHAOS; Fri 5-Aug-83 15:50:05-EDT Date: Friday, 5 August 1983, 15:50-EDT From: Bernard S. Greenberg Subject: File open options To: Common-Lisp%su-ai at USC-ECL The Laser Manual speaks of the :IF-EXISTS options :RENAME, :RENAME-AND-DELETE as though they do their renaming and deleting at open time. It goes out of its way to say that :SUPERSEDE "destroys" the existing file at successful close time. The former being unreasonable, I decided that the Lisp Machine local file system would continue to implement all of these concepts at successful close time. It keeps the real file open under a funny name until then. The only place it could possibly screw up is a direct access, interlocked, multi-process, shared file of a kind that we currently don't have. I guess I'm just thinking out loud, or asking for an adjudication on the legality of such a decision. While we are on the subject, should anything be said about open ':direction ':output ':if-exists ':overwrite closing in abort mode? Should the file go away?  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 29 Jul 83 21:31:18 PDT Received: from [128.2.254.192] by CMU-CS-PT with CMUFTP; 30 Jul 83 00:23:39 EDT Date: 30 Jul 83 0027 EDT (Saturday) From: Guy.Steele@CMU-CS-A To: common-lisp@SU-AI Subject: ASSERT and CHECK-TYPE Per Moon's remark, that the manual states that CHECK-TYPE does not evaluate the error-message argument is an error. CHECK-TYPE should evaluate its optional argument form. ASSERT should have the syntax ASSERT test-form [ ( {place}* ) [ string {arg}* ] ] --Guy  Received: from MIT-MC by SU-AI with TCP/SMTP; 29 Jul 83 13:37:48 PDT Received: from SCRC-MENOTOMY by SCRC-TENEX with CHAOS; Fri 29-Jul-83 16:34:38-EDT Date: Friday, 29 July 1983, 16:35-EDT From: David A. Moon Subject: Non-evaluated error message in ASSERT To: Scott E. Fahlman Cc: COMMON-LISP@SU-AI In-reply-to: The message of 29 Jul 83 11:07-EDT from Scott E. Fahlman CHECK-TYPE already does evaluate its optional third argument (error message). If the manual doesn't say this, it's a mistake in the manual.  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 29 Jul 83 08:07:23 PDT Received: ID ; Fri 29 Jul 83 11:07:58-EDT Date: Fri, 29 Jul 1983 11:07 EDT From: Scott E. Fahlman To: David A. Moon Cc: COMMON-LISP@SU-AI.ARPA Subject: Non-evaluated error message in ASSERT In-reply-to: Msg of 29 Jul 1983 00:30-EDT from David A. Moon If there are no objections to the proposed change to the syntax of ASSERT, I propose that we let Guy decide whether this "erratum" can go into the manual at this point without undue disruption of the proofreading/editing/production process. While changing anything that is widely used would be unacceptable to us at this time, ASSERT is not currently being used much in our code, and the proposed change is trivial. CHECK-TYPE would also be changed to eval its string, but this change is upward-compatible, or nearly so. Guy should give us a clear go/no-go decision on this change as soon as possible. I do remember Moon's query on this, and also that I didn't think very long about its implications, given the amount of stuff that was being dealt with just then. -- Scott  Received: from DEC-MARLBORO by SU-AI with TCP/SMTP; 29 Jul 83 06:07:34 PDT Date: Fri 29 Jul 83 09:06:44-EDT From: GBROWN@DEC-MARLBORO.ARPA Subject: ERROR SIGNALLING FUNCTIONS To: COMMON-LISP@SU-AI.ARPA Well, I certainly want to thank everyone for taking the time to read my message and give it some thought. I can tell that it's going to be refreshing to work on Common Lisp in an environment where a variety of people openly discuss the issues (I am just about to join the AI group at Digital). It is clear now that I was coming from a different direction. I tend to implement a simple internal error reporting facility for an application, and then spend most of my time on the user interface. Thus my reaction to the functions was slanted in the direction of the user. The functions are quite good for internal error reporting, and it's great that developers won't have to reinvent them every time. I do suggest that we take Dave Moon up on his willingness to change the definition of check-type and assert so that they can evaluate their message strings. We've had some success at Digital with message file translation, so we might want to do that with Lisp applications. One can still put the messages in the source; a fancy macro can do the dirty work. I also suggest that we think a little about how declarations interact with the key forms of these functions. Any day now we'll get our Lisp Machine. Thanks again. - Paul C. Anagnostopoulos -------  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 28 Jul 83 21:54:58 PDT Received: ID ; Fri 29 Jul 83 00:55:44-EDT Date: Fri, 29 Jul 1983 00:55 EDT From: Skef Wholey To: David A. Moon Cc: COMMON-LISP@SU-AI.ARPA Subject: Non-evaluated error message in ASSERT In-reply-to: Msg of 29 Jul 1983 00:30-EDT from David A. Moon Of course, with the current definition of ASSERT, one can still compute format-strings by using "~?", format indirection...  Received: from MIT-MC by SU-AI with TCP/SMTP; 28 Jul 83 21:30:38 PDT Received: from SCRC-BULLDOG by SCRC-TENEX with CHAOS; Fri 29-Jul-83 00:29:15-EDT Date: Friday, 29 July 1983, 00:30-EDT From: David A. Moon Subject: Non-evaluated error message in ASSERT To: COMMON-LISP@SU-AI In-reply-to: The message of 28 Jul 83 22:12-EDT from Scott E. Fahlman When I first proposed the current syntax of ASSERT, I asked if anyone wanted to change the syntax to allow the error message to be evaluated, and no one said yes. I would be perfectly happy to make that change and regard it as an erratum in the manual. The current syntax is (ASSERT test-form [reference*] [format-string] [format-arg*]) The new syntax would be (ASSERT test-form ([reference*]) [format-string] [format-arg*])  Received: from CMU-CS-C by SU-AI with TCP/SMTP; 28 Jul 83 19:12:13 PDT Received: ID ; Thu 28 Jul 83 22:12:52-EDT Date: Thu, 28 Jul 1983 22:12 EDT From: Scott E. Fahlman To: GBROWN@DEC-MARLBORO.ARPA Cc: COMMON-LISP@SU-AI.ARPA Subject: ERROR SIGNALLING FUNCTIONS In-reply-to: Msg of Thu 28 Jul 83 11:32:42-EDT from GBROWN at DEC-MARLBORO.ARPA A part of Paul's note that I agree with is that, in retrospect, I don't think that we want to have error-signalling forms that take unevaluated string args. In most cases we will want to stick some constant string in there, but there may well be cases where we want to evaluate any such arg. A function that goes off somewhere to find a string in the proper natural language is just one such application. Since the string arg in ASSERT is used as a syntactic marker, we would have to change that function's syntax to fix this -- the pre-string arguments would have to be encased in a list or something like that. We probably should think about fixing this in the second edition -- it is not of such earth-shaking importance that we should consider unfreezing edition 1 to put this change in. As others have pointed out, ASSERT is just a convenient abbreviation, not a primitive. -- Scott  Received: from MIT-MC by SU-AI with TCP/SMTP; 28 Jul 83 12:15:25 PDT Received: from SCRC-BORZOI by SCRC-TENEX with CHAOS; Thu 28-Jul-83 15:04:26-EDT Date: Thursday, 28 July 1983, 15:05-EDT From: Daniel L. Weinreb Subject: ERROR SIGNALLING FUNCTIONS To: GBROWN%DEC-MARLBORO@SU-DSN, COMMON-LISP@SU-AI In-reply-to: The message of 28 Jul 83 11:32-EDT from GBROWN at DEC-MARLBORO I have two answers to your first point about check-arg. You say that "the user will have no idea how to enter a new value". The problem with this is your model of what a "user" is. One of the main users of Common Lisp is the program developer, who is writing the program, and WILL know how to enter a new value. You say that this is "an example of an error message I'd hate for a user to see". Well, suppose there is a data-type mismatch detected at runtime. Would you rather see this message, or have the program continue to execute despite the mismatch and do something random, or blow up, or say "please call an expert, you obviously can't understand this", or what? You want to put all your error messages in a big file of error messages. Well, I think we simply have a difference of religion here. I'd hate to have to do that; if I did that, I'd never bother to take the trouble to create good error messages, and my program would be incomprehensible because when you read the program you wouldn't be able to see the error messages. How many users really would want to edit this file? What would they edit? And if you want to make an application multilingual, it's a lot harder than just replacing the error messages: what about all the prompts and so on? For assert, your only new objection ends with "I challenge anyone to do this in a stylish fashion." Well, I have a great deal of experience with advanced error systems, and we have had a lot of success in this area. Challenge accepted. When you get your first official release of Symbolics Common Lisp, try it. Besides, if you want to make up your own message, well, don't use e(c)case. Those functions exist for the convenience of those who don't want to spend a lot of effort optimizing theis messages. I think you might have a valid point about the interaction between the explicit type checking, and implicit type checking that might be generated because of declarations. If I had an "Excelsior edition" (so that's what it's called!), I could look into this further.  Received: from MIT-MC by SU-AI with TCP/SMTP; 28 Jul 83 12:16:02 PDT Received: from SCRC-BULLDOG by SCRC-TENEX with CHAOS; Thu 28-Jul-83 15:11:41-EDT Date: Thursday, 28 July 1983, 15:12-EDT From: David A. Moon Subject: ERROR SIGNALLING FUNCTIONS To: GBROWN%DEC-MARLBORO@SU-DSN Cc: COMMON-LISP@SU-AI In-reply-to: The message of 28 Jul 83 11:32-EDT from GBROWN at DEC-MARLBORO I don't recall seeing your comments before; perhaps your original message was swallowed by some mail system problem. It wouldn't be the first time. Your comments are well taken, but I think underlying this there is a fundamental disagreement about what Common Lisp is for. Such constructs as check-type and assert are intended for internal checking within a program; they are certainly not intended as a user interface for users of an application program. When a check-type signals an error, it is assumed that the user is thrown into the debugger. Supplying a new value is a debugger function suitable for someone who understands the program and the particular error that occurred. An application program that is trying to conceal its Lisp underpinnings from its user and present some consistent facade that differs from the facade the system presents to Lisp programmers would not allow this error to get into the debugger. Presumably it would say "Internal error; the program is broken". Indeed, Common Lisp in general is a system programming language and is not itself a framework for constructing user interfaces. At least not yet; this seems like a good area to address in a "second generation" of Common Lisp. But I think the conscious decision we made to concentrate on the easier areas first was wise, considering how long it has taken just to define the language in all of its details. Also you should note that check-type and assert are convenient abbreviations, not the most general error signalling mechanism. So it's supposed to be okay that you cannot do all possible error signalling with them, for instance you can't compute an error message at run time. Perhaps this design decision was wrong; I couldn't say. The condition system that I intend to propose after the basic language has been squared away addresses these issues. It is based on the Lisp Machine condition system, with some improvements and simplifications.  Received: from DEC-MARLBORO by SU-AI with TCP/SMTP; 28 Jul 83 09:52:04 PDT Date: Thu 28 Jul 83 11:32:42-EDT From: GBROWN@DEC-MARLBORO.ARPA Subject: ERROR SIGNALLING FUNCTIONS To: COMMON-LISP@SU-AI.ARPA I believe that use of the error signalling macros in sections 24.3 and 24.4 of the Common Lisp Reference Manual (Excelsior edition) will diminish the quality of applications written in Common Lisp. This note explains my reasoning. I realize that the note comes quite late, but I sent in a similar note right after Moon's proposal was distributed which appears to have been ignored. Please recognize that my opinions are not necessarily those of other people working on Common Lisp at Digital. My basic objection is that the macros incorporate assumptions about error signalling and error messages that are inapropriate in most circumstances and hence should not be promoted by the language. I feel quite strongly about this issue. Here are my specific objections. o check-type. In all but the most trivial cases, the user will have no idea how to enter a new value, and we wouldn't want the user to know anyway. The first example in the reference manual, telling the user that something is not a vector of integers, is precisely an example of an error message I'd hate for a user to see. The error message fragment alleviates this problem somewhat, but again only in trivial cases. The other problem with this macro is the use of an unevaluated string for the error message fragment. This is quite parochial, and certainly would only suffice in the country in which the application was written. At Digital, for example, we like to put our messages in a file that can be edited by the user, and invoke a function to obtain the message when needed. o assert. This suffers from the same shortcomings as check-type. In particular, the error message is actually part of the syntax, and thus couldn't be evaluated in any case! In addition, the assumption is made that a rational message could be composed from one of the generalized-variable references in order to prompt the user for a new value. I challenge anyone to do this in a stylish fashion (note that there were no examples of this in the manual). o e(c)typecase. I am quite surprised that Common Lisp implementors were willing to accept the hair involved in trying to compose a reasonable message for this function. Imagine trying to word the message for types such as a defstruct, a deftype, or even the relatively simple type (or (mod 16) (member t nil)). And I hope we'd agree that the resulting message would only confuse the user, who would have no idea how to enter a new value. o e(c)case. Except in the situation where there are only two or three clauses, I doubt if an application would want to list all the possible values from which the user can choose. Even applications that list all possible commands (e.g., Visicalc) do it in their own special style. o declarations. It is not clear how these macros interact with declarations. If a function declares the data item used as the key in one of these macros, it may be that Common Lisp has already detected the error and, in many implementations, signalled it with some other obscure error message. This completely circumvents the error message generated by the macro, and renders the macro useless. Let us reconsider the inclusion of these macros in Common Lisp. They address a problem, detection and alteration of incorrect input by the user, which is better addressed by an application-specific question asking facility. If we retain these macros, I suggest that they be used only to signal uncorrectable internal logic errors. - Paul C. Anagnostopoulos -------  Received: from CMU-CS-A by SU-AI with TCP/SMTP; 26 Jul 83 22:26:47 PDT Received: from [128.2.254.192] by CMU-CS-PT with CMUFTP; 27 Jul 83 01:26:01 EDT Date: 27 Jul 83 0126 EDT (Wednesday) From: Guy.Steele@CMU-CS-A To: JoSH Subject: Re: small snafu in LASER edn. CC: common-lisp@SU-AI In-Reply-To: "JoSH's message of 25 Jul 83 21:52-EST" The name of the variable should be *load-set-default-pathname*. It is an error that the description of load mentions "*load-set-pathname-defaults*". --Guy  Received: from MIT-MC by SU-AI with TCP/SMTP; 25 Jul 83 12:35:07 PDT Date: Thursday, 21 July 1983, 07:22-PDT From: Mail Server at SPA-Nimbus Subject: Failed mail To: Mail Maintainers Redistributed-to: common-lisp at su-ai at mc Redistributed-by: rsl at SPA-Nimbus Redistributed-date: Friday, 22 July 1983, 18:36-PDT Unable to deliver to the following recipient: Common-Lisp at SU-AI: Host not responding. ----- Failed message follows ----- Date: Friday, 15 July 1983, 15:29-PDT From: BENSON at SPA-Nimbus Subject: Re: Top level forms in a compiled file To: Martin.Griss , Common-Lisp at SAIL In-reply-to: The message of 15 Jul 83 12:07-PDT from Martin.Griss Date: 15 Jul 1983 1307-MDT From: Martin.Griss Subject: Re: Top level forms in a compiled file To: BENSON@SPA-NIMBUS cc: Griss@UTAH-20 In-Reply-To: Your message of 14-Jul-83 2127-MDT Should also mention that sometimes need COMPILETIME or BOTHTIMES to also get the execution of functions that used in defining forms to be compiled further on. MACRO definitions are explicitly BOTHTIMES.. Martin ------- That's a separate issue, but one that should also be addressed by the standard. On the Lisp Machine, macros aren't actually defined in the global compile time environment, just saved in a private place known to the compiler. Only an explicit EVAL-WHEN (COMPILE) actually puts something in the compile time Lisp world. Compare that with Arthur Norman's request to make everything evaluated at compile time by default! The former strategy is designed for the Lisp system builder, where compiling an incompatible version of part of the existing environment would be disastrous if things changed out from under him. I know this happened on many occasions with PSL, especially when cross-compiling to a new machine. Arthur's suggestion is geared to the applications programmer, who usually wants the effect of incremental evaluation even when compiling to a file. I suspect if we were to survey Lisp programmers who are not Lisp implementors, most would prefer to have everything defined at compile time. On the other hand, it is much more than just inconvenient to system implementors if this is the case. Uh oh, I feel an impending global variable, *EVAL-WHEN-DEFAULT*, set to (LOAD EVAL) by systems hackers and (COMPILE LOAD EVAL) by real people. Of course, one had better set it inside an EVAL-WHEN... -- Eric  Received: from USC-ISIB by SU-AI with TCP/SMTP; 20 Jul 83 20:32:22 PDT Date: 20 Jul 1983 1619-PDT Subject: list of lisps From: Dave Dyer To: common-lisp@SU-AI Has anyone got a master list of LISP implementations, all dialects, all machines? I get soooo tired of ennumerating all the rumors I remember. -------  Received: from MIT-MC by SU-AI with TCP/SMTP; 17 Jul 83 09:01:01 PDT Received: from SCRC-BORZOI by SCRC-TENEX with CHAOS; Sun 17-Jul-83 11:44:26-EDT Date: Sunday, 17 July 1983, 11:52-EDT From: Daniel L. Weinreb Subject: Top level forms in a compiled file To: KMP%MIT-MC@SU-DSN Cc: Common-Lisp@SU-AI In-reply-to: The message of 16 Jul 83 17:06-EDT from Kent M. Pitman Date: 16 July 1983 17:06 EDT From: Kent M. Pitman What follows is just speculation; not in any way a proposal... ...we could in principle have a function PRELOAD which was like LOAD but just "got everything in core" without doing any major side-effects. Then (LOAD "FILE1") might just do (G0003) without having to move bits from disk to core. In our work on the Lisp Machine, we sometimes have to LOAD in Lisp programs that the LOAD mechanism is based on, like pieces of the network software or local file system software. Boy, is it a pain! Your PRELOAD feature might be a good way to handle that.  Received: from MIT-MC by SU-AI with TCP/SMTP; 16 Jul 83 14:07:13 PDT Date: 16 July 1983 17:06 EDT From: Kent M. Pitman Subject: Top level forms in a compiled file To: BENSON @ SPA-NIMBUS cc: Common-Lisp @ SU-AI In-reply-to: Msg of 14 Jul 1983 18:13-PDT from BENSON at SPA-Nimbus Date: Thursday, 14 July 1983, 18:13-PDT From: BENSON at SPA-Nimbus ... This is handled in PSL by having function definitions add a call to FSET to the list of top level forms to be compiled. It is exactly as if ... (defmacro defun (name &body body) `(setf (symbol-function ',name) #',(lambda ,@body))) Even defining a function twice in a single file and using both definitions works... I assume you meant #'(lambda ,@body) rather than #',(lambda ,@body). In any case, now that you mention it, I once wrote a simple Lisp compiler which used this same trick. This style of presentation is also satisfactory to me. It is maximally parallel with scheme, where (setf (symbol-function ',name) #'(lambda ,@body)) would "macroexpand" to (setq ,name (lambda ,@body)) In fact, it's probably a loss to have the primitive conceptual unit not be #'(lambda ...), since anything else is almost sure to eventually turn up deficient for some extension to def- syntax. So I'd support this as a semantic model. Actually, named-lambda might be better than lambda, but that's no big deal. What follows is just speculation; not in any way a proposal. It's interesting to note that if FILE1 = [ (defun f (x) x) (defun g (x) x) ] "means" roughly... (defun g0001 (x) x) (defun g0002 (x) x) (defun g0003 () (setf #'f #'g0001) (setf #'g #'g0002)) then (load "FILE1") is the same as (G0003) so we could in principle have a function PRELOAD which was like LOAD but just "got everything in core" without doing any major side-effects. Then (LOAD "FILE1") might just do (G0003) without having to move bits from disk to core. Also, there might be a function RELOAD which just re-ran G0003 rather than moving a second set of the code into core. It wouldn't fix bashed constants, but that might either be know to be desirable or at least harmless for some applications.