Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 7 APR 86 22:28:52 EST Date: 7 Apr 1986 22:25 EST (Mon) Message-ID: From: "David A. Brown" To: gjs%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU, David%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU, dyb%indiana.csnet@CSNET-RELAY.ARPA, rrrs-authors@MC.LCS.MIT.EDU Phase-Of-The-Moon: LQ+6D.12H.38M.45S. Sorry about accidentally replying to all of you with that last message. Darn babyl 'r' command... - David  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 7 APR 86 22:12:26 EST Date: 7 Apr 1986 22:10 EST (Mon) Message-ID: From: "David A. Brown" To: Gerald Jay Sussman Cc: David%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU, dyb%indiana.csnet@CSNET-RELAY.ARPA, rrrs-authors@MC.LCS.MIT.EDU Subject: expansion of LETREC (hmmm) In-reply-to: Msg of 7 Apr 1986 16:31-EST from Gerald Jay Sussman Date: Monday, 7 April 1986 16:31-EST From: Gerald Jay Sussman To: dyb%indiana.csnet at CSNET-RELAY.ARPA cc: rrrs-authors at MC.LCS.MIT.EDU Re: expansion of LETREC (hmmm) ReSent-Date: Mon 7 Apr 86 20:55:41-EST ReSent-From: Eddie Gornish ReSent-To: david@OZ.AI.MIT.EDU ReSent-Message-ID: <12197057091.48.DFUSER.EHG@XX.LCS.MIT.EDU> ...they felt that LET, LET* and LETREC formed (or should form) a linear sequence, each more powerful (in a sense) than the last. I think that that is wrong. LET is more powerful than LET* because one can make LET* by nesting LETs but you cannot make LET easily from LET*. Sequential methods are often more convenient than parallel ones, but they are inessential. On the other hand, your implementation of LETREC: (letrec ((x v) ...) e ...) => (let ((x 'any) ...) (set! x v) ... e ...) certainly looks pretty good to me. The question is whether we want to specify the order of assignment as being the same as the order of the expressions in the LETREC. I see the same problems arising with internal definitions (being just a syntax for a LETREC form). I suppose that I can be moved either way. What the hell does this mean?  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 7 APR 86 16:39:03 EST Date: Mon 7 Apr 86 16:34:12-EST From: "Gerald Jay Sussman" Subject: Re: Immutable code and quoted data To: dyb%indiana.csnet@CSNET-RELAY.ARPA cc: rrrs-authors@MC.LCS.MIT.EDU In-Reply-To: Message from "Kent Dybvig " of Mon 7 Apr 86 12:09:50-EST Message-ID: <12197009491.61.GJS@OZ.AI.MIT.EDU> I dunno... I think that quoted structure should be immutable... I think that we should think of quotation as as syntax for constants. -------  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 7 APR 86 16:37:05 EST Date: Mon 7 Apr 86 16:31:58-EST From: "Gerald Jay Sussman" Subject: Re: expansion of LETREC (hmmm) To: dyb%indiana.csnet@CSNET-RELAY.ARPA cc: rrrs-authors@MC.LCS.MIT.EDU In-Reply-To: Message from "Kent Dybvig " of Mon 7 Apr 86 12:05:14-EST Message-ID: <12197009084.61.GJS@OZ.AI.MIT.EDU> ...they felt that LET, LET* and LETREC formed (or should form) a linear sequence, each more powerful (in a sense) than the last. I think that that is wrong. LET is more powerful than LET* because one can make LET* by nesting LETs but you cannot make LET easily from LET*. Sequential methods are often more convenient than parallel ones, but they are inessential. On the other hand, your implementation of LETREC: (letrec ((x v) ...) e ...) => (let ((x 'any) ...) (set! x v) ... e ...) certainly looks pretty good to me. The question is whether we want to specify the order of assignment as being the same as the order of the expressions in the LETREC. I see the same problems arising with internal definitions (being just a syntax for a LETREC form). I suppose that I can be moved either way. -------  Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 7 Apr 86 12:03:31 EST Received: from indiana by csnet-relay.csnet id af00192; 7 Apr 86 11:28 EST Date: Mon, 7 Apr 86 02:53:41 est From: Kent Dybvig To: rrrs-authors@mc.lcs.mit.edu Subject: efficiency vs functionality A letter to the editor. After sending my last note I got to thinking about how many arguments for or against a particular feature have been based on how difficult efficient implementation becomes. Decisions are often made by weighing functionality against efficiency (as in the splitting/coalescing discussion). It seems that the early development of Scheme was not affected by efficiency arguments, otherwise who would have first-class closures or continuations? Would we like Scheme as much today if the efficiency trade-offs had been factored in? Would we have bothered to learn how to implement first-class closures and continuations efficiently if we did not have them in our language? Sure, we want to give implementors a fair chance to compete in speed with other languages, but we may be making it a little to easy on them. At the very least, the decisions should be along the lines of feasibility of efficient implementation, not ease of efficient implementation. We should never make life harder for the user to make life easier for the implementor. Tomorrow's editorial topic: the effect of "historical reasons," "existing documentation," and "1,000,000 lines of existing code" on language design and standardization.  Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 7 Apr 86 12:02:58 EST Received: from indiana by csnet-relay.csnet id ae00192; 7 Apr 86 11:27 EST Date: Mon, 7 Apr 86 02:23:45 est From: Kent Dybvig To: rrrs-authors@mc.lcs.mit.edu Subject: Re: Immutable code and quoted data I agree that the report should not constrain implementations one way or another on the quote/mutable issue. There are reasonable arguments on both sides. On the immutable side, it can be more efficient in terms of garbage collection and virtual memory if an implementation is allowed to put quoted structures in read-only memory. On the mutable side, it can be quite useful for quote to produce mutable structures to share or retain state. For example, consider the following implementation of "once", presumably as a macro, where "(once e)" evalutates "e" only once and thereafter returns the same value: (once e) => (let ([x '(any . #!false)]) ; x not appearing in e (unless (cdr x) (set-car! x e) (set-cdr! x #!true)) (car x)) A perverse example using once: (begin (define foo (lambda (x) (once x))) (foo 3) (foo 4)) => 3 The same sort of idea can be used for "own" variables. Things get even stranger when quote is used to introduce the same (identical) structure in two separate places, for some sort of communication purposes. People here have actually done this, although it causes problems with printing object code in the absense of a hashing printer.  Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 7 Apr 86 12:00:41 EST Received: from indiana by csnet-relay.csnet id ab00192; 7 Apr 86 11:26 EST Date: Mon, 7 Apr 86 00:43:26 est From: Kent Dybvig To: rrrs-authors@mc.lcs.mit.edu Subject: Re: expansion of LETREC (hmmm) I have had two people express great surprise and chagrin that LETREC does not guarantee left-to-right evaluation as does LET*. (One is a veteran in computer science; the other is an economist with substantial programming experience in a few unmentionable languages. Both were new to Scheme.) They both wanted to use LET when there is no constraint on ordering, LET* when the ordering is sequential, and LETREC when there is recursion or circularity. Both felt that they should be able to use LETREC wherever they could have used LET*, (unless they needed to use a variable with a conflicting name outside of the form). In other words, they felt that LET, LET* and LETREC formed (or should form) a linear sequence, each more powerful (in a sense) than the last. They felt that the restrictions on LETREC were arbitrary and useless. When I showed them the definitions of LET, LET* and LETREC (the latter in terms of let and set!), both pointed out that it would be trivial to support this functionality. In other words, they wanted the definition for LETREC given in my last note: (letrec ((x v) ...) e ...) => (let ((x 'any) ...) (set! x v) ... e ...) This issue, of course, does not concern those who avoid anything but lambda expressions in LETREC. I'm not sure I see any harm in this definition of LETREC, but I haven't come to any real conclusion on this matter. It certainly has the merits of reducing confusion and making the writing of the RRRS easier.  Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 7 Apr 86 12:00:16 EST Received: from indiana by csnet-relay.csnet id aa00192; 7 Apr 86 11:25 EST Date: Mon, 7 Apr 86 00:26:03 est From: Kent Dybvig To: rrrs-authors@mc.lcs.mit.edu Subject: Re: expansion of LETREC I favor saying that "one possible" definition of LETREC is the one given earlier, or even the following: (letrec ((x v) ...) e ...) => (let ((x 'any) ...) (set! x v) ... e ...) Neither definition catches all the possible errors, but we have already said that not all errors need be caught. Of course, any implementation would be free to check for errors before performing this transformation!  Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 6 Apr 86 23:35:16 EST Received: from indiana by csnet-relay.csnet id a025875; 6 Apr 86 23:34 EST Date: Sun, 6 Apr 86 00:13:42 est From: Perry Wagle To: rrrs-authors@mc.lcs.mit.edu Subject: LETREC (REC) /**** iuvax:scheme-rrrs / iuvax!wagle / 12:50 am Apr 2, 1986 ****/ > iuvax:scheme-rrrs / iuvax!JINX%OZ.AI.MIT.EDU@xx.lcs / 11:41 pm Apr 1, 1986 > As you probably know by now, there is a feature that I REALLY dislike about > LETREC (REC), namely that LETREC allows non-lambda expressions in the > binding list. I would like to make this optional and make the standard > allow only lambda expressions. Is there a lot of opposition to this? > ... LAMBDA expressions aren't the only expressions to return closures. Except for trivial cases, there is no way to know at compile-time whether or not an expression is going to return a closure or not. I definitely demand that I be allowed to use "function constructors" in the RHS of letrec bindings (that is functions that return functions). Perry Wagle, Indiana University, Bloomington Indiana. ...!ihnp4!inuxc!iuvax!wagle (USENET) wagle@indiana (CSNET) wagle%indiana@csnet-relay (ARPA)  Date: Fri, 4 Apr 86 22:31:26 EST From: Jonathan A Rees Subject: Immutable code and quoted data To: ANDY@SU-SUSHI.ARPA cc: RRRS-AUTHORS@MC.LCS.MIT.EDU In-reply-to: Msg of Fri 4 Apr 86 15:08:28-PST from Andy Freeman Message-ID: <[MC.LCS.MIT.EDU].874480.860404.JAR> Date: Fri 4 Apr 86 15:08:28-PST From: Andy Freeman I believe procedure-b and procedure-c are the same because I believe that quote'd structures are built at load time (or possibly read or compile time). ... I believe that procedure-b and procedure-c are illegal because I believe that quoted structures are built in the user's mind (which the machine shouldn't be mucking around with). Weird "times" shouldn't come into question here ... Jonathan  Date: Fri, 4 Apr 86 22:25:15 EST From: Jonathan A Rees Subject: Immutable code and quoted data To: ANDY@SU-SUSHI.ARPA cc: RRRS-AUTHORS@MC.LCS.MIT.EDU In-reply-to: Msg of Fri 4 Apr 86 15:08:28-PST from Andy Freeman Message-ID: <[MC.LCS.MIT.EDU].874458.860404.JAR> The area of immutable data for Scheme is a good one for experimentation. But I don't think Scheme should take a stand on this subject at this time. The trick is to phrase the report in such a way as to allow latitude for people to play around with these ideas. My main motivation at this point (now that I see there's no consensus) is that I don't want anyone's implementations to have to change in order to support EQV? and QUOTE as defined in the Scheme report. My proposed EQV? and QUOTE specifications ALLOW implementations to create immutable structure and have EQV? (and even EQ?) compare the contents of immutable structure; but they don't REQUIRE them to. It is probably compatible with most Schemes in existence, because it is so noncommittal. It sounds like you're trying to make the language more concrete. If a stand is taken one way or another, then no matter which stand is taken, some implementations will have to change. If quoted structure must be mutable, then T, and I suspect some other implementations, including any implementation embedded in Maclisp or Common Lisp, will have to go to some trouble to avoid using the obvious existing mechanisms. If it must be immutable, you'll also be cursed by implementors who need to add immutable types and more complicated type checking. Saying that it is an error if structure created by QUOTE is clobberred is much weaker than saying either that implementations must have an IMMUTABLE? predicate or that quoted structure must be mutable. Errors do not have to be detected. I don't see why it makes sense to distinguish interpretation from compilation. Scheme has no way to distinguish these situations. Remember that there is no EVAL, and there's no guarantee that the mechanism which causes programs to be executed uses READ - it parses the program somehow, but READ has nothing to do with that. I think it would be reasonable to argue that READ should be allowed to return immutable structure, but I'm not going to do so, because I think some people disagree and I don't feel strongly about it. But again, QUOTE and READ are unrelated, since there's no EVAL. It doesn't make sense to talk about "copying the source" since source only exists in files. If there were an EVAL, I would certainly want it to copy both the code and the quoted structure (if those things were mutable), to ensure compatibility between EVAL and transduced (compiled or whatever) code; I think we agree there. I agree that if immutable structure exists, then some mechanism besides QUOTE should exist to create it. (Maclisp's solution is to have a single function, PURCOPY, which makes a pure copy of an impure structure.) I also agree that immutable structure shouldn't contain mutable structure and shouldn't be circular (although I doubt that there would be consensus on these questions - various functional languages out there let one create circular immutable objects using LETREC). But I wouldn't want to force these things on implementors; again, this area is too borderline and experimental. (A propos rarity of constant data structures: Algol 68 certainly has all kinds of constant data. Also, I was under the impression that C implementations were allowed to put in-line strings constants in pure (text) memory.) Jonathan  Received: from SU-SUSHI.ARPA by MC.LCS.MIT.EDU 4 Apr 86 21:09:21 EST Date: Fri 4 Apr 86 15:08:28-PST From: Andy Freeman Subject: Immutable code and quoted data To: rrrs-authors@MC.LCS.MIT.EDU Message-ID: <12196240218.45.ANDY@SU-SUSHI.ARPA> Summary: 1. Immutable structures raise lots of issues in the reader and other places that should be settled before they are added to the language. 2. Interpreters must copy the source, unless .... 3. Side-effects on quote'd structures really aren't different from other things the language must have. 4. Immutable quoted structures might be acceptable (and may even be a good idea) if everything is done right; it isn't yet. Andy Freeman (me) wrote: Immutable cons structures bother me. Every other immutable structure in Scheme has a distinct reader syntax. Will Clinger replied: I think the idea is that QUOTE would mark structures as immutable. Jonathan's proposal was that QUOTE mark structures in code as immutable, but QUOTE isn't external syntax for immutable. (I should have said distinct EXTERNAL syntax instead of reader syntax.) The value of (read)ing (quote (a b)) is not the same as (read)ing (a b); (write '(a b)) has the same output that (write (list 'a 'b)) does. JAR's reply to my objection is that write and read lose address information so why shouldn't they be allowed to lose the immutability bit? Accepting this point raises the question, should read return mutable structures? (I believe the answer is no.) If not, then every immutable structure has the obvious external syntax and no mutable structure has a reader syntax. (Requiring write's arguments to be immutable structures is going too far.) Everything that can be quoted will need an immutable counterpart and it seems arbitrary to restrict immutable structures to the domain of the interpreter. In other words, not only is immutable? necessary, but so is immutable-cons, immutable-vector, and immutable-string. (To put it another way, many structures will require mutable ones as well.) We also need to decide whether the arguments to the immutable constructors can be mutable. (I don't think they can be.) Will Clinger continues: I think immutable pairs are motivated by the fact that in many systems side effects to quoted list structure alter the source code, particularly when the code is interpreted rather than compiled. This can make it hard to debug, so the implementors want to discourage such side effects by calling them "errors". Not that I've done this right either, but since compilation must copy the source code, interpreters should behave as if they are using a copy of the source. This has other advantages. For example, is it legal for a program to modify its source to affect its behavior or for the source to be circular? (I think not.) If all of the above is accepted (read returns immutable structures and immutable structures can't contain mutable ones) and code and quoted data must be immutable and acyclic, then the copy seems unnecessary. Note that this last position is extreme; both code and quoted data are immutable. JAR's proposal was that quoted data should be immutable. I'd like immutable code. The issues are separate. Currently Scheme has mutable code and quoted data. I believe that Scheme should change to at least "immutable" code, which can be accomplished by copying the source. (No, it actually doesn't require new data types or operations.) JAR proposes immutable quoted data, which can be accomplished in the ways he described with the additions I suggest. True constant data structures, such as JAR proposes, are rare. Apart from functional and logic languages, like FP and Prolog (and they're a special case in Prolog), ML is the only language I know of with constant data. (c++ may have constant structures, but c definitely doesn't.) I don't see side effects on quoted structure as being something odd; QUOTE is a convenient short-hand, but it isn't a syntax for constants. -andy @begin(tangent) Obviously the following procedure can return 97. (let ((x (list 'a))) ; procedure-a (lambda (flag) (if flag (set-car! x flag) (car x)))) On the other hand, many of you object to the same behavior by the following procedure (let ((x '(a))) ; procedure-b (lambda (flag) (if flag (set-car! x flag) (car x)))) or an equivalent one. (lambda (flag) ; procedure-c (let ((x '(a))) (if flag (set-car! x flag) (car x)))) I believe procedure-b and procedure-c are the same because I believe that quote'd structures are built at load time (or possibly read or compile time). In other words, I believe that the following must be #t. (let ((x (lambda () (lambda () '(a))))) (eq? ((x)) ((x)))) @end(tangent) -------  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 4 APR 86 17:43:10 EST Date: 4 Apr 1986 10:47 EST (Fri) Message-ID: From: Bill Rozas To: Ken Haase Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: LETREC (REC) In-reply-to: Msg of 4 Apr 1986 09:31-EST from Ken Haase The problem is that this particular over restriction really diminishes the power of the language; no clever macrology (in the current RRRS) is going to allow general higher order functions to generate recursive functions. (By general, I mean higher order functions which don't specifically expect to generate recursive functions). This is not true. While it becomes more complicated, it is possible to do it. I don't remember your precise example but there is a simple trick which makes it work and satifies the constraint I like. The trick is the same as the one used in converting the normal order Y operator into applicative order. Questions of efficiency might arise if there is no procedure integration or the compiler is not able to deduce what's going on or allowed to use this information.  Received: from AI.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 4 APR 86 16:24:51 EST Date: Fri, 4 Apr 86 09:31:19 EST From: Ken Haase Subject: LETREC (REC) To: JINX@OZ.AI.MIT.EDU cc: RRRS-AUTHORS@MC.LCS.MIT.EDU In-reply-to: Msg of 1 Apr 1986 09:47 EST (Tue) from Bill Rozas Message-ID: <[AI.AI.MIT.EDU].23941.860404.KWH> Date: 1 Apr 1986 09:47 EST (Tue) From: Bill Rozas To: Ken Haase cc: RRRS-AUTHORS at MC.LCS.MIT.EDU Re: LETREC (REC) Unfortunately it is not ill defined. A simple "operational" description (like the one in the currentl version of RRRS) describes what is legal and what is not. I view this operational description as a crock, and the only way that I can see to restrict the use of LETREC to reasonable cases is to "over-restrict" it. The problem is that this particular over restriction really diminishes the power of the language; no clever macrology (in the current RRRS) is going to allow general higher order functions to generate recursive functions. (By general, I mean higher order functions which don't specifically expect to generate recursive functions). Note that the error is not unbound variable. The variable is bound, since the expressions are evaluated in an environment where the names are bound. At best it is unassigned, but this implies that there are side effects going on, which I don't like. I meant unassigned. I think that in any implementation-oriented explanation, you may have to resort to side effects to explain what is going on. Even if you characterize LETREC with delays, it seems to me that you will still have an understood side-effect lurking inside of the delay.  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 3 APR 86 14:35:10 EST Date: 3 Apr 1986 14:12 EST (Thu) Message-ID: From: Bill Rozas To: Paul Hudak Cc: Jonathan A Rees , RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: expansion of LETREC In-reply-to: Msg of 3 Apr 1986 11:59-EST from Paul Hudak Please ignore previous message. Somehow I did not notice the following lines (parser must have failed) Let xi' be like xi except that all (free) occurrences of vi are replaced with (force vi); similarly for body'. Then:  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 3 APR 86 14:33:58 EST Date: 3 Apr 1986 14:11 EST (Thu) Message-ID: From: Bill Rozas To: Paul Hudak Cc: Jonathan A Rees , RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: expansion of LETREC In-reply-to: Msg of 3 Apr 1986 11:59-EST from Paul Hudak Is your DELAY "forced" automatically on reference? If not I don't understand how this works. Neither of the 2 versions of DELAY that I'm familiar with (automatic forcing by appropriate primitives and explicit forcing) would solve the problem. If it is forced on reference then it seems pretty useless (useful only for this?) since one of the crucial features of DELAY is that CONS does not force it, so streams can be built on top of it.  Received: from yale-bulldog by MC.LCS.MIT.EDU 3 Apr 86 12:28:33 EST Received: by Yale-Bulldog.YALE.ARPA; 3 Apr 86 11:59:19 EST (Thu) Date: 3 Apr 86 11:59:19 EST (Thu) From: Paul Hudak Message-Id: <8604031659.AA05511@Yale-Bulldog.YALE.ARPA> Subject: Re: expansion of LETREC To: Jonathan A Rees Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU In-Reply-To: Jonathan A Rees , Wed, 2 Apr 86 16:35:01 EST Off-hand it seems odd that one can't write LETREC in Scheme -- the problem, of course, is that special forms are usually equated with macros, which have limited transformation capabilities. One CAN define the semantics of LETREC in Scheme by the following transformation: Let xi' be like xi except that all (free) occurrences of vi are replaced with (force vi); similarly for body'. Then: (letrec ((v1 x1) (v2 x2) ...) body) ==> (let ((v1 (delay (error ...))) (v2 (delay (error ...))) ...) (let ((temp1 x1') (temp2 x2') ...) ;unspecified evaluation order (set! v1 (delay temp1)) ;tempi don't occur free in body (set! v2 (delay temp2)) ... body')) Compare this with your: (let ((v1 ) (v2 ) ...) (let ((temp1 x1) (temp2 x2) ...) ;unspecified evaluation order (set! v1 temp1) ;tempi don't occur free in body (set! v2 temp2) ... body)) I haven't thought about this in detail, like how it interacts with CALL-WITH-CURRENT-CONTINUATION, but off-hand it seems to avoid the proliferation of primitive special forms (your solution 1) or primitive procedures (your solutions 2-5) yet is precise in the semantics (I think). -Paul  Received: from GODOT.THINK.COM by MC.LCS.MIT.EDU 3 Apr 86 11:19:31 EST Received: from katherine by GODOT.THINK.COM via CHAOS; Thu, 3 Apr 86 11:06:45 est Date: Thu, 3 Apr 86 11:08 EST From: Guy Steele Subject: begin To: KMP@SCRC-STONY-BROOK.ARPA, JAR@MIT-MC.ARPA, CPH@MIT-MC.ARPA Cc: RRRS-AUTHORS@MIT-MC.ARPA, gls@THINK-AQUINAS.ARPA In-Reply-To: <860402133240.3.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM> Message-Id: <860403110814.6.GLS@THINK-KATHERINE.ARPA> Date: Wed, 2 Apr 86 13:32 EST From: Kent M Pitman ... I didn't realize this idea of putting definitions in BEGIN was a serious suggestion. I strongly oppose having either BEGIN or LET do this. The reason is that it makes it impossible to write code which wants to use these primitives for other things and doesn't have additional implications that may be unwanted or may have implications in macros or program-writing programs that some programmer didn't count on. As a counter-proposal, how about a LOCALLY special form. ie, (LOCALLY *
*) The Common Lisp committee went through this issue, rather painfully. At one point I had proposed that PROGN, and any implicit PROGN (such as COND clauses) allow DECLARE forms at the front. This was roundly and soundly booed, and LOCALLY emerged from the fracas. --Guy  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 2 APR 86 19:06:10 EST Date: Wed, 2 Apr 1986 19:05 EST Message-ID: From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU To: Jonathan A Rees Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: expansion of LETREC In-reply-to: Msg of 2 Apr 1986 16:35-EST from Jonathan A Rees I favor position number 1. The reason: it is a relatively simple solution to what seems a relatively unimportant issue. I think that implementors are free to use a procedure like UNINITIALIZED internally, thus preserving LAMBDA as the sole binding operator. MIT Scheme does just this. The syntax for LETREC (and optionally, LET) provides the user with a means of creating uninitialized variables.  Received: from ZERMATT.LCS.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 2 APR 86 17:49:22 EST Received: from ASPEN.LCS.MIT.EDU by MIT-ZERMATT.ARPA via CHAOS with CHAOS-MAIL id 30141; Wed 2-Apr-86 17:37:39-EST Date: Wed, 2 Apr 86 17:37 EST From: Robert Halstead Subject: expansion of LETREC To: JAR@MIT-MC.ARPA cc: RRRS-AUTHORS@MIT-MC.ARPA In-Reply-To: <[MC.LCS.MIT.EDU].870750.860402.JAR> Message-ID: <860402173745.5.RHH@ASPEN.LCS.MIT.EDU> I have some misgivings about your solution number (3), involving CALL-WITH-UNINITIALIZED-PARAMETERS: what would it mean to apply this to a procedure of the form (LAMBDA (X . Y) ...)? Also, I am not entirely sure I am ecstatic about supplying a procedure such as C-W-U-P for people to use directly -- I guess my concern is more that I see no utility for it other than as an expository device for explaining LETREC, rather than as something people might want to use explicitly. Finally, I think there might be some resistance to defining LETREC in terms of a side-effect primitive such as SET!, even if such a definition is possible, but I guess I can let the people who would resist speak for themselves. If you use it, how about APPLY-TO-UNINITIALIZED-VALUES as an alternative name? -b.  Date: Wed, 2 Apr 86 16:35:01 EST From: Jonathan A Rees Subject: expansion of LETREC To: RRRS-AUTHORS@MC.LCS.MIT.EDU Message-ID: <[MC.LCS.MIT.EDU].870750.860402.JAR> I would like to put a little more detail in the report about the distinction between the "syntactic sugar" special forms (COND etc.) and the "primitive" or "core" ones (QUOTE IF LAMBDA BEGIN SET!). The distinction is a good one to make even in the absence of macros. This isn't hard to do for any of the special forms except for LETREC. The following almost works: (letrec ((v1 x1) (v2 x2) ...) body) ==> (let ((v1 ) (v2 ) ...) (let ((temp1 x1) (temp2 x2) ...) ;Note unspecified evaluation order (set! v1 temp1) ;temp1 etc. are vars which don't occur free in body (set! v2 temp2) ... body)) But this ultimately doesn't foot the bill because it fails to say that it is an error to reference the bound variables before they're initialized. This is very different from the variables having unspecified values, since if the variable has an unspecified value it cannot be an error to access that value, even though it may be an error to do anything with it. Let me describe the alternative solutions that have occurred to me: 1. Say that LETREC is "almost not primitive" except for this one quirk. That's probably the status quo position. This is bad because it increases the number of primitives from 5 to 6, and because there are now two variable binding constructs instead of one. LETREC is so close to being syntactic sugar that it would be a shame if it wasn't first-class syntactic sugar. 2. Legitimize this actually quite useful feature of creating uninitialized locations by introducing an explicit mechanism to create them: 2a. In MIT Scheme this is (define var). This is unacceptable because it makes DEFINE primitive instead of syntactic sugar. 2b. Another alternative would be to have a new binding construct [Andy, doesn't 1S have something like this?], say (LOCALS (var1 var2 ...) body), which introduces uninitialized bindings. This is also not good since it would be a shame to add a new special form, especially one which makes LAMBDA not be the only binding construct. 3. Similar to the #2, but with a new procedure instead of a special form. Let's call it CALL-WITH-UNINITIALIZED-PARAMETERS. This is a procedure of one argument, which calls its procedure argument in such a way that the procedure's parameters are uninitialized: (call-with-uninitialized-parameters (lambda (var1 var2 ...) body)) 4. Have a procedure, say (UNINITIALIZED), which returns an object which when stored in a variable's location causes it to be an error to access the location. This is similar to (3), but much more powerful, since initializedness is no longer "monotonic" - a variable which had a value can come to not have a value if it is SET! to (UNINITIALIZED). I think that kind of power could be dangerous although I can't say exactly why I think so. It's like MAKUNBOUND only worse. 5. Like 4 but don't document the procedure. I don't like this because it seems to hide something form the user -- it taunts, "I have this feature but I won't let you use it". 6. Disallow anything besides LAMBDA-expressions on the right-hand sides. This would mean that nothing would have to be said about it being an error to reference the variables since there's no way that could happen anyhow. The problem with this is that even if it's a perfectly good idea (true of the 1975 & 1978 Schemes) no one except Bill Rozas likes it, not even me. 7. Change to normal order evaluation. I don't think this is practical or desirable at this point. --- Let me know what y'all think about CALL-WITH-UNINITIALIZED-PARAMETERS. If you like it (I kind of do) then try to think of a name for it. Please overlook the question of what happens when you pass it CONS as an argument. We can just say that it's an error to pass it any primitive procedure, since they all presumably reference their parameters. If you don't like it then please defend position number 1 so that I feel more comfortable documenting it. Jonathan.  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 2 APR 86 16:19:34 EST Date: 2 Apr 1986 14:57 EST (Wed) Message-ID: From: Bill Rozas To: Kent M Pitman Cc: CPH@MC.LCS.MIT.EDU, JAR@MC.LCS.MIT.EDU, RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: begin In-reply-to: Msg of 2 Apr 1986 13:32-EST from Kent M Pitman I didn't realize this idea of putting definitions in BEGIN was a serious suggestion. I strongly oppose having either BEGIN or LET do this. The reason is that it makes it impossible to write code which wants to use these primitives for other things and doesn't have additional implications that may be unwanted or may have implications in macros or program-writing programs that some programmer didn't count on. As a counter-proposal, how about a LOCALLY special form. ie, (LOCALLY * *) The main reason for local DEFINE is S&ICP. If LET is just syntactic sugar for LAMBDA, DEFINE must be allowed at top level of a LET. Beyond that I would object strongly to disallowing DEFINE in LET since I (and other people at MIT) use it all the time. I think that JAR sent the message about begin at least half jokingly (April 1st), so it should not be taken too seriously.  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 2 APR 86 16:13:59 EST Date: Wed, 2 Apr 1986 14:32 EST Message-ID: From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU To: Jonathan A Rees Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: begin In-reply-to: Msg of 2 Apr 1986 13:20-EST from Jonathan A Rees Date: Wednesday, 2 April 1986 13:20-EST From: Jonathan A Rees Then perhaps BEGIN should be caled something else... maybe SEQUENCE or SEQUENTIALLY... I thought it got its name from Algol 60 and therefore should be as much like Algol 60's begin blocks as possible... This is one reason why I objected to this name at Brandeis. But it is clearly too late to change it now. don't anyone messages that I send on April 1 seriously. I guess the joke's on me... I didn't catch that one (although your other message was pretty obvious).  Date: Wed, 2 Apr 86 13:52:10 EST From: Jonathan A Rees Subject: begin To: KMP@SCRC-STONY-BROOK.ARPA cc: CPH@MC.LCS.MIT.EDU, RRRS-AUTHORS@MC.LCS.MIT.EDU In-reply-to: Msg of Wed 2 Apr 86 13:32 EST from Kent M Pitman Message-ID: <[MC.LCS.MIT.EDU].870557.860402.JAR> Date: Wed, 2 Apr 86 13:32 EST From: Kent M Pitman I didn't realize this idea of putting definitions in BEGIN was a serious suggestion. Let me repeat myself. I sent the message on April 1. I hoped that the would cue people. It was not a serious suggestion. I strongly oppose having either BEGIN or LET do this. The reason is that it makes it impossible to write code which wants to use these primitives for other things and doesn't have additional implications that may be unwanted or may have implications in macros or program-writing programs that some programmer didn't count on. Too late to get it out of LET and friends, I think. Let's make BEGIN the way to disallow define's, and leave the expansion of LET into ((LAMBDA ...) ...) as simple as it is. As a counter-proposal, how about a LOCALLY special form. ie, (LOCALLY * *) This is sort of what John Ramsdell was suggesting. It's also exists in T and is written (LOCALE #F ...). But I'll appeal to conservatism and say that not only will there not be any agreement on adding or naming this beast, but providing a special form especially for its benefit gives legitimacy to local DEFINE which I don't think most people want. J.  Received: from SCRC-STONY-BROOK.ARPA by MC.LCS.MIT.EDU 2 Apr 86 13:42:10 EST Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 453247; Wed 2-Apr-86 13:32:36-EST Date: Wed, 2 Apr 86 13:32 EST From: Kent M Pitman Subject: begin To: JAR@MIT-MC.ARPA, CPH@MIT-MC.ARPA cc: RRRS-AUTHORS@MIT-MC.ARPA In-Reply-To: <[MC.LCS.MIT.EDU].870519.860402.JAR> Message-ID: <860402133240.3.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM> Date: Wed, 2 Apr 86 13:20:44 EST From: Jonathan A Rees Date: Wed, 2 Apr 1986 12:57 EST From: CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU I don't like the idea of extending BEGIN to allow definitions. ALGOL needed that because it didn't have LET; we don't have that excuse. Then perhaps BEGIN should be caled something else... maybe SEQUENCE or SEQUENTIALLY... I thought it got its name from Algol 60 and therefore should be as much like Algol 60's begin blocks as possible... rememeber that BEGIN in Algol 60 is primarily a binding construct, not a sequencing construct so I thought there was a mismatch of name and functionality here, one or the other should change... don't anyone messages that I send on April 1 seriously. This issue has been beaten to death and it was (& is) in poor taste for me to inflame old wounds again. I'm going to leave BEGIN as it is. Rather than put SEQUENCE in an appendix, I and some others at MIT prefer that it be left in the main part of the report as a non-essential special form, and we want to flush the request that it "not be used in new code". (Today is April 2.) I hope this doesn't bother anyone too strongly. Apparently there's no consensus on any change to local DEFINE, so I'm going to leave it as it is the the RRRS: all the definitions must appear at the beginning; local defines are sugar for LETREC; LETREC binds everything at the top, and does the right-hand side computations and the assignments in an indeterminate order; LETREC permits arbitrary expressions on the right-hand sides; a reference to any of the variables during the evaluation of any of the right-hand sides is an error. Jonathan I didn't realize this idea of putting definitions in BEGIN was a serious suggestion. I strongly oppose having either BEGIN or LET do this. The reason is that it makes it impossible to write code which wants to use these primitives for other things and doesn't have additional implications that may be unwanted or may have implications in macros or program-writing programs that some programmer didn't count on. As a counter-proposal, how about a LOCALLY special form. ie, (LOCALLY * *)  Date: Wed, 2 Apr 86 13:26:24 EST From: Jonathan A Rees Subject: LETREC (REC) To: JINX@OZ.AI.MIT.EDU cc: RRRS-AUTHORS@MC.LCS.MIT.EDU, CPH@OZ.AI.MIT.EDU In-reply-to: Msg of 1 Apr 1986 23:31 EST (Tue) from Bill Rozas Message-ID: <[MC.LCS.MIT.EDU].870526.860402.JAR> Date: 1 Apr 1986 23:31 EST (Tue) From: Bill Rozas Do we have any way in the language to specify "delayed" evaluation except for LAMBDA? I agree DELAY is reasonable also. DELAY and FORCE will be documented (non-essential) in the next report.  Date: Wed, 2 Apr 86 13:20:44 EST From: Jonathan A Rees Subject: begin To: CPH@OZ.AI.MIT.EDU cc: RRRS-AUTHORS@MC.LCS.MIT.EDU Message-ID: <[MC.LCS.MIT.EDU].870519.860402.JAR> Date: Wed, 2 Apr 1986 12:57 EST From: CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU I don't like the idea of extending BEGIN to allow definitions. ALGOL needed that because it didn't have LET; we don't have that excuse. Then perhaps BEGIN should be caled something else... maybe SEQUENCE or SEQUENTIALLY... I thought it got its name from Algol 60 and therefore should be as much like Algol 60's begin blocks as possible... rememeber that BEGIN in Algol 60 is primarily a binding construct, not a sequencing construct so I thought there was a mismatch of name and functionality here, one or the other should change... don't anyone messages that I send on April 1 seriously. This issue has been beaten to death and it was (& is) in poor taste for me to inflame old wounds again. I'm going to leave BEGIN as it is. Rather than put SEQUENCE in an appendix, I and some others at MIT prefer that it be left in the main part of the report as a non-essential special form, and we want to flush the request that it "not be used in new code". (Today is April 2.) I hope this doesn't bother anyone too strongly. Apparently there's no consensus on any change to local DEFINE, so I'm going to leave it as it is the the RRRS: all the definitions must appear at the beginning; local defines are sugar for LETREC; LETREC binds everything at the top, and does the right-hand side computations and the assignments in an indeterminate order; LETREC permits arbitrary expressions on the right-hand sides; a reference to any of the variables during the evaluation of any of the right-hand sides is an error. Jonathan  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 2 APR 86 12:57:31 EST Date: Wed, 2 Apr 1986 12:57 EST Message-ID: From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU To: Jonathan A Rees Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: begin In-reply-to: Msg of 1 Apr 1986 23:51-EST from Jonathan A Rees I don't like the idea of extending BEGIN to allow definitions. ALGOL needed that because it didn't have LET; we don't have that excuse. I think that this would cause widespread use of the (to me) most objectionable form of local DEFINE, that is, use of DEFINE where LET is more appropriate. I have stated my position on this: local DEFINE should be a fossil preserved explicitly for S&ICP, just as SEQUENCE is. Given this position, it seems unwise to alter other parts of the language to accomodate local DEFINE. As yet no one except Jinx has responded to me. Instead, the discussion on DEFINE continues to extend itself into ever-new realms of complexity. To those of you who seem to need DEFINE: please at least give me some argument in favor of local DEFINE rather than just ignoring me.  Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 2 Apr 86 03:19:23 EST Received: from tektronix by csnet-relay.csnet id ag28242; 2 Apr 86 2:48 EST Received: by tektronix (5.31/5.14) id AA11753; Tue, 1 Apr 86 11:03:57 PST Received: by tekchips (5.31/5.14) id AA24444; Tue, 1 Apr 86 11:04:18 PST Message-Id: <8604011904.AA24444@tekchips> To: ANDY@su-sushi.ARPA Cc: rrrs-authors@mc.lcs.mit.edu Subject: Re: immutable structures In-Reply-To: Your message of Mon 31 Mar 86 10:07:51-PST. <12195136917.17.ANDY@SU-SUSHI.ARPA> Date: 01 Apr 86 11:04:11 PST (Tue) From: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Andy Freeman writes: Immutable cons structures bother me. Every other immutable structure in Scheme has a distinct reader syntax. I think the idea is that QUOTE would mark structures as immutable. ...Would someone please enlighten me and justify immutable quoted structures without resorting to "[some] formal system is cleaner without distinguishing them" as the best reason? There may be some formal systems that are made cleaner by making quoted structures immutable, but the denotational semantics certainly becomes more complex. I think immutable pairs are motivated by the fact that in many systems side effects to quoted list structure alter the source code, particularly when the code is interpreted rather than compiled. This can make it hard to debug, so the implementors want to discourage such side effects by calling them "errors". If, on the other hand, side effects to quoted structure don't alter the source code, then people get even more confused, as when a procedure whose source code is (lambda (flag) (let ((x '(a))) (if flag (car x) (whiznagle x)))) returns 97 when passed a true argument. Peace, Will  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 2 APR 86 00:10:59 EST Date: 1 Apr 1986 23:31 EST (Tue) Message-ID: From: Bill Rozas To: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Cc: Bill Rozas , RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: LETREC (REC) In-reply-to: Msg of 1 Apr 1986 23:10-EST from CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU Do we have any way in the language to specify "delayed" evaluation except for LAMBDA? I agree DELAY is reasonable also.  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 2 APR 86 00:10:57 EST Date: Tue, 1 Apr 1986 23:10 EST Message-ID: From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU To: Bill Rozas Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: LETREC (REC) In-reply-to: Msg of 31 Mar 1986 19:59-EST from Bill Rozas I think that restricting LETREC to only procedures is slightly excessive -- one should also be allowed to use delayed (call-by-need or call-by-name) thunks since these are also useful and do not allow any of the cases that I think you object to.  Date: Tue, 1 Apr 86 23:51:08 EST From: Jonathan A Rees Subject: begin To: RRRS-AUTHORS@MC.LCS.MIT.EDU Message-ID: <[MC.LCS.MIT.EDU].869376.860401.JAR> One more thing... I want to change the syntax of BEGIN as follows: ::= (begin ) ::= * + ::= end | This is for compatibility with Algol 60, which allows declarations at the beginning of begin...end blocks, and ends them with END. (sequence ...) of course would only do the sequential execution part of this, like ; in Algol 60, so it wouldn't allow definitions. So sequence could be used like progn 'compile is in Maclisp. Jonathan  Date: Tue, 1 Apr 86 21:42:41 EST From: Jonathan A Rees Subject: changes To: RRRS-AUTHORS@MC.LCS.MIT.EDU Message-ID: <[MC.LCS.MIT.EDU].869021.860401.JAR> I intend to add all the hyperbolic trig functions to Scheme. Also, the gamma function, Bessel functions, and Legendre polynomials. I use these all the time and don't know how anyone gets by without them. I think Scheme numbers are really ad hoc. The ring should be a required argument to +, *, etc. so that they know where the answer should come from. (E.g. (+ 4 7 (MOD Z 5)) ==> 1.) Scheme should support arithmetic mod N, polynomial arithmetic, and arithmetic in arbitrary algebraic number fields. Complex number fall out as a special case: (SQRT -1 (MOD (POLY R) (LAMBDA (X) (+ (* X X) 1 R)))) ==> 1i This should be easy to implement. I don't see why we need all these random special forms. For example, there's no need to have QUOTE or LAMBDA. We can write (SET! (X Y Z) (+ X (* Y Z N) N)) instead of (LAMBDA (X Y Z) (+ X (* Y Z N) N)). No ambiguity will result because if the first thing is a list then obviously the expression can't be an assignment. Similarly, we should be writing (SET! (D #(A (B C) 4))) instead of (QUOTE (D #(A (B C) 4))) because what would one-argument SET! mean? I don't understand why there's no existential quantifer in Scheme. For example, I often find myself wanting to write (EXISTS (X) (AND (MEMQ X L1) (MEMQ X L2))) to find out whether the lists L1 and L2 intersect. If we have first-class continuations I don't see any reason why we shouldn't have first-class stores also. E.g. (LET ((Z (CONS 1 2))) (CALL-WITH-CURRENT-STORE (LAMBDA (S) (SET-CAR! Z 3) (LIST (CAR Z) (S (LAMBDA () (CAR Z))))))) ==> (3 1) And while we're on the subject of modules, why don't we just adopt Common Lisp's package system wholesale? It's really useful and elegant. Also Zetalisp's LOOP construct is really good. I'll put all these features in the report (Penguin Books has already expressed interest, by the way) unless people send me enough money. Modestly, Jonathan Rees Editor  Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 1 Apr 86 13:45:25 EST Received: from indiana by csnet-relay.csnet id ac21966; 1 Apr 86 13:27 EST Date: Tue, 1 Apr 86 10:33:41 est From: Kent Dybvig To: RRRS-AUTHORS@mc.lcs.mit.edu Subject: Case Sensitivity I am most concerned about the system taking a mixed-case program and printing it all in one case (e.g., during debugging, editing or pretty-printing). I would be willing (with reluctance) to allow systems to treat HitMe and HITME as the same identifier. It is not impossible to have a system that retains symbols as the user types them yet treats two symbols differing only in case as the same identifier, it is just difficult and probably not worth the effort. Unless I have convinced everyone to be case-sensitive, I would like the RRRS not to specify one way or another. I prefer the first of Jonathan's solutions: 1. It's OK to write it, but only programs (and data files) which don't care one way or the other (using lower case for the things in the manual, and don't depend on EITHER (eq? 'foo 'Foo) or (not (eq? 'foo 'Foo))), will be portable.  Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 1 Apr 86 13:44:43 EST Received: from indiana by csnet-relay.csnet id a021966; 1 Apr 86 13:26 EST Date: Tue, 1 Apr 86 09:59:12 est From: Kent Dybvig To: JAR@mc.lcs.mit.edu Subject: Re: small changes Cc: RRRS-AUTHORS@mc.lcs.mit.edu If you insist on going counter to the Brandeis decision, making your implementation and book case-sensitive, ... My system (Chez Scheme) and book (on Scheme programming, with Bruce Smith of UNC) will not go counter to any Brandeis decision, unless, of course, the change is incorporated into the RRRS. Why would I bother spending all this time dealing with this stuff if I planned to ignore the RRRS anyway? I may be stubborn but I'm not stupid.  Received: from ZERMATT.LCS.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 1 APR 86 12:04:29 EST Received: from ASPEN.LCS.MIT.EDU by MIT-ZERMATT.ARPA via CHAOS with CHAOS-MAIL id 29860; Tue 1-Apr-86 12:04:18-EST Date: Tue, 1 Apr 86 12:03 EST From: Robert Halstead Subject: meaning of local define To: JINX@OZ.AI.MIT.EDU cc: JAR@MIT-MC.ARPA, RRRS-AUTHORS@MIT-MC.ARPA In-Reply-To: Message-ID: <860401120334.3.RHH@ASPEN.LCS.MIT.EDU> ... (define (quux x) (* x x)) (define (foo y) (define bar (quux y)) (define (quux x) (* x x x)) (quux y)) ... 3) It is an error because the definitions occur all in parallel but the values are assigned sequentially, and thus QUUX is bound but not assigned on first use. This is what MIT Scheme does currently (and used to do for top level). Multilisp has adopted a position which is a superset of this. I'm not terribly strongly attached to it, but I think it is pragmatic given that none of the alternatives is wonderfully appealing. DEFINEs are allowed to appear anywhere at the "top level" (which includes possibly being nested inside BEGINs) of a "variable-binding form" (which means lambda bodies, let bodies, and the like). They may be interspersed with other non-DEFINE forms -- in other words, they don't have to all be collected at the beginning of a body. The meaning of DEFINEs is specified by the following (operationally stated) rule: all variables named in DEFINEs at the top level of a particular body are bound to unassigned values on entry to that body, and the DEFINEs themselves are changed to SET!s and left where they are in the body. This implies a little more work for a compiler or interpreter than the current RRRS position, but I don't think it's really much uglier since even the current RRRS stance allows arbitrary computations to occur in calculating the values to be bound to some DEFINEd variables without waiting for all the variables' values to have been assigned. I think we should decide if we want DEFINE merely for compatibility with S&ICP (in which case we should scan the book & find out the minimal semantically appealing definition that will work for all the examples given) or whether we would put DEFINE in the Scheme standard even if S&ICP didn't mention it (in which case a debate about more "powerful" versions is appropriate). I tend toward a theory that essential Scheme should only include the minimum required for S&ICP to work. But I'll confess I still find it a muddle to know how to proceed from that decision.  Received: from yale-bulldog by MC.LCS.MIT.EDU 1 Apr 86 10:20:45 EST Received: by Yale-Bulldog.YALE.ARPA; 1 Apr 86 10:07:04 EST (Tue) Date: 1 Apr 86 10:07:04 EST (Tue) From: Richard Kelsey Message-Id: <8604011507.AA03682@Yale-Bulldog.YALE.ARPA> Subject: #t, #f, and (BEGIN) To: JAR@MIT-MC.ARPA Cc: RRRS-AUTHORS@MIT-MC.ARPA Two votes: I much prefer #t and #f over #!true and #!false. I also think that (BEGIN) and (LAMBDA (X)) should not be allowed. -Richard Kelsey -------  Received: from ZERMATT.LCS.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 1 APR 86 09:49:38 EST Received: from ASPEN.LCS.MIT.EDU by MIT-ZERMATT.ARPA via CHAOS with CHAOS-MAIL id 29836; Tue 1-Apr-86 09:49:25-EST Date: Tue, 1 Apr 86 09:48 EST From: Robert Halstead Subject: #t and #f To: JAR@MIT-MC.ARPA cc: RRRS-AUTHORS@MIT-MC.ARPA In-Reply-To: <[MC.LCS.MIT.EDU].865699.860329.JAR> Message-ID: <860401094840.2.RHH@ASPEN.LCS.MIT.EDU> I like #t and #f, and I'm even at MIT! -b.  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 1 APR 86 09:48:09 EST Date: 1 Apr 1986 09:47 EST (Tue) Message-ID: From: Bill Rozas To: Ken Haase Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: LETREC (REC) In-reply-to: Msg of 1 Apr 1986 08:19-EST from Ken Haase Certainly when binding non-procedures, the use of LETREC is ugly and ill-defined Unfortunately it is not ill defined. A simple "operational" description (like the one in the currentl version of RRRS) describes what is legal and what is not. I view this operational description as a crock, and the only way that I can see to restrict the use of LETREC to reasonable cases is to "over-restrict" it. The problem is that it is hard to decide when to stop. The boundary is fuzzy, but I'd be much happier with the restriction than with the current semantics. Here foo is being bound to a non-lambda expression one of whose arguments is a lambda-expression which calls foo. I think this is perfectly reasonable, as long as the recursive reference only occurs within defining forms like lambda; and if it doesn't there's already an error to handle the case (unbound identifier). If we start along these lines, what happens to macros that expand into lambdas? What if we use the definition of begin in RABBIT? Constraining it to "defining" forms is not enough, the lambda expressions must not be invoked until after all the expressions have been evaluated, but this is too complicated. Note that the error is not unbound variable. The variable is bound, since the expressions are evaluated in an environment where the names are bound. At best it is unassigned, but this implies that there are side effects going on, which I don't like.  Received: from AI.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 1 APR 86 08:19:50 EST Date: Tue, 1 Apr 86 08:19:07 EST From: Ken Haase Subject: LETREC (REC) To: JINX@OZ.AI.MIT.EDU cc: RRRS-AUTHORS@MC.LCS.MIT.EDU In-reply-to: Msg of 31 Mar 1986 19:59 EST (Mon) from Bill Rozas Message-ID: <[AI.AI.MIT.EDU].22994.860401.KWH> I'd like to defend the use of non-lambda expressions in LETREC; lambda is only one of the function specifying forms a user may wish to invoke. If a programmer uses a lot of higher order functions in specifying her programs, it seems completely reasonable for her to be able to use these forms for recursive definitions. Certainly when binding non-procedures, the use of LETREC is ugly and ill-defined; but when binding procedures it seems perfectly consistent and nice to have. Consider the following code: (define (when test result) (lambda (x) (if (test x) x (result x)))) (define (iterate n action) (letrec ((foo (until zero? (lambda (x) (print x) (foo x))))) (foo n))) Here foo is being bound to a non-lambda expression one of whose arguments is a lambda-expression which calls foo. I think this is perfectly reasonable, as long as the recursive reference only occurs within defining forms like lambda; and if it doesn't there's already an error to handle the case (unbound identifier). Ken  Received: from SCRC-STONY-BROOK.ARPA by MC.LCS.MIT.EDU 1 Apr 86 02:25:20 EST Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 451612; Tue 1-Apr-86 02:19:54-EST Date: Tue, 1 Apr 86 02:22 EST From: Kent M Pitman Subject: New special forms -- CALL and VAR (or some such) To: RRRS-AUTHORS@MIT-MC.ARPA Message-ID: <860401022221.7.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM> I find the presentation of special forms very clumsy. I believe that it would be much smoother if we would introduce two new special forms. I call them VAR and CALL. Jonathan points out that the VAR special form was effectively in the original (unrevised) SCHEME report as the STATIC special form. In any case, the idea would be that (VAR X) is the same as X in a program. (CALL X . args) would be the same as (X . args) where X didn't name a special form. I'm susceptible to other names. eg, VARIABLE-REFERENCE is a fine alternative for VAR. FUNCTION-CALL, COMPOSITION, or FUNCTION-COMPOSITION are ok for CALL. The main point is that it should be possible to define the language completely in terms of special forms. eg, we first introduce expressions that look like: (LAMBDA (X Y) (CALL (VAR +) (VAR X) (VAR Y))) and then introduce abbreviations for VAR and CALL forms such that (LAMBDA (X Y) (+ X Y)) means the same thing. The result is that when describing evaluable expressions you don't have to disjoin into (keyword . ...) and (fn . ...). Instead, you get a fair amount of mileage in the initial exposition out of just saying that there are only special forms, and then relaxing the description. Early T had these primitives, and I thought they made my first T manual look nicer, but they seem to have gotten lost over time. Anyway, does anybody buy this idea? --- Text that follows is just for fun and not part of the above proposal --- By the way, in the early T it was even possible to write: (LAMBDA (0 1) (CALL (VAR +) (VAR 0) (VAR 1))) or (LAMBDA (0 1) (+ (VAR 0) (VAR 1))) ie, you could have non-symbol variable names. This got lost at some point, but I still think this was kinda fun. As a hack, I even wrote things like: (DEFINE (GENSYM) (LET ((CELL (LIST 'VAR NIL))) (SET (CADR CELL) CELL) CELL)) (DEFINE FOO (LET ((V1 (GENSYM)) (V2 (GENSYM))) (ENCLOSE `(LAMBDA (,V1 ,V2) (+ ,V1 ,V2))))) (FOO 1 2) => 3 The reason for the CADR-circular result of GENSYM may not be completely obvious on first glance. I think it's the only way to satisfy the relevant constraints, though. I certainly won't try to argue that this was the "right thing", but it certainly struck me as novel. Hope some of you find it amusing...  Received: from SCRC-STONY-BROOK.ARPA by MC.LCS.MIT.EDU 1 Apr 86 02:10:50 EST Received: from RIO-DE-JANEIRO.SCRC.Symbolics.COM by SCRC-STONY-BROOK.ARPA via CHAOS with CHAOS-MAIL id 451605; Tue 1-Apr-86 02:05:34-EST Date: Tue, 1 Apr 86 02:08 EST From: Kent M Pitman Subject: Scheme BNF To: gls%aquinas@THINK.ARPA, JAR@MC.LCS.MIT.EDU, willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA cc: RRRS-AUTHORS@MC.LCS.MIT.EDU In-Reply-To: <860331111447.3.GLS@GUIDO.THINK.COM> Message-ID: <860401020800.6.KMP@RIO-DE-JANEIRO.SCRC.Symbolics.COM> Date: Mon, 31 Mar 86 11:14 EST From: Guy Steele Date: Sat, 29 Mar 86 17:41:34 EST From: Jonathan A Rees ... But in order to allow (BEGIN) to work, we have to add an exception to the description "BEGIN evaluates the forms sequentially, and returns the value of the last form" - you have to say "...except that if there are no forms, the value is unspecified". I have written interpreters and compilers that deal with (BEGIN) and they always have an extra conditional in them to be able to deal with that as a special case. ... The problem is with the form of the English; it blithely assumes that there is a last form. This is actually a fencepost error; we should focus on the spaces between the forms, and not the forms themselves. After the word BEGIN there is an , and after each subform the value of that form appears. BEGIN forms a sequence r of the value and the values of all the forms, and then returns (reduce #'(lambda (x y) y) r). Clear? I second GLS's motion to make (BEGIN) and (LAMBDA ()) legal. The problem is no worse than explaining why (AND) and (OR) are valid. This same issue has come up in a number of Lisp dialects I've worked with. I've never had a need for (BEGIN), (LAMBDA ()), etc. in a situation where I cared about the value, so I'd be quite happy to leave the value undefined as long as side-effects happen correctly. The situation where it comes up a lot is in program-writing programs. I end up writing: `(LAMBDA () ,@(IF (NOT THE-FORMS) '(NIL) THE-FORMS)) when I wish I could write: `(LAMBDA () ,@THE-FORMS)  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 31 MAR 86 20:00:53 EST Date: 31 Mar 1986 19:59 EST (Mon) Message-ID: From: Bill Rozas To: Bill Rozas Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: LETREC (REC) In-reply-to: Msg of 31 Mar 1986 19:45-EST from Bill Rozas As you probably know by now, there is a feature that I REALLY dislike about LETREC (REC), namely that LETREC allows non-lambda expressions in the binding list. I would like to make this optional and make the standard allow only lambda expressions. Is there a lot of opposition to this? I realize that it may be too late for this, and should probably have objected very strongly at last year's meeting, but I've thought a lot about the issue since then and I am becoming progressively more upset with the way it is now.  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 31 MAR 86 19:46:26 EST Date: 31 Mar 1986 19:45 EST (Mon) Message-ID: From: Bill Rozas To: Jonathan A Rees Cc: gls@AQUINAS.THINK.COM, LS.JINX%DEEP-THOUGHT.MIT.EDU@XX.LCS.MIT.EDU, RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: meaning of local define In-reply-to: Msg of 31 Mar 1986 13:53-EST from Jonathan A Rees Am I confused! I don't understand why good style allows global DEFINE to be used to define things other than procedures, but not local DEFINE. It seems to me that in general one ought to be able to use the same construct in the same way no matter where it appears. Call this principle "stylistic transparency". Am I confused? I agree with this... I guess this is why I thought it might be better to allow define's to be interspersed with other expressions in lambda-bodies, and saying they're evaluated sequentially, for uniformity with "top level". The problem is this: In the following (horrible) code (define (quux x) (* x x)) (define (foo y) (define bar (quux y)) (define (quux x) (* x x x)) (quux y)) We have various options: 1) The first reference to QUUX gives the value of the outer QUUX and the second gives the value of the inner QUUX since the inner one has not been defined yet. This is what the interpreter in chapter 4 of S&ICP does. This seems very ugly since it implies one of 2 things: - Definitions modify environments to have new bindings. The definition causes a side effect to the environment where it occurs. This is pretty ugly. - Definitions create new environments where the rest of the expressions are evaluated. This has clear problems with mutual recursion. 2) Both references result in the inner QUUX since the DEFINEs are equivalent to a LETREC, and there exists an order in which the definitions can be evaluated which gives this result. This would be easy to arrange if Scheme were evaluated in normal order, but hard (in general) given that it is applicative order. 3) It is an error because the definitions occur all in parallel but the values are assigned sequentially, and thus QUUX is bound but not assigned on first use. This is what MIT Scheme does currently (and used to do for top level). I would like 2 to hold, but it unfortunately does not. Making 3 the official semantics would be like specifying an order of argument evaluation which people would then take advantage of. Restricting the values to be lambda expressions guarantees that the result does not depend on the order of evaluation, while attempting to extend this (constants, expressions which depend only on outer variables, etc.) gets us into a sort of operational semantics. The sort of thing CPH and I are trying to avoid is the same thing that I (we ?) abhor about the definition of REC and LETREC, namely that (rec a (cons 3 a)) does not work, while (rec a (cons 3 (lambda () a))) does. We are making the implementation visible in the language definition. BTW, I restrict my use of top level DEFINE so that it does not depend in the potential sequentiality of evaluation.  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 31 MAR 86 18:43:20 EST Date: 31 Mar 1986 18:42 EST (Mon) Message-ID: From: Bill Rozas To: Jonathan A Rees Cc: gls@AQUINAS.THINK.COM, RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: (BEGIN) In-reply-to: Msg of 31 Mar 1986 13:57-EST from Jonathan A Rees I agree with you. I don't think (BEGIN) or (LAMBDA (X)) should be allowed.  Date: Mon, 31 Mar 86 13:59:45 EST From: Jonathan A Rees Subject: Denotational semantics for SIGPLAN? To: ramsdell%linus@MITRE-BEDFORD.ARPA cc: RRRS-AUTHORS@MC.LCS.MIT.EDU In-reply-to: Msg of Mon 31 Mar 86 07:03:58 est from John D. Ramsdell Message-ID: <[MC.LCS.MIT.EDU].867082.860331.JAR> Date: Mon, 31 Mar 86 07:03:58 est From: John D. Ramsdell Are there plans to include a semantic description of Scheme in the SIGPLAN report? If the denotational semantics is completed, I would very much like to see Scheme presented with it. Yes, it's in the works.  Date: Mon, 31 Mar 86 13:57:02 EST From: Jonathan A Rees Subject: (BEGIN) To: gls@AQUINAS.THINK.COM cc: RRRS-AUTHORS@MC.LCS.MIT.EDU In-reply-to: Msg of Mon 31 Mar 86 11:14 EST from Guy Steele Message-ID: <[MC.LCS.MIT.EDU].867079.860331.JAR> Date: Mon, 31 Mar 86 11:14 EST From: Guy Steele ... See? No special cases. OK, I don't feel strongly, and I haven't heard anyone but me speak up against allowing (BEGIN) and (LAMBDA (X)) and things like that. So I guess that unless the debate heats up again I'll change the report.  Date: Mon, 31 Mar 86 13:53:30 EST From: Jonathan A Rees Subject: meaning of local define To: gls@AQUINAS.THINK.COM cc: RRRS-AUTHORS@MC.LCS.MIT.EDU, LS.JINX@DEEP-THOUGHT.MIT.EDU In-reply-to: Msg of Mon 31 Mar 86 10:34 EST from Guy Steele Message-ID: <[MC.LCS.MIT.EDU].867067.860331.JAR> Date: Mon, 31 Mar 86 10:34 EST From: Guy Steele Am I confused! I don't understand why good style allows global DEFINE to be used to define things other than procedures, but not local DEFINE. It seems to me that in general one ought to be able to use the same construct in the same way no matter where it appears. Call this principle "stylistic transparency". Am I confused? I agree with this... I guess this is why I thought it might be better to allow define's to be interspersed with other expressions in lambda-bodies, and saying they're evaluated sequentially, for uniformity with "top level". As another example of this, one of the things currently distressing some users of Common Lisp is that (let ((seed (get-universal-time))) (defun random (n) (setq seed (random-mungicate seed)) (random-result seed n))) doesn't compile properly in all Common Lisp implementations because of ad hoc restrictions on where DEFUN is recognized. In spite of the wishes of many, we're not able at this point to change define's from being local to being global (like in T, Common Lisp, and some others dialects, I think), which would be one way to get rid of ad hoc restrictions. Another fix would be to allow local define's to appear anywhere, like in some versions of MIT Scheme, but this is hard to implement well and at least as confusing as restricting the contexts in which they're available. So I think we're stuck with the context restrictions. It's implicit in the RRRS that definitions aren't expressions, and I'm changing the prose for the R^3RS (?) to make this even clearer; see also the BNF I sent out. I admit this is more complex, and arguably ad hoc, but I am hoping that changing the report to emphasize that define's aren't expressions will help make them seem not ad hoc; the restrictions will be up front. Jonathan  Received: from SU-SUSHI.ARPA by MC.LCS.MIT.EDU 31 Mar 86 13:09:58 EST Date: Mon 31 Mar 86 10:07:51-PST From: Andy Freeman Subject: immutable structures To: rrrs-authors@MC.LCS.MIT.EDU Message-ID: <12195136917.17.ANDY@SU-SUSHI.ARPA> Immutable cons structures bother me. Every other immutable structure in Scheme has a distinct reader syntax. (I think numbers and symbols are the only ones although strings are occasionally candidates. BTW - I think that would be a mistake. Anyone have a use for immutable strings that can't be satisfied by symbols?) Even if the necessary immutable-cons? predicate is added to RRRS, that lack is fatal. I'm reasonably convinced that there is a fundamental difference between cons structures and numbers. Would someone please enlighten me and justify immutable quoted structures without resorting to "[some] formal system is cleaner without distinguishing them" as the best reason? (Since Scheme procedures have state, mutable quoted structures are merely syntactic sugar.) -andy -------  Received: from GODOT.THINK.COM by MC.LCS.MIT.EDU 31 Mar 86 11:18:39 EST Received: from guido by GODOT.THINK.COM via CHAOS; Mon, 31 Mar 86 10:32:46 est Date: Mon, 31 Mar 86 10:34 EST From: Guy Steele Subject: meaning of local define To: LS.JINX@DEEP-THOUGHT.MIT.EDU, JAR@MC.LCS.MIT.EDU Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU, gls@THINK-AQUINAS.ARPA In-Reply-To: Message-Id: <860331103424.1.GLS@GUIDO.THINK.COM> Am I confused! I don't understand why good style allows global DEFINE to be used to define things other than procedures, but not local DEFINE. It seems to me that in general one ought to be able to use the same construct in the same way no matter where it appears. Call this principle "stylistic transparency". Am I confused? As another example of this, one of the things currently distressing some users of Common Lisp is that (let ((seed (get-universal-time))) (defun random (n) (setq seed (random-mungicate seed)) (random-result seed n))) doesn't compile properly in all Common Lisp implementations because of ad hoc restrictions on where DEFUN is recognized. --Guy  Received: from GODOT.THINK.COM by MC.LCS.MIT.EDU 31 Mar 86 11:14:32 EST Received: from guido by GODOT.THINK.COM via CHAOS; Mon, 31 Mar 86 11:13:06 est Date: Mon, 31 Mar 86 11:14 EST From: Guy Steele Subject: Scheme BNF To: JAR@MC.LCS.MIT.EDU, willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU, gls@THINK-AQUINAS.ARPA In-Reply-To: <[MC.LCS.MIT.EDU].865763.860329.JAR> Message-Id: <860331111447.3.GLS@GUIDO.THINK.COM> Date: Sat, 29 Mar 86 17:41:34 EST From: Jonathan A Rees ... But in order to allow (BEGIN) to work, we have to add an exception to the description "BEGIN evaluates the forms sequentially, and returns the value of the last form" - you have to say "...except that if there are no forms, the value is unspecified". I have written interpreters and compilers that deal with (BEGIN) and they always have an extra conditional in them to be able to deal with that as a special case. ... The problem is with the form of the English; it blithely assumes that there is a last form. This is actually a fencepost error; we should focus on the spaces between the forms, and not the forms themselves. After the word BEGIN there is an , and after each subform the value of that form appears. BEGIN forms a sequence r of the value and the values of all the forms, and then returns (reduce #'(lambda (x y) y) r). Clear? To render this as a DO loop: (define (interpret-begin begin-form environment) (do ((forms (cdr begin-form) (cdr forms)) (result (interpret-form (car forms) environment))) ((null forms) result))) See? No special cases. --Guy  Received: from mitre-bedford.ARPA by MC.LCS.MIT.EDU 31 Mar 86 07:04:24 EST Organization: The MITRE Corp., Bedford, MA Received: by linus.MENET (4.12/4.7) id AA12710; Mon, 31 Mar 86 07:03:58 est Date: Mon, 31 Mar 86 07:03:58 est From: John D. Ramsdell Posted-Date: Mon, 31 Mar 86 07:03:58 est Message-Id: <8603311203.AA12710@linus.MENET> To: rrrs-authors@mit-mc.ARPA Subject: Denotational semantics for SIGPLAN? Are there plans to include a semantic description of Scheme in the SIGPLAN report? If the denotational semantics is completed, I would very much like to see Scheme presented with it. John P.S. In my opinion: 1) #t and #f are preferable over #!true and #!false. 2) Its good to include the boolean? predicate. 3) Local defines should be an alternate syntax for LETREC as advocated by Bill.  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 30 MAR 86 22:28:46 EST Date: 30 Mar 1986 22:28 EST (Sun) Message-ID: From: Bill Rozas To: Jonathan A Rees Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: [dfried%indiana.csnet: boolean?] In-reply-to: Msg of 30 Mar 1986 16:12-EST from Jonathan A Rees boolean? sounds fine to me.  Date: Sun, 30 Mar 86 16:12:06 EST From: Jonathan A Rees Subject: [dfried%indiana.csnet: boolean?] To: RRRS-AUTHORS@MC.LCS.MIT.EDU Message-ID: <[MC.LCS.MIT.EDU].866290.860330.JAR> I have thought of suggesting the following feature, which T has and which is nice to have occasionally, and is pleasantly symmetrical with the other type predicates like NUMBER?, SYMBOL?, PAIR?, etc. I haven't suggested it so far because of its marginal usefulness, but would be happy to put it in if other people think it's a good idea. Opinions? (Dan, I assume you meant #t instead of $t.) - Jonathan Date: Sun, 30 Mar 86 11:49:51 est From: Dan Friedman To: jar at mc.lcs.mit.edu Re: boolean? If # is used in the first position of the true and false value, might I suggest the existence of a predicate boolean? This predicate returns #t if its single argument is #t or #f. Dan  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 30 MAR 86 11:56:44 EST Date: Sun, 30 Mar 1986 11:53 EST Message-ID: From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU To: Jonathan A Rees Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: NAMED-LAMBDA, REC, DEFINE In-reply-to: Msg of 29 Mar 1986 20:19-EST from Jonathan A Rees Date: Saturday, 29 March 1986 20:19-EST From: Jonathan A Rees Date: Sat, 29 Mar 1986 16:53 EST From: CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU So I would like to retract my earlier statement in support of the simpler semantics. One man's simple is another's complex... could you be more precise? Which one do you like now? And the winner is... Alternative A (Norman's and mine and S&ICP's): (define (foo . rest) . body) means the same thing as (define foo (lambda rest . body))  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 30 MAR 86 00:42:52 EST Date: 30 Mar 1986 00:42 EST (Sun) Message-ID: From: Bill Rozas To: Jonathan A Rees Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: (EQV? '(A) '(A)) In-reply-to: Msg of 29 Mar 1986 23:13-EST from Jonathan A Rees Why should non-constant-time behavior be desirable for numbers, but desirable for lists? Immutable structured data with identical components are "operationally identical", and I'm endeavoring to make EQV? a close approximation to the operationally-identitical relation. As far as I know = always terminates and is rather efficient (linear in the size of the numbers in bits?). You are suggesting that we make EQV? work like EQUAL? on immutable lists, but this has a problem: 1) The fast, simple definition fails on circular structure. Agreed that there is no way in the standard to have immutable circular structure, but this seems like a simple compatible extension which people might want to make. It would then be bad if EQV? were not to terminate on immutable objects. 2) The only implementations of EQUAL? which handle circular structure correctly that I know of are very expensive (much worse than linear). This would make EQV? unusable in many cases, but we are trying to encourage its use over EQ?. I'm not saying I necessarily disagree with your suggestion, but I need more time to think about it before I agree. PS: If you have an efficient implementation of EQUAL? which handles circular structure, I would appreciate your sending it to me.  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 30 MAR 86 00:24:19 EST Date: 30 Mar 1986 00:24 EST (Sun) Message-ID: From: Bill Rozas To: Jonathan A Rees Cc: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU, RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: meaning of local define In-reply-to: Msg of 29 Mar 1986 16:57-EST from Jonathan A Rees I also thought that local DEFINE's were supposed to be "like top level ones," which are done sequentially At some point in time (I don't remember what it currently does) MIT Scheme collected top level defines and did them all at once (with unassigned values, to detect use before the new value is assigned) before running any code (the defines afterwards being treated as assignments), thus treating top level define and local define similarly. The only sequentiality inherent in top level define comes from interaction, namely that some code can be run before all defines are apparent. I don't view this as a difference between both. My BNF, and the current RRRS, say that DEFINE's can't occur in BEGIN's; The only problem is the same that originally gave us (progn 'compile ...) in MacLisp, namely macro expansion. Since we do not have macros in the standard this is moot probably.  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 30 MAR 86 00:15:31 EST Date: 30 Mar 1986 00:15 EST (Sun) Message-ID: From: Bill Rozas To: Jonathan A Rees Cc: dyb%indiana.csnet@CSNET-RELAY.ARPA, RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: small changes In-reply-to: Msg of 29 Mar 1986 16:48-EST from Jonathan A Rees I don't mind #t #f (#T #F). I think that #!true and #!false are merely long, not necessarily ugly. I would even be willing to say that SYMBOL->STRING will return lower case, and STRING->SYMBOL will only be guaranteed to accept lower-case letters. Implementations could be permitted to do what they like, even signal an error, if there are upper-case letters. (Case-insensitivity advocates should note that this makes no statement about how print names are to be stored internally, although these particular procedures would presumably be a little more efficient if the internal case of portable identifiers was lower.) I would much rather have a procedure canonicalize-case which takes a string in either case and converts it to the appropriate case. I do not use symbol->string and string->symbol very often, and the extra code to type does not seem like a real burden but would make SYMBOL->STRING cheaper since it could always return the standard case (rather than lower case). MIT Scheme unfortunately (I don't like it) uses upper case internally, but SYMBOL->STRING is basically CAR. Just a comment on my usual style: I write all my code in lower case, but write quoted symbols in upper case. Thus they are more easily distinguishable from identifiers (the quote is easy to miss sometimes), yet I can conveniently type them in lower case (MIT Scheme is insensitive). For example, I would write (define (definition? exp) (and (pair? exp) (eq? 'DEFINE (car exp)))) Which would be true of '(define (definition? exp) (and (pair? exp) (eq? 'DEFINE (car exp)))) I rarely use mixed case in Scheme. I don't mind #t #f (#T #F).  Date: Sat, 29 Mar 86 23:13:44 EST From: Jonathan A Rees Subject: (EQV? '(A) '(A)) To: JINX@MC.LCS.MIT.EDU cc: RRRS-AUTHORS@MC.LCS.MIT.EDU In-reply-to: Msg of 26 Mar 1986 17:11 EST (Wed) from Bill Rozas Message-ID: <[MC.LCS.MIT.EDU].865944.860329.JAR> Date: 26 Mar 1986 17:11 EST (Wed) From: Bill Rozas 2. Should we require (EQV? '(A) '(A)) to return true in implementations which forbid clobbering quoted structure (that would be all implementations, if the answer to 1. is yes)? Although it would be nice, it seems that it has serious implementation consequences: either quoted structure is hash-consed (BTW, what happens them to immutable parts of back-quoted structure?), or EQV? becomes more expensive than it already is. Why should non-constant-time behavior be desirable for numbers, but desirable for lists? Immutable structured data with identical components are "operationally identical", and I'm endeavoring to make EQV? a close approximation to the operationally-identitical relation. The backquoted structure question is a sticky one. Don't know quite what to do about it.  Date: Sat, 29 Mar 86 20:19:43 EST From: Jonathan A Rees Subject: NAMED-LAMBDA, REC, DEFINE To: CPH@OZ.AI.MIT.EDU cc: RRRS-AUTHORS@MC.LCS.MIT.EDU, adams%tekchips%tektronix.csnet@CSNET-RELAY.ARPA In-reply-to: Msg of Sat 29 Mar 1986 16:53 EST from CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU Message-ID: <[MC.LCS.MIT.EDU].865833.860329.JAR> Date: Sat, 29 Mar 1986 16:53 EST From: CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU So I would like to retract my earlier statement in support of the simpler semantics. One man's simple is another's complex... could you be more precise? Which one do you like now? Alternative A (Norman's and mine and S&ICP's): (define (foo . rest) . body) means the same thing as (define foo (lambda rest . body)) Alternative B (RRRS's and MIT Scheme's): (define (foo . rest) . body) means the same thing as (define foo (letrec ((foo (lambda rest . body))) ;or any equivalent syntax foo)) if foo is an identifier, and means the same as (define foo (lambda rest . body)) if foo is of the form (bar . rest). Alternative C: - Jonathan  Date: Sat, 29 Mar 86 20:07:17 EST From: Jonathan A Rees Subject: meaning of local define To: CPH@OZ.AI.MIT.EDU cc: RRRS-AUTHORS@MC.LCS.MIT.EDU In-reply-to: Msg of Sat 29 Mar 1986 17:07 EST from CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU Message-ID: <[MC.LCS.MIT.EDU].865830.860329.JAR> Date: Sat, 29 Mar 1986 17:07 EST From: CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU Date: Saturday, 29 March 1986 16:57-EST From: Jonathan A Rees My BNF, and the current RRRS, say that DEFINE's can't occur in BEGIN's; does anyone have any problem with that? If so, what should it mean? I have a small problem with that: as always, it is necessary to be able to write macros that expand into multiple definitions. So MIT Scheme takes the position that a BEGIN appearing anywhere that a DEFINE may appear is allowed to contain DEFINEs. This seems to solve the problem perfectly adequately, and is very easy to implement. Agreed, but it's also a compatible extension, presumably one added that would be added when macros are, so it doesn't need to be documented. Jonathan.  Date: Sat, 29 Mar 86 18:33:54 EST From: Jonathan A Rees Subject: Scheme BNF To: dyb%indiana.csnet@CSNET-RELAY.ARPA cc: RRRS-AUTHORS@MC.LCS.MIT.EDU Message-ID: <[MC.LCS.MIT.EDU].865782.860329.JAR> Date: Mon, 24 Mar 86 10:39:14 est From: Kent Dybvig I think it should not work on vectors. It makes sense to me only in non- constants, and until we make a firm statement that vectors have some useful meaning in Scheme other than as constants, backquote should not work within vectors. I also have some amount of hesitance about splicing a list into a vector, etc., and what that would mean. The RRRS doesn't say that backquote doesn't work on vectors; I'm only suggesting a clarification. I assume it would work as described in RRRS and as in Common Lisp, which is that the thing returned by form in ,@form must be a list, whose elements are spliced into the vector. I do not like the use of EQUAL?. If you don't like , how about ? Seriously, we need some term anyway, since it is the same thing accepted by EQV?. What about ? Or ? I'm trying to avoid introducing new nonterminals into the grammar, and nothing fits; self-evaluating doesn't work, because strings are self-evaluating and symbols aren't; there's already a for backquote, but it includes strings. Also, it's been said before, but I think we should allow for the optional syntax of a single "" not in a list. ::= ( ) This complicates the grammar, and (() ) is ambiguous. This was discussed at Brandeis, and this version of case was accepted unanimously after a somewhat painful discussion; I'm only trying to make it more precise. - Oh yeah, I forgot to mention in my previous message that I would like to document DELAY and FORCE, as non-essential special form and procedure, respectively. I believe they're non-controversial, and desirable given that they have a central role in S&ICP and are a little tricky to describe and implement. If you don't mind, please send out your prose for these and include the appropriate code for them. I don't have them in Chez Scheme yet and I'm not in the mood to think. There's a description and implementation in Structure & Interpretation. I'll send out my prose with the rest of the manual next week. I am uncomfortable with the use of in light of the existence of sequence as a special form. Why? I chose the term precisely because the term "sequence" was already in use this way. But I'll try to think of something better. Furthermore, I think that + would be more expressive where it appears, and in Scheme there should be no confusion with the operator + or sign +. The + meaning at least one won't be confused with + meaning the character or identifier + because it will be in superscript and in Roman typeface. I was thinking of changing the definition of to be * , to be a little more descriptive, and to emphasize the fact that the last value of a becomes its value. I think this nonterminal improves readability; if I were to get rid of it I'd also want to dispose of and several others. Anyone else have an opinion? Jonathan  Date: Sat, 29 Mar 86 17:41:34 EST From: Jonathan A Rees Subject: Scheme BNF To: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA cc: RRRS-AUTHORS@MC.LCS.MIT.EDU In-reply-to: Msg of 25 Mar 86 12:23:34 PST (Tue) from willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA Message-ID: <[MC.LCS.MIT.EDU].865763.860329.JAR> Date: 25 Mar 86 12:23:34 PST (Tue) From: willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA <[MC.LCS.MIT.EDU].860721.860324.JAR> [Someone (Dybvig maybe?):] Can we also have (BEGIN) return an unspecified value instead of being invalid syntax? [JAR:] I am certainly opposed to this. Care to say why? I should have said more. COND is already complicated with an exception because it says that if no guard returns true and there's no ELSE, then the value is unspecified. People like this because it make COND work well in statement positions where you don't care about the effect anyhow. So, in consequence, (COND) makes sense, without having to say explicitly that (COND) is legal. But in order to allow (BEGIN) to work, we have to add an exception to the description "BEGIN evaluates the forms sequentially, and returns the value of the last form" - you have to say "...except that if there are no forms, the value is unspecified". I have written interpreters and compilers that deal with (BEGIN) and they always have an extra conditional in them to be able to deal with that as a special case. And if I had written the BNF as (BEGIN * ), as I probably should have, that wouldn't have worked. I guess you could make some of the same arguments here that you do to allow (COND); programs which generate Scheme programs might know that the thing they're generating is a list of statements to be put in a statement position, so they might reasonably want to generate (BEGIN). But I hate exceptions and unnecessary conditionals. The COND exception seems unavoidable, and to disallow (COND) we'd need an exception in the form of a rationale explaining why it was disallowed even though its semantics is clear; but a (BEGIN) exception does seem avoidable and unnecessary. I guess I don't care as much about this as I thought I did. By the way: (COND) and (CASE x) are not disallowed by the textual description in the RRRS, they're only disallowed because the prototype lines say (COND clause1 clause2 ...) instead of (COND clause1 ...). The first means one or more, the second would mean zero or more. Jonathan  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 29 MAR 86 17:07:20 EST Date: Sat, 29 Mar 1986 17:07 EST Message-ID: From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU To: Jonathan A Rees Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: meaning of local define In-reply-to: Msg of 29 Mar 1986 16:57-EST from Jonathan A Rees Date: Saturday, 29 March 1986 16:57-EST From: Jonathan A Rees My BNF, and the current RRRS, say that DEFINE's can't occur in BEGIN's; does anyone have any problem with that? If so, what should it mean? I have a small problem with that: as always, it is necessary to be able to write macros that expand into multiple definitions. So MIT Scheme takes the position that a BEGIN appearing anywhere that a DEFINE may appear is allowed to contain DEFINEs. This seems to solve the problem perfectly adequately, and is very easy to implement.  Date: Sat, 29 Mar 86 16:57:33 EST From: Jonathan A Rees Subject: meaning of local define To: CPH@OZ.AI.MIT.EDU cc: RRRS-AUTHORS@MC.LCS.MIT.EDU In-reply-to: Msg of Sat 29 Mar 1986 16:45 EST from CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU Message-ID: <[MC.LCS.MIT.EDU].865709.860329.JAR> Date: Sat, 29 Mar 1986 16:45 EST From: CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU Anyway, to get to the point: as I recall, local-DEFINE was included in the standard only because of S&ICP. I would favor leaving the current description of its semantics, perhaps with a prominent note to that effect, and recommending LETREC for new code. OK. I don't care much about this question. Since you and JINX are the only people who have commented, I'll probably do as you say. Leaving it the way it is would simplify the language & documentation, I think, but a clarification is in order, since it's implicit that define's are like evaluable expressions, and the bodies of LAMBDA's etc. are evaluated sequentially. I also thought that local DEFINE's were supposed to be "like top level ones," which are done sequentially; but the analogy already breaks down because all local DEFINE's have to appear contiguously at the front of the body. My BNF, and the current RRRS, say that DEFINE's can't occur in BEGIN's; does anyone have any problem with that? If so, what should it mean?  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 29 MAR 86 16:54:09 EST Date: Sat, 29 Mar 1986 16:53 EST Message-ID: From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU To: adams%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Cc: rrrs-authors@MC.LCS.MIT.EDU Subject: NAMED-LAMBDA, REC, DEFINE In-reply-to: Msg of 27 Mar 1986 14:42-EST from adams%tekchips%tektronix.csnet at CSNET-RELAY.ARPA Date: Thursday, 27 March 1986 14:42-EST From: adams%tekchips%tektronix.csnet at CSNET-RELAY.ARPA Of course, a novice can still achieve confusion when defining and redefining procedures using the simple DEFINE syntax. Furthermore, you have to explain the difference between variable references that are self references and those that are not. I hadn't really thought that through. Clearly the situation with DEFINE can become arbitrarily complex with either semantics. So I would like to retract my earlier statement in support of the simpler semantics.  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 29 MAR 86 16:47:58 EST Date: Sat, 29 Mar 1986 16:47 EST Message-ID: From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU To: Guy Steele Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: small changes In-reply-to: Msg of 27 Mar 1986 17:32-EST from Guy Steele Date: Thursday, 27 March 1986 17:32-EST From: Guy Steele Well, what about tracing utilities of the style that replace the (functional) value of a variable with a new function that does tracing and also calls the old value? I think this could be fixed by having a somewhat more sophisticated tracing procedure. But that is a good point.  Date: Sat, 29 Mar 86 16:48:01 EST From: Jonathan A Rees Subject: small changes To: dyb%indiana.csnet@CSNET-RELAY.ARPA cc: RRRS-AUTHORS@MC.LCS.MIT.EDU Message-ID: <[MC.LCS.MIT.EDU].865699.860329.JAR> Date: Mon, 24 Mar 86 10:13:39 est From: Kent Dybvig I would like to see the Common Lispy definition that anything with no other possible syntax (especially wrt numbers) is an identifier. I don't necessarily like it, but I see no reason to do otherwise, and I might be interested sometime in implementing Common Lisp in Scheme. There were some objections to this at the Brandeis meeting; it's nice to be able to catch typos in numbers, knowing from the first character that what's coming is a symbol makes for simpler readers, and the "everything except" definition can't be captured by a context-free grammar. But regardless of the reasons, there wasn't agreement on allowing anything but what's there, so as usual this made the language smaller than some people would have liked, but it includes the things that everyone could accept. If you want to do Common Lisp in Scheme, this will be the least of your problems. You'll need to be able to deal with many other extensions to the read syntax, including package prefixes, escape sequences, circular structure, and a zillion other things. - I don't know of anyone who is a NAMED-LAMBDA partisan, so I intend to flush it. (It's not essential, anyhow.) However, I know there are some people out there who are partial to REC, so I'll take the conservative position again and leave it in (even though I and other MIT folks don't like it). Thank you for leaving in REC. I could not live without it. I forgot that Jim Miller wanted NAMED-LAMBDA, and Henry Wu also spoke up later in support of it, so it stays. I should have insisted on the things that I can't live without at the Brandeis meeting instead of being a nice guy. As it is I can't stand to program in RRRS Scheme. But that's beside the point. I've forgotten what the non-controversial changes to DO are. Perhaps you could refresh my memory. I hope it was related to the implied use of set! in the description used in the manual. That's correct. I would also like to bring up the case insensitivity issue once again. Yes, I do prefer that A-Symbol and a-symbol be different. I like to use case to set off certain things, like X for set and x for the element in (member x X). I see no value in having case-insensitive symbols, and a lot of conversion trouble. I think most of us now have terminals with lower-case letters. I would like the special-form keywords and function names to be in lower case. Sorry about my previous reply. I just meant to say that I have never heard a case-sensitivity argument on either side of the issue which wasn't basically religious. I don't think the two sides will ever be able to speak to each other dispassionately. I have been on both sides of the question at various times myself. (I think I started to change my mind when I tried to explain to my father, a computer novice, what a fantastically liberating thing it was that Foo and fOO were different, and he thought I had taken leave of my senses.) The purely political arguments for case-insensitivity are: conservatism - don't change the report more than necessary - we had a chance a year ago to talk about this, why bring it up now; compatibility with T, MIT Scheme, PC Scheme, MacScheme, and many others; and compatibility with Common Lisp and most operating systems (other than Unix and Multics) and languages (other than C). If you insist on going counter to the Brandeis decision, making your implementation and book case-sensitive, then there will be some painful decisions to make about what to say in the report. The report will have to say that some implementations of Scheme are case-sensitive; as for what to do with upper case, I can think of two solutions: 1. It's OK to write it, but only programs (and data files) which don't care one way or the other (using lower case for the things in the manual, and don't depend on EITHER (eq? 'foo 'Foo) or (not (eq? 'foo 'Foo))), will be portable. 2. Say that only programs which use lower-case only will be portable. I would even be willing to say that SYMBOL->STRING will return lower case, and STRING->SYMBOL will only be guaranteed to accept lower-case letters. Implementations could be permitted to do what they like, even signal an error, if there are upper-case letters. (Case-insensitivity advocates should note that this makes no statement about how print names are to be stored internally, although these particular procedures would presumably be a little more efficient if the internal case of portable identifiers was lower.) I'm not sure how much it matters much which case WRITE and DISPLAY generate, but there will be no agreement on this, so we can just make a note that what these things do is implementation-dependent, but case-sensitive implementations will print lower case so that READ will work. I think this can only cause problems if you're FTP'ing between an insensitive implementation which prints upper case to a case sensitive implementation, but it seems to me that this problem is politically unsolvable if you will not agree to be case-insensitive. There will be problems if you actually exploit case sensitivity in your book, that is, if any program depends on the non-eq-ness of two identifiers with the same name in differing cases. Then your book will conflict with most implementations. If you use varying case but never depend on (not (eq? 'foo 'Foo)) then everything should be fine. PLEASE - if people want to discuss this question - keep in mind the political situation; remember that if you like case-sensitivity or case-insensitivity, there's no chance you'll make a convert of someone in the opposite camp, so don't inflict pain by arguing this question. Be nice. The real question is what concessions are we willing to make in order to come to a consensus. I have stated above how far I'll go. On one other issue, there are some of us here at IU who have serious difficulty with #!true and #!false, and we will be sending out a new proposal under separate cover in a day or so. I agree completely; I have always thought that #!true and #!false were incredibly ugly, and I argued against them at Brandeis. And I have heard at least four different people say the same thing to me in the past couple of days alone. T uses #T and #F (or #t and #f), inspired by 3-Lisp's $T and $F. Who doesn't like #T and #F besides people at MIT (with whom I can speak in person)? Why? Jonathan  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 29 MAR 86 16:45:23 EST Date: Sat, 29 Mar 1986 16:45 EST Message-ID: From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU To: Jonathan A Rees Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: meaning of local define In-reply-to: Msg of 27 Mar 1986 15:40-EST from Jonathan A Rees Date: Thursday, 27 March 1986 15:40-EST From: Jonathan A Rees This can make a difference when a user tries to figure out whether expressions like the following will return a well-defined result: (define (foo x) (define bar (1+ x)) (define baz (* bar bar)) (/ baz 6)) According to the documentation of DEFINE, this is equivalent to (define (foo x) (letrec ((bar (1+ x)) (baz (* bar bar))) (/ baz 6))) I'm not a big fan of local define's, but I think that if they are implemented, they should have right-to-left semantics. I believe local-DEFINE partisans will agree with this. I (sort of) like local-DEFINE. If I understand correctly, you would like to have them be evaluated sequentially because each appears, syntactically, to be a side-effect. I feel funny about this, because the example above is precisely the kind of thing that constantly screws up beginning users in 6.001. I'm used to thinking of local-DEFINE as a syntax for LETREC (which takes less horizontal space!), and not having any dependence on order of evaluation. And in fact I consider that very, very bad style. The example above should be written using LET. In fact, the only useful values in local-DEFINE or LETREC are procedure definitions and delayed evaluations, because nothing else can need the mutual recursion -- every other kind of expression can always be written using LET. Anyway, to get to the point: as I recall, local-DEFINE was included in the standard only because of S&ICP. I would favor leaving the current description of its semantics, perhaps with a prominent note to that effect, and recommending LETREC for new code. I should probably learn to use LETREC instead, but I fear I'm too attached to DEFINE by now.  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 29 MAR 86 16:27:58 EST Date: Sat, 29 Mar 1986 16:27 EST Message-ID: From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU To: Jonathan A Rees Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: Scheme BNF In-reply-to: Msg of 27 Mar 1986 14:41-EST from Jonathan A Rees Date: Thursday, 27 March 1986 14:41-EST From: Jonathan A Rees I guess I would propose for EQ? to act on immutable data the same way it does on procedures, remembering where they came from but maybe returning false for things that are operationally equivalent. EQV? would test for true operational equivalence in the case of immutable data. I think that this is a good idea. If strings are immutable, I don't see why EQ? should be required to compare their contents.  Received: from DEEP-THOUGHT.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 28 MAR 86 16:18:29 EST Date: 28 Mar 1986 16:17 EST (Fri) Message-ID: From: Bill Rozas To: Jonathan A Rees Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: meaning of local define In-reply-to: Msg of 27 Mar 1986 15:40-EST from Jonathan A Rees My thoughts about local DEFINE and RECless DEFINE: 1) I think that local DEFINEs should be EXACTLY equivalent to LETREC. I also think that the standard should ONLY support LAMBDA expressions in LETREC, thus (define (foo x) ; (1) (define bar (1+ x)) (define baz (* bar bar)) (/ baz 6)) would be unspecified (might be an error in some implementations), and so would (letrec ((a (cons 3 (lambda () a)))) ; (2) a) and similar things. Individual implementations may extend the semantics of LETREC and local DEFINE, but it is up to them to give a consistent semantics. I REALLY dislike expressions of type (2) above because they are very misleading, and dislike expressions of type (1) almost as much. Note that I am a partisan of local DEFINE. I also think (from previous discussions) that most people at MIT would accept this. We've agreed on it before but never enforced it on MIT Scheme. 2) I think that DEFINE should not have an implicit NAMED-LAMBDA. I think that naive users will get confused either way (in equal numbers), and thus the decision should be left to us. At MIT, DEFINE behaves differently on the Scheme system on which S&ICP is run (we call this the student system) from the one which we use (which we call the development system). The student system always uses the semantics implied by the interpreter in section 4.1 of S&ICP (as opposed to the LETREC definition). We call this semantics "incremental" DEFINE, rather than "local" or "internal" DEFINE. I have not seen a single person have any problems when transferring from the student system to the development system (most of our hackers, including myself, transferred at one point from one to the other), so this incompatibility is not very important in practice. Thus my suggestion to CPH, JMILLER, and other people at MIT concerned about naive users, is that we keep these differences (implicit NAMED-LAMBDA vs. LAMBDA, incremental vs. local DEFINE) in semantics between both systems, but the standard should be cleaner. Note: for the difference between both semantics for DEFINE, read section 5.2.5 of S&ICP. In particular, read exercise 5.27. The student system at MIT would return 16, the development system would signal an error. Again, I do not remember seeing users run into this difference when transferring from one system to the other, because good style dictates that all internal definitions be used for defining procedures only, and it is this restriction that I would like to place on the standard.  Received: from ZERMATT.LCS.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 28 MAR 86 11:34:32 EST Received: from ASPEN.LCS.MIT.EDU by MIT-ZERMATT.ARPA via CHAOS with CHAOS-MAIL id 29416; Fri 28-Mar-86 11:33:55-EST Date: Fri, 28 Mar 86 11:33 EST From: Robert Halstead Subject: self-reference and DEFINE To: RRRS-AUTHORS@MIT-MC.ARPA In-Reply-To: <860327173232.2.GLS@THINK-KATHERINE.ARPA> Message-ID: <860328113321.1.RHH@ASPEN.LCS.MIT.EDU> I agree with the people who aren't ecstatic about the implicit self-reference of (DEFINE (FOO BAR BAZ) ...) -- mainly because of the fact that it works smoothly for recursive definitions but not for mutually recursive ones, as pointed out by Adams at Tektronix, but also because of the introduction of gratuitous hidden stuff. Too many times, I've seen people who thought they understood the simple Scheme model of environments (and did!) confuse themselves by trying experiments where they rebind a function name and then wonder why the re-binding didn't "take" in all the places they would have expected. It is then necessary to explain that reality is a little more complicated, and that their experiment didn't work because of some nice things Scheme is trying to do for you without telling you. I also doubt that as a practical, software engineering matter, in the hands of experienced users, it matters very much whether DEFINE does its special self-referential legerdemain or not! But I've never been able to change any minds with these arguments, and I wonder whether we should be trying to change this aspect of the MIT Scheme design at this point in the game. -Bert  Date: Thu, 27 Mar 86 21:26:53 EST From: Jonathan A Rees Subject: another nit To: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA cc: RRRS-AUTHORS@MC.LCS.MIT.EDU In-reply-to: Msg of 27 Mar 86 12:01:15 PST (Thu) from willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA Message-ID: <[MC.LCS.MIT.EDU].864078.860327.JAR> Date: 27 Mar 86 12:01:15 PST (Thu) From: willc%tekchips%tektronix.csnet at CSNET-RELAY.ARPA Leibniz's definition of the identity of X and Y goes something like this: X = Y iff for all properties P, P(X) = P(Y) If X and Y are identical except for the fact that EQV? or EQ? can distinguish them, then they're not identical. Hence I don't see why implementations that disallowed SET-CAR! on quoted lists would be required to say that (EQV? '(A) '(A)) is #!true. Well, let Z be some object, and let P be the property of objects X for which X = Z. Then your definition won't work, because it will be circular. So we make sure that = doesn't occur in P, and we win. That's how I define operational equivalence: let's write X = Y when X is operationally equivalent to Y; I say X = Y iff for all programs P not involving = (i.e. EQ?, EQV?, MEMQ, etc.), the value and effects of P(X) are the same as the value and effects of P(Y). Now = isn't computable, so we define EQV? to be an approximation to = which in the case of = procedures might return false but will return true in the cases that Sussman wants it to. So EQV? is a computable approximation to =. But by this definition, if it's an error to alter quoted structure, then necessarily (eqv? '(a) '(a)). Thus my inquiry. [I guess this begs the question of what "the same as" means, but I think the definition can be made to work.] With the current semantics of EQ? and EQV?, I don't believe there's any hope for an implementation-independent description. I'm sorry. I agree that EQV? can't be made to work the same in all implementations, but I think my description captures something reasonable. I should have been more explicit before. Yes, it should be an error to clobber quoted structure. In the formal semantics I use, however, it's simpler to allow side effects. (I don't want to have to deal with a separate class of immutable structures.) No, (EQV? '(A) '(A)) should not be required to return true in implementations that forbid clobbering quoted structure. If it were, (EQV? X Y) would have to return true if X were a list that was quoted in file "foo" and Y were a list that was quoted in file "bar". I don't want to write a fasl loader that interns structures. Not so - if EQV? had a way to distinguish mutable from immutable data, it could do exactly what it does with large numbers - a non-constant-time comparison, similar what EQUAL? does. No interning necessary, but either extra type codes or a disjoint region of memory in order to be able to tell when it should do a pointer omparison and when to look at the components. Jonathan  Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 27 Mar 86 20:38:12 EST Received: from tektronix by csnet-relay.csnet id ap16995; 27 Mar 86 18:48 EST Received: by tektronix (5.31/5.14) id AA18938; Thu, 27 Mar 86 11:59:07 PST Received: by tekchips (5.31/5.14) id AA15777; Thu, 27 Mar 86 12:01:20 PST Message-Id: <8603272001.AA15777@tekchips> To: JAR@mc.lcs.mit.edu Cc: RRRS-AUTHORS@mc.lcs.mit.edu, willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Subject: Re: another nit In-Reply-To: Your message of Wed, 26 Mar 86 16:20:58 EST. <[MC.LCS.MIT.EDU].862701.860326.JAR> Date: 27 Mar 86 12:01:15 PST (Thu) From: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Leibniz's definition of the identity of X and Y goes something like this: X = Y iff for all properties P, P(X) = P(Y) If X and Y are identical except for the fact that EQV? or EQ? can distinguish them, then they're not identical. Hence I don't see why implementations that disallowed SET-CAR! on quoted lists would be required to say that (EQV? '(A) '(A)) is #!true. With the current semantics of EQ? and EQV?, I don't believe there's any hope for an implementation-independent description. I'm sorry. Yes, it should be an error to clobber quoted structure. In the formal semantics I use, however, it's simpler to allow side effects. (I don't want to have to deal with a separate class of immutable structures.) No, (EQV? '(A) '(A)) should not be required to return true in implementations that forbid clobbering quoted structure. If it were, (EQV? X Y) would have to return true if X were a list that was quoted in file "foo" and Y were a list that was quoted in file "bar". I don't want to write a fasl loader that interns structures. The manual should distinguish "is an error" from "unspecified", but you shouldn't agonize over any unclear cases. I'm sorry about my mistakes. Peace, Will  Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 27 Mar 86 20:38:12 EST Received: from tektronix by csnet-relay.csnet id ao16995; 27 Mar 86 18:47 EST Received: by tektronix (5.31/5.14) id AA18725; Thu, 27 Mar 86 11:40:20 PST Received: by tekchips (5.31/5.14) id AA15499; Thu, 27 Mar 86 11:42:42 PST Message-Id: <8603271942.AA15499@tekchips> To: rrrs-authors@mc.lcs.mit.edu Cc: willc%tekchips%tektronix.csnet@CSNET-RELAY.ARPA Subject: NAMED-LAMBDA, REC, DEFINE Date: 27 Mar 86 11:42:37 PST (Thu) From: adams%tekchips%tektronix.csnet@CSNET-RELAY.ARPA In the spirit of fanatic minimalism, I would prefer to remove both NAMED-LAMBDA and REC. From: Chris Hanson Re: prefering LETREC in the expansion of (DEFINE (FOO ...) ...) I claim (and I believe that there will be support for this claim) that the INTENT of the author of such a self referential procedure was that the name FOO refer to the procedure itself, not the binding of the variable FOO. This is because the binding is normally assumed to be fixed; interactive definitions are something that the language has because we recognize the need for debugging and evolution of our programs. I agree (except that I think of redefinition as provided by the development environment, not the language). And the more naive the user, the more confusing it will be if the procedure FOO depends on the value of the variable FOO, rather than meaning "self reference". I am not convinced that introducing self references behind the naive user's back is doing him or her a great service. LETREC-introducing DEFINE provides what you consider to be the intuitive behavior only in the simple case. E.g.: (DEFINE (FOO N) ...(FOO...)...) (SET! BAZ FOO) the value of BAZ will be "consistent" because BAZ is the old version of FOO, and the old version of FOO will recur by calling the old version. But, in this case: (DEFINE (FOO N) ... (BAR N) ...) (DEFINE (BAR N) ... (FOO N) ...) (SET! BAZ FOO) the value of BAZ will be inconsistent because the old version of FOO will call the new version of BAR, which will call the new version of FOO. Of course, a novice can still achieve confusion when defining and redefining procedures using the simple DEFINE syntax. Furthermore, you have to explain the difference between variable references that are self references and those that are not.  Received: from THINK-AQUINAS.ARPA by MC.LCS.MIT.EDU 27 Mar 86 17:46:41 EST Received: from THINK-KATHERINE.ARPA by THINK-AQUINAS.ARPA via CHAOS with CHAOS-MAIL id 17625; Thu 27-Mar-86 17:47:35-EST Date: Thu, 27 Mar 86 17:46 EST From: Guy Steele Subject: meaning of local define To: JAR@MIT-MC.ARPA, RRRS-AUTHORS@MIT-MC.ARPA cc: gls@THINK-AQUINAS.ARPA In-Reply-To: <[MC.LCS.MIT.EDU].863786.860327.JAR> Message-ID: <860327174644.4.GLS@THINK-KATHERINE.ARPA> Date: Thu, 27 Mar 86 15:40:53 EST From: Jonathan A Rees LETREC may evaluate the right-hand sides in any order it pleases. But one could expect for several reasons that local DEFINEs are evaluated left to right (or top to bottom, depending on where the line breaks ----^^^^^^^^^^^^^ are). The conjunction of these properties is in contradiction with the assertion that local DEFINE's can always turn into a LETREC. ... I'm not a big fan of local define's, but I think that if they are implemented, they should have right-to-left semantics. I believe ----------------------------------^^^^^^^^^^^^^ local-DEFINE partisans will agree with this.... Should the second indicated place read "left-to-right", or am I misunderstanding your intent? --Guy  Date: Thu, 27 Mar 86 17:38:06 EST From: Jonathan A Rees Subject: meaning of local define (tiny correction) To: JAR@MC.LCS.MIT.EDU cc: RRRS-AUTHORS@MC.LCS.MIT.EDU In-reply-to: Msg of Thu 27 Mar 86 15:40:53 EST from Jonathan A Rees Message-ID: <[MC.LCS.MIT.EDU].863925.860327.JAR> I meant to say left-to-right, not right-to-left.  Received: from THINK-AQUINAS.ARPA by MC.LCS.MIT.EDU 27 Mar 86 17:32:42 EST Received: from THINK-KATHERINE.ARPA by THINK-AQUINAS.ARPA via CHAOS with CHAOS-MAIL id 17619; Thu 27-Mar-86 17:33:22-EST Date: Thu, 27 Mar 86 17:32 EST From: Guy Steele Subject: small changes To: CPH%OZ.AI.MIT.EDU@MIT-XX.ARPA, JAR@MIT-MC.ARPA cc: RRRS-AUTHORS@MIT-MC.ARPA, gls@THINK-AQUINAS.ARPA In-Reply-To: Message-ID: <860327173232.2.GLS@THINK-KATHERINE.ARPA> Date: Thu, 27 Mar 1986 01:43 EST From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU Date: Sunday, 23 March 1986 18:10-EST From: Jonathan A Rees Incompatible change: I'd like to change the meaning of (DEFINE (form var ...) body ...) so that it's defined in terms of LAMBDA instead of NAMED-LAMBDA. I don't like this, and would prefer that (DEFINE (FOO BAR BAZ) ...) expand into (DEFINE FOO (LETREC ((FOO (LAMBDA (BAR BAZ) ...))) FOO)) this additional complication mostly to eliminate the need for either REC or NAMED-LAMBDA. ... I claim (and I believe that there will be support for this claim) that the INTENT of the author of such a self referential procedure was that the name FOO refer to the procedure itself, not the binding of the variable FOO. This is because the binding is normally assumed to be fixed; ... Well, what about tracing utilities of the style that replace the (functional) value of a variable with a new function that does tracing and also calls the old value? I suppose I can always write (DEFINE FOO (LAMBDA (BAR BAZ) ...)) but it seems to me the language is more transparent if not too many implicit hidden things creep in. (In retrospect, I think that the Common Lisp "feature" of DEFUN supplying an implicit named BLOCK around its body was perhaps a mistake.) --Guy  Date: Thu, 27 Mar 86 15:40:53 EST From: Jonathan A Rees Subject: meaning of local define To: RRRS-AUTHORS@MC.LCS.MIT.EDU Message-ID: <[MC.LCS.MIT.EDU].863786.860327.JAR> LETREC may evaluate the right-hand sides in any order it pleases. But one could expect for several reasons that local DEFINEs are evaluated left to right (or top to bottom, depending on where the line breaks are). The conjunction of these properties is in contradiction with the assertion that local DEFINE's can always turn into a LETREC. This can make a difference when a user tries to figure out whether expressions like the following will return a well-defined result: (define (foo x) (define bar (1+ x)) (define baz (* bar bar)) (/ baz 6)) According to the documentation of DEFINE, this is equivalent to (define (foo x) (letrec ((bar (1+ x)) (baz (* bar bar))) (/ baz 6))) I'm not a big fan of local define's, but I think that if they are implemented, they should have right-to-left semantics. I believe local-DEFINE partisans will agree with this. One solution is to introduce a new special form LETREC* which evaluates the right-hand sides from top to bottom, and explain local DEFINE's in terms of that. So the example would be equivalent to: (define (foo x) (letrec* ((bar (1+ x)) (baz (* bar bar))) (/ baz 6))) But LETREC* would otherwise be of very marginal usefulness, and we don't need more secial forms. So what I propose to do is to document the (LET ((var) ...) ...) and (DO ((var) ...)...) syntax, with the meaning CPH described, and explain local DEFINE's in terms of LET and SET!, mentioning that in the case that the right-hand sides of all the DEFINE's are all LAMBDA's, the LETREC expansion would work just as well. Sorry to reverse my former opposition to this feature, but I hadn't thought of this before. Opinions? Any ideas about other ways to describe DEFINE? The funny thing about (LET ((var)) ...) is that it's the only documented way to get a variable bound to an uninitialized location which it is an error to access. This means that the correspondence between (LET ...) and ((LAMBDA ...) ...) isn't as direct as it ought to be, since there's no way that it can be an error to refer to a variable bound by a LAMBDA-expression. LET is primitive in Common Lisp (for other reasons), and I never liked that. On the other hand, this would give us an opportunity to describe LETREC in terms of LET and SET! (exercise for the student: how to make sure that the rhs's are evaluated in an indeterminate order?). I sniff another special form and semantic complexity here. What to do? Jonathan.  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 27 MAR 86 15:27:39 EST Date: 27 Mar 1986 14:59 EST (Thu) Message-ID: From: Bill Rozas To: Jonathan A Rees Cc: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU, RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: Scheme BNF In-reply-to: Msg of 27 Mar 1986 14:41-EST from Jonathan A Rees MIT Scheme detects the bound but not assigned error only in interpreted code currently. I don't think that (let ((var)) ...) or the equivalent DO form have to be in the standard. Both MIT Scheme and T (and whoever else wants it) can implement them as a compatible extension.  Date: Thu, 27 Mar 86 14:41:42 EST From: Jonathan A Rees Subject: Scheme BNF To: CPH@OZ.AI.MIT.EDU cc: RRRS-AUTHORS@MC.LCS.MIT.EDU In-reply-to: Msg of Thu 27 Mar 1986 03:27 EST from CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU Message-ID: <[MC.LCS.MIT.EDU].863725.860327.JAR> Date: Thu, 27 Mar 1986 03:27 EST From: CPH%OZ.AI.MIT.EDU at XX.LCS.MIT.EDU A fine point I would like to make is that RRRS is careful to allow the possibility of immutable strings. In this case I think that EQV? makes sense on strings, so that (sigh) an even more complicated syntax would be needed which took into account that possibility. I agree with you, but there are further ramifications. People have said that EQ? and EQV? should agree on everything besides numbers and characters. If this constraint is maintained, than EQ? must also return true for immutable strings with identical contents. But this could make EQ? expensive, which, it seems to me, would defeat the point of making it different from EQV?. Another issue is whether EQV? should compare immutable data in general. I would say it should. I guess I would propose for EQ? to act on immutable data the same way it does on procedures, remembering where they came from but maybe returning false for things that are operationally equivalent. EQV? would test for true operational equivalence in the case of immutable data. On the other hand, I like the idea of using EQUAL? and I agree that it is easy to make efficient. Like I say, I don't care. However, just to complicate things, I'll mention something about CASE that has bothered me when I have tried to use it. I sometimes have found that I am doing something of this kind: (COND ((EQ? X 'FOO) ...) ((EQ? X BAR) ...) ((EQ? X 'BAZ) ...) ...) where one of the keywords I am matching against has been parameterized for one reason or another, and this forces me to use COND rather than CASE. Has anyone else run into this problem? Is it interesting enough to consider modifying CASE? Yes. No. I like the fact that CASE is minimal. I think that if we try to generalize it or come up with other constructs, we'll never be able to agree on what to do, and the manual will get longer. I say you should either use COND, a more featureful language than Scheme. Actually, MIT Scheme has a consistent meaning for both of these, which is that the variable in question is bound but not assigned. Such variables are only useful in the presence of assignments, and it is an error to refer to one between the time that it is bound and when it is assigned. I suspect that some will find this offensive, although personally I find it preferable to other alternatives that I have seen for describing this particular state. So I'm just pointing it out for general interest. This is what T does too, although it doesn't detect the error. What do other people think? This would have to be a new documented feature of LET; would it have to be essential?  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 27 MAR 86 03:30:34 EST Date: Thu, 27 Mar 1986 03:27 EST Message-ID: From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU To: Jonathan A Rees Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: Scheme BNF In-reply-to: Msg of 23 Mar 1986 20:38-EST from Jonathan A Rees Date: Sunday, 23 March 1986 20:38-EST From: Jonathan A Rees - Shouldn't backquote work on vectors? If not, then what's the rationale for making them work on lists and not vectors? I think that the only reason for this is that the #(...) syntax for vectors was originally self-evaluating, which implied that the contents of the vector was already quoted. If this requirement is flushed (I don't know if there is consensus for this, but I would like it to be), then I think that backquote should work on vectors also. - What kinds of constants should be allowed in CASE clauses? I don't really care, but I can imagine two possible answers: 1. If EQV? is used for comparisons, then it doesn't make any sense to allow strings, lists, or vectors. 2. Use EQUAL? for comparisons, and allow any . ...but I won't listen to anyone who doesn't supply a better word to use for the nonterminal than "casable". I suspect that "casable" should be spelled "caseable". I don't think that counts as a better word, but I hope that you'll read my comments anyway. (Otherwise I suppose I'll have to invent a new language so that someone will listen to me.) A fine point I would like to make is that RRRS is careful to allow the possibility of immutable strings. In this case I think that EQV? makes sense on strings, so that (sigh) an even more complicated syntax would be needed which took into account that possibility. On the other hand, I like the idea of using EQUAL? and I agree that it is easy to make efficient. However, just to complicate things, I'll mention something about CASE that has bothered me when I have tried to use it. I sometimes have found that I am doing something of this kind: (COND ((EQ? X 'FOO) ...) ((EQ? X BAR) ...) ((EQ? X 'BAZ) ...) ...) where one of the keywords I am matching against has been parameterized for one reason or another, and this forces me to use COND rather than CASE. Has anyone else run into this problem? Is it interesting enough to consider modifying CASE? - I definitely want like to flush the () syntax for iteration specs in DO. It is inconsistent for DO to have this alternate form and not LET, and I don't like either. Does anyone actually ever use it? Actually, MIT Scheme has a consistent meaning for both of these, which is that the variable in question is bound but not assigned. Such variables are only useful in the presence of assignments, and it is an error to refer to one between the time that it is bound and when it is assigned. I suspect that some will find this offensive, although personally I find it preferable to other alternatives that I have seen for describing this particular state. So I'm just pointing it out for general interest.  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 27 MAR 86 01:46:08 EST Date: Thu, 27 Mar 1986 01:43 EST Message-ID: From: CPH%OZ.AI.MIT.EDU@XX.LCS.MIT.EDU To: Jonathan A Rees Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: small changes In-reply-to: Msg of 23 Mar 1986 18:10-EST from Jonathan A Rees Date: Sunday, 23 March 1986 18:10-EST From: Jonathan A Rees Incompatible change: I'd like to change the meaning of (DEFINE (form var ...) body ...) so that it's defined in terms of LAMBDA instead of NAMED-LAMBDA. I don't like this, and would prefer that (DEFINE (FOO BAR BAZ) ...) expand into (DEFINE FOO (LETREC ((FOO (LAMBDA (BAR BAZ) ...))) FOO)) this additional complication mostly to eliminate the need for either REC or NAMED-LAMBDA. My reasoning is that this semantics solves a classical problem: namely that if FOO is self referential, then subsequent redefinition of the variable FOO will cause the originally defined procedure to change its behavior. In particular, suppose that the procedure value of FOO is bound to the variable BAR, and then FOO is redefined to some completely different value, say (just to be extreme) the number 3. I claim (and I believe that there will be support for this claim) that the INTENT of the author of such a self referential procedure was that the name FOO refer to the procedure itself, not the binding of the variable FOO. This is because the binding is normally assumed to be fixed; interactive definitions are something that the language has because we recognize the need for debugging and evolution of our programs. And the more naive the user, the more confusing it will be if the procedure FOO depends on the value of the variable FOO, rather than meaning "self reference". Now, the reason why everyone wants the meaning of DEFINE to avoid the use of LETREC (or its special case NAMED-LAMBDA) is obvious: it is simpler to explain to people who are learning the language. However, I think that this is detrimental in the long run, because sooner or later many of those students who learned the simpler DEFINE semantics will get screwed by the fact that their intuition didn't match the semantics. I feel that teaching this subtle point would not take much effort. Furthermore it would illustrate an important concept in language design: that semantics should interact with our intuitive and esthetic concepts of how a language should behave.  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 26 MAR 86 17:13:46 EST Date: 26 Mar 1986 17:11 EST (Wed) Message-ID: From: Bill Rozas To: Jonathan A Rees Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: another nit In-reply-to: Msg of 26 Mar 1986 16:20-EST from Jonathan A Rees 1. Should we say that the (SET-CAR! '(A) 'B) is an error, rather than that it is unspecified? I sort of like that. 2. Should we require (EQV? '(A) '(A)) to return true in implementations which forbid clobbering quoted structure (that would be all implementations, if the answer to 1. is yes)? Although it would be nice, it seems that it has serious implementation consequences: either quoted structure is hash-consed (BTW, what happens them to immutable parts of back-quoted structure?), or EQV? becomes more expensive than it already is. I think that it would be a good idea to make a distinction between unspecified and "is an error".  Date: Wed, 26 Mar 86 16:20:58 EST From: Jonathan A Rees Subject: another nit To: RRRS-AUTHORS@MC.LCS.MIT.EDU Message-ID: <[MC.LCS.MIT.EDU].862701.860326.JAR> Now I'm trying to explain that QUOTE is allowed to return immutable structured objects, and that particular implementations may have other ways to create immutable data. One thing that implementations can do as a result of this is "coalesce" immutable structured objects the same way that symbols are always coalesced and numbers sometimes are. So it may be the case that (EQV? '(A) '(A)) returns true. So far so good. I'm trying to describe EQV? and EQ? in terms of a "operational equivalence", for which I think Ihave a fairly elegant definition. I was ready to say that EQV? is the procedure which determines operational equivalence [with a proviso allowing it to make an approximate judgement in the case of procedures and continuations, as discussed previously], and then realized that my documentation would imply that (EQV? '(A) '(A)) would be REQUIRED to return true in those implementations which disallowed SET-CAR! on quoted lists. Questions: 1. Should we say that the (SET-CAR! '(A) 'B) is an error, rather than that it is unspecified? [If some of you say it should never be an error, I think you'll get into an argument.] 2. Should we require (EQV? '(A) '(A)) to return true in implementations which forbid clobbering quoted structure (that would be all implementations, if the answer to 1. is yes)? I like this because it simplifies the documentation; I don't need to say anything about immutable data. It would be a shame to require implementations to be able to distinguish mutable from immutable data AND require them to create immutable data. That has serious implementation implications; I don't want to propose that. N. I have noticed that the manual isn't careful about distinguishing "is an error" from "unspecified". Do people want me to try to make a clear distinction between them, or is an unclear distinction sufficient? Maybe talking about mutability is a bad idea if there aren't MUTABLE? and IMMUTABLE? predicates. If you think I'm totally confused and that there's a better way to think about this, you're probably right. Tell me how. Jonathan  Date: Wed, 26 Mar 86 10:18:56 EST From: Jonathan A Rees Subject: small changes To: dyb%indiana.csnet@CSNET-RELAY.ARPA cc: RRRS-AUTHORS@MC.LCS.MIT.EDU In-reply-to: Msg of Mon 24 Mar 86 16:28:58 est from Kent Dybvig Message-ID: <[MC.LCS.MIT.EDU].862337.860326.JAR> Date: Mon, 24 Mar 86 16:28:58 est From: Kent Dybvig I have the same problem with people who, in Lisp, use upper case in some places and lower case in others and mean the same identifier. ... The right time to talk about this would have been a year and a half ago. We made a decision at Brandeis and I don't see any evidence that there is or might be general interest in reconsidering it.  Date: Tue, 25 Mar 86 16:05:09 EST From: Jonathan A Rees Subject: (do ((var init)) (...)) To: RRRS-AUTHORS@MC.LCS.MIT.EDU Message-ID: <[MC.LCS.MIT.EDU].861493.860325.JAR> I've heard no one insisting on the (do ((var)) ...) syntax, so I'm going to flush it, for consistency with LET. A few people say they like (do ((var init)) ...), so I'll leave it in. But there's one little issue which needs to be clarified: does the var get a new binding every time around the loop, or does it get just one binding at the beginning? That is, is there an outer LET for the variables which aren't stepped, or is (var init) the same as (var init var)? It makes a difference if closures are created in the loop. The easiest way to write the macro expander is to make (var init) be the same as (var init var). I think this is what ancient scheme interpreters like NSCHSY did, and it's certainly what T does. I don't know about any other implementation. This is the interpretation that I prefer - it's easier to describe and more useful and elegant. Speak up if you believe this is wrong. Jonathan  Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 25 Mar 86 15:03:27 EST Received: from indiana by csnet-relay.csnet id aa21173; 25 Mar 86 14:38 EST Date: Mon, 24 Mar 86 16:28:58 est From: Kent Dybvig To: jinx@mc.lcs.mit.edu Subject: Re: small changes Cc: rrrs-authors@mc.lcs.mit.edu Can we flush internal DEFINE and get Abelson & Sussman w/Sussman to make a new edition without it? I would object as strongly as I possibly could to this (and other people at MIT would also). It is not essential as it is, and does not imply first class environments or side-effected lambda environments anyway. The only thing it implies (if anything), is a more complicated LAMBDA special form to "scan out" the defines and "turn them into" LETREC. This was intended in jest, but since you responded, I have to give my reasoning. Inclusion of internal define is indeed optional, but it does destroy one of our (people at Indiana) favorite programming styles, namely the use of define within let to establish one or more globally visible values sharing internal identifiers, especially state variables and help functions: (let ([state-var1 ...] ... [help-fcn1 (lambda (...) ...)] ...) (define var1 ...) (define var2 ...)) We do not view the use "empty" defines outside and set! inside as a viable alternative, since that is clumsy and implies assignment rather than definition. As for defense of the feature itself, I feel that gumming up LAMBDA is the worst possible thing we can do to Scheme. It wasn't so long ago that it was a page of code to write a full Scheme interpreter. Now it is a page of code to handle lambda alone! I would also like to bring up the case insensitivity issue once again. Yes, I do prefer that A-Symbol and a-symbol be different. I like to use case to set off certain things, like X for set and x for the element in (member x X). I see no value in having case-insensitive symbols, and a lot of conversion trouble. I think most of us now have terminals with lower-case letters. I would like the special-form keywords and function names to be in lower case. I find C impossibly hard to read precisely because people use identifiers which differ only in case for different things. This is even worse than the dual environment of Common Lisp (value cell vs. function cell). I have the same problem with people who, in Lisp, use upper case in some places and lower case in others and mean the same identifier. Natural languages do not usually have different meanings for words with different capitalizations. (if (If iF) (IF iF) (If If)) ;yipee! I disagree that natural languages do not usually have different meanings for words with different captitalizations; some good examples are given in a recent submission to SIGPLAN notices (Mark Wells, V21 #3, March 86, p. 21). (The article in question is actually rather interesting, if you filter out the advertisements for Modcap.) This is at best a sylistic issue that should not be enforced by an otherwise useless and sometimes confusing restriction on the lexical syntax of the language.  Received: from mitre-bedford.ARPA by MC.LCS.MIT.EDU 25 Mar 86 09:43:40 EST Organization: The MITRE Corp., Bedford, MA Received: by linus.MENET (4.12/4.7) id AA19757; Tue, 25 Mar 86 07:43:11 est Date: Tue, 25 Mar 86 07:43:11 est From: John D. Ramsdell Posted-Date: Tue, 25 Mar 86 07:43:11 est Message-Id: <8603251243.AA19757@linus.MENET> To: rrrs-authors@mit-mc.ARPA Subject: Expunge NAMED-LAMBDA I would like to see NAMED-LAMBDA go. John  Date: Mon, 24 Mar 86 18:03:28 EST From: Jonathan A Rees Subject: Scheme BNF To: dyb%indiana.csnet@CSNET-RELAY.ARPA cc: RRRS-AUTHORS@MC.LCS.MIT.EDU In-reply-to: Msg of Mon 24 Mar 86 10:39:14 est from Kent Dybvig Message-ID: <[MC.LCS.MIT.EDU].860721.860324.JAR> Date: Mon, 24 Mar 86 10:39:14 est From: Kent Dybvig - Does anyone object to defining (COND) and (CASE) to return unspecified values? I think this would be a good idea. I thought that COND and CASE with no match and no ELSE were already defined to return unspecified values. If not, I think this should be the definition. No, it's not defined at all - it could be a syntax error, for example. Can we also have (BEGIN) return an unspecified value instead of being invalid syntax? I am certainly opposed to this.  Date: Mon, 24 Mar 86 17:59:41 EST From: Jonathan A Rees Subject: small changes To: JINX@OZ.AI.MIT.EDU cc: RRRS-AUTHORS@MC.LCS.MIT.EDU In-reply-to: Msg of 24 Mar 1986 12:54 EST (Mon) from Bill Rozas Message-ID: <[MC.LCS.MIT.EDU].860716.860324.JAR> Date: 24 Mar 1986 12:54 EST (Mon) From: Bill Rozas While I agree that it should have been like this, I thought that the only reason to add the more complicated defines was for compatibility with MIT-Scheme. MIT-Scheme has not changed, and there would be a big argument over it (at least as far as the student system is concerned). It seems useless to add it then if it is going to be incompatible anyway. No, I see other reasons to have (define (...) ...). The first is that it's used in S&ICP - notably, with the semantics I want (see page 303). The second is that some people like to use it; in particular, myself, and most T users, I think. And if it exists, I think the documentation would be clearer and simpler if it were the other way.  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 24 MAR 86 14:24:11 EST Date: 24 Mar 1986 13:59 EST (Mon) Message-ID: From: Bill Rozas To: Kent Dybvig Cc: rrrs-authors@MC.LCS.MIT.EDU Subject: small changes In-reply-to: Msg of 24 Mar 1986 10:13-EST from Kent Dybvig Can we flush internal DEFINE and get Abelson & Sussman w/Sussman to make a new edition without it? I would object as strongly as I possibly could to this (and other people at MIT would also). It is not essential as it is, and does not imply first class environments or side-effected lambda environments anyway. The only thing it implies (if anything), is a more complicated LAMBDA special form to "scan out" the defines and "turn them into" LETREC. I would also like to bring up the case insensitivity issue once again. Yes, I do prefer that A-Symbol and a-symbol be different. I like to use case to set off certain things, like X for set and x for the element in (member x X). I see no value in having case-insensitive symbols, and a lot of conversion trouble. I think most of us now have terminals with lower-case letters. I would like the special-form keywords and function names to be in lower case. I find C impossibly hard to read precisely because people use identifiers which differ only in case for different things. This is even worse than the dual environment of Common Lisp (value cell vs. function cell). Natural languages do not usually have different meanings for words with different capitalizations. (if (If iF) (IF iF) (If If)) ;yipee!  Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 24 Mar 86 13:47:36 EST Received: from indiana by csnet-relay.csnet id aa08451; 24 Mar 86 13:03 EST Date: Mon, 24 Mar 86 10:39:14 est From: Kent Dybvig To: rrrs-authors@mc.lcs.mit.edu Subject: Re: Scheme BNF Questions: Answers and more questions: - Does anyone object to defining (COND) and (CASE) to return unspecified values? I think this would be a good idea. I thought that COND and CASE with no match and no ELSE were already defined to return unspecified values. If not, I think this should be the definition. Can we also have (BEGIN) return an unspecified value instead of being invalid syntax? - Shouldn't backquote work on vectors? If not, then what's the rationale for making them work on lists and not vectors? I think it should not work on vectors. It makes sense to me only in non- constants, and until we make a firm statement that vectors have some useful meaning in Scheme other than as constants, backquote should not work within vectors. I also have some amount of hesitance about splicing a list into a vector, etc., and what that would mean. - What kinds of constants should be allowed in CASE clauses? I don't really care, but I can imagine two possible answers: 1. If EQV? is used ... ::= ((*) ) ::= | | | 2. Use EQUAL? for comparisons, ... ::= ((*) ) I do not like the use of EQUAL?. If you don't like , how about ? Seriously, we need some term anyway, since it is the same thing accepted by EQV?. What about ? Or ?) Also, it's been said before, but I think we should allow for the optional syntax of a single "" not in a list. ::= ( ) - I definitely want like to flush the () syntax for iteration specs in DO. It is inconsistent for DO to have this alternate form and not LET, and I don't like either. Does anyone actually ever use it? - I would also like to flush the ( ) syntax for DO iteration specs. Does anyone ever use this? I always wrap the DO in a LET if I need extra bindings. No replies from people who don't use DO, please. I agree completely with your sentiments, and I do use DO. - Oh yeah, I forgot to mention in my previous message that I would like to document DELAY and FORCE, as non-essential special form and procedure, respectively. I believe they're non-controversial, and desirable given that they have a central role in S&ICP and are a little tricky to describe and implement. If you don't mind, please send out your prose for these and include the appropriate code for them. I don't have them in Chez Scheme yet and I'm not in the mood to think. Picky comment: I am uncomfortable with the use of in light of the existence of sequence as a special form. Furthermore, I think that + would be more expressive where it appears, and in Scheme there should be no confusion with the operator + or sign +.  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 24 MAR 86 13:28:07 EST Date: 24 Mar 1986 13:03 EST (Mon) Message-ID: From: Bill Rozas To: "John D. Ramsdell" Cc: rrrs-authors@MC.LCS.MIT.EDU Subject: Expunge LETREC, BEGIN and SEQUENCE. In-reply-to: Msg of 24 Mar 1986 07:00-EST from John D. Ramsdell Local defines in MIT-Scheme (which I believe is the only one that originally implemented them) do not cause side effects to environments. (define (foo x) (define (bar y) (+ y (baz x))) (define (baz w) (* w x)) ... ) is equivalent to (define (foo x) (letrec ((bar (named-lambda (bar y) (+ y (baz x)))) (baz (named-lambda (baz w) (* w x)))) ...))  Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 24 Mar 86 13:20:48 EST Received: from indiana by csnet-relay.csnet id a008451; 24 Mar 86 13:02 EST Date: Mon, 24 Mar 86 10:13:39 est From: Kent Dybvig To: rrrs-authors@mc.lcs.mit.edu Subject: Re: small changes As the current editor of the RRRS, I would like to make the following to last year's report. If you have serious objections let me know. Otherwise I'll go ahead. ----- Compatible changes: - Allow identifiers to begin with tilde (^) and underscore (_). These characters can't begin numbers, and are allowed elsewhere in identifiers, so this seems innocuous and reasonable. Was there some reason this wasn't permitted in the first place? - Allow the characters - and + in the middle of identifiers. I assume this was an oversight. I would like to see the Common Lispy definition that anything with no other possible syntax (especially wrt numbers) is an identifier. I don't necessarily like it, but I see no reason to do otherwise, and I might be interested sometime in implementing Common Lisp in Scheme. - I don't know of anyone who is a NAMED-LAMBDA partisan, so I intend to flush it. (It's not essential, anyhow.) However, I know there are some people out there who are partial to REC, so I'll take the conservative position again and leave it in (even though I and other MIT folks don't like it). Thank you for leaving in REC. I could not live without it. Incompatible change: I'd like to change the meaning of (DEFINE (form var ...) body ...) so that it's defined in terms of LAMBDA instead of NAMED-LAMBDA. The only reason this existed in the first place, I think, was because that's the way MIT Scheme's DEFINE was defined. But on talking individually with many people at MIT and elsewhere, I find that no one likes this semantics and would rather have the simpler expansion in terms of LAMBDA. Can we flush internal DEFINE and get Abelson & Sussman w/Sussman to make a new edition without it? I have made all of Will's suggested "non-controversial changes", and have also changed the description of DO as previously discussed, which appears to be non-controversial. I've forgotten what the non-controversioal changes to DO are. Perhaps you could refresh my memory. I hope it was related to the implied use of set! in the description used in the manual. I would to be able to define DO as: (do ((x v u ...) ...) (t r ...) e ...) ==> ((rec loop (lambda (x ...) (if t (begin r ...) (begin e ... (loop u ...))))) v ...) I would also like to bring up the case insensitivity issue once again. Yes, I do prefer that A-Symbol and a-symbol be different. I like to use case to set off certain things, like X for set and x for the element in (member x X). I see no value in having case-insensitive symbols, and a lot of conversion trouble. I think most of us now have terminals with lower-case letters. I would like the special-form keywords and function names to be in lower case. On one other issue, there are some of us here at IU who have serious difficulty with #!true and #!false, and we will be sending out a new proposal under separate cover in a day or so. Kent  Received: from CSNET-RELAY.ARPA by MC.LCS.MIT.EDU 24 Mar 86 12:57:02 EST Received: from ti-csl by csnet-relay.csnet id ad08189; 24 Mar 86 12:34 EST Received: by tilde id AA26690; Mon, 24 Mar 86 08:50:18 cst Date: Mon 24 Mar 86 08:39:00-CST From: Don Oxley Subject: Re: Scheme BNF To: JAR%mc.lcs.mit.edu@CSNET-RELAY.ARPA, RRRS-AUTHORS%mc.lcs.mit.edu@CSNET-RELAY.ARPA In-Reply-To: <[MC.LCS.MIT.EDU].859967.860323.JAR> Message-Id: <12193263890.36.OXLEY@CSC60> Sorry to ask for a delay, but David Bartley is on vacation for a couple of weeks. I would really like to get his input before we at TI take any positions (I don't think we will have any serious problems - I'd just like for us to get our act together before we respond). --Don -------  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 24 MAR 86 12:55:03 EST Date: 24 Mar 1986 12:54 EST (Mon) Message-ID: From: Bill Rozas To: Jonathan A Rees Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: small changes In-reply-to: Msg of 23 Mar 1986 18:10-EST from Jonathan A Rees I'd like to change the meaning of (DEFINE (form var ...) body ...) so that it's defined in terms of LAMBDA instead of NAMED-LAMBDA. The only reason this existed in the first place, I think, was because that's the way MIT Scheme's DEFINE was defined. But on talking individually with many people at MIT and elsewhere, I find that no one likes this semantics and would rather have the simpler expansion in terms of LAMBDA. While I agree that it should have been like this, I thought that the only reason to add the more complicated defines was for compatibility with MIT-Scheme. MIT-Scheme has not changed, and there would be a big argument over it (at least as far as the student system is concerned). It seems useless to add it then if it is going to be incompatible anyway.  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 24 MAR 86 12:54:22 EST Date: Mon 24 Mar 86 12:54:00-EST From: "Henry M. Wu" Subject: Partisans of NAMED-LAMBDA To: rrrs-authors@MC.LCS.MIT.EDU Message-ID: <12193299388.74.MHWU@OZ.AI.MIT.EDU> I like NAMED-LAMBDA and wish it won't go away. I guess that makes me Jon Rees's first NAMED-LAMBDA partisan. I suspect a lot more will follow. Henry Wu -------  Received: from OZ.AI.MIT.EDU by MC.LCS.MIT.EDU via Chaosnet; 24 MAR 86 12:51:33 EST Date: 24 Mar 1986 12:46 EST (Mon) Message-ID: From: Bill Rozas To: Jonathan A Rees Cc: RRRS-AUTHORS@MC.LCS.MIT.EDU Subject: small changes In-reply-to: Msg of 23 Mar 1986 18:10-EST from Jonathan A Rees I am a partisan of NAMED-LAMBDA. If REC stays, I believe so should NAMED-LAMBDA. I'm prefectly happy to flush both.  Received: from GODOT.THINK.COM by MC.LCS.MIT.EDU 24 Mar 86 12:51:07 EST Received: from wenceslas by GODOT.THINK.COM via CHAOS; Mon, 24 Mar 86 12:50:50 est Date: Mon, 24 Mar 86 12:52 EST From: Guy Steele Subject: Scheme BNF To: JAR@MC.LCS.MIT.EDU, RRRS-AUTHORS@MC.LCS.MIT.EDU Cc: gls@THINK-AQUINAS.ARPA In-Reply-To: <[MC.LCS.MIT.EDU].859967.860323.JAR> Message-Id: <860324125242.3.GLS@THINK-WENCESLAS.ARPA> Date: Sun, 23 Mar 86 20:38:01 EST From: Jonathan A Rees [JAR's original message appears below only in excerpts. I am working with the AI Memo 848 version of RRRS, if that matters.] - Does anyone object to defining (COND) and (CASE) to return unspecified values? I think this would be a good idea. I think these cases already follow from the discussion on page 14, which says that if no guard or selector is satisfied then the result is unspecified. I don't object to drawing attention to these cases explicitly. - Shouldn't backquote work on vectors? If not, then what's the rationale for making them work on lists and not vectors? Yes. I observe that backquote works on vectors in Common Lisp (but not on structures, more's the pity). - What kinds of constants should be allowed in CASE clauses? I don't really care, but I can imagine two possible answers: 1. If EQV? is used for comparisons, then it doesn't make any sense to allow strings, lists, or vectors. In the context of Common Lisp, it does make sense because one could use backquote (for example) to construct a CASE expression with a cons cell as a selector and then feed this expression to EVAL. It probably makes less sense in a SCHEME that does not have the ENCLOSE operation. - I definitely want like to flush the () syntax for iteration specs in DO. It is inconsistent for DO to have this alternate form and not LET, and I don't like either. Does anyone actually ever use it? I have no strong opinion on this. - I would also like to flush the ( ) syntax for DO iteration specs. Does anyone ever use this? I always wrap the DO in a LET if I need extra bindings. No replies from people who don't use DO, please. I'm a user of DO, and I draw the following distinction when I write code: a variable bound by a LET wrapped around the DO is merely naming a quantity used a lot within the DO, but that value will not change, whereas a variable bound in the DO itself is explicitly updated by the DO loop using SET! (usually in the body) in a way that is too complicated to be conveniently expressed as a step-form. Regarding the grammar: (a) The handling of quasiquotation is very nice. (b) There is a confusion in the grammar: some parts of it deal in strings of tokens, and other parts in strings of characters. On the face of it it is unclear why spaces can be interpolated to produce "(a b c)" instead of "(abc)" in the grammar for a list but spaces may not be interpolated to produce "f o o b a z" instead of "foobaz" in the grammar for a symbol. The grammar should be divided in the usual way into a character-based lexical grammar for tokens and a token-based parsing grammar for expressions. --Guy  Received: from mitre-bedford.ARPA by MC.LCS.MIT.EDU 24 Mar 86 11:48:21 EST Organization: The MITRE Corp., Bedford, MA Received: by linus.MENET (4.12/4.7) id AA14182; Mon, 24 Mar 86 07:00:16 est Date: Mon, 24 Mar 86 07:00:16 est From: John D. Ramsdell Posted-Date: Mon, 24 Mar 86 07:00:16 est Message-Id: <8603241200.AA14182@linus.MENET> To: rrrs-authors@mit-mc.ARPA Subject: Expunge LETREC, BEGIN and SEQUENCE. I have a proposal that eliminates the need to modify lambda environments by local defines, and at the same time eliminates the need for LETREC, BEGIN and SEQUENCE. For expository purposes, I will introduce the special form DECLARE defined as: (DECLARE (DEFINE a z) (DEFINE b y) ... (DEFINE e r) statement1 statement2 ... statementn) ==> (LETREC ((a z) (b y) ... (e r)) statement1 statement2 ... statementn) In clsch, the macro is: (define-macro (declare . forms) (let loop ((forms forms) (decls '())) (let ((def (car forms))) (if (and (pair? def) (eq? 'define (car def))) (loop (cdr forms) (cons (cdr def) decls)) `(letrec ,decls . ,forms))))) Clearly, DECLARE is a simple generalization of BEGIN. It allows LETREC-like declarations in DEFINE syntax. This interpretation of local defines suggests that they do not modify environments, but create their own. I'm sure that will help those interested in good code. My proposal is to treat every sequence of statements as a DECLARE form. This includes the bodies of LAMBDAs, LETs, DOs and COND clauses minus the guard. Then we can expunge LETREC, BEGIN and SEQUENCE. John  Date: Sun, 23 Mar 86 21:05:39 EST From: Alan Bawden Subject: small changes To: JAR@MC.LCS.MIT.EDU cc: RRRS-AUTHORS@MC.LCS.MIT.EDU In-reply-to: Msg of Sun 23 Mar 86 18:10:53 EST from Jonathan A Rees Message-ID: <[MC.LCS.MIT.EDU].859993.860323.ALAN> Date: Sun, 23 Mar 86 18:10:53 EST From: Jonathan A Rees - Define GCD and LCM to work on Gaussian integers. (Complex numbers are inessential anyhow, so you won't be obliged to implement this - but I'll tell you how if you care.) - Define new procedures NUMERATOR and DENOMINATOR on nonzero Gaussian rationals which return canonical numerator and denominator (denominator will always be a positive integer). Super. I wanted these two in Common Lisp, but they were overlooked in the rush apparently. But you have to be careful about how you state the contract. What you have here is incorrect. GCD on integers always returns a non-negative result. On Gausian rationals you have to define some region of the complex plane that should contain the answer. You want it to include the non-negative integers for compatibility with the non-Gausian case. I would recommend { a+bi | a>0 & b>=0 or a=0 & b=0 }, which consists of the "first quadrant" and the non-negative real axis. LCM is constrained similarly for similar reasons. DENOMINATOR should also be defined to return a Gausian integer in the same region. It would be -incorrect- to always return a positive integer! For example, given (3/2)-(3/2)i, DENOMINATOR should return 1+i, since in lowest terms (3/2)-(3/2)i is 3/(1+i).  Date: Sun, 23 Mar 86 20:38:01 EST From: Jonathan A Rees Subject: Scheme BNF To: RRRS-AUTHORS@MC.LCS.MIT.EDU Message-ID: <[MC.LCS.MIT.EDU].859967.860323.JAR> Here is a draft of my proposed BNF for the RRRS appendix. I would like people to check it for correctness and completeness, and make other appropriate remarks. It will of course be properly fonted and explained in the report, with discussion of *, +, whitespace, ambiguities (there are lots), etc. I'll try to come up with some way to distinguish essential features from non-essential ones. I'm not enamored of the names of the nonterminals, and would be happy to entertain alternatives. A couple of minor problems in the explanations have been exposed by this exercise, which I'll quietly fix. For example, (DEFINE (FOO . X) ...) isn't defined to work in the current report, although I'm sure it does work in everyone's implementation. Questions: - Does anyone object to defining (COND) and (CASE) to return unspecified values? I think this would be a good idea. - Shouldn't backquote work on vectors? If not, then what's the rationale for making them work on lists and not vectors? - What kinds of constants should be allowed in CASE clauses? I don't really care, but I can imagine two possible answers: 1. If EQV? is used for comparisons, then it doesn't make any sense to allow strings, lists, or vectors. So these should be disallowed by the syntax. This makes the grammar a little more complicated, since one has to define what it means for something to be a "casable constant" (I'll come up with a better name than that). ::= ((*) ) ::= | | | 2. Use EQUAL? for comparisons, and allow any . This makes the grammar simpler and makes previously undefined and possibly useful syntaxes meaningful. This is an extension to the language, which some people might object to as being too liberal and/or not useful enough to warrant a change. (There's definitely no efficiency loss except in a very stupid interpreter.) If no one objects, I'll do this, but I won't argue if anyone does object, but I won't listen to anyone who doesn't supply a better word to use for the nonterminal than "casable". ::= ((*) ) - I definitely want like to flush the () syntax for iteration specs in DO. It is inconsistent for DO to have this alternate form and not LET, and I don't like either. Does anyone actually ever use it? - I would also like to flush the ( ) syntax for DO iteration specs. Does anyone ever use this? I always wrap the DO in a LET if I need extra bindings. No replies from people who don't use DO, please. - Oh yeah, I forgot to mention in my previous message that I would like to document DELAY and FORCE, as non-essential special form and procedure, respectively. I believe they're non-controversial, and desirable given that they have a central role in S&ICP and are a little tricky to describe and implement. ---------- ::= * ;This is what LOAD presumably parses ::= | ;This is what a read-eval-print might parse ::= | | | | (lambda ) | (if ) | (if ) | (cond *) | (cond * (else )) | (and *) | (or *) | (case *) | (case * (else )) | (let (*) ) | (let (*) ) | (let* (*) ) | (letrec (*) ) | (rec ) | (set! ) | (begin ) | (sequence ) | (do (*) ( +) *) | (delay ) | ::= ::= ( *) ::= ::= * ::= ' | (quote ) ::= * ::= + ::= (define ) | (define ) ::= ( *) | ( * . ) ::= | ::= | (*) | (+ . ) ::= ::= ::= ::= ( ) | ( => ) ::= ((*) ) ::= ( ) ::= ( ) ::=