First Draft of R7RS For The Small Language
As I recounted in my Two Schemes post, the Scheme Steering Committee decided to split Scheme into large and small languages and formed working groups for each. The small language working group has just published their draft R7RS for the small language. I've read over the draft and am very pleased with it. At 67 pages it remains small and concise and, in fact, it retains the flavor of R5RS as promised.
So what's different? There's a complete list of changes at the end of the draft, and also in the post announcing the draft, but here are some that appealed to me:
- Modules are now part of the language definition. This is important because it was one of the major sources of incompatibilities between different implementations.
- Records à la SRFI 9 are now included as part of the language.
- Parameters, sort of like dynamic variables from Common Lisp, are
introduced as global variables that can be safely dynamically
rebound. Objects such as
current-output-port, and the newly introduced
current-error-portare defined as parameters.
- Blobs, homogeneous vectors of integers in the range [0..255], are a new disjoint type. This is to allow Scheme to better handle binary data. Ports can now be defined as character or binary.
letrec*is now part of the language and internal defines are specified in terms of it.
casenow supports a ‘=>’ syntax analogous to
case-lambdais now part of the base library as a way of dispatching on the number of arguments.
vector-for-eachround out the sequence operations.
- Character escaping in strings is expanded.
- Case folding in the reader is configurable with no folding as the
default. Generally I don't care about this because I alway use lower
case anyway and don't understand why anyone would do otherwise. As
an Emacs user I already do enough chording without worrying about
capital letters. Still, it does raise an issue: as soon as Louis
Reasoner sees that case matters he starts using really ugly camel
case identifiers like
GeeIWishIWereCodingTheWindowsKernel. Now Louis is welcome to do whatever he likes as long as I can ignore it, which I can if there is case folding. Of course, once Louis gets used to case mattering, we get stuff like
(define sum-odds (lambda (lst) (define SUM-ODDS (lambda (lst result) (if (null? lst) result (if (odd? (car lst)) (SUM-ODDS (cdr lst) (+ (car lst) result)) (SUM-ODDS (cdr lst) result))))) (SUM-ODDS lst 0)))
Mostly, I just wish this issue would magically go away. Or better yet that people would be sensible in their coding conventions.
- No Unicode support is required but the set of characters used by an implementation are required to be consistent with the latest Unicode standard to the extent that the implementation supports Unicode.
Most of this is already in R6RS—indeed, what isn't in R6RS—and almost all of it can be added by the user. For example, we've all written code like
(define string-map (lambda (f str) (list->string (map f (string->list str)))))
as a quick and dirty
string-map but now we have a, presumably, more
robust version that handles multiple strings. Even the reference
implementation of parameters can be done at the user level—this is,
after all, one of the strengths of Scheme. What's nice is not a lot of
the work is done for us—well, OK, that is nice—but that these
things are now standardized and portable. There's more than I've
mentioned here so be sure to checkout the draft itself or at least the
list of changes from R5RS.
I'm looking forward to the large language R7RS draft. It will be interesting to see if the working group does indeed manage to produce the “happier outcome” that the steering committee promised.