Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 28 Jan 86 23:21:45 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 28 Jan 86 20:11:43 PST Received: ID ; Tue 28 Jan 86 23:12:32-EST Date: Tue, 28 Jan 1986 23:12 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: "James R. Meehan" Cc: common-lisp@SU-AI.ARPA Subject: DEFUN inside LET In-reply-to: Msg of 28 Jan 1986 10:06-EST from James R. Meehan I'm not sure if there's actually a firm consensus on this, but in my opinion Defun inside Let should always work. It's an idiom I use a lot, and if some alleged Common Lisp didn't supply this, I'd either complain or fix it myself. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 28 Jan 86 21:37:55 EST Received: from UCBVAX.BERKELEY.EDU by SU-AI.ARPA with TCP; 28 Jan 86 18:23:15 PST Received: by ucbvax.berkeley.edu (5.44/1.9) id AA10532; Tue, 28 Jan 86 18:23:27 PST Received: by renoir.berkeley.edu (5.44/5.16) id AA07538; Tue, 28 Jan 86 18:23:15 PST Resent-From: hilfingr@renoir.berkeley.edu (Paul Hilfinger) Resent-Message-Id: <8601290223.AA07538@renoir.berkeley.edu> Message-Id: <8601290223.AA07538@renoir.berkeley.edu> Resent-To: common-lisp@su-ai.arpa To: fateman@kim.berkeley.edu Subject: Re: IEEE float co-processors In-Reply-To: Your message of Tue, 28 Jan 1986 08:56 EST. Date: 28 Jan 86 12:24:12 PST (Tue) From: hilfingr@renoir.berkeley.edu Resent-Date: 28 Jan 86 16:10:21 PST (Tue) > My only concern is that the interpreter would probably be stuck with > doing the coercions at each step, and therefore might get a slightly > different (less precise) answer than the compiler would come up with. > Would that bother anyone? (Not me, but I only look at the first two > digits anyway...) I don't do numerical work, but working down the hall from a particularly famous and outspoken numerical analyst as I do, I don't dare be completely uninformed on the issue. I think that one clearly wants the compiler and interpreter to give identical results, not only for obvious reasons having to do with debugging, but also for consistency with the CL campaign to bring compiled and interpreted semantics closer together. Fateman's proposal doesn't seem to make it hard for the interpreter to be consistent with the compiler. For example, the implementation might choose an implementation in which 1. All expressions of the form (arith-op a b c ...) are grouped left-associatively (at least if one operand is floating point and possibly always. 2. All arithmetic involving floating point is done in extended precision, with the result being rounded to the appropriate precision at the end. Is there any difficulty in having either interpreter or compiler follow this semantics? Frankly, I think the freedom to re-arrange allowed on page 194 is a bad idea for any expression that might involve floating point operands (maybe for others, too, but my opinion isn't strong on that.) In CL, of course, you don't have the freedom to say ``well, we'll compile it this way for integers and ratios and that way for floating point'' because CL is not strongly typed. I therefore anticipate the objection, ``well we don't want to lower the quality of code for the usual case (some sort of integers, I presume).'' However, in the absence of very clear, solid, empirical evidence suggesting appreciable degradation of performance resulting from the compiler's inability to reassociate expressions, I'd just as soon chuck the flexibility. There is a prevailing opinion that ``well, floating point is approximate, so who cares? Why not rearrange as convenient?'' The fact of the matter is that while floating point arithmetic is approximate, it is ``approximate in a precise way'' (at least on most architectures, and certainly on anything conforming to the IEEE Standard 754.) For example, on most machines x+y, x*y, x-y, and x/y all have the property that in the absence of over/underflow, the result has a very small (order 2**(-number of binary digits of precision or so)) RELATIVE error. Indeed, for addition (subtraction), if the magnitudes of the operands are within a factor of 2 of each other and the operands have opposite (the same) signs, so that extensive cancellation occurs, the result is mathematically exact. The common intuition that cancellation introduces error is completely wrong. This property turns out to be very useful (for example, it makes it possible to compute the area of a triangle with a simple formula that works well even for very flat triangles.) It also explains why some of us would like to avoid cavalier rounding of small rationals to 0: doing so suddenly introduces a 100% relative error into the computation. Better to get an error indication or the right answer. I suppose one could argue that usually, one doesn't care. For integers and ratios this is certainly true, since the answer will be identical in any case, unless something exceptional (and in particular rare) happens. But when regrouping changes the answer in unexceptional cases, and when important properties of that answer by rights could be predicted by simple and well-understood rules if only the grouping were predictable, one has to wonder. Paul Hilfinger  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 28 Jan 86 21:15:08 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 28 Jan 86 18:03:28 PST Received: from WAIKATO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 403885; Tue 28-Jan-86 20:49:51-EST Received: from CUYAHOGA.SCRC.Symbolics.COM by WAIKATO.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 150379; Tue 28-Jan-86 20:51:24-EST Date: Tue, 28 Jan 86 20:52 EST From: Robert A. Cassels Subject: more boring-to-most-people floating point stuff To: fateman@dali.berkeley.edu, Moon@SCRC-STONY-BROOK.ARPA cc: common-lisp@SU-AI.ARPA In-Reply-To: <8601262213.AA19482@dali.berkeley.edu> Message-ID: <860128205234.4.CASSELS@CUYAHOGA.SCRC.Symbolics.COM> Reply-To: Robert A. Cassels Date: Sun, 26 Jan 86 14:13:29 PST From: fateman@dali.berkeley.edu (Richard Fateman) The example (/ (expt 10 68) 1.0e38) is illustrating ( ) whereas (/ (* 1.0e34 1.0e34) 1.0e38) is illustrating (recursively) ( ) . Only when you combine two number types, one majorizing the other, do you face this issue. The intent when combining different precisions (and ranges) within floats is clear. You coerce to the longer precision because it is likely to give you the right answer. Not the fastest. A reasonable extension of this is if you mix floats with even longer precision numbers (i.e., rational), you convert to rational, because it gives you the right answer, not the fastest. You can, of course, promote the notion that "anything goes" as soon as exact and approximate numeric types are mixed, or claim that it would be too costly to do the right thing. I agree it's a question of what's right, not what's costly. [Now that we have the EGC, we don't worry so much about consing.] I think my earlier statements about efficiency were really trying to get at my last point below about generic numeric functions. (Although I would like my generic functions to be as efficient as possible.) To say this is the wrong forum for this is to appear at odds with the space devoted to this and other numeric data types in the language specification. Okay, I think I see what you're driving at. You are saying that rational arithmetic is "right" (mathematically correct) and so computations should be encouraged to happen rationally. A user who *really* wants floating-point should have to be careful to say so. I agree that we should be pushing rational arithmetic. But I think that we should point out that use of a floating-point number anywhere in a computation must be assumed to have "tainted" the result. I think it would be misleading and less useful for (* pi 2) => 884279719003555/140737488355328. It would certainly be confusing for (* .001 10) => 42949675/4294967296. It's hard enough explaining that (* .001 10) => 0.010000001. I guess I prefer that any fuzziness in the computation be reflected in fuzziness of the result. You could object that coercion should then prefer the smaller precision rather than the larger, and I'd probably agree. From a pragmatic and language design point of view, I'd like to be able to write generic functions which work on both rational and floating-point numbers, such that rational inputs get rational results and floating inputs get floating results of the same precision. I'd prefer that the constants in those functions to be written rationally when they're (mathematically) rational numbers. So I'd still like coercion to prefer floating-point.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 28 Jan 86 19:52:49 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 28 Jan 86 15:26:37 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 403727; Tue 28-Jan-86 17:32:17-EST Date: Tue, 28 Jan 86 17:33 EST From: David A. Moon Subject: IEEE float co-processors To: common-lisp@SU-AI.ARPA In-Reply-To: <8601282012.1690@ur-seneca.rochester.arpa> Message-ID: <860128173314.1.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Tue, 28 Jan 86 15:12:49 est From: Lab Manager(Brad Miller) I have not been thrilled with this ongoing meandering about floating point, but I'd like to take exception to your statement about leaving intermediate result precision unspecified. It would be nice if a program working on one machine also worked on another. Surely that is what portability is supposed to insure, not that the language is so general that any floating point result is OK. Well, you see, there are two conflicting goals here. It would be nice for programs to be portable. It would also be nice for the Common Lisp community not to have to take on the job of forcing IBM and DEC to agree on a common format and semantics for floating-point arithmetic. What we have done is to provide some features for finding out the characteristics of floating-point arithmetic in a particular implementation. This may be only a half measure, but it may also be the best we can do. Taking off my language designer hat and putting on my manufacturer hat, of course the system my company sells conforms to the IEEE standard and otherwise makes an effort to provide reasonable, consistent, and standardized floating-point semantics. Some other manufacturers do so as well. But I don't think we want to forbid Common Lisp to be implemented on hardware that, for whatever reason, has different ideas about how floating-point should work. I'm going to try not to send any more mail on this subject.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 28 Jan 86 18:11:18 EST X-Sent: to SU-AI.ARPA by IMSSS.FRONSTAD.EDU via ETHERNET with PUPFTP; 1986-Jan-28 14:59:18 PST (=GMT-8hr) X-Mailer: EMACS -> PSL (FORMAT+SEND-ALL) -> PUPFTP Date: 1986 January 28 14:56:44 PST (=GMT-8hr) From: Robert Elton Maas (this host known locally only) To:lab@rochester.arpa CC:COMMON-LISP@SU-AI.ARPA Subject:Rebuttal to incorrect statement of portability definition Sender: REM%IMSSS@SU-SCORE.ARPA (for undeliverable-mail notifications) Reply-to: REM%IMSSS@SU-SCORE.ARPA L> Date: Tue, 28 Jan 86 15:12:49 est L> From: Lab Manager(Brad Miller) L> It would be nice if a program working on one machine also worked on L> another. Surely that is what portability is supposed to insure, not L> that the language is so general that any floating point result is OK. The contrapositive is that if it fails on another then it also fails on the one. I.e. nobody is allowed to make any improvements beyond the minimal implementation. Nobody is allowed to make private enhancements to the language, such as a window system etc. I disapprove. The correct statement, in my opinion, is that any program which restricts itself to features and capabilities as defined in CLtL will run on any machine, but programs are permitted to take advantage of nonportable features at the expense of no longer being portable. Thus in the case at hand, programs that rely only on the minimal accuracy of minimal results will be portable, runnable on all CL implementations, but it is possible that some programs may take advantage of extra accuracy available only on certain machines and those programs will not be portable. The programmer should attempt to determine whether the program is truly portable or not, although sometimes that may be difficult to determine without actually trying it on other machines (computer programming is still an experimental science). It may be desirable to have a flag that disables use of extended precision co-processors in order to test portability on a single machine, but it should be legal to switch that flag to machine-dependent maximum-precision mode at times.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 28 Jan 86 16:41:45 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 28 Jan 86 13:08:50 PST Received: from CUYAHOGA.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 403573; Tue 28-Jan-86 15:06:29-EST Date: Tue, 28 Jan 86 15:09 EST From: Robert A. Cassels Subject: comparisons between floats and ratios To: Fahlman@C.CS.CMU.EDU, GZ%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU cc: common-lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860128150911.1.CASSELS@CUYAHOGA.SCRC.Symbolics.COM> Reply-To: Robert A. Cassels Date: Mon, 27 Jan 1986 10:42 EST From: "Scott E. Fahlman" A not-entirely-unrelated question: What kind of rounding is FLOAT supposed to do? I think that the GOAL is to produce the closest approximation to the ratio that is possible in a given floating-point format. That's what implementors should shoot for. Whether it makes sense to REQUIRE this in the very last bit is less clear. I don't think I've ever seen a floating-point package that got this right all the time. You haven't looked at your 36xx lately, then. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 28 Jan 86 16:28:28 EST Received: from ROCHESTER.ARPA by SU-AI.ARPA with TCP; 28 Jan 86 13:13:37 PST Received: from ur-seneca.rochester.arpa (ur-seneca) by ur-cayuga.rochester.arpa id AA00446 (4.12u); Tue, 28 Jan 86 16:13:29 est Received: by ur-seneca.rochester.arpa id AA01690 (4.12v); Tue, 28 Jan 86 15:12:49 est Message-Id: <8601282012.1690@ur-seneca.rochester.arpa> Date: Tue, 28 Jan 86 15:12:49 est From: Lab Manager(Brad Miller) To: Moon@SCRC-STONY-BROOK.ARPA Cc: common-lisp@SU-AI.ARPA In-Reply-To: David A. Moon's message of Tue, 28 Jan 86 13:48 EST Subject: IEEE float co-processors I have not been thrilled with this ongoing meandering about floating point, but I'd like to take exception to your statement about leaving intermediate result precision unspecified. It would be nice if a program working on one machine also worked on another. Surely that is what portability is supposed to insure, not that the language is so general that any floating point result is OK. Make everything BIGNUM and forget it.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 28 Jan 86 16:10:01 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 28 Jan 86 12:56:44 PST Received: from CUYAHOGA.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 403567; Tue 28-Jan-86 15:04:10-EST Date: Tue, 28 Jan 86 15:06 EST From: Robert A. Cassels Subject: comparisons between floats and ratios To: DCP@SCRC-QUABBIN.ARPA, Fahlman@C.CS.CMU.EDU, GZ%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU cc: common-lisp@SU-AI.ARPA In-Reply-To: <860127111609.5.DCP@NEPONSET.SCRC.Symbolics.COM> Message-ID: <860128150652.0.CASSELS@CUYAHOGA.SCRC.Symbolics.COM> Reply-To: Robert A. Cassels Date: Mon, 27 Jan 86 11:16 EST From: David C. Plummer Date: Mon, 27 Jan 1986 10:37 EST From: "Scott E. Fahlman" Is (> a-rational a-float) supposed to err out when (float a-rational a-float) would overflow? If so, there should at least be some way to tell ahead of time if that's going to happen, for people who want to write a more careful comparison routine. Sounds like a job for the error system (a proposal for which KMP is supposed to have ready soon). Better to intercept this rare overflow problem when it occurs, and when you actually care, than to slow down the universe by trying to prevent it. There are two places to put the condition-case/bind (or whatever the KMP equivalent is). One is in the application program, the other is in the system code that does the comparision. Putting it in the application program will look like Common Lisp has a wart that numeric comparisons need special help sometimes. Putting it in the system code would probably slow it down as much as doing the check. The system code would probably look like (already checked that both are positive): (block nil (> (condition-case () (float a-rational a-float) ( (return t)) ( (return nil))) a-float)) This points up a problem with putting it in the application program: If overflow is signalled, how does the application figure out what the intent was? It might be hard to figure out that (float a-rational a-float), which is where the error happened, was being used for >. Ack! Even though we have an error system, I didn't consider using it for this particular application. I used the IEEE-required ability to turn off overflow traps: [simplified for presentation] (defnumop < ((x float) (y bignum)) (if (infinite x) ; + or - infinity (minusp x) (without-floating-overflow-traps (< x (float y x)))))  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 28 Jan 86 16:03:38 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 28 Jan 86 12:49:36 PST Received: from CUYAHOGA.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 403553; Tue 28-Jan-86 14:54:13-EST Date: Tue, 28 Jan 86 14:56 EST From: Robert A. Cassels Subject: Comparing float to rational To: gls@THINK-AQUINAS.ARPA, common-lisp@SU-AI.ARPA In-Reply-To: <860127175030.6.GLS@THINK-JEHOSEPHAT.ARPA> Message-ID: <860128145652.9.CASSELS@CUYAHOGA.SCRC.Symbolics.COM> Reply-To: Robert A. Cassels Date: Mon, 27 Jan 86 17:50 EST From: Guy Steele I thinm that Fateman has raised a valid issue that deserves discussion. Right now the Common Lisp book does seem to specify quite clearly (page 194) that for comparison as well as "combining" of a rational with a float, the rational shall be converted to a float of the same format. Evidence on the other side of the question is the remark that for MAX and MIN, if the largest (resp. smallest) argument is a rational then the returned result may be a rational even though the argument is a float. I think there is a lot to be said for requiring comparison between a rational and a float always to work and not to overflow. I think there is much less to be said in the case of addition, but I am on less solid ground here. What is FORTRAN's position on this? In FORTRAN when an integer meets a float, the integer gets converted to a float. I can't find my copy of the FORTRAN '77 standard just this minute, but I don't recall anything in the standard requiring the range of a float to be as large as that of an integer (granted that for an integer to exceed the range of a float would be considered unusual in that culture). Right. In the land of Fortran machines, integers can't overflow when converted to floats. But, speaking of Fortran, perhaps overflow considerations are where the coercion rules came from -- integers don't overflow when converted to singles, and singles don't overflow when converted to doubles. Now that we have bignums, the ground rules are different and we can rethink the rules. I also reject the notion that a floating-point number is really an interval (though I'm not sure GJC implied this directly). However, I do think it is reasonable to consider floating-point numbers to be approximations--at least, once the inexact flag gets set. (It seems to me, by the way, that if bits were free it would be more sensible to have an inexact bit in every value rather than a single global flag; but bits are not free and the 754 committee was having to sweat as it was to cram everything into 32 bits.) One strives for a reasonable economic balance between accuracy, speed, and ease of understanding. In the case of comparisons, it is not too difficult to be completely accurate, and doing so makes it much easier to understand. That's as far as I go with confidence. The issue for addition or multiplication is not so clear, because the speed costs are not clear (they can cascade). This is a reasonable matter for discussion. --Guy  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 28 Jan 86 14:39:34 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 28 Jan 86 11:06:14 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 403454; Tue 28-Jan-86 13:47:43-EST Date: Tue, 28 Jan 86 13:48 EST From: David A. Moon Subject: IEEE float co-processors To: Richard Fateman cc: common-lisp@SU-AI.ARPA In-Reply-To: <8601280708.AA04790@dali.berkeley.edu> Message-ID: <860128134840.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Note that on page 16 of the Common Lisp manual, the language is carefully defined not to require any particular floating-point format or arithmetic. For the same reasons that the language does not require adherence to the IEEE floating-point standard (or any other), I think it makes sense for the language not to require any particular precision for intermediate results. Defining floating point more precisely would limit portability to different pieces of hardware, or else would limit efficiency, and if efficiency is not a concern, why use floating point at all?  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 28 Jan 86 10:58:03 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 28 Jan 86 07:47:08 PST Received: from NEPONSET.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 403255; Tue 28-Jan-86 10:39:42-EST Date: Tue, 28 Jan 86 10:45 EST From: David C. Plummer Subject: IEEE float co-processors To: Richard Fateman , Scott E. Fahlman , common-lisp@SU-AI.ARPA In-Reply-To: <8601280708.AA04790@dali.berkeley.edu>, Message-ID: <860128104531.4.DCP@NEPONSET.SCRC.Symbolics.COM> I think I agree with what you two are talking about. It is critical that the answer be of the correct type. We (Symbolics) used to have a proceed option such that if a single float computation overflowed, the user could continue using double floats. We got rid of that after we realized that was tempting users to believe they had more accuracy than they actually had. It all goes back to: If you are going to use floating point, you better know what you are doing.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 28 Jan 86 10:34:45 EST Received: from YALE-CHEOPS.ARPA by SU-AI.ARPA with TCP; 28 Jan 86 07:28:07 PST Received: by yale-cheops.YALE.ARPA; Tue, 28 Jan 86 10:15:42 est Message-Id: <8601281515.AA16516@yale-cheops.YALE.ARPA> Received: by CSI-RING; Tue, 28 Jan 86 10:06:27 est Date: Tue, 28 Jan 86 10:06:27 est From: James R. Meehan To: common-lisp@su-ai.arpa Subject: DEFUN inside LET I remember seeing some mail on this topic, but I don't remember whether there was a consensus. Is Common Lisp supposed to support DEFUN inside LET? I know you can always write (SETF (SYMBOL-FUNCTION 'FOO) #'(LAMBDA ...)) to get much the same effect, but that's awkward.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 28 Jan 86 09:02:40 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 28 Jan 86 05:55:45 PST Received: ID ; Tue 28 Jan 86 08:56:35-EST Date: Tue, 28 Jan 1986 08:56 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: fateman@dali.berkeley.edu (Richard Fateman) Cc: common-lisp@SU-AI.ARPA Subject: IEEE float co-processors In-reply-to: Msg of 28 Jan 1986 02:08-EST from fateman at dali.berkeley.edu (Richard Fateman) I believe the standard should allow the processor to perform all floating point arithmetic computations in highest precision, and not require multiple conversions (from short to single to double to long). The paragraph which allows rearrangement or conversion to the longest format IN THE EXPRESSION is not flexible enough to quite allow this. This sounds like a good proposal, and it wouldn't break anyone's code to implement it. I think that all we need is a clarification that says that a compiler is allowed to do whatever it wants to in handling the precision of intermediate arithmetic results, as long as any outputs finally accessible to the user are of the specified type and as long as precision is at least as good as you would get by doing the obvious coercions at each step. My only concern is that the interpreter would probably be stuck with doing the coercions at each step, and therefore might get a slightly different (less precise) answer than the compiler would come up with. Would that bother anyone? (Not me, but I only look at the first two digits anyway...) -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 28 Jan 86 08:51:12 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 28 Jan 86 05:45:12 PST Received: ID ; Tue 28 Jan 86 08:46:01-EST Date: Tue, 28 Jan 1986 08:45 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: common-lisp@SU-AI.ARPA Subject: Spelling correction In-reply-to: Msg of 28 Jan 1986 06:29-EST from Christopher Fry In reply to Christopher Fry Sounds to me like you want a synonym facility rather than spelling correction. Then you can spell things however you like. For Hemlock users, we've now got word abbrev mode in, and people are experimenting with various versions of Lisp-mode symbol-completion. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 28 Jan 86 07:58:24 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 28 Jan 86 04:52:19 PST Date: Tue, 28 Jan 86 07:53:17 EST From: "George J. Carrette" Subject: Spelling correction To: cfry@OZ.AI.MIT.EDU cc: common-lisp@SU-AI.ARPA, BACH@SU-SCORE.ARPA, Fahlman@C.CS.CMU.EDU In-reply-to: Msg of Tue 28 Jan 86 06:29 EST from Christopher Fry Message-ID: <[MC.LCS.MIT.EDU].798777.860128.GJC> In the LMI system we have a spelling correction function that evolved as MIDAS (ITS SPELL) -> C (by Pace Willison) -> ZetaLisp (again Pace). It has only been used for META-$ in Zmacs so far; but maybe somebody would be willing to CL'ify it and perhaps try hooking it into the DWIMIFY-PACKAGE hooks that are in various error handlers.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 28 Jan 86 06:38:21 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 28 Jan 86 03:31:11 PST Received: from DUANE.AI.MIT.EDU by OZ.AI.MIT.EDU via Chaosnet; 28 Jan 86 06:30-EST Date: Tue, 28 Jan 86 06:29 EST From: Christopher Fry Subject: Spelling correction To: Fahlman@C.CS.CMU.EDU, BACH@SU-SCORE.ARPA cc: common-lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860128062939.3.CFRY@DUANE.AI.MIT.EDU> Spelling correction would be less necessary in Common Lisp if the names of certain functions were easier to spell. For example: rplaca cddadr nsublis svref sqrt hash-table [the type, includes dash] readtable [the type, no dash] exp, expt dpb Fixing the source of common spelling errors would be more profitable than adding heuristic patches like spelling correctors. Since the above examples are set in concrete, a yellow pages spelling corrector may make it possible for a part-time hacker [whose voice isn't heard on this mailing list] to survive in the unnecessarily complex CL environment.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 28 Jan 86 02:15:54 EST Received: from UCBVAX.BERKELEY.EDU by SU-AI.ARPA with TCP; 27 Jan 86 23:08:04 PST Received: by ucbvax.berkeley.edu (5.44/1.8) id AA00269; Mon, 27 Jan 86 23:08:29 PST Received: by dali.berkeley.edu (5.44/5.16) id AA04790; Mon, 27 Jan 86 23:08:19 PST Date: Mon, 27 Jan 86 23:08:19 PST From: fateman@dali.berkeley.edu (Richard Fateman) Message-Id: <8601280708.AA04790@dali.berkeley.edu> To: common-lisp@su-ai.arpa Subject: IEEE float co-processors Cc: fateman@dali.berkeley.edu in CLtL p193-194 it is stated that an operation combining a short float with a long results in a long. Presumably if you combine a short + a single you get a single. But how precise is the intermediate arithmetic? Is it OK to do the arithmetic in "long", or MUST you do the arithmetic no more precisely and with no larger range than "single"? Consider any of a number of existing and proposed co-processors in which all arithmetic is in fact done in, say, 80 bit units. A single * short * short then stored to a single would be done by converting each argument to a long, multiplying and rounding to single. This is faster than any other method using most such chips. Unfortunately, it might get an answer better than that prescribed by following CLtL strictly. Using the method on p 194, one can come up with problems where intermediate arithmetic done in single might overflow, underflow, or lose precision disasterously, (or all of these) before the final, exactly-single-representable answer is computed. I believe the standard should allow the processor to perform all floating point arithmetic computations in highest precision, and not require multiple conversions (from short to single to double to long). The paragraph which allows rearrangement or conversion to the longest format IN THE EXPRESSION is not flexible enough to quite allow this.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 28 Jan 86 00:23:30 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 27 Jan 86 21:09:41 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 403054; Tue 28-Jan-86 00:08:06-EST Date: Tue, 28 Jan 86 00:08 EST From: David A. Moon Subject: :capitalize in *print-case* To: Scott E. Fahlman cc: Martin Frost , common-lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860128000857.6.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Mon, 27 Jan 1986 23:50 EST From: "Scott E. Fahlman" I think that the manual means what it says here: lower-case characters don't get touched, regardless of the setting of this switch. I agree. Note that the manual clearly states that this switch does not affect printing when vertical bar syntax is used and that internally lowercase characters are printed in lowercase with an escape (backslash or vertical bar). An implementation where *print-case* changes what appears inside vertical bars is incorrect.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 28 Jan 86 00:00:14 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 27 Jan 86 20:50:16 PST Received: ID ; Mon 27 Jan 86 23:50:53-EST Date: Mon, 27 Jan 1986 23:50 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Martin Frost Cc: common-lisp@SU-AI.ARPA Subject: :capitalize in *print-case* In-reply-to: Msg of 27 Jan 1986 21:54-EST from Martin Frost I think that the manual means what it says here: lower-case characters don't get touched, regardless of the setting of this switch. The theory is that most symbol print names end up in all-upper-case internally, and the *print-case* flags control how you want to see those. If the user has taken special trouble to get a lower-case character into a symbol's print name, we assume that he really wants to see a lower-case character there. This is all pretty ugly, but seemed like the thing to do at the time; it's something of a holdover from the bad old days when the only way to get a character string was to make it the print-name of a symbol. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 27 Jan 86 22:17:42 EST Date: 27 Jan 86 1854 PST From: Martin Frost Subject: :capitalize in *print-case* To: common-lisp@SU-AI.ARPA CC: ME@SU-AI.ARPA CLtL says that lowercase letters in print names are always printed in lowercase, and that *print-case* controls the printing of uppercase. This implies that with *print-case* set to :CAPITALIZE, the symbol |aBCD| should be printed as |abcd|. This is of course not a capitalized word, and I've seen at least one Common Lisp implementation that prints this symbol as |Abcd|, thus violating the claim that "lowercase letters are always printed in lowercase". So which way should it be with :CAPITALIZE? Should it really capitalize or should lowercase letters always be printed in lowercase?  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 27 Jan 86 19:19:47 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 27 Jan 86 16:08:46 PST Date: Mon, 27 Jan 86 19:09:33 EST From: "George J. Carrette" Subject: precision, accuracy, and floating conversion (GJC's comment) To: fateman@DALI.BERKELEY.EDU cc: common-lisp@SU-AI.ARPA In-reply-to: Msg of Mon 27 Jan 86 11:52:37 PST from fateman at dali.berkeley.edu (Richard Fateman) Message-ID: <[MC.LCS.MIT.EDU].798122.860127.GJC> Quote RJF: "GJC's view that a floating point number x means an interval [x-epsilon,x+epsilon] for some unknown epsilon, is not ..." Quote GJC: "...that is *not* GJC's view" Quote GJC again (sigh): "'nuff said, but what about the PI bit? If the PI bit is set then floating point numbers are to be taken as a multiplier of PI. If the E bit then as a multiplier of (EXP 1)..."  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 27 Jan 86 18:02:09 EST Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 27 Jan 86 14:49:31 PST Received: from jehosephat by GODOT.THINK.COM via CHAOS; Mon, 27 Jan 86 17:49:27 est Date: Mon, 27 Jan 86 17:50 EST From: Guy Steele Subject: Comparing float to rational To: common-lisp@SU-AI.ARPA Cc: gls@THINK-AQUINAS.ARPA Message-Id: <860127175030.6.GLS@THINK-JEHOSEPHAT.ARPA> I thinm that Fateman has raised a valid issue that deserves discussion. Right now the Common Lisp book does seem to specify quite clearly (page 194) that for comparison as well as "combining" of a rational with a float, the rational shall be converted to a float of the same format. Evidence on the other side of the question is the remark that for MAX and MIN, if the largest (resp. smallest) argument is a rational then the returned result may be a rational even though the argument is a float. I think there is a lot to be said for requiring comparison between a rational and a float always to work and not to overflow. I think there is much less to be said in the case of addition, but I am on less solid ground here. What is FORTRAN's position on this? In FORTRAN when an integer meets a float, the integer gets converted to a float. I can't find my copy of the FORTRAN '77 standard just this minute, but I don't recall anything in the standard requiring the range of a float to be as large as that of an integer (granted that for an integer to exceed the range of a float would be considered unusual in that culture). I also reject the notion that a floating-point number is really an interval (though I'm not sure GJC implied this directly). However, I do think it is reasonable to consider floating-point numbers to be approximations--at least, once the inexact flag gets set. (It seems to me, by the way, that if bits were free it would be more sensible to have an inexact bit in every value rather than a single global flag; but bits are not free and the 754 committee was having to sweat as it was to cram everything into 32 bits.) One strives for a reasonable economic balance between accuracy, speed, and ease of understanding. In the case of comparisons, it is not too difficult to be completely accurate, and doing so makes it much easier to understand. That's as far as I go with confidence. The issue for addition or multiplication is not so clear, because the speed costs are not clear (they can cascade). This is a reasonable matter for discussion. --Guy  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 27 Jan 86 17:29:32 EST Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 27 Jan 86 14:17:22 PST Received: from jehosephat by GODOT.THINK.COM via CHAOS; Mon, 27 Jan 86 17:17:37 est Date: Mon, 27 Jan 86 17:18 EST From: Guy Steele Subject: precision, accuracy, and floating conversion (GJC's comment) To: common-lisp@SU-AI.ARPA In-Reply-To: <8601271952.AA06514@dali.berkeley.edu> Message-Id: <860127171840.5.GLS@THINK-JEHOSEPHAT.ARPA> Date: Mon, 27 Jan 86 11:52:37 PST From: fateman@dali.berkeley.edu (Richard Fateman) ... As for GJC's example, if I understand it, you want a floating point number so you can return (the float (* 1/2 ...)) or (* (the float 1/2) ...) Technical nit: I think these expressions should be (float (* 1/2 ...)) or (* (float 1/2) ...) to be correct. On the other hand, I think that GJC really wanted was to write a constant at the bottom of the coercion chain so that the type of the argument would determine the type of the answer. Hence (coerce (* 1/2 ...) (type-of arg)) or (* (coerce 1/2 (type-of arg)) ...) would do.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 27 Jan 86 15:04:52 EST Received: from UCBVAX.BERKELEY.EDU by SU-AI.ARPA with TCP; 27 Jan 86 11:52:52 PST Received: by ucbvax.berkeley.edu (5.44/1.8) id AA19106; Mon, 27 Jan 86 11:52:45 PST Received: by dali.berkeley.edu (5.44/5.16) id AA06514; Mon, 27 Jan 86 11:52:37 PST Date: Mon, 27 Jan 86 11:52:37 PST From: fateman@dali.berkeley.edu (Richard Fateman) Message-Id: <8601271952.AA06514@dali.berkeley.edu> To: common-lisp@su-ai.arpa Subject: precision, accuracy, and floating conversion (GJC's comment) GJC's view that a floating point number x means an interval [x-epsilon,x+epsilon] for some unknown epsilon, is not treated kindly in most of the current thinking about floating point arithmetic. To be consistent here, you should also propose that in combining floating point numbers, the SHORTEST precision should be used, because that would indicate that the answer is particularly uncertain. As for GJC's example, if I understand it, you want a floating point number so you can return (the float (* 1/2 ...)) or (* (the float 1/2) ...)  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 27 Jan 86 11:20:12 EST Received: from SCRC-VALLECITO.ARPA by SU-AI.ARPA with TCP; 27 Jan 86 08:11:03 PST Received: from NEPONSET.SCRC.Symbolics.COM by SCRC-VALLECITO.ARPA via CHAOS with CHAOS-MAIL id 79954; Mon 27-Jan-86 11:10:26-EST Date: Mon, 27 Jan 86 11:16 EST From: David C. Plummer Subject: comparisons between floats and ratios To: Scott E. Fahlman , Gail Zacharias cc: common-lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860127111609.5.DCP@NEPONSET.SCRC.Symbolics.COM> Date: Mon, 27 Jan 1986 10:37 EST From: "Scott E. Fahlman" Is (> a-rational a-float) supposed to err out when (float a-rational a-float) would overflow? If so, there should at least be some way to tell ahead of time if that's going to happen, for people who want to write a more careful comparison routine. Sounds like a job for the error system (a proposal for which KMP is supposed to have ready soon). Better to intercept this rare overflow problem when it occurs, and when you actually care, than to slow down the universe by trying to prevent it. There are two places to put the condition-case/bind (or whatever the KMP equivalent is). One is in the application program, the other is in the system code that does the comparision. Putting it in the application program will look like Common Lisp has a wart that numeric comparisons need special help sometimes. Putting it in the system code would probably slow it down as much as doing the check. The system code would probably look like (already checked that both are positive): (block nil (> (condition-case () (float a-rational a-float) ( (return t)) ( (return nil))) a-float)) This points up a problem with putting it in the application program: If overflow is signalled, how does the application figure out what the intent was? It might be hard to figure out that (float a-rational a-float), which is where the error happened, was being used for >.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 27 Jan 86 11:05:26 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 27 Jan 86 07:41:35 PST Received: ID ; Mon 27 Jan 86 10:42:18-EST Date: Mon, 27 Jan 1986 10:42 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Gail Zacharias Cc: common-lisp@SU-AI.ARPA Subject: comparisons between floats and ratios In-reply-to: Msg of 27 Jan 1986 08:42-EST from Gail Zacharias A not-entirely-unrelated question: What kind of rounding is FLOAT supposed to do? I think that the GOAL is to produce the closest approximation to the ratio that is possible in a given floating-point format. That's what implementors should shoot for. Whether it makes sense to REQUIRE this in the very last bit is less clear. I don't think I've ever seen a floating-point package that got this right all the time. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 27 Jan 86 10:45:07 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 27 Jan 86 07:37:10 PST Received: ID ; Mon 27 Jan 86 10:37:58-EST Date: Mon, 27 Jan 1986 10:37 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Gail Zacharias Cc: common-lisp@SU-AI.ARPA Subject: comparisons between floats and ratios In-reply-to: Msg of 27 Jan 1986 08:42-EST from Gail Zacharias Is (> a-rational a-float) supposed to err out when (float a-rational a-float) would overflow? If so, there should at least be some way to tell ahead of time if that's going to happen, for people who want to write a more careful comparison routine. Sounds like a job for the error system (a proposal for which KMP is supposed to have ready soon). Better to intercept this rare overflow problem when it occurs, and when you actually care, than to slow down the universe by trying to prevent it.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 27 Jan 86 09:53:03 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 27 Jan 86 06:44:30 PST Received: ID ; Mon 27 Jan 86 09:44:46-EST Date: Mon, 27 Jan 1986 09:44 EST Message-ID: From: Rob MacLachlan To: common-lisp@SU-AI.ARPA Subject: Compiler side effects lossage Cc: Kjeld Hvatum In-reply-to: Msg of 26 Jan 1986 22:39-EST from Kjeld Hvatum From: Steve Bacher (CSDL) To: Robert Elton Maas Subject: Compiler side effects lossage The user will simply have to wrap an (eval-when (compile ...)) around the ancillary DEFstuff - and this implies that the way the compiler treats DEFUN, DEFMACRO, etc. *cannot* be desribed as a case of an implicit (eval-when (compile)). Which means that I must take issue with the earlier statement of Rob MacLachlan's that there's no way to override the implicit eval-whenitude of DEFUN et al. Actually this is exactly my point. I was arguing that such forms should not be considered to have an implicit (eval-when (compile)); if they really did there would be no way to inhibit the compile-time evaluation. This is more a statement about the language which should be used in the definition than it is about the semantics of Common Lisp. Rob  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 27 Jan 86 08:49:51 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 27 Jan 86 05:43:29 PST Date: Mon 27 Jan 86 08:42:53-EST From: "Gail Zacharias" Subject: comparisons between floats and ratios To: common-lisp@SU-AI.ARPA Message-ID: <12178573608.22.GZ@OZ.AI.MIT.EDU> Is (> a-rational a-float) supposed to err out when (float a-rational a-float) would overflow? If so, there should at least be some way to tell ahead of time if that's going to happen, for people who want to write a more careful comparison routine. The only way I can figure out of doing this now is (> a-ratio (rational most-positive-xx-float)). Consing up a bignum representation of the largest float seems like a high price to pay for being careful. Since most floating point implementations can (internally at least) represent infinity, it shouldn't cause a great loss of efficiency to require that this case return T. A not-entirely-unrelated question: What kind of rounding is FLOAT supposed to do? -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 26 Jan 86 22:45:57 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 26 Jan 86 19:38:58 PST Date: Sun, 26 Jan 86 22:39:53 EST From: Kjeld Hvatum To: common-lisp@SU-AI.ARPA Message-ID: <[MC.LCS.MIT.EDU].796915.860126.KSH> From: Steve Bacher (CSDL) To: Robert Elton Maas Subject: Compiler side effects lossage It sounds like your compiler used the C... properties exclusively, refusing to use normal propertis {sic} even when the C... property didn't exist. I can't speak for Charles Hedrick or his compiler, but I do know that this problem can definitely occur even when the property masking you describe is in use. Consider the case of a DEFMACRO which references a function defined via DEFUN (or DEFMACRO, etc.) in the same file. If the compiler dutifully assigns a CMACRO or CFUNCTION property for the function in question, then invokes MACROEXPAND on the macro definition associated with the first DEFMACRO, you should expect to run into trouble if your macroexpander uses the standard evaluator, since that one, as described, WILL NOT find compiler-generated defs like CFUNCTION. Now, unless you want to rewrite the evaluator for the compiler to process Cfrobs, you can't get around this. The user will simply have to wrap an (eval-when (compile ...)) around the ancillary DEFstuff - and this implies that the way the compiler treats DEFUN, DEFMACRO, etc. *cannot* be desribed as a case of an implicit (eval-when (compile)). Which means that I must take issue with the earlier statement of Rob MacLachlan's that there's no way to override the implicit eval-whenitude of DEFUN et al. Lest you believe that this is all idle speculation and windbagging, let me point out that this is essentially how I have structured my LISP compiler, and this problem does come up despite the best of intentions. (Another screw case is defining SETF methods.) - Steve Bacher  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 26 Jan 86 22:26:24 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 26 Jan 86 19:20:01 PST Date: Sun, 26 Jan 86 22:20:54 EST From: "George J. Carrette" Subject: precision vs more information To: fateman@DALI.BERKELEY.EDU cc: common-lisp@SU-AI.ARPA, Moon@SCRC-STONY-BROOK.ARPA In-reply-to: Msg of Sun 26 Jan 86 14:13:29 PST from fateman at dali.berkeley.edu (Richard Fateman) Message-ID: <[MC.LCS.MIT.EDU].796884.860126.GJC> If you go from a floating point number to a ratio you lose information, the information that the number is an approximation. Exactly how much of an approximation is hard to tell of course because it depends on the computational history of the quantity. But the fact that it is a floating point number can be dangerous information to loose so easily. This about this: (defun s (t) (* 1/2 g (^ t 2))) The 1/2 has been introduced do to a process of symbolic integration. Why should it affect the form of the answer to a formula? Returning a floating point number tells you that the result might not be the right answer. But with rational arithmetic you can be sure of getting simply meaningful mathematic results from your formuli.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 26 Jan 86 17:21:03 EST Received: from UCBVAX.BERKELEY.EDU by SU-AI.ARPA with TCP; 26 Jan 86 14:13:22 PST Received: by ucbvax.berkeley.edu (5.44/1.8) id AA01884; Sun, 26 Jan 86 14:13:36 PST Received: by dali.berkeley.edu (5.44/5.16) id AA19482; Sun, 26 Jan 86 14:13:29 PST Date: Sun, 26 Jan 86 14:13:29 PST From: fateman@dali.berkeley.edu (Richard Fateman) Message-Id: <8601262213.AA19482@dali.berkeley.edu> To: Moon@scrc-stony-brook.arpa Subject: more boring-to-most-people floating point stuff Cc: common-lisp@su-ai.arpa The example (/ (expt 10 68) 1.0e38) is illustrating ( ) whereas (/ (* 1.0e34 1.0e34) 1.0e38) is illustrating (recursively) ( ) . Only when you combine two number types, one majorizing the other, do you face this issue. The intent when combining different precisions (and ranges) within floats is clear. You coerce to the longer precision because it is likely to give you the right answer. Not the fastest. A reasonable extension of this is if you mix floats with even longer precision numbers (i.e., rational), you convert to rational, because it gives you the right answer, not the fastest. You can, of course, promote the notion that "anything goes" as soon as exact and approximate numeric types are mixed, or claim that it would be too costly to do the right thing. To say this is the wrong forum for this is to appear at odds with the space devoted to this and other numeric data types in the language specification.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 26 Jan 86 16:31:50 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 26 Jan 86 13:24:45 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 401792; Sun 26-Jan-86 16:23:56-EST Date: Sun, 26 Jan 86 16:24 EST From: David A. Moon Subject: Re: comparisons between floats and ratios To: Richard Fateman cc: common-lisp@SU-AI.ARPA In-Reply-To: <8601250500.AA05647@dali.berkeley.edu> Message-ID: <860126162435.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Fri, 24 Jan 86 21:00:53 PST From: fateman@dali.berkeley.edu (Richard Fateman) I remain unconvinced, and a private note from Cassels also didn't help. (My mailing system was unable to send to Cassels individually, so here is a simplified response ) consider (/ (expt 10 68) 1.0E38) . The numerator overflows when you convert to floating point. The quotient is representable. I think that CL should err on the side of slow&correct. How is this example different from (/ (* 1.0e34 1.0e34) 1.0E38) ? If you want to campaign against the widespread misimpression that floating point is foolproof way to do numerical calculations, that's a fine thing, but I think this is the wrong mailing list.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 25 Jan 86 00:08:25 EST Received: from UCBVAX.BERKELEY.EDU by SU-AI.ARPA with TCP; 24 Jan 86 21:00:46 PST Received: by ucbvax.berkeley.edu (5.44/1.8) id AA04759; Fri, 24 Jan 86 21:00:59 PST Received: by dali.berkeley.edu (5.44/5.16) id AA05647; Fri, 24 Jan 86 21:00:53 PST Date: Fri, 24 Jan 86 21:00:53 PST From: fateman@dali.berkeley.edu (Richard Fateman) Message-Id: <8601250500.AA05647@dali.berkeley.edu> To: Fahlman@c.cs.cmu.edu, common-lisp@su-ai.arpa Subject: Re: comparisons between floats and ratios Subject: Re: comparisons between floats and ratios I remain unconvinced, and a private note from Cassels also didn't help. (My mailing system was unable to send to Cassels individually, so here is a simplified response ) consider (/ (expt 10 68) 1.0E38) . The numerator overflows when you convert to floating point. The quotient is representable. I think that CL should err on the side of slow&correct. While Cassel's solution to comparisons, by looking at overflows should be ok, it won't solve the above problem. Anyone who writes (+ x 1) when he means (+ x 1.0) can be warned or should pay the cost. Anyone who wants to AVOID conversions to mathematically reliable answers can easily insist on sloppy floats.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 24 Jan 86 22:53:10 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 24 Jan 86 19:45:54 PST Received: ID ; Fri 24 Jan 86 22:17:03-EST Date: Fri, 24 Jan 1986 21:41 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: common-lisp@SU-AI.ARPA Subject: comparisons between floats and ratios In-reply-to: Msg of 24 Jan 1986 19:20-EST from Robert A. Cassels The phrase that Fateman spotted on page 194 occurs in the middle of a discussion of FLOATING-POINT contagion rules. I think there is no suggestion, explicit or implicit, that as things currently stand this rule is meant to cover other kinds of numbers. Of course, it is legitimate to propose that we consider extending the rule in this way. After thinking about it a bit, I agree with Cassels on this. Coercing a float/rational operation to produce a rational is certainly going to lead to a lot of needless inefficiency and confusion, just to get rid of a paradox that most of us don't view as being paradoxical at all. And it just doesn't seem reasonable to me -- it's a bit like trying to restore the number's virginity. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 24 Jan 86 22:43:47 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 24 Jan 86 16:18:39 PST Received: from CUYAHOGA.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 401241; Fri 24-Jan-86 19:18:12-EST Date: Fri, 24 Jan 86 19:20 EST From: Robert A. Cassels Subject: comparisons between floats and ratios To: fateman@dali.berkeley.edu, common-lisp@SU-AI.ARPA In-Reply-To: <8601242025.AA29507@dali.berkeley.edu> Message-ID: <860124192014.5.CASSELS@CUYAHOGA.SCRC.Symbolics.COM> Reply-To: Robert A. Cassels Date: Fri, 24 Jan 86 12:25:47 PST From: fateman@dali.berkeley.edu (Richard Fateman) There is a rule (top of p 194, CLtL) indicating that CL preserves "as much accuracy as possible" (although not guaranteeing it). Thus when two numeric values are operated upon, the coercion is to the larger precision, which tends to preserve more accuracy. To be consistent with this rule, operations which combine floats of any precision with ratios should convert floats to ratios, not the reverse. By introducing a floating-point number into a computation, you're introducing a [hopefully] controlled inaccuracy. CLtL is just trying to preserve that amount of inaccuracy. Any float (except possibly IEEE NaN and infinity) can be converted to a ratio without loss of precision. (and Nan=0/0, inf = 1/0 might even be used). Of course the rational answer could be re-floated if required. This would solve the problem of incorrect equality of 0.0 with a non-zero but small ratio which "underflows". Now consider comparing the floating point number 0.5 with an integer sufficiently large as to overflow the exponent range of floats. The comparison is "an error", according to CLtL (p 194). If one is to ensure correct handling of the large number of numeric data types in the language specification, I think the comparison should return the mathematically correct answer. (Alternatively, one could consider re-building all built-in functions for applications like Macsyma.) You bring up three issues: - the coercion rules for mixed-type operations (+, -, *, etc.) - the coercion rules for mixed-type comparisons (=, <, etc.) - "correct answers" for mixed-type comparisons vs. blowing out I believe that although they are related, they are orthogonal. So I will discuss them separately. I don't think that you really want the coercion rules for operations to prefer rational arithmetic to floating-point. Consider that (+ x 1) will leave you with a rational result. Remember that rational canonicalization means you can't distinguish a "ratio" 1/1 from an integer 1. You'd have to be incredibly compulsive to keep your computations from consing ratios and taking forever. The reason we keep floating-point around is to do computations efficiently. By introducing a float, you're saying, "I know the answer might not be exactly correct, but I know what I'm doing -- just give me an answer, and give it to me fast." [-: I do know that a lot of people who use floating-point don't know what they're doing. But we should pretend they do. :-] You might want comparisons to be done rationally, although pretending that 0.0 is the same as 0 seems foolish to me. And the efficiency issue remains, since (< x 1) would most likely cons you a ratio of bigna. I do agree that you'd like to get answers to any comparison that doesn't involve NaNs. But that's possible even with the current CLtL coercion rules. In the next release of the Symbolics system, mixed-type comparisons are done in floating-point ala CLtL, but over- and underflow are accounted for so that "correct" answers are always given.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 24 Jan 86 19:36:17 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 24 Jan 86 16:18:39 PST Received: from CUYAHOGA.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 401241; Fri 24-Jan-86 19:18:12-EST Date: Fri, 24 Jan 86 19:20 EST From: Robert A. Cassels Subject: comparisons between floats and ratios To: fateman@dali.berkeley.edu, common-lisp@SU-AI.ARPA In-Reply-To: <8601242025.AA29507@dali.berkeley.edu> Message-ID: <860124192014.5.CASSELS@CUYAHOGA.SCRC.Symbolics.COM> Reply-To: Robert A. Cassels Date: Fri, 24 Jan 86 12:25:47 PST From: fateman@dali.berkeley.edu (Richard Fateman) There is a rule (top of p 194, CLtL) indicating that CL preserves "as much accuracy as possible" (although not guaranteeing it). Thus when two numeric values are operated upon, the coercion is to the larger precision, which tends to preserve more accuracy. To be consistent with this rule, operations which combine floats of any precision with ratios should convert floats to ratios, not the reverse. By introducing a floating-point number into a computation, you're introducing a [hopefully] controlled inaccuracy. CLtL is just trying to preserve that amount of inaccuracy. Any float (except possibly IEEE NaN and infinity) can be converted to a ratio without loss of precision. (and Nan=0/0, inf = 1/0 might even be used). Of course the rational answer could be re-floated if required. This would solve the problem of incorrect equality of 0.0 with a non-zero but small ratio which "underflows". Now consider comparing the floating point number 0.5 with an integer sufficiently large as to overflow the exponent range of floats. The comparison is "an error", according to CLtL (p 194). If one is to ensure correct handling of the large number of numeric data types in the language specification, I think the comparison should return the mathematically correct answer. (Alternatively, one could consider re-building all built-in functions for applications like Macsyma.) You bring up three issues: - the coercion rules for mixed-type operations (+, -, *, etc.) - the coercion rules for mixed-type comparisons (=, <, etc.) - "correct answers" for mixed-type comparisons vs. blowing out I believe that although they are related, they are orthogonal. So I will discuss them separately. I don't think that you really want the coercion rules for operations to prefer rational arithmetic to floating-point. Consider that (+ x 1) will leave you with a rational result. Remember that rational canonicalization means you can't distinguish a "ratio" 1/1 from an integer 1. You'd have to be incredibly compulsive to keep your computations from consing ratios and taking forever. The reason we keep floating-point around is to do computations efficiently. By introducing a float, you're saying, "I know the answer might not be exactly correct, but I know what I'm doing -- just give me an answer, and give it to me fast." [-: I do know that a lot of people who use floating-point don't know what they're doing. But we should pretend they do. :-] You might want comparisons to be done rationally, although pretending that 0.0 is the same as 0 seems foolish to me. And the efficiency issue remains, since (< x 1) would most likely cons you a ratio of bigna. I do agree that you'd like to get answers to any comparison that doesn't involve NaNs. But that's possible even with the current CLtL coercion rules. In the next release of the Symbolics system, mixed-type comparisons are done in floating-point ala CLtL, but over- and underflow are accounted for so that "correct" answers are always given.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 24 Jan 86 16:14:00 EST Received: from UCBVAX.BERKELEY.EDU by SU-AI.ARPA with TCP; 24 Jan 86 12:57:59 PST Received: by ucbvax.berkeley.edu (5.44/1.7) id AA26935; Fri, 24 Jan 86 12:56:18 PST Received: by dali.berkeley.edu (5.44/5.16) id AA29507; Fri, 24 Jan 86 12:25:47 PST Date: Fri, 24 Jan 86 12:25:47 PST From: fateman@dali.berkeley.edu (Richard Fateman) Message-Id: <8601242025.AA29507@dali.berkeley.edu> To: common-lisp@su-ai.arpa Subject: comparisons between floats and ratios There is a rule (top of p 194, CLtL) indicating that CL preserves "as much accuracy as possible" (although not guaranteeing it). Thus when two numeric values are operated upon, the coercion is to the larger precision, which tends to preserve more accuracy. To be consistent with this rule, operations which combine floats of any precision with ratios should convert floats to ratios, not the reverse. Any float (except possibly IEEE NaN and infinity) can be converted to a ratio without loss of precision. (and Nan=0/0, inf = 1/0 might even be used). Of course the rational answer could be re-floated if required. This would solve the problem of incorrect equality of 0.0 with a non-zero but small ratio which "underflows". Now consider comparing the floating point number 0.5 with an integer sufficiently large as to overflow the exponent range of floats. The comparison is "an error", according to CLtL (p 194). If one is to ensure correct handling of the large number of numeric data types in the language specification, I think the comparison should return the mathematically correct answer. (Alternatively, one could consider re-building all built-in functions for applications like Macsyma.)  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 24 Jan 86 02:07:39 EST Received: from MC.LCS.MIT.EDU by SU-AI.ARPA with TCP; 23 Jan 86 22:53:22 PST Date: Fri, 24 Jan 86 01:54:14 EST From: "Glenn S. Burke" Subject: common-lisp loop To: common-lisp@SU-AI.ARPA Message-ID: <[MC.LCS.MIT.EDU].794262.860124.GSB> A group at DEC in Hudson had one which had been derived from, i think, the source used in Symbolics release 5.something. I had been going to look it over, but never did; i no longer know where i put the source, if i ever had it online. If someone at hudson could get ahold of this from the natural language group (or linguistics or somesuch) i could check it to see if it really did correspond to a fairly recent loop. (They are the group a couple rows of cubicles over from the vaxlisp people, at least during the summer. I was over there once but all the vaxlisp people were out partying or something.) If not i suppose i could just sit down with the latest source and do the conversion.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 24 Jan 86 00:36:15 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 23 Jan 86 21:23:48 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 400276; Fri 24-Jan-86 00:23:22-EST Date: Fri, 24 Jan 86 00:23 EST From: David A. Moon Subject: [vrotney@isi-vaxa.ARPA: Forwarded] To: common-lisp@SU-AI.ARPA In-Reply-To: <860123163356.1.GLS@THINK-QUENTIN.ARPA> Message-ID: <860124002342.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Thu, 23 Jan 86 16:33 EST From: Guy Steele Can anyone help with the following problem? Date: Wed, 22 Jan 86 18:00:58 pst From: vrotney@isi-vaxa.ARPA (Bill Vrotney) I need a public domain loop macro that is roughly equivalent to the Zetalisp version, but will compile under Common Lisp. I don't have one, but if someone wants to write one I may be able to offer some guidance. I'd like to see it redesigned, but perhaps there is enough demand for a simple reimplementation in Common Lisp of the existing specification.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 23 Jan 86 22:00:10 EST Received: from SU-GLACIER.ARPA by SU-AI.ARPA with TCP; 23 Jan 86 18:47:28 PST Received: by glacier with Sendmail; Thu, 23 Jan 86 18:46:49 pst Received: from escargot.UUCP (escargot.ARPA) by mips.UUCP (4.12/4.7) id AA29948; Thu, 23 Jan 86 13:57:02 pst Received: by escargot.UUCP (4.12/4.7) id AA23779; Thu, 23 Jan 86 13:56:39 pst Date: Thu, 23 Jan 86 13:56:39 pst From: mips!escargot.earl@glacier (Earl Killian) Message-Id: <8601232156.AA23779@escargot.UUCP> To: DLW@SCRC-QUABBIN.ARPA Cc: COMMON-LISP@SU-AI.ARPA In-Reply-To: Daniel L. Weinreb's message of Fri, 17 Jan 86 19:28 EST Subject: time of evaluation Date: Fri, 17 Jan 86 19:28 EST From: Daniel L. Weinreb ... (1) The files being compiled see an empty Lisp environment when the compilation starts. The Lisp environment that called compile-file is untouched. ... Personally, I would find style (1) to be painful and inconvenient even if my machine could switch to a new Lisp environment in two nanoseconds, because I want the compilation to see the state in my Lisp environment. Think of people who define their favorite macros in their init files, who would then have to create some sort of "compiler init file" to set up the compilation environment for all of their programs, as a simple example. It is annoying to start out in a empty environment, but it is the only way you'll get people to write portable stuff. If compiling a file something implicitly depends on their favorite personal macros, then nobody else can use it. On the other hand, all that's required to live with the empty compiler environment is (REQUIRE DLW-DEFINITIONS). You just get in the habit of putting that in every file you create...  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 23 Jan 86 16:44:12 EST Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 23 Jan 86 13:33:20 PST Received: from quentin by GODOT.THINK.COM via CHAOS; Thu, 23 Jan 86 16:33:01 est Date: Thu, 23 Jan 86 16:33 EST From: Guy Steele Subject: [vrotney@isi-vaxa.ARPA: Forwarded] To: common-lisp@SU-AI.ARPA Cc: gls@THINK-AQUINAS.ARPA Message-Id: <860123163356.1.GLS@THINK-QUENTIN.ARPA> Can anyone help with the following problem? --Guy Date: Wed, 22 Jan 86 18:00:58 pst From: vrotney@isi-vaxa.ARPA (Bill Vrotney) Guy Steele, I am implementing our FSD on the HP 9000 machines in Common Lisp. I need a public domain loop macro that is roughly equivalent to the Zetalisp version, but will compile under Common Lisp. I copied over M.I.T.'s loop macro, but Common Lisp doesn't seem to have the "*features*" that it needs. Do you know of any such public domian loop macro designed for Common Lisp? Bill Vrotney USC/Information Sciences Institute vrotney@ISI-VAXA.ARPA  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 23 Jan 86 10:04:47 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 23 Jan 86 06:57:39 PST Received: ID ; Thu 23 Jan 86 09:58:31-EST Date: Thu, 23 Jan 1986 09:58 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Rene Bach Cc: common-lisp@SU-AI.ARPA Subject: Spelling correction In-reply-to: Msg of 22 Jan 1986 20:16-EST from Rene Bach I agree that a set of simple spelling error detection/correction facilities would make a useful addition to the Yellow pages. If people eventually decide that these things are universally used, we could move them into the standard language at that time. We already have such a package built into Hemlock, though I'm not sure how easy it would be to extract it. I have a hunch that a list of legal words is not the best possible interface to this thing. You want to have a spelling dictionary object type that can be built from a set of words, and that can be modified later. Probably once this reaches a certain size you want this object to be a hash-table or balanced binary tree or something like that, and not a simple list. The spell checking and correcting functions would operate on one of these objects, and not on the raw word-list. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 23 Jan 86 01:35:46 EST Received: from UTAH-CS.ARPA by SU-AI.ARPA with TCP; 22 Jan 86 20:48:31 PST Received: from utah-orion.ARPA by utah-cs.ARPA (5.5/4.40.2) id AA10541; Wed, 22 Jan 86 21:49:10 MST Received: by utah-orion.ARPA (5.5/4.40.2) id AA20265; Wed, 22 Jan 86 21:49:06 MST Date: Wed, 22 Jan 86 21:49:06 MST From: shebs%utah-orion@utah-cs.arpa (Stanley Shebs) Message-Id: <8601230449.AA20265@utah-orion.ARPA> To: common-lisp@su-ai.arpa Subject: Re: Spelling correction I can't get really enthused about spelling correction, even if it's just a pair of relatively innocuous functions. Common Lisp is already pretty fat ("pleasingly plump"?), and spelling correction really falls into a gray area, if one applies the agreed-upon inclusion criteria. Yellow pages seems appropriate, unless someone wants to argue that implementors can make it significantly better by doing implementation dependent hacks? stan  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 22 Jan 86 23:56:04 EST Received: from UTAH-CS.ARPA by SU-AI.ARPA with TCP; 22 Jan 86 20:48:31 PST Received: from utah-orion.ARPA by utah-cs.ARPA (5.5/4.40.2) id AA10541; Wed, 22 Jan 86 21:49:10 MST Received: by utah-orion.ARPA (5.5/4.40.2) id AA20265; Wed, 22 Jan 86 21:49:06 MST Date: Wed, 22 Jan 86 21:49:06 MST From: shebs%utah-orion@utah-cs.arpa (Stanley Shebs) Message-Id: <8601230449.AA20265@utah-orion.ARPA> To: common-lisp@su-ai.arpa Subject: Re: Spelling correction I can't get really enthused about spelling correction, even if it's just a pair of relatively innocuous functions. Common Lisp is already pretty fat ("pleasingly plump"?), and spelling correction really falls into a gray area, if one applies the agreed-upon inclusion criteria. Yellow pages seems appropriate, unless someone wants to argue that implementors can make it significantly better by doing implementation dependent hacks? stan  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 22 Jan 86 20:46:02 EST Received: from SU-SCORE.ARPA by SU-AI.ARPA with TCP; 22 Jan 86 17:37:02 PST Date: Wed 22 Jan 86 17:16:26-PST From: Rene Bach Subject: Re: Spelling correction To: DDYER@SCRC-RIVERSIDE.ARPA cc: DCP@SCRC-QUABBIN.ARPA, common-lisp@SU-AI.ARPA In-Reply-To: <860122132621.2.DDYER@PURPLE.SWW.Symbolics.COM> Message-ID: <12177389147.33.BACH@SU-SCORE.ARPA> Thank you. I have been waiting until the first burst of comments subsided before coming back. Yes. what I really had in mind were the equivalent of FIXSPELL and MISSPELLED? (see interlisp manual, in the 1978 edition it's page 17.18, for a specification of those functions. I'll type in the specs if asked to do so.) And I am not a LISP developer, but I am a user. I use LISP to write expert systems and believe that Common Lisp should be a helpful tool for the researchers in the different areas of AI. Thus many of the comments about DWIM and code development issues were somewhat off. I believe that FIXSPELL and MISSPELLED? functions have a wide range of utility and deserve to be included in C-L. Think of them as being smart equivalent of the MEMBER function. -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 22 Jan 86 16:35:25 EST Received: from SCRC-QUABBIN.ARPA by SU-AI.ARPA with TCP; 22 Jan 86 13:24:41 PST Received: from WHITE.SWW.Symbolics.COM by SCRC-QUABBIN.ARPA via CHAOS with CHAOS-MAIL id 237773; Wed 22-Jan-86 16:23:02-EST Received: from PURPLE.SWW.Symbolics.COM by WHITE.SWW.Symbolics.COM via CHAOS with CHAOS-MAIL id 168110; Wed 22-Jan-86 13:24:03-PST Date: Wed, 22 Jan 86 13:26 PST From: DDYER@SCRC-RIVERSIDE.ARPA Subject: Spelling correction To: David C. Plummer , Rene Bach , common-lisp@SU-AI.ARPA Fcc: W:>ddyer>mail.sent In-Reply-To: <860120135654.9.DCP@NEPONSET.SCRC.Symbolics.COM> Message-ID: <860122132621.2.DDYER@PURPLE.SWW.Symbolics.COM> Fonts: CPTFONT, CPTFONTB, CPTFONTI Date: Mon, 20 Jan 86 13:56 EST From: David C. Plummer Date: Mon 20 Jan 86 09:48:22-PST From: Rene Bach I am new on this list (please forgive me if this topic has been discussed already). It has been our experience that using the spelling correction facilities provided by Interlisp are very useful to provide nice user interfaces. It is also my belief that to do flexible symbol matching requires spelling correction. My question is: why doesn't CL include a specification for a spelling correction function. The description of the Interlisp functions could be used as specification for the I/O. The choice of the algorithm could be left open. Base my following reaction on never having used Interlisp but only heard about it and some of its 'features.' You are somewhat under-informed about the Interlisp spelling corrector. Here's the straight scoop from one who knows. Underlying everything, Interlisp has a function called FIXSPELL which has lots of optional arguments, but which essentially checks a "misspelled" symbol against a specified list of possible corrections. The parameters control how FIXSPELL responds to spelling errors or various degrees of severity. Depending on the various severity thresholds and the response specification, FIXSPELL can return a "correction" without comment, with a comment/warning message, with a Y-OR-N-P type response, or with an error. Interlisp has several mechanisms for automatically maintaining "spelling lists"; for example, it keeps a lists of "system" functions "system" variables, "user" functions and "user" variables. DWIM is an entirely separate facility, which among other things, can invoke FIXSPELL to attempt to find a correction. This is the use of the spelling corrector which is most often encountered by the casual Interlisp user. Forms you type to a lisp listener are passed to DWIM if an error occurs, and (various switches permitting) FIXSPELL can be invoked to find semantically reasonable corrections. DWIM (and therefore FIXSPELL) are also invoked by the compiler. Due to the form-based nature of Interlisp's environment, changes made by DWIM are automatically propagated to the sources. 2All 0changes made by DWIM are undoable. Summary: FIXSPELL is a utility which we could use. DWIM is a completely separate facility, which is controversial even within the Interlisp community. Most of use have a love/hate relationship with it, but few choose to turn it off. ---- The only 'spelling corrector' I've heard of in Interlisp is a DWIM facility to change the name of variables out from under you because you mistyped them. I don't believe in that kind of programming, since that will, among other things, hide bugs that will resurface indefinitely later if you happen to name a variable the same as your previous misspelling. This is a misconception; DWIM (as used by the compiler) actually fixes the sources, so the bug won't resurface later. The choice to fix the sources "silently" "noisily" or "with confirmation only" is available to the user. The really important thing you apparently didn't know is that when DWIM fixes something it2 stays0 fixed; So today's Error-fixed-by-dwim doesn't become tomorrow's non-bug because *BAX* is now defined. For example, if in a lispm compilation you get the warning "Function foo-bax-mumble is undefined", DWIM might instead have run an interaction such as Function FOO-BAX-MUMBLE is undefined. Do you mean FOO-BAR-MUMBLE? and if you respond Y, it fixes the source for you once and for all. I always found this extremely user-friendly, since DWIM was almost always right and since it saved me the trouble of doing another edit-compile cycle.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 21 Jan 86 14:01:57 EST Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 21 Jan 86 08:36:20 PST Received: from yon by GODOT.THINK.COM via CHAOS; Tue, 21 Jan 86 11:36:09 est Date: Tue, 21 Jan 86 11:36 EST From: Guy Steele Subject: Spelling correction To: DCP@SCRC-QUABBIN.ARPA, BACH@SU-SCORE.ARPA, common-lisp@SU-AI.ARPA Cc: gls@THINK-AQUINAS.ARPA In-Reply-To: <860120135654.9.DCP@NEPONSET.SCRC.Symbolics.COM> Message-Id: <860121113658.6.GLS@THINK-YON.ARPA> Date: Mon, 20 Jan 86 13:56 EST From: David C. Plummer Date: Mon 20 Jan 86 09:48:22-PST From: Rene Bach ... My question is: why doesn't CL include a specification for a spelling correction function. The description of the Interlisp functions could be used as specification for the I/O. The choice of the algorithm could be left open. Base my following reaction on never having used Interlisp but only heard about it and some of its 'features.' The only 'spelling corrector' I've heard of in Interlisp is a DWIM facility to change the name of variables out from under you because you mistyped them. Let me observe that there are several distinct things that may be desired: (1) DETECTION of spelling errors (2) CORRECTION of spelling errors. (2) PREVENTION of spelling errors. The correction process may proceed in different ways depending on how the error was detected. In some cases it is easier to prevent the error in the first place. The most general way in which spelling errors are "detected" is that a compiler warning or interpreter error is issued, and maybe you get a debugging breakpoint. This is not always the easiest way to correct the error. The Symbolics implementation handles undefined variables and functions at top level in a more useful way. First of all, it looks around in other packages to see whether a different symbol of the same name has the appropriate definition; if so, it offers to make the substitution. This is a kind of spelling correction (the package name having been "misspelled"). Failing that, it prints a warning and offers the opportunity to type a rubout or other input editor command rather than having to go through the heavy-duty debugger. Here at TMC we have an additional hack that allows the key to operate in nearly all contexts, including the top level. Frequently I need only type R E N to get "RENAME-WITHIN-NEW-DEFINITION-MAYBE" on the screen. This is spelling correction before the fact rather than after. It would be easy, in a similar manner, to make (or Meta-$) examine the previous word and apply a spelling-correction algorithm to it. This is explicit correction rather than implicit. So there are many styles for dealing with the spelling problem. I think it would be premature to standardize on any one. --Guy  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 21 Jan 86 13:48:45 EST Received: from HPLABS.ARPA by SU-AI.ARPA with TCP; 21 Jan 86 10:38:51 PST Received: from HP-HULK by hplabs.ARPA ; Tue, 21 Jan 86 10:37:24 pst Date: Tue 21 Jan 86 10:37:59-PST From: SCHUMACHER%HP-HULK@HPLABS To: common-lisp@su-ai.ARPA -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 20 Jan 86 14:00:30 EST Received: from SCRC-QUABBIN.ARPA by SU-AI.ARPA with TCP; 20 Jan 86 10:52:39 PST Received: from NEPONSET.SCRC.Symbolics.COM by SCRC-QUABBIN.ARPA via CHAOS with CHAOS-MAIL id 236886; Mon 20-Jan-86 13:51:40-EST Date: Mon, 20 Jan 86 13:56 EST From: David C. Plummer Subject: Spelling correction To: Rene Bach , common-lisp@SU-AI.ARPA In-Reply-To: <12176783291.16.BACH@SU-SCORE.ARPA> Message-ID: <860120135654.9.DCP@NEPONSET.SCRC.Symbolics.COM> Date: Mon 20 Jan 86 09:48:22-PST From: Rene Bach I am new on this list (please forgive me if this topic has been discussed already). It has been our experience that using the spelling correction facilities provided by Interlisp are very useful to provide nice user interfaces. It is also my belief that to do flexible symbol matching requires spelling correction. My question is: why doesn't CL include a specification for a spelling correction function. The description of the Interlisp functions could be used as specification for the I/O. The choice of the algorithm could be left open. Base my following reaction on never having used Interlisp but only heard about it and some of its 'features.' The only 'spelling corrector' I've heard of in Interlisp is a DWIM facility to change the name of variables out from under you because you mistyped them. I don't believe in that kind of programming, since that will, among other things, hide bugs that will resurface indefinitely later if you happen to name a variable the same as your previous misspelling. Errors should be signalled. DWIMing is a function of the application program only (provided CL had an error system to deal with errors) and is not a function of the system itself. For example, if I mistyped *BAX* when I meant *BAZ* I want an error. Someday I may legally define *BAX*. [Shift to programming enviroments...] I also make use of the compiler to tell me when variables are unknown and declared special (which is the most common manifestation of my misspellings) and functions being called that aren't defined. If there is a spelling corrector of this type, it should be integrated into the system at the user-interface level, which is probably out of bounds for CLtL.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 20 Jan 86 13:32:11 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 20 Jan 86 10:23:08 PST Received: ID ; Mon 20 Jan 86 13:23:11-EST Date: Mon, 20 Jan 1986 13:23 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Rene Bach Cc: common-lisp@SU-AI.ARPA Subject: Spelling correction In-reply-to: Msg of 20 Jan 1986 12:48-EST from Rene Bach Common Lisp deliberately specifies very little about the top-level command loop. This is so that many "cultures" (styles of dealing with the machine) can be supported on top of a common language that allows code packages to be shared. The overwhelming majority of Common Lisp implementors and users, at least at the start, come from the Maclisp tradition in which code is created by the use of some text editor, usually Emacs-like and usually written in the Lisp itself. CMU's Hemlock editor is a public-domain implementation of such a thing. It is not 100% portable, since it depends on the host system's screen management, but the majority of Common Lisp vendors who do not already have a good Emacs implementation on their machines are importing Hemlock. Most of these Emacs-like systems provide the user with an editor top-level mode, in which expressions are created within the editor and then are passed into the Lisp for evaluation. This provides full editing power (including spelling correction, word abbreviation mode, and the like) plus a buffer that records the history of the session. Instead of using a specialized mechanism for repeating and altering earlier commands, you just grab what you want from the buffer and fix it up before transmitting it to the Lisp. Anyone who is more comfortable with the Interlisp style of structure editing, DWIM, Masterscope, history, etc., is free to implement this on top of Common Lisp, and I suspect that at least one manufacturer is going to follow this route (though I hope they eventually provide a Hemlock-style interface as well). One could argue the merits of the two styles, but the point for Common Lisp is that they can coexist happily and that we don't need to standardize on either of them. Portable code lives below this level. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 20 Jan 86 13:00:51 EST Received: from SU-SCORE.ARPA by SU-AI.ARPA with TCP; 20 Jan 86 09:51:48 PST Date: Mon 20 Jan 86 09:48:22-PST From: Rene Bach Subject: Spelling correction To: common-lisp@SU-AI.ARPA Message-ID: <12176783291.16.BACH@SU-SCORE.ARPA> I am new on this list (please forgive me if this topic has been discussed already). It has been our experience that using the spelling correction facilities provided by Interlisp are very useful to provide nice user interfaces. It is also my belief that to do flexible symbol matching requires spelling correction. My question is: why doesn't CL include a specification for a spelling correction function. The description of the Interlisp functions could be used as specification for the I/O. The choice of the algorithm could be left open. Regards Rene Bach -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 19 Jan 86 20:43:50 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 19 Jan 86 17:36:40 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 396264; Sun 19-Jan-86 20:17:28-EST Date: Sun, 19 Jan 86 20:17 EST From: David A. Moon Subject: floating point question To: David Bein cc: common-lisp@SU-AI.ARPA In-Reply-To: <506559328/bein@pyramid> Message-ID: <860119201711.4.MOON@EUPHRATES.SCRC.Symbolics.COM> Floating-point arithmetic is never exact, so I don't think it's any more surprising if (= 0.0 1/123456789123456789123456789123456789) than if (= 1.0 (+ 1.0 1e-10)).  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 19 Jan 86 20:13:17 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 19 Jan 86 16:58:13 PST Received: ID ; Sun 19 Jan 86 19:57:28-EST Date: Sun, 19 Jan 1986 19:57 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: David Bein Cc: common-lisp@SU-AI.ARPA Subject: floating point question In-reply-to: Msg of 19 Jan 1986 17:55-EST from David Bein I'm not sure why you are asking me specifically about this. Of all the people on the Common Lisp mailing list, I'm probably the one who cares the least about the fine points of floating-point roundoff hackery and related mathematicalia. But anyway... It is well known that floating point numbers are mere approximations to mathematical truth, due to roundoff error. So I see no paradox here. No Common Lisp ratio is strictly equal to zero (else it would be reduced to an integer), but it is quite possible to have one whose closest approximation in the domain of short-floats is 0.0. So what? There are an infinite number of other examples where, due to roundoff, two arithmetic expressions that are supposed to lead to identical results in fact produce slightly different floating point numbers. No paradox, just the result of dealing with an approximation. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 19 Jan 86 18:44:42 EST Received: from SRI-UNIX.ARPA by SU-AI.ARPA with TCP; 19 Jan 86 15:37:14 PST Received: by sri-unix.ARPA (4.12/4.16) id AA02136; Sun, 19 Jan 86 15:34:41 pst Received: by pyramid (4.12/3.14) id AA20488; Sun, 19 Jan 86 15:10:53 pst Date: 19 Jan 1986 14:55 PST From: David Bein Subject: floating point question To: fahlman@cmu-cs-spice.ARPA Cc: common-lisp@su-ai.ARPA Message-Id: <506559328/bein@pyramid> Scott: I am wondering about the following bizarre character of the Common Lisp treatment of floats and ratios when doing comparisons, specifically = .. Suppose that you have X and Y where x is a SINGLE-FLOAT and Y is a RATIO. Also suppose that X is 0.0. Mathematically speaking no ratio is 0. So, according to rules of floating point contagion, you are supposed to convert Y to be a SINGLE-FLOAT which may result in a SINGLE-FLOAT == 0.0 due to rounding all of which results in notions like floating point 0.0 equals a non-zero ratio due to conversion. If I take another approach for = and test that the float is indeed 0.0 and thus conclude that no ratio (by rules of ratio canonicalization) is 0, then I end up with anomalies like (= X Y) != (= X (FLOAT Y X)) which does seem strange, but from a mathematical point of view, (= X Y) in this case should be FALSE. What do you think? Please pardon me if this question has been asked and/or resolved in some previous mail. --David  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 17 Jan 86 21:23:17 EST Received: from HPLABS.ARPA by SU-AI.ARPA with TCP; 17 Jan 86 18:13:35 PST Received: by hplabs.ARPA ; Fri, 17 Jan 86 18:12:12 pst Date: Friday, January 17, 1986 18:10:18 From: snyder@hplabs.ARPA Subject: Re: time of evaluation To: common-lisp@SU-AI.ARPA In-Reply-To: <860117192843.4.DLW@CHICOPEE.SCRC.Symbolics.COM> X-Sent-By-Nmail-Version: 04-Nov-84 17:14:46 There's no reason that this solution, or any other internal implementation technique used in a Lisp system, should be cast in concrete for everyone. It's important to distinguish between the defined semantics of Common Lisp, and implementation techniques. However, if there are mechanisms being used to support side-effect-free (or at least "reduced side effect") file compilation, it would be nice if there were a portable interface by which those mechanisms could be accessed by language extensions (for example, object oriented programming extensions). It would also be nice if those mechanisms were as effective as we know how to (portably) make them. For example, I believe a side-effect avoiding mechanism should have the following properties: 1. It should distinguish forms being compiled from forms being interpreted during compilation (e.g., because the compiler is interpreted, or because a macro expansion function is interpreted, or because a break loop was entered). Only a form being compiled should look in a special place for macro definitions, for example. 2. It should distinguish between different invocations of compile-file, as might arise if one compile-file entered a break loop and the user started another compile-file while the first was still active. We might be able to standardize on minimum requirements for a mechanism for "reduced side-effect compilation". If the requirements are reasonable, we might also be able to standardize on that mechanism being used by default, with options provided to select other (nonstandard) techniques, as has been suggested. -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 17 Jan 86 19:54:58 EST Received: from SCRC-QUABBIN.ARPA by SU-AI.ARPA with TCP; 17 Jan 86 16:42:48 PST Received: from CHICOPEE.SCRC.Symbolics.COM by SCRC-QUABBIN.ARPA via CHAOS with CHAOS-MAIL id 236384; Fri 17-Jan-86 19:41:45-EST Date: Fri, 17 Jan 86 19:42 EST From: Daniel L. Weinreb Subject: compiler environment, how best to isolate side effects To: REM%IMSSS@SU-SCORE.ARPA, COMMON-LISP@SU-AI.ARPA cc: HEDRICK@RED.RUTGERS.EDU In-Reply-To: The message of 16 Jan 86 17:04-EST from Robert Elton Maas Message-ID: <860117194222.5.DLW@CHICOPEE.SCRC.Symbolics.COM> Your "C-property" stuff is an implementation-oriented description of what I referred to as a "subjunctive environment". Contrary your mail, what Hedrick said is NOT a "reasonable argument against" this. In Hedrick's system, macros were placed into the subjunctive environment, but functions were not. That's why users were confused no end. Had everything been put into the sujunctive environment, it would have worked fine. The Symbolics system right now is like what Hedrick describes, except that EVAL-WHEN is available. So users can carefully put EVAL-WHEN's around functions that are needed in the subjunctive environment, so that the macros that call them will work. Unfortunately, (1) you have to remember to put in the EVAL-WHEN's, and understand what they mean, and (2) when you do compile-file, the function is left around in your Lisp environment. While I haven't seen a lot of evidence of confused users, I agree that this is the sort of thing I'd expect to confuse people, since it's rather subtle. Doing the "subjunctive environment" would make everything work right without muss or fuss. We would have done it by now except that it's so hard to implement in this architecture. I'm getting pretty close to agreeing that this isn't something we can tackle easily by simply dictating a behavior in CLtL. Instead we'll have to come up with one or two conventions so that portability can be achieved.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 17 Jan 86 19:40:28 EST Received: from SCRC-QUABBIN.ARPA by SU-AI.ARPA with TCP; 17 Jan 86 16:28:42 PST Received: from CHICOPEE.SCRC.Symbolics.COM by SCRC-QUABBIN.ARPA via CHAOS with CHAOS-MAIL id 236379; Fri 17-Jan-86 19:28:08-EST Date: Fri, 17 Jan 86 19:28 EST From: Daniel L. Weinreb Subject: time of evaluation To: Fahlman@C.CS.CMU.EDU cc: common-lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860117192843.4.DLW@CHICOPEE.SCRC.Symbolics.COM> Date: Wed, 15 Jan 1986 20:27 EST From: "Scott E. Fahlman" I guess this business of stashing the compiler's state changes in funny undoable places is about the best you can do. I wouldn't like to see this solution cast in concrete for everyone, though. There's no reason that this solution, or any other internal implementation technique used in a Lisp system, should be cast in concrete for everyone. It's important to distinguish between the defined semantics of Common Lisp, and implementation techniques. The semantic question is what compile-file does vis a vis the Lisp environment in which compile-file is called. Revising my earlier twofold choice in light of something Moon said, there are three possibilities: (1) The files being compiled see an empty Lisp environment when the compilation starts. The Lisp environment that called compile-file is untouched. (2) The files being compiled see a Lisp environment identical to the one from which compile-file was called. The Lisp environment that called compile-file is untouched. (3) The files being compiled see a Lisp environment identical to the one from which compile-file was called. The Lisp environment that called compile-file is modified by side-effects performed on the Lisp environment during the compilation. Personally, I would find style (1) to be painful and inconvenient even if my machine could switch to a new Lisp environment in two nanoseconds, because I want the compilation to see the state in my Lisp environment. Think of people who define their favorite macros in their init files, who would then have to create some sort of "compiler init file" to set up the compilation environment for all of their programs, as a simple example. I admit that this is a matter of philosophy of programming environment that other people could validly disagree with. I think that (2) is what I want, although I can see some benefits in (3) under some circumstances. Do we have to make a decision on this? If we feel that this behavior must be made consistent from one Common Lisp to the next in order to allow portability, that would mean that we have to make a decision. Otherwise we can just say "Common Lisp doesn't specify it." But let's make sure that we're not introducing a new way to make porting not work.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 17 Jan 86 11:00:44 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 17 Jan 86 07:53:48 PST Received: ID ; Fri 17 Jan 86 10:53:40-EST Date: Fri, 17 Jan 1986 10:53 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: David Bein Cc: common-lisp@SU-AI.ARPA Subject: compile environment.. In-reply-to: Msg of 17 Jan 1986 07:00-EST from David Bein David, I think your suggestions are good ones for systems that can provide these styles of compilation. I have a quibble or two about the defaults, and am dubious about providing nay isolation for COMPILE, but basically something like this would give the user the proper degree of control. I guess my preference would be to leave this sort of thing outside the language standard, but let implementations that can support this stuff use the same syntax by informal agreement. It seems to cause a lot of confusion to put something into the standard but to indicate that it is optional. Most of the environment-sensing functions were put into the book in the spirit of "you don't have to provide this, but if you do it should look like this". I get a lot of bug reports from people who don't understand that some of this stuff is optional. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 17 Jan 86 10:09:49 EST Received: from SRI-UNIX.ARPA by SU-AI.ARPA with TCP; 17 Jan 86 07:01:11 PST Received: by sri-unix.ARPA (4.12/4.16) id AA23958; Fri, 17 Jan 86 06:56:36 pst Received: by pyramid (4.12/3.14) id AA10463; Fri, 17 Jan 86 04:07:56 pst Date: 17 Jan 1986 04:00 PST From: David Bein Subject: compile environment.. To: fahlman@cmu-cs-spice.ARPA Cc: common-lisp@su-ai.ARPA Message-Id: <506342289/bein@pyramid> Scott: Two cheers for Accent -- they have clones and do it via copy-on-write One cheer for Unix -- they don't have copy-on-write.. How about the following? (1) compile-file :affect-environment :use-environment :load-result :affect-environment specifies whether or not it is permissible to muck with current image in the process of effecting the compilation. default: nil -- do not mess with my space :use-environment specifies that the current environment is needed (or not) for the compilation. default: nil always be clean and use the "standard" environment. :load-result says what to do with the result and does not necessarily imply that the current environment will be messed with in any ways other than what are implied if you only load the result of compilation. default: nil Letting the defaults for these be NIL and putting the handling of them into the same gray-zone as some of the file ops implies that they are standardized for those environments where they make sense (and can be implemented) and simply ignored where they can not be done or do not make sense. (Look out for the black-zone)... (2) compile :clone :virgin :in-current-env :in-other-environment :clone means explicitly do not mess with my process space to compile my function. The result of the compilation, i.e. the function object, magically finds it way into my space. default: nil -- do it in my space -- mess with it too. :virgin implies clone and do something akin to an exec with proper redirection such that the result of the compilation comes back as in :clone. Exactly what the "clean" environment must look like should be well specified as it is expected that this is the only part which could easily be standardized. default: nil -- do it in my space -- mess with it too. :in-current-environment means evaluate forms in the current environment and then :clone with the result being stuffed back into my current space. This is somewhat akin to eval-before-context-save or something like that. default: nil -- this means nothing special if there is not some kind of context saving mechanism going on other than yet another kind of top-level eval-when-who-knows kind of form. :in-other-environment means evaluate the forms after getting into the new environment. It applies to either :clone or :virgin. It is somewhat akin to eval-after-context-save or something like that. The effects of this should not be noticed in the post-compile environment. default: nil -- this means nothing if there is no way to get a new context or maybe it should be yet another pre-form which acts like eval-when- ... Somewhere in here we find that it is useful to have a working definition of what is a process (from a CL point of view) and that many things we would like to be able to do are limited by the fact that we don't have a good handle on things. I could very easily graft pieces from Accent or Unix into a working process definition, but that is beyond the question at hand. I guess your reply to Moon et al is just the tip of the iceberg. Comments? --David p.s. What about errors in compilation if we do it in another process space?  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 17 Jan 86 06:09:28 EST Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 17 Jan 86 03:03:24 PST Date: Fri, 17 Jan 86 06:04:14 EST From: "George J. Carrette" Subject: compiler enviornment To: HEDRICK@RED.RUTGERS.EDU cc: common-lisp@SU-AI.ARPA In-reply-to: Msg of 16 Jan 86 14:25:13 EST from Charles Hedrick Message-ID: <[MC.LCS.MIT.EDU].786938.860117.GJC> I agree, compiling and running in the same environment is just something that users need to be aware of if they are the type that like to debug their code using COMPILE-DEFUN in their ZMACS buffers, as compared with the type that like to make a couple changes in their sources and do MAKE-SYSTEM :COMPILE. If it were not for global special declarations, macros, defstruct, defflavor and the like there really wouldnt be much difference in semantics between the two styles. That the implementations usually go to a bit of trouble to avoid certain screws with defmacro and defflavor is nice of course.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 16 Jan 86 22:50:51 EST Received: from RED.RUTGERS.EDU by SU-AI.ARPA with TCP; 16 Jan 86 11:26:05 PST Date: 16 Jan 86 14:25:13 EST From: Charles Hedrick Subject: compiler enviornment To: common-lisp@SU-AI.ARPA Message-ID: <12175752345.24.HEDRICK@RED.RUTGERS.EDU> We have some experience with the compiler environment, based on our UCI Lisp implementations. In our second-generation UCI Lisp (called ELISP), we decided to separate the environment of the compiler from that of the current core image. We carefully kept all macros defined in a compiled file on separate properties from the normal macro property, and did other related things. We found that this confused users no end. For simple programs, none of this mattered. For complex systems, we found that users would normally supply macros, structure declarations, and functions that were used to expand both the macros and structure declarations. They would get very confused when macro compilation blew up because it couldn't get to functions that they had defined in their core image. I am sure that all of this could be solved by appropriate use of EVAL-WHEN, and appropriate care in implementation. But I suspect that most users would find it easier just to let the compiler use the current Lisp environment. I don't think Lisp-level copy on write is really needed. Most of our users are capable of writing initialization files that load in all of the pieces of their system that are needed for compilation. Then they have the choice of compiling in their current core image, or getting a new one, loading in the necessary initialization file, and compiling there. I suspect it would be handy to have a way of making it easy to do that in a subfork. A function like (COMPILE-IN-SUBFORK files-to-load files-to-compile) with some way to keep the subfork around for later compilations. Unless I hear some proposal more convincing than those so far, I don't think these mechanisms are ready for standardization yet. -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 16 Jan 86 17:35:48 EST X-Sent: to SU-AI.ARPA by IMSSS.FRONSTAD.EDU via ETHERNET with PUPFTP; 1986-Jan-16 14:05:55 PST (=GMT-8hr) X-Mailer: EMACS -> PSL (FORMAT+SEND-ALL) -> PUPFTP Date: 1986 January 16 14:04:27 PST (=GMT-8hr) From: Robert Elton Maas (this host known locally only) To:COMMON-LISP@SU-AI.ARPA CC:HEDRICK@RED.RUTGERS.EDU Subject:compiler environment, how best to isolate side effects Sender: REM%IMSSS@SU-SCORE.ARPA (for undeliverable-mail notifications) Reply-to: REM%IMSSS@SU-SCORE.ARPA H> Date: 16 Jan 86 14:25:13 EST H> From: Charles Hedrick H> We carefully kept all macros defined in a compiled file on separate H> properties from the normal macro property, ... H> We found that this confused users no end. Reasonable argument against Moon's separate-C-property idea, sigh. I was hoping that would be the method of choice because it's the easiest correct method to implement. H> For complex systems, we found that users would normally supply macros, H> structure declarations, and functions that were used to expand both H> the macros and structure declarations. They would get very confused H> when macro compilation blew up because it couldn't get to functions H> that they had defined in their core image. It sounds like your compiler used the C... properties exclusively, refusing to use normal propertis even when the C... property didn't exist. My suggestion (perhaps I was unclear) was to have the C... properties mask the normal properties for the compiler operations on the file, so if the user happened to define a normal macro or auxilary function in the normal environment before starting the compilation task the macro or auxilary function would still be seen unless it was shadowed by a new definition within the file itself (and would be shadowed only later in the file after the new definition actually occurred). Thus the compiler would never "blow up because it couldn't get to functions ..." as your compiler did. (In the other direction, the innerds of the compiler and other things running in the normal environment would not see the C... stuff at all. Perhaps that's the phrase you saw and misapplied to the reverse case of compilation seeing normal stuff.) H> But I suspect that most users would find it easier just to let the H> compiler use the current Lisp environment. Remember the problem stated by somebody earlier in this discussion, if you do that you can't build a new version of the compiler because macros and auxilary functions being compiled will replace macros and auxilary functions the compiler is trying to use to conduct the compilation, causing the compiler to crash. We are trying to find a bugfix for that problem so that it will be easy to compile compilers in common-lisp. H> Then they have the choice of compiling in their current core image, or H> getting a new one, ... H> I suspect it would be handy to have a way of making it easy to do H> that in a subfork. A function like H> (COMPILE-IN-SUBFORK files-to-load files-to-compile) H> with some way to keep the subfork around for later compilations. As was pointed out, on LISP machines and other single-address-space machines, you can't do that except by discarding the current core image that may have taken weeks to build up. It would be nice to solve address-space problems (using "address space" in the general sense of tag->value mapping such as value cell or functional properties etc.) within LISP itself without assuming an underlying operating system that supports multiple virtual machines (forks etc.). H> Unless I hear some proposal more convincing than those so far, I don't H> think these mechanisms are ready for standardization yet. With this I agree. On machines with multiple virtual machines that can be initialized to have identical memory contents but with copy-on-write, most users will want the COMPILE-IN-SUBFORK feature, although compiling a new version of the compiler will take special care. On other machines without multiple virtual machines the whole thing will need to be done within LISP itself somehow. The desiderata (semantics) should be specified, perhaps somewhat like I proposed in my previous message (compiled file equivalent to interpreted file, no side effects propagate back to normal environment), leaving the implementation method for the implementor to pick. (Another example: I still dislike the insistance that property lists be implemented as alternating lists instead of using whatever method the implementor chooses. Balanced binary trees for property lists would solve a lot of expensive-linear-search problems we were discussing a few weeks ago, and the implementor should be able to choose ASSOC lists or alternating or bbt or hashtable or whatever. You don't need a whole new set of functions, since you can use optional or keyword parameters for modifying the existing functions, such as (ASSOC key alist) can give you normal ASSOC-list search, while (ASSOC key altlist :FORMAT ALTLIST) can force it to handle alternating lists if you use them somewhere explicitly, or (ASSOC key balbinarytree :FORMAT BBT) can force it to handle balanced binary trees, and finally (ASSOC key plist :FORMAT PLIST) can give you whatever the implementation is using for property lists. Likewise (GET symbol key default) et al can be extended to (GET bbt key default :FORMAT BBT), (REMPROP altlist key :FORMAT ALIST) et al.) If we can prove mathematically there's only one internal mechanism that works, then we should set that in concrete in CLtL, otherwise not. (Opinion of REM)  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 16 Jan 86 05:07:06 EST X-Sent: to SU-AI.ARPA by IMSSS.FRONSTAD.EDU via ETHERNET with PUPFTP; 1986-Jan-16 01:39:30 PST (=GMT-8hr) X-Mailer: EMACS -> PSL (FORMAT+SEND-ALL) -> PUPFTP Date: 1986 January 16 01:37:21 PST (=GMT-8hr) From: Robert Elton Maas (this host known locally only) To:COMMON-LISP@SU-AI Subject:2 ways to compile macros correctly Sender: REM%IMSSS@SU-SCORE.ARPA (for undeliverable-mail notifications) Reply-to: REM%IMSSS@SU-SCORE.ARPA From the discussion, it seems there are two major ways to implement isolation of the compiler environment from the week-old running environment so that the compiler doesn't side-effect the running environment (assuming your operating system doesn't allow you to simply create a second virtual machine identical to the original but with copy-on-write): (1) You can implement copy-on-write at the LISP level, if you have tree-structured packages or can fake the same out by long names of packages. (2) You can install all compiler side-effects as unusual properties instead of the usual properties. To implement (1), when you start a compilation you make a complete copy of all the packages in the current environment, origined from some lower level instead of the top level of the package-tree, except you don't actualy copy the packages (hashtables) you merely set up an indirect vector that is copy-on-write, so the first time you actually modify any package that hashtable gets copied but the ones you haven't modified don't need to get copied at all. If you implement hashtables as balanced binary trees instead of as linear arrays, you only have to copy the log(N) path down to the change rather than en masse the whole contiguous hash array. To implement (2) (Moon's suggestion I believe), whenever a macro definition is compiled, you store it as a CMACRO instead of a normal MACRO, whenever a global SETQ occurs, you use the CVALUE property instead of the VALUE cell, likewise for CFUNCTION property instead of FUNCTION cell, CDEFSTRUCT instead of DEFSTRUCT, etc. etc. When the compiler is looking for the definition of a macro or auxilary function needed for macro etc. it looks first for the C... which overrides the normal definition if both are present. Meanwhile the compiler innerds continues to use the normal definitions and totally ignore he C... stuff, so none of the C... stuff can break the compiler itself. CLtL should specify the semantics, namely that (1) the compiled-file environment should be initialized to the current running environment unless that is overridden (virgin LISP wanted instead for example), (2) side-effects due to compiling definitions and SETQs etc. should afect only the compiled-file environment not the compiler-innerds = current-running-LISP environment, (3) when done with a batch of compilations the compiled-file environment should be discarded unless for some reason the operator wants it kept around for later use compiling more files or debugging etc. -- The method of implementation should be up to the compiler writer, with the above two methods (and spawn extra process on Unix or other multi-virtual-machine systems as a third method) merely suggested as ways it can done. Alternately the above can be summarized by two postulates, (1) as it says now, later loading the compiled file should have the same semantics as later loading it interpreted, (2) anything needed to make (1) work shouldn't modify the current running environment (in which the compiler itself runs) in any way even temporarily except of course for consuming memory and time. (Opinion of REM)  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 15 Jan 86 23:01:23 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 15 Jan 86 17:36:37 PST Received: ID ; Wed 15 Jan 86 20:35:54-EST Date: Wed, 15 Jan 1986 20:35 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: "David A. Moon" Cc: common-lisp@SU-AI.ARPA Subject: time of evaluation of defstruct, deftype, etc. In-reply-to: Msg of 15 Jan 1986 18:01-EST from David A. Moon This problem cannot be solved with multiple address spaces, unless you have a very complicated mechanism for sharing objects between address spaces, I don't understand this. What has to be shared in a complicated way? Stepping back a level, the main issue for the Common Lisp community is do we want to say that this is an issue which each implementation should solve for itself, in order to have a compiler that can be considered "high quality", or is this something that should be made a standard part of the language, with a portable interface? Obviously one alternative is "better" for the users and the other alternative is less work for the language standardization effort. As I said in my answer to Weinreb, the way you want to go about solving this problem depends a lot on the kind of system you're running in. In Accent, for example, there are multiple processes and it is very quick and easy to create a clone process due to the copy-on-write memory management. We should probably standardize those things that we have to in order to have sets of portable source files that can be compiled and run anywhere, and leave to the local culture those things that are not required for this. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 15 Jan 86 21:58:18 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 15 Jan 86 18:50:25 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 393624; Wed 15-Jan-86 21:50:12-EST Date: Wed, 15 Jan 86 21:50 EST From: David A. Moon Subject: time of evaluation of defstruct, deftype, etc. To: Scott E. Fahlman cc: common-lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860115215029.0.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Wed, 15 Jan 1986 20:35 EST From: "Scott E. Fahlman" This problem cannot be solved with multiple address spaces, unless you have a very complicated mechanism for sharing objects between address spaces, I don't understand this. What has to be shared in a complicated way? Copy-on-write is fine for getting things to the compiler, but what if you want to get something back? I don't want to get into a long discussion of this. Stepping back a level, the main issue for the Common Lisp community is do we want to say that this is an issue which each implementation should solve for itself, in order to have a compiler that can be considered "high quality", or is this something that should be made a standard part of the language, with a portable interface? Obviously one alternative is "better" for the users and the other alternative is less work for the language standardization effort. As I said in my answer to Weinreb, the way you want to go about solving this problem depends a lot on the kind of system you're running in. So your position is that this should not be made a standard part of the language. OK.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 15 Jan 86 21:53:19 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 15 Jan 86 17:27:56 PST Received: ID ; Wed 15 Jan 86 20:27:31-EST Date: Wed, 15 Jan 1986 20:27 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: "Daniel L. Weinreb" Cc: common-lisp@SU-AI.ARPA Subject: time of evaluation In-reply-to: Msg of 15 Jan 1986 17:45-EST from Daniel L. Weinreb In what Lisp environment is compile-file defined to compile the file? There are two possibilities: (1) it should use the present Lisp environment; (2) it should use an empty initial Lisp environment. CLtL doesn't say, but it needs to, because the two are significantly semantically different. I agree that it would be worthwhile to nail this down. If (1), then the techniques of spawning a separate Lisp process, or using a new package, won't work, unless you try to cleverly copy state from one place another or something. If (2), then you can't break your program into a "defs" file that defines a bunch of macros, which you then load before you compile other files. It means that every time you do a compile-file, you start with a bare Lisp and have to load up all the files with all the macros and other things that you plan to use. Even if you're compiling twenty files in a row and they all use the same defs files, you have to load the defs files over and over again. This kind of "batch" operation is highly undesirable. Your objection to interpretation 1 depends totally on what sort of system you're thinking about. On Unix, you can create a clone of the current process with a simple fork. Then if you're the new copy, you do the compile and commit suicide. Nothing clever required. Your objection to 2 also depends on the assumptions you are making about the system environment. In the previous message, I was careful to say "when you compile ONE OR MORE files". If you spawn a virgin Lisp process in which to compile, you just tell it to compile all 20 files (including some defs files) in a lump, preserving state between compiles; then commit suicide. Or you could keep the compiler process and its associated state around indefinitely and give the user a REVIRGINIZE-COMPILER call which kills off the now-polluted compiler process and creates a new fresh one. On the 3600, either of these solutions presents a problem, I guess. Since there's only one huge Lisp process (address space) to play with, and since it is very expensive to save a copy of this huge thing on disk, you don't have the option of compiling in one copy of an address space while running in a second copy that is not polluted by the compile. The right solution is to catch up with Unix and other modern operating systems by putting in true multiple processes (sorry, couldn't resist), but if that is not possible, I guess this business of stashing the compiler's state changes in funny undoable places is about the best you can do. I wouldn't like to see this solution cast in concrete for everyone, though. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 15 Jan 86 19:28:36 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 15 Jan 86 15:04:41 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 393466; Wed 15-Jan-86 18:00:48-EST Date: Wed, 15 Jan 86 18:01 EST From: David A. Moon Subject: time of evaluation of defstruct, deftype, etc. To: common-lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860115180103.0.MOON@EUPHRATES.SCRC.Symbolics.COM> This problem cannot be solved with multiple address spaces, unless you have a very complicated mechanism for sharing objects between address spaces, and cannot be solved with packages, because packages provide partial sharing and partial isolation with the division between sharing and isolation not being the same division that you need to distinguish the Lisp world in which you are running the compiler from the Lisp world that will exist when the compiler's output is loaded. A more viable technique is to attack the problem not at the level of binding objects to addresses, and not at the level of binding strings to symbols, but at the level of binding names to objects. Many compilers already do this for macros, using one mechanism for binding the name of a macro to its definition when DEFMACRO is loaded, or evaluated interactively, and a second mechanism when DEFMACRO is compiled. It isn't difficult to extend this to other name bindings, such as binding a structure name to the internal description of the structure. I'm sure we can all design data representations for doing this. The main issue in implementing this is getting each place that looks up a name, looking for an object, to know which mechanism it is supposed to be using. In some cases the lexical environment Common Lisp passes to macros is an appropriate place to store this information. I could say more, and so could other implementors, but I don't want to bore you. Stepping back a level, the main issue for the Common Lisp community is do we want to say that this is an issue which each implementation should solve for itself, in order to have a compiler that can be considered "high quality", or is this something that should be made a standard part of the language, with a portable interface? Obviously one alternative is "better" for the users and the other alternative is less work for the language standardization effort.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 15 Jan 86 18:05:32 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 15 Jan 86 14:56:28 PST Received: ID ; Wed 15 Jan 86 17:55:22-EST Date: Wed, 15 Jan 1986 17:55 EST Message-ID: From: Rob MacLachlan To: SANDRA Cc: BSG@SCRC-STONY-BROOK.ARPA, common-lisp@SU-AI.ARPA, DLW@SCRC-QUABBIN.ARPA, Soley@MIT-MC.ARPA Subject: time of evaluation In-reply-to: Msg of 15 Jan 1986 17:27-EST from SANDRA I agree it would be most consistent to evaluate everything all the time, but as JAR pointed out a while back, consistency is not an attribute of the Common Lisp language. In this case, I think it is better to be inconsistent so that you aren't consistently screwed. One thing to consider is that when you make a thing implicitly eval-when compile, there is no way to override this behavior. In contrast, it is always possible to make something evaluated in the compiler by using eval-when (compile). At least, that is my interpretation of eval-when's semantics, which are rather poorly defined, as I have mentioned before. Rob  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 15 Jan 86 17:52:16 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 15 Jan 86 14:45:28 PST Received: from CHICOPEE.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 393440; Wed 15-Jan-86 17:45:29-EST Date: Wed, 15 Jan 86 17:45 EST From: Daniel L. Weinreb Subject: time of evaluation To: Fahlman@C.CS.CMU.EDU, common-lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860115174547.1.DLW@CHICOPEE.SCRC.Symbolics.COM> In what Lisp environment is compile-file defined to compile the file? There are two possibilities: (1) it should use the present Lisp environment; (2) it should use an empty initial Lisp environment. CLtL doesn't say, but it needs to, because the two are significantly semantically different. If (1), then the techniques of spawning a separate Lisp process, or using a new package, won't work, unless you try to cleverly copy state from one place another or something. If (2), then you can't break your program into a "defs" file that defines a bunch of macros, which you then load before you compile other files. It means that every time you do a compile-file, you start with a bare Lisp and have to load up all the files with all the macros and other things that you plan to use. Even if you're compiling twenty files in a row and they all use the same defs files, you have to load the defs files over and over again. This kind of "batch" operation is highly undesirable.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 15 Jan 86 17:38:30 EST Received: from UTAH-20.ARPA by SU-AI.ARPA with TCP; 15 Jan 86 14:30:04 PST Date: Wed 15 Jan 86 15:27:01-MST From: SANDRA Subject: Re: time of evaluation To: RAM@C.CS.CMU.EDU cc: DLW@SCRC-QUABBIN.ARPA, BSG@SCRC-STONY-BROOK.ARPA, common-lisp@SU-AI.ARPA, Soley@MIT-MC.ARPA In-Reply-To: Message-ID: <12175523298.9.LOOSEMORE@UTAH-20.ARPA> This sounds similar to what currently happens with DEFSTRUCT in PCLS -- the information needed to open-code accessors and for handling :include gets added at both compile and load time, but the functions defstruct generates are only defined a load time. I think that, to be consistent, it would probably be better if the functions were defined at compile time too. After all, if you've just overwritten part of the information for an existing structure type, you might as well overwrite the rest of it too, and then at least the two pieces of information will agree with each other. The reason why I brought this up in the first place is that it's very difficult to write macros portably without knowing what things become part of the compile-time environment and what things don't. I suppose one could take the conservative approach and wrap an (eval-when (eval compile load) ...) around the entire contents of each file, but somehow I don't think this is what the language designers really had in mind. I don't have particularly strong feelings myself on what things should happen when, or whether things defined in the context of the compiler should or shouldn't modify the environment permanently. I would rather see some agreement now on a standard that most implementations already do, or can easily be changed to do, rather than spend 3 years arguing about what the most elegant solution is, and then another 3 years while everybody figures out how to implement it.... -Sandra -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 15 Jan 86 15:37:40 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 15 Jan 86 12:25:55 PST Received: ID ; Wed 15 Jan 86 14:32:25-EST Date: Wed, 15 Jan 1986 14:32 EST Message-ID: From: Rob MacLachlan To: "Daniel L. Weinreb" Cc: BSG@SCRC-STONY-BROOK.ARPA, common-lisp@SU-AI.ARPA, LOOSEMORE@UTAH-20.ARPA, Soley@MIT-MC.ARPA Subject: time of evaluation I think it's a bad idea to make defstruct literally eval-when (compile load eval). It will cause you (the implementor) no end of grief even if it doesn't bother users much. In Spice Lisp, our current solution is to have two separate defstruct definition properties, DEFSTRUCT-DEFINITION and DEFSTRUCT-DEFINITION-IN-COMPILER. The -IN-COMPILER property is set when the defstruct is compiled, and the normal definition is set at load time. The compiler definition is used preferentially for purposes of inclusion and any compiler uses. Compiling a defstruct puts compiler information into the environment so that accessors and predicates are open-coded, but the actual function definitions are not put into the environment. One problem with a strict eval-when compile strategy is that it causes any accessors in the environment to be clobbered with interpreted definitions. We also had problems with compiling the file which defines streams breaking the type structure such that *TERMINAL-IO* was no longer a stream, with understandably serious consequences. I'm sure that there are lots of problems with this approach, both in particular and in general, since it is similar to the defmacro problem but more complicated due to the more complicated semantics of defstruct. Nonetheless, I think that an approach like this is expedient for the same reasons that make special-casing macros important. Rob  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 15 Jan 86 15:18:02 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 15 Jan 86 10:49:45 PST Received: ID ; Wed 15 Jan 86 12:57:17-EST Date: Wed, 15 Jan 1986 12:57 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: common-lisp@SU-AI.ARPA Subject: time of evaluation In-reply-to: Msg of 15 Jan 1986 12:54-EST from Jim Kempf I agree pretty much with Weinreb's analysis of the problem. It seems to me that defstructs and deftypes should be handled the same way macros are when compiling a file. In older Lisps of the Maclisp generation, I think that it was always the case that such things were simply evaluated in the Lisp in which the compiler is running, altering that environment permanently. This didn't bother people too much, since typically you fired up a special Lisp/Compiler job that was only used for compiling one or more files. I think that this scheme is permitted in Common Lisp, but I haven't gone back to check the fine print; I'm sure that many implementations do it this way. In newer Lisps, people would like to be able to call Compile-File, have the compiler do its thing on one or more files, and then go on to do other things in that Lisp. The process of compiling one or more files should ideally not have any permanent effects on the Lisp in which Compile-File is called. One way to do this is to have Compile-File spawn a separate Lisp process to do the compilation(s) in, perhaps a virgin Lisp or perhaps a clone of the calling Lisp. (Which is preferable? Should a file being compiled be able to depend on macros that happen to be defined in the calling Lisp?) That solution is not attractive in systems like the Lisp Machine, where there is only one big Lisp address space and where people like to live in that for days or weeks on end without polluting it. Such systems do indeed need to create some sort of quarantined environment within their single Lisp. One suggestion made some time ago was that when a file did not specify any particular package, it should not be compiled in the calling Lisp's current package, but rather in SPECIAL-COMPILER-TEMPORARY-PACKAGE. The thing that dumps out the FASL file (or whatever) would arrange that symbols interned in this specific package would be loaded into whatever package is current when the FASL file is read in. On the other hand, if the file specifies package FOO, you read the stuff into package FOO. It seems to me that this would solve the problem in many cases, since if the user defined a macro, structure-name, or type name, the symbol naming that thing would be quarantined. However, you still could get conflicts in some odd cases, or when the user compiles a file with a specified package from a Lisp that has that package loaded. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 15 Jan 86 13:12:08 EST Received: from HPLABS.ARPA by SU-AI.ARPA with TCP; 15 Jan 86 09:55:14 PST Received: from hplabsc by hplabs.ARPA ; Wed, 15 Jan 86 09:53:25 pst Received: by hplabsc (4.16/4.30) ; id AA07687; Wed, 15 Jan 86 09:54:28 pst Date: Wed, 15 Jan 86 09:54:28 pst From: Jim Kempf Message-Id: <8601151754.AA07687@hplabsc> To: BSG@SCRC-STONY-BROOK.ARPA, DLW@SCRC-QUABBIN.ARPA, LOOSEMORE@UTAH-20.ARPA, Soley@MIT-MC.ARPA, common-lisp@SU-AI.ARPA Subject: Re: time of evaluation Cc: snyder@hplabsc This discussion is interesting, in that, it parallels some of our thinking on modifications to the compile time environment to support CommonObjects object oriented programming. A proposed addition to Common Lisp which we have suggested is a compiler dictionary (essentially, a hash table) which gets created during file compilation and into which defstructs and define-types (which create CommonObjects types) can enter information which needs to be discarded after the file is compiled. The problems with "really" defining a type or defstruct at compile time not only have to do with the compiler but also with the environment in general. Consider development in an environment which uses types or defstructs in its implementation. If changes are made to the types or defstructs, one doesn't want those changes to be propogated to the environment during the debugging and development phase, otherwise the entire environment may fall apart. Our current version of CommonObjects uses a highly implementation dependent way of getting around these problems, which works about 99% of the time. It is inherently not portable, however, because it depends on being able to tell when a file is being compiled, and, according to the definition of compile-file, this information is not made available. A similar problem occurs with defstruct. Jim Kempf kempf@hplabs  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 15 Jan 86 12:56:18 EST Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 15 Jan 86 08:15:08 PST Date: Wed, 15 Jan 86 11:16:02 EST From: Richard Mark Soley Subject: time of evaluation To: BSG@SCRC-STONY-BROOK.ARPA cc: common-lisp@SU-AI.ARPA, LOOSEMORE@UTAH-20.ARPA In-reply-to: Msg of Wed 15 Jan 86 09:11 EST from Bernard S. Greenberg Message-ID: <[MC.LCS.MIT.EDU].784707.860115.SOLEY> Date: Wed, 15 Jan 86 09:11 EST From: Bernard S. Greenberg To: Soley at MIT-MC.ARPA, LOOSEMORE at UTAH-20.ARPA, common-lisp at SU-AI.ARPA Re: time of evaluation Date: Tue, 14 Jan 86 15:17 EST From: Soley@MIT-MC.ARPA Date: Mon 13 Jan 86 18:08:50-MST From: SANDRA Subject: time of evaluation To: common-lisp@SU-AI.ARPA Message-ID: <12175028466.9.LOOSEMORE@UTAH-20.ARPA> Should types defined via deftype and defstruct be entered into the type structure at compile time as well as load/eval time? This is completely unclear. Consider an incompatible change to a defstruct used by the compiler. Consider that one of the accessor functions is passed as a funarg by the compiler. Doing this would break the compiler. It has to do something a lot more subtle, that limits its effects to functions being compiled in the same file. I had this exact problem with the GCLisp compiler, as a matter of fact. HOWEVER, I think the language should be designed more for the user than the compiler writer, who we assume has more smarts. -- Richard  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 15 Jan 86 12:06:30 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 15 Jan 86 08:58:50 PST Received: from CHICOPEE.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 393039; Wed 15-Jan-86 11:58:41-EST Date: Wed, 15 Jan 86 11:58 EST From: Daniel L. Weinreb Subject: time of evaluation To: BSG@SCRC-STONY-BROOK.ARPA, Soley@MIT-MC.ARPA, LOOSEMORE@UTAH-20.ARPA, common-lisp@SU-AI.ARPA In-Reply-To: <860115091150.4.BSG@CONCORD.SCRC.Symbolics.COM> Message-ID: <860115115858.7.DLW@CHICOPEE.SCRC.Symbolics.COM> Date: Wed, 15 Jan 86 09:11 EST From: Bernard S. Greenberg This is completely unclear. Consider an incompatible change to a defstruct used by the compiler. (Are you aware that defstruct is implicitly "(compile load eval)" in our implementation, and always has been?) The real issue here is what it means to "compile from a file". It's a tricky issue when the Lisp environment that's running the compiler is not a special Lisp created only for that compilation and then discarded (the way we used to do it in Maclisp), but is an ongoing environment. When the compiler sees a "defmacro" early in a file, it ideally should not actually alter the Lisp environment at all, but it should let forms in the file use that macro. It needs to maintain a "subjunctive Lisp environment", in which the contract of the compiler, given a Lisp fucntion to compile, is to produce code that will do the same thing that the interpreted code would do if that interpreted code were run in the "subjunctive environment", which means "if all the previous stuff file, but not the subsequent stuff, had been evaluated". The Symbolics implementation really does maintain a "subjunctive environment" for macros. But it doesn't do a perfect job. Consider a file with the following forms: (defun util (x) (list x x)) (defmacro mac (y) (util y)) (defun test (z) (mac z)) Now, if you call compile-file on this file, your Lisp environment should not end up having "util" defined when you are done. Yet, "util" needs to be in the "subjunctive environment", so that when the compiler tries to compile "mac", it will be able to. Our implementation of compile-file signals "The function UTIL is not defined." I'd be interested to know if any implementation handles this correctly. The current practice is that the programmer has to get around this by inserting an eval-when around the definition of util (or put it into a "defs" file that gets loaded before compilation, which is really the same thing). The problem is that it conflicts with/overrides the definition of "util" in the running environment. This is essentially the same problem as the one you are pointing out, in the "defstruct that's part of the compiler" example, except that breaking the compiler is obviously a more serious thing that will lead to immediate worse problems. Richard is right about how users don't hack the compiler much, but it's still true that using (eval-when (compile ...) ...) breaks the principle that compile-file should leaves the state of the Lisp environment unchanged, and user programs can definitely suffer from this problem: you compile a new version, and the suddently the old version doesn't work any more, perhaps because you modified some function like util.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 15 Jan 86 09:14:22 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 15 Jan 86 06:05:55 PST Received: from CONCORD.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 392860; Wed 15-Jan-86 09:06:01-EST Date: Wed, 15 Jan 86 09:11 EST From: Bernard S. Greenberg Subject: time of evaluation To: Soley@MIT-MC.ARPA, LOOSEMORE@UTAH-20.ARPA, common-lisp@SU-AI.ARPA In-Reply-To: <860114151755.6.SOLEY@MIT-CHERRY.ARPA> Message-ID: <860115091150.4.BSG@CONCORD.SCRC.Symbolics.COM> Date: Tue, 14 Jan 86 15:17 EST From: Soley@MIT-MC.ARPA Date: Mon 13 Jan 86 18:08:50-MST From: SANDRA Subject: time of evaluation To: common-lisp@SU-AI.ARPA Message-ID: <12175028466.9.LOOSEMORE@UTAH-20.ARPA> Should types defined via deftype and defstruct be entered into the type structure at compile time as well as load/eval time? Definitely yes. Although the book may not say so, it would be pretty bad for the compiler to not recognize (and perhaps open-code accessors of) a type previously defined in the same file. Along similar lines, I assume one has to wrap an eval-when around defstructs if one wishes to use #s syntax later on in the file to create a constant structure, so that the constructor function required for reading in the constant will be defined at compiletime. I think DEFSTRUCT should be "implicitly" eval-when (eval compile load), for the same reasons as above. This is what Gold Hill GCLisp and others do, for example. -- Richard Soley This is completely unclear. Consider an incompatible change to a defstruct used by the compiler. Consider that one of the accessor functions is passed as a funarg by the compiler. Doing this would break the compiler. It has to do something a lot more subtle, that limits its effects to functions being compiled in the same file.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 14 Jan 86 23:17:19 EST Received: from CSNET-RELAY.ARPA by SU-AI.ARPA with TCP; 14 Jan 86 18:54:07 PST Received: from tektronix by csnet-relay.csnet id ah00838; 14 Jan 86 21:43 EST From: S Sridhar To: common-lisp@su-ai.ARPA Received: from tekchips by tektronix with smtp ; 14 Jan 86 13:08:36 PST Date: Tuesday, 14 Jan 86 12:54:57 PST Subject: Errata on p.431 There are two mistakes in the first example on p.431. The function cerror in both places has an argument vals missing. In the first half of the example: (cerror "Assume ............. ..................... but ~R ~:[were~;was~] supplied." nvals (= nvals 1)) The last 2 args should be replaced by the three args: vals nvals (= nvals 1) Similarly in the second cerror function, after the line but ~R were supplied." the line nvals) should be replaced by vals nvals) --sridhar  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 14 Jan 86 15:29:13 EST Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 14 Jan 86 12:17:11 PST Received: from CHERRY.LCS.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 14 JAN 86 15:17:47 EST Date: Tue, 14 Jan 86 15:17 EST From: Soley@MIT-MC.ARPA Subject: time of evaluation To: LOOSEMORE@UTAH-20.ARPA, common-lisp@SU-AI.ARPA In-Reply-To: <12175028466.9.LOOSEMORE@UTAH-20.ARPA> Message-ID: <860114151755.6.SOLEY@MIT-CHERRY.ARPA> Date: Mon 13 Jan 86 18:08:50-MST From: SANDRA Subject: time of evaluation To: common-lisp@SU-AI.ARPA Message-ID: <12175028466.9.LOOSEMORE@UTAH-20.ARPA> Should types defined via deftype and defstruct be entered into the type structure at compile time as well as load/eval time? Definitely yes. Although the book may not say so, it would be pretty bad for the compiler to not recognize (and perhaps open-code accessors of) a type previously defined in the same file. Along similar lines, I assume one has to wrap an eval-when around defstructs if one wishes to use #s syntax later on in the file to create a constant structure, so that the constructor function required for reading in the constant will be defined at compiletime. I think DEFSTRUCT should be "implicitly" eval-when (eval compile load), for the same reasons as above. This is what Gold Hill GCLisp and others do, for example. -- Richard Soley  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 13 Jan 86 20:22:19 EST Received: from UTAH-20.ARPA by SU-AI.ARPA with TCP; 13 Jan 86 17:10:05 PST Date: Mon 13 Jan 86 18:08:50-MST From: SANDRA Subject: time of evaluation To: common-lisp@SU-AI.ARPA Message-ID: <12175028466.9.LOOSEMORE@UTAH-20.ARPA> Should types defined via deftype and defstruct be entered into the type structure at compile time as well as load/eval time? It seems pretty useless to declare things to be of a structure type if the compiler doesn't recognize the structure name as a valid type specifier. The documentation for deftype/defstruct says nothing special about things happening at compiletime, though, so I assume the usual defaults apply and nothing happens until loadtime unless you wrap an eval-when around it. Seems kind of awkward. Along similar lines, I assume one has to wrap an eval-when around defstructs if one wishes to use #s syntax later on in the file to create a constant structure, so that the constructor function required for reading in the constant will be defined at compiletime. -Sandra -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 12 Jan 86 09:46:15 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 12 Jan 86 06:42:04 PST Received: ID ; Sun 12 Jan 86 09:42:21-EST Date: Sun, 12 Jan 1986 09:42 EST Message-ID: From: Rob MacLachlan To: common-lisp@SU-AI.ARPA Subject: fill-pointers and destructive sequence functions If a destructive sequence function such as DELETE is passed an array with a fill pointer, may it reduce the size of the argument by adjusting the fill-pointer? The alternative would be to require the (ARRAY-DIMENSION 0) to be the resulting length. This seems excessively restrictive, since sequence functions only deal with the active elements of vectors. What should ADJUST-ARRAY do with the fill-pointer in an array if there is no :FILL-POINTER argument specified? It seems sub-optimal to leave it pointing into hyperspace. Does the fill pointer go away? Is it legal for MAKE-ARRAY to return an array with a fill-pointer when no :FILL-POINTER option was specified? This question is similar to the question "Are there contexts in which not having a fill-pointer is important?" Currently any Spice Lisp vector which is not a SIMPLE-ARRAY has a fill pointer. Rob  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 10 Jan 86 14:11:43 EST Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 10 Jan 86 11:02:22 PST Date: Fri, 10 Jan 86 14:01:04 EST From: "George J. Carrette" Subject: SETF of an &REST list. To: RPG@SU-AI.ARPA cc: common-lisp@SU-AI.ARPA In-reply-to: Msg of 10 Jan 86 0941 PST from Dick Gabriel Message-ID: <[MC.LCS.MIT.EDU].779630.860110.GJC> What you have to say is that SETF on the &REST list is not portable. e.g. (defun foo (&rest l) (setf (car l) 'foo)) (defun test () (let ((x (list nil))) (apply 'foo x) (car x))) In NIL (or Maclisp for that matter): (test) ==> NIL In zetalisp its always been that: (test) ==> FOO. This is also the kind of behavior that may be different depending on if a function is interpreted or compiled or traced etc.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 10 Jan 86 12:58:17 EST Date: 10 Jan 86 0941 PST From: Dick Gabriel Subject: Varia from Tektronix To: common-lisp@SU-AI.ARPA I am forwarding this for Will Clinger at Tektronix: With regard to the proposed starred change to page 145 of CLtL: (*) 145 ....Similarly, a function that takes a &REST argument should not destroy it because its top-level list structure might share with a list that the user gave as the last argument to APPLY. This would imply that destructive operations on any list given as the last argument to APPLY are also forbidden unless it is known that the function being applied does not take a &REST argument. The following code, for example, would be in error: (defun baz (&rest x) (if (numberp (car x)) #'(lambda () (1+ (car x))) #'(lambda () 0))) (defun kablooey () (let* ((zog (list 3)) (bar (apply #'baz zog))) (setf (car zog) 'zag) (funcall bar))) ;;; William Clinger ;;; willc%tekchips@tektronix.csnet ;;; Tektronix Computer Research Laboratory  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 10 Jan 86 10:18:02 EST Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 10 Jan 86 07:11:21 PST Date: 10 Jan 1986 09:52-EST Sender: NGALL@G.BBN.COM Subject: Re: questions about packages From: NGALL@G.BBN.COM To: LOOSEMORE@UTAH-20.ARPA Cc: common-lisp@SU-AI.ARPA Message-ID: <[G.BBN.COM]10-Jan-86 09:52:42.NGALL> In-Reply-To: <12174001594.14.LOOSEMORE@UTAH-20.ARPA> Date: Thu 9 Jan 86 20:08:03-MST From: SANDRA To: common-lisp@SU-AI.ARPA Subject: questions about packages Message-ID: <12174001594.14.LOOSEMORE@UTAH-20.ARPA> 1. Can a package use itself? Or is this "an error"? Yes. A package can use itself (though an error may be signalled due to name conflicts). 2. Does the :use argument to in-package default to the list of the lisp package in the same way that it does for make-package? In other words, if you do (in-package 'foo) and package foo does not yet exist, does it default to using the lisp package? What if package foo does exist but doesn't already use the lisp package? Hmmm...Good Question. "This function is similar to MAKE-PACKAGE" should be made more explicit. I think the intent here is that if :USE was actually an argument to IN-PACKAGE it is merely passed on to the call to MAKE-PACKAGE (in the case of FOO not existing); if it wasn't an actual arg. to IN-PACKAGE, MAKE-PACKAGE is called with no :USE arg. (and hence :USE defaults to '(LISP)). In the case where FOO existed, if :USE is not an actual arg. to IN-PACKAGE, :USE defaults to '(). -- Nick  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 9 Jan 86 22:16:23 EST Received: from UTAH-20.ARPA by SU-AI.ARPA with TCP; 9 Jan 86 19:09:12 PST Date: Thu 9 Jan 86 20:08:03-MST From: SANDRA Subject: questions about packages To: common-lisp@SU-AI.ARPA Message-ID: <12174001594.14.LOOSEMORE@UTAH-20.ARPA> 1. Can a package use itself? Or is this "an error"? 2. Does the :use argument to in-package default to the list of the lisp package in the same way that it does for make-package? In other words, if you do (in-package 'foo) and package foo does not yet exist, does it default to using the lisp package? What if package foo does exist but doesn't already use the lisp package? -Sandra -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 9 Jan 86 11:58:16 EST Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 9 Jan 86 08:33:10 PST Received: from eligius by GODOT.THINK.COM via CHAOS; Thu, 9 Jan 86 10:44:07 est Date: Thu, 9 Jan 86 10:45 EST From: Guy Steele Subject: Common Lisp 'open' To: massar@THINK-AQUINAS.ARPA, common-lisp@SU-AI.ARPA Cc: gls@THINK-AQUINAS.ARPA In-Reply-To: The message of 8 Jan 86 20:13-EST from JP Massar Message-Id: <860109104511.2.GLS@THINK-ELIGIUS.ARPA> Date: Wed, 8 Jan 86 20:13:29 est From: massar (JP Massar) Suppose I have the following: (open "x" :direction :output :if-exists :append :if-does-not-exist :create) This is fine and dandy unless I don't have permission to write to the file and/or create a new file. Probing the file is of no use, since either the file is there and it tells me so or it isn't and it tells me so -- in either case I still want to execute the open. It seems like a generic :if-unable-to construct would be a good idea. As it is I can see no way or writing robust, portable code that deals with files. I realize that "The opening if files is an area where complete portability is too much to hope for", but this seems like a pretty general problem (even on a Lispm, I could probe a file, then have the Chaosnet go down, and have the open fail on me...). Any ideas? Helpful hints? What we really need is a Common Lisp error-handling system. However, I am forwarding this to the Common Lisp mailing list. --Guy  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 8 Jan 86 11:45:48 EST Received: from HPLABS.ARPA by SU-AI.ARPA with TCP; 8 Jan 86 08:38:25 PST Received: from hplabsc by hplabs.ARPA ; Wed, 8 Jan 86 08:37:10 pst Received: by hplabsc (4.16/4.30) ; id AA03359; Wed, 8 Jan 86 08:37:59 pst Date: Wed, 8 Jan 86 08:37:59 pst From: Jim Kempf Message-Id: <8601081637.AA03359@hplabsc> To: common-lisp@su-ai.ARPA Subject: Hooks for Common Objects (Please ignore if this posting is repeated, we're having some trouble with our mailer daemon) At the December Common Lisp meeting in Boston, Alan Snyder presented a list of proposed language changes which we felt were needed in order to implement CommonObjects. For the benefit of those who weren't at the meeting, here is a quick summary of the changes (with notations for changes which are also part of Guy Steele's list): 1) Change DEFSTRUCT in the following ways, to better support encapsulation: a) Specify that the underlying data structure for DEFSTRUCT's is a vector-like object to which user access is made difficult, b) Add a keyword argument specifying that no accessor functions be generated. Access to slots would then only be through the accessor functions for the underlying data structure, c) Require that the type predicate, if specified, be used by TYPEP, d) Allow DEFSTRUCT to take function names for functions to be used when two DEFSTRUCT's are compared using EQL, EQUAL, and EQUALP. 2) Change the type system in the following ways: a) Introduce a new predicate, TYPE-DEFINED-P, which takes a symbol and returns T if a type with that name is defined, b) Introduce a new function, UNDEFINE-TYPE, which takes a symbol and undefines the type, if it is defined. This is similar to Steele's proposal for undo functions, c) Introduce a new function, RENAME-TYPE, which takes two symbols, and renames the type known as the first to the second. 3) Introduction of a new special form, LET-PSEUDO, which allows the definition of lexical instance variables (might also be useful for Smalltalk and Flavors instance variable access). 4) Clarify the role of #, so that load-time execution of embedded forms is possible from compiled, as well as interpreted code. 5) Introduce the following optimization hooks: a) Allow the environment parameter to DEFMACRO to be queried for various information which would make optimization more portable. This is similar to Steele's proposal for PARSE-BODY, except DECLARE forms from the environment as well as the body would need to be returned, b) Allow a macro to be associated with a function name for compilation purposes. Most implementations will do this in a nonportably anyway, if only to allow arithmetic operations to be optimized, c) Add two functions, which facilitate the efficient definition of indirect function calls. 6) Introduce the following hooks for seperate compilation: a) Allow a macro to inquire on its &ENVIRONMENT parameter if the result will be used in a file compilation, b) Provide a hash table for each COMPILE-FILE where information associated with the compilation can be stored. People who are interested in more details can ask for the document outlining the hooks: A Common Objects Implementation Kernel, by Alan Snyder, Michael Creech, and James Kempf, STL-TM-85-14 Electronic addresses are SNYDER@HPLABS or KEMPF@HPLABS. Mail address is: Hewlett-Packard Labs 1501 Page Mill Rd. Palo Alto, CA 94304 The most critical of the above hooks is 6). Currently, COMPILE-FILE is not defined to change its environment in any way which would allow one to know that a file is being compiled. This has many (mostly unpleasent) consequences for bootstrapping and type definition, and we currently use a nonportable technique which catches about 98% of the problems. We would be interested in other people's experiences with seperate compilation. How does one handle problems with compiling type/flavor/class defintions which are part of the compiler, for example? Would the above mentioned changes simplify things, or is there some way within the current language standard that seperate compilation can be done safely and portably? Jim Kempf kempf@hplabs  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 7 Jan 86 12:19:15 EST Received: from THINK.COM by SU-AI.ARPA with TCP; 7 Jan 86 09:10:50 PST Received: from jehosephat by GODOT.THINK.COM via CHAOS; Tue, 7 Jan 86 12:10:49 est Date: Tue, 7 Jan 86 12:11 EST From: Guy Steele Subject: Type questions To: cfry@OZ.AI.MIT.EDU, common-lisp@SU-AI.ARPA Cc: gls@THINK-AQUINAS.ARPA In-Reply-To: <860107033828.3.CFRY@JANIS.AI.MIT.EDU> Message-Id: <860107121140.2.GLS@THINK-JEHOSEPHAT.ARPA> Date: Tue, 7 Jan 86 03:38 EST From: Christopher Fry - What's the relationship between keyword, the type, and keyword, a symbol in the keyword package? Spicelisp calls the type keyword a subtype of symbol. They are the same notion. An item of type keyword is a symbol in the keyword package. - is (subtype foo foo) true for any valid type foo ? The book does not require this right now; SUBTYPEP is permitted to throw up its hands and say "I don't know". The nature of SUBTYPEP and what cases it is required to handle ought to be tied down more. - Are the new types: signed-byte and unsigned-byte subtypes of fixnum, like bit is? Yes. The descriptions of these types on pages 48-49 explicitly describe them as being equivalent to specified subtypes of integer (type specifiers of the form (INTEGER x y)). - In Spicelisp, COMMON is a subtype of ATOM and ATOM is a subtype of COMMON. True in CL? How can COMMON be a subtype of ATOM? CONS must be a subtype of COMMON, so if COMMON is a subtype of ATOM then CONS must be a subtype of ATOM. But no cons can be an ATOM (by the definition of ATOM), so if CONS is a subtype of ATOM then CONS must be an empty type. Therefore if COMMON is a subtype of ATOM there are no conses. CLtL should have explicite paragraphs and index entries for every type. I noticed BIT and KEYWORD lacked this kind of documentation. See my next message.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 7 Jan 86 12:18:43 EST Received: from THINK.COM by SU-AI.ARPA with TCP; 7 Jan 86 09:12:57 PST Received: from jehosephat by GODOT.THINK.COM via CHAOS; Tue, 7 Jan 86 12:12:56 est Date: Tue, 7 Jan 86 12:13 EST From: Guy Steele Subject: No more index typos, please To: common-lisp@SU-AI.ARPA Cc: gls@THINK-AQUINAS.ARPA Message-Id: <860107121347.3.GLS@THINK-JEHOSEPHAT.ARPA> I would like to ask that no more messages be sent to me about erroneous or missing index entries in CLtL. I am aware that the index is dreadful and that many important entries are missing. I have plans to do a much more thorough job on the next edition of the book by starting from scratch, so incremental corrections to the existing idnex are not useful to me at this time. Thanks to everyone who has pointed out errors in the past. --Guy  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 7 Jan 86 03:43:07 EST Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 7 Jan 86 00:38:03 PST Received: from JANIS.AI.MIT.EDU by OZ.AI.MIT.EDU via Chaosnet; 7 Jan 86 03:37-EST Date: Tue, 7 Jan 86 03:38 EST From: Christopher Fry Subject: Type questions To: common-lisp@SU-AI.ARPA Message-ID: <860107033828.3.CFRY@JANIS.AI.MIT.EDU> - What's the relationship between keyword, the type, and keyword, a symbol in the keyword package? Spicelisp calls the type keyword a subtype of symbol. - is (subtype foo foo) true for any valid type foo ? - Are the new types: signed-byte and unsigned-byte subtypes of fixnum, like bit is? - In Spicelisp, COMMON is a subtype of ATOM and ATOM is a subtype of COMMON. True in CL? CLtL should have explicite paragraphs and index entries for every type. I noticed BIT and KEYWORD lacked this kind of documentation.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 6 Jan 86 16:29:48 EST Received: from SCRC-YUKON.ARPA by SU-AI.ARPA with TCP; 6 Jan 86 13:23:00 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-YUKON.ARPA via CHAOS with CHAOS-MAIL id 185039; Mon 6-Jan-86 16:18:08-EST Date: Mon, 6 Jan 86 16:23 EST From: David A. Moon Subject: Defsetf and define-setf-method To: Stanley Shebs cc: common-lisp@SU-AI.ARPA In-Reply-To: <8601052323.AA05598@utah-orion.ARPA> Message-ID: <860106162308.4.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Sun, 5 Jan 86 16:23:57 MST From: shebs%utah-orion@utah-cs.arpa (Stanley Shebs) Recently I had a bright idea concerning the complex form of defsetf and define-setf-method, namely that any defsetf could expand into an equivalent call on define-setf-method, and that this would be the right thing for complex defsetfs. That is certainly a reasonable implementation technique and in fact is what I believe most implementations do. Actually defsetf and define-setf-method usually both expand into a third, internal thing. Well, after a few days of screwing around with this, I decided that I didn't really understand how a complex defsetf was supposed to work, or what its full setf method should look like. Is it all inherently hairy, or is there a simple relation between defsetf and define-setf-method that this pea-brained implementor has failed to notice? When you use define-setf-method you write a lot of calls to gensym, but when you use defsetf the macro-expansion of defsetf takes care of making the gensyms itself. See the discussion on page 103. Here's an example (Guy, maybe this should go in the manual): (defsetf subseq (sequence start &optional end) (new-sequence) `(progn (replace ,sequence ,new-sequence :start1 ,start :end1 ,end) ,new-sequence)) (define-setf-method subseq (sequence start &optional end) (let ((seqtemp (gensym)) (startemp (gensym)) (endtemp (gensym)) (stotemp (gensym))) (values (list seqtemp startemp endtemp) (list sequence start end) (list stotemp) `(progn (replace ,seqtemp ,stotemp :start1 ,startemp :end1 ,endtemp) ,stotemp) `(subseq ,seqtemp ,startemp ,endtemp))))  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 6 Jan 86 12:00:14 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 6 Jan 86 08:54:06 PST Received: ID ; Mon 6 Jan 86 11:54:17-EST Date: Mon, 6 Jan 1986 11:54 EST Message-ID: From: Rob MacLachlan To: SANDRA Cc: common-lisp@SU-AI.ARPA Subject: Another inconsistency in CLtL In-reply-to: Msg of 27 Dec 1985 13:53-EST from SANDRA I brought this up a couple months back, and I believe the consensus was that all the functions that take package arguments will accept a string or symbol as well, excepting the PACKAGE-xxx functions which will only accept a package object. I doesn't say this anywhere in the manual; this is a "clarification." Rob  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 5 Jan 86 18:26:58 EST Received: from UTAH-CS.ARPA by SU-AI.ARPA with TCP; 5 Jan 86 15:23:40 PST Received: from utah-orion.ARPA by utah-cs.ARPA (5.5/4.40.2) id AA04498; Sun, 5 Jan 86 16:24:00 MST Received: by utah-orion.ARPA (5.5/4.40.2) id AA05598; Sun, 5 Jan 86 16:23:57 MST Date: Sun, 5 Jan 86 16:23:57 MST From: shebs%utah-orion@utah-cs.arpa (Stanley Shebs) Message-Id: <8601052323.AA05598@utah-orion.ARPA> To: common-lisp@su-ai.arpa Subject: Defsetf and define-setf-method Recently I had a bright idea concerning the complex form of defsetf and define-setf-method, namely that any defsetf could expand into an equivalent call on define-setf-method, and that this would be the right thing for complex defsetfs. Well, after a few days of screwing around with this, I decided that I didn't really understand how a complex defsetf was supposed to work, or what its full setf method should look like. Is it all inherently hairy, or is there a simple relation between defsetf and define-setf-method that this pea-brained implementor has failed to notice? stan  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 4 Jan 86 22:11:43 EST Received: from SU-SCORE.ARPA by SU-AI.ARPA with TCP; 4 Jan 86 19:05:23 PST Received: from MC.LCS.MIT.EDU by SU-SCORE.ARPA with TCP; Sat 4 Jan 86 18:35:17-PST Date: Sat, 4 Jan 86 14:51:14 EST From: "Glenn S. Burke" Sender: HENRIK@MC.LCS.MIT.EDU Subject: Reader hacks, whitespace algorithm To: "REM@IMSSS"@MC.LCS.MIT.EDU cc: COMMON-LISP%SU-AI@SU-SCORE.ARPA Message-ID: <[MC.LCS.MIT.EDU].772855.860104.HENRIK> Any caching scheme has to be integrated with the existing system sufficiently so that the information gets uncached if anyone changes character syntaxes.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 3 Jan 86 22:40:22 EST Received: from UTAH-20.ARPA by SU-AI.ARPA with TCP; 3 Jan 86 09:17:31 PST Date: Fri 3 Jan 86 10:16:31-MST From: SANDRA Subject: yet another typo in the manual To: gls@AQUINAS.THINK.COM cc: common-lisp@SU-AI.ARPA Message-ID: <12172321045.30.LOOSEMORE@UTAH-20.ARPA> I haven't seen any mention of this one before: on page 133, the prog* macro is referred to as a special form. -Sandra -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 3 Jan 86 22:38:15 EST Received: from SU-SCORE.ARPA by SU-AI.ARPA with TCP; 3 Jan 86 08:17:59 PST Received: from IMSSS by Score with Pup; Fri 3 Jan 86 08:14:41-PST Date: 29 Dec 1985 1717-PST From: Rem@IMSSS Subject: Reader hacks, whitespace algorithm To: NGALL%BBNG.ARPA@SCORE cc: COMMON-LISP%SU-AI@SCORE It doesn't matter if your algorithm is inefficient, because it has to be run only once per different character, after which the results can be kept in a lookup table or as properties hanging off the character objects. Therefore if the algorithm works at all, I think you have solved the problem at hand, and since it's portable there's no urgency to put your algorithm in the CLtL manual, the yellow pages will suffice. -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 3 Jan 86 03:55:32 EST Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 3 Jan 86 00:49:50 PST Received: from DUANE.AI.MIT.EDU by OZ.AI.MIT.EDU via Chaosnet; 3 Jan 86 03:47-EST Date: Fri, 3 Jan 86 03:46 EST From: Christopher Fry Subject: Re: Reader hacks To: GSB@MC.LCS.MIT.EDU, NGALL@BBNG.ARPA cc: common-lisp@SU-AI.ARPA, gls@AQUINAS.THINK.COM In-Reply-To: <[MC.LCS.MIT.EDU].770795.860102.GSB> Message-ID: <860103034658.1.CFRY@DUANE.AI.MIT.EDU> Received: from MC.LCS.MIT.EDU by OZ.AI.MIT.EDU via Chaosnet; 2 Jan 86 13:46-EST Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 2 Jan 86 13:48:16 EST Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 2 Jan 86 10:21:48 PST Date: Thu, 2 Jan 86 13:24:29 EST From: "Glenn S. Burke" Subject: Re: Reader hacks To: NGALL@BBNG.ARPA cc: common-lisp@SU-AI.ARPA, gls@AQUINAS.THINK.COM Message-ID: <[MC.LCS.MIT.EDU].770795.860102.GSB> Date: 29 Dec 1985 18:21-EST From: NGALL@BBNG.ARPA I think there should be a function SYNTAX-TYPE char => {ILLEGAL | WHITESPACE | CONSTITUENT | SINGLE-ESCAPE | MULTIPLE-ESCAPE | MACRO} Yes. Please. Don't forget terminating vs. non-terminating macro, and keywords in the keyword package... I hope you meant here that syntax types should be specified by symbols in the keyword package, ie :illegal, :whitespace, etc.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 2 Jan 86 13:32:40 EST Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 2 Jan 86 10:21:48 PST Date: Thu, 2 Jan 86 13:24:29 EST From: "Glenn S. Burke" Subject: Re: Reader hacks To: NGALL@BBNG.ARPA cc: common-lisp@SU-AI.ARPA, gls@AQUINAS.THINK.COM Message-ID: <[MC.LCS.MIT.EDU].770795.860102.GSB> Date: 29 Dec 1985 18:21-EST From: NGALL@BBNG.ARPA I think there should be a function SYNTAX-TYPE char => {ILLEGAL | WHITESPACE | CONSTITUENT | SINGLE-ESCAPE | MULTIPLE-ESCAPE | MACRO} Yes. Please. Don't forget terminating vs. non-terminating macro, and keywords in the keyword package...  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 30 Dec 85 15:56:44 EST Received: from SU-SCORE.ARPA by SU-AI.ARPA with TCP; 30 Dec 85 12:47:10 PST Received: from IMSSS by Score with Pup; Mon 30 Dec 85 12:28:23-PST Date: 29 Dec 1985 1717-PST From: Rem@IMSSS Subject: Reader hacks, whitespace algorithm To: NGALL%BBNG.ARPA@SCORE cc: COMMON-LISP%SU-AI@SCORE It doesn't matter if your algorithm is inefficient, because it has to be run only once per different character, after which the results can be kept in a lookup table or as properties hanging off the character objects. Therefore if the algorithm works at all, I think you have solved the problem at hand, and since it's portable there's no urgency to put your algorithm in the CLtL manual, the yellow pages will suffice. -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 30 Dec 85 15:43:45 EST Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 30 Dec 85 12:30:40 PST Date: Mon, 30 Dec 85 15:33:21 EST From: Jonathan A Rees Subject: Retry, IMSSS->SCORE mail down a few days; Flush implicit catch frames To: REM%IMSSS@SU-SCORE.ARPA cc: COMMON-LISP@SU-AI.ARPA, edsel!eb@SU-NAVAJO.ARPA In-reply-to: Msg of 1985 Dec 29 23:21:04 PST (=GMT-8hr) from Robert Elton Maas Message-ID: <[MC.LCS.MIT.EDU].768914.851230.JAR> Date: 1985 December 29 23:21:04 PST (=GMT-8hr) From: Robert Elton Maas Your message is very interesting. It sounds like CL in forcing the availibility of RETURN-FROM just about everywhere in the language has accidently forbid efficient tail recursion except when an optimizing compiler has gone around and flushed unneeded RETURN-FROM (CATCH) frames. If you are correct, I would favor flushing this default behaviour of CL, instead requiring programmers to say explicitly when some PROG or LET might need the RETURN-FROM capability. As GJC correctly points out, Scheme has always had a lexical catch (i.e. block/return) which is implementable in such a way that catches incur no net stack growth, and no static code analysis is needed. The usual way to do this allocates the control point (either a stub pointing into the control stack, or the entire control stack) in the heap, but there are more or less hairy alternative implementation strategies which do less heap allocation (none, most of the time). I don't think this problem is much different from that of allocating storage for lexical environments, which if not done carefully also threatens tail recursion. So tail-recursion is not a reason to flush implicit blocks. (I can think of other reasons, but that's not the point.)  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 30 Dec 85 11:40:42 EST Received: from THINK.COM by SU-AI.ARPA with TCP; 30 Dec 85 08:32:29 PST Received: from yon by GODOT.THINK.COM via CHAOS; Mon, 30 Dec 85 11:32:39 est Date: Mon, 30 Dec 85 11:32 EST From: Guy Steele Subject: BOA constructor questions To: Moon@SCRC-STONY-BROOK.ARPA, gls@THINK-AQUINAS.ARPA, LOOSEMORE@UTAH-20.ARPA Cc: common-lisp@SU-AI.ARPA, gls@THINK-AQUINAS.ARPA In-Reply-To: <851228180256.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Message-Id: <851230113242.2.GLS@THINK-YON.ARPA> Date: Sat, 28 Dec 85 18:02 EST From: David A. Moon Date: Thu, 26 Dec 85 16:09 EST From: Guy Steele ... But this prompts in me another question: does (defstruct (foo (:constructor build-foo (&optional baz &aux baz))) (baz 5)) mean that (make-foo) initializes BAZ to 5 (make-foo :baz 43) initializes BAZ to 43 (build-foo 91) initializes BAZ to 91 (build-foo) *does not initialize* BAZ ? If not, how else can I say it? (Never mind why I would want to.) Isn't this in conflict with your (Guy's) suggested clarification to page 60, that a function may not have two parameters with the same name? If that clarification was not intended to apply to &AUX variables, you didn't say so. Yes, I suppose it is; but then the interpretation of &AUX variables in this context is completely crocky anyway. I think I prefer to have the very simple rule that no duplicate names are permitted within a single parameter list, period. One can come up with reasonable interpretations in many special cases, but such cases are probably all very poor examples of style. The way I read the Common Lisp manual, your example defstruct above does not define any function named make-foo. You'd have to say (defstruct (foo (:constructor build-foo (&optional baz &aux baz)) (:constructor make-foo)) (baz 5)) if you wanted that. Funny. I always thought that the normal constructor always gets created unless explicitly suppressed with (:constructor nil), BOA constructors being irrelevant to the question. However, I now find that the prose at the bottom of page 315 is horribly ambiguous. I think the answer to "how else can I say it?" is that you can't say it except by being more explicit and verbose, e.g. (defstruct (foo (:constructor build-foo (&optional baz)) (:constructor make-foo (&key (baz 5)))) baz) This sounds fine to me. This might be awkward if "5" were a very large expression and I wanted three constructors, two of which initialize slot BAZ, but I am not going to lose sleep over it. --Guy  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 30 Dec 85 09:08:23 EST Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 30 Dec 85 06:01:39 PST Date: Mon, 30 Dec 85 09:04:23 EST From: "George J. Carrette" Subject: tail recursion in CL interpreters. To: REM%IMSSS@SU-SCORE.ARPA cc: COMMON-LISP@SU-AI.ARPA In-reply-to: Msg of 1985 Dec 29 23:21:04 PST (=GMT-8hr) from Robert Elton Maas Message-ID: <[MC.LCS.MIT.EDU].768550.851230.GJC> Did my reply get lost or something? It explained how you could write an interpreter with tail recursion even with all the implicit BLOCK statements.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 30 Dec 85 05:45:13 EST X-Sent: to SU-AI.ARPA by IMSSS.FRONSTAD.EDU via ETHERNET with PUPFTP; 1985-Dec-30 02:31:40 PST (=GMT-8hr) X-Mailer: EMACS -> PSL (FORMAT+SEND-ALL) -> PUPFTP Date: 1985 December 29 23:21:04 PST (=GMT-8hr) Message-id: SU-IMSSS.REM.A132535112014.G0353 From: Robert Elton Maas To:edsel!eb@su-navajo.arpa CC:COMMON-LISP@SU-AI Subject:Retry, IMSSS->SCORE mail down a few days; Flush implicit catch frames Sender: REM%IMSSS@SU-SCORE.ARPA (for undeliverable-mail notifications) Reply-to: REM%IMSSS@SU-SCORE.ARPA (temporary until IMSSS.STANFORD.EDU registered) Date: 28 Dec 1985 1824-PST From: Rem@IMSSS Subject: I favor flushing implicit catch frames except where appropriate To: edsel!eb%su-navajo.arpa@SCORE cc: COMMON-LISP%SU-AI@SCORE Your message is very interesting. It sounds like CL in forcing the availibility of RETURN-FROM just about everywhere in the language has accidently forbid efficient tail recursion except when an optimizing compiler has gone around and flushed unneeded RETURN-FROM (CATCH) frames. If you are correct, I would favor flushing this default behaviour of CL, instead requiring programmers to say explicitly when some PROG or LET might need the RETURN-FROM capability. When I want to do a non-local return, I first think of THROW/CATCH, which is completely general, and not of RETURN-FROM. Something like 99% of PROGs and LETs et al are simple, don't need a non-local return mechanism. Let's take a survey. Is there anyone who programs in such a way that any significant fraction of PROGs or LETs et al make use of RETURN-FROM? Is there anyone would have to rewrite a lot of code if RETURN-FROM frames weren't implicit everywhere in the language. Would anyone object to requiring explicit CATCH where nonlocal return frames are desired? P.S. Normally all those extra frames are useful during debugging, so when something bombs out you can look up the recursion stack and see all the calls and jcalls still on the stack instead of just the calls (notation: jcall = tail-recursion, call = true-recursion). But often one has an interpreted function that is highly recursive but where those extra frames aren't useful and cause stack overflow, so I can see the value in being able to disable the creation of tail-recursion frames, and I second the motion to maybe flush them. -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 29 Dec 85 18:32:24 EST Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 29 Dec 85 15:24:02 PST Date: 29 Dec 1985 18:21-EST Sender: NGALL@BBNG.ARPA Subject: Re: Reader hacks From: NGALL@BBNG.ARPA To: gls@AQUINAS.THINK.COM Cc: common-lisp@SU-AI.ARPA Message-ID: <[BBNG.ARPA]29-Dec-85 18:21:24.NGALL> In-Reply-To: <851223164735.3.GLS@THINK-JEHOSEPHAT.ARPA> Date: Mon, 23 Dec 85 16:47 EST From: Guy Steele To: common-lisp@SU-AI.ARPA Subject: Reader hacks Message-ID: <851223164735.3.GLS@THINK-JEHOSEPHAT.ARPA> I am writing code for reader macros and find I need the following things: (1) A predicate that is true of whitespace characters and false of all others. The problem is that (member foo '(#\Space #\Newline)) doesn't cover tabs, etc., and (member foo '(#\Space #\Newline #\Tab #\Form)) is not completely portable because of the semi-standard character names. How about?: (defun whitespace-p (char) (with-input-from-string (input-string (string char)) (null (peek-char t input-string nil nil nil)))) If char is a whitespace char., PEEK-CHAR will hit EOF and return NIL; otherwise PEEK-CHAR will return the char. Inefficient, but the only portable solution I know. I think there should be a function SYNTAX-TYPE char => {ILLEGAL | WHITESPACE | CONSTITUENT | SINGLE-ESCAPE | MULTIPLE-ESCAPE | MACRO} -- Nick  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 29 Dec 85 17:23:56 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 29 Dec 85 14:15:51 PST Received: from NEPONSET.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 382604; Sun 29-Dec-85 17:15:01-EST Date: Sun, 29 Dec 85 17:18 EST From: David C. Plummer Subject: Multiple values and &optional To: David A. Moon , Guy Steele cc: common-lisp@SU-AI.ARPA In-Reply-To: <851220222705.5.MOON@EUPHRATES.SCRC.Symbolics.COM> Message-ID: <851229171821.7.DCP@NEPONSET.SCRC.Symbolics.COM> Date: Fri, 20 Dec 85 22:27 EST From: David A. Moon MULTIPLE-VALUE-CALL. Not only is that the right answer, but recall that MULTIPLE-VALUE-BIND is a MACRO, so says CLtL, and as far as I know the only way that macro can expand into special forms and functions defined in CLtL is via MULTIPLE-VALUE-CALL.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 28 Dec 85 20:33:43 EST Received: from SCRC-YUKON.ARPA by SU-AI.ARPA with TCP; 28 Dec 85 15:09:14 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-YUKON.ARPA via CHAOS with CHAOS-MAIL id 182987; Sat 28-Dec-85 18:04:58-EST Date: Sat, 28 Dec 85 18:02 EST From: David A. Moon Subject: BOA constructor questions To: Guy Steele , LOOSEMORE@UTAH-20.ARPA cc: common-lisp@SU-AI.ARPA In-Reply-To: <851226160949.7.GLS@THINK-JEHOSEPHAT.ARPA> Message-ID: <851228180256.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Thu, 26 Dec 85 16:09 EST From: Guy Steele Date: Thu 26 Dec 85 13:38:50-MST From: SANDRA It is not clear from the discussion of BOA constructors in the manual what is supposed to happen if you don't mention all the slot names in the arglist, or even that it's legal to omit slots from the arglist. Presumably, the omitted slots should be initialized to whatever default value was given in the body of the defstruct; if this is the case, the manual should say so. Perhaps a better example would help. I agree with your interpretation and with the suggestion for improving the manual. Also, it says that "the keywords &optional, &rest, and &aux are recognized in the argument list". Is there a reason why &key is not permitted? Or is this an oversight? I don't see any technical reason why &KEY should not be permitted, with semantics analogous to those for &OPTIONAL. Indeed. It works with the obvious semantics in our implementation. Then the standard constructor function can be explained as a special case the more general constructor feature that happens to take an argument for every slot and takes them all as &KEY arguments. But this prompts in me another question: does (defstruct (foo (:constructor build-foo (&optional baz &aux baz))) (baz 5)) mean that (make-foo) initializes BAZ to 5 (make-foo :baz 43) initializes BAZ to 43 (build-foo 91) initializes BAZ to 91 (build-foo) *does not initialize* BAZ ? If not, how else can I say it? (Never mind why I would want to.) Isn't this in conflict with your (Guy's) suggested clarification to page 60, that a function may not have two parameters with the same name? If that clarification was not intended to apply to &AUX variables, you didn't say so. The way I read the Common Lisp manual, your example defstruct above does not define any function named make-foo. You'd have to say (defstruct (foo (:constructor build-foo (&optional baz &aux baz)) (:constructor make-foo)) (baz 5)) if you wanted that. I think the answer to "how else can I say it?" is that you can't say it except by being more explicit and verbose, e.g. (defstruct (foo (:constructor build-foo (&optional baz)) (:constructor make-foo (&key (baz 5)))) baz)  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 28 Dec 85 19:57:38 EST Received: from SU-NAVAJO.ARPA by SU-AI.ARPA with TCP; 28 Dec 85 15:33:25 PST Received: by su-navajo.arpa with Sendmail; Sat, 28 Dec 85 15:30:24 pst Received: by edsel.uucp (2.2/SMI-2.0) id AA12247; Sat, 28 Dec 85 15:15:18 pst Date: Sat, 28 Dec 85 15:15:18 pst From: edsel!eb@su-navajo.arpa (Eric Benson) Message-Id: <8512282315.AA12247@edsel.uucp> To: navajo!Common-Lisp@SU-AI Subject: Tail recursive Common Lisp interpreter? Recently, we added a new feature to our compiler: general tail-recursion removal. That is, when FOO returns the value of calling BAR, there is no need to grow the stack; BAR can use the same stack frame as FOO and return to its caller. Scheme requires this behavior, so that iteration can be defined in terms of recursion. Scheme supporters tend to get irate about Lisp implementations which do not have this behavior. In fact, they call this "properly tail-recursive," giving a moral tone to the whole issue. When I wrote our interpreter, I tried to be very careful so that if it were compiled with a compiler which does tail recursion elimination, it too would be properly tail recursive. Finally, I had a chance to try it out. I compiled EVAL, loaded it in and typed (DEFUN FOO (X) (IF (ZEROP X) (BREAK) (FOO (1- X)))) (FOO 10) thus entering the debugger, expecting to find no frames on the stack. To my dismay, I saw 10 BLOCK frames. Then it dawned on me: every DEFUN wraps a BLOCK around the body, so that I would have been able to say (RETURN-FROM FOO ...) anywhere in my definition. BLOCK is implemented with a CATCH in the interpreter, and the last call of a CATCH is not tail recursive; the CATCH frame must be removed from the stack before returning. Even FLET and LABELS aren't tail recursive, for the same reason, due to our recent extension to them of the "implicit BLOCK" feature. Only raw LAMBDAs are truly tail recursive. I would like to change this, but I don't want to do a lot of static analysis in the interpreter. That tends to defeat the purpose of EVAL, which I take to be fast turnaround time in testing code. I can't see any other way of implementing the implicit BLOCK except using CATCH or some other mechanism which defeats tail recursion. Does anyone have any clever ideas for solving this problem?  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 28 Dec 85 19:45:05 EST Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 28 Dec 85 16:36:04 PST Date: Sat, 28 Dec 85 19:38:46 EST From: "George J. Carrette" Subject: Tail recursive Common Lisp interpreter? To: edsel!eb@SU-NAVAJO.ARPA cc: Common-Lisp@SU-AI.ARPA In-reply-to: Msg of Sat 28 Dec 85 15:15:18 pst from edsel!eb at su-navajo.arpa (Eric Benson) Message-ID: <[MC.LCS.MIT.EDU].767631.851228.GJC> Thats an extremely interesting discovery. One known way to win: You can implement an explicit control evaluator like one might in Scheme. The control-point from a block then falls out like schemes lexical catch contruct does. Or, what is easier, given a Scheme with lexical catch, write your Common-Lisp interpreter in that. Here is another tail-recursion story. One of Papert's hackers was relating to me one day how LOGO was tail recursive even though it used shallow binding, and how that this was a pretty clever thing (to pull off) So I said, ok, lets try to write: (DEFUN IFACT (N ACC) (IF (ZEROP N) ACC (IFACT (1- N) (* N ACC)))) and thus (DEFUN FACT (N) (IFACT N 1)). Well, my first try didnt work at all, in fact, it didnt return ANY VALUE. I was then told that, OH, to return a value you have to use OUTPUT. Thus (excuse the inexact logo syntax) TO IFACT :N :ACC IF N=0 OUTPUT ACC ELSE OUTPUT IFACT N-1 N*ACC well, the OUTPUT caused the tail recursion to be broken. Or, you cant teach an ancient dog old tricks. Or, you can dress the language up but you cant take it ...  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 27 Dec 85 14:02:39 EST Received: from UTAH-20.ARPA by SU-AI.ARPA with TCP; 27 Dec 85 10:54:16 PST Date: Fri 27 Dec 85 11:53:01-MST From: SANDRA Subject: Another inconsistency in CLtL To: common-lisp@SU-AI.ARPA Message-ID: <12170503603.18.LOOSEMORE@UTAH-20.ARPA> The specification for INTERN describes the optional "package" argument as being a package, not a package name. However, the discussion of #S syntax for reading structures on page 357 shows INTERN being called with the "package" argument being the symbol 'keyword. Should this actually be (find-package 'keyword), or have I missed something in the packages chapter that says arguments named "package" can be either packages or package names? -Sandra -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 27 Dec 85 08:37:38 EST Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 27 Dec 85 05:30:41 PST Date: Fri, 27 Dec 85 08:33:24 EST From: "George J. Carrette" Subject: Reader hacks To: GSB@MC.LCS.MIT.EDU cc: common-lisp@SU-AI.ARPA, gls@AQUINAS.THINK.COM, Moon@SCRC-STONY-BROOK.ARPA In-reply-to: Msg of Thu 26 Dec 85 16:45:01 EST from Glenn S. Burke Message-ID: <[MC.LCS.MIT.EDU].767075.851227.GJC> A reader should be able to be a portable common lisp program right? Maybe if a sufficiently flexible reader could be published then people like GLS could use it.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 27 Dec 85 06:27:51 EST Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 27 Dec 85 03:20:44 PST Received: from JANIS.AI.MIT.EDU by OZ.AI.MIT.EDU via Chaosnet; 27 Dec 85 06:26-EST Date: Fri, 27 Dec 85 06:21 EST From: Christopher Fry Subject: GLS's clarifications list (moderately long) To: COMMON-LISP@SU-AI.ARPA In-Reply-To: <8512200453.AA03243@uw-beaver.arpa> Message-ID: <851227062125.6.CFRY@JANIS.AI.MIT.EDU> + (-: The obvious way to have an all-purpose undo function is to generalize setf to work with an odd number of arguments: (setf (symbol-function 'foo)) => (undefun 'foo) (setf (symbol-value '*foov*)) => (mkunbound '*foov*) :-) Not obvious to me, even if there's only one argument. The overloading of the semantics of setf is clever ... which is exactly why I'd prefer the function that does the undo semantics to be spelled differently than "setf" . To me (setf (accessor ...)) implies setting the thing to NIL, but I wouldn't want setf to have that semantics either.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 26 Dec 85 23:08:34 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 26 Dec 85 19:59:59 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 381627; Thu 26-Dec-85 14:55:15-EST Date: Thu, 26 Dec 85 14:49 EST From: David A. Moon Subject: RE: Symbols as pathnames To: Common-Lisp@SU-AI.ARPA In-Reply-To: The message of 26 Dec 85 14:47-EST from "BACH::NELSON" Message-ID: <851226144932.3.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: 12/26/85 14:47 From: "BACH::NELSON" By choosing one from the list of pathname, filename, etc. to refer to pathnames, streams, and strings, did you mean that an argument called pathname could be any of those three types? If you meant that the word pathname actually means "pathname, symbol or string" when used in the text of the book, that seems confusing; while a statement that an argument called "pathname" could be a pathname, string, or stream seems helpful. I meant the latter; sorry to be ambiguous. If, by the way, the approach is to enumerate those three types under each function in chapter 23, it would probably be a god idea to do so for the pathname argument to require, as well. Thanks, I missed that one. Consider it added to my proposal.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 26 Dec 85 23:08:29 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 26 Dec 85 19:59:39 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 381615; Thu 26-Dec-85 14:36:40-EST Date: Thu, 26 Dec 85 14:30 EST From: David A. Moon Subject: XOR To: common-lisp@SU-AI.ARPA In-Reply-To: The message of 22 Dec 85 17:15-EST from MURRAY%umass-cs.csnet@CSNET-RELAY.ARPA Supersedes: <851226130548.6.MOON@EUPHRATES.SCRC.Symbolics.COM> Message-ID: <851226143056.0.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Sun, 22 Dec 85 17:15 EST From: MURRAY%umass-cs.csnet@CSNET-RELAY.ARPA I think the discussion about whether there should be an XOR function is very much off the mark. I think the criterion for including any new operator in the language should be one of the following: 1) It is not possible to write it in Common Lisp. 2) It can be implemented MUCH more efficiently in an implemention dependant way. 3) It requires a lot of programming effort (and is generally useful). As long as an operator is implementable in Common Lisp, your program would still be portable. The only problem that could arise is that your function/macro is called something that later on becomes defined in Common Lisp, with different syntax/semantics. But that problem exists with ANY operator that you define, and packages can deal with it. Thus I see no reason to include something like XOR. The language is certainly big enough already. I agree completely. I could not have stated my position as clearly and completely as you have. LATER: I also agree with the other people who said that a 4th criterion should be added, that enough people will use it that it's important to standardize the name, even though everyone could implement it for themselves. They seemed to think that by saying this they were disagreeing with you, but I didn't read what you said as disagreeing with that sentiment. [Rest of message, about other issues, not included in this particular reply]  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 26 Dec 85 20:13:51 EST Received: from SU-SCORE.ARPA by SU-AI.ARPA with TCP; 26 Dec 85 17:05:59 PST Received: from Xerox.ARPA by SU-SCORE.ARPA with TCP; Thu 26 Dec 85 17:02:36-PST Received: from Cabernet.ms by ArpaGateway.ms ; 26 DEC 85 17:05:48 PST Date: 26 Dec 85 17:05 PST From: Bobrow.pa@Xerox.ARPA Subject: Re: COPY and COPY-IN In-reply-to: Rem@IMSSS.ARPA's message of 26 Dec 85 16:25 PST To: Rem@IMSSS.ARPA cc: Bobrow.pa%Xerox.ARPA@SU-SCORE.ARPA, COMMON-LISP%SU-AI@SU-SCORE.ARPA Message-ID: <851226-170548-1750@Xerox> Do I understand your proposed semantics correctly, that at the very top level COPY will force-copy a named object creating an unnamed object with all the same parts as the original but not EQ to it and inaccessible via the oblist, but recursively an object is copied if and only if it isn't named, being a recursion-stop-point if it is named? (at least that's the proposed default, which could be overriden by keyword parameters to COPY which become fluid parameters accessed by COPY-IN) ------- I would propose that the top level COPY will force-copy (if that makes sense); but what it does is determined by a METHOD associated with the class of the object. Similarly, the recursion is controlled by the COPY-IN METHOD for each class. A class could have its own specific response to keyword-parameters.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 26 Dec 85 19:35:30 EST Received: from SU-SCORE.ARPA by SU-AI.ARPA with TCP; 26 Dec 85 16:28:28 PST Received: from IMSSS by Score with Pup; Thu 26 Dec 85 16:25:19-PST Date: 26 Dec 1985 1625-PST From: Rem@IMSSS Subject: COPY and COPY-IN To: Bobrow.pa%Xerox.ARPA@SCORE cc: COMMON-LISP%SU-AI@SCORE Do I understand your proposed semantics correctly, that at the very top level COPY will force-copy a named object creating an unnamed object with all the same parts as the original but not EQ to it and inaccessible via the oblist, but recursively an object is copied if and only if it isn't named, being a recursion-stop-point if it is named? (at least that's the proposed default, which could be overriden by keyword parameters to COPY which become fluid parameters accessed by COPY-IN) -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 26 Dec 85 16:50:31 EST Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 26 Dec 85 13:42:18 PST Date: Thu, 26 Dec 85 16:45:01 EST From: "Glenn S. Burke" Subject: Reader hacks To: Moon@SCRC-STONY-BROOK.ARPA cc: common-lisp@SU-AI.ARPA, gls@AQUINAS.THINK.COM Message-ID: <[MC.LCS.MIT.EDU].766640.851226.GSB> From: David A. Moon From: Guy Steele I am writing code for reader macros and find I need the following things: (1) A predicate that is true of whitespace characters and false of all others. . . . Is this something different from (or (char-equal char #\space) (not (graphic-char-p char))) ? Well, i was going to say that backspace didn't fit this mold, but CLtM says it isn't a token constituent unless quoted. Oh well. Anyway, have we ever speculated on the relationship of predicates like graphic-char-p or this hypothetical whitespace-p, and readtables? How well-defined is it to transfer the syntax of one character to another? (2) I find I can't easily write myself something akin to READ-DELIMITED-LIST that handles dotted lists because of the problem of recognizing all-dots tokens. PEEK-CHAR can only peek one ahead, so I can't tell whether there is a space after a dot before calling READ recursively. How about a way (a special variable?) to turn off the somewhat silly restriction that you can't have a symbol named .? Flushing the restriction of unquoted all-dots tokens would only ameliorate the problem a bit, because he would still have to read the token himself because he wouldn't be able to unread-char both the dot and the following token. Besides all the other stuff which is almost what read-delimited-list provides. Restated, the problem is that one might want read-delimited-list to barf about cons dots; for instance, to implement #( syntax. Alternatively, one might want to do variations of ordinary parentheses in which cons-dot is meaningful. So having some sort of flag argument to read-delimited-list makes sense. Alternatively, how about a function that does the token-isolating portion of READ but not the printed-representation-to-object conversion portion of READ? Do you think this could be done without over half the implementors having apoplectic fits, and with no loss of life?  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 26 Dec 85 16:17:17 EST Received: from THINK.COM by SU-AI.ARPA with TCP; 26 Dec 85 13:09:07 PST Received: from jehosephat by GODOT.THINK.COM via CHAOS; Thu, 26 Dec 85 16:09:15 est Date: Thu, 26 Dec 85 16:09 EST From: Guy Steele Subject: BOA constructor questions To: LOOSEMORE@UTAH-20.ARPA, common-lisp@SU-AI.ARPA Cc: gls@THINK-AQUINAS.ARPA In-Reply-To: <12170260722.11.LOOSEMORE@UTAH-20.ARPA> Message-Id: <851226160949.7.GLS@THINK-JEHOSEPHAT.ARPA> Date: Thu 26 Dec 85 13:38:50-MST From: SANDRA It is not clear from the discussion of BOA constructors in the manual what is supposed to happen if you don't mention all the slot names in the arglist, or even that it's legal to omit slots from the arglist. Presumably, the omitted slots should be initialized to whatever default value was given in the body of the defstruct; if this is the case, the manual should say so. Perhaps a better example would help. Also, it says that "the keywords &optional, &rest, and &aux are recognized in the argument list". Is there a reason why &key is not permitted? Or is this an oversight? -Sandra ------- I don't see any technical reason why &KEY should not be permitted, with semantics analogous to those for &OPTIONAL. Then the standard constructor function can be explained as a special case the more general constructor feature that happens to take an argument for every slot and takes them all as &KEY arguments. But this prompts in me another question: does (defstruct (foo (:constructor build-foo (&optional baz &aux baz))) (baz 5)) mean that (make-foo) initializes BAZ to 5 (make-foo :baz 43) initializes BAZ to 43 (build-foo 91) initializes BAZ to 91 (build-foo) *does not initialize* BAZ ? If not, how else can I say it? (Never mind why I would want to.) --Guy  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 26 Dec 85 15:48:17 EST Received: from UTAH-20.ARPA by SU-AI.ARPA with TCP; 26 Dec 85 12:40:04 PST Date: Thu 26 Dec 85 13:38:50-MST From: SANDRA Subject: BOA constructor questions To: common-lisp@SU-AI.ARPA Message-ID: <12170260722.11.LOOSEMORE@UTAH-20.ARPA> It is not clear from the discussion of BOA constructors in the manual what is supposed to happen if you don't mention all the slot names in the arglist, or even that it's legal to omit slots from the arglist. Presumably, the omitted slots should be initialized to whatever default value was given in the body of the defstruct; if this is the case, the manual should say so. Perhaps a better example would help. Also, it says that "the keywords &optional, &rest, and &aux are recognized in the argument list". Is there a reason why &key is not permitted? Or is this an oversight? -Sandra -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 26 Dec 85 14:47:57 EST Received: from XEROX.ARPA by SU-AI.ARPA with TCP; 26 Dec 85 11:39:06 PST Received: from Cabernet.ms by ArpaGateway.ms ; 26 DEC 85 11:39:17 PST Date: 26 Dec 85 11:39 PST From: Bobrow.pa@Xerox.ARPA Subject: Re: copy To: dfm@uw-beaver.arpa cc: COMMON-LISP@su-ai.arpa Message-ID: <851226-113917-1685@Xerox> If we adopt something like CommonLoops where all objects have an associated class, then the Copy problem becomes factored in a different way; that is, one independently decides for each class the response to two messages, COPY and COPY-IN: COPY is the top level call. It produces a copy if it can e.g. a new cons pair, same symbol, but a copy of a named structure (unnamed). COPY-IN is the recursive call. Each type determines whether to return itself or a copy for inclusion in a larger structure. The protocol suggested by dfm is probably the appropriate definition for COPY-IN. For named objects, COPY and COPY-IN would differ. For CONSes they would be the same, etc. danny  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 26 Dec 85 14:04:21 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 26 Dec 85 10:54:39 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 381574; Thu 26-Dec-85 13:52:11-EST Date: Thu, 26 Dec 85 13:46 EST From: David A. Moon Subject: Reader hacks To: Guy Steele cc: common-lisp@SU-AI.ARPA In-Reply-To: <851223164735.3.GLS@THINK-JEHOSEPHAT.ARPA> Message-ID: <851226134628.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Mon, 23 Dec 85 16:47 EST From: Guy Steele I am writing code for reader macros and find I need the following things: (1) A predicate that is true of whitespace characters and false of all others. The problem is that (member foo '(#\Space #\Newline)) doesn't cover tabs, etc., and (member foo '(#\Space #\Newline #\Tab #\Form)) is not completely portable because of the semi-standard character names. Is this something different from (or (char-equal char #\space) (not (graphic-char-p char))) ? (2) I find I can't easily write myself something akin to READ-DELIMITED-LIST that handles dotted lists because of the problem of recognizing all-dots tokens. PEEK-CHAR can only peek one ahead, so I can't tell whether there is a space after a dot before calling READ recursively. How about a way (a special variable?) to turn off the somewhat silly restriction that you can't have a symbol named .? Alternatively, how about a function that does the token-isolating portion of READ but not the printed-representation-to-object conversion portion of READ?  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 26 Dec 85 13:59:56 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 26 Dec 85 09:34:30 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 381485; Thu 26-Dec-85 12:33:42-EST Date: Thu, 26 Dec 85 12:27 EST From: David A. Moon Subject: Symbols as pathnames To: common-lisp@SU-AI.ARPA In-Reply-To: <851011153205.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Message-ID: <851226122756.1.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Fri, 11 Oct 85 15:32 EDT From: David A. Moon Date: Fri, 11 Oct 85 09:47:43 CDT From: wagner@GSWD-VMS On page 418 of CLtL, concerning the OPEN function: "The filename ...may be a string, a pathname, or a stream." May it not also be a symbol, and shouldn't the spec say so? Same for WITH-OPEN-FILE, etc.? (The underlying pathname functions work with symbols.) It's true that most places in the manual say that symbols are acceptable where pathnames are required, and are parsed as namestrings. I don't understand why this feature is in there; it seems like asking for trouble. What about implementations (yes they exist) where some streams are implemented as symbols? How do you tell whether a symbol was supposed to be a stream or supposed to be a string? What if NIL is accidentally used where a pathname was expected, do you really want to get a file named "NIL"? It's possible that the feature of allowing symbols as pathnames was blindly copied from an old version of Zetalisp, which used to allow that. A couple of bad ideas got into Common Lisp that way, in spite of significant effort by the committee to try to keep it from happening. Zetalisp allowed symbols for compatibility with an old version of pdp-10 Maclisp that didn't have strings. I never saw a response to the above. Now that we are discussing clarifications, I'd like to suggest the following as a proposed clarification, to fix the fact that in some places the manual says symbols are accepted as pathnames and in other places it says they aren't. Symbolics' implementation currently contains some inconsistencies in this area, which cannot be corrected without deviating from what the manual currently says in one way or another. I'd prefer to see all implementations deviate in the same direction. If you reply to this message, please delete the enclosures from October, which I only included for context. p.413, 3rd paragraph: change "string or symbol" to "string" in both sentences. p.413, pathname function: same. p.414, 2nd to last paragraph: same. p.417, pathname-host function, 1st sentence: same. p.417, namestring function, 1st sentence: same. p.414, parse-namestring function: delete the clause saying that @I[thing] may be a symbol, in the second sentence. p.415, merge-pathnames function, 3rd sentence: delete "or symbol". p.424, probe-file function: Specify what @I[file] may be (I presume a string, a pathname, or a stream). p.423, rename-file function: change "@I[new-name] (which must be a filename)" to "@I[new-name]." and add at the end of the first paragraph "@I[New-name] must be a pathname, a string, or a stream." I see no reason to disallow streams here; the conversion from stream to pathname is as defined by the PATHNAME function. p.424, file-write-date and file-author functions, also GLS's proposed extension to the file-length function: These use the term "filename", which I cannot find defined elsewhere. Change "filename" to "pathname or string". p.426, load function: This has an argument named "filename", whose type is not defined. Define it to be a pathname, string, or stream--the same as the argument named "filename" for open and with-open-file. In chapter 23, there are arguments named pathname, thing, filename, file, and name (really new-name). As far as I can tell there is no semantic difference associated with these five different names. A consistent terminology should be adopted. I suggest calling all of them pathname.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 26 Dec 85 13:40:34 EST Received: from THINK.COM by SU-AI.ARPA with TCP; 26 Dec 85 10:28:07 PST Received: from jehosephat by GODOT.THINK.COM via CHAOS; Thu, 26 Dec 85 13:27:58 est Date: Thu, 26 Dec 85 13:28 EST From: Guy Steele Subject: Comments To: MURRAY%umass-cs.csnet@CSNET-RELAY.ARPA, common-lisp@SU-AI.ARPA Cc: gls@THINK-AQUINAS.ARPA In-Reply-To: The message of 22 Dec 85 17:15-EST from MURRAY%umass-cs.csnet@CSNET-RELAY.ARPA Message-Id: <851226132828.4.GLS@THINK-JEHOSEPHAT.ARPA> Date: Sun, 22 Dec 85 17:15 EST From: MURRAY%umass-cs.csnet@CSNET-RELAY.ARPA I think the discussion about whether there should be an XOR function is very much off the mark. I think the criterion for including any new operator in the language should be one of the following: 1) It is not possible to write it in Common Lisp. 2) It can be implemented MUCH more efficiently in an implemention dependant way. 3) It requires a lot of programming effort (and is generally useful). There should be a fourth criterion: 4) It is so useful that many individual users keep reinventing it, and therefore it is deserving of standardization. PUSH and POP fall into this category, for example. On the other hand, I will not argue that XOR does fall into this category, as all the reent evidence on the mailing list indicates otherwise. Several others have also pointed out the potential ambiguity in extending XOR to more than two arguments: is it "an odd number true", "exactly one true", or "all but one true" (the latter being unlikely given the name, but nevertheless a consistent extension)? The main reason for choosing "an odd number true" is that that definition is associative, whereas the other choices are not. If XOR were to be added to the language (and I will not argue strongly that it should be), I would suggest making it a function (not a special form) of exactly two arguments (to avoid the ambiguity). I do not find convincing the argument against XOR on the grounds that it cannot terminate its execution early the way AND and OR do. After all, NOT is usually in the same bag as AND and OR, and it is not a special form. I would say that XOR is more like NOT than like AND and OR. --Guy  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 26 Dec 85 13:21:04 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 26 Dec 85 10:12:01 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 381519; Thu 26-Dec-85 13:11:31-EST Date: Thu, 26 Dec 85 13:05 EST From: David A. Moon Subject: XOR To: common-lisp@SU-AI.ARPA In-Reply-To: The message of 22 Dec 85 17:15-EST from MURRAY%umass-cs.csnet@CSNET-RELAY.ARPA Message-ID: <851226130548.6.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Sun, 22 Dec 85 17:15 EST From: MURRAY%umass-cs.csnet@CSNET-RELAY.ARPA I think the discussion about whether there should be an XOR function is very much off the mark. I think the criterion for including any new operator in the language should be one of the following: 1) It is not possible to write it in Common Lisp. 2) It can be implemented MUCH more efficiently in an implemention dependant way. 3) It requires a lot of programming effort (and is generally useful). As long as an operator is implementable in Common Lisp, your program would still be portable. The only problem that could arise is that your function/macro is called something that later on becomes defined in Common Lisp, with different syntax/semantics. But that problem exists with ANY operator that you define, and packages can deal with it. Thus I see no reason to include something like XOR. The language is certainly big enough already. I agree completely. I could not have stated my position as clearly and completely as you have. [Rest of message, about other issues, not included in this particular reply]  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 24 Dec 85 18:43:48 EST Received: from THINK.COM by SU-AI.ARPA with TCP; 24 Dec 85 15:35:39 PST Received: from jehosephat by GODOT.THINK.COM via CHAOS; Mon, 23 Dec 85 12:19:04 est Date: Mon, 23 Dec 85 12:16 EST From: Guy Steele Subject: GLS's clarifications list (moderately long) To: DLW@SCRC-QUABBIN.ARPA, apollo!dfm@UW-BEAVER.ARPA, COMMON-LISP@SU-AI.ARPA In-Reply-To: <851220193530.7.DLW@CHICOPEE.SCRC.Symbolics.COM> Message-Id: <851223121647.1.GLS@THINK-JEHOSEPHAT.ARPA> Date: Fri, 20 Dec 85 19:35 EST From: Daniel L. Weinreb I would like to point out that you are discussing the implementation details of "globals" before we have agreed what "globals" are. There were several interpretations of "globals" floating around on the mail and no resolution of which one we were talking about. You are quite right, of course. In my case that was intentional, but I failed to make that clear. I was trying to explicate an alternative semantics by proposing an implementation (not a specific one, but rather one tied to DEFCONSTANT).  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 24 Dec 85 18:38:47 EST Received: from THINK.COM by SU-AI.ARPA with TCP; 24 Dec 85 15:30:50 PST Received: from jehosephat by GODOT.THINK.COM via CHAOS; Mon, 23 Dec 85 16:49:47 est Date: Mon, 23 Dec 85 16:47 EST From: Guy Steele Subject: Reader hacks To: common-lisp@SU-AI.ARPA Cc: gls@THINK-AQUINAS.ARPA Message-Id: <851223164735.3.GLS@THINK-JEHOSEPHAT.ARPA> I am writing code for reader macros and find I need the following things: (1) A predicate that is true of whitespace characters and false of all others. The problem is that (member foo '(#\Space #\Newline)) doesn't cover tabs, etc., and (member foo '(#\Space #\Newline #\Tab #\Form)) is not completely portable because of the semi-standard character names. (2) I find I can't easily write myself something akin to READ-DELIMITED-LIST that handles dotted lists because of the problem of recognizing all-dots tokens. PEEK-CHAR can only peek one ahead, so I can't tell whether there is a space after a dot before calling READ recursively. --Guy  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 24 Dec 85 00:13:03 EST Received: from UW-BEAVER.ARPA by SU-AI.ARPA with TCP; 23 Dec 85 20:57:58 PST Received: by uw-beaver.arpa (4.42/4.2) id AA10071; Mon, 23 Dec 85 20:59:20 PST Return-Path: Message-Id: <8512240459.AA10071@uw-beaver.arpa> From: apollo!dfm@uw-beaver.arpa Date: Mon, 23 Dec 85 17:03:01 EST Subject: copy (moderately long message) To: COMMON-LISP@su-ai.arpa Cc: dfm Here's a more detailed description of one possible version of copy. I believe this combines most of the features people have suggested in recent mail and clarifies most of the ambiguities people have pointed out in recent mail. copy object &key :array :structure :hash-table :readtable :pathname :random-state :gensym :fill-pointer :adjustable :level :circle Recursively copies object as follows: If object is a cons copy returns a new cons (i.e. it is guaranteed that (and (consp object) (eq (copy object) object)) => nil) and calls itself recursively to fill in the car and cdr. If object is an array and :array is non-nil (it defaults to t) copy returns a new array as follows: The rank, dimensions, and element type are the same as object, subject to the restrictions regarding fill pointers below. Even if object is displaced, the result is not. The contents of the array are recursively copied. If an element of the array is undefined (e. g. not initialized), it is undefined in the result. In particular, if an implementation can recognize that an element is undefined it need not copy that element. Only if object has a fill pointer and :fill-pointer is non-nil will the result have a fill pointer. The fill pointer is initialized to the same value as object's fill pointer, and all the defined elements of object, even those that are inactive with respect to the fill pointer, are copied. If the object has a fill pointer but :fill-pointer is nil the result does not have a fill pointer, and the length of the resulting vector is reduced to the current value of object's fill pointer. :Fill-pointer defaults to nil. Only if object is adjustable and :adjustable is non-nil is the result adjustable. :Adjustable defaults to nil. If object is a user defined structure and :structure is non-nil copy returns a new structure of the same type. If object is named, the result acquires the same name (i.e. if object is a user defined, named structure then (eq (type-of object) (type-of (copy object)) => t). The values of the slots of object are recursively copied to the result. If the value of a slot of object is undefined, the value of the corresponding slot in the result is undefined. In particular, if an implementation can recognize that a slot's value is undefined it need not copy that slot. Any slots skipped over by the :initial-offset option to defstruct are not recursively copied; that is, their values in the result are eql to their values in object. :Structure defaults to t. If object is a hash table and :hash-table is non-nil copy returns a new hash table whose size is at least as large as that of object, and with the same test, rehash-size, and rehash-threshold. An entry is made in the new hash table for each entry in object: keys are not recursively copied (i.e. the key in the new table is eql to that in the old) but values are recursively copied. :Hash-table defaults to nil. If object is a readtable and :readtable is non-nil copy returns the same value as (copy-readtable object). :Readtable defaults to nil. If object is a pathname and :pathname is non-nil copy returns the same value as (make-pathname :host (pathname-host object) :device (pathname-device object) :directory (pathname-directory object) :name (pathname-name object) :type (pathname-type object) :version (pathname-version object) ) :Pathname defaults to t. If object is a random state and :random-state is non-nil copy returns the same value as (make-random-state object). :Random-state defaults to t. If object is an uninterned symbol and :gensym is non-nil copy returns the same value as (copy-symbol object). :Gensym defaults to t. Otherwise copy simply returns a value eql to object. The :level argument can be used to limit the depth of recursion. If supplied and non-nil it should be a non-negative integer, in which case copy will only copy items at that depth or shallower. For example, (copy object :level 1) copies only the top level object itself. As a boundary case (copy object :level 0) returns object with- out any copying. In the case of conses the depth is considered to increase only through the cars, and not the cdrs; that is, an entire list is considered to be at the same level. For example, if L is a list, then (copy L :level 1) returns the same value as (copy-seq L). :Level defaults to nil. If object is circular, or contains circular substructures, copy may fail to terminate. If :circle is non-nil copy endeavors to detect cycles and terminate normally, returning an isomorphic object. :Circle defaults to nil. NOTES: - The basic intention is that (copy object) be similar to (read-from-string (write-to-string object :array t)), with objects that would be printed using #< notation not being copied. Exactly what objects are printed using #< notation is implementation dependent, and it seems best that the value returned by copy be as implementation independent as possible. Therefore some choices have to be made, mostly reflected in the defaults (e.g. I expect most implementations to print hash tables using #<, but pathnames in some readable format). These choices are obviously subjective. - The reason no mechanism for preserving displacement in copying arrays is provided is that displacement is typically an effort to deliberately avoid copying. - It might seem strange to allow numeric and character keys in a #'eq hash table to be copied (a la eql). However, I don't think that it can ever make sense to use a #'eq hash table portably with numbers and characters. - Note that copying a readtable, pathname, or random state may be a "shallow" copy. However, since the structure of these items is not defined by the language it seems incorrect to try to define it otherwise. - No mechanism is supplied for copying interned ids or packages as that would appear to raise some prohibitively awkward issues. - No machinism is supplied for copying streams or functions, as the semantics of these seem to be too implementation dependent. - I see no reason why implementations couldn't allow copying other types of objects by supplying more keyword arguments. Such extensions would, of course, not be portable. - Regarding :level and cdrs there seems to be a choice to be made between lists and trees of conses. Lists are by far the more prevalent data structure so it seems best to favor them. This also makes :level parallel the use of :level in write. - One might expect that if there's a :level there should be a :length. This is awkward for anything but lists, however. While I would expect (copy '((1) (2) (3)) :length 2) to copy the first two elements but not the third, what do I do about (copy '#((1) (2) (3)) :length 2)? One could say that we don't copy the entire surrounding structure, and, for consistency, apply the same rule to lists; the complexity of this seems to more than outweigh the dubious usefulness of :length in copy. - I believe that (equalp x (copy x)) => t. Indeed, the intermediate equality predicate that Eric Benson proposed (case sensitive equalp) (and that I agree is needed -- and should be supported as a hash table test) should also be true. - I believe that this copy can easily be written in COMMON LISP, once the proposed functions hash-table-size, etc. have been added, except for the code dealing with structures. That implies to me that COMMON LISP probably needs more functionality for manipulating structures. For example, I don't think that there is even a portable way of even telling whether or not an object *is* a user defined structure. - Don Morrison  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 24 Dec 85 00:08:48 EST Received: from UW-BEAVER.ARPA by SU-AI.ARPA with TCP; 23 Dec 85 20:58:23 PST Received: by uw-beaver.arpa (4.42/4.2) id AA10088; Mon, 23 Dec 85 21:00:04 PST Date: Mon, 23 Dec 85 21:00:04 PST From: @uw-beaver.arpa Return-Path: <@uw-beaver.arpa> Message-Id: <8512240500.AA10088@uw-beaver.arpa> Apparently-To: COMMON-LISP@SU-AI.ARPA  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 23 Dec 85 17:10:28 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 23 Dec 85 13:55:20 PST Received: ID ; Mon 23 Dec 85 16:55:27-EST Date: Mon, 23 Dec 1985 16:55 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Common-Lisp@SU-AI.ARPA Subject: Ground rules not yet decided??? In-reply-to: Msg of 23 Dec 1985 11:28-EST from Rem at IMSSS In response to REM@IMSSS (mail sent to that address always bounces back in my face): It was never our intention to try to formalize the "ground rules" covering the philosophy of language design at the Boston meeting or anywhere else. This is a fluid process with a lot of varying opinions, and in the end these choices come down to taste and experience. I don't think it would be wise to try to chisel a set of principles in stone, even if we could get people to agree. What we did try to do in Boston was to work out some more formal way for making final decisions on what is in Common Lisp and what is not. I had assumed that everyone who cared about this had heard the news from someone who attended the meeting, but maybe not. What happened in the charter area was this (very briefly): After some discussion of the possible kinds of organization we might want to form, we heard from Bob Mathis on what it would take to standardize Common Lisp in a formal way under ISO. Mathis used to run the Ada and Stars programs at DOD, and he was deeply involved in the effort to get Ada standardized by ISO. In the past, most of us had discounted the formal standards organizations as unwieldy bureaucracies that mangle everything they touch, but Mathis persuaded most of us that there was a good chance of setting things up so that a technical committee acceptable to the current Common Lisp community produces a recommendation for a standard (perhaps a series of standards, one every couple of years) and the ISO approves this as the standard definition of Common Lisp without a lot of gratuitous alterations. We decided that this route was worth a try. The original gang of five, plus Mathis and Squires, were appointed to try to put together a steering committee to do the political work and a technical commitee that would be more representative of the total community than the gang of five are by themselves. This will then be proposed to ISO, with Mathis as the "convenor" of the committee -- a position of some power. The formation of a separate standards organization for Common Lisp was put on hold for six months, by which time we should have a good idea whether the ISO process is going to work the way we want it to. However, we hope to proceed rapidly toward getting ISI a contract from DARPA for performing various non-decision-making support tasks for Common Lisp. The intention is that the technical committee, once formed, would work in more or less the way that we always have worked. Issues would be raised, discussed via the network (we hope to establish better mail connections with Europe and Japan as quickly as possible), and when some sort of near consensus emerges, a decision would be made and recorded. The technical committee would then announce that this is going to be in the proposed standard that is sent on to ISO. Eventually, all of these decisions are bundled together, sent to ISO, and (we hope) they emerge from the other end of the process as an ISO standard. Getting through these last few steps could take a long time, but companies would be perfectly free to go ahead and implement what is in the proposal, rather than waiting for the final standard to be approved. One thing that became clear at the meeting was that there is considerable interest in Europe, especially in Jerome Chailloux's group in France, in working on a smaller, cleaner Lisp that probably would be a subset of Common Lisp. Of course, there has been some interest in this in the U.S. as well, particularly in Kessler's PCLS group at Utah, and Dr. Ida in Japan has been working on something similar. I personally don't see any fundamental conflict here. What might well emerge is a two-level standard (or maybe two distinct standards): big, ugly, hairy industrial strength Common Lisp on the one hand, and some cleaner subset on the other. (Whether the subset people can reach agreement is another matter -- there are many different reasons for doing a subset, and the resulting language would be different in each case.) It would cause a lot of confusion to use the name "Common Lisp" to refer to anything other than the big language more or less as defined in Guy's book, but if we're careful in choosing what to call the subset, the two levels should be able to coexist quite happily. So the next task is to work out the membership of the technical and steering committees, and then do whatever one does to get ISO to recognize them. This will take awhile. In the meantime, nobody is in a position to make any binding decisions on language issues, but we can continue to muddle along as we have for the last year or two until the more formal mechanism is in place. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 23 Dec 85 16:33:33 EST Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 23 Dec 85 13:22:52 PST Date: Mon, 23 Dec 85 16:25:37 EST From: Jonathan A Rees Subject: unspecial & global & macrolet To: common-lisp@SU-AI.ARPA Message-ID: <[MC.LCS.MIT.EDU].764953.851223.JAR> I don't much care whether DEFGLOBAL exists. But I will lobby for a (declare (unspecial ...)) or (declare (lexical ...)), which provides the sorely needed ability to do an assured lexical binding, independent of the existence of a global special binding. Does anyone have objections to the addition of an unspecial declaration? I have asked about this twice before and haven't had any replies, although I know there must be SOME reason it isn't in CLtL, since Maclisp and the various Lisp Machine Lisps have it, and it must have been considered. I guess one objection is that for symmetry there ought to be a (proclaim '(lexical ...)) to go with (declare (lexical ...)), and then we're back to arguing about DEFGLOBAL again. But Common Lisp doesn't strike me as a language in which symmetry and orthogonality play important roles, so I don't see that this objection carries much weight; you could have one and not the other. --- I actually make good use of MACROLET; I think it's too late to eradicate it, since many other users will be depending on it also. Jonathan  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 23 Dec 85 13:41:42 EST Received: from SU-SCORE.ARPA by SU-AI.ARPA with TCP; 23 Dec 85 10:29:44 PST Received: from IMSSS by Score with Pup; Mon 23 Dec 85 10:26:42-PST Date: 23 Dec 1985 0828-PST From: Rem@IMSSS Subject: Ground rules not yet decided??? To: COMMON-LISP%SU-AI@SCORE I thought the main reason for the big meeting this month was to make a constitution and to decide basic ground rules such as what rule of thumb should decide whether a given feature should be in CL or not? Why are we still arguing over it? Wasn't it decided at the meeting? I think the CL group should hurry up and decide these basic issues, so our debate over details of this should be in and this should be out won't be in a vacuum where only random personal opinions guide us. -------  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 23 Dec 85 11:09:24 EST Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 23 Dec 85 07:49:33 PST Date: 23 Dec 1985 10:51-EST Sender: NGALL@BBNG.ARPA Subject: Re: Comments From: NGALL@BBNG.ARPA To: MURRAY%umass-cs.csnet@CSNET-RELAY.ARPA Cc: common-lisp@SU-AI.ARPA Message-ID: <[BBNG.ARPA]23-Dec-85 10:51:26.NGALL> In-Reply-To: The message of Sun, 22 Dec 85 17:15 EST from MURRAY%umass-cs.csnet@CSNET-RELAY.ARPA Date: Sun, 22 Dec 85 17:15 EST From: MURRAY%umass-cs.csnet@CSNET-RELAY.ARPA To: common-lisp@su-ai.ARPA Subject: Comments I think the discussion about whether there should be an XOR function is very much off the mark. I think the criterion for including any new operator in the language should be one of the following: 1) It is not possible to write it in Common Lisp. 2) It can be implemented MUCH more efficiently in an implemention dependant way. 3) It requires a lot of programming effort (and is generally useful). As long as an operator is implementable in Common Lisp, your program would still be portable. The only problem that could arise is that your function/macro is called something that later on becomes defined in Common Lisp, with different syntax/semantics. But that problem exists with ANY operator that you define, and packages can deal with it. Thus I see no reason to include something like XOR. The language is certainly big enough already. I would change criterion (3) to 3) It is generally useful and without it, ugly (i.e., opaque) idioms must be used. Since (I believe) the point is whether or not "everyone" is going to implement it anyway, given that it is so useful. If they are, it should be standardized, regardless of the implementation effort. So, to me, the question concerning XOR is, will "everyone" use it? Since I have NEVER been aware of the need for such a construct, I would vote NO. ... I recall someone has already asked for the inclusion of the function MACROEXPAND-ALL. If this hasn't been accepted, I second the motion on the grounds of criterion 3 above (It requires knowledge of special-operators). I agree (on the grounds of my revised critterion 3). ... Random Functions: I would also like to suggest the addition of the predicate FILE-STREAM-P, which if true, would return the file pathname. On the grounds of what criteria? On the basis of being implementation dependant (criterion 1), I suggest three more functions: FUNCTION-ARGLIST, MACRO-ARGLIST, and FUNCTION-NAME. These should work for system functions as well as user defined ones. And for all kinds of functions - closures, compiled, interpreted. I heartily agree (at least about the first one)! I'm desperate for such right now! I'm writing a profile module now and I'm "advising" data collection calls around functions. And to make the advising function as fast as possible I'd like it to have an "equivalent" lambda-list. For example, currently, I'm forced to write something like: `(lambda (&rest arglist) (start-data-collection) (unwind-protect (apply ',original-function arglist) (stop-data-collection))) which is SLOW (in most (?) implementations) due to both the use of &REST and the use of APPLY. If I could get the number of req. and opt. args and an indication of whether or not a &rest arg (implicit or not) is required, I could write something like the following: (multiple-value-bind (req-args-count opt-args-count restp) (parameter-info original-function) (if (not restp) (let ((req-args '()) (opt-args '())) (dotimes (i req-args-count) (push (gensym) req-args)) (dotimes (i opt-args-count) (push (gensym) opt-args)) `(lambda (,@req-args &optional ,@opt-args) (declare (inline ,original-function)) (start-data-collection) (unwind-protect `(,original-function ,@req-args &optional ,@opt-args) (stop-data-collection)))) )) The above code if oversimplified. It assumes that the optional parameters of the original-function all default to NIL and don't contain s. But I hope you get the point. Thus I recommend a function named PARAMETER-INFO that takes an arg. of type (SATISFIES FUNCTIONP) and returns three values: the number of required parameters (an integer), the number of optional parameters (an integer), and either T or NIL depending on whether any &REST or &KEYWORD parameters appear in the lambda-list. I believe this information is retained (in all (?) implementations) even by compiled code. P.S. Does anyone know how I could get such info about a compiled function definition in VaxLisp?! -- Nick  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 23 Dec 85 11:08:01 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 23 Dec 85 07:56:00 PST Received: ID ; Mon 23 Dec 85 10:55:46-EST Date: Mon, 23 Dec 1985 10:55 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: MURRAY%umass-cs.csnet@CSNET-RELAY.ARPA Cc: common-lisp@SU-AI.ARPA Subject: Comments In-reply-to: Msg of 22 Dec 1985 17:15-EST from MURRAY%umass-cs.csnet at CSNET-RELAY.ARPA I don't agree with Murray's three cirteria for what should go into the language. I think a reasonable fourth criterion is: 4) The proposed construct will be used a lot, represents some abstraction that is easy to grasp, and code using it is clearer than the equivalent lower-level stuff appearing inline. Actually, that's a criterion that every programmer should use in deciding whether to create a new function or macro, but if the "used a lot" part applies to the Common Lisp community as a whole and not just to one or two application programs, then it is worthwhile putting this new thing in. This leads to a large language, but one in which there are lots of useful constructs and one in which it is much easier for person A to read person B's code. Murray's rules would lead to a very lean language, perhaps easier to learn and a little bit easier to implement, but not so good for heavy duty programming. For better or for worse, we decided years ago that Common Lisp would include a lot of these optional things. That is why, for example, we include all the sequence functions that could just as easily have been written as DO's (or as PROG's and GO's, for that matter.) Of course, we've got to stop somewhere. Constructs whose usefulness is unclear don't make it, nor do constructs where each person wants something a little bit different and where there is no general agreement on how to bundle these different versions into a single clear package. If an item is controversial, but is implementable in a strictly portable way, we generally suggest that it be put into a Yellow Pages library until we see if it is going to "take" or not. I don't like XOR because it doesn't look generally useful to me and because it can be quite confusing to deal with. There are several closely-related things that XOR might mean (only one versus odd parity, for example) and the parallelism with AND and OR breaks down in some ugly ways. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 23 Dec 85 11:06:44 EST Received: from MIT-MC.ARPA by SU-AI.ARPA with TCP; 23 Dec 85 07:48:31 PST Date: Mon, 23 Dec 85 10:51:14 EST From: "Glenn S. Burke" Subject: xor To: common-lisp@SU-AI.ARPA Message-ID: <[MC.LCS.MIT.EDU].764612.851223.GSB> What i don't like about XOR is that it sounds like it is in the same class as AND and OR, and it is not all that like them. Like it or not, AND and OR are control constructs. (I have never had any problem with this, but Lisp is my first programming language. I am somewhat disturbed by attempts to mask this nature of them -- they may lead to even more confusion by this deemphasis.) I wouldn't mind the functionality, but it's not clear to me that it is worth too much confusion. As far as implementation is concerned, i can see being able to implement this much better as a special operator than as a macro.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 23 Dec 85 03:41:36 EST Received: from CSNET-RELAY.ARPA by SU-AI.ARPA with TCP; 23 Dec 85 00:30:45 PST Received: from umass-cs by csnet-relay.csnet id a026470; 23 Dec 85 3:25 EST Date: Sun, 22 Dec 85 17:15 EST From: MURRAY%umass-cs.csnet@CSNET-RELAY.ARPA To: common-lisp@su-ai.ARPA Subject: Comments I think the discussion about whether there should be an XOR function is very much off the mark. I think the criterion for including any new operator in the language should be one of the following: 1) It is not possible to write it in Common Lisp. 2) It can be implemented MUCH more efficiently in an implemention dependant way. 3) It requires a lot of programming effort (and is generally useful). As long as an operator is implementable in Common Lisp, your program would still be portable. The only problem that could arise is that your function/macro is called something that later on becomes defined in Common Lisp, with different syntax/semantics. But that problem exists with ANY operator that you define, and packages can deal with it. Thus I see no reason to include something like XOR. The language is certainly big enough already. Other Issues: I would like to vehemently disagree with the proposed change to the mapping functions, such that it is an error to pass them circular-lists. A see no advantage to this, and a clear disadvantage (I use this mechanism, and often find it the clearest way to express certain computation e.g. (mapcar #'two-arg-fun arg1-list (or extra-arg-list (circular-list NIL))). Moreoever, any implementation that actually Checked for the error is certainly a foolish one. It seems to me that the DEFGLOBAL proposal adds more confusion than it could ever be worth. If the desire is to create a global variable without taking chances on doing a dynamic binding of it, then it seems the informal policy of doing *this* to a dynamic variable is adequate. Anyone who does (let ((*something* ...))) is surely begging to get a dynamic binding. Moreoever, it would seem to generate no more efficiency. ;; I vote for eradication of MacroLet. I recall someone has already asked for the inclusion of the function MACROEXPAND-ALL. If this hasn't been accepted, I second the motion on the grounds of criterion 3 above (It requires knowledge of special-operators). It appears that there is no way to return multiple values from conditional forms in any useful way. COND,AND,OR don't return multiple values for their predicate forms, except for the last form. AND isn't problematic, since if it returns non-nil, it returns the values of the last form, and hence multiple-values. It is OR that is problematic. I find it unfortunate that something like: (defun find-it (list parallel-list) (cond ((null list) nil) ((and (atom list) (passes-test list)) (values list parallel-list)) (t (or (find-it (car list) (car parallel-list)) (find-it (cdr list) (cdr parallel-list)))))) Won't work since the OR won't return the multiple values for the first (car) form. What is most distressing is that OR WILL return multiple values for the last form. This can easily create subtle bugs that are hard to figure out unless you know of the peculiar behavior of OR. Of course, you can give up on multiple-values, but it seems a real problem if you have to resort to returning Lists in cases like these. It is therfore my opinion that OR should return multiple values for ALL of it's forms, or none of them. If the latter, Multiple-Value-OR can be written in Common Lisp, but I wonder if it possible to do it more efficiently in an implementation dependant way? (BTW: Page 84 of Cltl refers to OR as a Special Form) Random Functions: I would also like to suggest the addition of the predicate FILE-STREAM-P, which if true, would return the file pathname. On the basis of being implementation dependant (criterion 1), I suggest three more functions: FUNCTION-ARGLIST, MACRO-ARGLIST, and FUNCTION-NAME. These should work for system functions as well as user defined ones. And for all kinds of functions - closures, compiled, interpreted. - Kelly Murray University Of Massachusetts  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 22 Dec 85 00:12:08 EST Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 21 Dec 85 17:37:57 PST Date: 21 Dec 1985 18:20-EST Sender: NGALL@BBNG.ARPA Subject: Re: Multiple values and &optional From: NGALL@BBNG.ARPA To: gls@AQUINAS.THINK.COM Cc: common-lisp@SU-AI.ARPA Message-ID: <[BBNG.ARPA]21-Dec-85 18:20:32.NGALL> In-Reply-To: <851220170310.1.GLS@THINK-WENCESLAS.ARPA> Date: Fri, 20 Dec 85 17:03 EST From: Guy Steele To: common-lisp@SU-AI.ARPA Subject: Multiple values and &optional Message-ID: <851220170310.1.GLS@THINK-WENCESLAS.ARPA> Just for the record, I had an application today where I really wanted to write something like (MULTIPLE-VALUE-BIND (VALUE &OPTIONAL (FOUNDP T)) (FUNCALL (MAGIC-HOOK-FUNCTION THINGY) FUNNY-ARG) (WHEN FOUNDP (CACHE-SOME-STUFF THINGY FUNNY-ARG VALUE)) (VALUES VALUE FOUNDP)) How about: (multiple-value-call #'(lambda (value &optional (foundp t)) (when foundp (cache-some-stuff thingy funny-arg value)) (values value foundp)) (magic-hook-function thingy)) And I agree that MULTIPLE-VALUE-BIND should be able to take a full-blown lambda-list. -- Nick  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 21 Dec 85 20:47:11 EST Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 21 Dec 85 17:37:57 PST Date: 21 Dec 1985 18:20-EST Sender: NGALL@BBNG.ARPA Subject: Re: Multiple values and &optional From: NGALL@BBNG.ARPA To: gls@AQUINAS.THINK.COM Cc: common-lisp@SU-AI.ARPA Message-ID: <[BBNG.ARPA]21-Dec-85 18:20:32.NGALL> In-Reply-To: <851220170310.1.GLS@THINK-WENCESLAS.ARPA> Date: Fri, 20 Dec 85 17:03 EST From: Guy Steele To: common-lisp@SU-AI.ARPA Subject: Multiple values and &optional Message-ID: <851220170310.1.GLS@THINK-WENCESLAS.ARPA> Just for the record, I had an application today where I really wanted to write something like (MULTIPLE-VALUE-BIND (VALUE &OPTIONAL (FOUNDP T)) (FUNCALL (MAGIC-HOOK-FUNCTION THINGY) FUNNY-ARG) (WHEN FOUNDP (CACHE-SOME-STUFF THINGY FUNNY-ARG VALUE)) (VALUES VALUE FOUNDP)) How about: (multiple-value-call #'(lambda (value &optional (foundp t)) (when foundp (cache-some-stuff thingy funny-arg value)) (values value foundp)) (magic-hook-function thingy)) And I agree that MULTIPLE-VALUE-BIND should be able to take a full-blown lambda-list. -- Nick  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 21 Dec 85 20:33:57 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 21 Dec 85 17:21:03 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 380091; Fri 20-Dec-85 22:32:47-EST Date: Fri, 20 Dec 85 22:27 EST From: David A. Moon Subject: Multiple values and &optional To: Guy Steele cc: common-lisp@SU-AI.ARPA In-Reply-To: <851220170310.1.GLS@THINK-WENCESLAS.ARPA> Message-ID: <851220222705.5.MOON@EUPHRATES.SCRC.Symbolics.COM> MULTIPLE-VALUE-CALL.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 21 Dec 85 03:05:17 EST Received: from UW-BEAVER.ARPA by SU-AI.ARPA with TCP; 20 Dec 85 23:55:56 PST Received: by uw-beaver.arpa (4.42/4.2) id AA15611; Fri, 20 Dec 85 22:43:24 PST Return-Path: Message-Id: <8512210643.AA15611@uw-beaver.arpa> From: apollo!dfm@uw-beaver.arpa Date: Fri, 20 Dec 85 10:49:08 EST Subject: Re: Elegant rule for what to copy To: uw-beaver!Rem%IMSSS Cc: COMMON-LISP@su-ai.arpa From: Rem@IMSSS@uw-beaver.UUCP Subject: Elegant rule for what to copy To: COMMON-LISP%SU-AI@SCORE Interned symbols (IDs) will be stop points, but GENSYMs will be recursed through, with another GENSYM of exactly the same name replacing it, and with copies of the value and plist and function. (In that case READing it back in would accidently INTERN all the former GENSYMs, so COPY is more "right" than PRIN1-READ.) That's not quite right, at least if *print-gensym* has its default value of t. Instead a gensym would be prin1'd using #: notation, and read back in as a new gensym with the same print name but *not* with the same plist, value, or function.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 20 Dec 85 20:01:42 EST Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 20 Dec 85 16:36:13 PST Received: from CHICOPEE.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 379983; Fri 20-Dec-85 19:35:18-EST Date: Fri, 20 Dec 85 19:35 EST From: Daniel L. Weinreb Subject: GLS's clarifications list (moderately long) To: gls@THINK-AQUINAS.ARPA, apollo!dfm@UW-BEAVER.ARPA, COMMON-LISP@SU-AI.ARPA In-Reply-To: <851220112818.5.GLS@THINK-WENCESLAS.ARPA> Message-ID: <851220193530.7.DLW@CHICOPEE.SCRC.Symbolics.COM> I would like to point out that you are discussing the implementation details of "globals" before we have agreed what "globals" are. There were several interpretations of "globals" floating around on the mail and no resolution of which one we were talking about.  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 20 Dec 85 17:13:20 EST Received: from THINK.COM by SU-AI.ARPA with TCP; 20 Dec 85 14:03:00 PST Received: from wenceslas by GODOT.THINK.COM via CHAOS; Fri, 20 Dec 85 17:03:02 est Date: Fri, 20 Dec 85 17:03 EST From: Guy Steele Subject: Multiple values and &optional To: common-lisp@SU-AI.ARPA Cc: gls@THINK-AQUINAS.ARPA Message-Id: <851220170310.1.GLS@THINK-WENCESLAS.ARPA> Just for the record, I had an application today where I really wanted to write something like (MULTIPLE-VALUE-BIND (VALUE &OPTIONAL (FOUNDP T)) (FUNCALL (MAGIC-HOOK-FUNCTION THINGY) FUNNY-ARG) (WHEN FOUNDP (CACHE-SOME-STUFF THINGY FUNNY-ARG VALUE)) (VALUES VALUE FOUNDP)) The context was that I wanted to have a user hook for a GETHASH-like protocol, where a second return value indicates whether or not a goodie was actually found. However, for convenience I wanted to allow the user hook function to be any function that returns one thing as well, in which case one assumes that the thing was found. In short, I wanted the second return value to default to T, not NIL. I ended up writing this instead: (LET ((STUFF (MULTIPLE-VALUE-LIST (FUNCALL (MAGIC-HOOK-FUNCTION THINGY) FUNNY-ARG)))) (WHEN (OR (NULL (CDR STUFF)) (CADR STUFF)) (CACHE-SOME-STUFF THINGY FUNNY-ARG (CAR STUFF))) (VALUES-LIST STUFF)) --Guy  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 20 Dec 85 15:26:25 EST Received: from THINK.COM by SU-AI.ARPA with TCP; 20 Dec 85 12:11:13 PST Received: from wenceslas by GODOT.THINK.COM via CHAOS; Fri, 20 Dec 85 11:28:13 est Date: Fri, 20 Dec 85 11:28 EST From: Guy Steele Subject: GLS's clarifications list (moderately long) To: apollo!dfm@UW-BEAVER.ARPA, COMMON-LISP@SU-AI.ARPA Cc: gls@THINK-AQUINAS.ARPA In-Reply-To: <8512200453.AA03243@uw-beaver.arpa> Message-Id: <851220112818.5.GLS@THINK-WENCESLAS.ARPA> Date: Thu, 19 Dec 85 17:18:36 EST From: apollo!dfm@uw-beaver.arpa + COMMON LISP's #n=/#n# syntax invites the creation of circular lists. For example, the following seems more tasteful than the example with star, and is, I believe, fairly perspicuous: (mapcar #'cons p-list '#0=(property value . #0#)) Of course, the example with the STAR function: (mapcar #'cons baz (star 'foo)) allows the value to be calculated at run time. The obvious way to do it with #n= syntax is to use backquote: (mapcar #'cons p-list `#0=(,property ,value . #0#)) but right now backquote is not defined to work on circular lists. We could define it to do so (or maybe introduce `@ to handle the circular case). Does COMMON LISP guarantee that we can successfully call inspect on a circular list or structure? It should. I agree, but it isn't addressed explicitly. A related clarification. Not only can data be circular, so can code. It should probably "be an error" to try to eval something like (progn . #0=((f) . #0#)) ; an ugly way of saying (loop (f)) A LISP for the IBM 370 developed at Yorktown by Fred Blair and colleagues actually made this work in both interpreter and compiler. Fred was very proud of it. + Regarding globals: ... I'd rather not see globals introduced into the language, but deep binding implementations may really need them... Actually, a trick that was designed for S-1 LISP may reduce the overhead in deep-binding implementations: let there be a counter associated with the global value cell, initially zero. Every time a deep binding of that variable is created, the counter is incremented, and when the binding is destroyed, the counter is decremented. Lookup of a special variable proceeds as follows: first check the global counter. If it is zero, just grab the global value cell. Otherwise do the usual deep-binding search. Process-switching involves nothing new. Note that if there are several processes, they share a single counter. The counter merely serves as a hint: you might do the search even if you didn't really have to (in the case where your process hasn't done a special binding but some other process did), but in the truly global case, no one has bound it and so the search is eliminated. It does increase the cost of the lookup in the special case, but only by a single zero check. One does have to be careful to destroy all bindings (in order to adjust the counts) when a process is destroyed if the efficiency is to be maintained. + (-: The obvious way to have an all-purpose undo function is to generalize setf to work with an odd number of arguments: (setf (symbol-function 'foo)) => (undefun 'foo) (setf (symbol-value '*foov*)) => (mkunbound '*foov*) :-) I would favor this quite a bit had not SETF been generalized to any even number of argument forms rather than just two. With the generalization, the chances for accidental lossage are too great. Maybe we could make one argument form do an undo, but three or five would be illegal. - Don Morrison --Guy  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 20 Dec 85 15:19:42 EST Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 20 Dec 85 12:03:38 PST Received: ID ; Fri 20 Dec 85 14:39:32-EST Date: Fri, 20 Dec 1985 14:38 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Masinter.pa@XEROX.ARPA Cc: common-Lisp@SU-AI.ARPA Subject: fonts in CLtL In-reply-to: Msg of 19 Dec 1985 16:09-EST from Masinter.pa at Xerox.ARPA I believe that all of us at CMU (I'm sure I'll be corrected if I'm wrong) feel that the fonts attribute in a character is worthless. For editor-like applications, it's too much work and too much wasted storage to deal with this on a per-character basis. It might be useful for extended character sets (e.g. Greek or Japanese), but not for the usual use of switching between various sizes and shapes of Roman characters. It's much better to use an additional data structure for that. I've felt for some time that the bits attribute is also a bit misguided. It seems to me that there are two distinct concepts that have become muddled together: input keystroke objects, which are probably keyborad or system dependent and which want to represent things like the various flavors of shift and whether a keystroke came from the alphanumeric area or the numeric keypad, and internal characters in some implementation independent encoding suitable for stuffing into strings or shoving into an output stream. The former has "bits" attached, but all you really do with such things is pass them around, translate them to true characters, dispatch on them, and maybe store them into a script of some sort. This is not something to be changed lightly, but I agree with Masinter that it is probably worth seeing whether anyone is really using these thing sin the way that they were originally intended to be used. If nobody is, or if the people using them also feel that they are not the right thing, then we should think hard about making a change. -- Scott  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 20 Dec 85 00:07:03 EST Received: from UW-BEAVER.ARPA by SU-AI.ARPA with TCP; 19 Dec 85 20:51:39 PST Received: by uw-beaver.arpa (4.42/4.2) id AA03243; Thu, 19 Dec 85 20:53:17 PST Return-Path: Message-Id: <8512200453.AA03243@uw-beaver.arpa> From: apollo!dfm@uw-beaver.arpa Date: Thu, 19 Dec 85 17:18:36 EST Subject: GLS's clarifications list (moderately long) To: COMMON-LISP@su-ai.arpa Apologies if any of the following have been discussed and resolved before. + COMMON LISP's #n=/#n# syntax invites the creation of circular lists. For example, the following seems more tasteful than the example with star, and is, I believe, fairly perspicuous: (mapcar #'cons p-list '#0=(property value . #0#)) Another place where circular lists are useful is with progv. Suppose I'm passed a list of dynamic variables to be bound and initialized to nil, but whose length I don't know. Three obvious ways are (1) to cons up a list of nils at runtime, (2) write a recursive macro, and (3), the following, which seems clearest: (progv var-list '#0=(nil . #0#) ...) Whether circular arguments to such functions are allowed or forbidden, all the functions where folks might be tempted to use them may need to be identified, so an explicit "it is an error to pass a circular list ...," "implementations are required to support circular lists ...," or whatever can be put in their descriptions. Alternatively some general rule, or possibly a table, can be constructed. Since people can do some pretty tasteless things, the list of possibilities is quite large. So far I've come up with the following, although I'm sure I've missed some: - map, every, some, notany, and notevery - mapc, mapcan, mapcar, mapcon, mapl, and maplist - the format directives ~?, ~{, ~:{, and ~:@{ - progv - dolist - the following, so long as :end (or possibly :end1, :end2, or :count) is supplied, although for most of them I have a lot of trouble imagining why anyone would actually try to use a circular list: count, count-if, count-if-not, delete, delete-if, delete-if-not, fill, find, find-if, find-if-not, mismatch, nsubstitute, nsubstitute-if, nsubstitute-if-not, position, position-if, position-if-not, reduce, remove, remove-if, remove-if-not, remove-duplicates, replace, search, substitute, substitute-if, and substitute-if-not - getting even more far-fetched, if tests with side-effects are allowed (possibly in conjuction with :test or :test-if-not) a lot of the functions in the previous item together with the following are possibilities: assoc, assoc-if-not, member, member-if, member-if-not, adjoin, union, nunion, intersection, nintersection, set-difference, nset-difference, set-exclusive-or, nset-exclusive-or, subset, rassoc, rassoc-if, rassoc-if-not, and pushnew. - does GLS's clarification of (tailp '() L) imply that the following is legal? (tailp '() '#0=(x . #0#)) I can imagine someone tastefully using everything down to and including dolist with circular lists, even though I'd never use most of them myself. Below that everything seems a revolting quagmire, and should explicitly "be an error." Does COMMON LISP guarantee that we can successfully call inspect on a circular list or structure? It should. A related clarification. Not only can data be circular, so can code. It should probably "be an error" to try to eval something like (progn . #0=((f) . #0#)) ; an ugly way of saying (loop (f)) + From: SCRC-STONY-BROOK.arpa!KMP@uw-beaver.UUCP (Kent M Pitman) Certainly I've had a lot more use for NAND and NOR than for XOR. Xor might be useful in that it avoids having to either repeat an expression or introduce a let variable. This is what distinguishes it from nand and nor. For example, (nand (one-of-my-special-expressions-p x) (apply (get (first x) 'dispatcher) (rest x)) ) can be written (not (and (one-of-my-special-expressions-p x) (apply (get (first x) 'dispatcher) (rest x)) )) which isn't much hairier, while (xor (one-of-my-special-expressions-p x) (apply (get (first x) 'dispatcher) (rest x)) ) can be written (if (one-of-my-special-expressions-p x) (not (apply (get (first x) 'dispatcher) (rest x))) (apply (get (first x) 'dispatcher) (rest x)) ) or (let* ((x (one-of-my-special-expressions-p x)) (y (apply (get (first x) 'dispatcher) (rest x))) ) (if x (not y) y) ) both of which are, I believe, hairier. Such reasoning led me write an xor several times. But neither I nor anyone else ever used the ones I wrote, as far as I can tell. Ever. It probably has no place in the language, especially since the rare someone who actually needs it a lot can easily enough write one. + Regarding adding the functions hash-table-rehash-size, hash-table-rehash-threshold, hash-table-size, and hash-table-test: - Would these be setf'able? I would expect the first two could be done easily, and even the size and test can be changed by rehashing the table. - What does hash-table-test return? 'eql or #'eql? While on the subject of hash tables, here are a couple more points that have been bothering me: - Why is there no way to hash on arrays (other than bit-vectors and strings) and structures? Should #'equalp hash tables also be supported? Things I would have preferred to implement as structures I've implemented as lists, defining accessors by hand, just so I can hash on them. - Shouldn't it be made explicit that hash tables may store the actual key, and that destructive operations should not be performed on it? Or is this even true? I suppose one might expect a #'eq hash table to continue working even if you mucked around with the keys stored in it, even though one would probably not expect that of a #'equal hash table (yuk). + Regarding requiring that implementations support tracing of macros: What does it mean to trace a macro? Do you just print information when the macro is expanded, or do you arrange to have information printed every time the expansion is eval'd? There are LISPs out there doing it each way. + Regarding globals: Standard LISP has the notion of a global. Nearly every time I've modified a Standard LISP program that used globals extensively I've had to change one or two of them to fluids (i.e. special) because something the original implementor (often myself) thought no one would ever want to rebind I neede to rebind. Even worse are the plethora of cases where somebody squirrels away a global's value in a local, and restores it on the way back out (at least doing this in COMMON LISP could be reasonably safe because of unwind-protect, which Standard LISP lacks). Of course, these have always been shallow binding implementations, where specials come for nearly free. I'd rather not see globals introduced into the language, but deep binding implementations may really need them, and it would be better to have one, standard mechanism than have each deep binding implementation define its own incompatible one. + Not only would it be nice to be able to copy things involving structures, it would be nice to be able to walk an arbitrary LISP object, including going through structures. As near as I can tell, there's no portable way to walk through the slots of an arbitrary structure. For example, how could one write a recursive function which counted the number of occurances of the symbol 'foo in an arbitrary LISP object which might contain, at any level, arbitrary structures? Have I missed something? I get the feeling that there may have been a deliberate decision to not allow this, but I'm not sure why. + I'm sure I'm being dense, but could someone explain two things from GLS's list of clarifications to me? - Why does (tailp '() L) return nil? I would have expected it to always return t (I think that means that I would have thought the second sentence of the description was right, and the first sentence was incorrect). - Why does xor with more than two arguments do the odd/even stuff? I would have expected it either to look for exactly one true value or exactly one false, but not something as random as an odd number of trues. + (-: The obvious way to have an all-purpose undo function is to generalize setf to work with an odd number of arguments: (setf (symbol-function 'foo)) => (undefun 'foo) (setf (symbol-value '*foov*)) => (mkunbound '*foov*) :-) - Don Morrison  Received: from SU-AI.ARPA by MC.LCS.MIT.EDU 19 Dec 85 16:56:06 EST Received: from XEROX.ARPA by SU-AI.ARPA with TCP; 19 Dec 85 13:46:37 PST Received: from Cabernet.ms by ArpaGateway.ms ; 19 DEC 85 13:46:28 PST Date: 19 Dec 85 13:09 PST From: Masinter.pa@Xerox.ARPA Subject: fonts in CLtL To: common-Lisp@su-ai.ARPA Message-ID: <851219-134629-1475@Xerox> Are there any implementations which use a value of CHAR-FONT-LIMIT other than 1, or a non-vacuous definition for CHAR-FONT? If not, could we remove this feature from the language? (Under the theory that "optional" features which no implementation uses should be removed from the specification.) ----- Begin Forwarded Messages ----- Return-Path: Received: from SCRC-STONY-BROOK.ARPA by Xerox.ARPA ; 17 DEC 85 18:18:31 PST Received: from EUPHRATES.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 376532; Tue 17-Dec-85 20:48:14-EST Date: Tue, 17 Dec 85 20:43 EST From: David A. Moon Subject: fonts in CLtL To: Daniel L. Weinreb , masinter.pa cc: rpg@SU-AI.ARPA, sybalsky.pa In-Reply-To: <851216230521.4.DLW@CHICOPEE.SCRC.Symbolics.COM> Message-ID: <851217204330.5.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Mon, 16 Dec 85 23:05 EST From: Daniel L. Weinreb Date: 16 Dec 85 15:11 PST From: masinter.pa@Xerox.ARPA It was my impression looking over the latest Symbolics documentation that Symbolics has moved away from using font-bits in characters. We've found them impossible -- they don't contain enough information. If there aren't any other implementations that use font-bits, maybe we could get rid of them. I thought I'd ask privately before broadcasting. Yes, I proposed this recently and I think that we have agreed to do it. Our model of character styles does not include any mapping from integers to styles (fonts) that is suitable for Common Lisp's model of the font attribute. (There is a mapping, but its lifetime is only over one Lisp environment, so it would be meaningless to say #3\A in a file.) (I've CC'ed Moon so he can correct me if necessary.) The above is all correct. CHAR-FONT-LIMIT will be 1 in our next release, CHAR-FONT will always return 0, and we will have a field in characters, whose value is an instance rather than an integer, that doesn't pretend to be any of the Common Lisp character fields. NB: None of this has anything to do with CHAR-BITS, which we make good use of. ----- End Forwarded Messages -----