R6RS Ratification Vote

Here are the final results of the ratification vote.

67 electors voted to ratify draft 5.97 as R6RS. 35 electors were opposed to ratification. Thus 65.7% of those who voted, voted in favor of ratification. This is more than the 60% required for ratification. The Steering Committee therefore ratifies the draft numbered 5.97 as the official "Revised6 Report on the Algorithmic Language Scheme".

A companion document containing some additional correspondence received after the poll closed is available here.

Voting in favor of ratification:

Voting against ratification:

The language is described and explained very well.

Let me begin this addendum to my vote with thanks to the editors of the report, and everyone involved in the Scheme standardization process. I imagine it must have been a monumental effort, and I appreciate the work put into this wonderful programming language that I like so much. On reading the report and associated documents, and pondering what they contained and did not contain, I ultimately reached a position I expect to be isomorphic to that of all those who vote to ratify the proposal --- 'This putative standard is not perfect, but it is enough of an improvement over the previous state of affairs that it deserves to be ratified.' I have, on reflection, found that all of the imperfections that troubled me are solvable with standard-consistent SRFIs (which admittedly are not necessarily implementable portably) and support from the programming environment. Nevertheless, I feel that two of these imperfections deserve description here, perhaps as fodder for additions to the Rationale document, and perhaps to stimulate the production of said SRFIs. One of the imperfections that troubled me is the apparent inflexibility of the library system. It appears that it is difficult to define and use a library for, say, generic arithmetic, that would extend + and * to work on, say, matrices. Specifically, it appears that if one were to just import (rnrs (6)) and (generic-arithmetic), one would get a symbol conflict and one's program would not run. Consequently, one must explicitly exclude or rename the (rnrs (6)) symbols that are also exported by the putative (generic-arithmetic) library. One is forced to choose whether to exclude all the symbols that (generic-arithmetic) redefines or only to import those symbols from (generic-arithmetic) that one wants, and exclude only them. Both options are unfortunate. Excluding all (generic-arithmetic) symbols from one's (rnrs (6)) import is annoying, especially in the situation where (generic-arithmetic) exports many symbols, such as cos or expt, many of which one might not care about, and which one might need to seek out in the library's documentation. Doing so is also unstable if the (generic-arithmetic) library is updated to overwrite more (or fewer!) symbols from (rnrs (6)). On the other hand, importing only the symbols one wants from (generic-arithmetic) is also annoying, because it is difficult to remember all the operations one may wish to use, because one has to mention them in both the exclude and the import only clauses, and of course because one will then change one's mind about which exports of (generic-arithmetic) one wants. I have high hopes, however, that either a SRFI that extends the library import syntax with a shadow form and/or a clever M-x organize-imports function will alleviate this trouble. The other imperfection that troubled me is the absence of a facility analagous to Common Lisp's reader macros, and even an apparent obstacle to the definition of such a facility. I have several specific use cases for such a facility in mind, mostly to do with literal strings and regular expressions. Regular expressions, for better or for worse, use the backslash as an escape character just like strings do, but with a different set of escapable characters. If one tries to write literal regular expressions in Scheme, therefore, one is forced to double those of one's backslashes that are intended for the regular expression parser rather than the string parser. Furthermore, the natural printed representations of regular expressions will include backslashes, and are therefore grossly unsuitable for copying and pasting into Scheme source. All this is irritating in the extreme, and I wish Scheme had a mechanism whereby I could write a user-land library that permitted something like #/foo|bar/ as literal syntax for a regular expression (in this case, one that matched either 'foo' or 'bar'). In the particular case of regular expressions, a macro won't have the desired effect, because the string out of which one would build a regular expression gets read by the reader, with the attendant substitution of backslash escapes, before the macro-expander sees it. [Note that while I am all for an s-expression language for semantically specifying complex regular expressions, the compact, string-based notation is, in my experience, far easier to read for short, simple ones.] Another use-case for reader macros would be a facility analagous to Ruby's and Perl's string substitution mechanisms. I would like to be able to write what amounts to quasiquote for strings, and while the bulk of the work can certainly be done by a macro, it would be nice to have a short cut analagous to the backquote, perhaps sharpsign doublequote, for all of the same reasons. Yet another use-case for reader macros are here documents, again inspired by Perl and Ruby. Those languages provide a facility for embedding comparatively long documents into one's source code as string literals. Long literal strings have different needs from short ones, for instance in that the usual string delimiter characters may appear in them. Therefore, the here document facilities I am familiar with give the programmer control over the end delimiter used (often the word END or HERE on a line by itself, hence the name of the facility) and some control over the amount of string interpolation that is done on such embedded texts. Scheme could benefit from a library for this, and it seems that such a facility cannot be implemented as a macro over data that has already been processed by the reader. I have made the case that there are extensions to Scheme's lexical syntax that are worth considering adding to the language. They are sufficiently disparate and special-purpose that it would be aesthetically displeasing, to say the least, to implement them all as separate, one-off additions to the syntax of the language. They are also complex enough that it would be very valuable to be able to implement them as user libraries and actually experiment with how well they work, without having to recompile one's Scheme, before submitting SRFIs proposing specific variations to the larger community. In fact, it would be valuable to be able to use such extensions in one's own work, portably across implementations, without having to secure the community's consensus at all. I am therefore troubled by the paragraph immediately preceding Section 4.1 of the main report, which appears to throw up an obstacle to the implementation of reader macros or any analagous facility as a SRFI, in the form of a prohibition against any changes of the lexical syntax of Scheme whatever. One reading of that paragraph suggests that that impression may be mistaken, as a SRFI that introduced a shebang directive like #!srfi-314-reader-macros which signalled that subsequent code was subject to interpretation according to the reader macro facility specified in this hypothetical SRFI 314 would constitute a standard-compliant extension adding reader macros, but such a directive feels like an awkward increase in boilerplate, and begins to smack of a thrid-party code distribution mechanism completely orthogonal to the library system. Whether or not that reading of the report is, in fact, the intended one, I would greatly appreciate a rewording of the relevant segments to make that clearer, as well as a section of the Rationale document explaining why the editors of the report reached the decision that they did about reader macros.

I think the draft is a good continuation of the current standard. In particular, I like the newly introduced concept of libraries, that the handling of unicode characters is specified and that error conditions can be handled within a Scheme program in a standardized way.

I am an idiot for not replacing this text.

While there are some aspects of R5.97RS that I'm uncomfortable with, I think it's an overall step in the right direction. I'm confident that time will tell which aspects of the report need to be corrected, and that this will be done for R7RS.

I am voting 'Yes' for ratification of the current R6RS draft. My belief is that the draft represents a step forward for Scheme and that it accomplishes stated goals of the editors like unicode support, libraries and exceptions. In addition, I wrote in my registration statement that one of the criteria by which we should judge this standard is whether it provides clear direction on how to accomplish basic programming tasks in a way that does not require building your own infrastructure, or resorting to implementation-specific features. I believe that the current draft standard does an acceptable job meeting this criteria by providing standard mechanisms for things like exceptions and tagged records. I would like the thank the editors for their hard work and dedication in bringing the standard to its current state.

I confess that I didn't follow the development process of R6RS closely, but I have spent considerable time over the last few weeks reading the report and the various email trails carefully. I started out feeling pretty negative about the report. I really liked the 50-page tight simplicity of R5RS. But I've made my peace with most of R6RS. I do appreciate that there are a number of things that are specified in much greater detail, and/or better explained, and/or made more consistent. And while I'm not sure of the need for *all* the macro facilities, I'm willing to believe that they were felt necessary by people with more expertise in this area than me. A few minor observations: The terms *static* and *dynamic* scoping are used, and perhaps it can be assumed that the reader of this report would know what they mean. But it couldn't hurt, for instance, when explaining how a lambda expression evaluates to a procedure, that the particular method of evaluation implements static scoping. The term *deprecated* is used twice in the report, and twice in the rationale, but as far as I can see, is never defined. And I think in addition, that some justification should be given for the deprecation of features. I'm particularly concerned about force and delay, but the point is general. Some answers are hinted at near the end of the rationale document, in a very terse fashion, and force and delay aren't dealt with at all. I don't understand the way the base library functions in the report. In particular, I don't see why the base library isn't just part of the language. I mean, you don't have much of a language without arithmetic, for example, right? Why does a program need to explicitly import it? (Or did I miss something?) I know that in general, there is no definitive answer to why something gets in a language report. The ultimate answer simply is that the vote went that way. Nevertheless, I think the time may be right for an expository piece -- perhaps even a short book -- that attempts to justify the current definition of the language. Another obvious question, for instance, is this: Since call/cc has always been regarded largely as the Scheme escape mechanism, why was a new escape mechanism introduced in addition? And does this now do away with the need for call/cc? (I assume the answer is no, and I think I could even come up with a reason myself, but I'd like to see some discussion of this. It would at least be interesting, I think.) Maybe the answers to all these questions are available in the report or the email trail. But I'll bet that if I missed them, then a lot of other people did, or will, as well.

I find the current draft to be an excellent compromise. Building a standard that is acceptable to the community as a whole, especially one as opinionated as the Scheme community, is clearly going to make no one completely happy. However, R5.97RS contains all of the elements that I feel the new standard needs, perhaps not in exactly the same form as I would have specified them, but definitely in a form that should be acceptable to any implementer. Therefore I am voting TO RATIFY this draft of R6RS.

R6RS is a huge step forward. May its fulfillment match its promise.

The 5.97 draft standard brings Scheme up-to-date, helping to make it a viable alternative to more popular languages such as Java and Python. It library feature promises to facilitate a much larger body of portable Scheme code. And although these languages are improving, by borrowing ideas from Scheme and other functional languages, they still sorely lack features of Scheme which are important for my work, such as s-expressions and macros, which are incredibly useful for implementing domain specific languages. I understand that 5.97 may not be perfect from an academic point of view, but Scheme standards are living documents. The SRFI process and future versions of the Revised Report provide procedures for continuing to improve the standard. And Scheme implementors are surely free to make non-standard improvements and extensions, as they have in the past.

R5.97RS is a reasonable candidate. Ratifying it now is better than wait and quibble about details for an indefinite time. There is no doubt that this report has numerous advantages over R5RS and implementations should support it as soon as possible.

Reading through all of the electorates stated concerns makes me feel nostalgic; thinking back to that moment I first fell in love with computer science. Scheme seems to have that effect on people; love at first sight. Having read once that 'any truly good language, no matter what its original goals, will eventually become a general purpose programming language; that is the nature of a good language', I can't help but think that Scheme has this nature. Scheme is special. It draws people in. It is a place to learn, and play. My hope is that the direction set forth by R6RS will prepare Scheme for the masses, giving it an opportunity truly shine.

The proposed standard is an enormous improvement in my opinion. It makes the language much more complete and easier to use for various tasks. Most importantly, it will allow practical support for the language to grow rapidly. I would not be surprised if the proposed standard, if accepted, turns out to be a major breakthrough for the language.

No comments

I think that this version (5.97) is good progress to a better standard of Scheme, the basic ideas---lexical scoping, continuations, ...---being still present. Concerning the language itself, I especially appreciate: ---the notion of libraries, ---the way the standard libraries have been built, ---the definition of exceptions. My regrets: ---some functionalities related to handling files and directories are missing, ---the functions dealing with Unicode could have been more powerful. About the report, I appreciate the clear distinction among must/must not/should/shoud not/may. To conclude with a personal touch, I would be ready to rewrite MlBibTeX---my new implementation of the BibTeX program---using this new version.

I vote yes, not because I think R5.97RS is perfect, or because I agree with every detail of it, but because I think it is good enough to become the next generation of Scheme. See my registration for further explanations. R5.97RS is a compromise, and a well-crafted compromise is in my opinion the most sacred thing that a secular age knows.

Almost all of the proposed changes increase Scheme's usability more than they reduce its simplicity and elegance, even for novice programmers.

Scheme needs facilities for portable development.

I believe that R6RS will unite the Scheme community and reduce incompatibility between implementations.

Other people express their opinions so good that I will refer to them. Essay of Matthew Flatt says it all about a process of standartization: polishing current document will take lots of time and will add very little, we can wait for perfection forever. Let's make a milestone and see what will happen next. Developers of Scheme implementations who will like the result will soon make their products to be standard-compliant, others will stay with old standards, so we will clearly see how popular new standard will be. Previous standards also had some missing parts, which were added by subsequent standards, and had some unnesessary parts, removed by subsequent standards. Regarding a direction where Scheme standard is going, I will refer to essay of John Clements who calls for unity in areas which are no longer experimental field, but practical nesessity.

I've looked over the 5.97 draft and read the criticism that it includes too much. However, I disagree. While simplicity has always been one of the hallmarks of Scheme, the extremely small core language makes fragmentation between implementations inevitable. I believe that a more thorough standard is required to ensure potability.

The current 5.97 draft standard represents a reasonable consensus among the Scheme community and will serve well as the basis for future evolution of the language.

Although not perfect and still containing many areas that can be improved (as seen in the electronic discussion), I vote for approval. What we have here is a solid basis from which we can continue to guide the evolution of the Scheme standard. I see R6RS not as having reached the end goal, but as a step in the devlopement process. I thank the members of the committee for their time and effort.

The library system is an incredible step forward. It brings us closer to being able to write large systems that are portable across multiple implementations.

R6RS is "perfect".

Progress before perfection

I wanted to vote against ratification because some aspects of the standard are less than perfect. It's the tension between "the right thing" vs. "worse is better". This time Scheme needs a splash of "worse is better" to move the language standard forward. Let's hope some experience can help the next standards group reach for the right thing.

It's not perfect, but it's good enough, and I'm happy to leave pursuit of perfection to the r7rs editors.

A more extensive standard will make it easier to convince colleagues to use it.

Reason for voting yes: pragmatism. If I am to continue to write Scheme code, I must be able to make use of multiple implementations without bending over backwards to do so.

The current draft is not perfect, but it is a clear improvement on R5RS and takes Scheme forward in the correct direction.

It is time for Scheme to move forward.

Well, it's not terribly clever of me but I will steal a quote that J.H. Conway uses in the preface to 'On Numbers and Games' from Bunyan's 'Apology for his Book (Pilgrim's Progress): Some said 'John, print it'; others said 'Not so.' Some said 'It might do good'; others said 'No.' It will be a waste of time to drag out discussion of the draft much longer and, even for all the objections raised, 'it might do good.' Meanwhile, if there is long-term substance to the dissent, I am hopeful that that that dissent can gracefully congeal in and exploit the SRFI process to evolve things beyond the current draft. If it seems I'm saying 'Sigh. It'll do I guess. Good enough,' well, I suppose I am. That's not feint praise, though -- not for R_RS.

I no longer feel strongly enough about the case-sensitivity issue to throw a monkey-wrench into the whole ratification process. Besides, with Unicode being allowed as <constituent>s of <identifier>s, the case mapping would get complicated. If it was only <letter>s that were at issue, then it would expose a certain 'Roman' bias in the language. After all, it is easy to imagine someone having a good reason for an upper-case Greek letter being destinct from its lower-case counterpart.

greater compatibility between implementations

I would gladly trade a report full of mistakes---not that I think this is such a report, but some do---for a library system which properly handles hygienic macros. Therefore, I am voting "Yes" on R6RS. (The exception specification is just icing on the cake, as far as I'm concerned.) Some consolation for those who do think this report is full of mistakes: 1. I expect we'll be seeing lots of "(r6rs base)"-compliant implementations which leave off libraries they don't like, and 2. "...in most matters it is more important that the applicable rule of law be settled than that it be settled right." --- Burnet v. Coronado Oil & Gas Co., 285 U.S. 393, 406--408 (1932) (Justice Brandeis dissenting).

There are a number of good, nice things that I see being made available in this draft at a high level, and I greatly applaud the efforts of the committee to develop something that fosters the important goals of portability and simplicity. However, if I were to sum up my objections to ratifying this current draft, it would simply be that this draft no longer maintains what I have come to believe to be the core philosophical values of the Scheme language. This draft appears to diverge so significantly from the other drafts in terms of organization, size, and scope, that it seems like it should not even be considered the same species. While I cannot call myself qualified enough to discuss the minute details of language specification and detail, I can come at this from an user who has utilized Scheme for pedagogical, professional, and research uses. If the language fails to be able to provide for these three sectors, it fails to adequately serve its purpose. I believe that the standard falls short of meeting what I would consider essential advantages of Scheme in all three of these areas. It appears as though this standard attempts to bring in the ideas or concepts of other languages in an attempt to convert the language from a Beautiful Lisp language, to just another common programming language with some cool features and a strange syntax. That is to say, the focus seems to have been lost. Let me first deal with the pedagogical area. This draft removes the aspects of elegant simplicity and limited scope that make Scheme such a great language for teaching. Right now, Scheme is easy to learn, because the core concepts are simple, and they extend outward in reasonable, predictable ways. A student who is learning to program can focus on a small aspect of the language and feel comfortable with tackling the rest of it later. As I see it now, the standard has become massive relative to R5RS. Not only does its size hinder a new student, but it also makes creating simple conforming Schemes that are easy for a newcomer to learn impossible. Now, I do teach, but more pressing on my needs are research and professional development. I see severe limitations of the language with regards to professional development. Something that was great about using Scheme for professional development was that I could precisely mold my implementation and code to fit the task at hand precisely, rather than using large, sledge hammer tactics, such as is often the case with over engineered OO designs. Many of these features included in this draft are absolutely useful features that I like to have in an implementation. However, to require them in the standard limits the capacity of the implementors to work in small, specialized fields. Embedded devices immediately come to mind, but other things also come to mind, such as applications that may not desire unicode, libraries, or other pieces. Granted, I do believe in the goals of interoperability, which is one of the most problematic issues with Scheme's. I am not happy with the way the library, unicode, disregard for very standard SRFI's, such as SRFI-1. There does not seem to be enough flexibility given to the implementors to do things in ways that might suit particular applications. Put simply, the goal of interoperability should not be achieved by demanding that one size fits all. Rather, there should be discovered some way to simplify, rather than add on features, and to reduce the total bloat in a way that permits such bloat as extensions if desirable, but allows this to be done in a way so that applications may have confidence of running unmodified on other implementations assuming that the needed extensions exist. Rather, this standard assumes that features exist, and hopes to provide portability in this way. I do not like this. While I would love to see the features outlined here in implementations, I also wish to respect the flexibility of the language to permit specialized and very minimal implementations, without having to break with the standard. Now I'd like to come to one of my own personal rants. Case-sensitivity. The change to case sensitivity flies in the face of Scheme tradition, for little to no benefit. To suggest such a major change in the standard, imo, for absolutely no significant benefit, against the traditions of Scheme, seems to be very, very ugly. Besides the fact that its easier to add Case-sensitivity in than to remove it in individual implementations, I very much dislike this new addition, and take it as my example that this standard is trying to change the heart of Scheme. Thus, therefore, No.

As many other schemers I think that what makes Scheme great is its reduction to the strict minimum. I must agree that nowadays, a language that does not handle UTF-8, should it be in strings or identifiers, irritates me quite a bit. I also believe that a language that clearly lacks a module/library/embedded-regexps system often ends up being a real pain to use. And I am not the only one to reimplement FOLD-LEFT or FILTER more than once a day. Of course, there are some SRFI's out there supposed to make our lives easier. And I believe in that. In fact, I believe a lot more in time spent developping new SRFIs, than in time spent wondering about the best character set. For this reason, although I agree more than I disagree with the R6RS draft, I decided to vote 'No'. I personnaly stick more to R4RS than even R5RS (for I like plain old dirty DEFINE-MACRO and its lack of hygiene), and I see no point in supporting R6RS. Moreover, I reckon that it will make Scheme too much complicated for a gain not worth it. I suggest well all focus on defining vital SRFIs, and that we all agree on portable extensions of Scheme, to implement, say, TCP/IP, non blocking IOs or bindings to a graphical library. I think that it costs too much to add a module system, and that this should be left to the maintainer of implementations to give their own if they want. Yet, whatever system they use (shoud it even be built-in or 'built-over' as Snow), we should agree on definining and sharing APIs for just anything we find useful. Eventually, I decided to say No to R6RS, not because I think its fundamentally bad, but because I think that it is definitely not what we should be focusing on. Think of it as an 'I say no for your own good'. I hope that the community will always be open and eager to share and compare opinions, as it is now, and that the next major evolution of our langage will not rely on its already genetically well fitted design, but rather on its ease of use for whatever challenging task we encounter. And that sockets will be implemented eventhough no generic portable implementation could be given. In fact, I see Scheme as someone with a psychic disorder. We have a well defined language, we can think with it. But we spent (and still spend) so much time in defining the language itself that we eventually forgot to define the way to speak and communicate with the outside world. And R6RS does not solve this issue, neither does it offer the tools to solve it. Let's keep Scheme small, but let's add some new plugs to it. (No Scheme implementation was hurt during the redaction of this ballot. And the camel was already dead, I swear.)

1. Prolog ========= The candidate R6RS has been prepared over several years by a distinguished group of editors. They have worked hard to identify and solve problems in the R5RS to make Scheme a more useful language while remaining faithful to its origins. In particular, they have engaged in a public discussion of various drafts over most of the last year. We are indebted to the editors. 2. Vote ======= With regret, I vote to REJECT the candidate R6RS. 3. Reasons For Rejection ======================== The steering committee requires that votes to reject the candidate be accompanied by an explanation. My five reasons are given in this section. 3.1. Implicit mantissa widths ----------------------------- Section 4.2.8 of the candidate R6RS requires If x is an external representation of an inexact real number object that contains no vertical bar, then its numerical value should be computed as though it had a mantissa width of 53 or more. Such implicit mantissa widths have not been justified in the rationale or in discussions on the r6rs-discuss mailing list. It is not clear what problem they solve. The use of 'should' indicates that this is a recommendation. As such, this does nothing to solve problems of incompatibilities between implementations. On the other hand, it is simultaneously harmless and dangerous. Harmless because the 'or more' implies that the value might be calculated in infinite precision (i.e., exactly) and dangerous because it permits double rounding (e.g., if the implementation would represent the result using an IEEE double-precision format and the value is subnormal or if the implementation would represent the result using an IEEE single-precision format). 3.2 No Rounding Mode for Mantissa Widths ---------------------------------------- The candidate R6RS does not specify whether 0.75|1 should round to 0.5 or 1.0. This makes the mantissa widths unportable between implementations. 3.3 Explicit Mantissa Widths ---------------------------- Two reasons have been given for including explicit mantissa widths. Will Clinger [1] stated: The |p notation is a replacement for the # notation that the R5RS used for nonsignificant digits. One of the things we learned from this process is that many Scheme programmers, perhaps even a majority, and apparently including several implementors, were interpreting # to mean 5 rather than 0. That doesn't work, because it makes the numerical value depend upon the number of trailing #s, which are supposed to be insignificant. We also learned that hardly anyone is using the R5RS notation. Mike Sperber [2] stated: The way we have it now (I hope) at least gives implementations a chance to exactly represent binary floating-point numbers on output in external representations. I note that these justifications are in apparent conflict. One suggests that the |p notation is supposed to be an indicator of less precision and the other suggests that the same notation is supposed to be an indicator of a more precision. I would suggest that the |p notation goes against the guiding principle that 'programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary.' I would suggest: Continuing to use # to indicate imprecision, but tightening up the definition so that it is clear that it is to be interpreted as 0 and not 5. Alternatively, since 'hardly anyone is using' this notation, eliminate it. Extend the lexical syntax of inexact numbers to allow mantissas to be read and written in binary, octal, decimal, and hexadecimal. (An ambiguity in the syntax for non-decimals could be required by requiring a point at the end of the number or immediately before the exponent so, #x0e0 is an exact integer not an inexact zero whereas #x0. and #x0.e0 are inexact zeros.) The number->string procedure should also be extended to allow for non-decimal radixes for inexact numbers. 3.4 Records ----------- Andre van Tonder [3] and Will Clinger [4] have pointed out an incompatibility between the procedural and syntactic record layers. I would like to see this issue discussed and, if possible, solved. 3.5 Library Versions -------------------- I am completely unconvinced by the need to embed library versions in import specifications. I might support a means to label libraries with versions and to make that information available to importing programs or libraries at run-time (e.g., so they can abort if version X.Y of a certain library is imported). However, in general I believe that matching library versions should be solved outside of the language. 4 Other Issues ============== In this section I describe two issues which in themselves are not reasons to reject the candidate R6RS, but which I find very uncomfortable. 4.1 No Characters Beyond Unicode -------------------------------- Tom Lord [5] and John Cowan [6] have suggested that implementations be allowed to support characters beyond Unicode. I support this suggestion. 4.2 Inappropriate Syntax ------------------------ I am uncomfortable with the implementation of file-options, buffer-mode, etc., as syntax rather than procedure. [1] http://lists.r6rs.org/pipermail/r6rs-discuss/2007-June/003049.html [2] Private email. [3] http://lists.r6rs.org/pipermail/r6rs-discuss/2007-July/003080.html [4] http://lists.r6rs.org/pipermail/r6rs-discuss/2007-June/002825.html [5] http://lists.r6rs.org/pipermail/r6rs-discuss/2007-June/002863.html [6] http://lists.r6rs.org/pipermail/r6rs-discuss/2007-June/002878.html

'Programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary.' This is the first sentence in the introduction to RnRS for a reason. It is the heart of what Scheme is - a powerful general purpose programming language expressed with just a few primitives. As with any other good idea, it can be taken to an absurd extreme, and there's more than a little room for leeway in its interpretation, but the R6RS draft is so far removed from the idea that it destroys the whole spirit of the language. To be clear, I don't mind the large report, and am in fact happy that a large selection of standard libraries was included. What I object to is the fact that these libraries are not built on simple primitives, but many of them are in fact incompatible extensions to the language, and features which imply core semantic changes. The R6RS draft has piled feature on top of feature with no attempt to minimize. There are many minor points to the draft I dislike that I won't bother to mention - below I list only those issues which I consider the most egregious. * Identifier syntax. Anything done with identifier syntax can be done with normal syntax, replacing X and (SET! X Y) with (X) and (X Y) or similar. Thus this is purely syntactic sugar. It's an interesting idea, with the intent of making pseudo-variables, but at the same time complicates the semantics of the language. Identifiers may no longer be simple variable references, making code potentially more difficult to read. Moreover, it weakens every macro in the entire language by removing knowledge about the language the macros are expanding. For example, the simplest implementation of the LET-OPTIONALS* macro used in many SRFI implementations I'm aware of is the following: (define-syntax let-optionals* (syntax-rules () ((_ opt-ls () body ...) (let () body ...)) ((_ (expr ...) vars body ...) (let ((tmp (expr ...))) (let-optionals* tmp vars body ...))) ((_ tmp ((var default) . rest) body ...) (let ((var (if (pair? tmp) (car tmp) default)) (tmp2 (if (pair? tmp) (cdr tmp) '()))) (let-optionals* tmp2 rest body ...))) )) This takes advantage of the fact that only parenthetical expressions need to be bound to temporary variables. With identifier syntax, this is no longer true, and the above macro cannot even be written without helper macros or artificial pattern literals. This is a complication and inconvenience, but there are workarounds. There are other macros, however, such as the FAST-MATH macro at http://synthcode.com/scheme/fast-math.scm which are no longer even feasible. The introduction of identifier syntax makes it impossible to write this kind of macro. Identifier syntax is a cute gimmick but is seldom used, and no one is clamoring for it to write portable code. For the weaknesses it introduces, to make it a required feature of every Scheme implementation is absurd. * SYNTAX-CASE. Almost everyone wants low-level and unhygienic macros, but SYNTAX-CASE is an unfortunate choice of systems. Both syntactic closures and explicit renaming macros are older, and are simpler and more in the spirit of Scheme. SYNTAX-CASE provides a bizarre mix of low-level macros with high-level pattern matching, but a true low-level system should be orthogonal to such matching, allowing the programmer his choice of pattern matching or other utilities. * `_' and `...' patterns. It's unfortunate that R5RS macros can't match `...' as a literal in templates, but with the same restriction on `_' many existing macros will break, and moreover they have no easy workaround, requiring otherwise simple pattern matching macros to be rewritten in much longer and more convoluted low-level code. Simply allowing these as pattern literals solves the issue without introducing any new issues or ambiguities, and this was even suggested on the list but was ignored. * Versioning in modules. This is just premature. There are a lot of different possible ways of handle the problem of library versions, and they need more exploration before standardization. Everything done with versions in the current draft could be added in a backwards compatible manner in future drafts. * Unicode. Scheme has been around for a long time, and has seen many encodings come and go - there's no reason to bind it to a single encoding forever. An appendix or separate document(s) specifying behavior for Unicode-based implementations could always be written for compatibility. ** Normalization forms. STRING-NORMALIZE-NFD and the other three normalization procedures handle normalization at the wrong level. It's inherently an encoding issue, and is best treated as such. Providing this functionality at the string level forbids the implementation strategy of keeping all strings in the same normalization form - a very appealing strategy on many levels. ** O(1) string access. This suggests all Schemes to use UCS-4 character vectors for their string representation, discouraging the use of alternate representations such as UTF-8 and ropes or trees. ** Character-level case mappings. Case in Unicode is a string-level concept - providing case utilities at the character level encourages programmers to write broken algorithms. * I/O. The I/O system was totally rewritten for no reason, and all aspects of it controlled with gratuitous syntactic forms - second class forms which discourage high-level procedures. * Enumerations. There's simply no reason for this, since Scheme has traditionally used symbols for the same purpose. The one place where enumerations are truly required would be in an FFI, but the R6RS draft provides no FFI, and the enumerations provided would be insufficient for any FFI since they don't even let you override the integer values of individual symbols. * Exceptions. The exception system is far too large and over-specified. Exceptional situations should be treated as such, and implementations should be free to experiment with extensions in these areas. For these and other reasons I feel I have no choice but to vote against ratification of the current R6RS draft. The extent of the change is so great I feel the draft can only be considered a new Lisp dialect - the name `Scheme' does not suit it.

IMPORT LEVELS: The draft does not specify how to write portable libraries that define or use macros with literals. In particular, the draft does not say whether uses of literals such as DEFINE, ELSE, ellipses, and so on (in other words, the arguments of free-identifier=? - when the comparison succeeds) count as references for level checking. Thus, users will be forced to resort to cargo-cult programming in the hope that their code will be portable. RECORDS: I think the constructor-related parts of the syntactic record layer and of the procedural layer are bewilderingly complex. The custom constructor design is a good example of premature generalization and piling feature upon feature, and since their current API adversely affects other aspects, such as modularity, of the design, as discussed on the list by Will Clinger and myself, I believe it would be better to drop custom constructors completely unless a simpler and better design can be agreed on. Such a design may be better left for a future SRFI. Only a minority of record applications use custom constructors, and these can always be expressed in terms of standard constructors (we have libraries for hiding unexposed names from the client if necessary). By the way, I do not think inheritance makes custom constructors necessary in the base API, since users can easily roll the current custom constructor functionality themselves without, I believe, loss of performance or modularity. LIBRARY VERSIONING: I do not think that versioning information should be in source code. Also, the version reference syntax is very complex and rather ugly. ENUMERATIONS: I cannot reconcile the presence of this library with the philosophy of prior Scheme reports or with the r6rs mandate. It seems an example of premature generalization and piling feature upon feature. I would prefer that it be dropped completely and left for a future SRFI if enough people feel the need for it. SET!: There is no way of importing set! for a single level. This limits the languages that a library designer can create. I would suggest the addition of a library (rnrs mutation) that exports only set! for level 0. The (rnrs base) library can still export set! for levels 0 and 1 if desired. LIBRARY INSTANTIATION: The draft links library instantiation and visitation not to import clauses, but instead to the presence of identifier references in the client, and provides no guarantee of instantiation otherwise. Again, I worry that this may force users to resort to cargo-cult-like programming (such as inserting otherwise unnecessary variable or macro references in client code whose only purpose is to force an instantiation or visitation) in an attempt to ensure portability. I would urge instantiation and visitation to be guaranteed at least for the declared import phases (this should be compatible with both explicit and implicit phasing models). CONDITIONS: Although the conditions API has seen improvement, I worry that the division into simple and compound conditions, along with the infrastructure required to manipulate these, is overly complex and may be awkward to use in practice. I would love to see a simpler design - perhaps something as simple as an alist-like object may work quite well and allow the current plethora of types to be replaced by properties instead. ======= I do not consider the following objections dealbreakers, but I would like to list them for the record: SYNTAX-CASE: The description of the mark-antimark algorithm significantly lengthens and increases the complexity of this chapter. It is hard for me to understand despite being an implementor (granted, I use a different algorithm). The draft could be simplified by cutting this operational description, especially since this is not the only algorithm, or even (to me) the simplest algorithm for implementing hygiene. A more declarative description in the spirit of r5rs, as already given in the introductory paragraphs of the draft section on hygiene (perhaps with some small refinements and examples), already says it all and could make this chapter considerably cleaner and shorter. COMPOSITE LIBRARY: I do not think (rnrs) should export define-syntax and let[rec]-syntax for level 1, or syntax-rules for level 0. In the context of the (rnrs) import, there is nothing one can do with these bindings at those levels.

Deliberating on the latest R5.97RS draft I find much that is agreeable about it, and it would be tempting to vote for its ratification. Indeed if but the programming language described therein would be named anything else than Scheme, it might seem the promising start of a practical and useful modern Lisp dialect. Yet as the R5.97RS main and library reports still read today, the resulting language is most definitely not Scheme. My primary issue with the draft is that it betrays the spirit of its very own opening paragraph: 'Programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary.' I should very much hope that paragraph will never be removed in future RnRS reports! Evaluating the rest of the main and library report against that principle, I think it stands out that the draft has simply suffered considerable feature creep and is vastly overspecified and overcomplex. In a word, it is too ambitious (or presumptuous, depending on your point of view). I'm convinced the draft as it stands would derail Scheme, in the sense of putting the language on a course that it is unlikely could be easily corrected through later RnRS iterations. Thus I must at this time, with apologies to the editors, vote against ratification and hope that there will be enough dissenting voices to reopen the editorial process. If the vote concerned only the main report in something not too far from its present form, ratification would not be an unfeasible prospect; and this despite the report having almost doubled in size. I do share others' misgivings on issues such as requiring the full numeric tower and chaining Scheme at the hip to Unicode; still, the main report all in all appears decent, and a standardized library definition facility, even if the current proposal seems rather overcomplex, would be a most important practical benefit provided by core R6RS. However, the proposed standard library report is simply unacceptable. Not only does it gratuitously eschew important and widely-used existing SRFIs (such as the SRFI-1 list library, and SRFI-69 hash tables) in favor of its equivalent incompatible functionality, but one must ask why features such as, say, byte vectors, enumerations and hash tables should even be included in the RnRS reports in the first place? The desire for a standard library is widespread, both for reasons of portability and practicability, but I think it is clear that when it comes to library functionality, the SRFI process has proven itself and works better than the committee process being voted on here. Attempting to evolve a standard library through the rightly slow- moving RnRS process seems to me shortsighted and counterproductive in the long run. Thus, I consider the standard library report largely superfluous and indeed harmful. Instead of attempting to set in stone a controversially large standard library with the RnRS process, I believe the R6RS committee should strictly confine itself to the core language only, and fully embrace the SRFI process for the standardization and dissemination of all non-essential library features.

There are many flawed aspects of R5.97RS, which time does not permit me to cover. I will describe three. Macros In the R5.97RS introduction: Scheme demonstrates that a very small number of rules for forming expressions, with no restrictions on how they are composed, suffice to form a practical and efficient programming language that is flexible enough to support most of the major programming paradigms in use today. This was true of R3RS and R4RS, but not for R5RS and R5.97RS. In R3RS and R4RS there were a small number of rules for forming expressions: DEFINE, QUOTE, LAMBDA, IF, SET!, BEGIN, COND, AND, OR, CASE, LET, LET*, LETREC, DO, DELAY, QUASIQUOTE, and combinations. I have 70,000 lines of mathematical, scientific, engineering, database, and scripting software written in (R4RS) Scheme showing that this small number of rules is "flexible enough to support most of the major programming paradigms in use today." One reason that this large multi-author corpus of (free software) Scheme code can be actively developed and maintained is because R4RS code is very readable. In a R4RS compliant file, it is easy to see which lists are expressions which might be evaluated; there are no new syntactic tokens which can be mistaken for identifiers. The use of LAMBDA in arguments to procedures establishes binding scope, no matter what those procedures do. The significance of this achievement by R4RS is not widely appreciated. Procedure are sufficient to create nearly any new features. Even new control features do not require new syntax. EVAL, VALUES, CALL-WITH-VALUES, and DYNAMIC-WIND, added in R5RS, are all procedures. In the R5RS introduction: More recently, Scheme became the first programming language to support hygienic macros, which permit the syntax of a block-structured language to be extended in a consistent and reliable manner. Extending the syntax would be desirable if Scheme's "small number of rules" were *not* sufficient "to form a practical and efficient programming language ...". But SLIB and other softwares show that R4RS is sufficient. The effect of adding macros to Scheme has been the proliferation of mutually incomprehensible language dialects. We have seen the growth of "convenience" macros like WHENNOT and UNLESS, use of macros as a substitute for compiler optimization, and use of macros to avoid using symbols as tokens. None of these uses increases the expressive power of the language. In a reusable software world, the use of incompatible dialects is detrimental; it is only through documenting, publishing, and deliberating, say in a SRFI, that new forms should be adopted into that "very small number of rules for forming expressions". Arrays Computations have been organized into multidimensional arrays for over 200 years. Applications for multi-dimensional arrays are widespread and continue to arise. Computer graphics and imaging, whether vector or raster based, use arrays. A general-purpose computer language without multidimensional arrays is an oxymoron. Although multidimensional arrays are the subject of SRFI-25, SRFI-47, SRFI-58, and SRFI-63, and portably supported by SLIB, search of http://www.r6rs.org/r6rs-editors/ finds nothing to indicate that the editors ever considered their inclusion in R6RS. Can R5.97R Scheme be extended to support SRFI-63 arrays? Libraries SRFI-63 redefines EQUAL? to work on arrays. But in the R5.97RS module system, a SRFI-63 library exporting EQUAL? will conflict with the RNRS language export of the same name. Thus any import of the array library (and there are many in SLIB) will require that EQUAL? be excluded from the import of RNRS. Thus the R5.97RS library mechanism fails to be modular; users must know and exclude from modules any exported redefinitions, whether or not they use those identifiers! This is more than an inconvenience. R5.97RS prevents the sort of language extensions which are a hallmark of LISPs. Consider SLIB's COMMUTATIVE-RING module, which captures and redefines *, +, -, /, and ZERO? to work on expressions: (require 'commutative-ring) (set! *ruleset* (combined-rulesets distribute* distribute/)) (define a 'a) ... (define z 'z) (* (+ a b) (- a b)) ==> (- (^ a 2) (^ b 2)) (require 'determinant) (determinant '#2A((a b c) (d e f) (g h i))) ==> (- (+ (* a e i) (* b f g) (* c d h)) (* a f h) (* b d i) (* c e g)) In R5.97RS, the DETERMINANT module bindings for *, +, -, and / would be unaffected by the COMMUTATIVE-RING extension. Even creating a new language binding to supplant RNRS is no help without modifying the source code of the DETERMINANT module. The R5.97RS library system has significantly reduced the expressive power of Scheme; it is no longer possible to extend built-in procedures to new types in a modular fashion. Conclusion The framework to extend R4RS and R5RS (through redefinition) made it possible to provide those features that Scheme lacked in a portable and modular fashion. R5.97RS not only lacks the multidimensional arrays essential to my work, it has removed the means for remediation of its deficiencies.

- Requiring the full numeric tower works against using Scheme in smaller environments such as embedded systems. - Procedures such as div0-and-mod0, exact-integer-sqrt simply do not belong in a base language. In fact a lot of the numerical procedures belong in a library. It is perfectly meaningful to say that if a specific library is implemented, it must meet the entire spec. but *all* libraries must be optional in a base language and a base language implemener *does not* have to provide all libraries. Even C does this! Surely, one of the rationale for Scheme was minimalism? - R6RS is not good enough for commericial usage since it lacks a FFI to interface it with libraries implented in C/C++ (such as system libraries, graphics etc). And it specifies too much for an experimental language. Neither fish nor fowl. - I would have preferred R6RS to be *smaller* than R5RS, where some of the required features get moved to optional.

When this process started, I expected to reluctantly vote for approval. However the discussion has been very illuminating, and the arguments against ratification have been both cogent and convincing, while those in favour have, at least to my mind, been less so. Here are the arguments that convinced me. Some are due to an excellent post by Alex Shinn dated 29-May-2007, while others are distilled from posts by David Rush and Jeffrey Mark Siskind. First, there is the question of why we want or need an Official Scheme Standard, and what the goal of the "RnRS process" should be. It seems to me that, broadly speaking, the draft R6RS has the goal of making Scheme be like C or perl: a workable programming language like other programming languages. This seems reasonable on its face, but Scheme has survived for a long time by not being a programming language like others, but rather by being an oddball: minimally specified, usable for real-world programming only by using numerous implementation-specific features, but ideal for teaching and research. Scheme is the defacto lingua-franca for programming language theory. R6RS and its associated mindset flies directly in the face of Scheme's historic strengths, and to my mind risks diluting them. If this were to occur it would be a disaster. In other words, it is not clear to me that the draft R6RS is moving Scheme in an appropriate direction. Second, it is not clear to me that the draft R6RS even specifies the right things to make Scheme industrial strength. This argument was made quite forcefully by people who actually do use Scheme in real-world settings. Third, the draft R6RS contains many features that are highly complex to specify and that are quite un-lispy. The enum stuff comes to mind. Records. The exception handling system. Symbol macros. Unicode enshrined. Each is individually motivated, but all together we end up with a very large ball of mud. The size of this ball directly impairs one of Scheme's important features from an industrial perspective: its role as a small language suitable for automatic program transformation and other PLT sorts of techniques. To sum up: I have come to the conclusion that ratification of the draft R6RS will not be healthy for the Scheme community. This draft, and the process behind it, puts the mindset of the community at risk, and is moreover unlikely to achieve its intended effect of industrial acceptance. For these reasons, I have been reluctantly dragged into a negative vote.

The following is not as polished as I'd like it to be, sorry. Most of my codes have the following features: 1. Homogeneous numeric vectors. 2. Various I/O features (read/write pgm/ppm/... files, open tcp sockets, .. 3. Unsafe arithmetic/list operations/... The standard does not explicitly help me in these areas. I'll comment a bit more. Re: Unsafe arithmetic and other operations. I understand that draft does not address these issues; that is fine. Re: Homogenous numeric vectors. The suggestion is made in the rationale that bytevectors plus sealed and opaque types can lead to efficient implementations of homogeneous vector types. To my mind, this assumes the existence of a "suitably smart compiler", and I no longer believe in such a thing. I appreciate Will Clinger's attempts to explain how various features in the proposed draft (including this one) could be implemented efficiently, but I don't think that these efficient implementation of specific features will be found in most R6RS systems. I've participated (mainly as an observer) in compiler development (gcc and gambit), and there are a lot of considerations that people bring to the table; a fancy implementation of a specific feature that is nearly trivial to implement as a primitive (homogeneous numeric vectors) is going to be hard to get to the top of a Scheme implementer's priorities. The parts of the proposal that I most object to are bytevectors and the I/O library. As the draft explains, these two features are intertwined. I think both of them are ad hoc, having a plethora of related procedures that still do not cover the facilities offered by other R5RS I/O extensions in existing Scheme systems. The fact that bytevectors are, by their nature, type aliasing nightmares is too lightly ignored in the draft. Making these the basic implementation strategy of homogenous vectors makes it harder for Scheme systems that compile to C for portability to implement homogeneous vectors efficiently, due to the C aliasing rules. (The authors of the draft clearly had certain implementation strategies in mind when they inserted or deleted various features into the draft; in this case I think their estimate of the affect of this feature was incorrect.) And this situation does not lead to portable code. (And, BTW, IEEE-754 does *not* specify the bit patterns for single- and double-precision floating-point numbers in a way that this report seems to think can be exploited in bytevectors.) I tried to go over some of my own codes to see if the changes in the I/O system would allow me to do what I wanted to do inside R6RS, either (what I would consider) reasonably, or at all. The answer generally was no. I consider the proposed I/O system and bytevectors to be a solution to problems that are nowhere near as important to me as they appear to the editors of the draft; at the same time the draft doesn't offer solutions to the problems I find in my code. I'm stating this in a very personal way so as not to claim universality for my perspectives or needs, but I think my concerns are valid. I consider the proposed bytevectors and I/O large parts of the draft that would be difficult or impossible to fix in R7RS, so I vote no.

Although my initial impression of the draft was mildly positive, after looking it over more thoroughly I am voting against ratification. My vote is based on my overall impression of the draft, but here are some illustrative examples of particular things I don't like about it: Fist, the problem of two record systems that don't quite work together. This was raised by Will Clinger, most recently in his essay "Fixing the Syntactic Record Layer" <http://www.ccs.neu.edu/home/will/R6RS/essay.txt>. Second, the fact that you cannot simply take a record value and access one of its fields by name. I explained my problem with that on the mailing list <http://lists.r6rs.org/pipermail/r6rs-discuss/2007-August/thread.html#3145> <http://lists.r6rs.org/pipermail/r6rs-discuss/2007-August/thread.html#3146>. None of the explanations given for this in the rationale, the mailing list, or the srfi discussions satisfy me. (And the only direct reply seemed to misunderstand the example -- we want a container that requires certain behavior of the values it contains while not requiring that they be on an approved list or inherit from the same ancestor. Importing the accessors of each type of value we wish to contain makes the container's import list the approved list.) Third, the condition system with its simple conditions and compound conditions. After reading through this part of the specification and disliking it, I found a reasonable counterproposal on the mailing list <http://lists.r6rs.org/pipermail/r6rs-discuss/2007-February/thread.html#1458>. It was rejected with a statement that it conflicted with other decisions of the editors and did not appear to be different in any other way. (It is, however quite different. It makes all condition types record types, eliminating the need for almost everything in section 7.2, and it makes it much easier to handle an exception by supplementing the condition with more information and re-raising it.) Those three are just illustrative examples. I am casting my vote based on my overall impression of r5.97rs: Too many things in the draft are designed primarily to work around limitations imposed by other things in the draft. The explanation of the condition system in particular helped me crystallize what I had felt while reading the draft. It was yet another explanation of the form "We must do X because we have decided to do Y and Z." Meanwhile, Y and Z are required by W, which is required by P and Q, which we need because we have X and Y. The editors are happy to explain each feature by pointing to the features that require it (or at least conflict with every alternative they are aware of) but don't seem to have considered the glaring possibility that all are bad and that this is why they are mutually forcing each other into a series of workarounds. The introduction to the draft still begins with, "Programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary." I feel I understand that principle much better now that I have seen r5.97rs itself violate it. If you start by planning to add lots of features, add them in ways that introduce weaknesses and restrictions, then refuse to remove or replace any of your additions as a way of repairing the damage, you end up with a mess that piles workaround on top of workaround and calls them features.

There are several reasons why I am unable to vote in favor of this set of documents. First, I am deeply disturbed by the size and scope of the proposed changes to R5RS. While many of these changes are sensible, there are very many changes, and rather than getting to vote on each change separately, we're forced into voting on all of them at once. This is very like the way national deliberative bodies work, and is even more distasteful in this context. A more incremental process would foster more thoughtful development, allow users and implementers to digest and understand the strengths and weaknesses of each feature before moving on to the next. (I certainly don't have time to fully understand all that is being proposed here.) One interpretation of this process is that it's driven by fear: the fear that the current set of authors have only a limited extent of control over the standards process, and are trying to make the most of it while they can. I don't think that's exactly what's happening here, but I do think there's a certain amount of distrust in the future, based more than likely on the dismal experiences of the past. Nonetheless I think we should start from the assumption that small successes now will lead to more small successes in the future, and that over time those successes will accumulate to make something great. We have to trust our ability to work together, and we have to trust that spreading control of the standards process more broadly through the community is best in the long run. So, what I'm advocating here is something more like the "bazaar" software development model: release early, release often, and be open to participation by the community. The second problem I have is the fairly low priority given to backwards compatibility. This is made all the more important by scope of the documents. I understand that the standard answer to this is that implementations are expected to provide mechanisms for switching between modes -- but this doesn't really address what to do with existing bodies of code. It also makes it more difficult to update existing code to the new language, since there's no incremental update path; each program must be completely transformed all at once, which effectively means it will never happen. Contrast this with ANSI C, for example, in which it's possible to incrementally update programs from traditional to ANSI C, and have them continue to run when only partially updated. This is a huge win that I've taken advantage of in my own code. The third problem I see is that two core features of the language have been designed as entirely new sub-languages: specifically, the module system and SYNTAX-CASE. Not only are these new languages, but they are declarative languages, which makes them fundamentally different from the core language, which has always been imperative. Worse, these sub-languages solve problems that could have been solved by application of the core language, meaning they lead to additional cognitive complexity while getting little in return. The module system is basically a way to tell the linker how to construct programs from parts. Rather than invent a new language to do this, it's possible to build the linker such that the programmer can insert code to control aspects of the linking process. Such code could do _more_ than the current module system does, and because of the added expressivity, it could do so more concisely in many cases. For example, I sometimes use a trivial module system in which names starting with "%" are local, and all other names are exported. This is a trivial program to write, and doesn't depend on the details of the names, but it can't be said at all with the proposed module system. SYNTAX-CASE has similar problems, although not as extreme: it implements a term-rewriting system, with limited programmability, to solve a problem for which there are significantly simpler solutions. This sub-language introduces a new kind of variable that behaves differently from the variables we're used to, and pushes pattern-matching and templating to the center of the macro-writing process. Yet with this added complexity it is arguably no better than the syntactic closures or explicit renaming mechanisms proposed years ago, which have very little cognitive overhead.

I think it is pointless to ratify a Scheme standard that doesn't hold true to the founding principles -- expressiveness and simplicity -- of Scheme. The key benefit to me, portability derives from standardization; but developers of significant compilers do not support this draft -- this fractures the community and reduces the likelihood of portability. Another summarized it this way: this draft seems to nail down the (more-or- less) easy-to- nail down things, and reduces the scope of solutions to the difficult issues without making substantial progress on them.

Programming languages should be designed not by piling feature on top of feature, but by removing the weaknesses and restrictions that make additional features appear necessary. The R6RS draft strays far away from the simplicity that characterized earlier versions of the report. As a result, the effort required to implement a standard-compliant Scheme becomes much larger than before. This will discouraging future implementors, endangering the diversity that is one of Scheme's present strengths (there are Schemes running in almost any imaginable environment -- embedded, desktop, in a browser, on top of Java and Ocaml etc). Furthermore, because of this complexity (as well as because R6RS is controversial) many existing implementations will choose not to support R6RS, thus splitting the Scheme community and codebase (some authors will choose to write R6RS code that will not be directly usable by those running R5RS-only implementations). I believe that, given Scheme's present maturity, the proper way to evolve and enhance the language is via SRFIs, which provide a more democratic and less biased process, and which minimize the destructive effect of poor design decisions. Other reasons for which I do not believe the R6RS should be ratified are: identifier macros, which make the job of code-walking macros much more difficult (especially as there is no way to programatically expand macros); the syntax-case macro system (even if relegated to the standard library); the complex and over-specified exception system; and immutable pairs, which may make optimization easier, but do not fit at all with the practice and spirit of Lisp.

It seems to me that, at 91 pages, the proposed Revised^6 Report would make Scheme something bigger than it should be. I think that this violates an important part of the spirit of Scheme, which is to keep the language small, so that learning and implementing it remains relatively easy. Yet the proposed Report, as far as I can tell, fails to address some criticisms that are more than likely in our day and age, such as the absence of network connection capabilities. If such features are to be omitted from the Report, why could not many other features be deemed "recommended yet optional", and grouped in a common library, that does not have to be a de jure standard? Other languages appear to live quite successfully with de facto standard libraries that are separate from the language description. One thing I definitely would not like is to have the R6RS be a widely-ignored standard, in the way that, many years after its publication, C99 has but very few implementations, none of them popular.

The shortest explanation for my dissatisfaction with the R6RS is that it appears to have gone fairly far off-track. There are some things I like in it, and would like to vote 'maybe' except for the core structural issues that I see. I have always felt that the brevity of the RnRS spec was one of it's stringest points. Now, with R5.97, the document has expanded to cover 4 interrelated specifications - which would not be bad in and of itself, but the documents seem heavily interdependent. Make no mistake about it, I actually *wanted* the standard split into core and library components, but I was looking at something rather closer to the SML 2000 split. The library machinery; however, is quite nice and I would like to see it preserved. In fact, it is the primary reason why I would like to vote maybe or even yes. It specifies modularization in terms of build processes, which is exactly the right level of abstraction. One minor error though seems to be the in the definition of top-level programs: it appears that only one import form is allowed for a program, which will certainly be violated in an interactive session. Perhaps I have missed the text which allows the REPL to behave differently from a program - but I'm not sure that such a behavior is actually desirable, anyway. An example of where the library/core breakdown is inadequately addressed is the persistence of DYNAMIC-WIND. It has been clearly shown that DYNAMIC-WIND (and R5RS CALL/CC) is implementable in terms of R4RS CALL/CC, but that the reverse is not true. Given the renaming facilities available in the library system, it would seem *really* obvious that R4RS CALL/CC should be in the core and R5RS' DYNAMIC-WIND and CALL/CC should be a separate library. I am quite ambivalent on the topic of exceptions and conditions. I have found that the under-specification of R5RS in this area has actually led me to write better and more comprehensive error handling code. However; I have often wished for a better standardization of error-handling procedures across implementations. The gripping hand holds that the exception and condition-handling behavior is insufficiently worked out. First of all, this functionality *should* be part of the core specification - as is shown by the inclusion of a section on exceptions in the formal semantics. Secondly, the interaction of exceptions and continuations is not clear. It is clear that someone has a notion of how it should all interact, but that does not come out in the document. This last issue is a definite showstopper and points out something that I would very much like to see in the Scheme specification: a solid model for asynchronous events. That alone would be justification enough for R6RS, but it is sadly lacking. A sound asynchronous semantics would enable more things than I can even begin to list at this point. I also feel that the approach to Unicode and non-ascii character sets to also be immature. There are two areas of concern here: program text and I/O. In Scheme the line between these two blurs because of the traditional representations of programs as s-expressions. After seeinng the example of Ruby, I am not convinced (in fact I have begun to be unconvinced as Ruby had its origins in a non-english environment) of the value of supporting unicode for program text. That said, the capability of sexp read makes it hard to avoid. I will only say that the addition of Unicode escapes is ugly to say the least. I am actually moderately pleased with what I see in the I/O system changes. I feel there is a fairly sound basis for extensions to include non-blocking I/O and (dare I say it) interrupt-driven I/O. Multiple-return values *still* has not been fixed. The most straightforward solution is simply to make all continuations multi-valued - or rather that apply a single-argument continuation to multiple values results in the coercion of the actual arguments to some list form. I hate to appeal to Ruby for examples of The Right Thing, but this is a Ruby practice which does seem to work well in practice *and* it would alleviate a major asymmetry in Scheme continuation semantics. It would actually be even better to eliminate multi-valued continuations entirely, but that would be at the cost of breaking existing code (SRFI code even). Personally I have shunned call-with-values and use explicit CPS whenever I have multiple values to return. There are a number of other issues about which I have heard rumblings from the more editorially involved and/or experienced implementors which leave me very worried. While I have not been able to fully evaluate their claims, I will state that I am in agreement with any concerns which reduce the ability of compilers to optimize my code. I am also quite concerned that there are gotchas waiting for prospective implementors (I *do* intend to become one :) - the R5RS spec was much clearer in that respect. A petty irritant for me is the official sanction of square brackets. Given the extensive training the my optical neural networks have received, I find the use of square brackets ugly and unhelpful in reading code. They create a very discordant visual rhythm and should be summarily outlawed. Square brackets are a gross violation of the LISP Party Ethic and offending implementors shall be required to submit thorough self-criticism of their motivations and then will be summarily shot. I really mean this. Finally I will say that it is nice to have a 3-state vote, although perhaps a continuous rating system would have been even better yet. I am not happy enough with the R^(5.97)RS to vote 'yes', or even 'maybe', but I am not far from it. I suppose the fault is mine for not engaging the process at an earlier date. Either way, my vote for the current draft is: NO.

R6RS completely breaks with Scheme's traditional values of simplicity, and throws in gratuitous assortments of needless features, while lacking coherency and generally appearing to be thrown together in haste. R6RS is controversial even among the R6RS editors, and tries to standardize insuffienct compromise solutions for things that are better left unspecified. R6RS is a misguided attempt to make Scheme more suitable for the mainstream, but effectively does the very opposite by removing the assets that always distinguished Scheme from other dialects: smallness and simplicity. I feel not represented by the people that call themselves 'R6RS editors'. This s-expr text format is idiotic. What the heck do you mean with 'an explanation is mandatory'? Need a refresher in democracy, folks?

I think an update to R5RS is needed, particularly to add a module system. Unfortunately, the current proposal doesn't simply add what is missing to R5RS: it tries to do much more. However we put it, the base library is a fundamental part of the proposal. But its design ignores a significant part of the SRFI process, for example by being incompatible with SRFI-1. It is also big and gratuitously complicated. The records, I/O and exceptions are good examples of the unneeded complexity. I'm against making Scheme a bloated and complicated language. I think the current proposal doesn't respect the philosophy of Scheme.

For me the single most important aspect of R6RS is what I will refer to as specifying a suitable system for "standardized portability": portable programming for library and application developers who want to move more easily beyond Scheme's solid established niches, while not endangering the virtues of the language that support both these niches and what we are trying to accomplish beyond them. The core language is the crown jewel of Scheme, and most of us would say the crown jewel of programming languages. In its current minimalist form, it is critical to Ivan Raikov's "holy grail of high-performance scientific computing", and the work of many others. But the failure of our community "to build a large collection of shared libraries" (Ryan Rhodes Newton) must be addressed. Or as Arthur A. Gleckler put it: I want to help make sure that R6RS maintains the right balance between the diamond-like jewel Scheme has always been and the practical everyday programming language that we have always wanted Scheme to be. The proposal took the tried and true approach of making a core language definition, a library mechanism, and a set of standard required libraries, and I approve of this. It is the only approach I can see that satisfies the needs of all the stakeholders. If done right, this approach does not have to compromise Scheme's current strengths---in fact, this can profitably be used to reduce the size of the core, while at the same time a few necessary things are added to it, like exceptions. While I appreciate the concerns of those who want to keep Scheme minimalist, to the point that I am voting against ratification first and foremost because this proposal does not satisfy them, I fail to see how any considerations beyond hooks in the core for library efficiency provide a compelling reason to not standardize it beyond the core, for those who want to get work done beyond the domains a minimalist core excels in. The devil is in details, and that is where this proposal most grievously fails, in the particulars of drawing the lines between the core and its various libraries at various levels. I therefore I pose this question: if the proposal is sufficiently bad that it endangers what we've got in an effort to get something more, why accept it? It is rather common in this sort of effort to lose what one has and thus never gain what is attempted. It is better to reach *correctly* for something new, or as David Rush in comp.lang.scheme put it "In RnRS, the middle 'R' means 'Report' and initially reflected the common and agreed practices in the Scheme community - this is a *retrospective* term and could never reflect the bleeding edge of language innovation." There is much good in this proposal; a lack of time and relevance to the voting process prompts me to focus on only two specific issues related to the all-important library mechanism that I caught on my first reading of it, and that I found had prompted formal comments: 1. The reason for ABSOLUTELY prohibiting linking to multiple versions of the same library per formal comment #130 is very weak. Scheme and the LISP family in general are incisive, powerful languages that give their users great power that can be easily misused. They are not "restraint" languages (e.g. Java), and the "potential for confusion" here seems to be balanced by the information and control the library system gives the user. I am certain that situations as outlined in the comment will occur and harm the efforts of developers, if a sufficiently rich set of library implementations following the standard's mechanism are developed---which is the motivation of creating such a library mechanism in the first place. Those of us who have plenty of scars from "DLLHell" are POWERFULLY motivated to avoid anything like it, but this goes too far, too against the grain. This single problem's damage to the raison d'etre of libraries and R6RS itself is a show stopper. 2. I feel that Scheme should accommodate the desires of library writers to intermix definitions and expressions [insert usual platitudes about needless restrictions---and how Scheme is perhaps more than anything else a system for communicating to other programmers...]. I found the response to formal comment #212 to be singularly unimpressive: that this "might be more useful, but there is no a priori reason to think so" is in frank contrast to the code survey made to reply to formal comment #117. The crowning touch of the response's justification by how it might confuse a Java programmer learning Scheme was for me the final nail in the coffin of R5.97RS. What I'd like to see happen if the proposal is not ratified and the community tries again for a R6RS: It should be *in the direction* of previous revised reports in requiring unanimous consent *for the core* (which includes the library mechanism, but precious few libraries). Therefore the process in the future must continue to require super-majorities for core ratification and maybe even greater ones than the current 60%---and that helps to properly draw the line between it and the required standard libraries. Library ratification does not need to be as strict: as long as they are "acceptable" and have nothing dreadfully wrong with them, it is better to have usable standards than no standards at all, and in theory the SFRI process has allowed the community to discover what works in practice and it worth standardizing. Therefore if this proposed version of R6RS is not ratified (and even if it is), I recommend serious consideration of separating the standardization of the core and standard libraries. They're different beasts for sometimes different audiences. As for what that next R6RS should be: it should define as absolutely minimal a core as is reasonable, keeping all the good things in R5.nnRS, especially exceptions (I think) and a requirement to implement the full numeric tower. Raising the bar for a minimally compliant implementation is worth it for these features---but maybe not Unicode per se, so that the embedded community is not overly taxed by that requirement. The above core will include a library mechanism like the proposed one with the show stopper problems fixed. Then a standard library set *with a reference implementation written in pure Scheme using only the core language* (and other required standard libraries). Part of the required standard core will be hooks required by the above standard libraries needed for minimal efficiency. Implementors wishing compliance with the full standard need only implement the core and ship the reference libraries with it. They and their users can write more efficient implementations of the standard libraries that take advantage of their lower level extensions and special capabilities as they see fit. The core should be satisfactory to the "minimalists" as long as it is not soiled by the additions and is not too "big" for them. The total should be a satisfactory base for those who want do things that would move well beyond what the core supplies. (The above is mostly from a discussion in comp.lang.scheme.) In the longer term, certain things should be added to the core, e.g. I think that continuations should be extended to full first class status, but it should become pretty stable pretty soon. *Ideally* there should be no major *changes* (e.g. case significance) to the core after not many more RnRSs. What I'll do if the proposal is ratified: I will decide that we no longer live in an civilized age ( http://xkcd.com/297/ ), for official "Scheme" will have lost too much of the elegance and correctness that has up to now defined it (I didn't realize it at the time, but so did our parent community when they standardized on Common Lisp, a harsh object lesson in language stagnafication we would do well to remember). There are many signs that ratification of this proposed standard will shatter the Scheme community. For many language implementors, the position of the standard is akin to that of Glendower in Shakespeare's King Henry the IV: I can call spirits from the vasty deep. Because as Hotspur replied: Why, so can I, or so can any man; But will they come when you do call for them? This standard if ratified cannot perforce move the entire community to it. Enough of the wrong things in the proposal can never be undone, and it is very unlikely the splintering of the community that this proposal will cause if ratified will ever be undone, precisely because these wrong things cannot be undone. The lead developer of my favorite Scheme implementation will not vote in favor of this proposed standard, and I would not be at all surprised if he and others fork off their own standard ... call it "Uncommon Scheme". And I think there will be more than enough people going in this direction to make a community with critical mass, That would be an truly unfortunate development, but while my most important personal interests are best served by a widespread acceptance of standardized portability, I cannot support it if it destroys that which makes Scheme so attractive in the first place, including the core upon which my other interests depend. - Harold

I find that Scheme R5RS has become a convenient tool for research and education because it is small and elegant. Its orthogonal feature set invites experimentation with the language. Because of its small size, the programmer has to learn only a few fundamental principles in order to master it. Consequently, there is a proliferation of competing R5RS implementations, which puts Scheme in a unique position, as no other current programming language can claim it has fostered such a diverse software ecosystem. I believe that the R6RS proposal is moving Scheme in a fundamentally wrong direction. It is my opinion that the Scheme community will benefit far more by rejecting the R6RS proposal and continuing the experimentation and innovation fostered by R5RS, than it would benefit from any potential interoperability gained by a new and far-reaching standard. I believe that a high-level language based on lambda calculus must permit precise formal algorithmic specifications of software systems that are invariant on all possible hardware platforms, operating systems, and that are independent of data formats, protocols and standards. Historically, Scheme has fulfilled such a role, and it is my opinion that any features that specify implementation details, as opposed to formal semantics and abstract implementation requirements, do not belong in the core language. The SRFI process has evolved to be the universally accepted standardization process for Scheme libraries, and R6RS must not attempt to subvert it. Each library must undergo its own standardization process. If one wants a standardized Unicode Library for Scheme, then the proper way is to develop an SRFI for a Scheme Unicode library and convince the implementors and users of existing Scheme systems to adopt that SRFI. However, the R6RS proposal demands a large set of extra libraries that are not universally adopted by existing implementations. It does not include widely used and implemented SRFIs, such as SRFI-1, yet it features SRFIs that impose very particular restrictions in fixnum representations, it relies heavily on Unicode, which may evolve and change as a standard, it imposes an imperative hashtable API, where many Scheme implementations feature purely functional dictionary structures, If the core language is sufficiently minimal and well-thought-out, and if the libraries are sufficiently high-level and general, the issues of organization and interoperability can be left to the implementations. A good language standard should support interoperability, not impose it. Following is a list of R6RS proposal features that I consider unnecessary and complicating the language: 1) Unicode It is perhaps better to remove those features of R5RS that prohibit Unicode implementation (such as char->integer and integer->char), and relying on extended SRFI-13 and SRFI-14 for Unicode support. If Unicode support is relegated to a library, the character and string representations will not be rigidly coupled to the language specification, and core Scheme will remain implementable on platforms without Unicode support. 2) Byte-vectors The core language must only include abstract vector type. Having particular types of vector representations is precisely the domain of SRFIs. The R6RS proposal byte vector syntax is not widely agreed upon, and it requires two sets of vector procedures in the core language. 3) Lists SRFI-1 is a well-thought API, which is widely implemented and used in the Scheme community. Yet the R6RS proposal uses incompatible names to several SRFI-1 procedures. Although R6RS claims to emphasize the role of the community, it seems that it is ignoring a previous community effort, and puts future SRFI work in a questionable position. 4) Dictionaries & hash tables The core specification must not mandate any particular standard for dictionary structures, as the existing implementations vary widely in APIs. A side effect free association list structure may be permitted, but anything more sophisticated must be relegated to a library. 5) Exceptions The R5RS report used the phrase "an error is signaled" to indicate that implementations must detect and report an error, without going into specifics. In contrast, the R6RS proposal requires the signaling of exceptions, and it goes further to propose a complex and very specific hierarchy of exceptions. Once again, common practices in the Scheme community are ignore, and instead of relying on the SRFI process, exceptions are mandated in the core language. 6) Modules The enforced phase separation in the module system described in the R6RS proposal overspecifies the module system and disallows different implementation strategies, thus prohibiting the Scheme community from experimenting and innovating. In addition, the module system becomes an obstacle to the use of Scheme as a teaching language, because beginners now must deal with it long before it can be explained to them why. Syntactically, library descriptions need to be enclosed in an additional layer of parentheses, as opposed to a single definition at the top of the file. The versioning system is complex and not obviously necessary, or tried in practice. Again, matters like these must be relegated to the SRFI process. 7) I/O All but fundamental I/O primitives should be put in a library. As with vectors, non-abstract operations do not belong in the core language. 8) R5RS compatibility The identifier macros in the R6RS proposal break R5RS compatibility by eliminating a specific invariant on which R5RS programs and macros can rely, namely that a reference to an identifier has no side effects. With identifier macros as proposed for the R6RS, an identifier may not actually be a variable reference, which can be confusing both for programmers and for code analysis algorithms -- again obstructing experimentation with compilers and language semantics. In the few cases where identifier macros are useful, it is again better to relegate them to a library.

The proposed R6 draft materials are almost four times as long as the R5 report: That's scary in its own right, the more so because the Scheme community relies in considerable part on the efforts of individual developers, or small teams of developers, who have to implement these reports -- or who would presumably like to do so if it did not take forever. I think the Scheme community would be better served by a much smaller language, whose features included the minimum necessary so that the language could easily be extended by loading Scheme source code itself (and perhaps compiling it). In that case, implementers could concentrate on getting a small feature set correct and fast, feature-developers could work on whatever enhancements they liked, and users could use such enhancements as they chose. Perhaps the community would eventually settle on a standard group of libraries for common use (though not everyone would have to use them); but such a development might take a while. The current thrust of Scheme development makes me worry that the language will go the way of C++, which seems to have given rise to a large variety of mutually nearly incomprehensible C++ dialects and programming styles, and to a great deal of confusion about what the various features are supposed to do: I don't know anyone who claims to understand the entire C++ language, and I _do_ know at least one product-development team at a large computer company that will remain nameless here, who are forbidden to use certain features of C++ because they are allegedly so ill-defined that they behave substantially differently in different widely-used implementations. I don't want to see Scheme go that way, so I am voting against the R5.97 draft. -- Jay Reynolds Freeman Jay_Reynolds_Freeman@mac.com http://web.mac.com/jay_reynolds_freeman (personal web site)

------------------------------------------------------------------------------- I have explained some of my sentiment in the following post to comp.lang.scheme on 6 August 2007: > Guys come on it is not as though Schemers are a bunch of stodgy old > uptight conservative worry warts who aren't willing to experiment, is > it? > Scheme was an experiment, and the results were pretty good. > How many people get things perfect on the first try? :) It is precisely for this reason that some of us argue against standardization efforts such as R5.97RS and R6RS. We want to experiment and innovate. And the purpose of standardization is the exact opposite: to prevent experimentation and innovation. The objective of standardization *is* to get it right on the first try, to allow long term stability and interoperability, when the benefits of such outweigh the benefits of innovation. It is my opinion that the Scheme community will benefit far more from experimentation and innovation by rejecting R5.97RS/R6RS that it would from any potential for interoperability that it would afford. We are not an electric power utility. Nor are we C. I think most of the proponents of R5.97RS/R6RS confuse the desire for features in the implementation that they use with desire for standardization. R5.97RS should not be ratified as R6RS. That would be disasterous for the community. But that should not prevent anybody from experimenting with any or all of the features from R5.97RS in their favorite implementation. ------------------------------------------------------------------------------- I have explained some more of my sentiment in the following post that I have prepared for comp.lang.scheme but have not yet sent: There are fundamental flaws in your argument. I suspect that these flaws are what motivate many of those who advocate adoption of R6RS. 1. To the best of my knowledge there is only one vendor of Scheme implementations: Chez. What I mean by vendor is a person or organization that is paid by customers to maintain and develop the core of the implementation. 2. To the best of my knowledge, there is only one community-supported Scheme implementation: Guile. What I mean by community supported is that there is a sustainable community distinct from the original implementor that actively maintains and develops the core of the implementation. The vast majority of Scheme implementations are part time labors of love of a single person or a small group that includes current and former graduate students of a single person. While most such implementations are open source, none has attracted an exogenous developer community. Many/most of such efforts are motivated by the fact that such implementations are part of the implementor's research program. For them, innovation is the driving force. Satisfying a customer base is not. Almost all of us in the Scheme community would love for Scheme to catch on in the mainstream. We would love for there to be many profitable vendors selling high-quality Scheme implementations. We would love for there to be a vibrant open-source community that actively maintains and develops many high-quality Scheme implementations. And we would love for there to be a large customer base of real-world Scheme users that would create a demand for the above. Some people believe that the only factor that prevents this from happening is standardization (of a big language). Thus they advocate adoption of R6RS. I think that there is a huge body of compelling historical evidence that this belief is false. There are at least three prior efforts to standardize Lisp: Common Lisp, IS Lisp, and EuLisp. All adopted standards that were essentially supersets of the functionality of R6RS. At one time, there were numerous profitable commercial vendors of Common Lisp implementations: Symbolics, LMI, TI, Gold Hill, Chestnut Hill, Lucid, Harlequin, Franz, Xerox, MCL, ExperCommon Lisp, Star Sapphire, IBCL, ... just to name a few. (There were others that I can't remember at the moment.) And there were many noncommercial implementations actively maintained and developed either by individuals or by well funded research efforts: KCL, AKCL, GCL, CMULISP, CLISP, ... just to name a few. (Again, there were many others that I can't remember at the moment.) And there were many large mainstream companies that developed products that relied on these implementations. That marketplace demand fueled the supply. But that marketplace has essentially disappeared. Today there is only one commercial vendor: Franz. And only one active community-supported development effort: CMULISP. I find it untenable to believe that standardization of R6RS with all of its `real world' features will catalyze growth of a Scheme marketplace. What does R6RS provide that the real-world needs that is not provided by Common Lisp? (No, as much as I like call/cc and a single namespace, they do not fit the bill.) Scheme occupies a unique niche. A research niche and an educational niche. It is not a language. Not R6RS, not R5RS, not R4RS. It is an idea. Or a collection of ideas. It is a framework. It is a way of thinking. It is a mindset. All of this is embodied in an ever growing family of languages or dialects, not a single language. It is a virus. It is the ultimate programming-language virus. The cat is already out of the bag and there is no way to get it back in