Received: from SU-AI.ARPA by AI.AI.MIT.EDU 13 Jul 86 00:52:54 EDT Received: from XEROX.COM by SU-AI.ARPA with TCP; 12 Jul 86 21:42:05 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 12 JUL 86 21:42:03 PDT Date: 12 Jul 86 21:40 PDT From: Pavel.pa@Xerox.COM Subject: Re: DECLARE SPECIAL Considered Confusing In-reply-to: "Scott E. Fahlman" 's message of Sat, 12 Jul 86 22:48 EDT To: Fahlman@C.CS.CMU.EDU cc: Common-Lisp@SU-AI.ARPA Message-ID: <860712-214203-1410@Xerox> Date: Sat, 12 Jul 86 22:48 EDT From: "Scott E. Fahlman" ... We would also need to spell out in detail exactly how all this works in DO, DO*, and friends. It's obvious what should happen if you think in terms of the expansion into a LET or LET* form, but we don't want to leave that up to the readers to figure out. Actually, I think that we ought to provide example macro definitions for almost all of the macros in CLtL in order to avoid the ambiguity in their descriptions. For example, as I think Moon or Weinreb pointed out, CLtL doesn't specify the result of this program: (setq foo nil) (dotimes (i 10) (push #'(lambda (n) n) foo)) (mapcar #'funcall foo) At the very least, it should be specified for DO, DOLIST and DOTIMES whether they repeatedly rebind their variables or simply SETQ them. I don't imagine that any implementation does rebinding for DO, but it's just as simple as SETQ for DOLIST. I disagree with Pavel's proposal for LAMBDA (and, therefore, DEFUN). He suggests that the scope of all the declarations should coincide with the scope of the first required parameter -- in effect, this follows the current rule of making the declarations wrap everything. That seems wrong to me. The variables are bound and the init-forms are computed left-to-right, as in LET*. If we change LET* in the way Pavel suggests, we ought to change LAMBDA in the corresponding way: the scope of a declaration matches the scope of the variable binding it applies to; the scope of declarations that do not apply to variable-bindings created by the lambda list includes only the body of the form. -- Scott I considered that approach in writing up my proposal and actually like it better than the ``whole form'' notion given there. The only problem I saw (and still see) with it is that in cases like this: (defun bar (&optional (x (foo))) (declare (inline foo)) ...) the call to FOO in the init-form is not covered by the INLINE declaration. Further, the only way to affect it at all is to use LOCALLY. I wasn't sure if this was an important enough problem to force a change, so I put in the current semantics and waited to see. Now that you've pointed it out, I'm in agreement with you; the consistency with LET* is much more important than any obscure difficulty in init-forms. Pavel  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 12 Jul 86 23:00:07 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 12 Jul 86 19:48:05 PDT Received: ID ; Sat 12 Jul 86 22:48:30-EDT Date: Sat, 12 Jul 1986 22:48 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Common-Lisp@SU-AI.ARPA Subject: DECLARE SPECIAL Considered Confusing It seems that Weinreb and Rees both like Pavel's proposal better than the status quo, so it is at least worthy of careful consideration. As an individual, I like the proposal too, except for a couple of problems that I think I see. I'm not sure whether it is enough of an improvement to be worth the trouble that such a change would cause, but in the case of Spice Lisp, our interpeter does not correctly implement the current rules at present. (Our compiler does.) Let's explore Pavel's idea, try to get it right, and then see if the community feels it improves the coherence and consistency of the langauge enough to be worth the trouble of changing things. I used to feel that the clearest and simplest way to handle these embedded declarations was to treat the scope of the declaration form as wrapping the whole form in which it appeared. Maybe this is an example of what Moon calls "superficial simplicity". The idea of letting the scope of each declaration match the scope of the variable it applies to, with any remaining declarations wrapping only the body of the form, is perhaps a conceptually clearer way to handle this if we explain it clearly enough. I think that Pavel's treatment of LET, LET*, FLET, LABELS, and MACROLET is good. We would also need to say explicitly that a SPECIAL declaration for a variable that is not bound by the form in question wraps only the body, not the init forms. We would also need to spell out in detail exactly how all this works in DO, DO*, and friends. It's ovious what should happen if you think in terms of the expansion into a LET or LET* form, but we don't want to leave that up to the readers to figure out. I disagree with Pavel's proposal for LAMBDA (and, therefore, DEFUN). He suggests that the scope of all the declarations should coincide with the scope of the first required parameter -- in effect, this follows the current rule of making the declarations wrap everything. That seems wrong to me. The variables are bound and the init-forms are computed left-to-right, as in LET*. If we change LET* in the way Pavel suggests, we ought to change LAMBDA in the corresponding way: the scope of a declaration matches the scope of the variable binding it applies to; the scope of declarations that do not apply to variable-bindings created by the lambda list includes only the body of the form. -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 12 Jul 86 19:28:23 EDT Received: from [192.10.41.41] by SU-AI.ARPA with TCP; 12 Jul 86 16:18:46 PDT Received: from CHICOPEE.SCRC.Symbolics.COM by ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 40282; Sat 12-Jul-86 19:18:35 EDT Date: Sat, 12 Jul 86 19:17 EDT From: Daniel L. Weinreb Subject: Re: DECLARE SPECIAL Considered Confusing To: fahlman@CMU-CS-C.ARPA cc: Common-Lisp@SU-AI.ARPA Message-ID: <860712191707.7.DLW@CHICOPEE.SCRC.Symbolics.COM> I think it's hard to say whether the current situation causes serious trouble for code writers, or will cause such trouble. I agree with you that the policy question of whether we should consider the question open or not is not completely clear. However, I find the current situation confusing and counterintuitive. Confusing behavior in a peripheral part of the language definition is one thing, but here we're talking about confusing in the basic semantics of how variables work. I definitely do not like the current definition. It seems arbitrary, inconsistent, and overly complex that the evaluation of certain forms, like optional init forms, should see the declarations from the body inside while they do not see the variables being bound. I fully expect to have bugs in my code because of this surprise, and I don't know if I'll ever get used to it. I would be happier if we decided to fix the definition in some way (Pavel's proposal looks like it's basically the right thing, but I have not thought hard about all the details yet).  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 12 Jul 86 13:03:21 EDT Received: from KIM.Berkeley.EDU by SU-AI.ARPA with TCP; 12 Jul 86 07:52:07 PDT Received: by kim.Berkeley.EDU (5.53/1.14) id AA18962; Sat, 12 Jul 86 07:52:21 PDT From: franz!fizzy!jkf@kim.berkeley.edu Received: from fizzy by franz (5.5/3.14) id AA21491; Sat, 12 Jul 86 07:45:53 PDT Received: by fizzy (4.12/3.14) id AA06716; Sat, 12 Jul 86 07:45:31 pdt Return-Path: Message-Id: <8607121445.AA06716@fizzy> To: David C. Plummer Cc: common-lisp@su-ai.arpa Subject: Re: GC, exit-to-system In-Reply-To: Your message of Sat, 12 Jul 86 08:07:00 EDT. <860712080715.8.DCP@FIREBIRD.SCRC.Symbolics.COM> Date: Sat, 12 Jul 86 07:45:28 PDT On a machine which does real-time garbage collection, a definition such as (defun gc () nil) would be sufficient. If you want to give people control over the various other types of gc that the lisp machine can do, then write different functions. Many people (I'd say 'most' but I don't have the figures at hand to back it up) use Lisp on stock hardware where a garbage collection does indeed stop computation for a noticeable period of time. It is for these systems that the 'gc' function exists. The gc function is merely a suggestion to the lisp system, if it can't do a gc, it can ignore the suggestion. -------- This whole discussion is an example of a bigger issue: there need to be sub-standards for various subsets of the community. For example, many (again, perhaps 'most') Lisp users run under the Unix operating system. Our users want hooks to the unique features of Unix. While there is a framework for declaring (proclaming?) standards, there should be a effort made to provide standards for communities of users. -john foderaro Franz Inc.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 12 Jul 86 13:03:07 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 12 Jul 86 05:33:26 PDT Received: ID ; Sat 12 Jul 86 08:33:53-EDT Date: Sat 12 Jul 86 08:33:52-EDT From: vijay Subject: KCl vs KCN To: common-lisp@SU-AI.ARPA Message-ID: <12222076950.27.SARASWAT@C.CS.CMU.EDU> Avoid KCN like the plague. KCl is a salt but KCN kills!! :-) -------  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 12 Jul 86 13:02:59 EDT Received: from SCRC-QUABBIN.ARPA by SU-AI.ARPA with TCP; 12 Jul 86 05:07:53 PDT Received: from FIREBIRD.SCRC.Symbolics.COM by QUABBIN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 18798; Sat 12-Jul-86 08:06:39 EDT Date: Sat, 12 Jul 86 08:07 EDT From: David C. Plummer Subject: Re: GC, exit-to-system To: franz!fizzy!jkf@kim.berkeley.edu cc: David A. Moon , common-lisp@SU-AI.ARPA In-Reply-To: <8607110525.AA04054@fizzy> Message-ID: <860712080715.8.DCP@FIREBIRD.SCRC.Symbolics.COM> Date: Thu, 10 Jul 86 22:25:30 PDT From: franz!fizzy!jkf@kim.berkeley.edu >> From: David Moon >> ... >> The concept of calling the GC at a particular >> time is not meaningful either; the GC runs in parallel with normal >> computation. I'm sure there are other implementations with different >> ideas about these concepts. They just don't make very much sense to >> standardize, because there is so much variation. I think that you may have missed the point. There are certain functions performed by many (but perhaps not all) of the implementations of common lisp. Such functions include stopping a computation and performing a garbage collection, You missed a subtle point. The LispM systems normal GC stop a computation only long enough to start the GC. The computation is not stopped for the performance of the garbage collection. There are a lot of different levels of GC in our system, perhaps more so than in most. In theory, you could call (si:gc-flip-now) to cause a GC to be started, or (si:gc-immediately) which not only starts it, but the code executing it doesn't return until the GC completes, BUT, other processes are still allowed to run. (si:full-gc) stops everybody while it does a massive amount of work. What about the user interface issues of trying to start a GC when the system is pretty sure you will run out of room (assuming a copying garbage collector)? Which of the above functions do you want in the language? Maybe figure out how to write one function that is completely overloaded? What if you ask a GC to be started but a GC is already in progress? Do you want options to say "that's OK, don't do another" and "wait for the current one and then start a new one"? What about ways to flip ephemeral spaces in systems that have ephemeral GCs as opposed to flipping dynamic spaces? I think you want the ability to do both. What about controlling different forms of ephemeral migration? I know of at least four possibilities: (1, normal) next level, (2, dynamic) always to non-ephemeral, (3, keep) lowest ephemeral level flips and is copied back into the lowest ephemeral level, (4, collect) lowest ephemeral level doesn't flip, so things tend to collect at the bottom. What about flipping a subset of "areas" for systems where that is meaningful. and exiting to the operating system. It would be a good thing if the names for these functions were the same across all common lisps where such functionality exists. Which functions? I've listed anywhere from 5 to 50 possibilities.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 12 Jul 86 00:50:46 EDT Received: from CSNET-RELAY.ARPA by SU-AI.ARPA with TCP; 11 Jul 86 21:42:01 PDT Received: from utokyo-relay by csnet-relay.csnet id al24876; 12 Jul 86 0:39 EDT Received: by u-tokyo.junet (4.12/4.9J-1[JUNET-CSNET]) id AA14429; Sat, 12 Jul 86 13:23:45+0900 From: yuasa%kurims.kurims.kyoto-u.junet%utokyo-relay.csnet@CSNET-RELAY.ARPA Received: by nttlab.ntt.junet (4.12/5.0) with TCP; Sat, 12 Jul 86 12:48:05 jst Received: by kurims.kurims.kyoto-u.junet (2.0/6.1Junet) id AA01353; Fri, 11 Jul 86 20:48:02+0900 Date: Fri, 11 Jul 86 20:48:02+0900 Message-Id: <8607111148.AA01353@kurims.kurims.kyoto-u.junet> To: MICHAEL%CS.COLUMBIA.EDU%u-tokyo.junet@CSNET-RELAY.ARPA Subject: A minimal Common Lisp interpreter. Cc: common-lisp%su-ai.arpa%u-tokyo.junet@CSNET-RELAY.ARPA This is the information from Kyoto Common Lisp. KCL is an acronym of Kyoto Common Lisp, but it is also the name of the full-set version of Kyoto Common Lisp. We also have a subset version of KCL, called KCN. KCN differs from KCL in that it does not contain the compiler nor the online documentations. In other respect, KCN is same as KCL. Its size is 1.26 Mbytes, excluding the user heap but including the system data. Many functions are written in Common Lisp, though it is not clear how large is the total size of these functions. The size of KCN is reduced about 5% on VAX. -- Taiichi  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 11 Jul 86 23:51:18 EDT Received: from AI.AI.MIT.EDU by SU-AI.ARPA with TCP; 11 Jul 86 20:42:00 PDT Date: Fri, 11 Jul 86 23:10:34 EDT From: Jonathan A Rees Subject: DECLARE SPECIAL Considered Confusing To: Pavel.pa@XEROX.COM cc: Common-Lisp@SU-AI.ARPA In-reply-to: Msg of 11 Jul 86 18:43 PDT from Pavel.pa at Xerox.COM Message-ID: <[AI.AI.MIT.EDU].68800.860711.JAR> Excellent. This is the closest thing I've seen yet to the right thing, given CL's political and compatibility constraints. Jonathan  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 11 Jul 86 23:35:22 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 11 Jul 86 20:19:40 PDT Received: ID ; Fri 11 Jul 86 23:19:50-EDT Date: Fri, 11 Jul 1986 23:19 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Pavel.pa@XEROX.COM Cc: Common-Lisp@SU-AI.ARPA Subject: DECLARE SPECIAL Considered Confusing In-reply-to: Msg of 11 Jul 1986 21:43-EDT from Pavel.pa at Xerox.COM Thanks for working out a coherent proposal for your proposed changes to the special declaration scoping rules. My feeling on this is that any change to the scoping rules is a very big change: such a change requires a lot of work to fix up existing implementations, and it has the potential to create a lot of subtle bugs in existing user code. Maybe in this case it is not quite so serious, since several implementations are currently incorrect, but still it is a big alteration in an area that was discussed and settled long ago. A change of this size should only be made if one of the following conditions holds: 1. The current situation is inconsistent and untenable. 2. The current situation causes serious trouble in practice for implementors or code writers. 3. We have nearly unanimous agreement that the new way is enough better that it is worth the trouble to make the change. I don't see any evidence for 1 or 2, and as of now I don't hear the kind of enthusiasm for this change that 3 would require. Then again, I haven't heard any implementors say they absolutely oppose this change. -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 11 Jul 86 22:02:42 EDT Received: from XEROX.COM by SU-AI.ARPA with TCP; 11 Jul 86 18:43:23 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 11 JUL 86 18:43:39 PDT Date: 11 Jul 86 18:43 PDT From: Pavel.pa@Xerox.COM Subject: Re: DECLARE SPECIAL Considered Confusing In-reply-to: David A. Moon 's message of Mon, 7 Jul 86 23:13 EDT To: Moon@STONY-BROOK.SCRC.Symbolics.COM cc: Common-Lisp@SU-AI.ARPA Message-ID: <860711-184339-1110@Xerox> In this message I will give a complete description of my proposal for declaration scoping. I won't attempt to argue for it on the basis of ``obviousness'' or clarity, though, because I think that there are people who find each of the two ways of scoping special declarations confusing. Rather, I like this way of doing things because it satisfies an important (to me) consistency criterion: the scope of \any/ declaration coincides with a particular lexical identifier scope. There are six primitive forms in Common Lisp that can both bind identifiers and carry declarations: LET LET* FLET LABELS MACROLET LAMBDA I will describe the scoping rules for declarations in each of these forms. LET The scope of the declarations within a LET is precisely the scope of the variables being bound. That is, any declarations within a LET affect all of the bindings themselves and all forms appearing within the scope of those bindings. Because the various initial-value expressions for the bindings are not evaluated within the scope of those bindings, neither are the declarations in effect over those expressions. Thus, in the form below, (let (( ) ... ( )) ) the given affect the bindings of through and the , but not through . LET* The LET* special form is most easily understood as a series of nested LET's. The question is, how are the declarations to be distributed among those various nested scopes? The answer is to leave almost all of the declarations in the innermost LET and to distribute to each of the other scopes only those declarations that could apply to the variable being bound there. Thus, the following LET*: (let* ((a ) (b ) (c )) (declare (special a b c) (inline foo) (optimize (speed 3)) (type (integer 0 *) b)) ) is equivalent to this set of nested LET's: (let ((a )) (declare (special a)) (let ((b )) (declare (special b) (type (integer 0 *) b)) (let ((c )) (declare (special c) (inline foo) (optimize (speed 3)) ))) FLET This is simply a syntactically pleasing way to lexically bind functions to identifiers appearing in functional position. Thus, we should think of the following FLET: (flet (( () ) ... ( () )) ) as this LET: (let (( #'(lambda () )) ... ( #'(lambda () ))) ) except that the are bound as function identifiers instead of as variables. The scope of the declarations thus includes the but none of the or . LABELS This is a version of FLET that differs only in the scope of the bindings of the names for the functions. Thus, the scope of the declarations should be the same as in FLET except for those applicable to the bindings themselves, which should cover the entire construct. MACROLET The scoping here is precisely as in FLET, covering the bindings of the macros (whatever that might mean) and the body of the form, but not the bodies of the macros themselves. LAMBDA The scope of the first required parameter in a LAMBDA covers all other bindings and code within the LAMBDA form. The declarations have the very same scope, covering all executable code within the form. (In the case where no required parameters exist, the declarations still cover the whole form, the scope of a new, imaginary, required parameter. ========== I believe that this proposal is consistent and relatively easy to reconstruct from the simple principle that the scope of a declaration is always the lexical scope of some identifier. Thoughts? Pavel  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 11 Jul 86 21:33:18 EDT Received: from [192.10.41.41] by SU-AI.ARPA with TCP; 11 Jul 86 18:22:10 PDT Received: from OWL.SCRC.Symbolics.COM by ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 40064; Fri 11-Jul-86 21:23:14 EDT Date: Fri, 11 Jul 86 21:21 EDT From: David A. Moon Subject: GC, exit-to-system To: Scott E. Fahlman cc: masinter.PA@XEROX.COM, common-lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860711212151.7.MOON@OWL.SCRC.Symbolics.COM> (defun bye () (si:halt "Shutdown yes ")) I think I had better not install this, though. It powers off the machine.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 11 Jul 86 19:20:35 EDT Received: from [192.10.41.41] by SU-AI.ARPA with TCP; 11 Jul 86 16:00:59 PDT Received: from CHICOPEE.SCRC.Symbolics.COM by ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 39569; Fri 11-Jul-86 10:13:13 EDT Date: Fri, 11 Jul 86 10:19 EDT From: Daniel L. Weinreb Subject: functionp To: Masinter.pa@XEROX.ARPA, common-lisp@SU-AI.ARPA In-Reply-To: <860710-170522-1643@Xerox> Message-ID: <860711101909.1.DLW@CHICOPEE.SCRC.Symbolics.COM> Date: 10 Jul 86 17:05 PDT From: Masinter.pa@Xerox.COM I've been staring at the spec, and I can't see what would prevent a legitimate implementation from defining functionp from universally returning T. "functionp is true if its argument is suitable for applying to arguments". Now, If in some implementation (functionp 3) returned T, I would not call that legitimate. (lambda (1 2 &nosuchkey) ...) isn't suitable for applying to arguments in the sense that funcall is guaranteed not to complain about it. It all depends on what you mean by "suitable for applying to arguments", which is admittedly a pretty vague phrase. How about a compiled code object in which there was a compiler bug that caused the argument-taking instructions to not be compiled quite right? What about (defun foo (&optional (x (/ 1 0))) x), which will signal an error during the argument-passing process if x is not provided? I'm wondering if anyone has any portable code where "functionp" has any meaningful uses? The Symbolics software environment uses it in about 35 places. I just looked at a few. In several cases, it's being used to provide error checking, so that the user will get an error message that says "hey, that should have been a function, but isn't" as early as possible, rather than finding out much later when it's harder to debug. In cases like the one you present, the user will just find out later, when it's harder to debug, but at least the functionp will accomplish its purpose for the vast majority of cases. In some of the other usages, it's part of what amounts to a user interface in a software tool, or a facility that does one thing when given a "function" and another when given a number, or something like that. These uses can indeed be somewhat heuristic, in that ambiguous cases are constructable, but in practice this does not seem to be a big problem.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 11 Jul 86 19:20:29 EDT Received: from [192.10.41.41] by SU-AI.ARPA with TCP; 11 Jul 86 16:00:53 PDT Received: from CHICOPEE.SCRC.Symbolics.COM by ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 39571; Fri 11-Jul-86 10:21:14 EDT Date: Fri, 11 Jul 86 10:27 EDT From: Daniel L. Weinreb Subject: portable code walkers vs. portable code To: LOOSEMORE@UTAH-20.ARPA, common-lisp@SU-AI.ARPA In-Reply-To: <12221663681.27.LOOSEMORE@UTAH-20.ARPA> Message-ID: <860711102726.2.DLW@CHICOPEE.SCRC.Symbolics.COM> Date: Thu 10 Jul 86 16:43:43-MDT From: SANDRA My contention is that it should be possible to write a portable program to "walk" *any* valid Common Lisp program. After all, this was the rationale for prohibiting implementations from defining their own additional special forms, right? If you allow implementations to extend the syntax of lambda lists, you might as well let implementations extend the syntax by introducing more special forms, and let users define their own special forms too. And once we do that, we might as well forget about having a standard Lisp dialect in the first place. The issue hinges on what the phrase "valid Common Lisp program" means. The intention of the manual is that any implementation may put in various extensions, but a valid Common Lisp program does not use any such extensions. Regarding code walkers, there was an attempt made to allow code walkers to work not only on valid Common Lisp programs, but even on programs that go outside the bounds of Common Lisp. This attempt is the reason for the magic list of special forms, and that idea that any new special form should have a translator, etc. As has been discussed in this mailing list previous, it's not at all clear that this attempt works, or can possibly work. You are correct in pointing out that the attempt certainly cannot work if implementations have extra lambda-list keywords. However, I think that we had already established that the attempt could not work, anyway, for other reasons. Your final contention is not true. If we let implementations put in their own special forms, that does not in any way prevent us from having a common subset that is shared among all these implementations. That is what Common Lisp is, and that's why it's called Common Lisp. It does mean that you can't write a portable code-walker capable of understanding any program in any extended dialect that contains Common Lisp as a subset, which doesn't seem very surprising. You can still write a code walker that's fully portable and can be guaranteed to work on any valid Common Lisp program, which means any program written completely within the common subset.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 11 Jul 86 18:55:21 EDT Received: from XEROX.COM by SU-AI.ARPA with TCP; 11 Jul 86 15:46:07 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 11 JUL 86 15:46:22 PDT Date: 11 Jul 86 15:46 PDT From: Masinter.pa@Xerox.COM Subject: Re: portable code walkers In-reply-to: Liz Allen 's message of Fri, 11 Jul 86 13:39:03 -0500 To: liz@brillig.umd.edu cc: common-lisp@su-ai.arpa Message-ID: <860711-154622-2562@Xerox> There's a portable code-walker which is part of Portable CommonLoops which does just what you want. The entry point is (walk-form form &key walk-function declarations lexical-variables environment lexical-variables) The walk-function is like your optional function but it can return a second value that says whether or not to re-walk; the other keywords are if you want to pass in some of the other information that the walker keeps track of. The code & documentation for it is part of the Portable CommonLoops release. ("Copyright (c) 1985 Xerox Corporation. All rights reserved. Use and copying of this software and preparation of derivative works based upon this software are permitted. ...") I have portable implementations of macrolet, flet, labels, and compiler-let using the portable code-walker, e.g. (defmacro compiler-let (vars &rest forms &environment env) (eval `(special-let ,vars (walk-form `(progn ,@forms) :environment env)))) where special-let is a macro that expands to a let with all of the variables declared special. This says to expand all of the macros in forms while the variables are bound.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 11 Jul 86 14:17:31 EDT Received: from UTAH-20.ARPA by SU-AI.ARPA with TCP; 11 Jul 86 10:57:03 PDT Date: Fri 11 Jul 86 11:54:52-MDT From: SANDRA Subject: Re: portable code walkers vs. portable code To: gls@ZARATHUSTRA.THINK.COM cc: common-lisp@SU-AI.ARPA In-Reply-To: <860711123622.2.GLS@BOTOLPH.THINK.COM> Message-ID: <12221873242.30.LOOSEMORE@UTAH-20.ARPA> Bleah.... Defining new evaluable objects opens up a whole can of worms that I don't even want to *think* about. (I would personally be happier if things like vectors that are subtypes of common were defined to be self-evaluating objects, and leave implementation-specific datatypes to have implementaton-specific meanings....) Fortunately CLtL is fairly concise about defining what forms are valid in all implementations, so a code walker could indeed detect this kind of non-standard usage. Likewise, a code walker could detect when you reference a non-standard lambda keyword (but probably not detect non-standard syntax for supplying defaults or whatever in the lambda list). The thing that really bothers me, though, is the possibility that a ((portable code) walker) could fail to process a piece of portable code because the implementation saw fit to expand a standard macro into something that contains references to implementation-specific syntax extensions, such as new special forms, nonstandard forms, and strange lambda list syntax. As the manual stands now (p 58), it at least *mentions* that implementors should avoid the first two, but doesn't say anything about avoiding lambda list syntax extensions in this situation. I'm all for making the warning a bit stronger and prohibiting all three cases. -Sandra -------  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 11 Jul 86 13:53:16 EDT Received: from BRILLIG.UMD.EDU by SU-AI.ARPA with TCP; 11 Jul 86 10:38:19 PDT Received: by brillig.umd.edu (5.9/4.7) id AA08321; Fri, 11 Jul 86 13:39:04 EDT Message-Id: <8607111739.AA08321@brillig.umd.edu> To: common-lisp@su-ai.arpa Subject: portable code walkers Date: Fri, 11 Jul 86 13:39:03 -0500 From: Liz Allen We did code walking in a simple way for our flavors implementation in Franz using their macroexpand function. The Franz macroexpand expands more than just the top level form; it finds all subforms that will be evaluated and expands any macros found there as well -- basically, it does a code walk. We had to fix it (since it didn't know about all the special forms in Franz). We then modified it so it takes an optional argument that is a function. That function is applied to every subform that will be eval'd after it has been completely macroexpanded. The value returned by that function is used in place of the form. I would like to propose something similar here: --------------- CODE-WALK form &optional function [ function ] For the form given, this expands all the macros at the top level, determines which subforms will be eval'd and calls itself recursively on those subforms consing up the equivalent form from the values given. If the optional function is given, after all the subforms are expanded (in each recursive call), the function is called and passed the new form and substitutes the value returned for that form. For example, given: (defun hack-ivar-refs (form) (cond ((ivarp form) `(get-ivar ,form self)) ((and (listp form) (eq (car form) 'setq) (ivarp (cadr form))) ;; being lazy -- assuming only 2 args to setq `(set-ivar ,(cadr form) self ,(caddr form))) (t form))) a call like (code-walk form #'hack-ivar-refs) will find all the references to the instance variables that need to be found and replaced by the appropriate calls to get and set their values. ----- This took care of what we needed to do for our flavors implementation quite nicely. I'm not sure if there are code walking situations that would require greater functionality... It is possible that someone would like to have hooks to look at the forms before they are macroexpanded or perhaps even after each macro is expanded; both of those two things could be handled easily. Comments? -Liz  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 11 Jul 86 13:15:28 EDT Received: from CSNET-RELAY.ARPA by SU-AI.ARPA with TCP; 11 Jul 86 09:59:18 PDT Received: from utokyo-relay by csnet-relay.csnet id ah19462; 11 Jul 86 12:41 EDT Received: by u-tokyo.junet (4.12/4.9J-1[JUNET-CSNET]) id AA29922; Fri, 11 Jul 86 15:32:59+0900 Received: by ccut.u-tokyo.junet (4.12/6.1Junet) id AA27740; Fri, 11 Jul 86 15:18:28+0900 Date: Fri, 11 Jul 86 15:18:28+0900 From: Masayuki Ida Message-Id: <8607110618.AA27740@ccut.u-tokyo.junet> To: common-lisp@SU-AI.ARPA Subject: Re: GC, exit-to-system >Date: Thu, 10 Jul 1986 22:28 EDT >Message-Id: >From: "Scott E. Fahlman" >To: "David A. Moon" >Cc: common-lisp@SU-AI.ARPA >Subject: GC, exit-to-system >In-Reply-To: Msg of 10 Jul 1986 20:56-EDT from David A. Moon >Received: from CSNet-Relay by utokyo-relay; 11 Jul 86 13:34:26-JST (Fri) >Status: R > > >I've been thinking about the GC issue since it first came up. Even >though systems differ tremendously in what GC means to them, it might >make sense to provide a portable GC construct for use in portable code. >This would say that IF the implementation ever needs to do a time >consuming GC operation, this is the time to do it; if that doesn't make >sense in a given implementation, this would be a no-op. This would be >used in portable code that runs benchmarks, for example, to start the >system in as fresh a state as possible. It might also be used when a >program wants to initiate some short real-time operation that should not >be interrupted for GC once it has started. It's not useful for >everyone, but is useful in many systems and does not harm the rest. > Yes! this is just the story we are talking. >I am somewhat more doubtful about the usefulness of BYE in any sort of >portable code. One could argue that it would give users a standard way >of getting out of Lisp on any system where that makes sense, and that it >always is best to have recognizable signs on the emergency exits. > I also think BYE is not so useful in portable codes. BYE came from the discussion on a tutorial for the novices. It may be useful for the general training cource without Lisp machine. If we teach a new subsystem under a operating system in my university, at least I, first, teach how to enter the subsystem and teach how to exit from it with no other operations. After that, I will start the main menu. >-- Scott > > ida  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 11 Jul 86 12:51:47 EDT Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 11 Jul 86 09:35:31 PDT Received: from botolph by Godot.Think.COM via CHAOS; Fri, 11 Jul 86 12:35:29 edt Date: Fri, 11 Jul 86 12:36 EDT From: Guy Steele Subject: portable code walkers vs. portable code To: LOOSEMORE@UTAH-20.ARPA, common-lisp@SU-AI.ARPA Cc: gls@AQUINAS In-Reply-To: <12221663681.27.LOOSEMORE@UTAH-20.ARPA> Message-Id: <860711123622.2.GLS@BOTOLPH.THINK.COM> Date: Thu 10 Jul 86 16:43:43-MDT From: SANDRA ... As an example of the kind of code walker I had in mind, consider a simple cross reference utility, something that traverses a function and keeps track of what other functions it calls. (Perhaps the purpose of the utility is to locate references to implementation-specific functions.) As long as I know exactly where evaluable code can or can't validly appear, I can certainly write this utility in a portable manner, regardless of whether the bits of code it analyzes are portable or not. However, if every implementation is free to extend the syntax of the language however it wants, it would be impossible to write a portable program that checks for portable usage! That is correct. But observe that an implementation is free to add new data types, and is free to make those data types mean something to the evaluator (see CLtL, pp. 54-55). For example, I might extend my Common Lisp to evaluate a vector by evaluating its elements in parallel and returning the value of just one of them (implemented by choosing the value of whichever one finishes first). I might introduce a new data type called a mote that is written as an Internet host number, an underscore, and a digit sequence (swiping some of the namespace for potential numbers). A mote can serve as an identifier, much like a symbol, but is shared among all processes on the network and resides in the specified host. I can let another host know when I am running ZORK by writing (defun zork () (let ((192.5.100.2_569 t)) ;bind mote 569 in host 192.5.100.2 ... )) Indeed, a (portable (code walker)) cannot hope to deal with such extensions. The intent of LAMBDA-LIST-KEYWORDS was simply to give a code walker a fighting chance at deciding whether or not something screwy was going on, and if so, how screwy it could be. --Guy  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 11 Jul 86 12:11:01 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 11 Jul 86 08:58:47 PDT Received: ID ; Fri 11 Jul 86 11:28:23-EDT Date: Fri, 11 Jul 1986 11:27 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: masinter.PA@XEROX.COM Cc: common-lisp@SU-AI.ARPA Subject: GC, exit-to-system I agree that many of these functions (BYE, ROOM, ED) are more for portable programmers than for portable programs. That doesn't mean that they are a bad thing; it just means that we have to carefully indicate what they are and are not required to do and what happens on systems where they make no sense. It's nice to be able to go up to a strange Common Lisp and know in general how to do the most important top-level things. GC is perhaps unusual, since it does have some uses in code, as several of us have indicated. As to your specific proposed changes, I don't like either of them. What's wrong with calling the GC function "GC"? Most Common Lisps already support this, and call it "GC". (Systems could define their own keyword arguments for this to get more subtle system-dependent effects.) As for "BYE", I think that it should be documented as leaving the Lisp altogether, if that makes sense. Bringing in the idea of leaving the current top-level loop complicates things immensely because it interacts with nested break levels and stack groups and all sorts of other non-standard things. -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 11 Jul 86 11:25:45 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 11 Jul 86 08:14:31 PDT Received: ID ; Fri 11 Jul 86 11:14:43-EDT Date: Fri, 11 Jul 1986 11:14 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: common-lisp@SU-AI.ARPA Subject: compiler-let In reply to: Niels Lauritzen Now I propose another form to round out the "binding" family MACROEXPAND-FLET. Use it to define functions that are only used during the dynamic extent of macroexpansion. MACROEXPAND-LET* would be icing on the cake because the same effect could be achieved by using a series of nested MACROEXPAND-LETs. MACROEXPAND-MACROLET macroexpand time binding of a macro (dynamic scoping), COMPILER-LET (or MACROEXPAND-LET, if you prefer) is of very marginal benefit, if any. If people feel that such a thing must be fully rounded out for reasons of symmetry, I say we should flush the whole thing. I also feel that it was a major mistake letting MACROLET in, but I've already lost that battle twice and don't plan to fight it again. -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 11 Jul 86 10:36:48 EDT Received: from UTAH-CS.ARPA by SU-AI.ARPA with TCP; 11 Jul 86 07:27:32 PDT Received: by utah-cs.ARPA (5.31/4.40.2) id AA07922; Fri, 11 Jul 86 08:24:01 MDT Received: by utah-orion.ARPA (5.31/4.40.2) id AA01909; Fri, 11 Jul 86 08:23:57 MDT Date: Fri, 11 Jul 86 08:23:57 MDT From: shebs%utah-orion@utah-cs.arpa (Stanley Shebs) Message-Id: <8607111423.AA01909@utah-orion.ARPA> Newsgroups: fa.common-lisp Subject: Re: GC, exit-to-system Summary: Expires: References: Sender: Reply-To: shebs@utah-orion.UUCP (Stanley Shebs) Followup-To: Distribution: Organization: University of Utah CS Dept Keywords: Apparently-To: common-lisp@su-ai.arpa In article Fahlman@C.CS.CMU.EDU (Scott E. Fahlman) writes: > >I've been thinking about the GC issue since it first came up. Even >though systems differ tremendously in what GC means to them, it might >make sense to provide a portable GC construct for use in portable code. I agree. Perhaps something more generic like CLEAN-STATE would be appropriate - it could do whatever "freshening up" might be appropriate, such as handling all pending interrupts or rehashing of internal tables or whatever other exotic things implementations might be doing concurrently with computation. >I am somewhat more doubtful about the usefulness of BYE in any sort of >portable code. One could argue that it would give users a standard way >of getting out of Lisp on any system where that makes sense, and that it >always is best to have recognizable signs on the emergency exits. If one were to argue against BYE, then one would also have to flush ED and ROOM and all other things that are required, but whose operation is highly unspecified. Along the same lines, it might make sense to require that an implementation should have a world dumper called SAVE-SYSTEM that takes a filename and puts in the file a copy of the lisp such that when it is restored (by unspecified means) you are in the state just before the SAVE-SYSTEM was done. This is something almost every Lisp provides, but with wildly varying details. It would of course be OK to have lots of extra keywords on such a function, but a portable implementation of an embedded language can just supply the filename to SAVE-SYSTEM and expect it to work almost everywhere. stan  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 11 Jul 86 10:24:15 EDT Received: from DECWRL.DEC.COM by SU-AI.ARPA with TCP; 11 Jul 86 07:15:45 PDT Received: from DEC-RHEA.ARPA (dec-rhea) by decwrl.DEC.COM (4.22.05/4.7.34) id AA10020; Fri, 11 Jul 86 07:17:10 pdt Message-Id: <8607111417.AA10020@decwrl.DEC.COM> Date: Friday, 11 Jul 1986 07:16:04-PDT From: greek%bach.DEC@decwrl.DEC.COM (What have I done?) To: common-lisp@su-ai, rich%bach.DEC@decwrl.DEC.COM Subject: Our MUFCSPC entry. We think the following pretty-printer for DO is pretty cute. Of course, one could say that we have an unfair perspicuity advantage since we've extended FORMAT to do pretty-printing. (define-list-print-function do (list stream) (format stream "~1!~W~^ ~:I~@_~/sys::bind-list/~^ ~_~ ~1!~^~W~^ ~_~W~^~@{~%~W~^~}~.~ ~1I~@{~^~%~W~}~." list)) Just in case you're wondering what the ~/SYS::BIND-LIST/ directive is: (define-format-directive sys::bind-list (list stream colon-p atsign-p) (declare (ignore atsign-p colon-p)) (format stream "~1!~@{~1!~W~^ ~:I~@_~@{~W~^ ~:_~}~.~^ ~%~}~." list)) Special thanks to Dick Waters. - Paul & Rich  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 11 Jul 86 10:01:36 EDT Received: from MIT-EMS.ARPA by SU-AI.ARPA with TCP; 11 Jul 86 06:51:49 PDT Received: by mit-ems.ARPA (4.12/4.8) id AA04885; Fri, 11 Jul 86 09:49:58 edt Date: Fri, 11 Jul 86 09:49:58 edt From: Steven Haflich Message-Id: <8607111349.AA04885@mit-ems.ARPA> To: LOOSEMORE@UTAH-20.ARPA, common-lisp@SU-AI.ARPA Subject: Re: portable code walkers vs. portable code > From: SANDRA > My contention is that it should be possible to write a portable program to > "walk" *any* valid Common Lisp program. Agreed. > But an implementation that includes syntactic extensions should not call > itself "Common Lisp". An *implementation* can provide anything it likes. Provided it is provably upward compatible with "Common Lisp", it is a valid Common Lisp. However, any *program* which uses these extensions cannot correctly be called a "Common Lisp program". A portable Common Lisp code walker will work only for Common Lisp code. This distinction is important if we are ever to nail down what is a legitimate Common Lisp and what isn't. > After all, this was the rationale for prohibiting implementations from > defining their own additional special forms, right? If you allow > implementations to extend the syntax of lambda lists, you might as well > let implementations extend the syntax by introducing more special > forms, and let users define their own special forms too. Implementations are free to provide additional special forms provided they also make available macro equivalents. Additional special forms are no problem for code walkers. (Provided the macro equivalents really are functionally [sic] equivalent...) Your argument is still a good one, that extending the syntax of lisp forms makes impossible portable code analysis tools. This should not be done lightly, but it doesn't invalidate a Common Lisp.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 11 Jul 86 05:53:13 EDT Received: from MIT-GOLDILOCKS.ARPA by SU-AI.ARPA with TCP; 11 Jul 86 02:40:49 PDT Received: from KOALA.MIT.EDU by MIT-GOLDILOCKS.ARPA via CHAOS with CHAOS-MAIL id 2813; Fri 11-Jul-86 05:41:15-EDT Date: Fri, 11 Jul 86 05:41 EDT From: Niels Lauritzen Subject: compiler-let To: common-lisp@SU-AI.ARPA, SR.LAURITZEN@SPEECH.MIT.EDU Message-ID: <860711054113.2.LAURITZEN@KOALA.MIT.EDU> If you object to the reference to compilers in COMPILER-LET how about naming it... MACROEXPAND-LET since both the interpreter and the compiler have a macroexpansion phase and these bindings may affect macroexpansion. (not to be confused with MACROLET) or (not so good) EARLY-LET because it binds before evaluation time in both the interpreter and the compiler. I certainly don't think that we should do away with the functionality of MACROLET and COMPILER-LET. They both are useful for hacking fancy macroexpansion environments. Now I propose another form to round out the "binding" family MACROEXPAND-FLET. Use it to define functions that are only used during the dynamic extent of macroexpansion. we have DEFVAR define a global, dynamically scoped variable DEFUN define a global function DEFMACRO define a global macro LET establish a lexically scoped variable, or bind a dynamically scoped variable FLET establish a lexically scoped function (in an intermediate category) MACROLET establish a lexically scoped macro MACROEXPAND-LET (was COMPILER-LET) macroexpand time binding of a variable (dynamic scoping) MACROEXPAND-FLET macroexpand time binding of a function (dynamic scoping) MACROEXPAND-LET* would be icing on the cake because the same effect could be achieved by using a series of nested MACROEXPAND-LETs. It seems to me (pardon me if I'm all wet) that because of the way macroexpansion is done (recursively), we don't need to distinguish between lexical and dynamic scoping of a macro. The environment of definition is always the same as the environment of the caller. So we don't need separate forms for MACROEXPAND-MACROLET macroexpand time binding of a macro (dynamic scoping), because it would be the same as MACROLET, or a lexically-scoped MACROEXPAND-LET or lexically-scoped MACROEXPAND-FLET.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 11 Jul 86 01:59:01 EDT Received: from XEROX.COM by SU-AI.ARPA with TCP; 10 Jul 86 22:47:59 PDT Received: from Salvador.ms by ArpaGateway.ms ; 10 JUL 86 22:46:50 PDT From: masinter.PA@Xerox.COM Date: 10 Jul 86 22:46:19 PDT Subject: Re: GC, exit-to-system In-reply-to: FAHLMAN@C.CS.CMU.EDU's message of Thu, 10 Jul 86 22:28 EDT, To: FAHLMAN@C.CS.CMU.EDU cc: "David A. Moon" , common-lisp@SU-AI.ARPA Message-ID: <860710-224650-1865@Xerox> Instead of "GC", call it "MAKE-ROOM" and put it in the spec next to "ROOM". It can be as wonderfully vague: make-room &optional x [Function] If the lisp system has any activity it can perform which increases the amount of storage available by collecting unused structures, do so now. The nature of this activity is implementation-dependent. (make-room nil) performs a minimal amount of activity. (make-room t) performs a maximal amount of useful activity. Simply (make-room) performs an intermediate amount of collection activity. (see p 442). As far as exit/bye/quit, I'd put it in the section on "The Top-Level Loop" (pp 324-325) bye (or whatever) [Function] The function bye causes the current invocation of whatever "top level read-eval-print loop" is being executed to be terminated. On some systems, this will mean "exit to the operating systems"; on others, it will merely terminate the current process. - - - - - - - - Both of these fit in what might more reasonably be called Common Lisp the Environment rather than Common Lisp the language, but they seem to have as much of a place as the other items that are in the sections I've placed them in. Most of these sections don't really correspond to things that have "semantics" in the traditional sense. They seem most important for portable programmers rather than portable programs.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 11 Jul 86 01:41:35 EDT Received: from KIM.Berkeley.EDU by SU-AI.ARPA with TCP; 10 Jul 86 22:33:21 PDT Received: by kim.Berkeley.EDU (5.53/1.14) id AA20046; Thu, 10 Jul 86 22:33:32 PDT From: franz!fizzy!jkf@kim.berkeley.edu Received: from fizzy by franz (5.5/3.14) id AA17044; Thu, 10 Jul 86 22:25:52 PDT Received: by fizzy (4.12/3.14) id AA04054; Thu, 10 Jul 86 22:25:33 pdt Return-Path: Message-Id: <8607110525.AA04054@fizzy> To: David A. Moon Cc: common-lisp@su-ai.arpa Subject: Re: GC, exit-to-system In-Reply-To: Your message of Thu, 10 Jul 86 20:56:00 EDT. <860710205605.1.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Thu, 10 Jul 86 22:25:30 PDT >> From: David Moon >> ... >> The concept of calling the GC at a particular >> time is not meaningful either; the GC runs in parallel with normal >> computation. I'm sure there are other implementations with different >> ideas about these concepts. They just don't make very much sense to >> standardize, because there is so much variation. I think that you may have missed the point. There are certain functions performed by many (but perhaps not all) of the implementations of common lisp. Such functions include stopping a computation and performing a garbage collection, and exiting to the operating system. It would be a good thing if the names for these functions were the same across all common lisps where such functionality exists. - john foderaro Franz Inc.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 11 Jul 86 01:10:51 EDT Received: from AMES-NAS.ARPA by SU-AI.ARPA with TCP; 10 Jul 86 22:01:46 PDT Message-Id: <8607101909.AA09830@ames-nas.ARPA> Received: from localhost by ames-nas.ARPA; Thu, 10 Jul 86 12:09:23 pdt To: common-lisp@su-ai.ARPA Subject: please add me Date: 10 Jul 86 12:09:19 PDT (Thu) From: raible@AMES-NAS.ARPA just onother brain-damaged request... raible@ames-nas ----------  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 10 Jul 86 22:38:02 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 10 Jul 86 19:28:16 PDT Received: ID ; Thu 10 Jul 86 22:28:11-EDT Date: Thu, 10 Jul 1986 22:28 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: "David A. Moon" Cc: common-lisp@SU-AI.ARPA Subject: GC, exit-to-system In-reply-to: Msg of 10 Jul 1986 20:56-EDT from David A. Moon I've been thinking about the GC issue since it first came up. Even though systems differ tremendously in what GC means to them, it might make sense to provide a portable GC construct for use in portable code. This would say that IF the implementation ever needs to do a time consuming GC operation, this is the time to do it; if that doesn't make sense in a given implementation, this would be a no-op. This would be used in portable code that runs benchmarks, for example, to start the system in as fresh a state as possible. It might also be used when a program wants to initiate some short real-time operation that should not be interrupted for GC once it has started. It's not useful for everyone, but is useful in many systems and does not harm the rest. I am somewhat more doubtful about the usefulness of BYE in any sort of portable code. One could argue that it would give users a standard way of getting out of Lisp on any system where that makes sense, and that it always is best to have recognizable signs on the emergency exits. -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 10 Jul 86 21:15:27 EDT Received: from [192.10.41.41] by SU-AI.ARPA with TCP; 10 Jul 86 18:03:51 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 39431; Thu 10-Jul-86 20:55:58 EDT Date: Thu, 10 Jul 86 20:56 EDT From: David A. Moon Subject: GC, exit-to-system To: Masayuki Ida cc: common-lisp@SU-AI.ARPA In-Reply-To: <8607100754.AA08957@ccut.u-tokyo.junet> Message-ID: <860710205605.1.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Thu, 10 Jul 86 16:54:22+0900 From: Masayuki Ida In the discussion of our committee, we wondered why the names of the functions for gc, and exit to system are NOT defined in CL. I am only thinking of the interface naming, not the contents, like editor interface is defined in CL but the editor subsystem is not defined yet. I think the unified name for them can be defined in CL. like, GC &optional parameters [function] and BYE [function] To give you an example of how much different systems can vary, neither of these interfaces exist in the Symbolics system. The concept of exiting to the "system" is not meaningful on Symbolics machines; you're always in the "system". The concept of calling the GC at a particular time is not meaningful either; the GC runs in parallel with normal computation. I'm sure there are other implementations with different ideas about these concepts. They just don't make very much sense to standardize, because there is so much variation.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 10 Jul 86 20:54:11 EDT Received: from XEROX.COM by SU-AI.ARPA with TCP; 10 Jul 86 17:47:16 PDT Received: from Concord.ms by ArpaGateway.ms ; 10 JUL 86 17:46:12 PDT Sender: "James_W._Rich.DlosLV"@Xerox.COM Date: 10 Jul 86 17:46:01 PDT (Thursday) Subject: Re: Editorial Comment From: berman@vaxa.isi.EDU To: jwr.DlosLV@Xerox.COM cc: common-lisp@SU-AI.Arpa In-Reply-to: Your message of Tue, 8 Jul 1986 21:32 EDT. Message-ID: <860710-174612-1703@Xerox> GVGVGVGVGVGVGVGVGVGVGVGVGVGVGVGVGVGVGVGVGVGVGVGVGV From: berman@vaxa.isi.edu (Richard Berman) To: "Scott E. Fahlman" Cc: common-lisp@SU-AI.ARPA Subject: Re: Editorial Comment In-Reply-To: Your message of Tue, 8 Jul 1986 21:32 EDT. Return-Path: <@SU-AI.ARPA:berman@vaxa.isi.edu> Redistributed: Xerox-Common-Lisp^.x Received: from SU-AI.ARPA by Xerox.COM ; 09 JUL 86 10:57:03 PDT Received: from VAXA.ISI.EDU by SU-AI.ARPA with TCP; 9 Jul 86 10:32:39 PDT Received: by vaxa.isi.edu (4.12/4.7) id AA25842; Wed, 9 Jul 86 10:32:06 pdt Message-Id: <8607091732.AA25842@vaxa.isi.edu> GVGVGVGVGVGVGVGVGVGVGVGVGVGVGVGVGVGVGVGVGVGVGVGVGV Merci.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 10 Jul 86 20:18:27 EDT Received: from XEROX.COM by SU-AI.ARPA with TCP; 10 Jul 86 17:05:15 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 10 JUL 86 17:05:22 PDT Date: 10 Jul 86 17:05 PDT From: Masinter.pa@Xerox.COM Subject: functionp To: common-lisp@su-ai.ARPA Message-ID: <860710-170522-1643@Xerox> I've been staring at the spec, and I can't see what would prevent a legitimate implementation from defining functionp from universally returning T. "functionp is true if its argument is suitable for applying to arguments". Now, (lambda (1 2 &nosuchkey) ...) isn't suitable for applying to arguments in the sense that funcall is guaranteed not to complain about it. I'm wondering if anyone has any portable code where "functionp" has any meaningful uses?  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 10 Jul 86 18:56:59 EDT Received: from UTAH-20.ARPA by SU-AI.ARPA with TCP; 10 Jul 86 15:45:27 PDT Date: Thu 10 Jul 86 16:43:43-MDT From: SANDRA Subject: portable code walkers vs. portable code To: common-lisp@SU-AI.ARPA Message-ID: <12221663681.27.LOOSEMORE@UTAH-20.ARPA> Date: Thu, 10 Jul 86 17:08 EDT From: David C. Plummer What's this talk about portable code walkers. You can't write portable code at all if you use implementation-specific lambda-list keywords, let alone portable code walkers. Date: Thu, 10 Jul 1986 17:35 EDT From: "Scott E. Fahlman" The option to include additional lambda-list keywords may or may not be a good idea, but it certainly is not an issue for someone implementing a portable code walker. Portable code walkers would only work on portable code, and that would not contain any such extensions. I must disagree with this sentiment. Perhaps there is is come confusion between a ((portable code) walker) and a (portable (code walker)). The issue is not whether or not my program-analyzing program uses nonportable lambda-list keywords. It's whether my program-analyzing program has to be able to recognize these beasties in the code it's analyzing. My contention is that it should be possible to write a portable program to "walk" *any* valid Common Lisp program. After all, this was the rationale for prohibiting implementations from defining their own additional special forms, right? If you allow implementations to extend the syntax of lambda lists, you might as well let implementations extend the syntax by introducing more special forms, and let users define their own special forms too. And once we do that, we might as well forget about having a standard Lisp dialect in the first place. As an example of the kind of code walker I had in mind, consider a simple cross reference utility, something that traverses a function and keeps track of what other functions it calls. (Perhaps the purpose of the utility is to locate references to implementation-specific functions.) As long as I know exactly where evaluable code can or can't validly appear, I can certainly write this utility in a portable manner, regardless of whether the bits of code it analyzes are portable or not. However, if every implementation is free to extend the syntax of the language however it wants, it would be impossible to write a portable program that checks for portable usage! In short, I think it is certainly valid for implementations to include implementation-specific functions, variables, and macros, (hopefully not living in the Lisp package), and still call themselves "Common Lisp". But an implementation that includes syntactic extensions should not call itself "Common Lisp". -Sandra -------  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 10 Jul 86 17:50:19 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 10 Jul 86 14:35:46 PDT Received: ID ; Thu 10 Jul 86 17:35:44-EDT Date: Thu, 10 Jul 1986 17:35 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: SANDRA Cc: common-lisp@SU-AI.ARPA Subject: extra lambda list keywords In-reply-to: Msg of 10 Jul 1986 16:18-EDT from SANDRA The option to include additional lambda-list keywords may or may not be a good idea, but it certainly is not an issue for someone implementing a portable code walker. Portable code walkers would only work on portable code, and that would not contain any such extensions. -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 10 Jul 86 17:24:46 EDT Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 10 Jul 86 14:14:17 PDT Received: from FIREBIRD.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 52332; Thu 10-Jul-86 17:08:35 EDT Date: Thu, 10 Jul 86 17:08 EDT From: David C. Plummer Subject: extra lambda list keywords To: SANDRA , common-lisp@SU-AI.ARPA In-Reply-To: <12221637274.15.LOOSEMORE@UTAH-20.ARPA> Message-ID: <860710170819.6.DCP@FIREBIRD.SCRC.Symbolics.COM> Date: Thu 10 Jul 86 14:18:40-MDT From: SANDRA I just noticed the bit on p. 65 of the manual where it says: "Implementations of Common Lisp are free to provide additional lambda-list keywords." Is this *really* useful to any implementation? Although you can supposedly find out about the additional keywords from the lambda-list-keywords constant, allowing implementation-specific crud to appear in lambda lists seems like another good way to frustrate would-be implementors of portable code walkers. In particular, I'm concerned that if implementations try to extend the syntax of what can appear in lambda lists, code walkers would have a very hard time identifying default values and other bits of evaluable code in the lambda list. Not to mention that a routine that tries to parse lambda lists could get very confused if, for example, it found a strange keyword &foo sitting where it expected to find only an &rest or &key. What's this talk about portable code walkers. You can't write portable code at all if you use implementation-specific lambda-list keywords, let alone portable code walkers. Historically, I think LispMs did (some may still) have lambda list keywords &SPECIAL and &LOCAL, whose effects are somewhat obvious by their names. There was also "E, which effectively defined a special form, because the argument was automatically quoted. There was also an &FUNCTIONAL which I think was like "E except that it wasn't quoted as data, it was quoted as a function. For example, this is how it soft of behaved: (defun foo1 ("e bar1 &functional baz1) (list bar1 baz1)) (foo1 car cdr) =more-or-less= (list 'car #'cdr) There was also a &LIST-OF for macros. See some old LispM documentation if you really care. The above may not be completely accurate, but you get the idea. I agree that extending lambda-list keywords should be done carefully and for very good reasons.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 10 Jul 86 16:36:31 EDT Received: from UTAH-20.ARPA by SU-AI.ARPA with TCP; 10 Jul 86 13:20:25 PDT Date: Thu 10 Jul 86 14:18:40-MDT From: SANDRA Subject: extra lambda list keywords To: common-lisp@SU-AI.ARPA Message-ID: <12221637274.15.LOOSEMORE@UTAH-20.ARPA> I just noticed the bit on p. 65 of the manual where it says: "Implementations of Common Lisp are free to provide additional lambda-list keywords." Is this *really* useful to any implementation? Although you can supposedly find out about the additional keywords from the lambda-list-keywords constant, allowing implementation-specific crud to appear in lambda lists seems like another good way to frustrate would-be implementors of portable code walkers. In particular, I'm concerned that if implementations try to extend the syntax of what can appear in lambda lists, code walkers would have a very hard time identifying default values and other bits of evaluable code in the lambda list. Not to mention that a routine that tries to parse lambda lists could get very confused if, for example, it found a strange keyword &foo sitting where it expected to find only an &rest or &key. -Sandra -------  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 10 Jul 86 14:14:21 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 10 Jul 86 10:50:44 PDT Received: ID ; Thu 10 Jul 86 13:50:23-EDT Date: Thu, 10 Jul 1986 13:50 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Michael van Biema Cc: common-lisp@SU-AI.ARPA Subject: A minimal Common Lisp interpreter. In-reply-to: Msg of 10 Jul 1986 11:50-EDT from Michael van Biema Let me hazard a guess that if you implmented only what is required to be present a legal Common Lisp and that if you were willing to give up a LOT of performance for compactness, you could probably pack the code into 256K bytes and perhaps 128K. This does not count any space for user-stuff, however. It assumes that you design a special byte-code with code-density in mind, and that you hand-code an interpreter for this byte-code. Such a system would not be very useful, of course. It would be slower than a less compact interpreter on the same machine by at least a factor of 10, and would be pretty useless without any environment stuff around. For a more reasonable implementation, I think that 1 Mbyte is a good figure to use as the minimum size of a complete Common Lisp and a little bit of space for user code, not counting the compiler or editor. This may be more or less, depending on the machine's instruction set. For those of you who like to point to such numbers as evidence that Common Lisp as a huge, bloated language, remember that 1 Mbyte is now 8 chips (plus a couple more for ECC). -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 10 Jul 86 13:35:00 EDT Received: from seismo.CSS.GOV by SU-AI.ARPA with TCP; 10 Jul 86 09:44:27 PDT Return-Path: Received: from unido.UUCP by seismo.CSS.GOV with UUCP; Thu, 10 Jul 86 12:30:59 EDT Received: by unido.uucp with uucp; Thu, 10 Jul 86 18:00:58 -0200 Received: by uklirb.UUCP (4.12/4.7) id AA04828; Thu, 10 Jul 86 17:38:53 -0100 Date: Thu, 10 Jul 86 17:38:53 -0100 From: unido!uklirb!przy@seismo.CSS.GOV (Gebhard Przyrembel) Message-Id: <8607101638.AA04828@uklirb.UUCP> To: common-lisp@su-ai.arpa Subject: Mailing-list Please, remove me from your mailing-list, because the costs are to expansive. Is there a posibility to send the Commonlisp-Mail to net.lang.lisp in the notes-system??? Thanks in advance, Gebhard /---------------------------------------------------------\ | e-mail: przy@uklirb.UUCP or | | ..!mcvax!unido!uklirb!przy | | Real-Name: Gebhard Przyrembel | | University Kaiserslautern | | Departement of Computer Sciene | | D-6750 Kaiserslautern | | West-Germany | \---------------------------------------------------------/  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 10 Jul 86 12:05:16 EDT Received: from CS.COLUMBIA.EDU by SU-AI.ARPA with TCP; 10 Jul 86 08:53:45 PDT Date: Thu 10 Jul 86 11:50:26-EDT From: Michael van Biema Subject: A minimal Common Lisp interpreter. To: common-lisp@SU-AI.ARPA Message-ID: <12221588445.45.MICHAEL@CS.COLUMBIA.EDU> Does anyone have some measure of how big it would be? Michael -------  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 10 Jul 86 06:39:58 EDT Received: from CSNET-RELAY.ARPA by SU-AI.ARPA with TCP; 10 Jul 86 03:31:12 PDT Received: from utokyo-relay by csnet-relay.csnet id ai05150; 10 Jul 86 6:32 EDT Received: by u-tokyo.junet (4.12/4.9J-1[JUNET-CSNET]) id AA14719; Thu, 10 Jul 86 17:10:52+0900 Received: by ccut.u-tokyo.junet (4.12/6.1Junet) id AA08957; Thu, 10 Jul 86 16:54:22+0900 Date: Thu, 10 Jul 86 16:54:22+0900 From: Masayuki Ida Message-Id: <8607100754.AA08957@ccut.u-tokyo.junet> To: common-lisp@SU-AI.ARPA, ida%u-tokyo.junet@CSNET-RELAY.ARPA Subject: GC, exit-to-system In the discussion of our committee, we wondered why the names of the functions for gc, and exit to system are NOT defined in CL. I am only thinking of the interface naming, not the contents, like editor interface is defined in CL but the editor subsystem is not defined yet. I think the unified name for them can be defined in CL. like, GC &optional parameters [function] and BYE [function] There are lots of names for the function to exit to system. like, (bye) , (exit), (quit), ... As an user and as a teacher, I feel happy if the name is only one for exit-to-system function. The needs to define a unique name is for user convenience. As to GC, it is not defined in CL too. Of cause, there are several ways of GC techniques, and there are several systems which do not have GC. We discussed about the needs to define a unique name for it. We found there are not so much needs, but for writing bench marking software library. If we might wanted to stick defining a name for GC, we might found several situation which need a unique name for GC. Masayuki Ida ----- PS: attached is the mail from Scott Fahlman as a reply to my mail. ------------------ Comment for GC by Fahlman --------------------------- Date: Sun, 8 Jun 1986 02:17 EDT From: "Scott E. Fahlman" To: ida%utokyo-relay.csnet@csnet-relay.csnet Subject: User initiated GC ? In-Reply-To: Msg of Fri 6 Jun 86 19:01:00+0900 from Masayuki Ida Received: from CSNet-Relay by utokyo-relay; 8 Jun 86 19:26:13-JST (Sun) Status: RO There is no explicit GC control in Common Lisp because we believed that garbage collection would vary tremendously from one implementation to another, and that new ideas for GC might come along in the future. There are already systems that do mark-and-sweep GC, incremental copying GC, stop-and-copy GC, reference-count GC with an occasional complete GC, ephemeral GC (see Moon's paper in the last Lisp conference), and a proposal by Jon White for a system that would have a huge memory and would do a GC very rarely. Some systems do a GC because they are really running out of space; others do a GC just to compact live items and improve paging performance. In such a diverse world, it is hard to imagine any use for explicit GC-control functions that would not be system-dependent. One can imagine a GC function that says "if the system ever stops to garbage-collect, do it now", but when would you use this in portable code? It might take a millisecond on one machine and six hours on another. It might or might not guarantee that you're safe from further GC's for a certain period. So we decided to leave such controls to the discretion of the implementor on any given system. -- Scott ------------------- end ----------------------  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 10 Jul 86 04:33:25 EDT Received: from AI.AI.MIT.EDU by SU-AI.ARPA with TCP; 10 Jul 86 01:24:43 PDT Received: from OZ.AI.MIT.EDU by AI.AI.MIT.EDU via Chaosnet; 10 JUL 86 01:06:34 EDT Date: Thu, 10 Jul 1986 01:02 EDT Message-ID: From: STEVER%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU To: common-lisp@SU-AI.ARPA Subject: more editorial comment on format In-reply-to: Msg of 9 Jul 1986 16:39-EDT from SANDRA Date: Wednesday, 9 July 1986 16:39-EDT From: SANDRA To: common-lisp at SU-AI.ARPA Re: more editorial comment on format Personally, I think that if you need to use more than ~a, ~s, ~%, ~t, and ~~, you should be writing Lisp code to do the formatting instead of using this crufty embedded language that bears no resemblance or relationship to the rest of Common Lisp. I heartily agree! Being a relative novice at using FORMAT (except in the most straightforward way), I've spent far too much time trying to get format control strings to do what I want. This seems like a case of the solution being harder than the problem... It's also unfortunate that there aren't *functions* provided to do some of the nastier numeric formatting, like ~e and friends. Well, you can always: (defun exp-floating-point (w d e k overflow-char padchar expchar) (format nil "~v,v,v,v,v,v,vE" w d e k overflow-char padchar expchar)) ... :-) Stever  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 9 Jul 86 19:03:39 EDT Received: from SDCSVAX.UCSD.EDU by SU-AI.ARPA with TCP; 9 Jul 86 15:54:19 PDT Received: by sdcsvax.ucsd.edu (5.31/4.42) id AA11256; Wed, 9 Jul 86 15:56:39 PDT hops=0 Date: Wed, 9 Jul 86 15:56:39 PDT From: jvz@sdcsvax.ucsd.edu (John Van Zandt) Message-Id: <8607092256.AA11256@sdcsvax.ucsd.edu> To: Common-Lisp@su-ai.arpa Subject: mailing list Please add me to your mailing list. Thanks, John Van Zandt jvz@UCSD Engineering Manager DataFlo(tm) Computer Products Loral Instrumentation  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 9 Jul 86 16:52:53 EDT Received: from UTAH-20.ARPA by SU-AI.ARPA with TCP; 9 Jul 86 13:40:55 PDT Date: Wed 9 Jul 86 14:39:09-MDT From: SANDRA Subject: more editorial comment on format To: common-lisp@SU-AI.ARPA Message-ID: <12221378859.20.LOOSEMORE@UTAH-20.ARPA> Some years ago, while taking a software engineering class, I heard a lecture on "The Magical Number Seven". Essentially, the idea is that people get confused if confronted with more than seven options or choices at one time. Wouldn't it be nice if we only had to remember 7 obscure format commands, instead of 30 (plus all of their innumerable modifiers and variations)? Personally, I think that if you need to use more than ~a, ~s, ~%, ~t, and ~~, you should be writing Lisp code to do the formatting instead of using this crufty embedded language that bears no resemblance or relationship to the rest of Common Lisp. It's also unfortunate that there aren't *functions* provided to do some of the nastier numeric formatting, like ~e and friends. Trying to imitate the way FORTRAN does it is not necessarily a very good idea. Anybody who has ever taught FORTRAN knows that FORMAT is by far the most difficult part of the language to understand. Even experienced FORTRAN programmers who think they grok FORMAT are continually surprised by its bizzarities. I suppose that if CL was trying to achieve cultural compatibility with FORTRAN, it's succeeded.... -Sandra -------  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 9 Jul 86 15:30:25 EDT Received: from GANDALF.CS.CMU.EDU by SU-AI.ARPA with TCP; 9 Jul 86 12:18:20 PDT Date: Wed, 9 Jul 86 15:16:25 EDT From: Walter.Tichy@GANDALF.CS.CMU.EDU To: common-lisp@su-ai Subject: Concurrent Lisp I'm looking for information on the following: 1. What concurrent processing and synchronization primitives have evolved in the Lisp community? (supporting the model of "communicating sequential processes", not so much the "massively" parallel stuff.) 2. Is there any work addressing the problem of simultaneous access and updates to semantic nets? 3. What about distributed semantic nets or distributed shared memory? -Walter Tichy tichy@gandalf.cs.cmu.edu  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 9 Jul 86 14:41:56 EDT Received: from VAXA.ISI.EDU by SU-AI.ARPA with TCP; 9 Jul 86 10:32:39 PDT Received: by vaxa.isi.edu (4.12/4.7) id AA25842; Wed, 9 Jul 86 10:32:06 pdt From: berman@vaxa.isi.edu (Richard Berman) Message-Id: <8607091732.AA25842@vaxa.isi.edu> Date: 9 Jul 1986 1032-PDT (Wednesday) To: "Scott E. Fahlman" Cc: common-lisp@SU-AI.ARPA Subject: Re: Editorial Comment In-Reply-To: Your message of Tue, 8 Jul 1986 21:32 EDT. Merci.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 9 Jul 86 14:41:41 EDT Received: from CS.UCL.AC.UK by SU-AI.ARPA with TCP; 9 Jul 86 10:24:02 PDT Received: from aiva.edinburgh.ac.uk by 44d.Cs.Ucl.AC.UK via Janet with NIFTP id a000970; 9 Jul 86 18:13 BST From: Jeff Dalton Date: Wed, 9 Jul 86 18:11:41 -0100 Message-Id: <20095.8607091711@aiva.ed.ac.uk> To: common-lisp@su-ai.arpa Subject: Re: DECLARE SPECIAL Sorry. I seem to have blown it again. The macro expansion for special declarations inside a LET should be: (let ((foo (1+ foo))) (declare (special foo)) foo) ==> ((lambda () (declare (special foo)) ;decl for init form ((lambda (foo) (declare (special foo)) foo) (1+ foo)))) Anyway, if you try this kind of LET in some implementations, you'll find that they get it right (the special declaration applies to the foo in the init form) in the compiler but not in the interpreter. -- Jeff  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 9 Jul 86 14:41:24 EDT Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 9 Jul 86 10:14:13 PDT Received: from faustinas by Godot.Think.COM via CHAOS; Wed, 9 Jul 86 13:14:15 edt Date: Wed, 9 Jul 86 13:15 EDT From: Guy Steele Subject: Editorial Comment To: Fahlman@C.CS.CMU.EDU, gls@ZARATHUSTRA Cc: common-lisp@SU-AI.ARPA, gls@AQUINAS In-Reply-To: Message-Id: <860709131505.2.GLS@FAUSTINUS.THINK.COM> Date: Tue, 8 Jul 1986 21:32 EDT From: "Scott E. Fahlman" :-( "~:[{~;[~]~:{~S~:[!~S~;~*~]~:^ ~}~:[ ~]~{~S!~^ ~}~:[ ~]~[~*~;!~S~;. ~S~;!~*~]~:[}~;]~]" )-: !!! Well, it seemed clear when I wrote it...  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 9 Jul 86 11:22:37 EDT Received: from SDCSVAX.UCSD.EDU by SU-AI.ARPA with TCP; 9 Jul 86 08:09:46 PDT Received: by sdcsvax.ucsd.edu (5.31/4.42) id AA03774; Tue, 8 Jul 86 18:09:33 PDT hops=0 Received: by sdcc6.ARPA (5.51/4.41) id AA25847; Tue, 8 Jul 86 18:08:41 PDT Received: from sally.LORAL (sally.ARPA) by loral.UUCP (4.12/4.7) id AA08598; Tue, 8 Jul 86 11:18:03 pdt Received: by sally.LORAL (5.45/4.7) id AA11840; Tue, 8 Jul 86 11:21:53 PDT Date: Tue, 8 Jul 86 11:21:53 PDT From: loral!jvz@sdcsvax.ucsd.edu (John Van Zandt) Message-Id: <8607081821.AA11840@sally.LORAL> To: Common-Lisp@su-ai.arpa Please add me to your mailing list. Thanks, John Van Zandt jvz@UCSD Engineering Mgr DataFlo(tm) Computer Products Loral Instrumentation  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 9 Jul 86 10:03:13 EDT Received: from SCRC-QUABBIN.ARPA by SU-AI.ARPA with TCP; 9 Jul 86 06:53:31 PDT Received: from CHICOPEE.SCRC.Symbolics.COM by QUABBIN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 17243; Tue 8-Jul-86 14:39:38 EDT Date: Tue, 8 Jul 86 14:45 EDT From: Daniel L. Weinreb Subject: compiler-let To: common-lisp@SU-AI.ARPA In-Reply-To: The message of 8 Jul 86 12:57 EDT from hpfclp!diamant@hplabs.HP.COM Message-ID: <860708144532.2.DLW@CHICOPEE.SCRC.Symbolics.COM> I agree with much of what's been said. I'd just like to add that the really bogus thing is that compiler-let is defined in terms of "the interpreter does this, the compiler does that", in a language where the whole point is that they do the same thing. The definition should be in terms of the actual semantics of the language, without reference to the interpreter or compiler. Of course, that's hard, but it would also point up some of the same problems that we've been discussing. I also agree that the name is terrible. If everything important that it does can be done just as well with macrolet, then perhaps simply removing compiler-let is the right thing to do. Historical note: the first edition Lisp Machine Manual [Weinreb and Moon 1978] lists this form, and explains it primarily as a way to control compiler-directive flags (which is really bogus for CL), and secondarily to bind flags that affect macro expansion. This survived into the later editions of the manual. So I certainly take some blame for this mess. The Symbolics documentation has been improved a lot by someone, and while it retains the old compiler-flag stuff, it also includes a good example of what compiler-let is really for. Interestingly, it then shows how to do the same thing with macrolet!  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 8 Jul 86 21:48:34 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 8 Jul 86 18:32:44 PDT Received: ID ; Tue 8 Jul 86 21:32:28-EDT Date: Tue, 8 Jul 1986 21:32 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Guy Steele Cc: common-lisp@SU-AI.ARPA Subject: Editorial Comment In-reply-to: Msg of 8 Jul 1986 13:04-EDT from Guy Steele :-( "~:[{~;[~]~:{~S~:[!~S~;~*~]~:^ ~}~:[ ~]~{~S!~^ ~}~:[ ~]~[~*~;!~S~;. ~S~;!~*~]~:[}~;]~]" )-: !!!  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 8 Jul 86 17:03:15 EDT Received: from CS.UCL.AC.UK by SU-AI.ARPA with TCP; 8 Jul 86 13:54:24 PDT Received: from aiva.edinburgh.ac.uk by 44d.Cs.Ucl.AC.UK via Janet with NIFTP id a002506; 7 Jul 86 19:30 BST From: Jeff Dalton Date: Mon, 7 Jul 86 19:27:20 -0100 Message-Id: <1672.8607071827@aiva.ed.ac.uk> To: Common-Lisp@su-ai.arpa, DCP@scrc-quabbin.arpa, Pavel.pa@xerox.com Subject: Re: DECLARE SPECIAL Considered Confusing Date: Mon, 7 Jul 86 10:03 EDT From: "David C. Plummer" Subject: DECLARE SPECIAL Considered Confusing Date: 5 Jul 86 16:54 PDT From: Pavel.pa@Xerox.COM What do people think? It would appear that some implementations already work this way. I agree. Consider LET to be a macro that turns into LAMBDA: (let ((foo (1+ foo))) (declare (special foo)) foo) => ((lambda (foo) (declare (special foo)) foo) (1+ foo)) [I think this is what MacLisp actually did (does?).] The scoping here is clear: the foo in (1+ foo) is outside the scope of the declaration. If the SPECIAL declaration is to apply to the init forms, LET can be a macro that turns into two lambdas: (let ((foo (1+ foo))) (declare (special foo)) foo) => ((lambda () (declare (special foo)) ((lambda (foo) foo) (declare (special foo)) (1+ foo)))) Some implementations do work this way.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 8 Jul 86 16:06:16 EDT Received: from HPLABS.HP.COM by SU-AI.ARPA with TCP; 8 Jul 86 12:56:22 PDT Received: from hplsny by hplabs.HP.COM ; Tue, 8 Jul 86 12:54:00 pdt Received: by hplsny ; Tue, 8 Jul 86 12:54:00 pdt From: Alan Snyder Message-Id: <8607081954.AA13185@hplsny> Date: Tuesday, July 8, 1986 12:53:47 Subject: Re: Compiler recognizing uses of only two values To: KMP@SCRC-STONY-BROOK.ARPA Cc: common-lisp@su-ai.ARPA In-Reply-To: Your message of 3-Jul-86 11:57:00 X-Sent-By-Nmail-Version: 04-Nov-84 17:14:46 Date: Thu, 3 Jul 86 11:57 EDT From: Kent M Pitman Subject: Compiler recognizing uses of only two values To: snyder%hplsny@hplabs.HP.COM I had thought about that and decided not to mention it because I fear someone will take it seriously. It's a good idea, of course, but unless you practically -- perhaps literally -- require compilers to do hairy optimizations like this, most people won't bother and I'll be stuck with having to effectively treat the feature as unavailable on some systems. Sigh. The problem with portability is that the whole idea is to allow your program to move from the "reasonable" system you developed it in to a bunch of "hostile" systems that you didn't develop your code in -- often for good reason. Perhaps I'm being too pessimistic. Of course, Common Lisp already has the problem that users and implementors don't always agree on what "should" be efficient. On the other hand, just providing the "efficient" function in the language definition doesn't guarantee that an implementor will implement it efficiently. If he doesn't share (or is not aware of) your view of its importance, he may implement it by calling the inefficient function and throwing away the excess values. Alan -------  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 8 Jul 86 13:15:20 EDT Received: from HPLABS.HP.COM by SU-AI.ARPA with TCP; 8 Jul 86 09:59:46 PDT Received: by hplabs.HP.COM ; Tue, 8 Jul 86 09:57:30 pdt Date: Tue, 8 Jul 86 09:57:30 pdt From: hpfclp!diamant@hplabs.HP.COM To: common-lisp@su-ai.ARPA Subject: compiler-let Subject: compiler-let From: David A. Moon Date: Mon, 7 Jul 86 15:13 EDT From: Jonathan A Rees COMPILER-LET seems pretty confused; CLtL says that it is intended "for communication among complicated macros," but as far as I can tell it doesn't reliably serve this end, since its effect is not the same in interpreted and compiled code. Consider the following example: (defvar *foo* nil) (defmacro foo () `',*foo*) (defun test () (compiler-let ((*foo* t)) #'(lambda () (foo)))) Now if TEST is "interpreted," then (funcall (test)) presumably returns NIL; if it's "compiled," then (funcall (test)) presumably returns T. It always returns T in the implementation on my machine. It also always returns T on my machine (HP Common Lisp). But I see your point. If the macro foo was not expanded until after the closure was made, and if the interpreter failed to include the COMPILER-LET information in the closure, it would return NIL. I certainly agree with Jonathan that as stated in CLtL, COMPILER-LET is bogus. When implementing this special form, we determined that (if we were to believe the intent stated for COMPILER-LET) the bindings must be in effect in the same context that the macroexpansion will occur. The statement made in CLtL for the compiler is correct as all Common Lisp implementations are required to expand macros at compile time (see page 143). However, the statement that COMPILER-LET behaves like LET in the interpreter implictly assumes that macros are expanded at eval time in the interpreter. Since this is not true in our implementation, we had to decide what was needed to make COMPILER-LET perform as needed. This meant that for our implementation, COMPILER-LET does the same thing whether interpreted or compiled (it sets up bindings in the preprocessor environment -- which is when macroexpansion occurs in our system). I am not sure whether COMPILER-LET should remain in the language or not, but I think that the correction to the description which I mentioned does make it meaningful (although terribly misnamed). John  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 8 Jul 86 13:14:13 EDT Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 8 Jul 86 10:03:06 PDT Received: from boethius by Godot.Think.COM via CHAOS; Tue, 8 Jul 86 13:03:15 edt Date: Tue, 8 Jul 86 13:04 EDT From: Guy Steele Subject: [gls@Think.COM: Re: compiler-let] To: common-lisp@SU-AI.ARPA Message-Id: <860708130406.5.GLS@BOETHIUS.THINK.COM> Date: Mon, 7 Jul 86 17:10:25 MDT From: shebs%utah-orion@utah-cs.ARPA (Stanley Shebs) ... Methinks there is a tongue pressed into cheek somewhere, but I'll answer bravely anyway: COMPILER-LET takes honors as the most bogus item in Common Lisp, with the possible exception of certain format directives (GLS's example of the FORMAT-ERROR function is an unusually subtle joke - "looks pretty flashy when done properly"!). In this connection, I would like to nominate the following for Most Unreadable Format Control String in Production Code: "~:[{~;[~]~:{~S~:[!~S~;~*~]~:^ ~}~:[ ~]~{~S!~^ ~}~:[ ~]~[~*~;!~S~;. ~S~;!~*~]~:[}~;]~]" I am not kidding; I wrote this as part of the Connection Machine Lisp simulator, and it really does do exactly what I want. It is part of the printing function for a data structure called a xapping, whose syntax involves brackets or braces under various circumstances. Here is the entire printing function: (defun print-xapping (xapping stream depth) (declare (ignore depth)) (format stream "~:[{~;[~]~:{~S~:[!~S~;~*~]~:^ ~}~:[ ~]~{~S!~^ ~}~:[ ~]~[~*~;!~S~;. ~S~;!~*~]~:[}~;]~]" ;\_______/\_____________________/\____/\________/\____/\____________________/\_______/ (xectorp xapping) (do ((vp (xectorp xapping)) (sp (finite-part-is-xetp xapping)) (d (xapping-domain xapping) (cdr d)) (r (xapping-range xapping) (cdr r)) (z '() (cons (list (if vp (car r) (car d)) (or vp sp) (car r)) z))) ((null d) (reverse z))) (not (and (xapping-domain xapping) (or (xapping-exceptions xapping) (xapping-infinite xapping)))) (xapping-exceptions xapping) (not (or (and (xapping-exceptions xapping) (xapping-infinite xapping)) (and (eq (xapping-infinite xapping) :lazy) (null (xapping-domain xapping)) (null (xapping-exceptions xapping))))) (ecase (xapping-infinite xapping) (:constant 1) (:lazy 2) (:universal 3) ((nil) 0)) (xapping-default xapping) (xectorp xapping)))  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 7 Jul 86 23:31:26 EDT Received: from SCRC-QUABBIN.ARPA by SU-AI.ARPA with TCP; 7 Jul 86 20:15:02 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by QUABBIN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 17091; Mon 7-Jul-86 23:13:40 EDT Date: Mon, 7 Jul 86 23:13 EDT From: David A. Moon Subject: DECLARE SPECIAL Considered Confusing To: Pavel.pa@Xerox.COM cc: Common-Lisp@SU-AI.ARPA In-Reply-To: <860705-165424-2715@Xerox> Supersedes: <860707205952.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Message-ID: <860707231340.6.MOON@EUPHRATES.SCRC.Symbolics.COM> I do not wish to defend the current choice of declaration-scoping rules in Common Lisp as the best or only choice, but I do wish to clarify what the rules are in the language as it is currently defined. It wouldn't bother me if a future revision of the language adopted simpler rules, provided they were truly (not just superficially) simpler. Date: 5 Jul 86 16:54 PDT From: Pavel.pa@Xerox.COM I have a question concerning some ambiguity in the description of the scope of a special declaration inside a LET. Consider this code: (setq foo 6) (let ((foo 7)) (let ((foo (1+ foo))) (declare (special foo)) foo)) Both Symbolics and CLISP return 8 for this, but VAXLISP returns 7. VAXLISP is correct here. The SPECIAL declaration is pervasive for references (but non-pervasive for bindings). Because SPECIAL is pervasive for references it affects the reference to foo inside 1+. I apologize for the incorrect earlier version of this message that said that VAXLISP was incorrect here. I didn't mean to add to the confusion; it must have been a Freudian slip. Incidentally, the incorrect result returned here by the Symbolics implementation is a (poorly) documented incompatibility with Common Lisp that will be fixed at some time in the future. Clearly, the question is whether or not the special declaration covers the init-form of the enclosing LET or just the bindings themselves. According to the ``nonsense'' example in CLtL, page 155, the reference to ``foo'' in the call to 1+ should be special. The GLS clarification for page 159, however, seems to support a different philosophy: ``(*) 159 Clarify that in the following example (defun foo (x) (declare (inline bar)) (bar x) ; first (flet ((bar (z) (bar (+ z 1)))) ; second (bar x)) ; third (bar x) ; fourth the first, second and fourth calls to BAR are affected by the INLINE declaration, but not the third one.'' This seems to support the view that the init-form of a binding is in a scope outside of that of the binding itself and the body of the LET (or FLET or ...). I prefer this view. The scoping of variables (and FLET functions) is different from the scoping of pervasive declarations. There is no analogy between this example and your previous one, because the INLINE declaration is not attached to a binding, but the SPECIAL declaration is attached to a binding. All that's shown by this clarification is that INLINE, just like SPECIAL, is shadowed by an occurrence of another binding of the same name inside its scope. Incidentally, the bottom of p.154 says that SPECIAL is the only declaration that falls into both classes, but I think INLINE is really in the same category. It concerns a particular binding, but can also be used in the absence of a binding and is pervasive for references, just like SPECIAL. I would like to propose the following rule for the scope of declarations in binding forms: ``A declaration in a binding form (such as LET) affects the body of the form and the bindings themselves. It does not affect the init-forms for the bindings; they are in the same scope as the binding form as a whole.'' This rule has the advantage (over the rule given for the nonsense example) that the scope of the declarations is the same as the scope of the bindings. Thus, for the nonsense example: (defun nonsense (k x z) (foo z x) ;First call to foo (let ((j (foo k x)) ;Second call to foo (x (* k k))) (declare (inline foo) (special x z)) (foo x j z))) ;Third call to foo the inline declaration affects only the third call to foo (not the second) and only the references to x and z in the third call to foo are special (not the reference to x in the second call). There would be only two exceptions to this rule: -- In a LABELS binding, references in the definitions of the functions to the very functions being bound would be affected by any declarations affecting the bindings themselves. This makes sense because of the recursive quality of the binding. -- The PROCLAIM function establishes pervasive declarations, covering all bindings of and references to the symbols named. Such declarations can, of course, be countermanded by local declarations or later proclamations. What about declarations inside the body of DEFUN? With your rules I cannot see how a declaration could ever affect the default value forms for &optional, &key, and &aux variables. And what about declarations inside the body of a LET*? The scoping of ones attached to variables is fairly obvious, but what about ones not attached to variables? We went all through this during the design of Common Lisp (I think the discussion is available online) and the current rules resulted. Given that we must have DECLARE at all (a point which you should not necessarily be willing to concede), the current rules seem to work more consistently than the alternatives that were considered.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 7 Jul 86 22:58:54 EDT Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 7 Jul 86 19:45:22 PDT Date: 7 Jul 1986 22:44-EDT Sender: NGALL@G.BBN.COM Subject: Re: DECLARE SPECIAL Considered Confusing From: NGALL@G.BBN.COM To: Moon@SCRC-STONY-BROOK.ARPA Cc: Pavel.pa@XEROX.COM, Common-Lisp@SU-AI.ARPA Message-ID: <[G.BBN.COM] 7-Jul-86 22:44:13.NGALL> In-Reply-To: <860707205952.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Mon, 7 Jul 86 20:59 EDT From: David A. Moon To: Pavel.pa@Xerox.COM Subject: DECLARE SPECIAL Considered Confusing In-Reply-To: <860705-165424-2715@Xerox> Message-ID: <860707205952.2.MOON@EUPHRATES.SCRC.Symbolics.COM> ... Date: 5 Jul 86 16:54 PDT From: Pavel.pa@Xerox.COM I have a question concerning some ambiguity in the description of the scope of a special declaration inside a LET. Consider this code: (setq foo 6) (let ((foo 7)) (let ((foo (1+ foo))) (declare (special foo)) foo)) Both Symbolics and CLISP return 8 for this, but VAXLISP returns 7. VAXLISP is incorrect here. The SPECIAL declaration is pervasive for references (but non-pervasive for bindings). Because SPECIAL is pervasive for references it affects the reference to foo inside 1+. I don't wish to add to the confusion here, but my reading of pg 155 agrees with VaxLisp: the above example should return 7. The outermost LET binds a lexical var. named foo that is never referenced. The special declaration in the inner LET affects the variable being bound by the LET (foo) and it affects the reference to foo in the explicit body (i.e. the last reference to foo) and the reference to foo in the init-form in the inner LET is also special. The global value of foo is 6, and 6 + 1 = 7. -- Nick  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 7 Jul 86 21:28:27 EDT Received: from [192.10.41.41] by SU-AI.ARPA with TCP; 7 Jul 86 18:15:31 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 36962; Mon 7-Jul-86 20:58:58 EDT Date: Mon, 7 Jul 86 20:59 EDT From: David A. Moon Subject: DECLARE SPECIAL Considered Confusing To: Pavel.pa@Xerox.COM cc: Common-Lisp@SU-AI.ARPA In-Reply-To: <860705-165424-2715@Xerox> Message-ID: <860707205952.2.MOON@EUPHRATES.SCRC.Symbolics.COM> I do not wish to defend the current choice of declaration-scoping rules in Common Lisp as the best or only choice, but I do wish to clarify what the rules are in the language as it is currently defined. It wouldn't bother me if a future revision of the language adopted simpler rules, provided they were truly (not just superficially) simpler. Date: 5 Jul 86 16:54 PDT From: Pavel.pa@Xerox.COM I have a question concerning some ambiguity in the description of the scope of a special declaration inside a LET. Consider this code: (setq foo 6) (let ((foo 7)) (let ((foo (1+ foo))) (declare (special foo)) foo)) Both Symbolics and CLISP return 8 for this, but VAXLISP returns 7. VAXLISP is incorrect here. The SPECIAL declaration is pervasive for references (but non-pervasive for bindings). Because SPECIAL is pervasive for references it affects the reference to foo inside 1+. Clearly, the question is whether or not the special declaration covers the init-form of the enclosing LET or just the bindings themselves. According to the ``nonsense'' example in CLtL, page 155, the reference to ``foo'' in the call to 1+ should be special. The GLS clarification for page 159, however, seems to support a different philosophy: ``(*) 159 Clarify that in the following example (defun foo (x) (declare (inline bar)) (bar x) ; first (flet ((bar (z) (bar (+ z 1)))) ; second (bar x)) ; third (bar x) ; fourth the first, second and fourth calls to BAR are affected by the INLINE declaration, but not the third one.'' This seems to support the view that the init-form of a binding is in a scope outside of that of the binding itself and the body of the LET (or FLET or ...). I prefer this view. The scoping of variables (and FLET functions) is different from the scoping of pervasive declarations. There is no analogy between this example and your previous one, because the INLINE declaration is not attached to a binding, but the SPECIAL declaration is attached to a binding. All that's shown by this clarification is that INLINE, just like SPECIAL, is shadowed by an occurrence of another binding of the same name inside its scope. Incidentally, the bottom of p.154 says that SPECIAL is the only declaration that falls into both classes, but I think INLINE is really in the same category. It concerns a particular binding, but can also be used in the absence of a binding and is pervasive for references, just like SPECIAL. I would like to propose the following rule for the scope of declarations in binding forms: ``A declaration in a binding form (such as LET) affects the body of the form and the bindings themselves. It does not affect the init-forms for the bindings; they are in the same scope as the binding form as a whole.'' This rule has the advantage (over the rule given for the nonsense example) that the scope of the declarations is the same as the scope of the bindings. Thus, for the nonsense example: (defun nonsense (k x z) (foo z x) ;First call to foo (let ((j (foo k x)) ;Second call to foo (x (* k k))) (declare (inline foo) (special x z)) (foo x j z))) ;Third call to foo the inline declaration affects only the third call to foo (not the second) and only the references to x and z in the third call to foo are special (not the reference to x in the second call). There would be only two exceptions to this rule: -- In a LABELS binding, references in the definitions of the functions to the very functions being bound would be affected by any declarations affecting the bindings themselves. This makes sense because of the recursive quality of the binding. -- The PROCLAIM function establishes pervasive declarations, covering all bindings of and references to the symbols named. Such declarations can, of course, be countermanded by local declarations or later proclamations. What about declarations inside the body of DEFUN? With your rules I cannot see how a declaration could ever affect the default value forms for &optional, &key, and &aux variables. And what about declarations inside the body of a LET*? The scoping of ones attached to variables is fairly obvious, but what about ones not attached to variables? We went all through this during the design of Common Lisp (I think the discussion is available online) and the current rules resulted. Given that we must have DECLARE at all (a point which you should not necessarily be willing to concede), the current rules seem to work more consistently than the alternatives that were considered.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 7 Jul 86 20:44:46 EDT Received: from [192.10.41.41] by SU-AI.ARPA with TCP; 7 Jul 86 17:33:02 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 36946; Mon 7-Jul-86 20:30:53 EDT Date: Mon, 7 Jul 86 20:31 EDT From: David A. Moon Subject: compiler-let To: common-lisp@SU-AI.ARPA In-Reply-To: <860707151336.1.JAR@ROCKY-GRAZIANO.LCS.MIT.EDU> Message-ID: <860707203141.0.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Mon, 7 Jul 86 15:13 EDT From: Jonathan A Rees COMPILER-LET seems pretty confused; CLtL says that it is intended "for communication among complicated macros," but as far as I can tell it doesn't reliably serve this end, since its effect is not the same in interpreted and compiled code. Consider the following example: (defvar *foo* nil) (defmacro foo () `',*foo*) (defun test () (compiler-let ((*foo* t)) #'(lambda () (foo)))) Now if TEST is "interpreted," then (funcall (test)) presumably returns NIL; if it's "compiled," then (funcall (test)) presumably returns T. It always returns T in the implementation on my machine. But I see your point. If the macro foo was not expanded until after the closure was made, and if the interpreter failed to include the COMPILER-LET information in the closure, it would return NIL. This is item #300 (or thereabouts) among the minor design decisions that were not reevaluated when full lexical scoping was added to the language late in the process of designing Common Lisp. Perhaps there should be a committee of interested persons to search for these systematically. To get you started, #259 is: what does this form do? (dotimes (i n) (push #'(lambda () i) l)) I don't know why you say COMPILER-LET is difficult to handle in code-walkers. I think it might be the second-easiest special form, after QUOTE. You just bind the special variables and proceed. Is there any kind of thing which can be done using COMPILER-LET which can't be done using MACROLET? MACROLETs aren't visible in the scope of the body of a macro expansion function. That's the whole reason why COMPILER-LET uses dynamic scoping. I thought about this a bit and looked at some real examples, too large and unilluminating to include here. I think the answer is that since COMPILER-LET can only affect the expansion of macros, it can always be replaced with a MACROLET that redefines the macro to a new version of its body with the COMPILER-LET variable's value included in the macro as a constant. This gets cumbersome when the macro definition is large (this can be addressed by calling a subroutine) or when there are nested COMPILER-LETs for different variables or variables that are not constant but depend on the particular macro call (I haven't figured out how to cope with that, other than by using the trick of explicitly calling MACROEXPAND that you had in your mail, which is essentially using the MACROLET environment to simulate deep-bound special variables). Another reason for COMPILER-LET, no doubt bogus, can be found in the Lisp Machine manual ("Chine Nual"). It can be used to bind switches that affect the operation of the compiler. Presumably this could be done with declarations or special forms, at some small increase in compiler complexity. Except for this application, COMPILER-LET doesn't appear to have anything to do specifically with compilers, and is evidently misnamed.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 7 Jul 86 19:23:34 EDT Received: from UTAH-CS.ARPA by SU-AI.ARPA with TCP; 7 Jul 86 16:14:05 PDT Received: by utah-cs.ARPA (5.31/4.40.2) id AA05923; Mon, 7 Jul 86 17:10:29 MDT Received: by utah-orion.ARPA (5.31/4.40.2) id AA18578; Mon, 7 Jul 86 17:10:25 MDT Date: Mon, 7 Jul 86 17:10:25 MDT From: shebs%utah-orion@utah-cs.arpa (Stanley Shebs) Message-Id: <8607072310.AA18578@utah-orion.ARPA> Newsgroups: fa.common-lisp Subject: Re: compiler-let Summary: Expires: References: <860707181000.8.DLW@CHICOPEE.SCRC.Symbolics.COM> Sender: Reply-To: shebs@utah-orion.UUCP (Stanley Shebs) Followup-To: Distribution: Organization: University of Utah CS Dept Keywords: Apparently-To: common-lisp@su-ai.arpa In article <860707181000.8.DLW@CHICOPEE.SCRC.Symbolics.COM> DLW@QUABBIN.SCRC.Symbolics.COM (Daniel L. Weinreb) writes: >To: shebs@utah-orion.UUCP > > Date: Mon, 7 Jul 86 13:45:37 MDT > From: shebs%utah-orion@utah-cs.arpa (Stanley Shebs) > > For PCLS we took advantage of subsetness and totally ignored COMPILER-LET, > since nobody could figure out what it was really for or how a user could > use it in correct code. > >That's a very good way to make design decisions. > >It's certainly true that CLtL does not explain compiler-let well enough. >A single example would probably help a great deal. > >For purposes of future manual revisions: what other features did you >totally ignore for the same reasons? Methinks there is a tongue pressed into cheek somewhere, but I'll answer bravely anyway: COMPILER-LET takes honors as the most bogus item in Common Lisp, with the possible exception of certain format directives (GLS's example of the FORMAT-ERROR function is an unusually subtle joke - "looks pretty flashy when done properly"!). PCLS includes FIFTH through TENTH, but that was because they were so easy that people spent time on those to avoid working on useful functions. We used to be prejudiced against MACROLET, but have since been partially convinced of its worth, and it's likely to appear in the next version of PCLS. There was also a move afoot to flush CONS because it consed immensely, but everybody's resigned to keeping it in PCLS... stan  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 7 Jul 86 18:17:06 EDT Received: from [192.10.41.41] by SU-AI.ARPA with TCP; 7 Jul 86 15:07:36 PDT Received: from CHICOPEE.SCRC.Symbolics.COM by ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 36864; Mon 7-Jul-86 18:04:45 EDT Date: Mon, 7 Jul 86 18:10 EDT From: Daniel L. Weinreb Subject: Re: compiler-let To: common-lisp@SU-AI.ARPA In-Reply-To: <8607071945.AA17899@utah-orion.ARPA> Message-ID: <860707181000.8.DLW@CHICOPEE.SCRC.Symbolics.COM> To: shebs@utah-orion.UUCP Date: Mon, 7 Jul 86 13:45:37 MDT From: shebs%utah-orion@utah-cs.arpa (Stanley Shebs) For PCLS we took advantage of subsetness and totally ignored COMPILER-LET, since nobody could figure out what it was really for or how a user could use it in correct code. That's a very good way to make design decisions. It's certainly true that CLtL does not explain compiler-let well enough. A single example would probably help a great deal. For purposes of future manual revisions: what other features did you totally ignore for the same reasons?  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 7 Jul 86 16:02:12 EDT Received: from UTAH-CS.ARPA by SU-AI.ARPA with TCP; 7 Jul 86 12:49:18 PDT Received: by utah-cs.ARPA (5.31/4.40.2) id AA26991; Mon, 7 Jul 86 13:45:41 MDT Received: by utah-orion.ARPA (5.31/4.40.2) id AA17899; Mon, 7 Jul 86 13:45:37 MDT Date: Mon, 7 Jul 86 13:45:37 MDT From: shebs%utah-orion@utah-cs.arpa (Stanley Shebs) Message-Id: <8607071945.AA17899@utah-orion.ARPA> Newsgroups: fa.common-lisp Subject: Re: compiler-let Summary: Expires: References: <860707151336.1.JAR@ROCKY-GRAZIANO.LCS.MIT.EDU> Sender: Reply-To: shebs@utah-orion.UUCP (Stanley Shebs) Followup-To: Distribution: Organization: University of Utah CS Dept Keywords: Apparently-To: common-lisp@su-ai.arpa In article <860707151336.1.JAR@ROCKY-GRAZIANO.LCS.MIT.EDU> JAR@MIT-AI.ARPA (Jonathan A Rees) writes: >COMPILER-LET seems pretty confused; Hear, hear! >Of course, the fact that COMPILER-LET has different meanings in >"interpreted" and "compiled" code is in conflict with th "consistency" >statement on page 2. If COMPILER-LET is to be made meaningful, a >precise distinction between the interpreted language and the compiled >language must be made somewhere, and this is something I haven't seen so >far. Since interpreter/compiler/strange evaluator consistency is one of the few things that almost everybody agrees is good about Common Lisp, it should take precedence over anything that would damage this; COMPILER-LET should be flushed, and EVAL-WHEN, and I wouldn't mind some constraints on macros in general, although there's not much prospect for that... >I'm surprised that people writing code-walkers haven't complained about >COMPILER-LET before (sorry if you have and I've forgotten). For PCLS we took advantage of subsetness and totally ignored COMPILER-LET, since nobody could figure out what it was really for or how a user could use it in correct code. stan  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 7 Jul 86 15:25:52 EDT Received: from LIVE-OAK.LCS.MIT.EDU by SU-AI.ARPA with TCP; 7 Jul 86 12:11:59 PDT Received: from ROCKY-GRAZIANO.LCS.MIT.EDU by MIT-LIVE-OAK.ARPA via CHAOS with CHAOS-MAIL id 3718; Mon 7-Jul-86 15:15:52-EDT Date: Mon, 7 Jul 86 15:13 EDT From: Jonathan A Rees Subject: compiler-let To: common-lisp@SU-AI.ARPA Message-ID: <860707151336.1.JAR@ROCKY-GRAZIANO.LCS.MIT.EDU> COMPILER-LET seems pretty confused; CLtL says that it is intended "for communication among complicated macros," but as far as I can tell it doesn't reliably serve this end, since its effect is not the same in interpreted and compiled code. Consider the following example: (defvar *foo* nil) (defmacro foo () `',*foo*) (defun test () (compiler-let ((*foo* t)) #'(lambda () (foo)))) Now if TEST is "interpreted," then (funcall (test)) presumably returns NIL; if it's "compiled," then (funcall (test)) presumably returns T. Thus the binding of the variable *FOO* is not reliably communicated to the macro FOO. Of course, the fact that COMPILER-LET has different meanings in "interpreted" and "compiled" code is in conflict with th "consistency" statement on page 2. If COMPILER-LET is to be made meaningful, a precise distinction between the interpreted language and the compiled language must be made somewhere, and this is something I haven't seen so far. Such a distinction would necessarily and absurdly cramp the styles of "interpreters" and "compilers," e.g. by dictating when macro expansion must happen (must a compiler expand macros? must an interpreter avoid doing so until the code is actually executed?). Is there any kind of thing which can be done using COMPILER-LET which can't be done using MACROLET? E.g., if you want a macro FOO to expand to one thing when a (FOO ...) form occurs lexically inside of a (BAR ...) form, but otherwise to something else, one is tempted to write (defvar *inside-bar-p* nil) (defmacro bar (&body body) `(compiler-let ((*inside-bar-p* t)) (progn ,@body))) (defmacro foo () `',*inside-bar-p*) (foo) => nil (bar (foo)) => t but this fails in exactly the same way the previous example does: (funcall (bar #'(lambda () (foo)))) => ?? (let ((fun #'(lambda () (foo)))) (bar (funcall fun))) => ?? MACROLET works much better; there are several ways to achieve the desired effect. (defmacro foo () ''nil) (defmacro bar (&body body) `(macrolet ((foo () ''t)) (progn ,@body))) (foo) => nil (bar (foo)) => t (funcall (bar #'(lambda () (foo)))) => t (let ((fun #'(lambda () (foo)))) (bar (funcall fun))) => nil or, alternatively: (defmacro foo (&environment e) (if (macroexpand '(inside-bar-p) e) ''t ''nil)) (defmacro inside-bar-p () 'nil) ;macroexpands to t or nil (defmacro bar (&body body) `(macrolet ((inside-bar-p () 't)) (progn ,@body))) etc. That is, the macro environment can be used reliably as a communications device, without being sensitive to how the code is being processed. I'm surprised that people writing code-walkers haven't complained about COMPILER-LET before (sorry if you have and I've forgotten). I can't imagine what one is supposed to take COMPILER-LET to mean if one is trying to understand the meaning of a program, instead of just trying to run it. If I had my way, I think I'd have COMPILER-LET excised, and if macros need to communicate with each other (a dubious proposition in the first place: can someone provide a realistic example?), the environments passed by MACROEXPAND to macro expanders can be used as a communcations channel. Another alternative is to require that macros always be pre-expanded even in "interpreted" code, and process COMPILER-LET's at this time; this would synchronize the MACROEXPAND environment with special variable bindings, so that source-code-lexical and expand-time-dynamic would mean the same thing. But this would require nontrivial changes to implementations. Jonathan  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 7 Jul 86 15:20:04 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 7 Jul 86 12:05:51 PDT Received: ID ; Mon 7 Jul 86 15:05:51-EDT Date: Mon, 7 Jul 1986 15:05 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Guy Steele Cc: common-lisp@SU-AI.ARPA Subject: Argument lists In-reply-to: Msg of 7 Jul 1986 14:45-EDT from Guy Steele I think that we should not get into the business of requiring that particular forms not cons or that they be efficient in other ways. That's opening Pandora's box. In some cases (e.g. multiple values) the whole idea of the construct is to make it possible to avoid consing, and we may point that out, but we shouldn't prescribe or forbid certain implementation techniques. In some strange future implementaiton, consing might be faster than anything else, even if you count GC time (or have some way of avoiding gc). -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 7 Jul 86 14:54:16 EDT Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 7 Jul 86 11:44:19 PDT Received: from boethius by Godot.Think.COM via CHAOS; Mon, 7 Jul 86 14:44:17 edt Date: Mon, 7 Jul 86 14:45 EDT From: Guy Steele Subject: Argument lists To: Fahlman@C.CS.CMU.EDU Cc: common-lisp@SU-AI.ARPA In-Reply-To: Message-Id: <860707144509.1.GLS@BOETHIUS.THINK.COM> Date: Mon, 7 Jul 1986 14:22 EDT From: "Scott E. Fahlman" ... However, it would be unprecedented, and probably a bad idea, to require that every compiler do this clever thing, and without such a requirement many implementations would skip this. People writing applications like the ones KMP has in mind would not be able to use FUNCTION-PARAMETERS if it is important to them that there be no consing in any reasonable implementation. On the other hand, there is no temptatation to do consing for FUNCTION-PARAMETER-RANGE, so it would be non-consing in any halfway decent implementation, without our having to require explicitly that it avoids consing. Also unprecedented in Common Lisp is the notion that a function be explicitly documented as not consing. Perhaps we want to introduce such a notion into the documentation, but it has repercussions far greate than on FUNCTIOn-PARAMETER-RANGE. --Guy  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 7 Jul 86 14:41:57 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 7 Jul 86 11:27:00 PDT Received: ID ; Mon 7 Jul 86 14:22:43-EDT Date: Mon, 7 Jul 1986 14:22 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Alan Snyder Cc: common-lisp@SU-AI.ARPA Subject: Argument lists In-reply-to: Msg of 3 Jul 1986 08:39-EDT from Alan Snyder Let's add both FUNCTION-PARAMETERS and FUNCTION-PARAMETER-RANGE. Isn't the proper "Common Lisp" solution to this issue to say that the compiler ought to recognize calls to FUNCTION-PARAMETERS that only use the first two values and, in implementations where FUNCTION-PARAMETER-RANGE would be faster, convert those calls to calls on SYS:FUNCTION-PARAMETER-RANGE (now an internal function)? Let me try to simulate KMP here, since the FUNCTION-PARAMETER-RANGE function is being proposed for him. Yes, a smart enough compiler could recognize those cases of FUNCTION-PARAMETERS which could be fast and non-consing and do the right thing. If this were required behavior, then people desiring speed could use FUNCTION-PARAMETERS with confidence that there would be no consing or groveling the code for parameters that are not really needed. However, it would be unprecedented, and probably a bad idea, to require that every compiler do this clever thing, and without such a requirement many implementations would skip this. People writing applications like the ones KMP has in mind would not be able to use FUNCTION-PARAMETERS if it is important to them that there be no consing in any reasonable implementation. On the other hand, there is no temptatation to do consing for FUNCTION-PARAMETER-RANGE, so it would be non-consing in any halfway decent implementation, without our having to require explicitly that it avoids consing. -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 7 Jul 86 13:28:27 EDT Received: from XEROX.COM by SU-AI.ARPA with TCP; 7 Jul 86 10:15:20 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 07 JUL 86 10:15:26 PDT Date: 7 Jul 86 10:15 PDT From: Masinter.pa@Xerox.COM Subject: Re: subst-if-not and nsubst-if-not, programming folk-lore In-reply-to: Guy Steele 's message of Mon, 7 Jul 86 10:30 EDT To: Common-Lisp@SU-AI.ARPA Message-ID: <860707-101526-3291@Xerox> Sounds like people want the equivalent of Interlisp's SUBST: (SUBST NEW OLD EXPR) [Function] Returns the result of substituting NEW for all occurrences of OLD in the expression EXPR. Substitution occurs whenever OLD is EQUAL to CAR of some subexpression of EXPR, or when OLD is atomic and EQ to a non-NIL CDR of some subexpression of EXPR. For example: (SUBST 'A 'B '(C B (X . B))) => (C A (X . A)) (SUBST 'A '(B C) '((B C) D B C)) => (A D B C) not (A D . A) SUBST returns a copy of EXPR with the appropriate changes. Furthermore, if NEW is a list, it is copied at each substitution. If the standard called it "IL:SUBST" then we wouldn't have to do any work. :-).  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 7 Jul 86 11:19:15 EDT Received: from SCRC-QUABBIN.ARPA by SU-AI.ARPA with TCP; 7 Jul 86 08:10:24 PDT Received: from FIREBIRD.SCRC.Symbolics.COM by QUABBIN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 16715; Mon 7-Jul-86 11:08:59 EDT Date: Mon, 7 Jul 86 11:08 EDT From: David C. Plummer Subject: subst-if-not and nsubst-if-not, programming folk-lore To: Guy Steele , DCP@QUABBIN.SCRC.Symbolics.COM, Common-Lisp@SU-AI.ARPA In-Reply-To: <860707103053.5.GLS@BOETHIUS.THINK.COM> Message-ID: <860707110827.8.DCP@FIREBIRD.SCRC.Symbolics.COM> Date: Mon, 7 Jul 86 10:30 EDT From: Guy Steele Date: Sun, 29 Jun 86 19:42 EDT From: David C. Plummer ... Now, when one tries subst-if-not, one gets a small surprise until one thinks about it a bit: (let* ((item-list '(numbers (1.0 2 5/3) symbols (foo bar))) (new (subst-if-not '3.1415 #'numberp item-list))) (values new item-list)) => 3.1415 (NUMBERS (1.0 2 5/3) SYMBOLS (FOO BAR)) How about (let* ((item-list '(numbers (1.0 2 5/3) symbols (foo bar))) (new (subst-if-not '3.1415 #'(lambda (x) (or (numberp x) (listp x))) item-list))) (values new item-list)) ? Sure, we can all find the right solution once we see the pitfall. My point is to document the pitfall so people are less surprised when it happens to them. [I tried to test this, but there appears to be a trivial bug in the Symbolics 3600 release 6.1 implementation of SUBST-IF-NOT.] [Recently fixed. Somebody should write a program to analyze mail coming out of vendors to track what areas of the software system the vendors are working on...] What the person probably wanted is to replace the non-null atomic leafs. I'm not sure what to think. One thing I'm thinking is that (n)subst-if-not is too counter-intuitive to be worth having in the language, even for completeness. At the very list, I think the book/manual should carefully discuss this issue to people don't get confused for years. At the very LIST, you say? So I did. A recent typo I made was "If you are trying to confuse me, you are goind a good job." --Guy --  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 7 Jul 86 10:39:07 EDT Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 7 Jul 86 07:29:54 PDT Received: from boethius by Godot.Think.COM via CHAOS; Mon, 7 Jul 86 10:29:57 edt Date: Mon, 7 Jul 86 10:30 EDT From: Guy Steele Subject: subst-if-not and nsubst-if-not, programming folk-lore To: DCP@QUABBIN.SCRC.Symbolics.COM, Common-Lisp@SU-AI.ARPA Cc: gls@AQUINAS In-Reply-To: <860629194244.5.DCP@FIREBIRD.SCRC.Symbolics.COM> Message-Id: <860707103053.5.GLS@BOETHIUS.THINK.COM> Date: Sun, 29 Jun 86 19:42 EDT From: David C. Plummer ... Now, when one tries subst-if-not, one gets a small surprise until one thinks about it a bit: (let* ((item-list '(numbers (1.0 2 5/3) symbols (foo bar))) (new (subst-if-not '3.1415 #'numberp item-list))) (values new item-list)) => 3.1415 (NUMBERS (1.0 2 5/3) SYMBOLS (FOO BAR)) How about (let* ((item-list '(numbers (1.0 2 5/3) symbols (foo bar))) (new (subst-if-not '3.1415 #'(lambda (x) (or (numberp x) (listp x))) item-list))) (values new item-list)) ? [I tried to test this, but there appears to be a trivial bug in the Symbolics 3600 release 6.1 implementation of SUBST-IF-NOT.] What the person probably wanted is to replace the non-null atomic leafs. I'm not sure what to think. One thing I'm thinking is that (n)subst-if-not is too counter-intuitive to be worth having in the language, even for completeness. At the very list, I think the book/manual should carefully discuss this issue to people don't get confused for years. At the very LIST, you say? --Guy  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 7 Jul 86 10:29:12 EDT Received: from SCRC-QUABBIN.ARPA by SU-AI.ARPA with TCP; 7 Jul 86 07:13:17 PDT Received: from FIREBIRD.SCRC.Symbolics.COM by QUABBIN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 16667; Mon 7-Jul-86 10:11:21 EDT Date: Mon, 7 Jul 86 10:10 EDT From: David C. Plummer Subject: subst-if-not and nsubst-if-not, programming folk-lore To: Brad Miller , David C. Plummer cc: Common-Lisp@SU-AI.ARPA In-Reply-To: <860706144822.2.MILLER@UR-BEECHNUT.ARPA> Message-ID: <860707101058.9.DCP@FIREBIRD.SCRC.Symbolics.COM> Date: Sun, 6 Jul 86 14:48 EDT From: Brad Miller Date: Sun, 29 Jun 86 19:42 EDT From: David C. Plummer These are really neat functions, and counterintuitive to boot. One of our documentation people tried this: [...] Now, when one tries subst-if-not, one gets a small surprise until one thinks about it a bit: (let* ((item-list '(numbers (1.0 2 5/3) symbols (foo bar))) (new (subst-if-not '3.1415 #'numberp item-list))) (values new item-list)) => 3.1415 (NUMBERS (1.0 2 5/3) SYMBOLS (FOO BAR)) and nsubst-if-not gives the same thing [...] , i.e., the list is NOT destructed. A careful reading explains why: the item-list is indeed not a number, and therefore it gets substituted (but you can't substitute the entire list, so you don't modify it). What the person probably wanted is to replace the non-null atomic leafs. I'm not sure what to think. One thing I'm thinking is that (n)subst-if-not is too counter-intuitive to be worth having in the language, even for completeness. At the very list, I think the book/manual should carefully discuss this issue to people don't get confused for years. Good point. To point out the obvious: perhaps [n]subst-if-not should not try to match subtrees? (which would include nil cdrs)..... That would still give a useful function on leaves.... Your example would have been evaluated to: (3.1415 (1.0 2 5/3) 3.1415 (3.1415 3.1415)) which is a bit more intuitive, I think, though not precisely an inverse to subst-if, which as you suggested, can be quite non-intuitive (and perhaps unnecessary).... No, I think if [n]subst-if-not stay in the language then their definitions should not change. Conses are just as valid as any other data, and changing their definition could make them even more confusing. I'm not (currently) advocating removing them from the language. I am advocating documenting this pitfall. It may want to say that "we" currently believe code is easier to write, undersetand and maintain if [n]subst-if is used intead of [n]subst-if-not and give the example (nsubst-if 3.1415 #'(lambda (item) (and item (atom item) (not (numberp item)))) item-list) The screw here is that NIL in the CAR isn't distinguished from NIL in the CDR, which may be a more fundamental problem. Doing the CDR, even though it may be NIL has several valid applications, so it shouldn't be dismissed lightly.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 7 Jul 86 10:27:38 EDT Received: from BBNCC5.ARPA by SU-AI.ARPA with TCP; 7 Jul 86 07:11:51 PDT To: Brad Miller cc: "David C. Plummer" , Common-Lisp@su-ai.ARPA Subject: Re: subst-if-not and nsubst-if-not, programming folk-lore In-reply-to: Your message of Sun, 6 Jul 86 14:48 EDT. <860706144822.2.MILLER@UR-BEECHNUT.ARPA> Date: 07 Jul 86 10:04:29 EDT (Mon) From: Andy Latto Date: Sun, 29 Jun 86 19:42 EDT From: David C. Plummer These are really neat functions, and counterintuitive to boot. [...] Now, when one tries subst-if-not, one gets a small surprise until one thinks about it a bit: (let* ((item-list '(numbers (1.0 2 5/3) symbols (foo bar))) (new (subst-if-not '3.1415 #'numberp item-list))) (values new item-list)) => 3.1415 (NUMBERS (1.0 2 5/3) SYMBOLS (FOO BAR)) and nsubst-if-not gives the same thing [...] , i.e., the list is NOT destructed. A careful reading explains why: the item-list is indeed not a number, and therefore it gets substituted (but you can't substitute the entire list, so you don't modify it). [...] Good point. To point out the obvious: perhaps [n]subst-if-not should not try to match subtrees? (which would include nil cdrs)..... That would still give a useful function on leaves.... Your example would have been evaluated to: (3.1415 (1.0 2 5/3) 3.1415 (3.1415 3.1415)) which is a bit more intuitive, I think, though not precisely an inverse to subst-if, which as you suggested, can be quite non-intuitive (and perhaps unnecessary).... Brad Miller miller@rochester.arpa miller@ur-acorn.arpa I think this would be a bad idea. Consistency is important. Everywhere else that there are two functions that differ only by a -not in the name of one, the only difference in the semantics is to reverse the test. This is as it should be. Conceptually, there are four possible subst-if-like functions, depending on whether the the test is positive or negative and whether the substitution applies to subtrees or only to leaves. These could have names like subst-if, subst-if-not, leaf-subst, and leaf-subst-if-not. If you think that the only two of these worthy of being part of common lisp are subst-if and leaf-subst-if-not, I would disagree with you, but not strongly. If you think that these functions should exist under the names subst-if and subst-if-not, and everyone should remember that -not automatically implies leaf-, I would disagree with you strongly. leaf-subst-if and its relatives might be useful, but they're easy to simulate with test functions like (lambda (foo) (and (atom foo) (whatever foo))), though this would match nil cdr's. Do we really need them? Andy Latto alatto@bbn.arpa  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 7 Jul 86 10:19:10 EDT Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 7 Jul 86 07:08:34 PDT Received: from boethius by Godot.Think.COM via CHAOS; Mon, 7 Jul 86 10:08:44 edt Date: Mon, 7 Jul 86 10:09 EDT From: Guy Steele Subject: Re: Argument lists: a proposal to shoot at To: masinter.pa@Xerox.COM Cc: gls@AQUINAS, common-lisp@SU-AI.ARPA In-Reply-To: <860703-170554-2046@Xerox> Message-Id: <860707100936.1.GLS@BOETHIUS.THINK.COM> Date: 3 Jul 86 17:04 PDT From: masinter.pa@Xerox.COM if min and max were like start and end, the "max" would be exclusive, not inclusive. That is correct, and if I were to press my proposal further I would adopt that change. --Guy  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 7 Jul 86 10:14:29 EDT Received: from SCRC-QUABBIN.ARPA by SU-AI.ARPA with TCP; 7 Jul 86 07:04:50 PDT Received: from FIREBIRD.SCRC.Symbolics.COM by QUABBIN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 16663; Mon 7-Jul-86 10:03:32 EDT Date: Mon, 7 Jul 86 10:03 EDT From: David C. Plummer Subject: DECLARE SPECIAL Considered Confusing To: Pavel.pa@Xerox.COM, Common-Lisp@SU-AI.ARPA In-Reply-To: <860705-165424-2715@Xerox> Message-ID: <860707100308.8.DCP@FIREBIRD.SCRC.Symbolics.COM> Date: 5 Jul 86 16:54 PDT From: Pavel.pa@Xerox.COM What do people think? It would appear that some implementations already work this way. I agree. Consider LET to be a macro that turns into LAMBDA: (let ((foo (1+ foo))) (declare (special foo)) foo) => ((lambda (foo) (declare (special foo)) foo) (1+ foo)) [I think this is what MacLisp actually did (does?).] The scoping here is clear: the foo in (1+ foo) is outside the scope of the declaration.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 6 Jul 86 18:10:58 EDT Date: 06 Jul 86 1501 PDT From: Dick Gabriel Subject: Object-Oriented Programming Meeting at L&FP To: common-lisp@SU-AI.ARPA There will be a meeting on the topic of Object-Oriented Programming right after the Lisp and Functional Programming Conference. The date is Wednesday, August 6, at 2pm, in a room to be announced. This audience might also be interested in the panel session, chaired by Peter Deutsch, on Object-Oriented Programming, to be held from 3:45pm until 5:45pm on Tuesday, August 5, at the Lisp Conference. The distinguished panel includes these folks: Danny Bobrow, Xerox PARC Gary Drescher, MIT David Moon, Symbolics Alan Snyder, HP -rpg-  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 6 Jul 86 15:00:33 EDT Received: from UR-ACORN.ARPA by SU-AI.ARPA with TCP; 6 Jul 86 11:51:52 PDT Received: from UR-BEECHNUT.ARPA by UR-ACORN.ARPA via INTERNET with SMTP id 30083; 6 Jul 86 14:47:48-EDT Date: Sun, 6 Jul 86 14:48 EDT From: Brad Miller Subject: subst-if-not and nsubst-if-not, programming folk-lore To: David C. Plummer cc: Common-Lisp@SU-AI.ARPA Fcc: ACORN:>miller>mail>mailout.file In-Reply-To: <860629194244.5.DCP@FIREBIRD.SCRC.Symbolics.COM> Message-ID: <860706144822.2.MILLER@UR-BEECHNUT.ARPA> Date: Sun, 29 Jun 86 19:42 EDT From: David C. Plummer These are really neat functions, and counterintuitive to boot. One of our documentation people tried this: [...] Now, when one tries subst-if-not, one gets a small surprise until one thinks about it a bit: (let* ((item-list '(numbers (1.0 2 5/3) symbols (foo bar))) (new (subst-if-not '3.1415 #'numberp item-list))) (values new item-list)) => 3.1415 (NUMBERS (1.0 2 5/3) SYMBOLS (FOO BAR)) and nsubst-if-not gives the same thing [...] , i.e., the list is NOT destructed. A careful reading explains why: the item-list is indeed not a number, and therefore it gets substituted (but you can't substitute the entire list, so you don't modify it). What the person probably wanted is to replace the non-null atomic leafs. I'm not sure what to think. One thing I'm thinking is that (n)subst-if-not is too counter-intuitive to be worth having in the language, even for completeness. At the very list, I think the book/manual should carefully discuss this issue to people don't get confused for years. Good point. To point out the obvious: perhaps [n]subst-if-not should not try to match subtrees? (which would include nil cdrs)..... That would still give a useful function on leaves.... Your example would have been evaluated to: (3.1415 (1.0 2 5/3) 3.1415 (3.1415 3.1415)) which is a bit more intuitive, I think, though not precisely an inverse to subst-if, which as you suggested, can be quite non-intuitive (and perhaps unnecessary).... Brad Miller miller@rochester.arpa miller@ur-acorn.arpa  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 6 Jul 86 14:21:57 EDT Received: from SCRC-QUABBIN.ARPA by SU-AI.ARPA with TCP; 6 Jul 86 11:12:31 PDT Received: from FIREBIRD.SCRC.Symbolics.COM by QUABBIN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 14598; Sun 29-Jun-86 19:42:30 EDT Date: Sun, 29 Jun 86 19:42 EDT From: David C. Plummer Subject: subst-if-not and nsubst-if-not, programming folk-lore To: Common-Lisp@SU-AI.ARPA Message-ID: <860629194244.5.DCP@FIREBIRD.SCRC.Symbolics.COM> These are really neat functions, and counterintuitive to boot. One of our documentation people tried this: (let* ((item-list '(numbers (1.0 2 5/3) symbols (foo bar))) (new (subst-if '3.1415 #'numberp item-list))) (values new item-list)) => (NUMBERS (3.1415 3.1415 3.1415) SYMBOLS (FOO BAR)) (NUMBERS (1.0 2 5/3) SYMBOLS (FOO BAR)) which is correct, numbers were substituted. Similarly, nsubst-if works as expected: (let* ((item-list '(numbers (1.0 2 5/3) symbols (foo bar))) (new (nsubst-if '3.1415 #'numberp item-list))) (values new item-list)) => (NUMBERS (3.1415 3.1415 3.1415) SYMBOLS (FOO BAR)) (NUMBERS (3.1415 3.1415 3.1415) SYMBOLS (FOO BAR)) Now, when one tries subst-if-not, one gets a small surprise until one thinks about it a bit: (let* ((item-list '(numbers (1.0 2 5/3) symbols (foo bar))) (new (subst-if-not '3.1415 #'numberp item-list))) (values new item-list)) => 3.1415 (NUMBERS (1.0 2 5/3) SYMBOLS (FOO BAR)) and nsubst-if-not gives the same thing (let* ((item-list '(numbers (1.0 2 5/3) symbols (foo bar))) (new (nsubst-if-not '3.1415 #'numberp item-list))) (values new item-list)) => 3.1415 (NUMBERS (1.0 2 5/3) SYMBOLS (FOO BAR)) , i.e., the list is NOT destructed. A careful reading explains why: the item-list is indeed not a number, and therefore it gets substituted (but you can't substitute the entire list, so you don't modify it). What the person probably wanted is to replace the non-null atomic leafs. I'm not sure what to think. One thing I'm thinking is that (n)subst-if-not is too counter-intuitive to be worth having in the language, even for completeness. At the very list, I think the book/manual should carefully discuss this issue to people don't get confused for years.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 6 Jul 86 14:21:52 EDT Received: from SCRC-QUABBIN.ARPA by SU-AI.ARPA with TCP; 6 Jul 86 11:13:05 PDT Received: from FIREBIRD.SCRC.Symbolics.COM by QUABBIN.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 14719; Mon 30-Jun-86 11:54:52 EDT Date: Mon, 30 Jun 86 11:55 EDT From: David C. Plummer Subject: Two functions for everything? To: SANDRA , common-lisp@SU-AI.ARPA In-Reply-To: <12218956472.19.LOOSEMORE@UTAH-20.ARPA> Message-ID: <860630115511.0.DCP@FIREBIRD.SCRC.Symbolics.COM> Date: Mon 30 Jun 86 08:52:34-MDT From: SANDRA From: DCP@QUABBIN.SCRC.Symbolics.COM (David C. Plummer) This is bogus folks. All you need is two entrypoints: one which doesn't check anything, and one which checks what it needs to. They then join. Safety 0 (at compile time) causes functions to call the the don't-check-anything entrypoint, and safety > 0 causes functions to call the one that checks. Hell, you could have a different entrypoint for each setting of safety. Yeah, but where in CLtL do we provide a way to make functions with multiple entry points? I certainly don't want to have to hand-code every single function that does optional error checking in assembly language (or whatever). The point I was trying to make was that, if we are serious about making multiple levels of error checking part of the language, we should also provide some high-level constructs for specifying what error checking goes on when. Multiple entry points would be one way to implement such a construct.... Why do you think CLtL has to specify how this is done? It is completely in the domain of the implementation of the compiler, the linker and the compiled function format. The only thing CLtL needs to specify is how to get what you want, and I think it already has that with the safety setting.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 5 Jul 86 20:02:58 EDT Received: from XEROX.COM by SU-AI.ARPA with TCP; 5 Jul 86 16:54:09 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 05 JUL 86 16:54:24 PDT Date: 5 Jul 86 16:54 PDT From: Pavel.pa@Xerox.COM Subject: DECLARE SPECIAL Considered Confusing To: Common-Lisp@SU-AI.ARPA Message-ID: <860705-165424-2715@Xerox> I have a question concerning some ambiguity in the description of the scope of a special declaration inside a LET. Consider this code: (setq foo 6) (let ((foo 7)) (let ((foo (1+ foo))) (declare (special foo)) foo)) Both Symbolics and CLISP return 8 for this, but VAXLISP returns 7. Clearly, the question is whether or not the special declaration covers the init-form of the enclosing LET or just the bindings themselves. According to the ``nonsense'' example in CLtL, page 155, the reference to ``foo'' in the call to 1+ should be special. The GLS clarification for page 159, however, seems to support a different philosophy: ``(*) 159 Clarify that in the following example (defun foo (x) (declare (inline bar)) (bar x) ; first (flet ((bar (z) (bar (+ z 1)))) ; second (bar x)) ; third (bar x) ; fourth the first, second and fourth calls to BAR are affected by the INLINE declaration, but not the third one.'' This seems to support the view that the init-form of a binding is in a scope outside of that of the binding itself and the body of the LET (or FLET or ...). I prefer this view. I would like to propose the following rule for the scope of declarations in binding forms: ``A declaration in a binding form (such as LET) affects the body of the form and the bindings themselves. It does not affect the init-forms for the bindings; they are in the same scope as the binding form as a whole.'' This rule has the advantage (over the rule given for the nonsense example) that the scope of the declarations is the same as the scope of the bindings. Thus, for the nonsense example: (defun nonsense (k x z) (foo z x) ;First call to foo (let ((j (foo k x)) ;Second call to foo (x (* k k))) (declare (inline foo) (special x z)) (foo x j z))) ;Third call to foo the inline declaration affects only the third call to foo (not the second) and only the references to x and z in the third call to foo are special (not the reference to x in the second call). There would be only two exceptions to this rule: -- In a LABELS binding, references in the definitions of the functions to the very functions being bound would be affected by any declarations affecting the bindings themselves. This makes sense because of the recursive quality of the binding. -- The PROCLAIM function establishes pervasive declarations, covering all bindings of and references to the symbols named. Such declarations can, of course, be countermanded by local declarations or later proclamations. What do people think? It would appear that some implementations already work this way. Pavel Curtis Xerox AIS  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 3 Jul 86 21:52:56 EDT Received: from XEROX.COM by SU-AI.ARPA with TCP; 3 Jul 86 14:16:56 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 03 JUL 86 14:16:05 PDT Date: 3 Jul 86 14:15 PDT From: masinter.pa@Xerox.COM Subject: Re: Types of Functions In-reply-to: Fahlman%C.CS.CMU:EDU:Xerox's message of 2 Jul 86 17:32 To: Common-Lisp@su-ai.ARPA Message-ID: <860703-141605-1874@Xerox> The problem is that the "function" types isn't a very good member of the type lattice. For example, "functionp" is true of lists whose car is lambda. In this case, "functionp" is a much more dynamic property. With most data types, (typecase x (regulartype ... compute ... use x ... )) the "use x" can assume that x is still "regulartype". This is currently true of all types except those defined with "satisfies". In this example, if "compute" were to (setf (car x) 'not-lambda), functionp would no longer be true. Given the existence of "satisfies" type specifiers, (deftype function () '(satisfies functionp)) Note also that symbols satisfy "functionp". ("functionp is always true of symbols, lists whose car is the symbol lambda, any value returned by the function special form, and any values returned by the function compile... "). This is dangerous to those who might write (typecase foo (function ...) (symbol ...) ...) Finally, it is an implementation dependent type like "fixnum", whose use is discouraged. Functions aren't a first-class type in Common Lisp, and wishing it so (or allowing 'function in a typep) won't make it so.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 3 Jul 86 11:50:54 EDT Received: from HPLABS.HP.COM by SU-AI.ARPA with TCP; 3 Jul 86 08:41:25 PDT Received: from hplsny by hplabs.HP.COM ; Thu, 3 Jul 86 08:39:46 pdt Received: by hplsny ; Thu, 3 Jul 86 08:39:28 pdt From: Alan Snyder Message-Id: <8607031539.AA03068@hplsny> Date: Thursday, July 3, 1986 08:39:19 Subject: Re: Argument lists To: Fahlman@C.CS.CMU.EDU Cc: common-lisp@su-ai.ARPA In-Reply-To: Your message of 2-Jul-86 22:46:00 X-Sent-By-Nmail-Version: 04-Nov-84 17:14:46 I'm still not convinced that speed is of critical importance here, but it is clear to me that your perception of the need for this possibly faster way of getting parameter info is stronger than my desire to reduce the number of functions by one. Maybe you're right. I give up. Revised proposal: Let's add both FUNCTION-PARAMETERS and FUNCTION-PARAMETER-RANGE. Can anybody not live with THAT? -- Scott Sorry, I tried, but I can't resist... Isn't the proper "Common Lisp" solution to this issue to say that the compiler ought to recognize calls to FUNCTION-PARAMETERS that only use the first two values and, in implementations where FUNCTION-PARAMETER-RANGE would be faster, convert those calls to calls on SYS:FUNCTION-PARAMETER-RANGE (now an internal function)? Alan -------  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 3 Jul 86 09:39:09 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 3 Jul 86 06:30:35 PDT Received: ID ; Thu 3 Jul 86 09:17:50-EDT Date: Thu, 3 Jul 1986 09:17 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: NGALL@BBNG.ARPA Cc: Common-Lisp@SU-AI.ARPA Subject: Types of Functions In-reply-to: Msg of 3 Jul 1986 02:09-EDT from NGALL at G.BBN.COM (typep foo 'function) causes an error to be signalled according to page 47. Perhaps that is why functionp is not defined in terms of it? :-) I'm not sure what the scope of your :-) keyword is meant to be (this is not defined in the current spec), but I have always read the passage on page 47 as outlawing Typep on the complex list form of the Function type-specifier. The wording here is ambiguous about whether the simple form, (typep foo 'function), is legal, and I see no reason for this not to be legal. I guess this is another thing we need to clarify. -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 3 Jul 86 09:32:14 EDT Received: from LIVE-OAK.LCS.MIT.EDU by SU-AI.ARPA with TCP; 3 Jul 86 06:24:10 PDT Received: from GOLD-HILL-ACORN.DialNet.Symbolics.COM by MIT-LIVE-OAK.ARPA via DIAL with SMTP id 3621; 3 Jul 86 09:26:37-EDT Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 27120; Thu 3-Jul-86 09:26:06-EDT Date: Thu, 3 Jul 86 09:23 EST Sender: mike@a To: NGALL@G.BBN.COM From: mike%gold-hill-acorn@mit-live-oak.arpa Subject: Re: Types of Functions Cc: Fahlman@C.CS.CMU.EDU, Rice@SUMEX-AIM.ARPA, Common-Lisp@SU-AI.ARPA ...brain damaged mail program strikes again,.. and I forgot to sign my reply. You'll notice that the from field of my last note contains only mike@a, to which you cannot reply. I am: mike beckerle Gold Hill Computers send replies to: mike%gold-hill-acorn@mit-live-oak.arpa  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 3 Jul 86 09:28:47 EDT Received: from LIVE-OAK.LCS.MIT.EDU by SU-AI.ARPA with TCP; 3 Jul 86 06:19:34 PDT Received: from GOLD-HILL-ACORN.DialNet.Symbolics.COM (DIAL|DIAL|4925473) by MIT-LIVE-OAK.ARPA via DIAL with SMTP id 3620; 3 Jul 86 09:21:40-EDT Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 27118; Thu 3-Jul-86 09:21:34-EDT Date: Thu, 3 Jul 86 09:18 EST From: mike@a To: NGALL@G.BBN.COM Subject: Re: Types of Functions Cc: Fahlman@C.CS.CMU.EDU, Rice@SUMEX-AIM.ARPA, Common-Lisp@SU-AI.ARPA Date: 3 Jul 1986 02:09-EDT From: NGALL@G.BBN.COM Why is it that in CLtL (p 76) Functionp is the only type predicate which is not specified to be equivalent to (typep foo 'function)? -------------------- (typep foo 'function) causes an error to be signalled according to page 47. Perhaps that is why functionp is not defined in terms of it? :-) -- Nick On pg. 47, the spec states that type SIGNATURES cannot be used to discriminate types. However, the type "function" is not a signature. Clearly (typep foo '(function (...) ...)) shouldn't be allowed since it is obvious that one cannot decide it, or even try to decide it in any reasonable way. For example (typep foo (satisfies #'my-type-predicate)) is reasonable since one can at least run the satisfies function on the object "foo". But in (typep foo '(function ((satisfies #'my-type-predicate)) t))), there is absolutely no way to know, and nothing to try to run to find out. However, there is no reason why (typep foo 'function) should cause any problems. It should be equivalent to (functionp foo).  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 3 Jul 86 09:17:26 EDT Received: from LIVE-OAK.LCS.MIT.EDU by SU-AI.ARPA with TCP; 3 Jul 86 06:08:06 PDT Received: from GOLD-HILL-ACORN.DialNet.Symbolics.COM (DIAL|DIAL|4925473) by MIT-LIVE-OAK.ARPA via DIAL with SMTP id 3618; 3 Jul 86 09:10:26-EDT Received: from VENEZUELA.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 27113; Thu 3-Jul-86 08:58:37-EDT Date: Thu, 3 Jul 86 08:56 EST From: JerryB@a To: KMP@SCRC-STONY-BROOK.ARPA Subject: Speed of FUNCTION-PARAMETER-RANGE Cc: NGALL@G.BBN.COM, COMMON-LISP@SU-AI.ARPA Date: Thu, 3 Jul 86 03:12 EDT From: Kent M Pitman Date: 3 Jul 1986 02:29-EDT From: NGALL@G.BBN.COM Out of curiosity, why do you feel the need for a 'fast' version of function-parameters? I got the feeling that most people thought that it would not be used in time-critical code. Most people thought that. I guess they were wrong. I have counterexamples. I agree with KMP, that a fast version is necessary to determine just the min and max number of parameters a function takes.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 3 Jul 86 05:33:15 EDT Received: from WISCVM.WISC.EDU by SU-AI.ARPA with TCP; 3 Jul 86 02:25:59 PDT Received: from (DESMEDT)HNYKUN52.BITNET by WISCVM.ARPA on 07/03/86 at 04:26:13 CDT Date: Thu, 3 Jul 86 10:52 N From: Subject: withdrawal from mailing list To: common-lisp@su-ai.arpa X-Original-To: common-lisp@su-ai.arpa Please remove my name from this mailing list. My only real interest is in object-oriented extensions of Common LISP. If there happens to be a separate discussion group dedicated to this topic, please let me know. Koenraad De Smedt  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 3 Jul 86 03:22:56 EDT Received: from [192.10.41.41] by SU-AI.ARPA with TCP; 3 Jul 86 00:13:29 PDT Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 34985; Thu 3-Jul-86 03:12:49 EDT Date: Thu, 3 Jul 86 03:12 EDT From: Kent M Pitman Subject: Speed of FUNCTION-PARAMETER-RANGE To: NGALL@G.BBN.COM cc: COMMON-LISP@SU-AI.ARPA In-Reply-To: <[G.BBN.COM] 3-Jul-86 02:29:33.NGALL> References: <860702222311.3.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM> Message-ID: <860703031210.9.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM> Date: 3 Jul 1986 02:29-EDT From: NGALL@G.BBN.COM Out of curiosity, why do you feel the need for a 'fast' version of function-parameters? I got the feeling that most people thought that it would not be used in time-critical code. Most people thought that. I guess they were wrong. I have counterexamples. If it is not going to be used in tight-loops, do we really need the separate 'speed' functionality? Yes. In embedded languages which use their own interpreters rather than calling EVAL (eg, Macsyma, Scheme, ...), you may wish to enforce number-of-args checking even if the implementation you are running is does not. Also, Macsyma has a situation where it's been asked to defer the application of certain kinds of functions and just return what we call a noun form. ie, (SIN X) where X is 3 might yield the symbolic expression (SIN 3) rather a numeric approximation such as 0.14112002 . There's a command that later asks Macsyma to go through and evaluate nounds. Even though the function for a noun doesn't get applied at the time the rest of an expression is being evaluated, it may be desirable at the interpreter to go ahead and do a preliminary check for correct number of arguments. Both of these situations want to be very fast because they occur in MEVAL, the Macsyma analog of EVAL, and can consequently happen quite often. If you or anyone else has further queries, I'll gladly answer them, but I suggest we carry them on in private mail. I think I've made my point and my guess is that most readers are tired of this line of discussion by now.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 3 Jul 86 02:41:33 EDT Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 2 Jul 86 23:30:04 PDT Date: 3 Jul 1986 02:29-EDT Sender: NGALL@G.BBN.COM Subject: Re: Argument lists From: NGALL@G.BBN.COM To: KMP@SCRC-STONY-BROOK.ARPA Cc: Fahlman@C.CS.CMU.EDU, Common-Lisp@SU-AI.ARPA Message-ID: <[G.BBN.COM] 3-Jul-86 02:29:33.NGALL> In-Reply-To: <860702222311.3.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM> Date: Wed, 2 Jul 86 22:23 EDT From: Kent M Pitman To: Fahlman@CMU-CS-C.ARPA Subject: Argument lists In-Reply-To: Message-ID: <860702222311.3.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM> A single function FUNCTION-PARAMETER-RANGE which returns two values is indeed a fine idea. (I don't like -COUNT, though, because it suggests a single return value.) Your claim that having this function "adds clutter" is unsubstantiated in my mind. The function is simple, well-defined, and useful to a definable subset of people. MACSYMA already had such a thing which was implemented by some of the grungiest system-dependent code you could imagine. If you think it duplicates functionality with this other function, it's probably because your view of functionality is too intimately tied to data flow. Some functions want part of their contract to be that they are fast. If you overgeneralize their return values, as I claim is happening here, you add "data flow" functionality, but you may end up forcing some implementations to be slow on an operation that they didn't need to be slow at, or you may force some implementations to have to do a radical redesign of their storage technique for arglists in order to achieve the required speed. I'd just as soon we didn't force such redesigns for reasons like this where we can so trivially keep from doing this. Out of curiosity, why do you feel the need for a 'fast' version of function-parameters? I got the feeling that most people thought that it would not be used in time-critical code. If it is not going to be used in tight-loops, do we really need the separate 'speed' functionality? Also, I would be interested to hear from any implementor (preferably the one who would be responsible for implementing FUNCTION-PARAMETERS and FUNCTION-PARAMETER-RANGE) who thinks they would implement FUNCTION-PARAMETERS in such a way as to make it, say, an order of magnitude slower. Anyway, if it comes to a vote and if I had a vote, I would vote against adding FUNCTION-PARAMETER-RANGE. -- Nick  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 3 Jul 86 02:21:17 EDT Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 2 Jul 86 23:10:15 PDT Date: 3 Jul 1986 02:09-EDT Sender: NGALL@G.BBN.COM Subject: Re: Types of Functions From: NGALL@G.BBN.COM To: Fahlman@C.CS.CMU.EDU Cc: Rice@SUMEX-AIM.ARPA, Common-Lisp@SU-AI.ARPA Message-ID: <[G.BBN.COM] 3-Jul-86 02:09:58.NGALL> In-Reply-To: Date: Wed, 2 Jul 1986 19:56 EDT From: "Scott E. Fahlman" To: James Rice Subject: Types of Functions In-Reply-To: Msg of 2 Jul 1986 13:55-EDT from James Rice Message-ID: Why is it that in CLtL (p 76) Functionp is the only type predicate which is not specified to be equivalent to (typep foo 'function)? Good question. I don't remember, and can't think of any good reason for this omission. Does anyone else remember what's going on here? It is too glaringly different from the neighboring descriptions to be an inadvertent omission. Maybe it is just the result of the confusion about what we mean by function, which got tightened up a bit after this section was written and needs to be tightened up still more. Once that is done, I see no reason for Functionp not to be equivalent to Typep of Funciton. -- Scott -------------------- (typep foo 'function) causes an error to be signalled according to page 47. Perhaps that is why functionp is not defined in terms of it? :-) -- Nick  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 2 Jul 86 23:08:20 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 2 Jul 86 19:57:31 PDT Received: ID ; Wed 2 Jul 86 22:57:06-EDT Date: Wed, 2 Jul 1986 22:57 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Kent M Pitman Cc: Common-Lisp@SU-AI.ARPA Subject: Argument lists In-reply-to: Msg of 2 Jul 1986 22:23-EDT from Kent M Pitman ...I hope we will make it explicit that &AUX specs should not be visible in the list returned by ARGLIST. *IF* we add ARGLIST to the spec. There seems to be very little enthusiasm for adding ARGLIST in raw form. By the way, everyone keeps making vague allusions to the new condition system as if it could somehow solve the issue of argument checking. You shouldn't hope for magical cures from my camp. Well, once we've decided on an error system in general, then we have to decide what kind of error we signal for various problems, such as "too many/few args", and what information has to be passed to the handler. This is what people are waiting to see. You may not plan to make proposals in this area, but your error proposal is a prerequisite for discussing the signalling of specific errors in details. Nobody expects a magical way of detecting errors at no cost, but the amount of stuff that must be included in the signal certainly influences the cost of requiring certain checks. -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 2 Jul 86 22:55:38 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 2 Jul 86 19:46:22 PDT Received: ID ; Wed 2 Jul 86 22:46:06-EDT Date: Wed, 2 Jul 1986 22:46 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Kent M Pitman Cc: Common-Lisp@SU-AI.ARPA Subject: Argument lists In-reply-to: Msg of 2 Jul 1986 22:23-EDT from Kent M Pitman Nobody has ever accused me of consorting with dataflow ideas before. I guess one needs a thick skin to make it in this job... I'm still not convinced that speed is of critical importance here, but it is clear to me that your perception of the need for this possibly faster way of getting parameter info is stronger than my desire to reduce the number of functions by one. Maybe you're right. I give up. Revised proposal: Let's add both FUNCTION-PARAMETERS and FUNCTION-PARAMETER-RANGE. Can anybody not live with THAT? -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 2 Jul 86 22:36:08 EDT Received: from [192.10.41.41] by SU-AI.ARPA with TCP; 2 Jul 86 19:24:51 PDT Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 34906; Wed 2-Jul-86 22:23:53 EDT Date: Wed, 2 Jul 86 22:23 EDT From: Kent M Pitman Subject: Argument lists To: Fahlman@CMU-CS-C.ARPA cc: Common-Lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860702222311.3.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM> A single function FUNCTION-PARAMETER-RANGE which returns two values is indeed a fine idea. (I don't like -COUNT, though, because it suggests a single return value.) Your claim that having this function "adds clutter" is unsubstantiated in my mind. The function is simple, well-defined, and useful to a definable subset of people. MACSYMA already had such a thing which was implemented by some of the grungiest system-dependent code you could imagine. If you think it duplicates functionality with this other function, it's probably because your view of functionality is too intimately tied to data flow. Some functions want part of their contract to be that they are fast. If you overgeneralize their return values, as I claim is happening here, you add "data flow" functionality, but you may end up forcing some implementations to be slow on an operation that they didn't need to be slow at, or you may force some implementations to have to do a radical redesign of their storage technique for arglists in order to achieve the required speed. I'd just as soon we didn't force such redesigns for reasons like this where we can so trivially keep from doing this. By the way, of the implementations which cache a constant list, I wonder how many of them cache a list containing the &AUX spec. I hope we will make it explicit that &AUX specs should not be visible in the list returned by ARGLIST. They are not part of the external interface and my experience is that I always end up writing the same idiom, namely: (LET ((AUXL (MEMBER '&AUX ARGL))) (IF AUXL (LDIFF ARGL AUXL) ARGL)) I've done this enough times in destructuring LAMBDA lists myself that I'd just as soon it were done for me now that we're talking about having a system supplied tool for extracting arglists. However, I wouldn't want my FUNCTION-PARAMETER-RANGE function to have to wait for the MEMBER and LDIFF if I was just going to throw away the result anyway. Anyway, the real point is that it's not fair for you to make claims about comparative speeds or even about things probably being fast unless you have the data to back up such claims. My experience with trying to write portable CL programs thus far suggests that the only thing you can depend on are things that are unambiguously specified in CLtL; if something is not specified, it may vary widely. Speed is certainly no exception. With regard to your suggestion that the best way to proceed is to hope that we reach closure on the issue of argument checking, I don't think that's a good idea. I see no obvious reason for near-term concensus on that issue and would prefer to assume that FUNCTION-PARAMETER-RANGE will go in unless I'm pleasantly surprised, rather than vice versa. Also, resolution of that issue won't be adequate for my purposes unless number-of-argument checking is required in both interpreted and compiled code. By the way, everyone keeps making vague allusions to the new condition system as if it could somehow solve the issue of argument checking. You shouldn't hope for magical cures from my camp. The condition system only says what happens after you signal an error. It doesn't get involved at all in the decision of when to signal and when not to. The issue of whether to do number of argument checking (or any other kind of error checking) is only peripherally related to the issue of how errors which result from such checks are to be signalled/corrected.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 2 Jul 86 21:03:10 EDT Received: from XEROX.COM by SU-AI.ARPA with TCP; 2 Jul 86 17:52:22 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 02 JUL 86 16:59:42 PDT Date: 2 Jul 86 16:09 PDT From: Daniels.pa@Xerox.COM Subject: Re: underspecified type-of In-reply-to: Masinter.pa's message of 2 Jul 86 13:47 PDT To: Masinter.pa@Xerox.COM cc: common-lisp@su-ai.ARPA Message-ID: <860702-165942-1012@Xerox> Seems to me that you should only be able to do that if you've declared it as (:TYPE VECTOR). -- Andy. --  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 2 Jul 86 20:52:47 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 2 Jul 86 17:36:57 PDT Received: ID ; Wed 2 Jul 86 20:34:31-EDT Date: Wed, 2 Jul 1986 20:34 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Kent M Pitman Cc: common-lisp@SU-AI.ARPA Subject: Argument lists In-reply-to: Msg of 1 Jul 1986 19:36-EDT from Kent M Pitman (In response to the Function-Parameters proposal...) No. This does not assure adequately fast access to just the max and min information for use in embedded interpreters. The other info might be expensive to cons and it may be getting consed for no good reason. I feel that either there should be two functions, or the function should be given arguments saying kinds of info you wanted so that no time was wasted in consing in situations where speed matters. This wouldn't be so essential if implementations were always required to signal an error in an wrong number of arguments situation -and- if we had the error system in place. I expect the latter to happen in the near future, but am not so sure the former will go through, so I really think fast access to just the numbers part is important. I suppose we could add Function-Parameter-Count along with Function-Parameters. The former would return two values: min args and max args, with the second value being NIL if there is an &rest or &key. This is probably better than separate min and max functions, since you normally want both values and it's faster to get both at once. This does add clutter, however, so I would prefer not to add this function unless we really need it. I think it is of very marginal value for several reasons: 1. Except in the case where the function to be called takes keywords, the difference in speed between the two calls will be very small compared to the total cost of a call in an embedded interpreter. 2. I suspect that most implementations will return a pre-stored keyword list rather than consing up a keyword list on the fly. 3. As you point out, the checking you would do with the Function-Parameter-Count function is redundant with the checking that most implementations now do, and that may be required of all implementations (in the interpreter) if this proposal passes. Maybe the best way to proceed is to decide now about Function-Parameters, and for you to raise the issue of Function-Parameter-Count (or whatever) if you still believe this is needed after the error system and related issues are firmed up. -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 2 Jul 86 20:06:11 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 2 Jul 86 16:56:49 PDT Received: ID ; Wed 2 Jul 86 19:56:53-EDT Date: Wed, 2 Jul 1986 19:56 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: James Rice Cc: Common-Lisp@SU-AI.ARPA Subject: Types of Functions In-reply-to: Msg of 2 Jul 1986 13:55-EDT from James Rice Why is it that in CLtL (p 76) Functionp is the only type predicate which is not specified to be equivalent to (typep foo 'function)? Good question. I don't remember, and can't think of any good reason for this omission. Does anyone else remember what's going on here? It is too glaringly different from the neighboring descriptions to be an inadvertent omission. Maybe it is just the result of the confusion about what we mean by function, which got tightened up a bit after this section was written and needs to be tightened up still more. Once that is done, I see no reason for Functionp not to be equivalent to Typep of Funciton. -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 2 Jul 86 18:29:02 EDT Received: from HOPKINS-EECS-BRAVO.ARPA by SU-AI.ARPA with TCP; 2 Jul 86 15:12:13 PDT Date: Wed, 2 Jul 86 16:06:14 EDT From: Marty Hall To: common-lisp@su-ai.ARPA Subject: Removal from mailing list. Oops! I goofed. I thought this list was kinda the Arpa equivalent of net.lang.lisp, and my mailbox here is accumulating too many messages... If you wouldn't mind, please remove my name from your mailing list. Thanks! -Marty Hall.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 2 Jul 86 17:32:58 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 2 Jul 86 14:14:51 PDT Received: ID ; Wed 2 Jul 86 17:06:58-EDT Date: Wed, 2 Jul 1986 17:06 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Masinter.pa@XEROX.COM Cc: common-lisp@SU-AI.ARPA Subject: underspecified type-of In-reply-to: Msg of 2 Jul 1986 16:47-EDT from Masinter.pa at Xerox.COM As you say, it is non-portable to assume that default structures are vectors. It is currently allowed for an implementation to produce structures that are subtypes of array, though there must be some way of telling that they are structures as well. Several people have suggested that we should require the default structure type to be disjoint from array, and this is on my list of things to discuss when the current set of issues simmers down a bit. -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 2 Jul 86 17:09:18 EDT Received: from XEROX.COM by SU-AI.ARPA with TCP; 2 Jul 86 13:51:15 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 02 JUL 86 13:47:47 PDT Date: 2 Jul 86 13:47 PDT From: Masinter.pa@Xerox.COM Subject: underspecified type-of In-reply-to: mike%gold-hill-acorn%mit-live-oak:ARPA:Xerox's message of 2 Jul 86 09:13 To: common-lisp@su-ai.ARPA Message-ID: <860702-134747-1026@Xerox> CommonLoops gets around the underspecified nature of type-of by defining "class-of". Class-of is defined to work for all Lisp data types, and always returns a "class" object. While implementations may have implementation-dependent classes (e.g., (class-of 3) may be different than (class-of 123123123123123123)), the classes themselves observe a well-behaved protocol, e.g., (subclassp (class-of 3) (class-named 'number)). As you point out, "type-of" is portably useful only for structures, since it would be valid for implementations to always return "t" otherwise. - - - - - - On a side note: we had a user trying to port code from another Common Lisp in which (he claims) it is legal to do (defstruct env part1 part2) (setq x (make-env)) (eq (aref x 0) 'env) While implementations can implement structures using "arrays", isn't it "an error" to call AREF on an instance of one? (E.g., should a "maximal error checking" implementation always signal an error in this case?) I've looked carefully in the defstruct section and also the section in arrays, and I don't see anything that explicitly rules this out, although it is clearly non-portable.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 2 Jul 86 15:25:59 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 2 Jul 86 12:13:58 PDT Received: ID ; Wed 2 Jul 86 15:12:38-EDT Date: Wed, 2 Jul 1986 15:12 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: ELIOT%cs.umass.edu@CSNET-RELAY.ARPA Cc: Common-Lisp@SU-AI.ARPA Subject: Portability and Code walkers In-reply-to: Msg of 30 Jun 1986 16:47-EDT from ELIOT%cs.umass.edu at CSNET-RELAY.ARPA We might or might not be able to agree to set up an absolute restriction against macros expanding into non-standard special forms. We could require everyone to provide legitimate macro-expansions that are equivalent to any non-standard special forms that the system really uses, but whether this is useful depends on what you are using the code walker for. You don't want to optimize or modify these equivalent forms and then have the system bypass the whole thing. I think that most practical solution is to provide a good extension language for your code-walker and then add templates for any unusual special forms present in a given system. The resulting system is not 100% portable, but the effort required to move it to a new system is neglegible. -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 2 Jul 86 14:13:55 EDT Received: from XEROX.COM by SU-AI.ARPA with TCP; 2 Jul 86 11:01:51 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 02 JUL 86 11:02:01 PDT Date: 2 Jul 86 10:57 PDT Sender: Gregor.pa@Xerox.COM From: Gregor Kiczales Subject: Re: Portability and Code walkers In-reply-to: ELIOT%cs.umass.edu@CSNET-RELAY.ARPA's message of Mon, 30 Jun 86 15:47 EST To: ELIOT%cs.umass.edu@CSNET-RELAY.ARPA cc: Common-Lisp@SU-AI.ARPA Message-ID: <860702-110201-4868@Xerox> It is still (all but) impossible to write a portable code walker because of the underspecification of the environment argument to macroexpand(-1). I think this problem is well understood, I just thought I would take advantage of this opportunity to bring it up so that it would be sure to be recorded in Scott's list of "issues to resolve". Something like the following is needed. There need to be constructors and accessors for the environment structures like: make-environment environment-function/macro-bindings environment-declarations There needs to be a function like variable-globally-special-p, or variable-special-p which takes a variable and an environment. It would also be nice if environments had the variable bindings in them. It may be that the accessors are not required, but the constructor is required so that a code-walker as it walks down through an flet (macrolet labels) can make a new environment corresponding to the scope of the flet.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 2 Jul 86 14:10:42 EDT Received: from SUMEX-AIM.ARPA by SU-AI.ARPA with TCP; 2 Jul 86 10:57:47 PDT Date: Wed 2 Jul 86 10:55:31-PDT From: James Rice Subject: Types of Functions To: Common-Lisp@SU-AI.ARPA Message-ID: <12219514065.67.RICE@SUMEX-AIM.ARPA> Since this is being discussed now this seems a reasonable time to ask the following :- Why is it that in CLtL (p 76) Functionp is the only type predicate which is not specified to be equivalent to (typep foo 'function)? This means that there is no guarantee that the following will work for the obvious expansion of typecase. (typecase foo (function (funcall foo bar)) (otherwise (frobulate foo bar))) It seems to me that CL should require that all implementation dependent representation types of functions, whether they be #s or whatever, should be required to be Subtypep of the type Function, and hence that (typep foo 'function) should be T for such an object. Rice -------  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 2 Jul 86 12:25:24 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 2 Jul 86 09:15:42 PDT Received: ID ; Wed 2 Jul 86 12:15:34-EDT Date: Wed, 2 Jul 1986 12:15 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: mike%gold-hill-acorn@LIVE-OAK.LCS.MIT.EDU Cc: common-lisp@SU-AI.ARPA Subject: Argument lists In-reply-to: Msg of 2 Jul 1986 12:30-EDT from mike%gold-hill-acorn at mit-live-oak.arpa The real problem with TYPE-OF is that Common Lisp types form a lattice, not a simple hierarchy. So in addition to implementation-dependent decisions about how much precision to return, there are fundamental issues about which of many possible including classes to describe. Moon's objection is an instance of this: he loooks at one way of cutting up the super class, while you look at a different one. None of this bothers TYPEP or SUBTYPEP, but TYPE-OF becomes less meaningful as the complexity of the type hierarchy increases. We nearly threw TYPE-OF out of the language last time around, but we were persuaded that we should keep it because it is of some use to people trying to browse around the system. Trying to extend it and make it "do the right thing" in all cases is a mistake. -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 2 Jul 86 11:58:08 EDT Received: from LIVE-OAK.LCS.MIT.EDU by SU-AI.ARPA with TCP; 2 Jul 86 08:42:48 PDT Received: from GOLD-HILL-ACORN.DialNet.Symbolics.COM (DIAL|DIAL|4925473) by MIT-LIVE-OAK.ARPA via DIAL with SMTP id 3554; 2 Jul 86 11:44:56-EDT Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 27010; Wed 2-Jul-86 11:33:20-EDT Date: Wed, 2 Jul 86 11:30 EST Sender: mike@a To: Moon@STONY-BROOK.SCRC.Symbolics.COM From: mike%gold-hill-acorn@mit-live-oak.arpa Subject: Argument lists Cc: common-lisp@SU-AI.ARPA Date: Tue, 1 Jul 86 13:26 EDT From: David A. Moon Date: Tue, 1 Jul 86 10:13 EST From: mike%gold-hill-acorn@mit-live-oak.arpa I still think the right thing to do is to make (type-of ) return a type signature for the function..... Doesn't this conflict with the possibility of (type-of ) telling you whether it's an interpreted or compiled function, and whether it's a closure or not, and (in some systems) whether it's generic or not? Or, as CLtL says, "(type-of object) returns an implementation-dependent result". This depends on what you think type-of is supposed to do. Maybe we need a new function name, but as far as I'm concerned, closures, (compiled or not) and functions, can all have the same type, that is (function (...) ...), as do all applicable objects. However, their representations have different types. The question really boils down to whether type-of is supposed to tell you something about the CL type lattice, or the representation of the object. My interpretation of CLtL was that type-of returns an implementation dependent result, in that the "precision" of the type might vary from one interpretation to another. The "weakest" type-of would return types of defstructs, and type t for everything else. The strongest (and certainly unachievable) type-of would return complete function signatures for all applicable objects, etc. In every case, what is returned is a CL type, not the rep type. Generics are a much harder problem, since their type signatures can be really elaborate. I assume you mean by generics the kind of overloaded operators you can get in Commonloops and New Flavors? Are the implications of these for the type system understood at all? Will CL have anything left of a type system after this kind of overloading becomes the norm, or can we somehow salvage it? ...mike beckerle Gold Hill Computers.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 2 Jul 86 11:51:03 EDT Received: from LIVE-OAK.LCS.MIT.EDU by SU-AI.ARPA with TCP; 2 Jul 86 08:37:40 PDT Received: from GOLD-HILL-ACORN.DialNet.Symbolics.COM by MIT-LIVE-OAK.ARPA via DIAL with SMTP id 3552; 2 Jul 86 11:39:22-EDT Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 27010; Wed 2-Jul-86 11:33:20-EDT Date: Wed, 2 Jul 86 11:30 EST Sender: mike@a To: Moon@STONY-BROOK.SCRC.Symbolics.COM From: mike%gold-hill-acorn@mit-live-oak.arpa Subject: Argument lists Cc: common-lisp@SU-AI.ARPA Date: Tue, 1 Jul 86 13:26 EDT From: David A. Moon Date: Tue, 1 Jul 86 10:13 EST From: mike%gold-hill-acorn@mit-live-oak.arpa I still think the right thing to do is to make (type-of ) return a type signature for the function..... Doesn't this conflict with the possibility of (type-of ) telling you whether it's an interpreted or compiled function, and whether it's a closure or not, and (in some systems) whether it's generic or not? Or, as CLtL says, "(type-of object) returns an implementation-dependent result". This depends on what you think type-of is supposed to do. Maybe we need a new function name, but as far as I'm concerned, closures, (compiled or not) and functions, can all have the same type, that is (function (...) ...), as do all applicable objects. However, their representations have different types. The question really boils down to whether type-of is supposed to tell you something about the CL type lattice, or the representation of the object. My interpretation of CLtL was that type-of returns an implementation dependent result, in that the "precision" of the type might vary from one interpretation to another. The "weakest" type-of would return types of defstructs, and type t for everything else. The strongest (and certainly unachievable) type-of would return complete function signatures for all applicable objects, etc. In every case, what is returned is a CL type, not the rep type. Generics are a much harder problem, since their type signatures can be really elaborate. I assume you mean by generics the kind of overloaded operators you can get in Commonloops and New Flavors? Are the implications of these for the type system understood at all? Will CL have anything left of a type system after this kind of overloading becomes the norm, or can we somehow salvage it? ...mike beckerle Gold Hill Computers.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 2 Jul 86 09:25:59 EDT Received: from CSNET-RELAY.ARPA by SU-AI.ARPA with TCP; 2 Jul 86 06:15:47 PDT Received: from utokyo-relay by csnet-relay.csnet id ab05841; 2 Jul 86 6:29 EDT Received: by u-tokyo.junet (4.12/4.9J-1[JUNET-CSNET]) id AA05547; Wed, 2 Jul 86 17:10:26+0900 Received: by ccut.u-tokyo.junet (4.12/6.1Junet) id AA03156; Wed, 2 Jul 86 16:48:42+0900 Date: Wed, 2 Jul 86 16:48:42+0900 From: Masayuki Ida Message-Id: <8607020748.AA03156@ccut.u-tokyo.junet> To: common-lisp@SU-AI.ARPA, ida%u-tokyo.junet@CSNET-RELAY.ARPA Subject: function keys >From common-lisp-request%csnet-relay.csnet@u-tokyo.junet Wed Jul 2 13:50:47 1986 >Date: Tue, 1 Jul 86 13:31 EDT >From: "David A. Moon" >Subject: function keys >To: Masayuki Ida >Cc: common-lisp@SU-AI.ARPA >In-Reply-To: <8607010506.AA09337@ccut.u-tokyo.junet> >Message-Id: <860701133101.2.MOON@EUPHRATES.SCRC.Symbolics.COM> >Received: from CSNet-Relay by utokyo-relay; 2 Jul 86 13:32:15-JST (Wed) > >Do function keys modify other characters that are pressed at the same >time (like SHIFT and META), or do they stand by themselves (like RETURN >and Q)? If they stand by themselves, then function keys can fit into >Common Lisp simply as twenty (or however many you have on the particular >keyboard) additional characters that are not STANDARD-CHAR-P and not >GRAPHIC-CHAR-P. I don't think the fact that some function keys are >entered with SHIFT ought to be reflected in CHAR-UPCASE and related >functions. > > Many personal computers which are also used as a low cost terminal in japan have function keys. They can be assisted by SHIFT key. It doubles the capability. For example, if there are 10 function keys, pressing function 1 at the same time with shift key acts as a function 11. Logically, function keys can be viewed as independent keys, even if they may be assisted by shift key. So, by now, I think they are the (20 or other numbers of) additional characters that are not STANDARD-CHAR-P and not GRAPHIC-CHAR-P as you stated. Masayuki Ida  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 2 Jul 86 08:43:14 EDT Received: from CSNET-RELAY.ARPA by SU-AI.ARPA with TCP; 2 Jul 86 05:34:57 PDT Received: from umass-cs by csnet-relay.csnet id bq03967; 2 Jul 86 1:42 EDT Date: Mon, 30 Jun 86 15:47 EST From: ELIOT%cs.umass.edu@CSNET-RELAY.ARPA To: Common-Lisp@SU-AI.ARPA Subject: Portability and Code walkers On P56-58 CLtL defines special forms so that it is *almost* possible to implement a portable code-walker. The loophole is that implementors are only encouraged, not required, to implement CL macros so as not to expand into implementation-dependant special forms. All of the effort to make portable code-walkers possible is useless because of this exception. I don't think this exception is neeed. Instead, implementations should use implementation-dependant optimizers to get the efficient compilation, but still provide legitimate expansions. Another way out would be to require implementations to provide macro-expansions of all special forms that can be produced by macro-expansion of any CL macro. The compiler could still use its implementation dependant knowledge of the non-standard special form, while the code walker could use the (less efficient) macro expansion. A code walker written according to the description on P57 should be included in the validation set. The code walker should be able to walk all of the code in the validation examples.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 1 Jul 86 22:47:30 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 1 Jul 86 19:35:49 PDT Received: ID ; Tue 1 Jul 86 22:35:55-EDT Date: Tue, 1 Jul 1986 22:35 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: common-lisp@SU-AI.ARPA Subject: Open keyboard, insert foot. I intended that my reply to Richard Berman's message about validation suites would go to him alone. It was sent to Common Lisp by accident. My question about whether Lucid had "reneged" was meant as a semi-humorous way of asking Richard why Lucid was not on the "expect something soon" list, when he and I both knew that Lucid intended to participate in the validation process. I would not have expressed it this way in a message meant for the wider Common Lisp community, where it could easily have been misunderstood. Since I have broadcast this poorly worded question by accident, let me also broadcast the answer: Lucid is working with the ISI people to develop validation code that will properly reflect the revised spec that we are working on now, rather than the current one; that is why they weren't on Berman's list of current or near-future contributors. My aplogies to Dick Gabriel and Lucid for any discomfort I may have caused them. This is what happens when one tries to answer too many mail messages in the course of an afternoon. -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 1 Jul 86 19:57:28 EDT Received: from SCRC-STONY-BROOK.ARPA by SU-AI.ARPA with TCP; 1 Jul 86 16:38:16 PDT Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 45410; Tue 1-Jul-86 19:37:55 EDT Date: Tue, 1 Jul 86 19:36 EDT From: Kent M Pitman Subject: Argument lists To: Fahlman@C.CS.CMU.EDU, common-lisp@SU-AI.ARPA In-Reply-To: Message-ID: <860701193628.4.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM> Date: Mon, 30 Jun 1986 23:25 EDT From: "Scott E. Fahlman" Subject: Argument lists ... Nick Gall's proposal seems to be the leading contender for a low-cost standard way of finding out how a function may legally be called. ... (function-parameter ) Returns ... six values ... Can everyone live with that? If not, say so. No. This does not assure adequately fast access to just the max and min information for use in embedded interpreters. The other info might be expensive to cons and it may be getting consed for no good reason. I feel that either there should be two functions, or the function should be given arguments saying kinds of info you wanted so that no time was wasted in consing in situations where speed matters. This wouldn't be so essential if implementations were always required to signal an error in an wrong number of arguments situation -and- if we had the error system in place. I expect the latter to happen in the near future, but am not so sure the former will go through, so I really think fast access to just the numbers part is important.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 1 Jul 86 18:37:01 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 1 Jul 86 15:27:17 PDT Received: ID ; Tue 1 Jul 86 18:27:20-EDT Date: Tue, 1 Jul 1986 18:27 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: berman@vaxa.isi.edu (Richard Berman) Cc: common-lisp@SU-AI.ARPA Subject: Validation status In-reply-to: Msg of 1 Jul 1986 17:14-EDT from berman at vaxa.isi.edu (Richard Berman) Richard, Thanks for the progress report. I don't see Lucid in there anywhere. have they reneged on their promise? I'd like to have a look at the support proposl you're sending in. In fact, all of the technical and steering committee members should probably see this. They can all be reached by mail to CL-Steering@su-ai. Ohlander is on the steering committee if there are questions. Glad to see you're rolling. -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 1 Jul 86 17:43:06 EDT Received: from VAXA.ISI.EDU by SU-AI.ARPA with TCP; 1 Jul 86 14:14:44 PDT Received: by vaxa.isi.edu (4.12/4.7) id AA18071; Tue, 1 Jul 86 14:14:20 pdt From: berman@vaxa.isi.edu (Richard Berman) Message-Id: <8607012114.AA18071@vaxa.isi.edu> Date: 1 Jul 1986 1414-PDT (Tuesday) To: common-lisp@su-ai.arpa Cc: Subject: Validation status Validation Suite Report 01 July 1986 Currently I have just (in the past 10 days) actually received the first few signifigant (in size) contributions. By and large these are only partially evaluated at this time. Each validation suite contributed uses its own form of test control and reporting. At present I am looking over the various control mechanisms, as well as cataloging and understanding (or trying to) the various individual tests. The following shows the status of each contributor. THINGS RECEIVED: CDC - Tape received from them yesterday, containing large test suite. Coral Software - Brought a Macintosh disk with shallow tests of a number of CL functions. Gould Computer Systems - Sent a test suite for Arrays. Also sent a manual for their "test harness" test controller, but did not send the source code for the test controller run-time, macro definitions, etc. I have asked for this extra data. THINGS PROMISED: Data General - Currently sanitizing a broad/shallow suite. Should be ready soon. DEC - Has promized a suite for FORMAT, may do more as this public domain suite progresses. Franz - Has promised "something" after the 4th. H.P. -- Around June 19 they said they'd send "everything", which would be a large test suite. There may have been some hitch in figuring out how to send it in a form that I can use it. Symbolics - In May said they'd sanitize and send in a full test suite around the beginning of June. I am not sure of the cause for the delay, but I can imagine that this project is not a high priority. T.I. - Will do something. I've suggested a scoping test (hee hee hee). ------------------------ OTHER THINGS: I'd love to hear from any of the following, 'cuz I either have been unable to et your corret net address or for some other reason we have not connected: AT&T Bell Labs -- Elia Weixelbaum Gold Hill -- Greg Faust Integrated Inference Machines -- James H. Hind Intermetrics -- Karen Huff LMI -- George Carrette Pyramid Technology -- David Bein Tektronix -- William Waller Xerox AIS -- Paul Ricci ---------------------------- In addition there is the ISI proposal on their involvement in supporting the Common Lisp community. It goes much beyond just the validation suite. Please send a message to me, Berman@Vaxa.ISI.EDU, if you would like to see this. Best, RB  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 1 Jul 86 16:54:53 EDT Received: from MIT-LIVE-OAK.ARPA by SU-AI.ARPA with TCP; 1 Jul 86 13:38:40 PDT Received: from GOLD-HILL-ACORN.DialNet.Symbolics.COM by MIT-LIVE-OAK.ARPA via DIAL with SMTP id 3490; 1 Jul 86 16:40:04-EDT Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 26904; Tue 1-Jul-86 16:39:47-EDT Date: Tue, 1 Jul 86 16:09 EST Sender: mike@a To: Fahlman@C.CS.CMU.EDU From: mike%gold-hill-acorn@mit-live-oak.arpa Subject: Argument lists Cc: common-lisp@SU-AI.ARPA Date: Tue, 1 Jul 1986 12:00 EDT From: "Scott E. Fahlman" I still think the right thing to do is to make (type-of ) return a type signature for the function. ... I proposed this last week sometime, and I saw only minimal feedback (which was positive). Are there any good reasons why the type system isn't the right place to garner this information? Sorry I didn't jump on this when it was first proposed. Too much mail went by in too short a time. I really dislike this way of doing it. Several reasons: First, this is a very inconvenient interface. We require the system to cons up a funny list that the user then has to parse. This is no harder than parsing a regular arglist; however, I see your point. My complaint is not that there oughtn't be a digested numeric version of this functionality, (and the circulated proposal seems fine,) but rather this: The need to make statements about function types in terms of arglists is indicative of a shortcoming in the type system of CL. The shortcoming is that you can't find out anything about the type of a function object. Second, it requires the type of every argument to be available in explicit form; this may be too much to ask of many systems. Actually, the types of the arguments can always be t, e.g., (function (t t &key t ) (values t t)) Which additionally hides the names of the variables. Third, TYPE-OF has a lot of leeway in what it returns for all other forms, and is the source of much confusion. Right. I think the leeway should be removed, so that it is no longer confusing. CLtL defines a powerful and elegant type system for lisp. Things like type-of should be tools that programmers can use rather than underspecified thorns in the side. I've seen several portable packages try to use this and get screwed up because they expected STRING and got (SIMPLE-STRING 37) or something. This is the equality bug all over again on types. Subtypep is usually the right comparison to use for types, not list equality. Typep is generally too strong as well. I would like to promote the idea that TYPE-OF is useful mostly as an interactive debugging interface, and if you ever see TYPE-OF in code it is probably an error. This is the way I feel about arglist accessing functions! They should be part of an interactive debugging interface, not part of applications code. And if you see programs manipulating arglists or asking about them, it is probably something better stated in terms of the type of the function involved. ...mike beckerle Gold Hill Computers  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 1 Jul 86 16:51:46 EDT Received: from [192.10.41.41] by SU-AI.ARPA with TCP; 1 Jul 86 13:35:17 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 33510; Tue 1-Jul-86 13:26:40 EDT Date: Tue, 1 Jul 86 13:26 EDT From: David A. Moon Subject: Argument lists To: mike%gold-hill-acorn@MIT-LIVE-OAK.ARPA cc: common-lisp@SU-AI.ARPA In-Reply-To: The message of 1 Jul 86 11:13 EDT from mike%gold-hill-acorn@mit-live-oak.arpa Message-ID: <860701132627.1.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Tue, 1 Jul 86 10:13 EST From: mike%gold-hill-acorn@mit-live-oak.arpa I still think the right thing to do is to make (type-of ) return a type signature for the function. Then the user's program can conclude whatever it wants. If an implementation can do this, then it can certainly do what is required below, and other things too, depending on how specific the type signature is. I proposed this last week sometime, and I saw only minimal feedback (which was positive). Are there any good reasons why the type system isn't the right place to garner this information? Doesn't this conflict with the possibility of (type-of ) telling you whether it's an interpreted or compiled function, and whether it's a closure or not, and (in some systems) whether it's generic or not? Or, as CLtL says, "(type-of object) returns an implementation-dependent result".  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 1 Jul 86 16:51:32 EDT Received: from [192.10.41.41] by SU-AI.ARPA with TCP; 1 Jul 86 13:35:25 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 33521; Tue 1-Jul-86 13:31:14 EDT Date: Tue, 1 Jul 86 13:31 EDT From: David A. Moon Subject: function keys To: Masayuki Ida cc: common-lisp@SU-AI.ARPA In-Reply-To: <8607010506.AA09337@ccut.u-tokyo.junet> Message-ID: <860701133101.2.MOON@EUPHRATES.SCRC.Symbolics.COM> Do function keys modify other characters that are pressed at the same time (like SHIFT and META), or do they stand by themselves (like RETURN and Q)? If they stand by themselves, then function keys can fit into Common Lisp simply as twenty (or however many you have on the particular keyboard) additional characters that are not STANDARD-CHAR-P and not GRAPHIC-CHAR-P. I don't think the fact that some function keys are entered with SHIFT ought to be reflected in CHAR-UPCASE and related functions.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 1 Jul 86 14:19:00 EDT Received: from XEROX.COM by SU-AI.ARPA with TCP; 1 Jul 86 11:08:21 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 01 JUL 86 11:08:15 PDT Date: 1 Jul 86 10:42 PDT Sender: Gregor.pa@Xerox.COM From: Gregor Kiczales Subject: Re: Argument lists In-reply-to: "Scott E. Fahlman" 's message of Mon, 30 Jun 86 23:25 EDT To: Fahlman@C.CS.CMU.EDU cc: common-lisp@SU-AI.ARPA Message-ID: <860701-110815-3923@Xerox> It might be better if function-parameter-names returned 4 values by splitting its first value up into 3 separate values. The required, the optional and the rest. This would make it easier for programs which just want to print the parameters of a function, they wouldn't have to both function-parameter-names and function-parameters (using the values from the second to split up the values from the second). If function-parameter-names gets changed that way, the spec has to make it very clear whether the values returned can be bashed since people who want just one value (all the argument names) are going to have to decide whether to use nconc or append.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 1 Jul 86 14:15:16 EDT Received: from XEROX.COM by SU-AI.ARPA with TCP; 1 Jul 86 11:04:41 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 01 JUL 86 11:04:31 PDT Date: 1 Jul 86 10:22 PDT Sender: Bobrow.pa@Xerox.COM Subject: Re: Argument lists In-reply-to: mike%gold-hill-acorn@mit-live-oak.arpa's message of Tue, 1 Jul 86 10:13 EST To: mike%gold-hill-acorn@mit-live-oak.arpa cc: Fahlman@C.CS.CMU.EDU, common-lisp@SU-AI.ARPA From: Bobrow.pa@Xerox.COM (Danny Bobrow) Message-ID: <860701-110431-3911@Xerox> I still think the right thing to do is to make (type-of ) return a type signature for the function. Then the user's program can conclude whatever it wants. I support this idea, especially since it extends well to the notion of generic functions where type information is specified. -- danny  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 1 Jul 86 13:07:25 EDT Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 1 Jul 86 09:58:01 PDT Received: from katherine by Godot.Think.COM via CHAOS; Tue, 1 Jul 86 12:58:04 edt Date: Tue, 1 Jul 86 12:59 EDT From: Guy Steele Subject: Argument lists To: Fahlman@C.CS.CMU.EDU, NGALL@BBNG.ARPA Cc: common-lisp@SU-AI.ARPA, gls@AQUINAS In-Reply-To: Message-Id: <860701125913.4.GLS@KATHERINE.THINK.COM> Date: Tue, 1 Jul 1986 11:38 EDT From: "Scott E. Fahlman" (function-parameter ) I think this is a typo. Should be function-parameters. Right! -- Scott With this amendment, I endorse this proposal and retract the several functions I suggested initially. --Guy  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 1 Jul 86 13:05:37 EDT Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 1 Jul 86 09:55:16 PDT Received: from katherine by Godot.Think.COM via CHAOS; Tue, 1 Jul 86 12:55:14 edt Date: Tue, 1 Jul 86 12:56 EDT From: Guy Steele Subject: Argument lists To: mike%gold-hill-acorn@mit-live-oak.ARPA, Fahlman@C.CS.CMU.EDU Cc: common-lisp@SU-AI.ARPA, gls@AQUINAS In-Reply-To: <8607011415.AA08297@Zarathustra.Think.COM> Message-Id: <860701125623.3.GLS@KATHERINE.THINK.COM> Date: Tue, 1 Jul 86 10:13 EST From: mike%gold-hill-acorn@mit-live-oak.ARPA Date: Mon, 30 Jun 1986 23:25 EDT From: "Scott E. Fahlman" Perhaps we can try to converge on the argument-list business. Nick Gall's proposal seems to be the leading contender for a low-cost standard way of finding out how a function may legally be called. This is an upward-compatible extension to the language: I still think the right thing to do is to make (type-of ) return a type signature for the function. The problem is more general than that. Sometimes you just want the word FUNCTION and sometimes the more elaborate thing. There is not enough control over what TYPE-OF returns, and that, in turn, is because there are many possible types to which an object might belong. --Guy  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 1 Jul 86 12:11:09 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 1 Jul 86 09:00:30 PDT Received: ID ; Tue 1 Jul 86 12:00:32-EDT Date: Tue, 1 Jul 1986 12:00 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: mike%gold-hill-acorn@MIT-LIVE-OAK.ARPA Cc: common-lisp@SU-AI.ARPA Subject: Argument lists In-reply-to: Msg of 1 Jul 1986 11:13-EDT from mike%gold-hill-acorn at mit-live-oak.arpa I still think the right thing to do is to make (type-of ) return a type signature for the function. ... I proposed this last week sometime, and I saw only minimal feedback (which was positive). Are there any good reasons why the type system isn't the right place to garner this information? Sorry I didn't jump on this when it was first proposed. Too much mail went by in too short a time. I really dislike this way of doing it. Several reasons: First, this is a very inconvenient interface. We require the system to cons up a funny list that the user then has to parse. Second, it requires the type of every argument to be available in explicit form; this may be too much to ask of many systems. Third, TYPE-OF has a lot of leeway in what it returns for all other forms, and is the source of much confusion. I've seen several portable packages try to use this and get screwed up because they expected STRING and got (SIMPLE-STRING 37) or something. I would like to promote the idea that TYPE-OF is useful mostly as an interactive debugging interface, and if you ever see TYPE-OF in code it is probably an error. Just the argument names can be misleading. A broken abstraction is a broken abstraction. On the other hand, if you are going to allow people the "documentation" value of knowing the formal parameter names, I don't see why you draw the line at the default forms. They can be useful to look at as well, for example to decide if you need to calculate and pass an optional argument, or whether the default is good enough. I don't see this as a broken abstraction. The programmer needs to know which arguments are supposed to do what, and the names are a quick way of indicating that (or at least what the argument order is if the user already knows what the function is supposed to do). Documentation strings typically say something like "Takes two arguments, ITEM and LIST, and looks for the second occurrence of ITEM in LIST..." The proposed function would give you the first half of that. It doesn't tell you what's in the black box. It doesn't tell you anything you wouldn't get from an Ada function header. If all the default forms were constants, I'd argue for including those as well, but they are arbitrary forms of unbounded complexity that cross the line into implementation in many cases. -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 1 Jul 86 11:48:45 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 1 Jul 86 08:39:34 PDT Received: ID ; Tue 1 Jul 86 11:38:29-EDT Date: Tue, 1 Jul 1986 11:38 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: NGALL@BBNG.ARPA Cc: common-lisp@SU-AI.ARPA Subject: Argument lists In-reply-to: Msg of 1 Jul 1986 09:38-EDT from NGALL at G.BBN.COM (function-parameter ) I think this is a typo. Should be function-parameters. Right! -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 1 Jul 86 11:46:15 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 1 Jul 86 08:36:26 PDT Received: ID ; Tue 1 Jul 86 11:36:02-EDT Date: Tue, 1 Jul 1986 11:35 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Hvatum@MIT-MULTICS.ARPA Cc: common-lisp@SU-AI.ARPA Subject: subseq In-reply-to: Msg of 1 Jul 1986 08:41-EDT from Hvatum at MIT-MULTICS.ARPA (subseq #(1 2 3) 0 5 :signal-error nil) ? This still looks like a really bad way of accomplishing whatever it is you are trying to accomplish. A subsequence should be a SUBsequence, period. -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 1 Jul 86 11:39:49 EDT Received: from MIT-LIVE-OAK.ARPA by SU-AI.ARPA with TCP; 1 Jul 86 08:24:48 PDT Received: from GOLD-HILL-ACORN.DialNet.Symbolics.COM by MIT-LIVE-OAK.ARPA via DIAL with SMTP id 3460; 1 Jul 86 11:26:00-EDT Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 26728; Tue 1-Jul-86 11:25:53-EDT Date: Tue, 1 Jul 86 11:23 EST From: mike@a To: Masinter.pa@Xerox.COM Subject: Cc: common-lisp@su-ai.ARPA Date: 26 Jun 86 15:36 PDT From: Masinter.pa@Xerox.COM Sounds like I wasn't clear enough. When I suggested portable programs "stick within the set of standard characters" I was referring to "the Common Lisp character set" as defined on pp 20-21 of "Common Lisp the Language" by Guy L. Steele Jr. as follows: "The Common Lisp character set consists of a space character #\Space, a newline character #\Newline, and the following ninety-four non-blank printing characters or their equivalents..." It looks awfully specific to me, and I'm not sure what our friends at IBM or Japan would be chuckling about. In reply to KMPs other points: "It's important to distinguish between implementation dependent behavior and unpredictable behavior. Many things in Common Lisp are conceptually well-defined even though they vary from implementation to implementation. For example, the behavior of (1+ MOST-POSITIVE-FIXNUM) varies in detail from implementation to implementation, but conceptually it does not. I don't think that it's inappropriate to describe a program as having useful commands bound to keys and to tell the user to type "?" to see a list of the commands available." I agree whole-heartedly with this analysis and the appropriateness of the situation you describe. "The issue is much bigger than you make it out to be and if you claim it to be fatal, then I claim you're attacking the whole notion of whether CL can be portable..." I object to your claim: I firmly believe that CL can be portable and I'm making no such attack. That's the point of this whole discussion. I think that this is in fact one of the few intrinsicly non-portable parts of the language. I agree that CHAR-BITS-LIMIT is in the same class as "MOST-POSITIVE-FIXNUM". The issue as I see it is: does this abstraction *encourage* or *discourage* users from writing portable programs? I claim that this particular feature works against portability: It is my belief that having "char-bits" in the book will encourage users who are working in an implementation which supports "char-bits" to rely upon "char-bits" in their programs, with a nod to the fact "well, those lusers without char-bits just can't use this program". If char-bits were *not* in the standard, then the writer of a portable program would set aside a table somewhere, which said: ; implementation-dependent table of character codes and their functions #\control-A delete-next-character #\control-R retype-line and clearly identify that these were not "standard" (in the sense of pp 20-21) characters. Let me put it in terms of a more definite proposal in terms of chapter and verse: a) eliminate constants char-code-limit, char-font-limit and char-bits-limit, and instead have a constants: char-integer-limit [Constant] The value of char-integer-limit is a non-negative integer that is the upper exclusive bound on values produced by the function char-integer. ... string-char-integer-limit [constant] The value of string-char-integer-limit is the upper exclusive bound on values produced by the funcion char-integer for characters which satisfy string-char-p. [Implementation note: older Common Lisps can implement this by (defconstant char-integer-limit (+ char-code-limit char-font-limit char-bits-limit)) (defconstant string-char-integer-limit char-code-limit)] b) change the wording of char-upcase and char-downcase to omit references to "characters with non-zero bits". [note: I detect an inconsistency in the description of char-upcase on p. 241, which in the second paragraph says that it returns a character object with the same font and bits attributes but with possibly a different code, and in the last paragraph says that they have no effect on characters with non-zero bits attributes] c) eliminate functions char-code, char-bits, char-font, code-char, make-char from the standard. [Compatibility note: users with older common lisp programs may want to define char-code as (mod (char-int char) string-char-integer-limit)) and similarly make the other ones as transforms on char-integers] d) eliminate the constants char-control-bit char-meta-bit char-super-bit char-hyper-bit and the functions char-bit set-char-bit. [Compatibility note: users with older common lisp programs who want to use these features can define these constants as 1 2 4 8 respectively, and define (defun char-bit char name (int-char (logtest (int-char char) (* string-char-integer-limit (ecase name (:control 1) (:meta 2) ...))))))  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 1 Jul 86 10:25:40 EDT Received: from MIT-LIVE-OAK.ARPA by SU-AI.ARPA with TCP; 1 Jul 86 07:14:06 PDT Received: from GOLD-HILL-ACORN.DialNet.Symbolics.COM by MIT-LIVE-OAK.ARPA via DIAL with SMTP id 3458; 1 Jul 86 10:15:29-EDT Received: from BOSTON.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 26712; Tue 1-Jul-86 10:15:22-EDT Date: Tue, 1 Jul 86 10:13 EST Sender: mike@a To: Fahlman@C.CS.CMU.EDU From: mike%gold-hill-acorn@mit-live-oak.arpa Subject: Argument lists Cc: common-lisp@SU-AI.ARPA Date: Mon, 30 Jun 1986 23:25 EDT From: "Scott E. Fahlman" Perhaps we can try to converge on the argument-list business. Nick Gall's proposal seems to be the leading contender for a low-cost standard way of finding out how a function may legally be called. This is an upward-compatible extension to the language: I still think the right thing to do is to make (type-of ) return a type signature for the function. Then the user's program can conclude whatever it wants. If an implementation can do this, then it can certainly do what is required below, and other things too, depending on how specific the type signature is. I proposed this last week sometime, and I saw only minimal feedback (which was positive). Are there any good reasons why the type system isn't the right place to garner this information? The only real objection that I can see to this is that creating function-specs may require consing them up, or storing them previously. There seems to be little enthusiasm for REQUIRING that an implementation supply the function's original argument list or the names of the parameters, especially for compiled code. Agreed. I think this is a programming environment issue, not a Language definition issue. There remains the issue of whether we should provide a standard way of asking for additional, internal argument list information if it is available. Some implementations would supply this information, others would not, and others might supply it for some functions and not for others. I personally believe that a standard format for getting at argument-name information, if it is available, would be useful, but I don't like the idea of returning the original lambda-list (or a copy of it). The problem is that the lambda-list contains default-value forms that can be very complex and that would be confusing when taken out of context. Just the argument names can be misleading. A broken abstraction is a broken abstraction. On the other hand, if you are going to allow people the "documentation" value of knowing the formal parameter names, I don't see why you draw the line at the default forms. They can be useful to look at as well, for example to decide if you need to calculate and pass an optional argument, or whether the default is good enough. Would something like this be useful in the standard, or should we let each implementation decide for itself wht format to use in providing arglist info? I don't see much agreement on this issue. -- Scott ...mike  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 1 Jul 86 09:48:33 EDT Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 1 Jul 86 06:39:15 PDT Date: 1 Jul 1986 09:38-EDT Sender: NGALL@G.BBN.COM Subject: Re: Argument lists From: NGALL@G.BBN.COM To: Fahlman@C.CS.CMU.EDU Cc: common-lisp@SU-AI.ARPA Message-ID: <[G.BBN.COM] 1-Jul-86 09:38:16.NGALL> In-Reply-To: Date: Mon, 30 Jun 1986 23:25 EDT From: "Scott E. Fahlman" To: common-lisp@SU-AI.ARPA Subject: Argument lists Message-ID: Perhaps we can try to converge on the argument-list business. Nick Gall's proposal seems to be the leading contender for a low-cost standard way of finding out how a function may legally be called. This is an upward-compatible extension to the language: --------------------------------------------------------------------------- (function-parameter ) I think this is a typo. Should be function-parameters. ... --------------------------------------------------------------------------- (function-parameter-names ) Takes one argument which must be a function, not a macro or special form. Returns two values: 1. A list containing the symbols naming the required, optional, and rest parameters, in order, if this information is available; NIL otherwise. 2. T if the list returned as value 1 is valid; NIL otherwise. --------------------------------------------------------------------------- Would something like this be useful in the standard, or should we let each implementation decide for itself wht format to use in providing arglist info? Looks fine (and useful) to me. -- Nick  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 1 Jul 86 09:04:06 EDT Received: from MIT-MULTICS.ARPA by SU-AI.ARPA with TCP; 1 Jul 86 05:56:09 PDT Date: Tue, 1 Jul 86 08:41 EDT From: Hvatum@MIT-MULTICS.ARPA Subject: subseq To: common-lisp@SU-AI.ARPA Message-ID: <860701124137.380202@MIT-MULTICS.ARPA> From: Steve Bacher (C.S.Draper Lab) To: common-lisp Subject: subseq How about (subseq #(1 2 3) 0 5 :signal-error nil) ? This seems ideal to me, since the programmer's intention (i.e. whether or not an out-of-bounds condition is expected) is stated right there in the function call form.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 1 Jul 86 07:01:05 EDT Received: from CSNET-RELAY.ARPA by SU-AI.ARPA with TCP; 1 Jul 86 03:50:40 PDT Received: from utokyo-relay by csnet-relay.csnet id ak08281; 1 Jul 86 6:36 EDT Received: by u-tokyo.junet (4.12/4.9J-1[JUNET-CSNET]) id AA14426; Tue, 1 Jul 86 14:10:30+0900 Received: by ccut.u-tokyo.junet (4.12/6.1Junet) id AA09337; Tue, 1 Jul 86 14:06:56+0900 Date: Tue, 1 Jul 86 14:06:56+0900 From: Masayuki Ida Message-Id: <8607010506.AA09337@ccut.u-tokyo.junet> To: common-lisp@SU-AI.ARPA, ida@UTOKYO-RELAY.CSNET, ida%u-tokyo.junet@CSNET-RELAY.ARPA Subject: function keys >Date: Fri, 20 Jun 86 10:37 EDT >From: "Daniel L. Weinreb" >Subject: Re: Why aren't char bits portable? This mail is not directly related to this subject. But, I want to talk about the keyboard interface. >To: Masinter.pa@XEROX.COM, common-lisp@SU-AI.ARPA >Received: from CSNet-Relay by utokyo-relay; 22 Jun 86 7:27:22-JST (Sun) > > ... I believe that the intent of including >"bits" in the standard is to allow for the fact that some of the "bits" >are gaining some amount of currency as ad hoc standards. If "bits" are gaining some amount of currency as ad hoc standard, "function-keys" are also gaining some amount of currency as ad hoc standard, in japan. (I am not talking about the character issues here. I am talking about the ad hoc standard for keyboard interfaces) > ... In particular, >there are now several terminals on the market that have a "Meta" key, > ... There are now MANY terminals/personal computers that have "function-keys" in Japan. > >A program that wants to be universally portable, of course, cannot >depend on the presence of such key on the user's keyboard. However, it >is not hard to imagine a program that wants to be portable, but also >wants to allow any user who has a Meta key to take advantage of it. >(Indeed, many Emacs-family editors have this property.) > >I believe the intention of the "bits" feature was to help out such >programs. While I'm not sure that all the details of the "bits" feature >in the standard are ideal, nevertheless I wanted to point out that the >entire feature is not necessarily bankrupt. > > Actually, there are discussions about the standard interface for "function-keys" in CL in japan. I was asked the possibility of the standard for it. Lisp based interactive system faces the problem. There arises a portability problem. Furthremore many editor/word processing software in japan use function keys. The semantics for the function keys may vary. There may be 10 function keys physically, and with shift-key they act as a command pannel for 20 functions. The meaning of the each key is guided in CRT. Or a guide pad for each software is provided for user convinience. I wonder this type of standardization for interface is japan domestic or no ? Masayuki Ida ida@utokyo-relay.csnet  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Jun 86 23:33:46 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 30 Jun 86 20:25:03 PDT Received: ID ; Mon 30 Jun 86 23:25:06-EDT Date: Mon, 30 Jun 1986 23:25 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: common-lisp@SU-AI.ARPA Subject: Argument lists Perhaps we can try to converge on the argument-list business. Nick Gall's proposal seems to be the leading contender for a low-cost standard way of finding out how a function may legally be called. This is an upward-compatible extension to the language: --------------------------------------------------------------------------- (function-parameter ) Takes one argument which must be a function, not a macro or special form. Returns the following six values: 1. Number of required parameters in the function's lambda list. 2. Number of optional parameters in the function's lambda list. 3. T if the function's lambda list contains the &REST lambda-keyword; NIL otherwise. 4. T if the function's lambda list contains the &KEY lambda-keyword; NIL otherwise. 5. A list of all keywords accepted by the function, in arbitrary order. 6. T if the function's lambda list contains the &ALLOW-OTHER-KEYS lambda-keyword; NIL otherwise. If return value 4 is NIL, 5 and 6 must also be NIL. --------------------------------------------------------------------------- Can everyone live with that? If not, say so. There seems to be little enthusiasm for REQUIRING that an implementation supply the function's original argument list or the names of the parameters, especially for compiled code. There remains the issue of whether we should provide a standard way of asking for additional, internal argument list information if it is available. Some implementations would supply this information, others would not, and others might supply it for some functions and not for others. I personally believe that a standard format for getting at argument-name information, if it is available, would be useful, but I don't like the idea of returning the original lambda-list (or a copy of it). The problem is that the lambda-list contains default-value forms that can be very complex and that would be confusing when taken out of context. I'd prefer something like the following, to be used in conjunction with Function-Parameter as defined above: --------------------------------------------------------------------------- (function-parameter-names ) Takes one argument which must be a function, not a macro or special form. Returns two values: 1. A list containing the symbols naming the required, optional, and rest parameters, in order, if this information is available; NIL otherwise. 2. T if the list returned as value 1 is valid; NIL otherwise. --------------------------------------------------------------------------- Would something like this be useful in the standard, or should we let each implementation decide for itself wht format to use in providing arglist info? -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Jun 86 22:07:17 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 30 Jun 86 18:59:03 PDT Received: ID ; Mon 30 Jun 86 21:40:02-EDT Date: Mon, 30 Jun 1986 21:39 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Masinter.pa@XEROX.COM Cc: common-lisp@SU-AI.ARPA Subject: signalling errors In-reply-to: Msg of 30 Jun 1986 20:43-EDT from Masinter.pa at Xerox.COM I think that changing "is an error" to "signals an error" is premature until the error-handler is adopted and we can actually standardize *which error* is signalled. OK, technically we should probably do this after KMP has brought forth his revised error proposal and implementation, and after we have debated that system and the alternatives. Everything depends on everything else to some extent. But I think that this issue of whether certain errors must be detected if the user asks for safety would look the same regardless of the details of the error handler. I'd like to try to reach a conclusion on this. We can re-open this issue if the error system ultimately adopted has some unforseen consequences. For now, let's just assume that distinct errors must be signalled for "too many arguments', "too few arguments", "array access out of bounds", and "attempt to take CAR/CDR of a non-list". -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Jun 86 20:56:32 EDT Received: from XEROX.COM by SU-AI.ARPA with TCP; 30 Jun 86 17:48:25 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 30 JUN 86 17:48:37 PDT Date: 30 Jun 86 17:43 PDT From: Masinter.pa@Xerox.COM Subject: signalling errors To: common-lisp@su-ai.ARPA Message-ID: <860630-174837-3346@Xerox> I think that changing "is an error" to "signals an error" is premature until the error-handler is adopted and we can actually standardize *which error* is signalled. Before there is an error standard, neither phrase has particularly well-defined semantics, and choosing between one and the other is (nearly) moot. After there is an error standard, there will be much more to decide for each one. Further, the "hardship" question is much more restrictive -- implementations may not find it hard to signal some error, but there may be many more difficulties in getting implementations to agree on the error type.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Jun 86 17:49:30 EDT Received: from WISCVM.WISC.EDU by SU-AI.ARPA with TCP; 30 Jun 86 14:42:49 PDT Received: from (DESMEDT)HNYKUN52.BITNET by WISCVM.ARPA on 06/30/86 at 16:43:06 CDT Date: Mon, 30 Jun 86 12:19 N From: Subject: request to join To: common-lisp@su-ai.arpa X-Original-To: common-lisp@su-ai.arpa I would like to be on the e-mailing list of the Common Lisp discussion group. I am currently working on Natural Language applications (in Common Lisp, of course) and have been involved in the development of an object-oriented language on top of Common Lisp (CommonOrbit). Koenraad De Smedt University of Nijmegen Psychology Lab Montessorilaan 3 6525 HR Nijmegen The Netherlands e-mail: desmedt@hnykun52.bitnet  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Jun 86 16:13:29 EDT Received: from UTAH-20.ARPA by SU-AI.ARPA with TCP; 30 Jun 86 13:01:39 PDT Date: Mon 30 Jun 86 13:59:54-MDT From: SANDRA Subject: Re: Two functions for everything? To: DCP@SCRC-QUABBIN.ARPA cc: common-lisp@SU-AI.ARPA In-Reply-To: <860630135301.3.DCP@FIREBIRD.SCRC.Symbolics.COM> Message-ID: <12219012418.13.LOOSEMORE@UTAH-20.ARPA> I was under the impression that we were discussing a proposal to standardize what kinds of error checking certain functions (like CAR and AREF and SUBSEQ) should perform when called from code compiled with various settings of the "optimize safety" switch. The main reason why I would like to have a standard, high-level utility to do such things is so that ordinary users would have a portable way to provide various levels of error checking for functions they write themselves. Secondarily, it's a lot of work for us implementors to have to write 4 different versions of each of these functions (or hand-code them with 4 entry points) and manually add special hooks so the compiler will know about them. I think a more general utility would be less work in the long run. Furthermore, I think that there's a much better chance that various implementors could agree to do the same kinds of error checks if it were easy to do so, instead of requiring a lot of special-purpose hackery. Conditional compilation of in-line error checks based on the current value of the safety setting is another matter entirely. Again, the language doesn't provide any portable way to do this, but it doesn't really sound like such an unreasonable thing for a user to want to do. Parenthetically, I might point out that this is similar to the problems involved with implementing generic arithmetic and sequence functions. CL puts so much emphasis on polymorphic functions it's somewhat annoying that there aren't built-in utilities for ordinary users to use to define their own polymorphic functions and make them known to the compiler in a portable way. It would be real nice to have a way to generate dispatching code automatically, and optionally hook into the compiler so it can make use of declarations to do generic-to-specific optimizations. It's especially annoying because probably most implementations already have some internal mechanisms to do this (and those that don't would benefit from having them, if experience with PSL/PCLS is anything to go by). And, I don't think there's anything inherently nonportable about such a utility. -Sandra -------  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Jun 86 15:30:27 EDT Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 30 Jun 86 12:15:36 PDT Received: from katherine by Godot.Think.COM via CHAOS; Mon, 30 Jun 86 14:54:30 edt Date: Mon, 30 Jun 86 14:55 EDT From: Guy Steele Subject: Argument lists: a proposal to shoot at To: JAR@AI.AI.MIT.EDU, gls@ZARATHUSTRA Cc: common-lisp@SU-AI.ARPA, Moon@SCRC-STONY-BROOK.ARPA, gls@AQUINAS In-Reply-To: <[AI.AI.MIT.EDU].63675.860630.JAR> Message-Id: <860630145533.6.GLS@KATHERINE.THINK.COM> Date: Mon, 30 Jun 86 14:30:51 EDT From: Jonathan A Rees Date: Mon, 30 Jun 86 13:57 EDT From: Guy Steele Maybe it's not worth eliminating K, I grant. However, while it may be reasonable for the author of the code to write (&key), it's not clear that that information is important to a potential caller who needs to know what arguments may be passed. Such a function accepts no keyword arguments directly, and does not have &allow-other-keys, and so, operationally speaking, what is the need to know that &key was there? If the formal parameter list is (&key), then an actual parameter list of (:foo 7 :allow-other-keys t :bar 'a) is legal, n'est-ce pas? Touche! Magnifique! (Or, as Frank Zappa titled an album, Zoot allures!) What a wonderful language. Therefore the K value is not redundant after all. --Guy  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Jun 86 15:01:15 EDT Received: from AI.AI.MIT.EDU by SU-AI.ARPA with TCP; 30 Jun 86 11:46:20 PDT Date: Mon, 30 Jun 86 14:30:51 EDT From: Jonathan A Rees Subject: Argument lists: a proposal to shoot at To: gls@ZARATHUSTRA.THINK.COM cc: common-lisp@SU-AI.ARPA, Moon@SCRC-STONY-BROOK.ARPA In-reply-to: Msg of Mon 30 Jun 86 13:57 EDT from Guy Steele Message-ID: <[AI.AI.MIT.EDU].63675.860630.JAR> Date: Mon, 30 Jun 86 13:57 EDT From: Guy Steele Maybe it's not worth eliminating K, I grant. However, while it may be reasonable for the author of the code to write (&key), it's not clear that that information is important to a potential caller who needs to know what arguments may be passed. Such a function accepts no keyword arguments directly, and does not have &allow-other-keys, and so, operationally speaking, what is the need to know that &key was there? If the formal parameter list is (&key), then an actual parameter list of (:foo 7 :allow-other-keys t :bar 'a) is legal, n'est-ce pas?  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Jun 86 14:39:00 EDT Received: from GODOT.THINK.COM by SU-AI.ARPA with TCP; 30 Jun 86 10:56:21 PDT Received: from katherine by Godot.Think.COM via CHAOS; Mon, 30 Jun 86 13:56:14 edt Date: Mon, 30 Jun 86 13:57 EDT From: Guy Steele Subject: Re: Argument lists: a proposal to shoot at To: Moon@STONY-BROOK.SCRC.Symbolics.COM, common-lisp@SU-AI.ARPA In-Reply-To: <860627181505.4.MOON@EUPHRATES.SCRC.Symbolics.COM> Message-Id: <860630135717.1.GLS@KATHERINE.THINK.COM> Date: Fri, 27 Jun 86 18:15 EDT From: David A. Moon Date: Fri, 27 Jun 86 14:45 EDT From: Guy Steele Date: 26 Jun 1986 19:17-EDT From: NGALL@G.BBN.COM How about keeping the number of functions down and eliminating the 'encoding' in MAX-ARGS, and using correct terminology with the following one-function alternative to FUNCTION-MIN-ARGS, -MAX-ARGS, -HAS-KEYWORD-PARAMETERS, and -KEYWORD-PARAMETERS. I think FUNCTION-KEYWORD-PARAMETER-P addresses an idiom common enough to warrant its own function. FUNCTION-PARAMETERS function [Function] Returns Q, P, R, K, a list of keywords explicitly accepted by the function (order undefined), and A. Note that if K is false, the list is necessarily empty. I like one function to return all the information better than a bunch of separate functions. As for whether it's better to return min-and-max or required-and-optional, in all these years I've never made up my mind on that point. I do think it's a good idea for the presence of &rest or &key not to throw away the information about how many positional parameters there are, even if some of the proposed uses for that information are bad ideas. In the min-and-max model, max could be the maximum number of positional parameters, thus you have to look at (OR R K) to know whether this is actually the maximum you are permitted to pass. MIN-and-MAX is somewhat more like the :START/:END convention for subsequences; required-nad-optional is like start/count. That is why I chose min and max. I have to admit (blush) that another design criterion I employed implicitly was that it should be possible to acquire most of the information without either consing on the fly or requiring an explicit pre-stored list of the keywords. I don't understand how the information would be accessible at all if there was not a pre-stored list. Perhaps you have some clever implementation in mind? If I were doing this on a PDP-10, I might arrange for the keywords to be checked by stylized code at the start of each function, and would write a little routine that could grovel through the instructions looking for the keywords. In your proposal for FUNCTION-PARAMETERS, I observe that returning K is redundant: K is true iff [(the keyword list is not empty) or A]. That's not to say that returning K separately isn't a good idea. (defun foo (&key) ...) has some semantic meaning, namely that if this function is ever extended it's going to take keyword parameters. If you don't think this is a realistic example, see CLtL page 427. I don't think clever elimination of the K return value is advisable. Maybe it's not worth eliminating K, I grant. However, while it may be reasonable for the author of the code to write (&key), it's not clear that that information is important to a potential caller who needs to know what arguments may be passed. Such a function accepts no keyword arguments directly, and does not have &allow-other-keys, and so, operationally speaking, what is the need to know that &key was there? --Guy  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Jun 86 14:24:26 EDT Received: from [192.10.41.41] by SU-AI.ARPA with TCP; 30 Jun 86 11:02:08 PDT Received: from FIREBIRD.SCRC.Symbolics.COM by ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 32541; Mon 30-Jun-86 13:53:03 EDT Date: Mon, 30 Jun 86 13:53 EDT From: David C. Plummer Subject: Re: Two functions for everything? To: SANDRA , DCP@QUABBIN.SCRC.Symbolics.COM cc: common-lisp@SU-AI.ARPA In-Reply-To: <12218981356.18.LOOSEMORE@UTAH-20.ARPA> Message-ID: <860630135301.3.DCP@FIREBIRD.SCRC.Symbolics.COM> Date: Mon 30 Jun 86 11:09:16-MDT From: SANDRA Setting the safety switch only seems like half the story to me. You still have to provide some way to specify what error checking a given function does for each value of the safety setting. The reason why I would prefer to see this mechanism part of the language spec, rather than left up to each implementation, is that there is no real distinction between "system" code and "user" code in Lisp. Since most CL implementations are, in fact, written *in* CL, chances are they would have some internal, high-level hooks to do this anyway. (Although I suppose there is at least one masochistic implementor out there who actually *likes* writing code in assembly language! :-)) So why not make these hooks available to the user? I'm still not sure I understand you, but I have thought up one scenario. I was thinking that what safety affected were things that "are an error" as defined by the language. This includes such things as AREF out of bounds, calling a function with the wrong number of arguments, etc. Under this view, if I compile (defun foo (a) (car a)) with safety 0, the implementation may encode CAR inline. If I compile it with safety 1, speed fast, it might compile as if I had written (defun foo (a) (check-type a 'list) (and a (car a))) If I compile it with safety 3, speed slow, space small, it might compile as (defun foo (a) (call-car's-full-checking-entrypoint a)) Some other settings might make it compile as (defun foo (a) (call-car's-no-checking-entrypoint a)) [Seems silly for CAR, but consider a slightly larger function, such as AREF.] Maybe what you are saying is that the user might write (defun foo (a) (check-type a 'list) (and a (car a))) but might want to allow the check-type to be avoided if a caller of FOO was compiled with safety 0. I don't know what to do about this. One theory, which I think I believe, is that if a programmer puts in explicit checking, that checking is always run. The sort of thing I have in mind is like a declarative form that contains the assertions about the arguments to a particular function, and the "safety level" at which to test each assertion. It would be up to the implementation to figure out how to wrap the tests around the body of the function. Personally, I think having to write error checking code at all is a nuisance, and trying to manage multiple levels of error checking sounds like a real nightmare. Unless we can come up with some abstractions for dealing with the complexity, I suspect that a lot of implementors are going to avoid messing with it entirely. If I write a function that I expect other programmers to call, I usually put in some error checking. I don't find it a nuisance, I find it a benefit to make sure (a) they get the error messages they deserve at a reasonable time, and (b) to make sure assumptions about the data I make are valid (because they passed the tests). Isn't this is a tug-of-war between speed and robustness on stock hardware? Special hardware is usually designed to do both. CLtL tries to give users the option of speed or robustness. I'm under the impression this is a compile-time-only choice, and that you would like a run-time choice as well?  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Jun 86 13:54:06 EDT Received: from C.CS.CMU.EDU by SU-AI.ARPA with TCP; 30 Jun 86 10:40:21 PDT Received: ID ; Mon 30 Jun 86 13:40:14-EDT Date: Mon, 30 Jun 1986 13:40 EDT Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: SANDRA Cc: common-lisp@SU-AI.ARPA Subject: Two functions for everything? In-reply-to: Msg of 30 Jun 1986 13:09-EDT from SANDRA It is impossible in a portable language spec to indicate exactly what opimizations will be be available and how the user will control them. The nature of these optimizations and the trade-offs they involve will vary tremendously from one system to another. There are probably optimzations that we haven't invented yet, but that will be part of some Common Lisp implementation some day. If an implementaiton wants to give its users access to all of the individual policy switches so that they have precise control over which optimizations are used, that's fine, but it is deeply non-portable. The OPTIMIZE declaration gives the user a portable way of saying, in general, what his preferences are. It is up to the implementor of each system to turn these preferences into reasonable policy decisions, given his system's particular tradeoffs. These decisions should be documented for each implementation, but they cannot be standardized in any meaningful way across very different implementations. I am a bit skeptical of systems that allow the user to redefine what the OPTIMIZE declaration does. It seems more tasteful to hard-wire the optimize-to-policy mapping, but to give the really tense users an implementation-dependent way to over-ride the OPTIMIZE settings and to manipulate the individual policy switches directly. Implementations will vary in how finely they allow the user to control the degree of error checking, but I hope not too many will take the view that "having to write error checking code at all is a nuisance". A little trouble taken by the implementors can save a *LOT* of trouble for the users later on. -- Scott  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Jun 86 13:27:05 EDT Received: from UTAH-20.ARPA by SU-AI.ARPA with TCP; 30 Jun 86 10:11:15 PDT Date: Mon 30 Jun 86 11:09:16-MDT From: SANDRA Subject: Re: Two functions for everything? To: DCP@SCRC-QUABBIN.ARPA cc: common-lisp@SU-AI.ARPA In-Reply-To: <860630115511.0.DCP@FIREBIRD.SCRC.Symbolics.COM> Message-ID: <12218981356.18.LOOSEMORE@UTAH-20.ARPA> From: David C. Plummer Date: Mon 30 Jun 86 08:52:34-MDT From: SANDRA Yeah, but where in CLtL do we provide a way to make functions with multiple entry points? I certainly don't want to have to hand-code every single function that does optional error checking in assembly language (or whatever). The point I was trying to make was that, if we are serious about making multiple levels of error checking part of the language, we should also provide some high-level constructs for specifying what error checking goes on when. Multiple entry points would be one way to implement such a construct.... Why do you think CLtL has to specify how this is done? It is completely in the domain of the implementation of the compiler, the linker and the compiled function format. The only thing CLtL needs to specify is how to get what you want, and I think it already has that with the safety setting. Setting the safety switch only seems like half the story to me. You still have to provide some way to specify what error checking a given function does for each value of the safety setting. The reason why I would prefer to see this mechanism part of the language spec, rather than left up to each implementation, is that there is no real distinction between "system" code and "user" code in Lisp. Since most CL implementations are, in fact, written *in* CL, chances are they would have some internal, high-level hooks to do this anyway. (Although I suppose there is at least one masochistic implementor out there who actually *likes* writing code in assembly language! :-)) So why not make these hooks available to the user? The sort of thing I have in mind is like a declarative form that contains the assertions about the arguments to a particular function, and the "safety level" at which to test each assertion. It would be up to the implementation to figure out how to wrap the tests around the body of the function. Personally, I think having to write error checking code at all is a nuisance, and trying to manage multiple levels of error checking sounds like a real nightmare. Unless we can come up with some abstractions for dealing with the complexity, I suspect that a lot of implementors are going to avoid messing with it entirely. -Sandra -------  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Jun 86 12:46:17 EDT Received: from CSNET-RELAY.ARPA by SU-AI.ARPA with TCP; 30 Jun 86 09:35:13 PDT Received: from utokyo-relay by csnet-relay.csnet id ab00802; 30 Jun 86 12:30 EDT Received: by u-tokyo.junet (4.12/4.9J-1[JUNET-CSNET]) id AA01657; Mon, 30 Jun 86 21:14:43+0900 From: yuasa%kurims.kurims.kyoto-u.junet%utokyo-relay.csnet@CSNET-RELAY.ARPA Received: by nttlab.ntt.junet (4.12/5.0) with TCP; Mon, 30 Jun 86 13:22:16 jst Received: by kurims.kurims.kyoto-u.junet (2.0/6.1Junet) id AA00372; Mon, 30 Jun 86 11:49:49+0900 Date: Mon, 30 Jun 86 11:49:49+0900 Message-Id: <8606300249.AA00372@kurims.kurims.kyoto-u.junet> To: Common-Lisp%SU-AI.ARPA%u-tokyo.junet@CSNET-RELAY.ARPA Subject: DRIBBLE Some people detected that DRIBBLE in KCL works quite differently from other, American Common Lisp systems. The differences certainly came from the incomplete description of DRIBBLE (page 443). While other debugging tools depend highly on implementatins, DRIBBLE could be given more detailed definition independent of the implementation. Here are my inquiries which, I think, should be made clear. 1. Is it an error to turn DRIBBLE on, while it is on already? If it is allowed, then what action should the system take? Especially, "which DRIBBLE" should (DRIBBLE) turn off? 2. Does (DRIBBLE ) supercede the specified file if it exists already? Or, does it append? Do you need any additional parameter to specify this? 3. Which stream variables should (DRIBBLE ) rebind? CLtL says only that (DRIBBLE ) rebinds *STANDARD-INPUT* and *STANDARD-OUTPUT*. What about other variables such as *TERMINAL-IO* ? 4. Suppose that (DRIBBLE ) rebinds *STANDARD-INPUT*. Are the followings are legal uses of DRIBBLE? If legal, what actions should the system take? 4a. >(dribble "foo.log") >(let ((*standard-input* ...)) .... (dribble) ....) 4b. >(let ((*standard-input* ...)) ... (dribble "foo.log") ...) >(dribble) Note: Currently, KCL causes an error in the case of 4a. This is because, at the exit from the LET form, *STANDARD-OUTPUT* is rebound to a broadcast stream that includes an already closed stream to foo.log. -- Taiichi  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Jun 86 10:59:05 EDT Received: from UTAH-20.ARPA by SU-AI.ARPA with TCP; 30 Jun 86 07:54:10 PDT Date: Mon 30 Jun 86 08:52:34-MDT From: SANDRA Subject: Two functions for everything? To: common-lisp@SU-AI.ARPA Message-ID: <12218956472.19.LOOSEMORE@UTAH-20.ARPA> From: DCP@QUABBIN.SCRC.Symbolics.COM (David C. Plummer) This is bogus folks. All you need is two entrypoints: one which doesn't check anything, and one which checks what it needs to. They then join. Safety 0 (at compile time) causes functions to call the the don't-check-anything entrypoint, and safety > 0 causes functions to call the one that checks. Hell, you could have a different entrypoint for each setting of safety. Yeah, but where in CLtL do we provide a way to make functions with multiple entry points? I certainly don't want to have to hand-code every single function that does optional error checking in assembly language (or whatever). The point I was trying to make was that, if we are serious about making multiple levels of error checking part of the language, we should also provide some high-level constructs for specifying what error checking goes on when. Multiple entry points would be one way to implement such a construct.... -Sandra -------  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Jun 86 10:56:28 EDT Received: from KIM.Berkeley.EDU by SU-AI.ARPA with TCP; 30 Jun 86 07:51:38 PDT Received: by kim.Berkeley.EDU (5.51/1.14) id AA00572; Mon, 30 Jun 86 07:51:45 PDT From: franz!fizzy!jkf@kim.berkeley.edu Received: from fizzy by franz (5.5/3.14) id AA10208; Mon, 30 Jun 86 07:46:22 PDT Received: by fizzy (4.12/3.14) id AA05530; Mon, 30 Jun 86 07:46:45 pdt Return-Path: Message-Id: <8606301446.AA05530@fizzy> To: David C. Plummer Cc: common-lisp@su-ai.arpa Subject: Re: Error Signalling In-Reply-To: Your message of Mon, 30 Jun 86 09:17:00 EDT. <860630091710.8.DCP@FIREBIRD.SCRC.Symbolics.COM> Date: Mon, 30 Jun 86 07:46:43 PDT >> Nit: that isn't in the LISP: or USER: package, I hope, but SYS: or some >> other private package. Yes, it is in the compiler package. If other implementations use this idea and want to make it portable, we wouldn't mind moving these symbols to the a package such as the system package, a private package which most implementations have. - john foderaro Franz Inc.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Jun 86 09:27:25 EDT Received: from [192.10.41.41] by SU-AI.ARPA with TCP; 30 Jun 86 06:18:24 PDT Received: from FIREBIRD.SCRC.Symbolics.COM by ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 32238; Mon 30-Jun-86 09:17:12 EDT Date: Mon, 30 Jun 86 09:17 EDT From: David C. Plummer Subject: Re: Error Signalling To: franz!fizzy!jkf@kim.Berkeley.EDU cc: common-lisp@SU-AI.ARPA In-Reply-To: <8606300118.AA04052@fizzy> Message-ID: <860630091710.8.DCP@FIREBIRD.SCRC.Symbolics.COM> Date: Sun, 29 Jun 86 18:18:21 PDT From: franz!fizzy!jkf@kim.Berkeley.EDU >> It's *probably* not a portability problem that (safety 1) means something >> different in different implementations. PCLS uses the speed settings to >> switch various kinds of optimizations, but we didn't have much intuition >> about what the difference between (speed 2) and (speed 3) should be >> ... We also didn't know what should be done for the various settings of speed, size and safety so we put the decision back in the users' hands. Our compiler can perform a number of optimizations, some of the optimizations involve removing safety checks and for these we felt that the user should be aware of what they are and should have control over when they are done. Therefore each optimization is controlled by a function of safety, size and speed. The user is free to redefine the functions if he doesn't like the default function. Here is an example of the function which controls one of the optimizations discussed recently: that of not checking the number of arguments passed to the function: (defvar verify-argument-count-switch #'(lambda (safety size speed) (declare (ignore size)) (or (< speed 3) (> safety 0))) "bound to a function which given safety, size and speed returns t if the compiler should generate code to verify that the correct number of arguments were passed to a function. Note: an argument count check is always done if there are optional or rest arguments.") Nit: that isn't in the LISP: or USER: package, I hope, but SYS: or some other private package. -john foderaro Franz Inc.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Jun 86 09:25:50 EDT Received: from [192.10.41.41] by SU-AI.ARPA with TCP; 30 Jun 86 06:16:20 PDT Received: from FIREBIRD.SCRC.Symbolics.COM by ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 32234; Mon 30-Jun-86 09:15:09 EDT Date: Mon, 30 Jun 86 09:15 EDT From: David C. Plummer Subject: two functions for everything To: common-lisp@SU-AI.ARPA Message-ID: <860630091505.6.DCP@FIREBIRD.SCRC.Symbolics.COM> This is bogus folks. All you need is two entrypoints: one which doesn't check anything, and one which checks what it needs to. They then join. Safety 0 (at compile time) causes functions to call the the don't-check-anything entrypoint, and safety > 0 causes functions to call the one that checks. Hell, you could have a different entrypoint for each setting of safety. We should be debating implementation issues less and debating what we want the specification for a robust language to state.  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Jun 86 02:26:45 EDT Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 29 Jun 86 22:35:45 PDT Date: 30 Jun 1986 01:35-EDT Sender: NGALL@G.BBN.COM Subject: Re: Argument lists: a proposal to shoot at From: NGALL@G.BBN.COM To: Fahlman@C.CS.CMU.EDU Cc: common-lisp@SU-AI.ARPA Message-ID: <[G.BBN.COM]30-Jun-86 01:35:20.NGALL> In-Reply-To: Date: Thu, 26 Jun 1986 23:51 EDT From: "Scott E. Fahlman" To: NGALL@BBNG.ARPA Subject: Argument lists: a proposal to shoot at In-Reply-To: Msg of 26 Jun 1986 19:17-EDT from NGALL at G.BBN.COM Message-ID: Your encoding scheme does not let me see the number of 'probably-stack-based' parameters (i.e., P+Q) given a function that has a &rest param and no &key params. This makes it impossible to provide an encapsulation that would use &rest only where necessary (it would force the use of a &rest parameter for all args beyond the required parameters). Sorry, maybe I'm being dense, but I don't understand this. What is it that an encapsulation can do better if it can see P+Q ? Why do you want to rip the lid off this particular black box? -- Scott What follows is some code that demonstrates what I had in mind. The function ENCAPPED is the function that my encapsulation program has to put a wrapper around. ENCAP1 is an example of the kind of wrapper that is possible when both Q and P are known. ENCAP2 is an example of the kind of wrapper that must be used when only Q is known. (I am ignore the issue of keywords here.) (defvar *defaulted-optional-marker* (make-symbol "DEFAULTED-OPTIONAL-MARKER")) (defun encap1 (r1 r2 &optional (o1 *defaulted-optional-marker*) (o2 *defaulted-optional-marker*) (o3 *defaulted-optional-marker*) &rest rest) (declare (optimize (speed 3) (safety 0) (space 0))) (prog2 t ;; (before) (cond ((eq o1 *defaulted-optional-marker*) (encapped r1 r2)) ((eq o2 *defaulted-optional-marker*) (encapped r1 r2 o1)) ((eq o3 *defaulted-optional-marker*) (encapped r1 r2 o1 o2)) ((null rest) (encapped r1 r2 o1 o2 o3)) (t (apply #'encapped r1 r2 o1 o2 o3 rest))) ;; (after) )) (defun encap2 (r1 r2 &rest rest) (declare (optimize (speed 3) (safety 0) (space 0))) (prog2 t ;; (before) (apply #'encapped r1 r2 rest) ;; (after) )) (defun encapped (r1 r2 &optional (o1 1) (o2 2) (o3 3) &rest rest) (setf foor1 r1) (setf foor2 r2) (setf fooo1 o1) (setf fooo2 o2) (setf fooo3 o3) (setf foorest rest)) (defun tencap1 (n) (time (dotimes (i n) (encap1 'a 'b 'c 'd 'e)))) (defun tencap2 (n) (time (dotimes (i n) (encap2 'a 'b 'c 'd 'e)))) Note that ENCAP1 has exactly the same lambda-list-signature as ENCAPPED. ENCAP1 benchmarks considerably faster in three CLs that I tried it in than ENCAP2. Now it is true that one could always use an arbitrary number of optionals in the wrapper lambda-list, but one could not be sure that one had used enough or too many, e.g., if I always use 10 optionals, the wrapper could slow things down if the encapsulated function never took more than 3 args. after the requireds. Its not a big deal, but then neither is returning P. -- Nick  Received: from SU-AI.ARPA by AI.AI.MIT.EDU 30 Jun 86 01:48:13 EDT Received: from BBNG.ARPA by SU-AI.ARPA with TCP; 29 Jun 86 22:35:45 PDT Date: 30 Jun 1986 01:35-EDT Sender: NGALL@G.BBN.COM Subject: Re: Argument lists: a proposal to shoot at From: NGALL@G.BBN.COM To: Fahlman@C.CS.CMU.EDU Cc: common-lisp@SU-AI.ARPA Message-ID: <[G.BBN.COM]30-Jun-86 01:35:20.NGALL> In-Reply-To: Date: Thu, 26 Jun 1986 23:51 EDT From: "Scott E. Fahlman" To: NGALL@BBNG.ARPA Subject: Argument lists: a proposal to shoot at In-Reply-To: Msg of 26 Jun 1986 19:17-EDT from NGALL at G.BBN.COM Message-ID: Your encoding scheme does not let me see the number of 'probably-stack-based' parameters (i.e., P+Q) given a function that has a &rest param and no &key params. This makes it impossible to provide an encapsulation that would use &rest only where necessary (it would force the use of a &rest parameter for all args beyond the required parameters). Sorry, maybe I'm being dense, but I don't understand this. What is it that an encapsulation can do better if it can see P+Q ? Why do you want to rip the lid off this particular black box? -- Scott What follows is some code that demonstrates what I had in mind. The function ENCAPPED is the function that my encapsulation program has to put a wrapper around. ENCAP1 is an example of the kind of wrapper that is possible when both Q and P are known. ENCAP2 is an example of the kind of wrapper that must be used when only Q is known. (I am ignore the issue of keywords here.) (defvar *defaulted-optional-marker* (make-symbol "DEFAULTED-OPTIONAL-MARKER")) (defun encap1 (r1 r2 &optional (o1 *defaulted-optional-marker*) (o2 *defaulted-optional-marker*) (o3 *defaulted-optional-marker*) &rest rest) (declare (optimize (speed 3) (safety 0) (space 0))) (prog2 t ;; (before) (cond ((eq o1 *defaulted-optional-marker*) (encapped r1 r2)) ((eq o2 *defaulted-optional-marker*) (encapped r1 r2 o1)) ((eq o3 *defaulted-optional-marker*) (encapped r1 r2 o1 o2)) ((null rest) (encapped r1 r2 o1 o2 o3)) (t (apply #'encapped r1 r2 o1 o2 o3 rest))) ;; (after) )) (defun encap2 (r1 r2 &rest rest) (declare (optimize (speed 3) (safety 0) (space 0))) (prog2 t ;; (before) (apply #'encapped r1 r2 rest) ;; (after) )) (defun encapped (r1 r2 &optional (o1 1) (o2 2) (o3 3) &rest rest) (setf foor1 r1) (setf foor2 r2) (setf fooo1 o1) (setf fooo2 o2) (setf fooo3 o3) (setf foorest rest)) (defun tencap1 (n) (time (dotimes (i n) (encap1 'a 'b 'c 'd 'e)))) (defun tencap2 (n) (time (dotimes (i n) (encap2 'a 'b 'c 'd 'e)))) Note that ENCAP1 has exactly the same lambda-list-signature as ENCAPPED. ENCAP1 benchmarks considerably faster in three CLs that I tried it in than ENCAP2. Now it is true that one could always use an arbitrary number of optionals in the wrapper lambda-list, but one could not be sure that one had used enough or too many, e.g., if I always use 10 optionals, the wrapper could slow things down if the encapsulated function never took more than 3 args. after the requireds. Its not a big deal, but then neither is returning P. -- Nick