Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 30 Nov 87 02:14:29 EST Received: from CAEN.ENGIN.UMICH.EDU by SAIL.STANFORD.EDU with TCP; 29 Nov 87 22:52:55 PST Received: by caen.engin.umich.edu (5.54/umix-2.0) id AA03082; Mon, 30 Nov 87 01:39:01 EST Date: Mon, 30 Nov 87 01:39:01 EST From: conliffe@caen.engin.umich.edu (darryl c conliffe) Message-Id: <8711300639.AA03082@caen.engin.umich.edu> To: Common-Lisp@SAIL.Stanford.Edu Subject: List membership? I am interested - what news is here? - Darryl C. Conliffe  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Nov 87 16:58:12 EST Received: from AI.WISC.EDU by SAIL.STANFORD.EDU with TCP; 24 Nov 87 13:40:00 PST Date: Tue, 24 Nov 87 15:39:43 CST From: neves@cs.wisc.edu (David M. Neves) Message-Id: <8711242139.AA12265@ai.wisc.edu> Received: by ai.wisc.edu; Tue, 24 Nov 87 15:39:43 CST To: common-lisp@sail.stanford.edu Cc: neves@cs.wisc.edu Subject: changing the value of *package* within a load? When our students log into one of our Lisp Machines (Xerox 1108s) an init file is loaded that initializes certain things for them. One of the things I would like the init file to set is the value of *package*. Unfortunately the load function protects *package* and reinstates the value it had before load was called. Is there any way (even a kludge) that I can permanently change the value of *package* when a file is being loaded with load? (I realize that one solution is to code my own version of load that doesn't save away *package*.) -Thanks, David  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 20 Nov 87 17:48:32 EST Received: from XX.LCS.MIT.EDU by SAIL.STANFORD.EDU with TCP; 20 Nov 87 14:29:22 PST Received: from RTS-12.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 20 Nov 87 17:22-EST Message-Id: <2773434123-6011396@RTS-12> Sender: cerys@RTS-12 Date: Fri, 20 Nov 87 17:22:03 EST From: "Daniel L. Cerys" To: vax135!lcuxle!elia@ucbvax.Berkeley.EDU (Weixelbaum Elia) Cc: common-lisp@sail.stanford.edu Subject: Re: assoc question In-Reply-To: Msg of Thu, 19 Nov 87 10:41:03 EST from vax135!lcuxle!elia@ucbvax.Berkeley.EDU (Weixelbaum Elia) > Franz Common Lisp and Xerox Common Lisp > follow the book and permit :key for just assoc (and rassoc), while KCL and > TI Explorer don't allow :key at all. On your Explorer, you are probably either using Zetalisp or you are running with very old software (Release 2). The Common-Lisp ASSOC in Release 3.0 of the Explorer follows CLtL and allows for a :KEY arg. > In any event, there should certainly > not be an inconsistency. I agree, but I think all of the ASSOC functions should accept a :KEY arg. Alists are commonly used in Lisp. Of the following, the ASSOC-IF version is much easier to read. ;;ALIST is an alist where the CAR's are objects (eg persons) (assoc-if #'over-the-hill-p alist :key #'age) (find-if #'over-the-hill-p alist :key #'(lambda (x) (age (car x)))) Since alists are in common use, and it would make the ASSOC functions consistent with FIND et al, the ASSOC functions should also accept :KEY args.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 19 Nov 87 16:27:29 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 19 Nov 87 13:09:54 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 284243; Thu 19-Nov-87 15:10:25 EST Date: Thu, 19 Nov 87 15:10 EST From: David A. Moon Subject: assoc question To: Weixelbaum Elia cc: common-lisp@SAIL.STANFORD.EDU In-Reply-To: <8711191541.AA27647@lcuxle.UUCP> Message-ID: <19871119201019.5.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Thu, 19 Nov 87 10:41:03 EST From: vax135!lcuxle!elia@ucbvax.Berkeley.EDU (Weixelbaum Elia) According to CLtL (pp 279-281), assoc permits the keyword :key, but neither assoc-if nor assoc-if-not allow it (same for rassoc, rassoc-if, and rassoc-if-not). The Cleanup subcommittee of X3J13 has addressed this issue, but apparently it's on hold right now while higher priority things are attended to, although the proposal really just needs some editorial work before it's presented to X3J13. My own opinion is that the -if and -if-not ones should take keys also.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 19 Nov 87 14:37:44 EST Received: from [128.81.41.234] by SAIL.STANFORD.EDU with TCP; 19 Nov 87 11:16:26 PST Received: from SWAN.SCRC.Symbolics.COM by MEAD.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 112217; Thu 19-Nov-87 14:02:22 EST Date: Thu, 19 Nov 87 14:01 EST From: David C. Plummer Subject: assoc question To: Weixelbaum Elia , common-lisp@sail.stanford.edu In-Reply-To: <8711191541.AA27647@lcuxle.UUCP> Message-ID: <19871119190135.5.DCP@SWAN.SCRC.Symbolics.COM> Date: Thu, 19 Nov 87 10:41:03 EST From: vax135!lcuxle!elia@ucbvax.Berkeley.EDU (Weixelbaum Elia) ... I think it should not be allowed at all since assoc lists are defined as pairs such that the keys are the cars of the respective pairs, not some function of the respective cars. In any event, there should certainly not be an inconsistency. I think this is because an "Association list" is poorly defined. It appears to be historically defined. A better definition of the CLtL'84 intent might be that the car /contains/ the key of the association, and by default the car /is/ the key of the association. I agree it does appear to be inconsistent (with FIND, COUNT and POSITION) that ASSOC-IF doesn't take a :KEY argument.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 19 Nov 87 13:18:01 EST Received: from UCBVAX.Berkeley.EDU by SAIL.STANFORD.EDU with TCP; 19 Nov 87 09:58:56 PST Received: by ucbvax.Berkeley.EDU (5.58/1.26) id AA26105; Thu, 19 Nov 87 10:01:43 PST Received: by lcuxle.UUCP (4.6/4.2) id AA27647; Thu, 19 Nov 87 10:41:03 EST Date: Thu, 19 Nov 87 10:41:03 EST From: vax135!lcuxle!elia@ucbvax.Berkeley.EDU (Weixelbaum Elia) Message-Id: <8711191541.AA27647@lcuxle.UUCP> To: common-lisp@sail.stanford.edu Subject: assoc question I don't know if this was discussed before, so please excuse the possible repetition. According to CLtL (pp 279-281), assoc permits the keyword :key, but neither assoc-if nor assoc-if-not allow it (same for rassoc, rassoc-if, and rassoc-if-not). Franz Common Lisp and Xerox Common Lisp follow the book and permit :key for just assoc (and rassoc), while KCL and TI Explorer don't allow :key at all. I think it should not be allowed at all since assoc lists are defined as pairs such that the keys are the cars of the respective pairs, not some function of the respective cars. In any event, there should certainly not be an inconsistency. Elia Weixelbaum  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 18 Nov 87 03:15:22 EST Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 17 Nov 87 23:56:19 PST Received: from relay2.cs.net by RELAY.CS.NET id ab06854; 18 Nov 87 2:50 EST Received: from utokyo-relay by RELAY.CS.NET id ad13095; 18 Nov 87 2:48 EST Received: by ccut.cc.u-tokyo.junet (5.51/6.2.9Junet) id AA16866; Wed, 18 Nov 87 16:15:40 JST Received: by titcca.cc.titech.junet (4.12/6.3Junet-BETA) id AA26556; Wed, 18 Nov 87 16:10:00 jst Return-Path: Received: by nttlab.ntt.jp (4.12/6.2NTT.h) with TCP; Wed, 18 Nov 87 15:43:39 jst Received: by tutics.tut.junet (ver3.3/6.2J/systemV) id AA01704; Wed, 18 Nov 87 15:23:57 jst Message-Id: <8711181523.AA01704@tutics.tut.junet> Date: Wed, 18 Nov 87 15:23:57 jst From: Taiichi Yuasa To: common-lisp@SAIL.STANFORD.EDU Subject: new address I recently moved to Toyohashi University of Technology, which is located somewhere between Kyoto and Tokyo, Japan. My new mail address is yuasa@tutics.tut.junet from within Japan, and yuasa%tutics.tut.junet%utokyo-relay.csnet@RELAY.CS.NET from csnet in US. Sincerely, Taiichi Yuasa, Dr. Lecturer Department of Information and Computer Science Toyohashi University of Technology Tempaku-cho, Toyohashi, 440, Japan tel: 0532-47-0111 ext 503  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 18 Nov 87 01:49:19 EST Received: from THINK.COM by SAIL.STANFORD.EDU with TCP; 17 Nov 87 22:27:31 PST Return-Path: <@Think.COM:barmar@Think.COM> Received: from sauron.think.com by Think.COM; Wed, 18 Nov 87 01:26:46 EST Received: from OCCAM.THINK.COM by sauron.think.com; Wed, 18 Nov 87 01:26:42 EST Date: Wed, 18 Nov 87 01:27 EST From: Barry Margolin Subject: Implementation Questions To: LINNDR%VUENGVAX.BITNET@forsythe.stanford.edu Cc: common-lisp@sail.stanford.edu In-Reply-To: <8711180458.AA21295@Think.COM> Message-Id: <871118012756.0.BARMAR@OCCAM.THINK.COM> Date: Tue, 17 Nov 87 22:55 CDT From: (David Linn) If defun is a macro, to what does it expand? My best guess would be a (setf (symbol-function 'name) ...) based on the discussion of symbol-function on page 90. My question then becomes: Into what does the setf form expand? Is it intended that the update function for symbol-value have an implmentation-dependent name? ^^^^^^^^^^^^ You meant SYMBOL-FUNCTION there, didn't you? The same sort of question applies to the update function for macro-function. MOST update functions have implementation-dependent names. There are no Common Lisp updaters for CAR, CDR, AREF, defstruct accessors, etc. The only accessors I can think of offhand that have defined updaters are SYMBOL-VALUE (the updater is SET), LDB (DPB), LOAD-BYTE (DEPOSIT-BYTE), and CHAR-BIT (SET-CHAR-BIT). 2) LAMBDA-LISTS - Is the order of lambda-list keywords fixed? (p. 60) Will the order alway be &optional/&rest/&key/&aux (meaning that if the keyword is used, it will be in the order given)? It seems likely that this is so but I'm not sure. Since it doesn't say that they can be in any order, don't assume that they can. I know some implementations are picky. The description shows the order that is defined to be portable; if a program supplies them in a different order then it "is an error". I think there was a proposal in X3J13 regarding relaxing this somewhat, but I'm not sure. On the other hand, perhaps the proposal was to make the text explicit about the order requirement. barmar  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 18 Nov 87 00:21:56 EST Received: from LINDY.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 17 Nov 87 20:58:02 PST Received: by lindy.stanford.edu; Tue, 17 Nov 87 20:55:47 PST Received: by Forsythe.Stanford.EDU; Tue, 17 Nov 87 20:56:34 PST Date: Tue, 17 Nov 87 22:55 CDT From: (David Linn) Subject: Implementation Questions To: common-lisp@sail.stanford.edu X-Original-To: common-lisp@sail.stanford.edu, LINNDR The recent discussion on CL environments sent me back to my CLtL in hopes that I could better understand what was being discussed. Thie review of CLtL revealed several topics that I clearly do not understand. I apologize in advance if these have been discussed before but I can find no clear answer in CLtL. 1) DEFUN - Is this a special form or a macro? From CLtL, p. 67: The _defun_ special form is the usual means for defining named functions. The very next line declares that defun is a [Macro]. This view is supported by the absence of defun from the list of special forms on page 57. (BTW, the index entry for defun muddies the water by listing page 57 (not 67) as the first entry, the entry which for (all?) other defined words is the page of the definition.) If defun is a macro, to what does it expand? My best guess would be a (setf (symbol-function 'name) ...) based on the discussion of symbol-function on page 90. My question then becomes: Into what does the setf form expand? Is it intended that the update function for symbol-value have an implmentation-dependent name? The same sort of question applies to the update function for macro-function. 2) LAMBDA-LISTS - Is the order of lambda-list keywords fixed? (p. 60) Will the order alway be &optional/&rest/&key/&aux (meaning that if the keyword is used, it will be in the order given)? It seems likely that this is so but I'm not sure. David Linn BITNET: linndr@vuengvax INTERNET(new): linndr@vuengvax.vanderbilt.edu INTERNET(old): linndr%vuengvax.bitnet@wiscvm.wisc.arpa UUCP: ...!uunet!vuse!drl  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 17 Nov 87 19:31:45 EST Received: from RUTGERS.EDU by SAIL.STANFORD.EDU with TCP; 17 Nov 87 16:09:21 PST Received: by RUTGERS.EDU (5.54/1.14) with UUCP id AA24821; Tue, 17 Nov 87 19:12:44 EST Received: from pyrnova.pyramid.COM (manpyrnova) by pyramid.UUCP (5.51/OSx4.0b-870424) id AA26981; Tue, 17 Nov 87 15:10:51 PST Received: by pyrnova.pyramid.COM (5.51/OSx4.0b-870424) id AA28461; Tue, 17 Nov 87 15:11:38 PST Date: 17 Nov 1987 15:11 PST From: David Bein Subject: fill-pointers and adjust-array To: common-lisp@sail.stanford.edu@RUTGERS.EDU Message-Id: <564186732/bein@pyrnova> Does anyone have a clear idea (page 297 CLtL) of what is supposed to happen to the fill-pointer (this assumes the array is a vector) when none is specified in the argument list to ADJUST-ARRAY? I could imagine: (1) Reset it to the new length of the array. (2) Reset it to 0. (3) Reset it to the minimum of the new length and the current value. (4) Not changing it. I am somewhat uncomfortable with it changing and would prefer something in the spec which reads: The :fill-pointer argument defaults to the current value of the vector's fill-pointer. If the fill-pointer is out of bounds after any adjustment, an error should be signaled. With this there would be no fuzziness about the fill-pointer changing magically and it would be well defined in the same way it is in the other places where fill-pointers have special meaning. Comments? --David p.s. Sorry if this has been answered sometime in the past.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 17 Nov 87 19:31:29 EST Received: from RUTGERS.EDU by SAIL.STANFORD.EDU with TCP; 17 Nov 87 16:09:23 PST Received: by RUTGERS.EDU (5.54/1.14) with UUCP id AA24830; Tue, 17 Nov 87 19:12:55 EST Received: from pyrnova.pyramid.COM (manpyrnova) by pyramid.UUCP (5.51/OSx4.0b-870424) id AA27328; Tue, 17 Nov 87 15:34:47 PST Received: by pyrnova.pyramid.COM (5.51/OSx4.0b-870424) id AA29596; Tue, 17 Nov 87 15:35:34 PST Date: 17 Nov 1987 15:30-PST From: David Bein Subject: fill-pointers and adjust-array To: common-lisp@sail.stanford.edu@RUTGERS.EDU Message-Id: <564190247/bein@pyrnova> Regarding the last message, I think that ADJUST-ARRAY should have the following semantics for its :fill-pointer argument. (1) If :fill-pointer is NIL or not supplied, it defaults to the current value of the vector's fill-pointer. (2) If :fill-pointer is T, then the fill-pointer is set to the minimum of its current value or the length of the resulting vector. (3) Otherwise, :fill-pointer should be a non-negative integer less than or equal to the size of the resulting array. In all cases, an error occurs if the final value of the fill-pointer is out of bounds. --David  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 16 Nov 87 22:14:35 EST Received: from XX.LCS.MIT.EDU by SAIL.STANFORD.EDU with TCP; 16 Nov 87 18:52:22 PST Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 16 Nov 87 21:51-EST Received: from ACORN.Gold-Hill.DialNet.Symbolics.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 68043; 16 Nov 87 21:45:06-EST Received: from HPHCS_.Gold-Hill.DialNet.Symbolics.COM by ACORN.Gold-Hill.DialNet.Symbolics.COM via CHAOS with CHAOS-MAIL id 86411; Mon 16-Nov-87 20:51:58-EST Date: Mon, 16 Nov 1987 20:02 EST From: ejs%acorn@oak.lcs.mit.edu To: R Dunbar Poor Subject: [Question regarding FORMAT with ~:^ within ~:{] cc: common-lisp@sail.stanford.edu > Date: Mon, 9 Nov 87 18:53:10 PST > From: R Dunbar Poor > To: labrea!common-lisp%sail.stanford.edu@labrea.stanford.edu > Subject: Question regarding FORMAT with ~:^ within ~:{ > > ... > > (format nil "~:{~@?~:^...~}" '(("a") ("b"))) > > > MY CLAIM: It should return "a". > For what it's worth, GCLISP 3.0 returns "a" as well.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 15 Nov 87 21:36:05 EST Received: from C.CS.CMU.EDU by SAIL.STANFORD.EDU with TCP; 15 Nov 87 18:14:43 PST Received: ID ; Sun 15 Nov 87 21:12:35-EST Date: Sun, 15 Nov 1987 21:12 EST Message-ID: Sender: FAHLMAN@C.CS.CMU.EDU From: "Scott E. Fahlman" To: Don Morrison Cc: common-lisp@SAIL.STANFORD.EDU Subject: destructuring in macrolet? In-reply-to: Msg of 13 Nov 1987 18:36-EST from Don Morrison The language on page 146 of CLtL clearly implies that macrolet does not support defmacro-style arglist destructuring: Defmacro, unlike any other COMMON LISP construct that has a lambda-list as part of its syntax, provides an additional facility known as destructuring. Well, the definition of macrolet says that it uses the same format as defmacro, and I read that as requiring the same handling of the arglist. I think that the use of the phrase "any other" in the paragraph you cite is just a bit of sloppy wording. -- Scott  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 14 Nov 87 18:11:06 EST Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 14 Nov 87 14:52:54 PST Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 279905; Sat 14-Nov-87 17:52:14 EST Date: Sat, 14 Nov 87 17:52 EST From: David A. Moon Subject: questions about CLOS [original subject: equality of structures] To: goldman@vaxa.isi.edu cc: COMMON-LISP@SAIL.STANFORD.EDU, Common-Lisp-Object-System@SAIL.STANFORD.EDU In-Reply-To: <8711092000.AA14975@vaxa.isi.edu> Message-ID: <19871114225202.0.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Mon, 09 Nov 87 12:00:35 PST From: goldman@vaxa.isi.edu Re: the suggestion that CLOS should subsume (by convention or otherwise) uses of un:TYPEed defstruct types? I presume that this takes care of the issue of EQUAL, because the CLOS specifies the semantics of EQUAL for its class instances? (What is the specification, by the way?) CLOS does not currently say anything about how the functions EQUAL, EQUALP, and EQL behave on instances of standard classes (you can read the last four words as equivalent to "user-defined objects"). It also doesn't say anything about the type-specific equality functions CHAR-EQUAL, CHAR-NOT-EQUAL, TREE-EQUAL, STRING-EQUAL, and STRING-NOT-EQUAL, nor the 6 type-specific = and /= functions. It would fit the structure of CLOS to say that EQUAL and EQUALP will be expanded to generic functions whose behavior can be extended by defining methods. I don't think we would want to allow extending EQL or the type-specific functions, since CLOS does not claim to be so powerful as to allow you to create new types of numbers, characters, or strings. Extending EQ would not make any sense, of course. I suspect the reason CLOS currently shys away from EQUAL and EQUALP is that the equality predicates in Common Lisp are clearly not very well chosen and beg for a lot of cleaning up based on a better theory of what we want. To give just one example, it's peculiar that comparing arrays element-by-element has been bundled together with ignoring alphabetic case. It's probably better to wait for Common Lisp to get its act together before extending CLOS into this area; clearly, equality methods can be added later to the standard or to an individual implementation without any incompatibilities, so there's no rush. A possible additional reason is that CLOS does not deal terribly well with symmetric two-argument functions such as EQUAL. It's possible to specialize them, but you usually have to define a lot of seemingly extraneous methods, since the generic function dispatch mechanism has no concept of commutativity nor of type translation. But I would be loathe to replace my un:TYPEed defstructs with DEFCLASSes if I gave up substantial efficiency when I only wanted the limited power provided by the "record structure" semantics. Are there enough declarations available in CLOS so that I could get my compiled accesses to slots of such instances down to the equivalent of an array element reference? As an implementation-independent language specification, CLOS does not and cannot directly address this issue. However, it's clear what would generally need to be declared to allow implementations to do something like that, although you would have to look at each individual implementation to see whether it was faster or slower than arrays with declarations; you might even find an implementation where slot access was faster than array access even without declarations. Basically what you need to declare is that the class cannot be redefined or subclassed. Some members of the CLOS subcommittee volunteered to propose declaration names and syntaxes to allow for this type of optimization, but they haven't finished yet. However, it is intended that most CLOS implementations either be very efficient or have a way to make them very efficient through declarations.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 14 Nov 87 17:38:14 EST Received: from THINK.COM by SAIL.STANFORD.EDU with TCP; 14 Nov 87 14:16:10 PST Return-Path: <@Think.COM:barmar@Think.COM> Received: from sauron.think.com by Think.COM; Sat, 14 Nov 87 17:15:34 EST Received: from OCCAM.THINK.COM by sauron.think.com; Sat, 14 Nov 87 17:14:30 EST Date: Sat, 14 Nov 87 17:16 EST From: Barry Margolin Subject: reduce should allow an accessor function to be specified To: Mark Bromley Cc: common-lisp@Think.COM In-Reply-To: <8711140938.AA17929@pozzo> Message-Id: <871114171605.6.BARMAR@OCCAM.THINK.COM> Date: Sat, 14 Nov 87 04:38:32 est From: Mark Bromley Currently, the function is directly applied to the elements of the sequence. This limits the utility of reduce. Summing the cars of a sequence of conses is cumbersome using reduce, and is possible only because numbers can be distinguished from conses at run time. E.g. (reduce #'(lambda (a b) (+ (if (consp a) (car a) a) (if (consp b) (car b) b))) sequence) It would be much more natural to be able to use the following (reduce #'+ sequence :key #'car). A better interim solution, except for the fact that it conses more, would be to use (reduce #'+ (map 'vector #'car sequence)) This doesn't depend on distinguishing previous results from input. barmar  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 14 Nov 87 17:21:40 EST Received: from THINK.COM by SAIL.STANFORD.EDU with TCP; 14 Nov 87 14:05:23 PST Return-Path: <@Think.COM:barmar@Think.COM> Received: from sauron.think.com by Think.COM; Sat, 14 Nov 87 17:04:41 EST Received: from OCCAM.THINK.COM by sauron.think.com; Sat, 14 Nov 87 17:04:36 EST Date: Sat, 14 Nov 87 17:06 EST From: Barry Margolin Subject: Re: Local redefs of special forms To: David N Gray Cc: COMMON-LISP@sail.stanford.edu In-Reply-To: <2772843873-1355116@Kelvin> Message-Id: <871114170611.4.BARMAR@OCCAM.THINK.COM> Date: Fri, 13 Nov 87 20:24:33 CST From: David N Gray Jeff, But DEFSUBST is not part of Common Lisp, and I imagine that this is part of the reason it isn't. Furthermore, DEFSUBSTs and INLINE functions are not the same thing. Doing it the Common Lisp way: (proclaim '(inline foo)) (defun foo (x) (car x)) On Symbolics Lispms, DEFSUBST is simply a macro, and (defsubst foo (x) (car x)) expands into precisely the above PROCLAIM followed by DEFUN. barmar  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 14 Nov 87 12:39:23 EST Received: from THINK.COM by SAIL.STANFORD.EDU with TCP; 14 Nov 87 09:22:37 PST Return-Path: Received: from ELEPHANT-BUTTE.SCRC.Symbolics.COM by Think.COM; Sat, 14 Nov 87 12:21:46 EST Received: from SWAN.SCRC.Symbolics.COM by ELEPHANT-BUTTE.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 235305; Sat 14-Nov-87 12:21:32 EST Date: Sat, 14 Nov 87 12:21 EST From: David C. Plummer Subject: reduce should allow an accessor function to be specified To: Mark Bromley , common-lisp@Think.COM In-Reply-To: <8711140938.AA17929@pozzo> Message-Id: <19871114172119.6.DCP@SWAN.SCRC.Symbolics.COM> Date: Sat, 14 Nov 87 04:38:32 est From: Mark Bromley ... It would be much more natural to be able to use the following (reduce #'+ sequence :key #'car). Several people have suggested this functionality and I think most of us think it is reasonable. Many people also believe the :KEY is not the right keyword for extraction on the grounds that keys are for predicates, not for operators. We even had a naming contest for the name of extraction keyword. I don't remember if there was a clear winner. I really don't know what to do with this conversation. We've been over this about 5 times now and it seems like beating a dead horse to have another long discussion. On the other hand, we never reached consensus/conclusion during any of those previous attempts, so this issue will come up again and again until the functionality exists.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 14 Nov 87 11:46:52 EST Received: from THINK.COM by SAIL.STANFORD.EDU with TCP; 14 Nov 87 08:26:05 PST Return-Path: Received: from OZ.AI.MIT.EDU (AI.AI.MIT.EDU) by Think.COM; Sat, 14 Nov 87 11:25:23 EST Date: Sat, 14 Nov 1987 11:26 EST Message-Id: From: STEVER%OZ.AI.MIT.EDU@xx.lcs.mit.edu To: Mark Bromley Cc: common-lisp@Think.COM Subject: reduce should allow an accessor function to be specified In-Reply-To: Msg of 14 Nov 1987 04:38-EST from Mark Bromley Date: Saturday, 14 November 1987 04:38-EST From: Mark Bromley [request for :KEY argument to REDUCE] Summing the cars of a sequence of conses is cumbersome using reduce: (reduce #'(lambda (a b) (+ (if (consp a) (car a) a) (if (consp b) (car b) b))) sequence) Could you clean this up by using: (reduce #'(lambda (total cons) (+ total (car cons))) sequence :initial-value 0) ??? It's still not pretty, but it's a bit closer to 'nice'. It treats empty sequences differently, though. My version returns 0 (the :INITIAL-VALUE argument), while the other signals an error (the LAMBDA is called with 0 arguments). It would be much more natural to be able to use the following (reduce #'+ sequence :key #'car). I agree. :KEY is a much more elegant way to solve the problem. -- Stephen  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 14 Nov 87 04:57:40 EST Received: from THINK.COM by SAIL.STANFORD.EDU with TCP; 14 Nov 87 01:39:19 PST Return-Path: Received: from pozzo by Think.COM; Sat, 14 Nov 87 04:38:39 EST Received: by pozzo; Sat, 14 Nov 87 04:38:32 est Date: Sat, 14 Nov 87 04:38:32 est From: Mark Bromley Message-Id: <8711140938.AA17929@pozzo> To: common-lisp@Think.COM Subject: reduce should allow an accessor function to be specified Currently, the function is directly applied to the elements of the sequence. This limits the utility of reduce. Summing the cars of a sequence of conses is cumbersome using reduce, and is possible only because numbers can be distinguished from conses at run time. E.g. (reduce #'(lambda (a b) (+ (if (consp a) (car a) a) (if (consp b) (car b) b))) sequence) It would be much more natural to be able to use the following (reduce #'+ sequence :key #'car). Mark Bromley bromley@think.com  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 14 Nov 87 02:26:21 EST Received: from LABREA.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 13 Nov 87 23:03:03 PST Received: by labrea.stanford.edu; Fri, 13 Nov 87 23:01:21 PST Received: from bhopal.lucid.com by edsel id AA05420g; Fri, 13 Nov 87 22:50:27 PST Received: by bhopal id AA14252g; Fri, 13 Nov 87 22:50:26 PST Date: Fri, 13 Nov 87 22:50:26 PST From: Jon L White Message-Id: <8711140650.AA14252@bhopal.lucid.com> To: labrea!DFM%Palladian.COM@labrea.stanford.edu Cc: labrea!barmar%think.com@labrea.stanford.edu, labrea!common-lisp%sail@labrea.stanford.edu In-Reply-To: Don Morrison's message of Fri, 13 Nov 87 18:36 EST <871113183615.4.DFM@WHITBY.Palladian.COM> Subject: destructuring in macrolet? It certainly would be ill-design to have a substantially different syntax for the lexically-local versions of definers than for the global ones. -- JonL --  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Nov 87 23:35:59 EST Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 13 Nov 87 20:15:56 PST Received: from relay2.cs.net by RELAY.CS.NET id ad14665; 13 Nov 87 22:27 EST Received: from csl.ti.com by RELAY.CS.NET id ae15242; 13 Nov 87 22:24 EST Received: from Kelvin by tilde id AA09293; Fri, 13 Nov 87 20:24:03 CST Message-Id: <2772843873-1355116@Kelvin> Sender: GRAY%kelvin.csc.ti.com@RELAY.CS.NET Date: Fri, 13 Nov 87 20:24:33 CST From: David N Gray To: COMMON-LISP@SAIL.STANFORD.EDU Subject: Re: Local redefs of special forms > From: Jeff Barnett > Date: 12 Nov 87 05:21:47 GMT > > If you allow FLETS, et al, to shadow special forms, there is an implementation > issue with inline function expansions nee DEFSUBSTs. The compiler cannot > substitute the function body and optimize as some compilers now do. In fact > the body must be (re)expanded in the null lexical environment no matter what. > Consider the following example: > > (defsubst foo (x) (car x)) > > (flet((car (l) (cdr l))) > (foo (car q))) > > The value of the flet should be (cadr q) while if the compiler is not careful, > the result will be (cddr q) instead. ... Jeff, But DEFSUBST is not part of Common Lisp, and I imagine that this is part of the reason it isn't. Furthermore, DEFSUBSTs and INLINE functions are not the same thing. Doing it the Common Lisp way: (proclaim '(inline foo)) (defun foo (x) (car x)) the compiler is required to ensure that any inline expansion preserves the semantics of the function call. Rather than attempting to achieve this as a source transformation, our compiler does the expansion during compilation, after all local function and variable names have been replaced by pointers to the appropriate symbol table entries. Thus for something that can be done by either a macro or inline function (a DEFSUBST is considered to be a macro in this context), it is preferable to use an inline function and let the compiler worry about getting the environments right. The problem remains for things that have to be implemented as macros because they don't follow the syntax or semantics of a function call. -- David Gray  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Nov 87 23:35:33 EST Received: from THINK.COM by SAIL.STANFORD.EDU with TCP; 13 Nov 87 16:40:20 PST Return-Path: <@Think.COM:barmar@Think.COM> Received: from sauron.think.com by Think.COM; Fri, 13 Nov 87 19:39:39 EST Received: from OCCAM.THINK.COM by sauron.think.com; Fri, 13 Nov 87 19:39:34 EST Date: Fri, 13 Nov 87 19:41 EST From: Barry Margolin Subject: destructuring in macrolet? To: Don Morrison Cc: common-lisp@sail.stanford.edu In-Reply-To: <871113183615.4.DFM@WHITBY.Palladian.COM> Message-Id: <871113194113.8.BARMAR@OCCAM.THINK.COM> Date: Fri, 13 Nov 87 18:36 EST From: Don Morrison The language on page 146 of CLtL clearly implies that macrolet does not support defmacro-style arglist destructuring: Defmacro, unlike any other COMMON LISP construct that has a lambda-list as part of its syntax, provides an additional facility known as destructuring. According to the definition of MACROLET on page 113, it doesn't take a lambda-list, it takes a "varlist". And at the top of page 114 it says "MACROLET ... defines local macros, using the same format used by DEFMACRO." I interpret that to mean that since DEFMACRO destructures, so does MACROLET. barmar  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Nov 87 23:35:24 EST Received: from XX.LCS.MIT.EDU by SAIL.STANFORD.EDU with TCP; 13 Nov 87 15:59:33 PST Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 13 Nov 87 18:40-EST Received: from JASPER.Palladian.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 67786; 13 Nov 87 18:39:05-EST Received: from WHITBY.Palladian.COM by JASPER.Palladian.COM via INTERNET with SMTP id 14069; 13 Nov 87 18:32:36-EST Date: Fri, 13 Nov 87 18:36 EST From: Don Morrison Subject: destructuring in macrolet? To: common-lisp@sail.stanford.edu Message-ID: <871113183615.4.DFM@WHITBY.Palladian.COM> Reply-To: Don Morrison The language on page 146 of CLtL clearly implies that macrolet does not support defmacro-style arglist destructuring: Defmacro, unlike any other COMMON LISP construct that has a lambda-list as part of its syntax, provides an additional facility known as destructuring. These seems like an oversight. Both implementations I tried (Symbolics and Lucid, which latter is usually fairly strict about supplying only those features that CLtL requires) do, in fact, support destructuring in macrolet. While any implementation can clearly support destructuring within macro, it would be nice if Common LISP required all implementations to do so, so that it can be used in portable code. I can see no reason, aesthetic or implementational, for prohibiting it, once you accept that macrolet's going to exist at all.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Nov 87 19:57:07 EST Received: from THINK.COM by SAIL.STANFORD.EDU with TCP; 13 Nov 87 16:40:20 PST Return-Path: <@Think.COM:barmar@Think.COM> Received: from sauron.think.com by Think.COM; Fri, 13 Nov 87 19:39:39 EST Received: from OCCAM.THINK.COM by sauron.think.com; Fri, 13 Nov 87 19:39:34 EST Date: Fri, 13 Nov 87 19:41 EST From: Barry Margolin Subject: destructuring in macrolet? To: Don Morrison Cc: common-lisp@sail.stanford.edu In-Reply-To: <871113183615.4.DFM@WHITBY.Palladian.COM> Message-Id: <871113194113.8.BARMAR@OCCAM.THINK.COM> Date: Fri, 13 Nov 87 18:36 EST From: Don Morrison The language on page 146 of CLtL clearly implies that macrolet does not support defmacro-style arglist destructuring: Defmacro, unlike any other COMMON LISP construct that has a lambda-list as part of its syntax, provides an additional facility known as destructuring. According to the definition of MACROLET on page 113, it doesn't take a lambda-list, it takes a "varlist". And at the top of page 114 it says "MACROLET ... defines local macros, using the same format used by DEFMACRO." I interpret that to mean that since DEFMACRO destructures, so does MACROLET. barmar  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Nov 87 19:21:55 EST Received: from XX.LCS.MIT.EDU by SAIL.STANFORD.EDU with TCP; 13 Nov 87 15:59:33 PST Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 13 Nov 87 18:40-EST Received: from JASPER.Palladian.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 67786; 13 Nov 87 18:39:05-EST Received: from WHITBY.Palladian.COM by JASPER.Palladian.COM via INTERNET with SMTP id 14069; 13 Nov 87 18:32:36-EST Date: Fri, 13 Nov 87 18:36 EST From: Don Morrison Subject: destructuring in macrolet? To: common-lisp@sail.stanford.edu Message-ID: <871113183615.4.DFM@WHITBY.Palladian.COM> Reply-To: Don Morrison The language on page 146 of CLtL clearly implies that macrolet does not support defmacro-style arglist destructuring: Defmacro, unlike any other COMMON LISP construct that has a lambda-list as part of its syntax, provides an additional facility known as destructuring. These seems like an oversight. Both implementations I tried (Symbolics and Lucid, which latter is usually fairly strict about supplying only those features that CLtL requires) do, in fact, support destructuring in macrolet. While any implementation can clearly support destructuring within macro, it would be nice if Common LISP required all implementations to do so, so that it can be used in portable code. I can see no reason, aesthetic or implementational, for prohibiting it, once you accept that macrolet's going to exist at all.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Nov 87 14:39:01 EST Received: from GORT.CS.BUFFALO.EDU by SAIL.STANFORD.EDU with TCP; 13 Nov 87 11:22:38 PST Received: by gort.cs.Buffalo.EDU (5.58/1.1) id AA24330; Fri, 13 Nov 87 14:21:06 EST Date: Fri, 13 Nov 87 14:21:06 EST From: kumard@cs.Buffalo.EDU (Deepak Kumar) Message-Id: <8711131921.AA24330@gort.cs.Buffalo.EDU> To: Common-Lisp@sail.stanford.edu Subject: Request for adding to mailing list Please add the following address to your mailing list. It is a local alias for Lisp wiz's. Thank you. lispwiz@gort.cs.buffalo.edu Deepak.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Nov 87 02:24:45 EST Received: from C.CS.CMU.EDU by SAIL.STANFORD.EDU with TCP; 12 Nov 87 22:55:23 PST Received: ID ; Thu 12 Nov 87 14:31:38-EST Date: Thu, 12 Nov 1987 02:47 EST Message-ID: From: Skef Wholey To: common-lisp@SAIL.STANFORD.EDU Subject: Missing and desired sequence function. Date: Thursday, 12 November 1987 01:09-EST From: Bob Kanefsky [...] later I realized I wanted it [the BEST function] to return the position as well as the element; [...] Following the lead of FIND, POSITION, and perhaps even COUNT, we could add a few new functions: FIND-BEST, POSITION-BEST (I think BEST-POSITION sounds nicer, though), and COUNT-BEST. This gives a picture of "BEST" functions having a kind of orthagonalilty with the -IF and -IF-NOT forms of these functions; indeed, the argument lists of these forms would be identical to those of the -IF and -IF-NOT functions. Also note that functions of this sort should take a :FROM-END keyword (defaulting to NIL), so that one has control over which "best" item is selected. --Skef  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Nov 87 02:15:10 EST Received: from SPAR-20.ARPA by SAIL.STANFORD.EDU with TCP; 11 Nov 87 22:08:30 PST Received: from MANTIS.SPAR.CAS.SLB.COM (MANTIS.#Internet) by SPAR-20.SPAR.SLB.COM with TCP; Wed 11 Nov 87 22:09:53-PST Date: Wed, 11 Nov 87 22:09 PST From: Bob Kanefsky Subject: Missing and desired sequence function. To: common-lisp@sail.stanford.edu In-Reply-To: <19871111230324.4.DCP@SWAN.SCRC.Symbolics.COM> References: <870923091026.7.7THSON@MOTH.SPAR.CAS.SLB.COM> Message-ID: <871111220942.4.KANEF@MANTIS.SPAR.CAS.SLB.COM> I agree with you that this is a useful feature that is an obvious hole in Common Lisp's sequence functions. As evidence that it's obviously needed, I thought of it six weeks ago independently (or did you see my suggestion to Symbolics Customer Reports, referenced above?). Below is the implementation I used. It's an iterative approach using the MIT LOOP macro, made ugly by the need to handle lists and vectors separately. It's not as elegant as using SORT or REDUCE, but later I realized I wanted it to return the position as well as the element; see below. --Kanef (defun minimize (sequence &key (key 'identity) (test '<)) ;;A generalization of MIN that takes :KEY and :TEST arguments ;;as other Common-Lisp functions do. ;;Examples: (minimize '(1 2 3 4)) is the same as (min 1 2 3 4) but slower. ;; (minimize *people* :key 'height) finds the shortest person. ;; (minimize *people* :key 'age) finds the youngest person. ;; (minimize *people* :key 'age :test '>) finds the oldest person. (declare (values element position key-value)) (macrolet ((doit (type) ;;I know the Symbolics implementations of the other sequence functions use a macro ;;for this called CLI::SEQUENCE-ITERATOR, but the callers of it are all in a restricted ;;source. This macro is the same idea. (let ((iterator (case type (list '(in)) (vector '(being the array-elements of))))) `(loop with best-candidate = (elt sequence 0) with best-offer = (funcall key best-candidate) with best-index = 0 for index from 0 for candidate ,@iterator sequence for offer = (funcall key candidate) when (funcall test offer best-offer) do (setq best-candidate candidate best-offer offer best-index index) finally (return (values best-candidate best-index best-offer)))))) (etypecase sequence (list (doit list)) (vector (doit vector))))) As soon as I went back to writing the caller of the MINIMIZE function, I realized that it would be convenient to have it return the index as well as the element (ala POSITION as well as FIND). (defun minimize (sequence &key (key 'identity) (test '<)) ;;A generalization of MIN that takes :KEY and :TEST arguments ;;as other Common-Lisp functions do. ;;Examples: (minimize '(1 2 3 4)) is the same as (min 1 2 3 4) but slower. ;; (minimize *people* :key 'height) finds the shortest person. ;; (minimize *people* :key 'age) finds the youngest person. ;; (minimize *people* :key 'age :test '>) finds the oldest person. (declare (values element position key-value)) (macrolet ((doit (type) ;;I know the Symbolics implementations of the other sequence functions use a macro ;;for this called CLI::SEQUENCE-ITERATOR, but the callers of it are all in a restricted ;;source. This macro is the same idea. (let ((iterator (case type (list '(in)) (vector '(being the array-elements of))))) `(loop with best-candidate = (elt sequence 0) with best-offer = (funcall key best-candidate) with best-index = 0 for index from 0 for candidate ,@iterator sequence for offer = (funcall key candidate) when (funcall test offer best-offer) do (setq best-candidate candidate best-offer offer best-index index) finally (return (values best-candidate best-index best-offer)))))) (etypecase sequence (list (doit list)) (vector (doit vector)))))  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 12 Nov 87 17:16:19 EST Received: from THINK.COM by SAIL.STANFORD.EDU with TCP; 12 Nov 87 13:54:16 PST Return-Path: <@occam.think.com:barmar@Think.COM> Received: from sauron.think.com by Think.COM; Thu, 12 Nov 87 13:54:29 EST Received: from OCCAM.THINK.COM by sauron.think.com; Thu, 12 Nov 87 13:54:24 EST Date: Thu, 12 Nov 87 13:56 EST From: Barry Margolin Subject: Re: Local redefs of special forms To: Jeff Barnett Cc: common-lisp@sail.stanford.edu In-Reply-To: <8711120203.AA21595@Think.COM> Message-Id: <871112135607.0.BARMAR@OCCAM.THINK.COM> Date: Wed, 11 Nov 87 16:28:54 PST From: Jeff Barnett If you allow FLETS, et al, to shadow special forms, there is an implementation issue with inline function expansions nee DEFSUBSTs. The compiler cannot substitute the function body and optimize as some compilers now do. In fact the body must be (re)expanded in the null lexical environment no matter what. Consider the following example: (defsubst foo (x) (car x)) (flet((car (l) (cdr l))) (foo (car q))) While what you are saying is true, this particular case is not germaine to the discussion, because CAR is not a special form, it is a function. Also, if a compiler is going to do inline substitution, it should take care to use the appropriate environment. I tried the above on a Symbolics lispm and it simply decided not to do the inline substitution; not optimal, but within the standard. The problem you are describing DOES exist, but it is with macros. In the case of inline functions, the compiler can simply punt using the expansion if there is a name clash or use the global definition, but it doesn't have the choice with macros. If you change the above example to (defmacro foo (x) `(car ,x)) you will encounter the problem. This problem that macros violate lexical scoping is well-known, and there is ongoing research on how to deal with it. A proposed solution was the subject of a presentation at the 1986 Lisp & Functional Programming conference, with a title something like "Hygienic Macro Expansion". There is a subcommittee of X3J13 following the research, and if any acceptable solutions come up I'm sure they will let us know about them. barmar  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 12 Nov 87 01:33:26 EST Received: from SPAR-20.ARPA by SAIL.STANFORD.EDU with TCP; 11 Nov 87 22:08:30 PST Received: from MANTIS.SPAR.CAS.SLB.COM (MANTIS.#Internet) by SPAR-20.SPAR.SLB.COM with TCP; Wed 11 Nov 87 22:09:53-PST Date: Wed, 11 Nov 87 22:09 PST From: Bob Kanefsky Subject: Missing and desired sequence function. To: common-lisp@sail.stanford.edu In-Reply-To: <19871111230324.4.DCP@SWAN.SCRC.Symbolics.COM> References: <870923091026.7.7THSON@MOTH.SPAR.CAS.SLB.COM> Message-ID: <871111220942.4.KANEF@MANTIS.SPAR.CAS.SLB.COM> I agree with you that this is a useful feature that is an obvious hole in Common Lisp's sequence functions. As evidence that it's obviously needed, I thought of it six weeks ago independently (or did you see my suggestion to Symbolics Customer Reports, referenced above?). Below is the implementation I used. It's an iterative approach using the MIT LOOP macro, made ugly by the need to handle lists and vectors separately. It's not as elegant as using SORT or REDUCE, but later I realized I wanted it to return the position as well as the element; see below. --Kanef (defun minimize (sequence &key (key 'identity) (test '<)) ;;A generalization of MIN that takes :KEY and :TEST arguments ;;as other Common-Lisp functions do. ;;Examples: (minimize '(1 2 3 4)) is the same as (min 1 2 3 4) but slower. ;; (minimize *people* :key 'height) finds the shortest person. ;; (minimize *people* :key 'age) finds the youngest person. ;; (minimize *people* :key 'age :test '>) finds the oldest person. (declare (values element position key-value)) (macrolet ((doit (type) ;;I know the Symbolics implementations of the other sequence functions use a macro ;;for this called CLI::SEQUENCE-ITERATOR, but the callers of it are all in a restricted ;;source. This macro is the same idea. (let ((iterator (case type (list '(in)) (vector '(being the array-elements of))))) `(loop with best-candidate = (elt sequence 0) with best-offer = (funcall key best-candidate) with best-index = 0 for index from 0 for candidate ,@iterator sequence for offer = (funcall key candidate) when (funcall test offer best-offer) do (setq best-candidate candidate best-offer offer best-index index) finally (return (values best-candidate best-index best-offer)))))) (etypecase sequence (list (doit list)) (vector (doit vector))))) As soon as I went back to writing the caller of the MINIMIZE function, I realized that it would be convenient to have it return the index as well as the element (ala POSITION as well as FIND). (defun minimize (sequence &key (key 'identity) (test '<)) ;;A generalization of MIN that takes :KEY and :TEST arguments ;;as other Common-Lisp functions do. ;;Examples: (minimize '(1 2 3 4)) is the same as (min 1 2 3 4) but slower. ;; (minimize *people* :key 'height) finds the shortest person. ;; (minimize *people* :key 'age) finds the youngest person. ;; (minimize *people* :key 'age :test '>) finds the oldest person. (declare (values element position key-value)) (macrolet ((doit (type) ;;I know the Symbolics implementations of the other sequence functions use a macro ;;for this called CLI::SEQUENCE-ITERATOR, but the callers of it are all in a restricted ;;source. This macro is the same idea. (let ((iterator (case type (list '(in)) (vector '(being the array-elements of))))) `(loop with best-candidate = (elt sequence 0) with best-offer = (funcall key best-candidate) with best-index = 0 for index from 0 for candidate ,@iterator sequence for offer = (funcall key candidate) when (funcall test offer best-offer) do (setq best-candidate candidate best-offer offer best-index index) finally (return (values best-candidate best-index best-offer)))))) (etypecase sequence (list (doit list)) (vector (doit vector)))))  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Nov 87 22:36:13 EST Received: from [128.81.41.234] by SAIL.STANFORD.EDU with TCP; 11 Nov 87 19:12:24 PST Received: from SWAN.SCRC.Symbolics.COM by MEAD.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 109603; Wed 11-Nov-87 18:03:54 EST Date: Wed, 11 Nov 87 18:03 EST From: David C. Plummer Subject: Missing and desired sequence function. To: common-lisp@sail.stanford.edu Message-ID: <19871111230324.4.DCP@SWAN.SCRC.Symbolics.COM> I would like a sequence function that gives me the "best" element of a sequence. I want to give it a sequence, a predicate and (with keywords) the bounds of the sequence and a key to extract the arguments for the predicate. It returns the element of the sequence that is "predicate" (e.g., less than) all the other elements. There are a couple ways to implement this using existing functions, but it would be nice if CLtL had this as part of the language if others find it a sibling of existing functions. Implementation 1: User SORT. Running time is n*log(n). Sort the list and return the first element. Guarenteed to cons. This fails for zero length sequences. Zero length sequences may want to be or signal an error. (defun best (sequence predicate &key key start end) (elt (sort (subseq sequence start end) predicate :key key) 0)) Implementation 2: Use REDUCE. Running time is linear. Make a reduction function which compares two elements and returns the best. (defun best (sequence predicate &key key start end) (reduce #'(lambda (elt1 elt2) (if (funcall predicate (funcall key elt1) (funcall key elt2)) elt1 elt2)) sequence :start start :end end)) There are obviously some details missing in the above implementations; they are to convey the concept. A better name might be CHOOSE. Does this seem reasonably useful to add to the language?  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Nov 87 21:18:51 EST Received: from NRTC.NORTHROP.COM by SAIL.STANFORD.EDU with TCP; 11 Nov 87 16:31:02 PST Received: by nrtc.nrtc.northrop.com id aa03871; 11 Nov 87 16:31 PST Date: Wed, 11 Nov 87 16:28:54 PST From: Jeff Barnett To: common-lisp@sail.stanford.edu Subject: Re: Local redefs of special forms If you allow FLETS, et al, to shadow special forms, there is an implementation issue with inline function expansions nee DEFSUBSTs. The compiler cannot substitute the function body and optimize as some compilers now do. In fact the body must be (re)expanded in the null lexical environment no matter what. Consider the following example: (defsubst foo (x) (car x)) (flet((car (l) (cdr l))) (foo (car q))) The value of the flet should be (cadr q) while if the compiler is not careful, the result will be (cddr q) instead. Note, this issue has nothing to do with special forms, it depends only on the interaction between an inline function, the defsubst, and local function defs, the flet. In order to get the proper semantics AND the optimization implied by using an inline function, a compiler must mark expressions with their lexical environment. Perhaps the expression (foo (cdr q)) in the above would need to look something like (# (foo (car q))) (# (car q))) (# (car (# (car q)))) and if the flet is inlined (# (car (cdr (# q)))) at different times as the compiler elaborated the original. Note, the env wrap around the variable is necesssary also: Think about the interactions that might result (with more complex local fcn defs) if there is a special declaration around an inline expansion (let(...) (declare ....) (in-line-fcn reference ...) ...) If the subst's body is just substituted AND it binds a declared variable, all hell will break loose. I don't think that you can get out of the delemma without some sort of env wrapper. In any event, there needs to be a good set of primitives to manage and interagate environments so that sexy system macros and substs don't blow the bunnies. As long as they need to exist, why not standardize, document, and distribute them?  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Nov 87 19:49:18 EST Received: from NRTC.NORTHROP.COM by SAIL.STANFORD.EDU with TCP; 11 Nov 87 16:31:02 PST Received: by nrtc.nrtc.northrop.com id aa03871; 11 Nov 87 16:31 PST Date: Wed, 11 Nov 87 16:28:54 PST From: Jeff Barnett To: common-lisp@sail.stanford.edu Subject: Re: Local redefs of special forms If you allow FLETS, et al, to shadow special forms, there is an implementation issue with inline function expansions nee DEFSUBSTs. The compiler cannot substitute the function body and optimize as some compilers now do. In fact the body must be (re)expanded in the null lexical environment no matter what. Consider the following example: (defsubst foo (x) (car x)) (flet((car (l) (cdr l))) (foo (car q))) The value of the flet should be (cadr q) while if the compiler is not careful, the result will be (cddr q) instead. Note, this issue has nothing to do with special forms, it depends only on the interaction between an inline function, the defsubst, and local function defs, the flet. In order to get the proper semantics AND the optimization implied by using an inline function, a compiler must mark expressions with their lexical environment. Perhaps the expression (foo (cdr q)) in the above would need to look something like (# (foo (car q))) (# (car q))) (# (car (# (car q)))) and if the flet is inlined (# (car (cdr (# q)))) at different times as the compiler elaborated the original. Note, the env wrap around the variable is necesssary also: Think about the interactions that might result (with more complex local fcn defs) if there is a special declaration around an inline expansion (let(...) (declare ....) (in-line-fcn reference ...) ...) If the subst's body is just substituted AND it binds a declared variable, all hell will break loose. I don't think that you can get out of the delemma without some sort of env wrapper. In any event, there needs to be a good set of primitives to manage and interagate environments so that sexy system macros and substs don't blow the bunnies. As long as they need to exist, why not standardize, document, and distribute them?  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Nov 87 14:39:53 EST Received: from ECLA.USC.EDU by SAIL.STANFORD.EDU with TCP; 11 Nov 87 11:17:06 PST Date: Wed 11 Nov 87 11:17:51-PST From: Kim A. Barrett Subject: flet/labels/macrolet and environments To: common-lisp@SAIL.STANFORD.EDU cc: Mincy@THINK.COM, iim@ECLA.USC.EDU Message-ID: <12349814619.24.IIM@ECLA.USC.EDU> { The mailer seems to have bounced the first time I sent this. Apologies to anyone who receives it twice. kab } Date: Thu, 5 Nov 87 04:20 EST From: Jeff Mincy ... These forms {special-forms -- kab} really are special, users have to understand them seperately from other things like function call. ... You still can't funcall a special-form. I don't think this is an adequate argument by itself. Many macros also have peculiar syntax, which has to be learned on a case by case basis by the user. You also can't funcall macros. But you can locally redefine them. There is a certain simplicity to the description of flet &etc. It says that within the specified scope, named functional references which match the specified names refer to the specified definitions. If the names of special-forms cannot be shadowed, you have to add a statement to that effect as an additional caveat. Note that I am NOT arguing that it is necessarily reasonable for a user to write such code, since it may very well break things. But this is true for any local redefinition, especially of 'standard' names, like the built-in Common Lisp names that are in the Lisp package. I would consider it perfectly acceptable for a compiler to issue some sort of style warning when it encounters a local redefinition of a standard Common Lisp function, as long as there is some way for the user to turn it off if that is REALLY what he means to do. I understand that some compilers already do this. In fact, I've just added this to my todo list, for the next time I start major surgery on our compiler. Its interesting to note that everywhere else I can find where the issue of possibly redefining a special-form comes up, CLtL specifically says it is an error to do so, yet is totally silent on the subject regarding local redefinition. Not that I'm putting this forward as an argument in favor of allowing shadowing, since it doesn't address the question of what is the RIGHT thing to do. I was just wondering if it was an oversight, or if it was intentional. As a random additional piece of dirt to throw into this mess, what happens if you have an flet &etc in which the same name appears twice? My guess is that, with the usual left-to-right order of evaluation, combined with the scoping rules, the most obvious answer is that the LAST of the definitions ends up taking precedence, and the previous one(s) get ignored. Of course, the left-to-right ordering is kind of a red herring, since the order is left undefined, like in a LET form, where the same question arises. Very peculiar, and probably worth a compiler warning. ... I would suggest that it {local-function-p -- kab} return a second value of t if the symbol is a lexical macro. I had thought about this, and in an earlier version actually had it in, but decided it probably isn't necessary. In the places I've seen where this function would get used, the second value would probably only be useful as an efficiency hack, allowing you to avoid superflously calling macroexpand on a form that references a local function, rather than a macro. Not being one to sneer at efficiency issues, I think I've changed my mind again, and agree with your suggestion. I am not really convinced that this {augment-function-environment -- kab} is needed. ... You need something like augment-function-environment so that your code walker can process an flet/labels/macrolet form and update the environment you are passing around in a way that keeps it compatable with the Common Lisp implementation's representation of environments, so that you can pass the updated environment to macroexpand. Look at the PCL code walker for an example of the horrible kludges people are forced to try in order to write something that is at least semi-portable. kab -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Nov 87 11:24:58 EST Received: from XX.LCS.MIT.EDU by SAIL.STANFORD.EDU with TCP; 11 Nov 87 08:06:27 PST Received: from RTS-12.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 11 Nov 87 11:03-EST Message-Id: <2772633993-10450594@RTS-12> Sender: cerys@RTS-12 Date: Wed, 11 Nov 87 11:06:33 EST From: "Daniel L. Cerys" To: R Dunbar Poor Cc: common-lisp@sail.stanford.edu Subject: Re: Question regarding FORMAT with ~:^ within ~:{ > The question is, what should this form return: > > (format nil "~:{~@?~:^...~}" '(("a") ("b"))) Like the other MIT-based LISPM, the TI Explorer returns "a...b". So far, Nick Gall seems to have the best explanation for this. Dan  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Nov 87 01:12:21 EST Received: from G.BBN.COM by SAIL.STANFORD.EDU with TCP; 10 Nov 87 21:52:21 PST Date: 11 Nov 1987 00:51-EST Sender: NGALL@G.BBN.COM Subject: Re: Question regarding FORMAT with ~:^ within ~:{ From: NGALL@G.BBN.COM To: edsel!r@LABREA.STANFORD.EDU Cc: common-lisp@SAIL.STANFORD.EDU Message-ID: <[G.BBN.COM]11-Nov-87 00:51:10.NGALL> In-Reply-To: <8711100253.AA07681@vesuvius.lucid.com> Date: Mon, 9 Nov 87 18:53:10 PST From: R Dunbar Poor ... (format nil "~:{~@?~:^...~}" '(("a") ("b"))) MY CLAIM: It should return "a". ... CLtL page 406 states that: "If ~^ is used within a ~:{ construct, then it merely terminates the current iteration step (because in the standard case it tests for remaining arguments of the current step only); the next iteration step commences immediately. To terminate the entire iteration process, use ~:^." Although I agree that a superficial reading of the above would lead one to expect "a" to be returned, if one thinks about the intent of the parenthetical (because in the standard case it tests for remaining arguments of the current step only) one should agree that "a...b" will be returned. In refering to ~^ as the "standard case", which tests the arguments remaining in the current argument sublist, this parenthetical implies that there is an `other case', which tests `something else.' The only `other case' discussed is ~:^, which therefore must test `something else.' I claim that the parentheical makes no sense if we interpret ~:^ as testing the same condition as ~^. If they both test the same condition, why have the parenthetical explanation? If ~:^ doesn't test the same condition as ~^, then what does it test? I claim that the only test that makes sense is for ~:^ to test the only thing that affects the "entire iteration process:" the number of sublists. When there are no more sublists, "the entire iteration process" is terminated. Finally, It makes no sense for ~:^ to test the number of args remaining in the current sublist, since this can be acheived by the following: (format nil "~:{~@?~#[~0:^~]...~}" '(("a") ("b"))) But it makes perfect sense for ~:^ to test the number of arglists remaining, SINCE THERE IS NO OTHER WAY TO TEST THIS. Comments? -- Nick  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 10 Nov 87 18:58:50 EST Received: from UCBARPA.Berkeley.EDU by SAIL.STANFORD.EDU with TCP; 10 Nov 87 15:41:55 PST Received: by ucbarpa.Berkeley.EDU (5.58/1.25) id AA02907; Tue, 10 Nov 87 15:46:05 PST Received: from akbar by franz (5.5/3.14) id AA11686; Tue, 10 Nov 87 15:32:19 PST Received: by akbar (5.5/3.14) id AA28113; Tue, 10 Nov 87 15:26:55 PST From: franz!akbar!layer@ucbarpa.Berkeley.EDU (Kevin Layer) Return-Path: Message-Id: <8711102326.AA28113@akbar> To: common-lisp@sail.stanford.edu Subject: Re: Question regarding FORMAT with ~:^ Date: Tue, 10 Nov 87 15:26:53 PST >> I have a question regarding the correct behavior of FORMAT. Please >> open up your CLtL books to page 406 and tell me what the following >> construct should return: >> >> (format nil "~:{~@?~:^...~}" '(("a") ("b"))) >> Franz's Allegro Common Lisp returns "a", which we feel is the correct answer. Kevin Layer  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 10 Nov 87 16:24:25 EST Received: from DECWRL.DEC.COM by SAIL.STANFORD.EDU with TCP; 10 Nov 87 13:05:43 PST Received: by decwrl.dec.com (5.54.4/4.7.34) id AA19455; Tue, 10 Nov 87 13:06:36 PST Date: Tue, 10 Nov 87 13:06:36 PST Message-Id: <8711102106.AA19455@decwrl.dec.com> From: robbins%expert.DEC@decwrl.dec.com To: common-lisp@sail.stanford.edu Subject: Re: Question regarding FORMAT with ~:^ >> I have a question regarding the correct behavior of FORMAT. Please >> open up your CLtL books to page 406 and tell me what the following >> construct should return: >> >> (format nil "~:{~@?~:^...~}" '(("a") ("b"))) >> Should return "a" for exactly the reason you gave. Otherwise "To terminate the entire iteration process, use ~:^." is meaningless. I agree with those who prefer "a" By the way, VAX-Lisp returns "a" -- Rich  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 10 Nov 87 15:07:28 EST Received: from MULTIMAX.ARPA by SAIL.STANFORD.EDU with TCP; 10 Nov 87 11:34:03 PST Received: by multimax.ARPA (5.51/25-eef) id AA13651; Tue, 10 Nov 87 10:53:47 EST Message-Id: <8711101553.AA13651@multimax.ARPA> To: R Dunbar Poor Cc: common-lisp@sail.stanford.edu Subject: Re: Question regarding FORMAT with ~:^ within ~:{ In-Reply-To: Your message of Mon, 09 Nov 87 18:53:10 -0800. <8711100253.AA07681@vesuvius.lucid.com> Date: Tue, 10 Nov 87 10:53:40 EST From: Dan L. Pierson >> I have a question regarding the correct behavior of FORMAT. Please >> open up your CLtL books to page 406 and tell me what the following >> construct should return: >> >> (format nil "~:{~@?~:^...~}" '(("a") ("b"))) >> Should return "a" for exactly the reason you gave. Otherwise "To terminate the entire iteration process, use ~:^." is meaningless. KCL returns "a". dan  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 10 Nov 87 14:48:56 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 10 Nov 87 11:12:30 PST Received: from Cabernet.ms by ArpaGateway.ms ; 10 NOV 87 11:12:26 PST Date: Tue, 10 Nov 87 11:11:59 PST From: Pavel.pa@Xerox.COM Subject: Re: Question regarding FORMAT with ~:^ within ~:{ In-reply-to: <8711100253.AA07681@vesuvius.lucid.com> To: R Dunbar Poor Cc: common-lisp@sail.stanford.edu Message-ID: <871110-111226-5309@Xerox> I won't bother trying to quote your message here. Folks who missed it should look in the archives. The question is, what should this form return: (format nil "~:{~@?~:^...~}" '(("a") ("b"))) Rob wants it to return "a" since ~:? means to terminate all iterations now. Other people, including the implementors of the Symbolics FORMAT facility, believe that it should be "a...b" since it is required to check for the presence or absence of any further arguments to the outer iteration. I believe that Symbolics (and the other people) are right. Consider the following: the quoted paragraph from CLtL page 406 says this: "If ~^ is used within a ~:{ construct, then it merely terminates the current iteration step (because in the standard case it tests for remaining arguments of the current step only); the next iteration step commences immediately. To terminate the entire iteration process, use ~:^." In the first sentence, the claim is that ~^ will unconditionally terminate the current iteration step. But we know from context on the page that this isn't true, that really it will terminate the step only when no more arguments remain for that step. If we had wanted truly unconditional termination, we should have used ~0^. Thus, by the same context, the claim that ~:^ terminates the entire iteration must be understood to mean that it does so only when there are no more arguments for that iteration. If we had wanted the other meaning, we should have used ~0:^. Thus, I think that a truly strict interpretation of CLtL implies that the other people (and Symbolics) are right. Pavel  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Nov 87 22:17:01 EST Received: from LABREA.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 9 Nov 87 18:58:23 PST Received: by labrea.stanford.edu; Mon, 9 Nov 87 18:57:58 PST Received: from vesuvius.lucid.com by edsel id AA20827g; Mon, 9 Nov 87 18:52:11 PST Received: by vesuvius id AA07681g; Mon, 9 Nov 87 18:53:10 PST Date: Mon, 9 Nov 87 18:53:10 PST From: R Dunbar Poor Message-Id: <8711100253.AA07681@vesuvius.lucid.com> To: labrea!common-lisp%sail.stanford.edu@labrea.stanford.edu Subject: Question regarding FORMAT with ~:^ within ~:{ I have a question regarding the correct behavior of FORMAT. Please open up your CLtL books to page 406 and tell me what the following construct should return: (format nil "~:{~@?~:^...~}" '(("a") ("b"))) MY CLAIM: It should return "a". THE RATIONALE: According to the Steele's spec, the ~:^ construct (with the : modifier) should exit ALL iterations, therefore, FORMAT only gets as far as printing the "a" before it quits. CLtL page 406 states that: "If ~^ is used within a ~:{ construct, then it merely terminates the current iteration step (because in the standard case it tests for remaining arguments of the current step only); the next iteration step commences immediately. To terminate the entire iteration process, use ~:^." OTHER PEOPLE CLAIM: It should return "a...b". THE RATIONALE: Since ~:^ is planning to exit the entire iteration it should check whether there are more arguments to the entire iteration, rather than checking for more arguments in the current sublist. A SYMBOLICS 3600 CLAIMS: It should return "a...b" THE RATIONALE: I don't know, but that's what I got when I typed the example in. In closing, I might even agree that "a...b" would be more useful behavior, but it is not in keeping with a strict interpretation of Steele's specification. I'd be interested in cogent comments and clarifications. - Robert Poor Lucid, Inc  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Nov 87 17:39:02 EST Received: from THINK.COM by SAIL.STANFORD.EDU with TCP; 9 Nov 87 14:12:06 PST Return-Path: <@occam.think.com:barmar@Think.COM> Received: from pozzo ([192.5.104.209]) by Think.COM; Mon, 9 Nov 87 13:16:56 EST Received: from OCCAM.THINK.COM (occam.think.com.ARPA) by pozzo; Mon, 9 Nov 87 13:12:48 est Date: Mon, 9 Nov 87 13:14 EST From: Barry Margolin Subject: Access to lexical environment? To: futrell%corwin.ccs.northeastern.edu@relay.cs.net Cc: slug@r20.utexas.edu, common-lisp@sail.stanford.edu, futrelle%corwin.ccs.northeastern.edu@relay.cs.net In-Reply-To: <8711090904.AA02522@Think.COM> Message-Id: <871109131445.7.BARMAR@OCCAM.THINK.COM> Date: Sun, 8 Nov 87 21:12:26 EST From: futrell%corwin.ccs.northeastern.edu@relay.cs.net Creating new syntax using Lisp -- access to lexical environment? I am not sure how to properly develop simple extensions to Lisp syntax (using CL). For example, suppose that I'd like to set up a way to create new things that has the following (familiar) syntax: (def-newthing fred (other-thing) ((n :initform (+ a b)) (ls :initform (rest ls1))) ...etc.) Now a,b, and ls1 would typically be lexically scoped. Given this, how do I define "def-newthing"? If I use defun, it will attempt to evaluate (other-thing), and worse, ((n :initform ....)). This won't work. If I use defmacro, when I pull out an initform to evaluate, such as (+ a b), the defmacro won't allow me access to the lexical bindings of a and b. eval has similar problems. I'm stuck. Any ideas? (There might be a lisp group to send this to, but we don't subscribe -- anyway, I have confidence that I'll be enlightened on this by sluggers.) The right place to ask questions like this is COMMON-LISP@SAIL.STANFORD.EDU, and I've CCed my response there so that other CLers can help out after I do. For the most part, defining forms such as the above are expected to appear at top-level. However, the standard doesn't actually say that (except maybe for DEFUN, but I think there is some contention about this). In any case, the way to do what you want is to create a lexical closure, by expanding into a use of the FUNCTION special form, and when you actually go to use the initial form you must FUNCALL it rather than EVALing it. Here's a simplified DEFSTRUCT that does this (I don't know whether the standard Symbolics defstruct does it, and I'm not sure whether the CL standard requires it): (defmacro structure-defaults (symbol) `(get ,symbol 'simple-structure-defaults)) (defmacro def-simple-struct (name &body components) "Use as (def-simple-struct name (slot default) ...). Defines NAME-SLOTn macro accessors. Use MAKE-SIMPLE-STRUCTURE to create an instance." (let ((component-names (mapcar #'car components)) (component-defaults (mapcar #'cadr components))) `(progn ,@(loop for component in component-names for i from 0 collect `(defmacro ,(intern (concatenate 'string (symbol-name name) "-" (symbol-name component))) (object) `(aref ,object ,',i))) (setf (structure-defaults ',name) (list .,(loop for default in component-defaults collect `(function (lambda () ,default)))))))) (defun make-simple-structure (type &rest values) (let* ((defaults (structure-defaults type)) (size (length defaults)) (struct (make-array size))) (dotimes (i (length values)) ;fill in specified values (setf (aref struct i) (nth i values))) (do ((i (length values) (1+ i))) ((>= i size)) (setf (aref struct i) (funcall (nth i defaults)))) struct)) Another way to accomplish this would be for DEF-SIMPLE-STRUCT to include in its expansion the definition of a function that makes the objects, and to include the default forms in this expansion. This would define a function in the appropriate lexical environment (not that it is unclear whether DEFUN can be used in this way -- the Symbolics interpreter queries you if you try to use DEFUN in a non-null environment). Here is an example of the above that works this way: (defmacro def-simple-struct (name &body components) "Use as (def-simple-struct name (slot default) ...). Defines NAME-SLOTn macro accessors, and make-NAME instance creator." (let ((component-names (mapcar #'car components)) (component-defaults (mapcar #'cadr components))) `(progn ,@(loop for component in component-names for i from 0 collect `(defmacro ,(intern (concatenate 'string (symbol-name name) "-" (symbol-name component))) (object) `(aref ,object ,',i))) (setf (symbol-function ',(intern (concatenate 'string "MAKE-" (symbol-name name)))) #'(lambda (&key .,component-names) (let ((struct (make-array ,(length component-names)))) ,@(loop for name in component-names for default in component-defaults for i from 0 collect `(setf (aref struct ,i) (or ,name ,default))) struct)))))) Both of these mechanisms are essentially equivalent. The first version creates one lexical closure per slot and stores a list of them in the property list of the structure name symbol, and MAKE-SIMPLE-STRUCTURE extracts and calls them. The second creates a single lexical closure that contains all the default forms and stores it in the function cell of the creation function, and normal function evaluation invokes it. If you don't understand the macros (they were hard enough to write correctly), run some examples through MEXP to see what they expand into. barmar  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Nov 87 17:28:52 EST Received: from THINK.COM by SAIL.STANFORD.EDU with TCP; 9 Nov 87 14:09:56 PST Return-Path: <@occam.think.com:barmar@Think.COM> Received: from pozzo ([192.5.104.209]) by Think.COM; Mon, 9 Nov 87 11:36:06 EST Received: from OCCAM.THINK.COM (occam.think.com.ARPA) by pozzo; Mon, 9 Nov 87 11:31:59 est Date: Mon, 9 Nov 87 11:34 EST From: Barry Margolin Subject: equality of structures, or *default-structure-type* To: "Hiroshi \"Gitchang\" Okuno" Cc: common-lisp@sail.stanford.edu In-Reply-To: <12349062523.26.OKUNO@SUMEX-AIM.STANFORD.EDU> Message-Id: <871109113400.5.BARMAR@OCCAM.THINK.COM> I believe the intent, but not the letter, of the specification was that when you don't specify the type explicitly, an implementation-dependent type that is distinguishable from all other types would be used. The actual implementation may be as some other primitive type (list, array) but the object will be marked in some way that it can be recognized as a defstruct-created structure. I believe that this interpretation is necessary in order to cause the structure's print-function to be invoked. If structures weren't distinguishable from other data types then they would print as those data types print, rather than using the #S notation (or the :PRINT-FUNCTION). Therefore, the definition of EQUAL could be extended to explicitly specify its interpretation given two structures of the same type. barmar  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Nov 87 15:21:42 EST Received: from VAXA.ISI.EDU by SAIL.STANFORD.EDU with TCP; 9 Nov 87 11:58:55 PST Posted-Date: Mon, 09 Nov 87 11:59:25 PST Message-Id: <8711091959.AA14960@vaxa.isi.edu> Received: from LOCALHOST by vaxa.isi.edu (5.54/5.51) id AA14960; Mon, 9 Nov 87 11:59:49 PST To: COMMON-LISP@sail.stanford.edu From: goldman@vaxa.isi.edu Subject: equality of structures Cc: goldman@vaxa.isi.edu Date: Mon, 09 Nov 87 11:59:25 PST Sender: goldman@vaxa.isi.edu From the standpoint of writing TRANSFORMATIONs on common lisp programs, it would be preferable to have EQUAL well defined for structure instances for which no :type (too bad that wasn't called :implementation) is specified. Personally, I would like the definition should be: two instances are EQL iff they are EQ two instances are EQUAL iff a) they are instances of the same most specific structure type, and b) the contents of all corresponding fields are EQUAL. [This is like the current definition of EQUALP for un:TYPEed structures, at least if you believe structures are objects that have components -- see CLtL's definition of EQUALP.] [However, I suspect that most implementors would rather have it defined like to have these objects be EQUAL iff they are EQL, so they can be implemented as arrays.] This entire problem, I am sure, stems from the more fundamental "problem" that EQUAL is defined to recur into components of lists, but NOT of arrays, -- except for STRINGs and BIT-VECTORs -- a decision that could ONLY have its roots in implementation considerations. An alternative suggested by the earlier message, a *default-structure-type* variable, implies making the definition of EQUAL implementation specific. But I think it carried along with it an implication that implementations are limitied to defaulting the implementation of such structure instances to the equivalent of what results from either :ARRAY or :LIST, and to defaulting the implementation of ALL instances the same way. Re: the suggestion that CLOS should subsume (by convention or otherwise) uses of un:TYPEed defstruct types? I presume that this takes care of the issue of EQUAL, because the CLOS specifies the semantics of EQUAL for its class instances? (What is the specification, by the way?) But I would be loathe to replace my un:TYPEed defstructs with DEFCLASSes if I gave up substantial efficiency when I only wanted the limited power provided by the "record structure" semantics. Are there enough declarations available in CLOS so that I could get my compiled accesses to slots of such instances down to the equivalent of an array element reference? Neil  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Nov 87 15:21:09 EST Received: from VAXA.ISI.EDU by SAIL.STANFORD.EDU with TCP; 9 Nov 87 11:59:43 PST Posted-Date: Mon, 09 Nov 87 12:00:35 PST Message-Id: <8711092000.AA14975@vaxa.isi.edu> Received: from LOCALHOST by vaxa.isi.edu (5.54/5.51) id AA14975; Mon, 9 Nov 87 12:00:38 PST To: COMMON-LISP@sail.stanford.edu From: goldman@vaxa.isi.edu Subject: equality of structures Cc: goldman@vaxa.isi.edu Date: Mon, 09 Nov 87 12:00:35 PST Sender: goldman@vaxa.isi.edu From the standpoint of writing TRANSFORMATIONs on common lisp programs, it would be preferable to have EQUAL well defined for structure instances for which no :type (too bad that wasn't called :implementation) is specified. Personally, I would like the definition should be: two instances are EQL iff they are EQ two instances are EQUAL iff a) they are instances of the same most specific structure type, and b) the contents of all corresponding fields are EQUAL. [This is like the current definition of EQUALP for un:TYPEed structures, at least if you believe structures are objects that have components -- see CLtL's definition of EQUALP.] [However, I suspect that most implementors would rather have it defined like to have these objects be EQUAL iff they are EQL, so they can be implemented as arrays.] This entire problem, I am sure, stems from the more fundamental "problem" that EQUAL is defined to recur into components of lists, but NOT of arrays, -- except for STRINGs and BIT-VECTORs -- a decision that could ONLY have its roots in implementation considerations. An alternative suggested by the earlier message, a *default-structure-type* variable, implies making the definition of EQUAL implementation specific. But I think it carried along with it an implication that implementations are limitied to defaulting the implementation of such structure instances to the equivalent of what results from either :ARRAY or :LIST, and to defaulting the implementation of ALL instances the same way. Re: the suggestion that CLOS should subsume (by convention or otherwise) uses of un:TYPEed defstruct types? I presume that this takes care of the issue of EQUAL, because the CLOS specifies the semantics of EQUAL for its class instances? (What is the specification, by the way?) But I would be loathe to replace my un:TYPEed defstructs with DEFCLASSes if I gave up substantial efficiency when I only wanted the limited power provided by the "record structure" semantics. Are there enough declarations available in CLOS so that I could get my compiled accesses to slots of such instances down to the equivalent of an array element reference? Neil  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Nov 87 15:20:58 EST Received: from VAXA.ISI.EDU by SAIL.STANFORD.EDU with TCP; 9 Nov 87 11:58:28 PST Posted-Date: Mon, 09 Nov 87 11:57:36 PST Message-Id: <8711091958.AA14947@vaxa.isi.edu> Received: from LOCALHOST by vaxa.isi.edu (5.54/5.51) id AA14947; Mon, 9 Nov 87 11:58:22 PST To: COMMON-LISP@sail.stanford.edu From: goldman@vaxa.isi.edu Subject: equality of structures Cc: goldman@vaxa.isi.edu Date: Mon, 09 Nov 87 11:57:36 PST Sender: goldman@vaxa.isi.edu From the standpoint of writing TRANSFORMATIONs on common lisp programs, it would be preferable to have EQUAL well defined for structure instances for which no :type (too bad that wasn't called :implementation) is specified. Personally, I would like the definition should be: two instances are EQL iff they are EQ two instances are EQUAL iff a) they are instances of the same most specific structure type, and b) the contents of all corresponding fields are EQUAL. [This is like the current definition of EQUALP for un:TYPEed structures, at least if you believe structures are objects that have components -- see CLtL's definition of EQUALP.] [However, I suspect that most implementors would rather have it defined like to have these objects be EQUAL iff they are EQL, so they can be implemented as arrays.] This entire problem, I am sure, stems from the more fundamental "problem" that EQUAL is defined to recur into components of lists, but NOT of arrays, -- except for STRINGs and BIT-VECTORs -- a decision that could ONLY have its roots in implementation considerations. An alternative suggested by the earlier message, a *default-structure-type* variable, implies making the definition of EQUAL implementation specific. But I think it carried along with it an implication that implementations are limitied to defaulting the implementation of such structure instances to the equivalent of what results from either :ARRAY or :LIST, and to defaulting the implementation of ALL instances the same way. Re: the suggestion that CLOS should subsume (by convention or otherwise) uses of un:TYPEed defstruct types? I presume that this takes care of the issue of EQUAL, because the CLOS specifies the semantics of EQUAL for its class instances? (What is the specification, by the way?) But I would be loathe to replace my un:TYPEed defstructs with DEFCLASSes if I gave up substantial efficiency when I only wanted the limited power provided by the "record structure" semantics. Are there enough declarations available in CLOS so that I could get my compiled accesses to slots of such instances down to the equivalent of an array element reference? Neil  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Nov 87 09:19:01 EST Received: from DECWRL.DEC.COM by SAIL.STANFORD.EDU with TCP; 9 Nov 87 05:56:39 PST Received: by decwrl.dec.com (5.54.4/4.7.34) id AA16094; Mon, 9 Nov 87 05:57:27 PST Date: Mon, 9 Nov 87 05:57:27 PST Message-Id: <8711091357.AA16094@decwrl.dec.com> From: nelson%tle.DEC@decwrl.dec.com (Beryl Elaine Nelson) To: Okuno@SUMEX-AIM.STANFORD.EDU Subject: RE: equality of structures, or *default-structure-type* ... The equality of structures may differ on these two implementations, since equality of array is checked by the 'eq'ness and that of list is checked by the equality of corresponding elements (CLtL p.80). - Gitchang - This problem could be solved by specifying the result of using equal with "default type" structures. Pathname equality was specified separately; why not structures? Beryl Nelson  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Nov 87 19:32:33 EST Received: from LABREA.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 8 Nov 87 16:16:08 PST Received: by labrea.stanford.edu; Sun, 8 Nov 87 16:14:28 PST Received: from bhopal.lucid.com by edsel id AA16787g; Sun, 8 Nov 87 16:08:10 PST Received: by bhopal id AA13142g; Sun, 8 Nov 87 16:07:52 PST Date: Sun, 8 Nov 87 16:07:52 PST From: Jon L White Message-Id: <8711090007.AA13142@bhopal.lucid.com> To: labrea!Okuno%SUMEX@labrea.stanford.edu Cc: labrea!common-lisp%SAIL@labrea.stanford.edu In-Reply-To: Hiroshi "Gitchang" Okuno's message of Sun, 8 Nov 87 14:26:27 PST <12349062523.26.OKUNO@SUMEX-AIM.STANFORD.EDU> Subject: equality of structures, or *default-structure-type* A defstruct not given the :type option is the one area where CL's defstruct tries to go beyond the "record structure" semantics, and enter the area of limited "object based" programming. It's somewhat ironic that only when you don't specify :type do the elements of the defined structure become full-fledged members of the common-lisp type system; i.e., they are identifiably of of the defined type rather than the implementational type. Many persons have criticized this merger of capabilities in defstruct. The most popular direction, however, is not to "fix" the problem with non-:type structures, but to hail the coming of the Common Lisp Object System, which will do a much grander job of providing object-oriented capabilities. All the interesting properties of defaultly-typed defstructs will be subsumed by defclass. Then, the use of defstruct could be, conventionally, limited to :type structures. -- JonL --  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Nov 87 17:43:15 EST Received: from SUMEX-AIM.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 8 Nov 87 14:26:38 PST Date: Sun, 8 Nov 87 14:26:27 PST From: Hiroshi "Gitchang" Okuno Subject: equality of structures, or *default-structure-type* To: common-lisp@SAIL.STANFORD.EDU Organization: Knowledge Systems Laboratory, CSD, Stanford University Group: Heuristic Programming Project Project: Advanced Architectures Project Address: 701 Welch Road, Building C, Palo Alto, CA 94304-1703 Phone: +1 (415)725-4854 Message-ID: <12349062523.26.OKUNO@SUMEX-AIM.STANFORD.EDU> If the :type option is not specified in defstruct, the structure is represented in an implementation-dependent manner (CLtL p.314). However, this implementation-dependentness introduces the ambiguity of equality of structures. Suppose that one implementation uses an array for the default representation of a structure, while the other implementation uses a list for it (of course, it's a silly implementation). The equality of structures may differ on these two implementations, since equality of array is checked by the 'eq'ness and that of list is checked by the equality of corresponding elements (CLtL p.80). For example, (defstruct foo a b c) default :type = :array (equal (make-foo) (make-foo)) ===> nil default :type = :list (equal (make-foo) (make-foo)) ===> t This observation proves that we need introduce a new global variable, say *default-structure-type*, in order to raise the portability of COMMON Lisp programs. Since I cannot find any messages on this matter in the archived files at sumex, I post this message. - Gitchang - -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 6 Nov 87 04:09:54 EST Received: from ECLA.USC.EDU by SAIL.STANFORD.EDU with TCP; 5 Nov 87 19:49:57 PST Date: Thu 5 Nov 87 19:49:37-PST From: Kim A. Barrett Subject: flet/labels/macrolet & environments To: common-lisp@SAIL.STANFORD.EDU cc: iim@ECLA.USC.EDU, mincy@THINK.COM Message-ID: <12348334919.24.IIM@ECLA.USC.EDU> Date: Thu, 5 Nov 87 04:20 EST From: Jeff Mincy ... These forms {special-forms -- kab} really are special, users have to understand them seperately from other things like function call. ... You still can't funcall a special-form. I don't think this is an adequate argument by itself. Many macros also have peculiar syntax, which has to be learned on a case by case basis by the user. You also can't funcall macros. But you can locally redefine them. There is a certain simplicity to the description of flet &etc. It says that withing the specified scope, named functional references which match the specified names refer to the specified definitions. If the names of special-forms cannot be shadowed, you have to add a statement to that effect as an additional caveat. Note that I am NOT arguing that it is necessarily reasonable for a user to write such code, since it may very well break things. But this is true for any local redefinition, especially of 'standard' names, like the built-in Common Lisp names that are in the Lisp package. I would consider it perfectly acceptable for a compiler to issue some sort of style warning when it encounters a local redefinition of a standard Common Lisp function, as long as there is some way for the user to turn it off if that is REALLY what he means to do. I understand that some compilers already do this. In fact, I've just added this to my todo list, for the next time I start major surgery on our compiler. Its interesting to note that everywhere else I can find where the issue of possibly redefining a special-form comes up, CLtL specifically says it is an error to do so, yet is totally silent on the subject regarding local redefinition. Not that I'm putting this forward as an argument in favor of allowing shadowing, since it doesn't address the question of what is the RIGHT thing to do. I was just wondering if it was an oversight, or if it was intentional. As a random additional piece of dirt to throw into this mess, what happens if you have an flet &etc in which the same name appears twice? My guess is that, with the usual left-to-right order of evaluation, combined with the scoping rules, the most obvious answer is that the LAST of the definitions ends up taking precedence, and the previous one(s) get ignored. Of course, the left-to-right ordering is kind of a red herring, since the order is left undefined, like in a LET form, where the same question arises. Very peculiar, and probably worth a compiler warning. ... I would suggest that it {local-function-p -- kab} return a second value of t if the symbol is a lexical macro. I had thought about this, and in an earlier version actually had it in, but decided it probably isn't necessary. In the places I've seen where this function would get used, the second value would probably only be useful as an efficiency hack, allowing you to avoid superflously calling macroexpand on a form that references a local function, rather than a macro. Not being one to sneer at efficiency issues, I think I've changed my mind again, and agree with your suggestion. I am not really convinced that this {augment-function-environment -- kab} is needed. ... You need something like augment-function-environment so that your code walker can process an flet/labels/macrolet form and update the environment you are passing around in a way that keeps it compatable with the Common Lisp implementation's representation of environments, so that you can pass the updated environment to macroexpand. Look at the PCL code walker for an example of the horrible kludges people are forced to try in order to write something that is at least semi-portable. kab -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Nov 87 04:34:04 EST Received: from THINK.COM by SAIL.STANFORD.EDU with TCP; 5 Nov 87 01:16:08 PST Return-Path: Received: from zeno by Think.COM via CHAOS; Thu, 5 Nov 87 04:15:58 EST Date: Thu, 5 Nov 87 04:20 EST From: Jeff Mincy Subject: flet/labels/macrolet To: IIM@ecla.usc.edu, common-lisp@sail.stanford.edu In-Reply-To: <12348118610.33.IIM@ECLA.USC.EDU> Message-Id: <871105042045.8.MINCY@ZENO.THINK.COM> Date: Thu 5 Nov 87 00:01:23-PST From: "Kim A. Barrett" It is our opinion that it is reasonable for a local function/macro to be able to shadow a special form. If such shadowing is not allowed, it's basically just another totally arbitrary rule that the programmer has to remember. It also makes for some extra work for program-analyzing programs, either in the analysis of flet/labels/macrolet forms, where it must check the names to see if they would shadow any of the standard special-forms, or at form-processing time (where it is currently impossible to do portably). I, just to be different, do not think that it is reasonable or desirable to hide special-forms lexically. These forms really are special, users have to understand them separately from other things like funtion call. Making it so that could be lexically hidden only makes special forms superficially like other forms. You still cant funcall a special form. It seems to me that the necessary functionality for examining the function environment is pretty easy to describe. All you really need is something like (defun local-function-p (symbol environment) "This function returns T if the specified symbol names a local function or macro in the specified environment, and Nil otherwise. Environment should be either the environment argument passed to a macroexpander function (obtained with the &environment lambda-keyword), or the environment argument to applyhook/evalhook." ...) I have had this problem as well. One of the few places where I've *HAD* to resort to #+symbolics ..., #+lucid ... I would suggest that it return something different so that lexical macros can be distinguished from lexical functions. Say return multiple values where the first value is t if is a local function or macro and the second value of t if the symbol is lexical macro. I would expect that, for any given implementation, it is completely trivial to write the code for local-function-p. Does anyone know of a counter-example? With this function available, when your code walker is processing a form which is a list whose car is a symbol, it does the following The functionality needed for augmenting environments is less obvious to me, since I haven't studied all that many code walkers to know what their needs are, nor all that many implementations, to know what their quirks are, as far as manipulation of environments is concerned. I think something like the following would be adequate for the walkers and implementations I have seen, but feel free to blow holes in it. I am not really convinced that this is needed. But, I havent really thought about it. kab -jeff  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 5 Nov 87 03:19:06 EST Received: from ECLA.USC.EDU by SAIL.STANFORD.EDU with TCP; 5 Nov 87 00:00:51 PST Date: Thu 5 Nov 87 00:01:23-PST From: "Kim A. Barrett" Subject: flet/labels/macrolet To: common-lisp@SAIL.STANFORD.EDU cc: iim@ECLA.USC.EDU Message-ID: <12348118610.33.IIM@ECLA.USC.EDU> It is our opinion that it is reasonable for a local function/macro to be able to shadow a special form. If such shadowing is not allowed, it's basically just another totally arbitrary rule that the programmer has to remember. It also makes for some extra work for program-analyzing programs, either in the analysis of flet/labels/macrolet forms, where it must check the names to see if they would shadow any of the standard special-forms, or at form-processing time (where it is currently impossible to do portably). Note that the description of how such programs should process a form whose car is a symbol (on page 57 of CLtL) is wrong, in that it may not correctly handle local definitions. The key point is that such a program is allowed to special knowledge for 'functions' other than the 24 standard special-forms. If it does have such knowledge, it must first examine the local environment to see if its definition is being shadowed. Unfortunately, there is no portable way to examine the local environment. Actually, as I'm sitting here writing this, my thoughts keep drifting into a diatribe against the lack of portable mechanisms for dealing with environments. If you want to write a portable code walker that accepts an initial environment argument, either you simply can't do it if special-forms can be shadowed, or you have to restrict your code walker to only knowing about the standard special forms, which means it's still impossible, if the many complaints I've heard from people trying to write such things is any indication. Well, if I'm going to complain about it, I suppose I should propose a solution, so here goes ... It seems to me that the necessary functionality for examining the function environment is pretty easy to describe. All you really need is something like (defun local-function-p (symbol environment) "This function returns T if the specified symbol names a local function or macro in the specified environment, and Nil otherwise. Environment should be either the environment argument passed to a macroexpander function (obtained with the &environment lambda-keyword), or the environment argument to applyhook/evalhook." ...) I would expect that, for any given implementation, it is completely trivial to write the code for local-function-p. Does anyone know of a counter-example? With this function available, when your code walker is processing a form which is a list whose car is a symbol, it does the following ;; special forms can be shadowed (if (local-function-p (car form) environment) (multiple-value-bind (newform macrop) (macroexpand-1 form environment) (if macrop << recurse on newform >> << treate the form as a function call >> )) << do the stuff described on page 57 of CLtL >> ) ;; special forms cannot be shadowed (cond ((member (car form) *the-infamous-24-built-in-special-forms-names*) << run special code >> ) ((local-function-p (car form) environment) (multiple-value-bind (newform macrop) (macroexpand-1 form environment) (if macrop << recurse on newform >> << treate the form as a function call >> ))) (t << do the stuff described on page 57 of CLtL >> )) The functionality needed for augmenting environments is less obvious to me, since I haven't studied all that many code walkers to know what their needs are, nor all that many implementations, to know what their quirks are, as far as manipulation of environments is concerned. I think something like the following would be adequate for the walkers and implementations I have seen, but feel free to blow holes in it. (defun augment-function-environment (function-list environment &optional macroletp) "Return a new environment which is the same as environment except that the functions specified in function-list are visible. Environment should be an environment argument passed to a macroexpander function or applyhook/evalhook. Function-list is something suitable for the second argument to flet/labels/macrolet. If the optional third argument is true, they are added to the environment as local macro definitions, otherwise as local functions." ...) The reason for returning a new object, rather than possibly destructively modifying it, is so that the environment can be captured at a particular point without risking having it get modified during further processing. The definitions are needed for macrolet so that macroexpanding within the augmented environment will work. I don't know if anything clever needs to be done with the definitions for local functions. If so, then rather than having a macroletp flag this will probably need an argument which must be (member flet labels macrolet). Again, this seems like it should be trivial to write for a given implementation, although I feel a lot less certain about it for augment-function-environment than I do for local-function-p. I can't offhand think of a reasonable data structure for implementing environments which would have problems with this, but that doesn't mean there aren't any. As an argument for this being sufficient, I believe that these two functions are all that is needed to make the PCL code walker really portable, up to non-standard special-forms in a particular implementation. By the way, I have no strong attachment to the names specified above. They are only intended to be suggestive. kab -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Oct 87 19:12:18 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 28 Oct 87 15:54:13 PST Received: from Cabernet.ms by ArpaGateway.ms ; 28 OCT 87 15:54:24 PST Date: 28 Oct 87 15:54 PST From: Masinter.pa@Xerox.COM Subject: Re: suggestion for language extension In-reply-to: miller%ACORN.CS.ROCHESTER:EDU:Xerox's message of 26 Oct 87 15:28 To: miller@cs.rochester.EDU cc: common-lisp@Sail.stanford.edu Message-ID: <871028-155424-3550@Xerox> One of the primary design goals of CommonLoops was to allow the extensibility you describe; this certainly has been reflected in the Common Lisp Object System proposal. It seemed beyond the scope of the CLOS proposal to separate out exactly which functions were extensible and which were not; too many implementations make assumptions about what CAR can and cannot do for it to be part of today's standard. However, CLOS certainly gives the appropriate terminology -- far better than ADVISE. What you want to specify are some new methods for some of the existing generic functions.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Oct 87 13:57:56 EST Received: from CS.UTAH.EDU by SAIL.STANFORD.EDU with TCP; 28 Oct 87 10:32:57 PST Received: by cs.utah.edu (5.54/utah-2.0-cs) id AA14775; Wed, 28 Oct 87 11:32:27 MST Received: by orion.utah.edu (5.54/utah-1.0-slave) id AA13639; Wed, 28 Oct 87 11:32:19 MST Date: Wed, 28 Oct 87 11:32:19 MST From: sandra%orion@cs.utah.edu (Sandra J Loosemore) Message-Id: <8710281832.AA13639@orion.utah.edu> Subject: Re: integer-decode-float usage question To: Barry Margolin Cc: Sandra J Loosemore , Jeff Mincy , common-lisp@sail.stanford.edu In-Reply-To: Barry Margolin , Wed, 28 Oct 87 12:15 EST From: Barry Margolin The numbers [INTEGER-DECODE-FLOAT] returns are generally the exact same bit patterns as were in the float to begin with (except for the sign). All of the float formats I've ever come across assume there is an implied radix point in front of the fraction part, and the value of the the exponent stored in the bit pattern assumes the fraction part is really a fraction. If the float radix is 2, the exponent of 1.0 has a value of 1 regardless of how many bits are used to represent the fraction. That's the case for the native Vax representations, the Motorola FFP representation, the double precision floats handled by the E&S PS300 ACP (an implementation directly derived from Knuth's book), and I believe the IEEE representations as well (if my memory serves me correctly). The exponent returned by INTEGER-DECODE-FLOAT, which does depend on the number of bits in the fraction part, is almost certainly not the bit pattern actually stored in the number. (Besides, the exponent is often stored as an unsigned excess-N number instead of in its two's complement form.) The way CLtL defines the "exponent" makes some sense in its own right, but it's a different interpretation than what I believe to be the usual one. Again, it's the terminology that got me confused in the first place. -Sandra -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Oct 87 12:33:26 EST Received: from THINK.COM by SAIL.STANFORD.EDU with TCP; 28 Oct 87 09:14:49 PST Return-Path: Received: from occam by Think.COM via CHAOS; Wed, 28 Oct 87 12:14:47 EST Date: Wed, 28 Oct 87 12:15 EST From: Barry Margolin Subject: Re: integer-decode-float usage question To: Sandra J Loosemore Cc: Jeff Mincy , common-lisp@sail.stanford.edu In-Reply-To: <8710280507.AA11702@orion.utah.edu> Message-Id: <871028121504.5.BARMAR@OCCAM.THINK.COM> Date: Tue, 27 Oct 87 22:07:23 MST From: sandra%orion@cs.utah.edu (Sandra J Loosemore) I guess the real problem I'm having is one of terminology: the "exponent" returned by INTEGER-DECODE-FLOAT doesn't have the usual interpretation as the power of 2 (or whatever the float radix is) that you multiply the fractional part of the number by. (integer-decode-float 1.0) => 8388608, -23, 1 (float-radix 1.0) => 2 (expt 2 -23) => 1/8388608 (* 8388608 1/8388608) => 1 So, what's your complaint? 1.0 = 8388608*2^(-23) If you want the fraction to be as small as possible, you can write a function that repeatedly shifts it until the least-significant bit is 1, incrementing the exponent as it goes. In this case you'll end up with 1, 0, 1. This is at least the third time I've had to do a conversion between one floating point format and another. I've found myself wishing that, as long as CL provides portable primitives for inquiring about the floating point representations native to a particular implementation, it would also provide a function like INTEGER-DECODE-FLOAT that lets you ask for the same kinds of numbers but for some other float radix and precision. Or at least some more specific documentation on how users can do this themselves, given the existing primitives. INTEGER-DECODE-FLOAT does one very simple thing: it unpacks a floating point number. The numbers it returns are generally the exact same bit patterns as were in the float to begin with (except for the sign). barmar  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Oct 87 05:36:33 EST Received: from SCRC-YUKON.ARPA by SAIL.STANFORD.EDU with TCP; 28 Oct 87 02:15:17 PST Received: from WHITE-BIRD.SCRC.Symbolics.COM by YUKON.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 283329; Wed 28-Oct-87 05:16:18 EST Date: Wed, 28 Oct 87 05:16 EST From: Robert W. Kerns Subject: re: defstruct extensions To: goldman@vaxa.isi.edu cc: COMMON-LISP@sail.stanford.edu In-Reply-To: <8710271733.AA15979@vaxa.isi.edu> Message-ID: <19871028101610.9.RWK@WHITE-BIRD.SCRC.Symbolics.COM> Date: Tue, 27 Oct 87 09:33:23 PST From: goldman@vaxa.isi.edu The recently discussed extensions to DEFSTRUCT are reasonable and needed improvements. But I dissent from the proposal(s) for controlling printing, which seem like they require the use of a sledgehammer to crack an egg -- i.e., rebinding a special variable with dynamic effect on printing of ALL structure instances (or even all instances of a given class), including those embedded withing fields of other instances, when what is wanted, if Corkill's example is representative, is a finer control over a particular instance of printing. [I can't parse this last over-long sentence.] The default structure printing is no egg. It is a large boulder that someone dropped on us. The right technology to deal with it is not a sledgehammer, but dynamite. The one and only thing I want to have to do with the default structure printer is to *MAKE* *IT* *GO* *AWAY*! The one exception to this is if I indicate that I am doing output that is to be read by a program. The default structure printer is something only a program could love. The issue of how structures print is closely related to the issue of separating the use of printer control variables for controlling program communication from the use of printer control variables as user-interface parameters. In this vein, I have another proposal to make: *PRINT-STRUCTURE-CONTENTS* :FORCE-READABLE == force the now "standard" syntax. T == use the now "standard" syntax unless a printer is defined. NIL (the recommended default at top level) = use the #<...> syntax unless a printer is defined. [Feel free to add finer-grain control if desired, but this is definitely the level I would want to control this at.] PRINTING-RANDOM-OBJECT ((object stream &key (typep t) (unique-id t)) &body body) Used in print functions, this takes care of printing the standard part of non-readable objects. If *PRINT-FOR-READ* is T (see below), it signals an error. The body is responsible for printing all of the stuff in the middle, to identify the particular structure. :TYPEP NIL suppresses the type name at the start (leaving that responsibility to the body), and :UNIQUE-ID NIL suppresses the number at the end. *PRINT-ESCAPE* NIL == use the printer control variables. T == use the printer control variables. :FOR-READ = signal an error if PRINTING-RANDOM-OBJECT is called. :FOR-READ-FORCE = skip print functions, and signal an error if PRINTING-RANDOM-OBJECT is called (say, by the system-supplied printer for a compiled function). WITH-IO-ENVIRONMENT ((&Rest IO-keywords &KEY &ALLOW-OTHER-KEYS) &Body body) Set up the IO parameters to allow programs to communicate. Binds all IO parameters (including any defined by local extensions to CL) to produce the standard results. (*PRINT-ESCAPE* is bound to :FOR-READ, *PRINT-STRUCTURE-CONTENTS* is bound to T). Any IO-keywords supplied override the standard values. For example, an application may which to say: (WITH-IO-ENVIRONMENT (:PACKAGE "MY-DATABASE" :BASE 8.) (PRINT DATABASE STREAM)) [Actually, I really think that printer control should be on a per-stream basis, and the printer control variables should just serve as defaults when creating a stream. But I don't see how to change that at this late date.] DEFAULT-PRINT-STRUCTURE (object stream print-depth) Print a structure in the now-standard manner. To take your example and recast it slightly: (defstruct (employee (:print-function (lambda (employee stream print-depth) ;; This print function won't be called if *PRINT-ESCAPE* ;; is :FOR-READ-FORCE. (case *print-escape* (:for-read (default-print-structure employee stream print-depth)) (otherwise (format stream "{Employee: ~A}" (employee-name employee)))))))) (One flaw in your example was that *PRINT-PRETTY* is only supposed to control simple changes like whitespace and 'FOO vs (QUOTE FOO).) Implementations would be allowed to default the printer flags with somewhat more latitude than they are now. For example: *print-case*, *print-level*, *print-length*, *print-array*, *print-structure-contents*. In addition, an implementation may provide other flags, such as *PRINT-ARRAY-LENGTH*, (a maximum size to print using the readable syntax for arrays), and these must be bound by WITH-IO-ENVIRONMENT to values to producing the standard syntax. Any program writing data for use by other programs which does not use WITH-IO-ENVIRONMENT is in error. (Currently, any program which doesn't simulate WITH-IO-ENVIRONMENT by hand, is going to break whenever any user sets any control variables for whatever reason.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 28 Oct 87 00:23:35 EST Received: from CS.UTAH.EDU by SAIL.STANFORD.EDU with TCP; 27 Oct 87 21:07:20 PST Received: by cs.utah.edu (5.54/utah-2.0-cs) id AA22203; Tue, 27 Oct 87 22:07:27 MST Received: by orion.utah.edu (5.54/utah-1.0-slave) id AA11702; Tue, 27 Oct 87 22:07:23 MST Date: Tue, 27 Oct 87 22:07:23 MST From: sandra%orion@cs.utah.edu (Sandra J Loosemore) Message-Id: <8710280507.AA11702@orion.utah.edu> Subject: Re: integer-decode-float usage question To: Jeff Mincy Cc: sandra%orion@cs.utah.edu, common-lisp@sail.stanford.edu In-Reply-To: Jeff Mincy , Tue, 27 Oct 87 21:14 EST I guess the real problem I'm having is one of terminology: the "exponent" returned by INTEGER-DECODE-FLOAT doesn't have the usual interpretation as the power of 2 (or whatever the float radix is) that you multiply the fractional part of the number by. This is at least the third time I've had to do a conversion between one floating point format and another. I've found myself wishing that, as long as CL provides portable primitives for inquiring about the floating point representations native to a particular implementation, it would also provide a function like INTEGER-DECODE-FLOAT that lets you ask for the same kinds of numbers but for some other float radix and precision. Or at least some more specific documentation on how users can do this themselves, given the existing primitives. -Sandra -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Oct 87 21:36:09 EST Received: from THINK.COM by SAIL.STANFORD.EDU with TCP; 27 Oct 87 18:11:52 PST Return-Path: Received: from zeno by Think.COM via CHAOS; Tue, 27 Oct 87 21:11:50 EST Date: Tue, 27 Oct 87 21:14 EST From: Jeff Mincy Subject: integer-decode-float usage question To: sandra%orion@cs.utah.edu, common-lisp@sail.stanford.edu In-Reply-To: <8710280144.AA11261@orion.utah.edu> Message-Id: <871027211454.3.MINCY@ZENO.THINK.COM> Date: Tue, 27 Oct 87 18:44:02 MST From: sandra%orion@cs.utah.edu (Sandra J Loosemore) Perhaps I'm just being exceptionally dense today, but I'm having a hard time figuring out how to convert floating point numbers on one machine into a representation used by another machine (namely, the Motorola FFP format). I assume that this was the reason why the function INTEGER-DECODE-FLOAT was provided, but darned if I know how to interpret the numbers I'm getting back from it -- the exponent of 1.0 is -23?!? Or is that a bug in the implementation (VaxLisp)? Can anyone shed some light on the topic? -Sandra Having -23 as an exponent makes perfect sense if the first value that integer-decode-float returns is (expt 2 23) or 8388608, and the float-radix is 2. You have to look at both values together for the exponent to make sense. To get the 1.0 back from the integer-decode-float values do (scale-float (float 8388608) -23). Which is (expt 2 (+ 23 -23)) or 1. -jeff  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Oct 87 21:02:37 EST Received: from CS.UTAH.EDU by SAIL.STANFORD.EDU with TCP; 27 Oct 87 17:43:53 PST Received: by cs.utah.edu (5.54/utah-2.0-cs) id AA17563; Tue, 27 Oct 87 18:44:06 MST Received: by orion.utah.edu (5.54/utah-1.0-slave) id AA11261; Tue, 27 Oct 87 18:44:02 MST Date: Tue, 27 Oct 87 18:44:02 MST From: sandra%orion@cs.utah.edu (Sandra J Loosemore) Message-Id: <8710280144.AA11261@orion.utah.edu> Subject: integer-decode-float usage question To: common-lisp@sail.stanford.edu Perhaps I'm just being exceptionally dense today, but I'm having a hard time figuring out how to convert floating point numbers on one machine into a representation used by another machine (namely, the Motorola FFP format). I assume that this was the reason why the function INTEGER-DECODE-FLOAT was provided, but darned if I know how to interpret the numbers I'm getting back from it -- the exponent of 1.0 is -23?!? Or is that a bug in the implementation (VaxLisp)? Can anyone shed some light on the topic? -Sandra -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Oct 87 15:31:29 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 27 Oct 87 12:11:53 PST Received: from Salvador.ms by ArpaGateway.ms ; 27 OCT 87 11:57:07 PST Date: 27 Oct 87 11:18 PDT From: masinter.pa@Xerox.COM Subject: Re: macrolet/flet/labels In-reply-to: pyrnj!pyramid!bein%RUTGERS:EDU:Xerox's message of 24 Oct 87 21:09 To: pyrnj!pyramid!bein@RUTGERS.EDU cc: common-lisp@sail.stanford.edu Message-ID: <871027-115707-1048@Xerox> Until the issue has been resolved, it seems like a good idea to avoid shadowing ANY function or macro in CLtL with MACROLET/FLET/LABELS, but especially special forms. For example, suppose that you had (flet ((cons (x y) (cons y x))) (unwind-protect (my-call) (my-cleanup))) In some systems, unwind-protect might be implemented as a macro which expands into something that invokes CONS. The primary problem is the possibility of references to Common Lisp functions and special forms within macros invoked within the scope of the FLET, LABELS or MACROLET. Until there is a macro expansion mechanism universally adopted which protects macro references from unexpected local rebindings, you're best off avoiding the whole problem by not shadowing functions whose references you have no control over.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Oct 87 13:04:48 EST Received: from [192.5.53.205] by SAIL.STANFORD.EDU with TCP; 27 Oct 87 09:44:16 PST Received: from Think.COM (THINK.COM) by DOUGHNUT.CS.ROCHESTER.EDU via INTERNET with SMTP id 8517; 27 Oct 87 12:44:34 EST Return-Path: Received: from occam by Think.COM via CHAOS; Tue, 27 Oct 87 12:43:43 EST Date: Tue, 27 Oct 87 12:43 EST From: Barry Margolin Subject: Re: suggestion for language extension To: miller@cs.rochester.edu Cc: cl@doughnut.cs.rochester.edu In-Reply-To: <871027010550.1.MILLER@DOUGHNUT.CS.ROCHESTER.EDU> Message-Id: <871027124353.3.BARMAR@OCCAM.THINK.COM> Date: Tue, 27 Oct 87 01:05 EST From: Brad Miller Date: Mon, 26 Oct 87 18:34 EST From: Barry Margolin I believe CLOS will allow this, although there will probably be some restrictions on the built-in functions that may be converted to generic functions (my feeling is that only functions proclaimed INLINE should be restricted). I don't think this would be general enough, see following... It seems completely general to me. Anything that isn't open-coded could be turned into a generic function that dispatches on the data types of its arguments. What more do you need? You mentioned that overloading could be implemented using an ADVISE feature. A simple-minded ADVISE can be implemented using existing CL facilities, so there is no real need for extending the language: This (a macro) does not alter the run-time semantics of already compiled programs, which would be necessary... Why doesn't it? It redefines the function you want to overload. Unless the function you are overloading was originally a macro or open-coded function, future calls will go to the new definition. Before we got into the habit of customizing the Symbolics environment using ADVISE we used something like it all the time. What I would *like* to do... Take the example of creating something that is a (possibly infinite) list, but lazy-eval'd. So you want to overload all the existing CL functions that can possibly accept lists, That's a LOT of functions! and make them accept lazy-lists as well. ... cons, car, cdr, etc. work on all objects of type list independent of their lazyness. Except that most of the functions already in the environment had CAR and CDR compiled inline, so they won't pick up the overloaded definition. The main intent (for me particularly) is to get scheme-style streams up, but I figured other people might want to create first class objects too... Scheme-style streams don't require overloading. In Scheme you use different functions (HEAD, TAIL) to get the items of a stream from the ones used to get items in a list (CAR, CDR). Scheme doesn't have any special overloading support, either. The other thing I *really* would like is scheme-style continuations, but I suspect this sort of thing would be politically non-feasible at this point. Overloading helps, in that I can make continuations first class objects, but getting to just what a continuation is would still be hard since you need to snapshot the stack... CL already knows how to snapshot the stack, to make lexical closures. The problem is that there are some arbitrary limitations on what a closure can do. This sort of thing may be better addressed as something CL would provide explicitly; I can't think of general underlying mechanisms that solve continuations that would also be useful to make generally available because of their utility in extending the language. (without consing up infinite hair in terms of concrete language semantics). All that needs to be done to CL to make continuations as useful as they are in Scheme is to change the extent of CATCH tags, BLOCK names, and TAGBODY labels from dynamic to indefinite. Unfortunately, this would be a significant change to the language, and I'm not sure that its impact on existing implementations would be worth the gain. But if those restrictions were lifted, the following definition of CALL/CC would suffice: (defmacro call/cc (function &rest args &aux (block-name (gensym))) `(block ,block-name (funcall ,function #'(lambda (&rest results) (return-from ,block-name (values-list results))) .,args))) I'm not a Scheme programmer, and I don't know what the value of being able to transfer into a function that already returned is. One thing I believe CALL/CC is used for is coroutines, and the above CL implementation will support that; however, without tail-recursion optimization you will get pretty deep pretty quickly. barmar  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Oct 87 12:54:17 EST Received: from VAXA.ISI.EDU by SAIL.STANFORD.EDU with TCP; 27 Oct 87 09:33:07 PST Posted-Date: Tue, 27 Oct 87 09:33:23 PST Message-Id: <8710271733.AA15979@vaxa.isi.edu> Received: from LOCALHOST by vaxa.isi.edu (5.54/5.51) id AA15979; Tue, 27 Oct 87 09:33:43 PST To: COMMON-LISP@sail.stanford.edu From: goldman@vaxa.isi.edu Subject: re: defstruct extensions Cc: goldman@vaxa.isi.edu Date: Tue, 27 Oct 87 09:33:23 PST Sender: goldman@vaxa.isi.edu The recently discussed extensions to DEFSTRUCT are reasonable and needed improvements. But I dissent from the proposal(s) for controlling printing, which seem like they require the use of a sledgehammer to crack an egg -- i.e., rebinding a special variable with dynamic effect on printing of ALL structure instances (or even all instances of a given class), including those embedded withing fields of other instances, when what is wanted, if Corkill's example is representative, is a finer control over a particular instance of printing. In fact, it looks like what is wanted here is the CALL-NEXT-METHOD ability of CLOS. Think of PRINT-STRUCTURE as a generic operation, with a method defined for STRUCTURE (which prints #<...>). Providing a print-function in a defstruct can then be viewed as a syntactic device for defining a PRINT-STRUCTURE method for that specialization of STRUCTURE. If there is sufficient need to resolve this problem prior to any integration of CLOS and structures, I would favor a solution that at least "feels" like this -- e.g., a special form (DEFAULT-PRINT-STRUCTURE) (no arguments) that could ONLY appear lexically within a structure's print function (defstruct (employee (:print-function (lambda (employee stream print-depth) (declare (ignore print-depth)) (cond ((and (not *print-pretty*) *print-escape*) (DEFAULT-PRINT-STRUCTURE)) ;; Pretty printing requested (t (format stream "{Employee: ~A}" (employee-name employee))))))) ...) Alternatively, and less desirable in my mind, a function (WRITE-STRUCTURE-DEFAULT structure-instance) could be provided to ask for an arbitrary instance to be printed with the default structure printer. Neil  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Oct 87 01:28:36 EST Received: from [192.5.53.205] by SAIL.STANFORD.EDU with TCP; 26 Oct 87 22:06:14 PST Date: Tue, 27 Oct 87 01:05 EST From: Brad Miller Subject: Re: suggestion for language extension To: Barry Margolin cc: cl@DOUGHNUT.CS.ROCHESTER.EDU In-Reply-To: <871026183445.4.BARMAR@OCCAM.THINK.COM> Message-ID: <871027010550.1.MILLER@DOUGHNUT.CS.ROCHESTER.EDU> Default-Character-Style: (:FIX :CONDENSED :NORMAL) Fonts: CPTFONTC Sender: miller@cs.rochester.edu Reply-To: miller@cs.rochester.edu Organization: University of Rochester, Department of Computer Science Postal-address: 401A CS Building, Computer Science Department, University of Rochester, Rochester NY 14627 Phone: 716-275-1118 Date: Mon, 26 Oct 87 18:34 EST From: Barry Margolin Date: Mon, 26 Oct 87 17:37 EST From: Brad Miller There is, in fact, something conceptually simple that could be added to the spec, is upward compatible with the current language, and would make me sleep a lot easier (though compiler writers may groan a bit): Allow overloading of functions. This would allow me to create my own first-class objects, since I could overload common operators to handle (special case) the new type. What do you mean by this? Do you mean overloading in the Ada sense, where you specify the data types of the arguments that cause a particular implementation of the function to be invoked? Yes. Like Ada, the information would be static, unlike Ada, result type wouldn't (necessarily) need to be taken into account. I believe CLOS will allow this, although there will probably be some restrictions on the built-in functions that may be converted to generic functions (my feeling is that only functions proclaimed INLINE should be restricted). I don't think this would be general enough, see following... You mentioned that overloading could be implemented using an ADVISE feature. A simple-minded ADVISE can be implemented using existing CL facilities, so there is no real need for extending the language: This (a macro) does not alter the run-time semantics of already compiled programs, which would be necessary... ... redefined without affecting the advice, which requires hooks in the implementation; however, I don't think it is necessary for the overloading feature that Brad wants. Then again... Another question: what particular problem does overloading solve for you? What I would *like* to do... Take the example of creating something that is a (possibly infinite) list, but lazy-eval'd. So you want to overload all the existing CL functions that can possibly accept lists, and make them accept lazy-lists as well. Some of them (e.g. reverse) might return an error when you pass them a lazy-list, but most (e.g. cdr) may run the function associated with the lazy-list to generate the next item. Once the lazy-list abstraction/type has been defined, there should be no particular reason existing programs should not be able to accept/deal with them, so long as the underlying functions have been taught how to handle them. You have, with this mechanism, *extended the language* to include the new first class object of lazy-stream, which is considerably different than defining lazy-cons, lazy-car, .... and having your program call these functions itself. To the programmer, the extension is transparent. cons, car, cdr, etc. work on all objects of type list independent of their lazyness. The main intent (for me particularly) is to get scheme-style streams up, but I figured other people might want to create first class objects too... The other thing I *really* would like is scheme-style continuations, but I suspect this sort of thing would be politically non-feasible at this point. Overloading helps, in that I can make continuations first class objects, but getting to just what a continuation is would still be hard since you need to snapshot the stack... This sort of thing may be better addressed as something CL would provide explicitly; I can't think of general underlying mechanisms that solve continuations that would also be useful to make generally available because of their utility in extending the language. (without consing up infinite hair in terms of concrete language semantics). Thanks for your interest! Brad Miller ------ miller@cs.rochester.edu {...allegra!rochester!miller} Brad Miller University of Rochester Computer Science Department  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 27 Oct 87 01:08:36 EST Received: from SCRC-YUKON.ARPA by SAIL.STANFORD.EDU with TCP; 26 Oct 87 21:49:55 PST Received: from WHITE-BIRD.SCRC.Symbolics.COM by YUKON.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 282589; Mon 26-Oct-87 23:37:47 EST Date: Mon, 26 Oct 87 23:37 EST From: Robert W. Kerns Subject: extending DEFSTRUCT To: Don Morrison cc: Rick.Busdiecker@cs.cmu.edu, common-lisp@SAIL.STANFORD.EDU In-Reply-To: <871026122502.1.DFM@WHITBY.Palladian.COM> Message-ID: <19871027043741.4.RWK@WHITE-BIRD.SCRC.Symbolics.COM> Date: Mon, 26 Oct 87 12:25 EST From: Don Morrison If you do, you probably should make it # where NNN is an integer (decimal?) such that two eq structures always have the same number, and two not eq structures don't. I believe this corresponds pretty closely to current practice for those implementations that do support such a beast. The major difference, I believe, is that often NNN is currently an address that can change over time; it would probably be cleaner for eq structures to always print the same, no matter how manner GCs have intervened. Since the hash or whatever it is you'd stick there would only need to be computed if you're printing the thing, I suspect it wouldn't add any serious overhead to structures that's not already there to support eq hash tables. Wait a minute, EQ hash tables can't work that way; they have to work on bignums and rationals and conses and other things that don't have any private slot to store the hash in. And yes, adding overhead to structures to support this would indeed be prohibitively expensive. On the other hand, if you don't mind having things you print never go away in the GC, you could use EQ hash tables to implement this, and only incur a cost for structures you actually print. But not having structures GC is a serious flaw, too. I don't see that we could reasonably impose this on implementations. Also, the octal address is often useful. I use it all the time when I'm debugging the mouse input code so that I can't just point at structures with the mouse. We used to use it a lot more, and (sys:%find-structure-header #o234725) is sort of an idiom around here amongst the hackers of the lower levels. (It returns the object; it means essentially "object at address", and figures out the type codes).  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 26 Oct 87 18:56:08 EST Received: from [192.5.53.205] by SAIL.STANFORD.EDU with TCP; 26 Oct 87 15:34:51 PST Received: from Think.COM (THINK.COM) by DOUGHNUT.CS.ROCHESTER.EDU via INTERNET with SMTP id 8511; 26 Oct 87 18:35:09 EST Return-Path: Received: from occam by Think.COM via CHAOS; Mon, 26 Oct 87 18:34:22 EST Date: Mon, 26 Oct 87 18:34 EST From: Barry Margolin Subject: suggestion for language extension To: miller@cs.rochester.edu Cc: cl@doughnut.cs.rochester.edu In-Reply-To: <871026173702.5.MILLER@DOUGHNUT.CS.ROCHESTER.EDU> Message-Id: <871026183445.4.BARMAR@OCCAM.THINK.COM> Date: Mon, 26 Oct 87 17:37 EST From: Brad Miller There is, in fact, something conceptually simple that could be added to the spec, is upward compatible with the current language, and would make me sleep a lot easier (though compiler writers may groan a bit): Allow overloading of functions. This would allow me to create my own first-class objects, since I could overload common operators to handle (special case) the new type. What do you mean by this? Do you mean overloading in the Ada sense, where you specify the data types of the arguments that cause a particular implementation of the function to be invoked? I believe CLOS will allow this, although there will probably be some restrictions on the built-in functions that may be converted to generic functions (my feeling is that only functions proclaimed INLINE should be restricted). You mentioned that overloading could be implemented using an ADVISE feature. A simple-minded ADVISE can be implemented using existing CL facilities, so there is no real need for extending the language: (defmacro advise (function &body body) (let ((new-fun (gensym))) `(progn (setf (symbol-function ',new-fun) (symbol-function ',function)) (defun ,function (&rest arglist) (flet ((do-it () (apply ',new-fun arglist))) .,body))))) This defines something like the lispm :AROUND advice, except that (do-it) is used in place of :do-it. It also doesn't support unadvise, named advice, etc., but those merely require maintaining a database. It also doesn't support the lispm feature that an advised function can be redefined without affecting the advice, which requires hooks in the implementation; however, I don't think it is necessary for the overloading feature that Brad wants. Another question: what particular problem does overloading solve for you? If you want a function that is like READ-CHAR except that it does something different when the stream argument is one of your structures, you can do: (defun my-read-char (stream) (if (my-struct-p stream) (read-char-from-my-struct stream) (read-char stream))) and call my-read-char in place of read-char in your program. If your intent was to pass a my-struct to some other CL input function, such as READ or READ-LINE, advising read-char wouldn't necessarily help (CL gives no guarantee that READ, READ-LINE, etc. call READ-CHAR internally, although particular CL implementations may do so). barmar  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 26 Oct 87 17:56:09 EST Received: from [192.5.53.205] by SAIL.STANFORD.EDU with TCP; 26 Oct 87 14:37:12 PST Date: Mon, 26 Oct 87 17:37 EST From: Brad Miller Subject: suggestion for language extension To: cl@DOUGHNUT.CS.ROCHESTER.EDU Message-ID: <871026173702.5.MILLER@DOUGHNUT.CS.ROCHESTER.EDU> Sender: miller@cs.rochester.edu Reply-To: miller@cs.rochester.edu Organization: University of Rochester, Department of Computer Science Postal-address: 401A CS Building, Computer Science Department, University of Rochester, Rochester NY 14627 Phone: 716-275-1118 I'd like to make a proposal, though this is not concrete enough to be handed to the technical committee, I'm hoping it will generate some discussion. I don't know if any of you saw my short flame in comp.lang.lisp; in summary I am disapointed in the lack of (certain kinds of) extensibility in CL. There is, in fact, something conceptually simple that could be added to the spec, is upward compatible with the current language, and would make me sleep a lot easier (though compiler writers may groan a bit): Allow overloading of functions. This would allow me to create my own first-class objects, since I could overload common operators to handle (special case) the new type. What (I think) this means to the CL implementor... If you are a lispm manufacturer, I can imagine something like 'advise' would pretty much do the trick, though one might like to be able to (at some point compile in the advice on a function, make the compiler know about the new type etc. Even create a special tag for the object and patch the microcode. But that's probably going overboard (though it is something a lispm may be able to do a lot easier than a SUN). For most, a function similar to the lispm advise would be needed, since one may want to overload potentally any function. Again, there would be no particular requirement for *efficiency*, though it would be nice, of course, the idea would be to allow the user to create a first-class object, be it a lazy-stream, a continuation, or whatever. Thanks for listening, Brad Miller ------ miller@cs.rochester.edu {...allegra!rochester!miller} Brad Miller University of Rochester Computer Science Department  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 26 Oct 87 16:15:56 EST Received: from CS.UTAH.EDU by SAIL.STANFORD.EDU with TCP; 26 Oct 87 12:52:24 PST Received: by cs.utah.edu (5.54/utah-2.0-cs) id AA17779; Mon, 26 Oct 87 13:52:35 MST Received: by cons.UTAH.EDU (4.30/4.40.2) id AA03833; Mon, 26 Oct 87 13:52:20 mst Date: Mon, 26 Oct 87 13:52:20 mst From: kessler%cons@cs.utah.edu (Robert R. Kessler) Message-Id: <8710262052.AA03833@cons.UTAH.EDU> To: common-lisp@sail.stanford.edu Subject: 1988 LISP & FUNCTIONAL PROGRAMMING - CALL FOR PAPERS CALL FOR PAPERS 1988 ACM Conference on LISP AND FUNCTIONAL PROGRAMMING Snowbird, Utah, July 25-27, 1988 The 1988 ACM Conference on LISP and Functional Programming is the fifth in a series of biennial conferences devoted to the theory, design, and implementation of programming languages and systems that support symbolic computation. The conference is jointly sponsored by ACM SIGPLAN, SIGACT, and SIGART. Papers presented at the conference must include new ideas or experimental results that have not been previously published. The conference program is not limited to topics discussed in previous conferences in the series; authors are strongly encouraged to submit papers that in- troduce important new topics that are relevant to functional pro- gramming and symbolic computation. The major topics that have been addressed at previous conferences include: 1) programming language concepts and facilities 2) implementation methods 3) machine architectures 4) semantic foundations 5) programming logics 6) program development environments 7) applications of symbolic computation Authors are invited to submit 11 copies of a technical summary of a prospective confer- ence paper to the program committee chairman. The length of the summary should not exceed 3,000 words (10 pages double-spaced or typeset 10-point on 16-point spacing). Since the committee ex- pects to receive a large number of submissions, the summary should be organized so that it is easily understood. It is im- portant for the summary to identify what has been accomplished, explain why it is significant, and compare it with previous work. Submissions must be received by Jan 22, 1988. They should in- clude a return postal address and an electronic mail address if it is available. Authors will be notified of the acceptance or rejection of their papers by March 11, 1988. Full versions of the accepted papers must be received in camera-ready form by April 22, 1988. Authors of accepted papers will be required to sign ACM copyright release forms. Proceedings will be distribut- ed at the conference and will later be available for purchase from the ACM. The conference site at Snowbird, Utah is a resort located in the rugged Wasatch mountain range approximately 35 miles from Salt Lake City. Summer activities include hiking, climbing, swimming, tennis, and wildflower photography. Program Committee Chairman Program Committee Robert (Corky) Cartwright Harold Abelson, MIT Attn: LFP 88 Richard Bird, Oxford University Rice University Luca Cardelli, DEC Systems Res. Ctr. Department of Computer Science Robert Cartwright, Rice University P. O. Box 1892 Richard Gabriel, Lucid Inc. Houston, TX 77251-1892 Christopher Haynes, Indiana University (713) 527-4834 Gerard Huet, INRIA Rocquencourt cork@rice.edu Gilles Kahn, INRIA Sophia Antipolis David Moon, Symbolics Inc. Guy Steele, Thinking Machines Corp. Carolyn Talcott, Stanford University General Chairman Local Arrangements Chairman Jerome Chailloux Robert Kessler INRIA University of Utah Domaine de Voluceau-Rocquencourt Department of Computer Science B.P. 105 3190 M.E.B. Le Chesnay Cedex Salt Lake City, Utah 84112 France kessler@cs.utah.edu chaillou@inria.inria.fr  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 26 Oct 87 14:03:30 EST Received: from XX.LCS.MIT.EDU by SAIL.STANFORD.EDU with TCP; 26 Oct 87 10:50:31 PST Received: from LIVE-OAK.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 26 Oct 87 13:27-EST Received: from JASPER.Palladian.COM by MIT-LIVE-OAK.DialNet.Symbolics.COM via DIAL with SMTP id 65230; 26 Oct 87 13:16:01-EST Received: from WHITBY.Palladian.COM by JASPER.Palladian.COM via INTERNET with SMTP id 12227; 26 Oct 87 12:27:26-EST Date: Mon, 26 Oct 87 12:25 EST From: Don Morrison Subject: extending DEFSTRUCT To: Rick.Busdiecker@cs.cmu.edu cc: common-lisp@SAIL.STANFORD.EDU In-Reply-To: <562168063/rfb@H.GP.CS.CMU.EDU> Message-ID: <871026122502.1.DFM@WHITBY.Palladian.COM> Reply-To: Don Morrison Date: 25 Oct 1987 08:47-EST From: Rick.Busdiecker@H.GP.CS.CMU.EDU Is there really a standard for #<> notation? If so, what is it and where is it defined? If not, perhaps we should define a default #<> notation such as #. If you do, you probably should make it # where NNN is an integer (decimal?) such that two eq structures always have the same number, and two not eq structures don't. I believe this corresponds pretty closely to current practice for those implementations that do support such a beast. The major difference, I believe, is that often NNN is currently an address that can change over time; it would probably be cleaner for eq structures to always print the same, no matter how manner GCs have intervened. Since the hash or whatever it is you'd stick there would only need to be computed if you're printing the thing, I suspect it wouldn't add any serious overhead to structures that's not already there to support eq hash tables.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 26 Oct 87 12:51:14 EST Received: from [128.81.41.45] by SAIL.STANFORD.EDU with TCP; 26 Oct 87 09:34:45 PST Received: from EUPHRATES.SCRC.Symbolics.COM by ALLEGHENY.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 69577; Mon 26-Oct-87 12:11:28 EST Date: Mon, 26 Oct 87 12:11 EST From: David A. Moon Subject: Re: extending DEFSTRUCT To: Daniel L. Cerys cc: common-lisp@SAIL.STANFORD.EDU In-Reply-To: <2771248902-3508558@RTS-12> Message-ID: <19871026171117.8.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Mon, 26 Oct 87 10:21:42 EST From: "Daniel L. Cerys" > Kerns: > When *PRINT-STRUCTURE* in NIL: > I think a slightly better name is *PRINT-STRUCTURE-CONTENTS*. > (We've had this for a couple years). I agree on the utility of this variable, but not on its name. Since *PRINT-ARRAY* determines whether the contents of arrays are printed, a variable named *PRINT-STRUCTURE* should do the same for structures. Using *PRINT-STRUCTURE-CONTENTS* wouldn't be as clear. Don't you think that what that really indicates is that the name *PRINT-ARRAY* was poorly chosen and is not as clear? If you look through the list of printer flags on CLtL pp.370-373, *print-array* is the only one that doesn't connote very well what it does, to my ear. It's as if someone thought it was more important to make all the names exactly two words long.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 26 Oct 87 12:14:34 EST Received: from [128.81.41.223] by SAIL.STANFORD.EDU with TCP; 26 Oct 87 08:55:34 PST Received: from EVENING-GROSBEAK.SCRC.Symbolics.COM by SAPSUCKER.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 175095; Mon 26-Oct-87 11:57:40 EST Date: Mon, 26 Oct 87 11:55 EST From: Scott McKay Subject: Re: macrolet/flet/labels To: Pavel.pa@Xerox.COM, common-lisp@sail.stanford.edu In-Reply-To: <871025-162130-1009@Xerox> Message-ID: <19871026165544.1.SWM@EVENING-GROSBEAK.SCRC.Symbolics.COM> Date: Sun, 25 Oct 87 15:44:22 PST From: Pavel.pa@Xerox.COM Date: 24 Oct 87 18:57 PDT From: David Bein What is the current consensus about using a name within a macrolet/flet/labels construct which is a special form? I am cleaning things up this way and it occurred to me that things could go either way. I am of the opinion that the names of the special forms are really reserved words and that you cannot redefine them even lexically. Thus, none of the names of special forms can be used as the defined-name in flet, labels, or macrolet. I can't imagine a case in which this could be anything but extremely confusing to a program reader nor can I think of any reason why it might be useful. We subscribe to your notions here. Our compiler warns you that you will probably lose when you FLET/LABEL/MACROLET a special form.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 26 Oct 87 10:47:39 EST Received: from XX.LCS.MIT.EDU by SAIL.STANFORD.EDU with TCP; 26 Oct 87 07:30:53 PST Received: from RTS-12.LCS.MIT.EDU by XX.LCS.MIT.EDU via Chaosnet; 26 Oct 87 10:27-EST Message-Id: <2771248902-3508558@RTS-12> Sender: cerys@RTS-12 Date: Mon, 26 Oct 87 10:21:42 EST From: "Daniel L. Cerys" To: "Robert W. Kerns" Cc: common-lisp@SAIL.STANFORD.EDU Subject: Re: extending DEFSTRUCT In-Reply-To: Msg of Sun, 25 Oct 87 21:31 EST from Robert W. Kerns > When *PRINT-STRUCTURE* in NIL: > I think a slightly better name is *PRINT-STRUCTURE-CONTENTS*. > (We've had this for a couple years). I agree on the utility of this variable, but not on its name. Since *PRINT-ARRAY* determines whether the contents of arrays are printed, a variable named *PRINT-STRUCTURE* should do the same for structures. Using *PRINT-STRUCTURE-CONTENTS* wouldn't be as clear.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 25 Oct 87 21:49:58 EST Received: from SCRC-YUKON.ARPA by SAIL.STANFORD.EDU with TCP; 25 Oct 87 18:30:43 PST Received: from WHITE-BIRD.SCRC.Symbolics.COM by YUKON.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 281872; Sun 25-Oct-87 21:31:32 EST Date: Sun, 25 Oct 87 21:31 EST From: Robert W. Kerns Subject: extending DEFSTRUCT To: Rick.Busdiecker@cs.cmu.edu cc: Dave.Touretzky@C.CS.CMU.EDU, common-lisp@SAIL.STANFORD.EDU In-Reply-To: <562168063/rfb@H.GP.CS.CMU.EDU> Message-ID: <19871026023112.9.RWK@WHITE-BIRD.SCRC.Symbolics.COM> Date: 25 Oct 1987 08:47-EST From: Rick.Busdiecker@H.GP.CS.CMU.EDU I also support the proposed extensions to structure handling. Date: Sat 24 Oct 87 15:16:08-EDT From: Dave.Touretzky@C.CS.CMU.EDU When *PRINT-STRUCTURE* in NIL: I think a slightly better name is *PRINT-STRUCTURE-CONTENTS*. (We've had this for a couple years). Most of us find this has to be NIL in order not to be innundated with useless internal details of the structures we look at. (The #<...> representations are designed to provide what information you need at a glance). Generally, CL fails to distinguish between PRINT/READ as communication between programs (in which case, you either want to bind all the flags to standard, known values, or ignored totally), and communication with the user or programmer, in which case you want the flags set for maximum usability. #S syntax is clearly an example where utility for programs was chosen over usability for programmers. defstructs with their own print functions will use them defstructs without their own print function will print in the #<> notation Is there really a standard for #<> notation? If so, what is it and where is it defined? If not, perhaps we should define a default #<> notation such as #. The standard is that it signals an error (see pg 360 of CLtL). What CLtL doesn't say, but should, is that: 1) The #< should be balanced with a >. 2) There are certain recommended higher conventions to be followed: a) The type should be given first. This is not necessarily what TYPE-OF will return, but it should be descriptive and non-confusing to the user. (This means it should probably be a type acceptable to TYPEP, of which this object is a member). The structure type name is the default. b) Named objects should, where possible, follow their type with their name. c) Other descriptive information may be included, in a user-determined (but brief) format. d) Where it is desirable to distinguish different instances of the same type of object, which may otherwise print the same, the last thing printed before the closing ">" should be a unique-ID. (On our system we use the octal address by default). This should generally be omitted when there is no difficulty distinguishing objects on sight (for example, objects with unique names). As you can see, these are conventions designed to make things easier for the programmer looking at these objects while debugging, and not something that some program or other rigid-thinking entity will look at.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 25 Oct 87 19:37:06 EST Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 25 Oct 87 16:20:49 PST Received: from Salvador.ms by ArpaGateway.ms ; 25 OCT 87 16:21:30 PST Date: Sun, 25 Oct 87 15:44:22 PST From: Pavel.pa@Xerox.COM Subject: Re: macrolet/flet/labels In-reply-to: <562125428/bein@pyrnova> To: common-lisp@sail.stanford.edu Message-ID: <871025-162130-1009@Xerox> Date: 24 Oct 87 18:57 PDT From: David Bein What is the current consensus about using a name within a macrolet/flet/labels construct which is a special form? I am cleaning things up this way and it occurred to me that things could go either way. I am of the opinion that the names of the special forms are really reserved words and that you cannot redefine them even lexically. Thus, none of the names of special forms can be used as the defined-name in flet, labels, or macrolet. I can't imagine a case in which this could be anything but extremely confusing to a program reader nor can I think of any reason why it might be useful. Pavel  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 25 Oct 87 12:57:39 EST Received: from [128.32.130.5] by SAIL.STANFORD.EDU with TCP; 25 Oct 87 09:39:29 PST Received: by cogsci.berkeley.edu (5.58/1.26) id AA20167; Sun, 25 Oct 87 09:43:08 PST Date: Sun, 25 Oct 87 09:43:08 PST From: norvig%cogsci.Berkeley.EDU@ucbvax.Berkeley.EDU (Peter Norvig) Message-Id: <8710251743.AA20167@cogsci.berkeley.edu> To: common-lisp@sail.stanford.edu Subject: extending DEFSTRUCT I agree with Touretzky's proposal, except I would add: When *PRINT-STRUCTURE* is a non-nil list: defstructs whose types are members of the list use their own print function defstructs whose types are not in the list use #S() I think the membership test should be TYPEP, and that :INCLUDEd types inherit the print function dynamically (with possibility of over-ride, of course). I personally prefer to use a macro DEFSTRUCT-PRINT-FUNCTION so that I can define the print function separately from the DEFSTRUCT itself, but I wouldn't go so far as to make that part of CL; rather, let's: define a GET-PRINT-FUNCTION function (with a SETF form) which returns the print function associated with a type.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 25 Oct 87 09:44:01 EST Received: from H.GP.CS.CMU.EDU by SAIL.STANFORD.EDU with TCP; 25 Oct 87 06:24:36 PST Date: 25 Oct 1987 08:47-EST From: Rick.Busdiecker@H.GP.CS.CMU.EDU To: Dave.Touretzky@C.CS.CMU.EDU Cc: common-lisp@SAIL.STANFORD.EDU Subject: extending DEFSTRUCT Reply-To: Rick.Busdiecker@cs.cmu.edu Message-Id: <562168063/rfb@H.GP.CS.CMU.EDU> I also support the proposed extensions to structure handling. Date: Sat 24 Oct 87 15:16:08-EDT From: Dave.Touretzky@C.CS.CMU.EDU When *PRINT-STRUCTURE* in NIL: defstructs with their own print functions will use them defstructs without their own print function will print in the #<> notation Is there really a standard for #<> notation? If so, what is it and where is it defined? If not, perhaps we should define a default #<> notation such as #. Rick  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Oct 87 23:53:22 EDT Received: from RUTGERS.EDU by SAIL.STANFORD.EDU with TCP; 24 Oct 87 20:35:59 PDT Received: by RUTGERS.EDU (5.54/1.14) with UUCP id AA16558; Sat, 24 Oct 87 23:39:14 EDT Received: from pyrnova.pyramid.COM (manpyrnova) by pyramid.UUCP (5.51/OSx4.0b-870424) id AA23234; Sat, 24 Oct 87 19:01:02 PDT Received: by pyrnova.pyramid.COM (5.52/OSx4.0b-870424) id AA27898; Sat, 24 Oct 87 19:02:43 PDT Date: 24 Oct 1987 18:57-PDT From: David Bein Subject: macrolet/flet/labels To: common-lisp@sail.stanford.edu@RUTGERS.EDU Message-Id: <562125428/bein@pyrnova> What is the current consensus about using a name within a macrolet/flet/labels construct which is a special form? I am cleaning things up this way and it occurred to me that things could go either way. I think the only really ugly one is QUOTE since most compilers seem to treat that specially in all kinds of places. Another equally nasty one would be FUNCTION. --David  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Oct 87 15:41:11 EDT Received: from C.CS.CMU.EDU by SAIL.STANFORD.EDU with TCP; 24 Oct 87 12:24:05 PDT Received: ID ; Sat 24 Oct 87 15:16:09-EDT Date: Sat 24 Oct 87 15:16:08-EDT From: Dave.Touretzky@C.CS.CMU.EDU Subject: extending DEFSTRUCT To: common-lisp@SAIL.STANFORD.EDU Message-ID: <12345095715.31.TOURETZKY@C.CS.CMU.EDU> I support the proposal of Gallagher and Corkill, with one modification: Instead of *INHIBIT-DEFSTRUCT-PRINTERS*, there should be a variable called *PRINT-STRUCTURE* that is analagous to *PRINT-ARRAY*. When *PRINT-STRUCTURE* is T: defstructs with their own print functions will use them defstructs without prnt functions will print in the #S() notation When *PRINT-STRUCTURE* in NIL: defstructs with their own print functions will use them defstructs without their own print function will print in the #<> notation When *PRINT-STRUCTURE* is :FORCE all defstructs print in #S() notation -- Dave -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 24 Oct 87 04:54:35 EDT Received: from RELAY.CS.NET by SAIL.STANFORD.EDU with TCP; 24 Oct 87 01:30:01 PDT Received: from relay2.cs.net by RELAY.CS.NET id ac18609; 24 Oct 87 2:18 EDT Received: from cs.umass.edu by RELAY.CS.NET id bf09392; 24 Oct 87 2:11 EDT Date: Fri, 23 Oct 87 12:26 EDT From: "Dan Corkill, COINS, Umass (413)545-0156" Subject: RE: Extending DEFSTRUCT To: Common-Lisp@SAIL.STANFORD.EDU X-VMS-To: IN%"Common-Lisp@SAIL.Stanford.Edu" Kevin Gallagher has twice proposed what I believe is a well-reasoned and much needed extension to defstruct-defined structures. About a year ago his first proposal received one favorable response on the list and died. His most recent reposting (in response to the recent discussion of defstruct) has received no responses. [The proposed extensions were: STRUCTURE-SLOT structure slot {a valid SETF form} [Function] STRUCTURE-SLOT-NAMES structure-type [Function] MAKE-STRUCTURE structure-type keyword-1 value-1 ... [Function] STRUCTURE-OPTION structure-type option [Function] STRUCTURE-SLOT-OPTION structure-type slot option [Function] DEFSTRUCTP symbol [Function] ] I would like to believe that the lack of responses to Kevin's extensions (or any further discussion of defstruct and structures) indicated an implicit endorsement of a useful proposal. Anyone who builds portable tools, layered systems, or extensible languages that rely on defstruct- defined structures needs these capabilities. They are relatively easy for an implementer to provide, they are impossible for a user to write in an implementation independent manner, they do not violate the storage abstraction provided by defstruct, and they elevate structures to the same level of ``official'' support for interrogatives as arrays. (I can ask for the dimensions of an array but not the slot-names of a structure?) I heartily endorse his proposal. In fact, I would add two more EXTENSIONS that I have found frustratingly absent from the CL specifications. --------------------------------------------------------------------------- Add'l extension 1: There is no way in the type system to detect if an object is a structure whose structure name has been added to the CL data-type system (i.e., defined with no :TYPE option). The following would provide this ability: STRUCTUREP object [Function] Returns true if object is a structure whose structure name has been added to the CL data-type system; nil otherwise. --------------------------------------------------------------------------- Add'l extension 2: I often use defstruct print functions to print structures in a palatable format for human eyes. I also want them printed using the normal #S() notation when writing them to a database file. The following is a tempting way of writing such print functions: (defun EMPLOYEE-DEFSTRUCT-PRINTER (employee stream print-depth) (declare (ignore print-depth)) (cond ;; Less-than-pretty printing requested :: ((and (not *print-pretty*) *print-escape*) (prin1 employee)) ;; Pretty printing requested :: (t (format stream "{Employee: ~A}" (employee-name employee))))) Of course, this will NOT work because there is no way of disabling the employee print function during the printing performed by prin1. Instead, I am forced to duplicate the printing of the default #S() format myself. (I might be tempted to write a generic print-structure-in-default-format function, but of course I would need the extensions proposed by Gallagher to do that!) So instead of prin1, I must write: (format stream "#S(EMPLOYEE :SOCIAL-SECURITY-NUMBER ~S ~ :NAME ~S :HOURLY-RATE ~S ...)" (employee-social-security-number employee) (employee-name employee) (employee-hourly-rate employee) ...)) Explicitly naming each slot in the structure (and remembering to change the printer if a slot is added or deleted from the defstruct definition). Ugh!! The abstraction provided by defstruct has been lost (as well as whatever efficient default printing of structures has been provided by the implementers). A simple parameter *INHIBIT-DEFSTRUCT-PRINTERS* to control whether or not printing uses or ignores the defstruct print function would save the day! Voila: (defun EMPLOYEE-DEFSTRUCT-PRINTER (employee stream print-depth) (declare (ignore print-depth)) (cond ;; Less-than-pretty printing requested :: ((and (not *print-pretty*) *print-escape*) (let ((*inhibit-defstruct-printers* t)) (prin1 stream employee))) ;; Pretty printing requested :: (t (format stream "{Employee: ~A}" (employee-name employee))))) --------------------------------------------------------------------------- Structures have become such an important component of CL. It's unfortunate that the lack of a few simple extensions seriously hamper using them. -- Dan Corkill cork@cs.umass.edu  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 19 Oct 87 14:13:39 EDT Received: from THINK.COM by SAIL.STANFORD.EDU with TCP; 19 Oct 87 10:51:29 PDT Return-Path: Received: from kali.think.com by Think.COM; Mon, 19 Oct 87 13:51:21 EDT Received: by kali.think.com; Mon, 19 Oct 87 13:51:37 EDT Date: Mon, 19 Oct 87 13:51:37 EDT From: gls@Think.COM Message-Id: <8710191751.AA27708@kali.think.com> To: common-lisp@sail.stanford.edu Subject: [boyer@rascal.ics.utexas.edu: CLTL] We can all feel good about a comment like this: Date: Mon, 12 Oct 87 09:06:54 CDT From: boyer@rascal.ics.utexas.edu (Bob Boyer) I want to express to you my great gratitude for your having put together CLTL. J Moore and I have recently finished converting our theorem-prover from a Franz/Zetalisp/Maclisp/PSL version to Common Lisp. The converted code now runs with absolutely no operating system or dialect dependencies under Symbolics Common Lisp, Kyoto Common Lisp, and Lucid Common Lisp. And I half suspect that it might still run on those systems a decade from now. How wonderful to be relieved of the dread that every few months a new "release" of whatever Lisp I was using would break my code! The only incompatibility between the three Lisps we encountered was about the meanings of the "put in seven extremely random user interface commands", which we just decided to avoid completely. This last paragraph seemed quite timely, apropos of the current discussion about REQUIRE. --Guy  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 19 Oct 87 12:13:02 EDT Received: from SPICE.CS.CMU.EDU by SAIL.STANFORD.EDU with TCP; 19 Oct 87 08:46:37 PDT Date: 19 Oct 1987 11:32-EDT From: Steve.Handerson@SPICE.CS.CMU.EDU To: common-lisp@sail.stanford.edu Subject: Compiler-let Message-Id: <561655978/skh@SPICE.CS.CMU.EDU> I apologize if this has been brought up and settled previously. Compiler-let limits its usefulness by stating only that it special-binds during evaluation. Where lazy macroexpansion is used in the evaluator, there's a clear and useless difference between compile-time and runtime behavior; the bindings aren't there any more. Instead, CL should loudly proclaim that whatever compiler-let binds will be special-bound for all macroexpansions occuring within. Only evaluators not based on compilation need be changed, and I think it's worth the effort (especially if the evaluators in question aren't too hairy). It would be nice if existing implementations were updated in this matter, but I guess everyone has to agree first. -- Steve  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 16 Oct 87 16:32:52 EDT Received: from SCRC-YUKON.ARPA by SAIL.STANFORD.EDU with TCP; 16 Oct 87 13:11:21 PDT Received: from SWAN.SCRC.Symbolics.COM by YUKON.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 277966; Fri 16-Oct-87 16:11:56 EDT Date: Fri, 16 Oct 87 16:12 EDT From: David C. Plummer Subject: Re: with-open-stream and with-open-file To: Pavel.pa@Xerox.COM, common-lisp@sail.stanford.edu In-Reply-To: <871016-105629-3613@Xerox> Message-ID: <19871016201200.1.DCP@SWAN.SCRC.Symbolics.COM> Date: Fri, 16 Oct 87 10:56:21 PDT From: Pavel.pa@Xerox.COM [deleted] Surely I'm misunderstanding you. Why use the above form instead of simply `constructor'? In my example, there is no reason... It must be that you mean to do more stuff before the prog1, perhaps to "set up" the stream and/or some other structures concerned with it. ... and indeed this is what I typically use it for. I checked a few of my cases, and what is >really< going on, for me, is in the internals of constructing a stream and is something like (defun open (pathname &rest open-options) (with-open-stream (stream (construct-file-stream)) ...process-options... (shiftf stream nil))) The idea would be to have the implicit unwind-protect around those set-up forms and then be able to leave the unwind-protect with the stream still open. Have I properly understood your intent? Yes. If so, then I must say that I would find the form you describe far less clear than the equivalent explicit unwind-protect. In general, I dislike forms that pass information to invisible parts by the setting of a lexical variable. The information path is just too hidden. That's a good point which I'll have to think about. Five minutes' reflection, clearly not enough, says: - with-open-thing neatly packages the unwind-protect and the abort cleanup. - with-open-thing requires the programmer to remember only one form: the with-open-thing form. This observation is quite weak; convention would dictate that there would be a corresponding open-thing form (e.g., with-open-serial-stream/open-serial-stream). It might be, however, that the with-open-thing is an external symbol and open-thing is internal. The first observation will probably cause me to continue my current practices, though at a higher level of awareness. Whatever consensus we come to, the language should be clarified and faulty implementations corrected so that the goal of writing portable programs isn't diminished.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 16 Oct 87 14:46:38 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 16 Oct 87 10:58:54 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 16 OCT 87 10:56:29 PDT Date: Fri, 16 Oct 87 10:56:21 PDT From: Pavel.pa@Xerox.COM Subject: Re: with-open-stream and with-open-file In-reply-to: <871016113352.2.DCP@KOYAANISQATSI.S4CC.Symbolics.COM> To: common-lisp@sail.stanford.edu Message-ID: <871016-105629-3613@Xerox> Date: Fri, 16 Oct 87 11:33 EDT From: David C. Plummer CLtL says that the stream (file) scoped by with-open-stream (with-open-file) is closed when the form is exited, independent of exit-reason. I would like people to consider the following allowance: that if the stream variable is NIL during the close operation, then the stream (file) is not closed. Thus (with-open-stream (stream constructor) (prog1 stream (setq stream nil))) would evaluate to an open stream. [More language supporting the above as an idiom.] Surely I'm misunderstanding you. Why use the above form instead of simply `constructor'? It must be that you mean to do more stuff before the prog1, perhaps to "set up" the stream and/or some other structures concerned with it. The idea would be to have the implicit unwind-protect around those set-up forms and then be able to leave the unwind-protect with the stream still open. Have I properly understood your intent? If so, then I must say that I would find the form you describe far less clear than the equivalent explicit unwind-protect. In general, I dislike forms that pass information to invisible parts by the setting of a lexical variable. The information path is just too hidden. Pavel  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 16 Oct 87 14:20:18 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 16 Oct 87 10:58:54 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 16 OCT 87 10:56:29 PDT Date: Fri, 16 Oct 87 10:56:21 PDT From: Pavel.pa@Xerox.COM Subject: Re: with-open-stream and with-open-file In-reply-to: <871016113352.2.DCP@KOYAANISQATSI.S4CC.Symbolics.COM> To: common-lisp@sail.stanford.edu Message-ID: <871016-105629-3613@Xerox> Date: Fri, 16 Oct 87 11:33 EDT From: David C. Plummer CLtL says that the stream (file) scoped by with-open-stream (with-open-file) is closed when the form is exited, independent of exit-reason. I would like people to consider the following allowance: that if the stream variable is NIL during the close operation, then the stream (file) is not closed. Thus (with-open-stream (stream constructor) (prog1 stream (setq stream nil))) would evaluate to an open stream. [More language supporting the above as an idiom.] Surely I'm misunderstanding you. Why use the above form instead of simply `constructor'? It must be that you mean to do more stuff before the prog1, perhaps to "set up" the stream and/or some other structures concerned with it. The idea would be to have the implicit unwind-protect around those set-up forms and then be able to leave the unwind-protect with the stream still open. Have I properly understood your intent? If so, then I must say that I would find the form you describe far less clear than the equivalent explicit unwind-protect. In general, I dislike forms that pass information to invisible parts by the setting of a lexical variable. The information path is just too hidden. Pavel  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 16 Oct 87 11:59:11 EDT Received: from [128.81.51.3] by SAIL.STANFORD.EDU with TCP; 16 Oct 87 08:32:13 PDT Received: from KOYAANISQATSI.S4CC.Symbolics.COM by DIAMOND.S4CC.Symbolics.COM via CHAOS with CHAOS-MAIL id 133767; Fri 16-Oct-87 11:32:33 EDT Date: Fri, 16 Oct 87 11:33 EDT From: David C. Plummer Subject: with-open-stream and with-open-file To: common-lisp@sail.stanford.edu Message-ID: <871016113352.2.DCP@KOYAANISQATSI.S4CC.Symbolics.COM> CLtL says that the stream (file) scoped by with-open-stream (with-open-file) is closed when the form is exited, independent of exit-reason. I would like people to consider the following allowance: that if the stream variable is NIL during the close operation, then the stream (file) is not closed. Thus (with-open-stream (stream constructor) (prog1 stream (setq stream nil))) would evaluate to an open stream. The strict reading of CLtL says that the stream should be closed and the stream, not the variable, should be considered to have dynamic extent. (I'd quote, except my book is packed.) I don't like the word "considered" as it could be interpreted to legitimize not closing the stream. Personally, I have found the above technique (setting the stream variable to nil and returning the stream) as quite useful; the Symbolics implementation already implementing the relaxation. I ask that the language be clarified. Also, the (prog1 stream (setq stream nil)) is a cliche which can also be written as (shiftf stream nil). For many months I have not liked either of those forms; the way they look, not what they do. Unfortunately, the best form I've been able to think of is (grab-and-clear stream) and I don't like that very much either.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 16 Oct 87 11:52:58 EDT Received: from [128.81.51.3] by SAIL.STANFORD.EDU with TCP; 16 Oct 87 07:38:26 PDT Received: from KOYAANISQATSI.S4CC.Symbolics.COM by DIAMOND.S4CC.Symbolics.COM via CHAOS with CHAOS-MAIL id 133712; Fri 16-Oct-87 09:50:40 EDT Date: Fri, 16 Oct 87 09:51 EDT From: David C. Plummer Subject: The IDENTITY function and multiple args To: peck@Sun.COM, common-lisp@sail.stanford.edu In-Reply-To: <8710160417.AA04480@denali.sun.com> Message-ID: <871016095157.3.DCP@KOYAANISQATSI.S4CC.Symbolics.COM> Date: Thu, 15 Oct 87 21:17:31 -0700 From: peck@Sun.COM Is there a fundamental reason why #'IDENTITY and #'VALUES should be different? VALUES seems like a much safer function to use for a "default" function, since it will nicely consume any number of args and return them, which is the same behavior that the improverished IDENTITY does for a single arg. Why encourage programmers to make fragile programs by documenting "IDENTITY"? Two reasons I see: 1, Intent: If the intent is to return one value based on one argument, then IDENTITY is the correct function to use. It "is an error" to pass it more or less than one argument, and some implementations "signal an error." If the intent is to accept multiple values and pass them through, then VALUES is the correct function to use. I don't consider VALUES and "safer" or IDENTITY introducing "fragility". On the contrary, I would claim that failure to program the intent will make the program less safe and more fragile. 2, Efficiency (linguistically, this is a weak argument): some (many?) implementations optimize the one return-value case. This makes multiple values less efficient.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 16 Oct 87 11:09:10 EDT Received: from [128.81.51.3] by SAIL.STANFORD.EDU with TCP; 16 Oct 87 07:38:26 PDT Received: from KOYAANISQATSI.S4CC.Symbolics.COM by DIAMOND.S4CC.Symbolics.COM via CHAOS with CHAOS-MAIL id 133712; Fri 16-Oct-87 09:50:40 EDT Date: Fri, 16 Oct 87 09:51 EDT From: David C. Plummer Subject: The IDENTITY function and multiple args To: peck@Sun.COM, common-lisp@sail.stanford.edu In-Reply-To: <8710160417.AA04480@denali.sun.com> Message-ID: <871016095157.3.DCP@KOYAANISQATSI.S4CC.Symbolics.COM> Date: Thu, 15 Oct 87 21:17:31 -0700 From: peck@Sun.COM Is there a fundamental reason why #'IDENTITY and #'VALUES should be different? VALUES seems like a much safer function to use for a "default" function, since it will nicely consume any number of args and return them, which is the same behavior that the improverished IDENTITY does for a single arg. Why encourage programmers to make fragile programs by documenting "IDENTITY"? Two reasons I see: 1, Intent: If the intent is to return one value based on one argument, then IDENTITY is the correct function to use. It "is an error" to pass it more or less than one argument, and some implementations "signal an error." If the intent is to accept multiple values and pass them through, then VALUES is the correct function to use. I don't consider VALUES and "safer" or IDENTITY introducing "fragility". On the contrary, I would claim that failure to program the intent will make the program less safe and more fragile. 2, Efficiency (linguistically, this is a weak argument): some (many?) implementations optimize the one return-value case. This makes multiple values less efficient.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 16 Oct 87 00:45:57 EDT Received: from SUN.COM by SAIL.STANFORD.EDU with TCP; 15 Oct 87 21:17:38 PDT Received: from snail.sun.com by Sun.COM (4.0/SMI-3.2) id AA27648; Thu, 15 Oct 87 21:13:14 PDT Received: from denali.sun.com by snail.sun.com (4.0/SMI-3.2) id AA20740; Thu, 15 Oct 87 21:17:16 PDT Received: from localhost by denali.sun.com (3.2/SMI-3.2) id AA04480; Thu, 15 Oct 87 21:17:33 PDT Message-Id: <8710160417.AA04480@denali.sun.com> To: common-lisp@sail.stanford.edu Subject: The IDENTITY function and multiple args Date: Thu, 15 Oct 87 21:17:31 -0700 From: peck@Sun.COM Is there a fundamental reason why #'IDENTITY and #'VALUES should be different? VALUES seems like a much safer function to use for a "default" function, since it will nicely consume any number of args and return them, which is the same behavior that the improverished IDENTITY does for a single arg. Why encourage programmers to make fragile programs by documenting "IDENTITY"?  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Oct 87 15:18:13 EDT Received: from NGP.UTEXAS.EDU by SAIL.STANFORD.EDU with TCP; 13 Oct 87 11:48:59 PDT Posted-Date: Tue, 13 Oct 87 12:15:32 CDT Received: by ngp.utexas.edu (5.51/5.51) id AA04440; Tue, 13 Oct 87 12:15:47 CDT Date: Tue, 13 Oct 87 12:15:32 CDT From: kclmail@rascal.ics.utexas.edu (Bob Boyer) Message-Id: <8710131715.AA24859@rascal.ics.utexas.edu> Received: by rascal.ics.utexas.edu (3.2/4.22) id AA24859; Tue, 13 Oct 87 12:15:32 CDT To: common-lisp@sail.stanford.edu Subject: KCL Mailing List An electronic mailing list for news about Kyoto Common Lisp has been established. To have your name placed on this list, send a message to the Arpanet/Internet address: kcl-request@rascal.ics.utexas.edu To post an item to those on the list, send a note to Arpanet/Internet address: kcl@rascal.ics.utexas.edu The authors of KCL, Yuasa and Hagiya, are on the list. A discouragingly high percentage of those in electronically remote corners of the U.S.A. or in foreign countries who receive this message and who send a message to kcl-request asking to join the list will be inaccessible from rascal.ics.utexas.edu because of a variety of network problems. If you do not regularly send mail to and receive mail from several Arpanet sites, please include in any request to kcl-request a paper mail address to which I can mail my regrets over your apparent inaccessibility if necessary. Messages to kcl@rascal.ics.utexas.edu will be archived in the file /pub/kcl-mail-archive, accessible by ftping into rascal.ics.utexas.edu as user ftp, any password. In the same place is the file kcl.broadcast, which contains information about obtaining without fee the Kyoto Common Lisp system, including sources, after the appropriate license procedures have been completed.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 13 Oct 87 00:48:29 EDT Received: from SCORE.STANFORD.EDU by SAIL.STANFORD.EDU with TCP; 12 Oct 87 21:21:45 PDT Received: from hplabs.HP.COM (hplabs.hpl.hp.com.#Internet) by SCORE.STANFORD.EDU with TCP; Mon 12 Oct 87 21:17:28-PDT Received: from hpfcla.HP.COM (hpfcla) by hplabs.HP.COM with SMTP ; Mon, 12 Oct 87 17:57:45 PDT Received: from hpfclp.HP.COM by hpfcla.HP.COM; Mon, 12 Oct 87 18:50:03 mdt Received: from hpfcjrd.HP.COM by hpfclp.HP.COM; Mon, 12 Oct 87 18:49:44 mdt Received: from hpfcjrd by hpfcjrd.HP.COM; Mon, 12 Oct 87 18:49:52 mdt Return-Path: To: common-lisp@sail.stanford.edu Subject: Re: REQUIRE X-Answer: 42 X-Mailer: mh6.5 + ivomh Date: Mon, 12 Oct 87 18:49:50 MDT Message-Id: <29520.561084590@hpfcjrd> From: John Diamant I have strong beliefs about what PROVIDE/REQUIRE should do (at least what their purpose is in the language). They are a necessary mechanism for loading needed modules exactly once. LOAD is inadequate for loading complete subsystems as it becomes very difficult to make sure you only load something once. I do believe it should occur at compile-time since many dependencies are at compile-time, not just during execution. But even if this only covered execution-time dependencies, the purpose for REQUIRE would be clear. If I access functions in a module written by someone else, then I need to bring that module into the system. If I have several optional parts of my system, then each of my parts may need to make sure that the module is loaded. If they all used LOAD, multiple copies would be loaded, thus wasting space (at least in many implementations it would). With REQUIRE, I avoid that, and also have a way of registering a module for public consumption. John Diamant Fort Collins, CO UUCP: {hplabs,hpfcla}!hpfclp!diamant Hewlett Packard Co. ARPA Internet: diamant%hpfclp@hplabs.HP.COM  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 12 Oct 87 23:14:57 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 12 Oct 87 12:44:16 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 12 OCT 87 11:57:17 PDT Date: Mon, 12 Oct 87 11:57:06 PDT From: Pavel.pa@Xerox.COM Subject: Re: the lexical environment for DEFTYPE, DEFINE-SETF-METHOD and In-reply-to: To: common-lisp@SAIL.STANFORD.EDU Message-ID: <871012-115717-3651@Xerox> Date: Mon, 12 Oct 87 11:56 EDT From: Ram@C.CS.CMU.EDU If I believed in your proposed semantics for DEFMACRO, then I would buy this argument, but I don't. It seems to me to be a bizzarre suggestion that the semantics of an operation should depend on whether the environment is null or not. I think that the only reason that anyone buys this at all is that Lisp compilers have traditionally magically special-cased forms that "appear at top-level", whatever that means. I think that there is a pretty convincing argument that the whole concept of a "top-level form" is inappropriate in a lexically scoped Lisp. In my proposal for Common Lisp compilation (really evaluation) semantics, I define things in a way that is consistent with general usage, but makes no use of the concept "top level". If I remember your proposal correctly (it's been a while since I read it), you insist that the compiler ALWAYS be able to evaluate the body of a DEFMACRO. I claim that this is overly restrictive. I can well imagine wanting to use a lexical variable as an "own" variable for maintaining state across expansions of a particular macro. Such variables might be used for allowing functionality like the :include feature of DEFSTRUCT, for keeping statistics, etc. Your semantics would not allow this. I have no trouble with requiring the compiler to notice macro definitions and to make use of them when it can. I also have no trouble with there being a class of such definitions that cannot be made use of at compilation time. Pavel  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 12 Oct 87 18:23:52 EDT Received: from C.CS.CMU.EDU by SAIL.STANFORD.EDU with TCP; 12 Oct 87 09:58:10 PDT Received: ID ; Mon 12 Oct 87 12:58:23-EDT Date: Mon, 12 Oct 1987 12:58 EDT Message-ID: Sender: RAM@ From: Ram@C.CS.CMU.EDU To: sandra%orion@cs.utah.edu (Sandra J Loosemore) Cc: common-lisp@SAIL.STANFORD.EDU, "Robert W. Kerns" Subject: REQUIRE In-reply-to: Msg of 9 Oct 1987 12:50-EDT from sandra%orion at cs.utah.edu (Sandra J Loosemore) Date: Friday, 9 October 1987 12:50-EDT From: sandra%orion at cs.utah.edu (Sandra J Loosemore) To: Ram at c.cs.cmu.edu Re: REQUIRE From: Ram@C.CS.CMU.EDU This means that doing a LOAD may not make definitions available to a following COMPILE-FILE. This is what REQUIRE is for. Well, maybe that's what REQUIRE was intended to be used for, but I'm afraid it hasn't turned out that way in practice. Portability problems with PROVIDE and REQUIRE are currently #2 on my list, after problems with top-level forms. In fact, it appears that many (most?) CL implementations insist on treating PROVIDE and REQUIRE specially when they appear as top-level forms. This may be just a mental block on my part, but I always used to wonder why anyone would use PROVIDE/REQUIRE at all. More recently I came to the conclusion that their reason for existence was to state compile-time dependencies, i.e. loading macro packages at compile time. If you believe this, then it is obvious that the compiler must evaluate REQUIRE at compile time. But on reading the manual just now, I don't see any support for this theory that REQUIRE is a mechanism for dealing with compile-time dependencies. Probably anyone who either: a] Has strong beliefs about what PROVIDE/REQUIRE should do, or b] has a good solution to the compile-time dependency problem should speak up. It does seem to be useful to have some syntax attached to the code file that the compiler can recognize as an explicit manipulation of its environment. The other problem is that implementation-specific way that REQUIRE looks for the files to load if you don't provide a specific pathname. [...] If it were up to me, I'd like to see a variable named something like *REQUIRE-PATHNAME-DEFAULTS*, which specifies where REQUIRE should look for modules if you don't give an explicit pathname. Having some standard mechanism for specifying a library search-list seems reasonable. We have this capability, but implement it using our "logical device" mechanism. Note that having simple default interpretation for REQUIRE without a pathname doesn't prevent implementations from providing alternate interpretations as long as the simple version still works. Rob  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 12 Oct 87 14:54:25 EDT Received: from RUTGERS.EDU by SAIL.STANFORD.EDU with TCP; 12 Oct 87 10:18:50 PDT Received: by RUTGERS.EDU (5.54/1.14) with UUCP id AA22162; Mon, 12 Oct 87 13:21:57 EDT Received: from pyrnova.pyramid.COM (manpyrnova) by pyramid.UUCP (5.51/OSx4.0b-870424) id AA07026; Mon, 12 Oct 87 10:17:55 PDT Received: by pyrnova.pyramid.COM (5.52/OSx4.0b-870424) id AA17592; Mon, 12 Oct 87 10:20:15 PDT Date: 12 Oct 1987 10:01-PDT From: David Bein Subject: defmacro environment again.. To: ram@c.cs.cmu.edu, pavel.pa@xerox.com Cc: common-lisp@sail.stanford.edu@RUTGERS.EDU Message-Id: <561056467/bein@pyrnova> I'll rephrase the question. Suppose you have the following in some file: (let ((a )) (defun a-getter () a) (defun a-setter (value) (setq a value))) It is fairly clear what the compiler should do with this, namely build a lexical environment when the file is loaded and create two compiled closures using that environment which define a-getter and a-setter. Now suppose we have the following: (let ((a )) (defmacro hack () `(list 1 2 3 ',a)) (defun a-setter (value) (setq a value))) Is the macro HACK allowed to refer to the lexical value of A which was apparent when the macro function for HACK was created (loaded)? (I know this is difficult if the macro is used in the compiler's environment since the compiler does not have the lexical environment around yet..) ... If I read the manual correctly, it is saying that HACK may not refer to the lexical environment it was defined in. So my question is, should DEFTYPE,DEFINE-SETF-METHOD and DEFSETF (complicated version) be the same way? This is really separate from the &environment arg which a macro function could use in the runtime environment to call macroexpand with. --David  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 12 Oct 87 14:34:02 EDT Received: from C.CS.CMU.EDU by SAIL.STANFORD.EDU with TCP; 12 Oct 87 09:58:10 PDT Received: ID ; Mon 12 Oct 87 12:58:23-EDT Date: Mon, 12 Oct 1987 12:58 EDT Message-ID: Sender: RAM@ From: Ram@C.CS.CMU.EDU To: sandra%orion@cs.utah.edu (Sandra J Loosemore) Cc: common-lisp@SAIL.STANFORD.EDU, "Robert W. Kerns" Subject: REQUIRE In-reply-to: Msg of 9 Oct 1987 12:50-EDT from sandra%orion at cs.utah.edu (Sandra J Loosemore) Date: Friday, 9 October 1987 12:50-EDT From: sandra%orion at cs.utah.edu (Sandra J Loosemore) To: Ram at c.cs.cmu.edu Re: REQUIRE From: Ram@C.CS.CMU.EDU This means that doing a LOAD may not make definitions available to a following COMPILE-FILE. This is what REQUIRE is for. Well, maybe that's what REQUIRE was intended to be used for, but I'm afraid it hasn't turned out that way in practice. Portability problems with PROVIDE and REQUIRE are currently #2 on my list, after problems with top-level forms. In fact, it appears that many (most?) CL implementations insist on treating PROVIDE and REQUIRE specially when they appear as top-level forms. This may be just a mental block on my part, but I always used to wonder why anyone would use PROVIDE/REQUIRE at all. More recently I came to the conclusion that their reason for existence was to state compile-time dependencies, i.e. loading macro packages at compile time. If you believe this, then it is obvious that the compiler must evaluate REQUIRE at compile time. But on reading the manual just now, I don't see any support for this theory that REQUIRE is a mechanism for dealing with compile-time dependencies. Probably anyone who either: a] Has strong beliefs about what PROVIDE/REQUIRE should do, or b] has a good solution to the compile-time dependency problem should speak up. It does seem to be useful to have some syntax attached to the code file that the compiler can recognize as an explicit manipulation of its environment. The other problem is that implementation-specific way that REQUIRE looks for the files to load if you don't provide a specific pathname. [...] If it were up to me, I'd like to see a variable named something like *REQUIRE-PATHNAME-DEFAULTS*, which specifies where REQUIRE should look for modules if you don't give an explicit pathname. Having some standard mechanism for specifying a library search-list seems reasonable. We have this capability, but implement it using our "logical device" mechanism. Note that having simple default interpretation for REQUIRE without a pathname doesn't prevent implementations from providing alternate interpretations as long as the simple version still works. Rob  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 12 Oct 87 14:33:45 EDT Received: from RUTGERS.EDU by SAIL.STANFORD.EDU with TCP; 12 Oct 87 10:56:54 PDT Received: by RUTGERS.EDU (5.54/1.14) id AA23288; Mon, 12 Oct 87 14:00:07 EDT Received: ID ; Mon 12 Oct 87 13:56:05-EDT Date: Mon, 12 Oct 1987 13:55 EDT Message-Id: Sender: RAM@ From: Ram@c.cs.cmu.edu To: David Bein Cc: common-lisp%sail.stanford.edu@RUTGERS.EDU, pavel.pa@xerox.com Subject: defmacro environment again.. In-Reply-To: Msg of 12 Oct 1987 13:01-EDT from David Bein Everyone seems to agree that it would be most consistent with the rest of Common Lisp for the bodies of DEFTYPE, DEFINE-SETF-METHOD, ... to be evaluated in the null environment. There was only disagreement over whether these forms would do something else in the best of all possible Lisp dialects. Rob  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 12 Oct 87 12:38:06 EDT Received: from C.CS.CMU.EDU by SAIL.STANFORD.EDU with TCP; 12 Oct 87 09:08:38 PDT Received: ID ; Mon 12 Oct 87 11:56:47-EDT Date: Mon, 12 Oct 1987 11:56 EDT Message-ID: Sender: RAM@ From: Ram@C.CS.CMU.EDU To: Pavel.pa@XEROX.COM Cc: common-lisp@SAIL.STANFORD.EDU, David Bein Subject: the lexical environment for DEFTYPE, DEFINE-SETF-METHOD and In-reply-to: Msg of 11 Oct 1987 23:49-EDT from Pavel.pa at Xerox.COM Date: Sunday, 11 October 1987 23:49-EDT From: Pavel.pa at Xerox.COM To: David Bein cc: common-lisp at sail.stanford.edu Re: the lexical environment for DEFTYPE, DEFINE-SETF-METHOD and DEFSETF [...] the description of DEFMACRO that states that the body of a DEFMACRO is evaluated in the null lexical environment. This restriction was put in with the thought that it was necessary in order for the compiler to be able to macroexpand forms without evaluating the surrounding code to create a lexical environment. This argument, however, is bogus, since it is the lexical environment of the DEFMACRO, not that of the macro-call, that is important. If a DEFMACRO appears in a non-null lexical environment, the compiler is not obliged to notice it at all (aside from compiling it correctly). That is, later forms in the same file may not depend upon that macro having been installed. If I believed in your proposed semantics for DEFMACRO, then I would buy this argument, but I don't. It seems to me to be a bizzarre suggestion that the semantics of an operation should depend on whether the environment is null or not. I think that the only reason that anyone buys this at all is that Lisp compilers have traditionally magically special-cased forms that "appear at top-level", whatever that means. I think that there is a pretty convincing argument that the whole concept of a "top-level form" is inappropriate in a lexically scoped Lisp. In my proposal for Common Lisp compilation (really evaluation) semantics, I define things in a way that is consistent with general usage, but makes no use of the concept "top level". Rob  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 12 Oct 87 00:20:16 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 11 Oct 87 20:50:54 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 11 OCT 87 20:50:06 PDT Date: Sun, 11 Oct 87 20:49:48 PDT From: Pavel.pa@Xerox.COM Subject: Re: the lexical environment for DEFTYPE, DEFINE-SETF-METHOD and DEFSETF In-reply-to: <560990513/bein@pyrnova> To: David Bein Cc: common-lisp@sail.stanford.edu Message-ID: <871011-205006-2922@Xerox> Date: 11 Oct 87 15:41 PDT From: David Bein Do functions created by DEFTYPE, DEFINE-SETF-METHOD and DEFSETF have the same restriction as DEFMACRO (page 145 CLtL) does about where the function body is effectively defined, i.e. would it be legal to take DEFTYPE, DEFINE-SETF-METHOD and DEFSETF forms and evaluate them as if
(wherever it appears) is (EVAL ') ... If I understand your question correctly, you are referring to the sentence in the description of DEFMACRO that states that the body of a DEFMACRO is evaluated in the null lexical environment. This restriction was put in with the thought that it was necessary in order for the compiler to be able to macroexpand forms without evaluating the surrounding code to create a lexical environment. This argument, however, is bogus, since it is the lexical environment of the DEFMACRO, not that of the macro-call, that is important. If a DEFMACRO appears in a non-null lexical environment, the compiler is not obliged to notice it at all (aside from compiling it correctly). That is, later forms in the same file may not depend upon that macro having been installed. (On the other hand, if you then load that file, the compilation of later files \may/ count on the macro being present.) Regardless of all this, the restriction is still a part of the language and so, for consistency's sake, given the understanding everyone has about the correctness of Sandra's top-level form proposal, the same restriction should indeed apply to the three kinds of forms you mentioned: DEFTYPE, DEFINE-SETF-METHOD and DEFSETF. More succinctly, the answer to your question is yes. On the other hand, the language would probably be better served by removing the restriction on DEFMACRO instead. Perhaps someday I'll get around to proposing this to the cleanup committee... Pavel  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Oct 87 22:47:44 EDT Received: from RUTGERS.EDU by SAIL.STANFORD.EDU with TCP; 11 Oct 87 19:21:03 PDT Received: by RUTGERS.EDU (5.54/1.14) id AA23606; Sun, 11 Oct 87 22:21:05 EDT Received: ID ; Sun 11 Oct 87 22:17:21-EDT Date: Sun, 11 Oct 1987 22:17 EDT Message-Id: Sender: RAM@ From: Ram@c.cs.cmu.edu To: David Bein Cc: common-lisp%sail.stanford.edu@RUTGERS.EDU Subject: ... [compile-time lexical environment] In-Reply-To: Msg of 11 Oct 1987 18:41-EDT from David Bein If a form is implcitly evaluated at compile time, then it cannot access the lexical environment, since the environment doesn't exist until run-time. Given this, the only alternative to requiring that the null environment be used is stating that the environment is undefined. I see no advantage in the latter, and no reason to resolve the problem in a different way than DEFMACRO currently does. Rob  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Oct 87 22:25:18 EDT Received: from RUTGERS.EDU by SAIL.STANFORD.EDU with TCP; 11 Oct 87 18:58:00 PDT Received: by RUTGERS.EDU (5.54/1.14) with UUCP id AA19722; Sun, 11 Oct 87 20:47:19 EDT Received: from pyrnova.pyramid.COM (manpyrnova) by pyramid.UUCP (5.51/OSx4.0b-870424) id AA21802; Sun, 11 Oct 87 15:44:26 PDT Received: by pyrnova.pyramid.COM (5.52/OSx4.0b-870424) id AA11888; Sun, 11 Oct 87 15:46:49 PDT Date: 11 Oct 1987 15:41-PDT From: David Bein Subject: ... To: common-lisp@sail.stanford.edu@RUTGERS.EDU Message-Id: <560990513/bein@pyrnova> Do functions created by DEFTYPE, DEFINE-SETF-METHOD and DEFSETF have the same restriction as DEFMACRO (page 145 CLtL) does about where the function body is effectively defined, i.e. would it be legal to take DEFTYPE, DEFINE-SETF-METHOD and DEFSETF forms and evaluate them as if (wherever it appears) is (EVAL ') ... --David  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 11 Oct 87 21:28:20 EDT Received: from MIT-MULTICS.ARPA by SAIL.STANFORD.EDU with TCP; 11 Oct 87 18:02:10 PDT Delivery-Date: 11 Oct 87 20:42 EDT Delivery-By: Network_Server.Daemon@MIT-Multics.ARPA Date: Sun, 11 Oct 87 20:36 EDT From: Marion@MIT-Multics.ARPA Subject: Mailing List Message-ID: <871012003626.851916@MIT-Multics.ARPA> Resent-Date: 11 Oct 87 20:58 EDT Resent-From: Marion@MIT-Multics.ARPA Resent-To: COMMON-LISP@SAIL.STANFORD.EDU Resent-Message-ID: <871012005851.152580@MIT-Multics.ARPA> Please add me to your mailing list. Thank you.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Oct 87 17:04:47 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Oct 87 12:33:14 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 09 OCT 87 12:23:28 PDT Date: 9 Oct 87 12:23 PDT From: cutting.pa@Xerox.COM Subject: Re: *REQUIRE-PATHNAME-DEFAULTS* In-reply-to: sandra%orion@cs.utah.edu's message of Fri, 9 Oct 87 10:50:32 MDT To: sandra%orion@cs.utah.edu cc: common-lisp@sail.stanford.edu Message-ID: <871009-122328-1356@Xerox> Date: Fri, 9 Oct 87 10:50:32 MDT From: sandra%orion@cs.utah.edu (Sandra J Loosemore) If it were up to me, I'd like to see a variable named something like *REQUIRE-PATHNAME-DEFAULTS*, which specifies where REQUIRE should look for modules if you don't give an explicit pathname. Yes! To flesh out the specification: *REQUIRE-PATHNAME-DEFAULTS* [Variable] A pathname or list of pathnames searched in order by REQUIRE when no pathname is explicitly specified. By allowing lists of pathnames we allow multiple "library" directories as well as multiple file types. For example, a user could push his own directory on to the standard path as follows: (setq *require-pathname-defaults* (list* (make-pathname :directory "~/lisp" :type "lisp") (make-pathname :directory "~/lisp" :type "fasl") *require-pathname-defaults*))  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Oct 87 16:01:42 EDT Received: from XEROX.COM by SAIL.STANFORD.EDU with TCP; 9 Oct 87 12:33:14 PDT Received: from Cabernet.ms by ArpaGateway.ms ; 09 OCT 87 12:23:28 PDT Date: 9 Oct 87 12:23 PDT From: cutting.pa@Xerox.COM Subject: Re: *REQUIRE-PATHNAME-DEFAULTS* In-reply-to: sandra%orion@cs.utah.edu's message of Fri, 9 Oct 87 10:50:32 MDT To: sandra%orion@cs.utah.edu cc: common-lisp@sail.stanford.edu Message-ID: <871009-122328-1356@Xerox> Date: Fri, 9 Oct 87 10:50:32 MDT From: sandra%orion@cs.utah.edu (Sandra J Loosemore) If it were up to me, I'd like to see a variable named something like *REQUIRE-PATHNAME-DEFAULTS*, which specifies where REQUIRE should look for modules if you don't give an explicit pathname. Yes! To flesh out the specification: *REQUIRE-PATHNAME-DEFAULTS* [Variable] A pathname or list of pathnames searched in order by REQUIRE when no pathname is explicitly specified. By allowing lists of pathnames we allow multiple "library" directories as well as multiple file types. For example, a user could push his own directory on to the standard path as follows: (setq *require-pathname-defaults* (list* (make-pathname :directory "~/lisp" :type "lisp") (make-pathname :directory "~/lisp" :type "fasl") *require-pathname-defaults*))  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Oct 87 13:18:57 EDT Received: from CS.UTAH.EDU by SAIL.STANFORD.EDU with TCP; 9 Oct 87 09:51:01 PDT Received: by cs.utah.edu (5.54/utah-2.0-cs) id AA01872; Fri, 9 Oct 87 10:50:37 MDT Received: by orion.utah.edu (5.54/utah-1.0-slave) id AA16553; Fri, 9 Oct 87 10:50:32 MDT Date: Fri, 9 Oct 87 10:50:32 MDT From: sandra%orion@cs.utah.edu (Sandra J Loosemore) Message-Id: <8710091650.AA16553@orion.utah.edu> Subject: REQUIRE To: Ram@c.cs.cmu.edu Cc: "Robert W. Kerns" , common-lisp@sail.stanford.edu, Sandra J Loosemore In-Reply-To: Ram@C.CS.CMU.EDU, Fri, 9 Oct 1987 11:37 EDT From: Ram@C.CS.CMU.EDU This means that doing a LOAD may not make definitions available to a following COMPILE-FILE. This is what REQUIRE is for. Well, maybe that's what REQUIRE was intended to be used for, but I'm afraid it hasn't turned out that way in practice. Portability problems with PROVIDE and REQUIRE are currently #2 on my list, after problems with top-level forms. In fact, it appears that many (most?) CL implementations insist on treating PROVIDE and REQUIRE specially when they appear as top-level forms. The other problem is that implementation-specific way that REQUIRE looks for the files to load if you don't provide a specific pathname. I'm currently trying to get the same bits of code to run under 4 different CL implementations (and two different operating systems with incompatible filename conventions, no less) and I've got the compiled files from each implementation living in separate subdirectories.... If it were up to me, I'd like to see a variable named something like *REQUIRE-PATHNAME-DEFAULTS*, which specifies where REQUIRE should look for modules if you don't give an explicit pathname. -Sandra -------  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Oct 87 12:04:08 EDT Received: from C.CS.CMU.EDU by SAIL.STANFORD.EDU with TCP; 9 Oct 87 08:36:48 PDT Received: ID ; Fri 9 Oct 87 11:37:18-EDT Date: Fri, 9 Oct 1987 11:37 EDT Message-ID: Sender: RAM@ From: Ram@C.CS.CMU.EDU To: "Robert W. Kerns" Cc: common-lisp@SAIL.STANFORD.EDU, Sandra J Loosemore Subject: compile-time actions & top-level forms (long) In-reply-to: Msg of 9 Oct 1987 09:43-EDT from Robert W. Kerns Date: Friday, 9 October 1987 09:43-EDT From: Robert W. Kerns To: Sandra J Loosemore cc: common-lisp at sail.stanford.edu Re: compile-time actions & top-level forms (long) Date: Thu, 8 Oct 87 11:27:49 MDT From: sandra%orion@cs.utah.edu (Sandra J Loosemore) This is pretty good. I have a general comment, and a few specifics. General comment: Those forms which affect the compilation environment should not be *required* to leave that effect behind when the compilation is finished. [...] I think it is best if the compilation is not defined to affect the environment, I agree with this. [...] and you should be required to load the file before compiling the next if you want macro definitions to be visible in the next file, portably. I don't exactly agree with this. I don't think that you should assume that the COMPILE-FILE environment necessarily has anything in common with the environment seen by the user REP loop. This means that doing a LOAD may not make definitions available to a following COMPILE-FILE. This is what REQUIRE is for. [I also agree with the other remarks made by RWK...] Rob  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Oct 87 11:12:35 EDT Received: from SCRC-YUKON.ARPA by SAIL.STANFORD.EDU with TCP; 9 Oct 87 07:41:41 PDT Received: from WHITE-BIRD.SCRC.Symbolics.COM by YUKON.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 274377; Fri 9-Oct-87 09:43:11 EDT Date: Fri, 9 Oct 87 09:43 EDT From: Robert W. Kerns Subject: compile-time actions & top-level forms (long) To: Sandra J Loosemore cc: common-lisp@sail.stanford.edu In-Reply-To: <8710081727.AA11678@orion.utah.edu> Message-ID: <871009094342.8.RWK@WHITE-BIRD.SCRC.Symbolics.COM> Date: Thu, 8 Oct 87 11:27:49 MDT From: sandra%orion@cs.utah.edu (Sandra J Loosemore) This is pretty good. I have a general comment, and a few specifics. General comment: Those forms which affect the compilation environment should not be *required* to leave that effect behind when the compilation is finished. That is, it should be legal for a compiler, when finished compiling a file or set of files, to leave your environment exactly as it was before starting. The tricky part is "set of files"; there is a concept of scoping possible for a single compilation over multiple files. This is particularly useful if you defer warnings about undefined functions that are defined in later files. But as far as the language standard is concerned, I think it is best if the compilation is not defined to affect the environment, and you should be required to load the file before compiling the next if you want macro definitions to be visible in the next file, portably. Systems which are used for weeks at a time without booting shouldn't be polluted by compiling, say, a file of macros with incompatible changes. Specific comments: [I agree 200% with everything I've deleted.] DEFVAR, DEFPARAMETER. The compiler must recognize that the variables have been proclaimed special. It is probably not a good idea to evaluate the initial-value form. It should be definitely illegal to evaluate it at load time. DEFCONSTANT. If this "normally" stores any information that is used by the compiler (for example, to warn about assignment to or rebinding of the variable), then this information should also be stored at compile time. It's probably acceptable to evaluate the initial-value form in this case. Yes, this should be *required* to be evaluatable at compile time. If there were such a thing as "evaluatable-p", it could be deferred if not, but if the compiler is going to make use of this, it has to know it can evaluate it. DEFSETF. The SETF method should be available during the expansion of calls to SETF later on in the file. (Does anybody care about DEFINE-SETF-METHOD and DEFINE-MODIFY-MACRO?) Yes, both of those as well. DEFSTRUCT. The structure type name must be recognized as a valid type name in declarations (as in the DEFTYPE example above). In addition, further DEFSTRUCT definitions should be able to :include a structure type defined earlier in the file being compiled. The functions which DEFSTRUCT generates may or may not be available at compile time. But the accessors must be made available to SETF.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 9 Oct 87 03:08:01 EDT Received: from C.CS.CMU.EDU by SAIL.STANFORD.EDU with TCP; 8 Oct 87 15:46:10 PDT Received: ID ; Thu 8 Oct 87 18:46:45-EDT Date: Thu, 8 Oct 1987 18:46 EDT Message-ID: Sender: RAM@ From: Ram@C.CS.CMU.EDU To: sandra%orion@cs.utah.edu (Sandra J Loosemore) Cc: common-lisp@SAIL.STANFORD.EDU Subject: compile-time actions & top-level forms (long) In-reply-to: Msg of 8 Oct 1987 13:27-EDT from sandra%orion at cs.utah.edu (Sandra J Loosemore) This obviously falls within the purview of the Compiler Cleanup comittee, which unfortunately seems to be moribund. I agree with all the expectation of compiler semantics that you mention, and my proposal to the compiler cleanup comittee does have these properties. As a separate but related issue, I'd also like to see a DEF form defined to replace the magical compile-time behavior of the package functions. The solution I propose is to require package manipulation forms to appear at the beginning of the file. The package functions are only special-cased when they appear in that position. My proposal is accessible as cprop.txt on c.cs.cmu.edu. Anybody who knows Lisp compilers and has a recent history of breathing is encouraged to harrass the compiler comittee. Rob  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Oct 87 21:43:32 EDT Received: from NRTC.NORTHROP.COM by SAIL.STANFORD.EDU with TCP; 8 Oct 87 17:42:39 PDT Received: by nrtc.nrtc.northrop.com id aa03397; 8 Oct 87 17:42 PDT Date: Thu, 8 Oct 87 17:34:11 PDT From: Jeff Barnett To: common-lisp@sail.stanford.edu Subject: I need help I am currently trying to design and implement a high level protocol to lash together a bunch of programs running on SYMBOLICS and SUNS. The protocol is a generalization of the EVAL protocol used by the distributed DCLOCKS shell. Unfortunately, the SUN documentation available to me doesn't discuss what is available in terms of stack groups, processes, network code, etc. I need pointers to more detailed SUN documentation, or better yet, a knowledgable individual to talk to. Any suggestions of volunters would be much appreciated. Thanks in advance for any help or sympathy. Jeff Barnett  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Oct 87 21:24:48 EDT Received: from SCRC-STONY-BROOK.ARPA by SAIL.STANFORD.EDU with TCP; 8 Oct 87 17:59:15 PDT Received: from EUPHRATES.SCRC.Symbolics.COM by STONY-BROOK.SCRC.Symbolics.COM via CHAOS with CHAOS-MAIL id 252027; Thu 8-Oct-87 20:28:27 EDT Date: Thu, 8 Oct 87 20:28 EDT From: David A. Moon Subject: compile-time actions & top-level forms (long) To: Sandra J Loosemore cc: common-lisp@sail.stanford.edu In-Reply-To: <8710081727.AA11678@orion.utah.edu> Message-ID: <871008202812.0.MOON@EUPHRATES.SCRC.Symbolics.COM> Date: Thu, 8 Oct 87 11:27:49 MDT From: sandra%orion@cs.utah.edu (Sandra J Loosemore) .... As a separate but related issue, I'd also like to see a DEF form defined to replace the magical compile-time behavior of the package functions. I don't know or remember why the Common Lisp committee would not accept DEFPACKAGE. It seems simple and obvious to me. In Symbolics Common Lisp, it accepts the same arguments as MAKE-PACKAGE, except for the obvious syntactic differences between a macro and a function, namely that nothing is evaluated and that a keyword and its associated arguments are enclosed in parentheses (like defstruct-options). In SCL, the arguments to MAKE-PACKAGE are (NAME &KEY NICKNAMES PREFIX-NAME USE SHADOW EXPORT IMPORT SHADOWING-IMPORT IMPORT-FROM relative-names relative-names-for-me SIZE EXTERNAL-ONLY new-symbol-function hash-inherited-symbols invisible colon-mode prefix-intern-function include) The arguments in lower case are features that probably don't exist in straight Common Lisp. I agree with all your other suggestions.  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Oct 87 21:14:20 EDT Received: from NRTC.NORTHROP.COM by SAIL.STANFORD.EDU with TCP; 8 Oct 87 17:42:39 PDT Received: by nrtc.nrtc.northrop.com id aa03397; 8 Oct 87 17:42 PDT Date: Thu, 8 Oct 87 17:34:11 PDT From: Jeff Barnett To: common-lisp@sail.stanford.edu Subject: I need help I am currently trying to design and implement a high level protocol to lash together a bunch of programs running on SYMBOLICS and SUNS. The protocol is a generalization of the EVAL protocol used by the distributed DCLOCKS shell. Unfortunately, the SUN documentation available to me doesn't discuss what is available in terms of stack groups, processes, network code, etc. I need pointers to more detailed SUN documentation, or better yet, a knowledgable individual to talk to. Any suggestions of volunters would be much appreciated. Thanks in advance for any help or sympathy. Jeff Barnett  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Oct 87 21:04:50 EDT Received: from C.CS.CMU.EDU by SAIL.STANFORD.EDU with TCP; 8 Oct 87 15:46:10 PDT Received: ID ; Thu 8 Oct 87 18:46:45-EDT Date: Thu, 8 Oct 1987 18:46 EDT Message-ID: Sender: RAM@ From: Ram@C.CS.CMU.EDU To: sandra%orion@cs.utah.edu (Sandra J Loosemore) Cc: common-lisp@SAIL.STANFORD.EDU Subject: compile-time actions & top-level forms (long) In-reply-to: Msg of 8 Oct 1987 13:27-EDT from sandra%orion at cs.utah.edu (Sandra J Loosemore) This obviously falls within the purview of the Compiler Cleanup comittee, which unfortunately seems to be moribund. I agree with all the expectation of compiler semantics that you mention, and my proposal to the compiler cleanup comittee does have these properties. As a separate but related issue, I'd also like to see a DEF form defined to replace the magical compile-time behavior of the package functions. The solution I propose is to require package manipulation forms to appear at the beginning of the file. The package functions are only special-cased when they appear in that position. My proposal is accessible as cprop.txt on c.cs.cmu.edu. Anybody who knows Lisp compilers and has a recent history of breathing is encouraged to harrass the compiler comittee. Rob  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Oct 87 20:38:10 EDT Received: from C.CS.CMU.EDU by SAIL.STANFORD.EDU with TCP; 8 Oct 87 15:46:10 PDT Received: ID ; Thu 8 Oct 87 18:46:45-EDT Date: Thu, 8 Oct 1987 18:46 EDT Message-ID: Sender: RAM@ From: Ram@C.CS.CMU.EDU To: sandra%orion@cs.utah.edu (Sandra J Loosemore) Cc: common-lisp@SAIL.STANFORD.EDU Subject: compile-time actions & top-level forms (long) In-reply-to: Msg of 8 Oct 1987 13:27-EDT from sandra%orion at cs.utah.edu (Sandra J Loosemore) This obviously falls within the purview of the Compiler Cleanup comittee, which unfortunately seems to be moribund. I agree with all the expectation of compiler semantics that you mention, and my proposal to the compiler cleanup comittee does have these properties. As a separate but related issue, I'd also like to see a DEF form defined to replace the magical compile-time behavior of the package functions. The solution I propose is to require package manipulation forms to appear at the beginning of the file. The package functions are only special-cased when they appear in that position. My proposal is accessible as cprop.txt on c.cs.cmu.edu. Anybody who knows Lisp compilers and has a recent history of breathing is encouraged to harrass the compiler comittee. Rob  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Oct 87 20:10:00 EDT Received: from C.CS.CMU.EDU by SAIL.STANFORD.EDU with TCP; 8 Oct 87 15:46:10 PDT Received: ID ; Thu 8 Oct 87 18:46:45-EDT Date: Thu, 8 Oct 1987 18:46 EDT Message-ID: Sender: RAM@ From: Ram@C.CS.CMU.EDU To: sandra%orion@cs.utah.edu (Sandra J Loosemore) Cc: common-lisp@SAIL.STANFORD.EDU Subject: compile-time actions & top-level forms (long) In-reply-to: Msg of 8 Oct 1987 13:27-EDT from sandra%orion at cs.utah.edu (Sandra J Loosemore) This obviously falls within the purview of the Compiler Cleanup comittee, which unfortunately seems to be moribund. I agree with all the expectation of compiler semantics that you mention, and my proposal to the compiler cleanup comittee does have these properties. As a separate but related issue, I'd also like to see a DEF form defined to replace the magical compile-time behavior of the package functions. The solution I propose is to require package manipulation forms to appear at the beginning of the file. The package functions are only special-cased when they appear in that position. My proposal is accessible as cprop.txt on c.cs.cmu.edu. Anybody who knows Lisp compilers and has a recent history of breathing is encouraged to harrass the compiler comittee. Rob  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Oct 87 19:18:54 EDT Received: from C.CS.CMU.EDU by SAIL.STANFORD.EDU with TCP; 8 Oct 87 15:46:10 PDT Received: ID ; Thu 8 Oct 87 18:46:45-EDT Date: Thu, 8 Oct 1987 18:46 EDT Message-ID: Sender: RAM@ From: Ram@C.CS.CMU.EDU To: sandra%orion@cs.utah.edu (Sandra J Loosemore) Cc: common-lisp@SAIL.STANFORD.EDU Subject: compile-time actions & top-level forms (long) In-reply-to: Msg of 8 Oct 1987 13:27-EDT from sandra%orion at cs.utah.edu (Sandra J Loosemore) This obviously falls within the purview of the Compiler Cleanup comittee, which unfortunately seems to be moribund. I agree with all the expectation of compiler semantics that you mention, and my proposal to the compiler cleanup comittee does have these properties. As a separate but related issue, I'd also like to see a DEF form defined to replace the magical compile-time behavior of the package functions. The solution I propose is to require package manipulation forms to appear at the beginning of the file. The package functions are only special-cased when they appear in that position. My proposal is accessible as cprop.txt on c.cs.cmu.edu. Anybody who knows Lisp compilers and has a recent history of breathing is encouraged to harrass the compiler comittee. Rob  Received: from SAIL.Stanford.EDU (TCP 1200000013) by AI.AI.MIT.EDU 8 Oct 87 14:06:10 EDT Received: from CS.UTAH.EDU by SAIL.STANFORD.EDU with TCP; 8 Oct 87 10:28:02 PDT Received: by cs.utah.edu (5.54/utah-2.0-cs) id AA18377; Thu, 8 Oct 87 11:27:55 MDT Received: by orion.utah.edu (5.54/utah-1.0-slave) id AA11678; Thu, 8 Oct 87 11:27:49 MDT Date: Thu, 8 Oct 87 11:27:49 MDT From: sandra%orion@cs.utah.edu (Sandra J Loosemore) Message-Id: <8710081727.AA11678@orion.utah.edu> Subject: compile-time actions & top-level forms (long) To: common-lisp@sail.stanford.edu The following is a rough proposal I've put together to try to get some agreement on what the compile-time behavior of certain top-level macros should be. I came up with many items on this list by noting things that were "broken" or behaved surprisingly in some implementations; KCL is certainly the worst offender in this respect. The situations I've listed appear to be fairly standard programming practices and I think we need to state explicitly somewhere that CL supports them. I have found that some implementations also have disturbing variations from the behavior that is explicitly specified in CLtL regarding evaluation of ordinary function calls appearing at the top level. Some implementors have responded to my complaints by saying, in effect, that if I don't like the default behavior they provide, I can always explicitly wrap the offending form in an eval-when to get the behavior I want. This just isn't good enough -- if everybody is free to diverge from CLtL however they want, then I'd have to wrap *every* top-level form with an eval-when to guarantee portability. Do we really want to force that on unsuspecting users? In many of these cases, the top-level form needs to store information at compile time. I'm leaving open the possibility that the place where the information is stored during compile-time processing might be different than where it gets stored during normal load/eval processing. My primary concern is that the information be available for use by the compiler later on during the compilation of the same file. A simple implementation technique (one which I've used to patch KCL, for example) is to simply wrap the forms which store the information in the macro expansion with an (eval-when (eval compile load) ...). As a separate but related issue, I'd also like to see a DEF form defined to replace the magical compile-time behavior of the package functions. DEFTYPE. Type names defined via DEFTYPE should be recognized as valid in subsequent type declarations. (deftype small-int '(int 0 10)) (let ((x 0)) (declare (type small-int x)) ....) DEFMACRO. Macro definitions must be stored at compile time, so that occurences of the macro later on in the file will be expanded correctly. (defmacro silly (x) `(car ,x)) ... (silly foo) .... ; should compile as (car foo) DEFUN. Nothing special is required here, although an implementation may wish to store information about the lambda-list (etc.) for the purposes of compile-time error checking. DEFVAR, DEFPARAMETER. The compiler must recognize that the variables have been proclaimed special. It is probably not a good idea to evaluate the initial-value form. (defvar *stack* (some-incredibly-hairy-function)) (let ((*stack* *stack*)) ; this should be a special binding. ....) DEFCONSTANT. If this "normally" stores any information that is used by the compiler (for example, to warn about assignment to or rebinding of the variable), then this information should also be stored at compile time. It's probably acceptable to evaluate the initial-value form in this case. DEFSETF. The SETF method should be available during the expansion of calls to SETF later on in the file. (Does anybody care about DEFINE-SETF-METHOD and DEFINE-MODIFY-MACRO?) (defsetf foo modify-foo) (setf (foo x y) z) DEFSTRUCT. The structure type name must be recognized as a valid type name in declarations (as in the DEFTYPE example above). In addition, further DEFSTRUCT definitions should be able to :include a structure type defined earlier in the file being compiled. The functions which DEFSTRUCT generates may or may not be available at compile time. (defstruct person name age sex) (defstruct (astronaut (:include person) (:conc-name astro-)) helmet-size (favorite-beverage 'tang)) Questions & comments are welcome.... -Sandra -------