Scheme: Second R6RS draft published

The second draft of R6RS, version 5.92, is now available at www.r6rs.org. (For more general information about Scheme standards, see the Standards page at schemers.org.)

This version of R6RS incorporates the responses to the formal comments that were submitted prior to Nov 15th, 2006. A few of the changes are highlighted below (not intended to be comprehensive):

  • The report has been split into two separate documents: one for the base language, and one for the standard libraries. (A third document is currently planned, to include certain non-normative appendices.)
  • The I/O system has been significantly revised.
  • A number of features have been dropped from the report, including the inexact arithmetic library and the declarations feature.
  • The report now includes a formal operational semantics, developed by Robby Findler and Jacob Matthews, building on their semantics for R5RS.
  • "Top-level programs" replace scripts in the base language, eliminating certain OS-specificities, with a specification for scripts to be added in a non-normative appendix.

The current six-month public comment period is still ongoing, and will continue until March 15, 2007. The schedule subsequent to that date can be found here.

The editors encourage comments on the report, either informally on the discuss@r6rs.org mailing list, or via the formal comment process.

Of course, kibitzing here on LtU is welcome too! (Previous discussions on LtU include the announcement of the previous draft and the June status report.)

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.

Kibitzing

Good work!

Barely into it (and my question is probably answered in the docs), but I see...

In most places where a truth value is expected, however, any value different from #f counts as true.
So I was trying to do a bit of reverse engineering on scheme the other day, and came across behavior in 'and' and 'or' that I did not quite expect:

   > (and #t 2)
   2
   > (or 2 #t)
   2
   > (and #t 2 #t)
   #t
   > (or #f 2 #t)
   2

Which seems counter to the explanation above (though it is hedged). What I was wondering is why Scheme has this behavior?

{Edit Note: In actually writing out the question, I see that and returns the last expression if it is not #f. And or returns the first true expression. I guess I'm too used to static languages that want the result of them to be true or false].

How is that so?

The "or" form returns the first "value different from #f" for its "truth value", or #f otherwise.
The "and" form returns the last "value different from #f" for its "truth value", or #f otherwise.

Seems consistent with the idea that "any value different from #f" counts as true.

You beat me too it...

...back to reading the Scheme docs b/4 I ask any more questions. :-)

As expected

R5RS (the current standard) says:

The expressions [of "and"] are evaluated from left to right, and the value of the first expression that evaluates to a false value (see section 6.3.1) is returned. Any remaining expressions are not evaluated. If all the expressions evaluate to true values, the value of the last expression is returned. If there are no expressions then #t is returned.

[...]

The expressions [of "or"] are evaluated from left to right, and the value of the first expression that evaluates to a true value (see section 6.3.1) is returned. Any remaining expressions are not evaluated. If all expressions evaluate to false values, the value of the last expression is returned. If there are no expressions then #f is returned.

The effect is that "or" will provide the first true result, and "and" will provide the last true result; by arranging the expressions (when possible) in a suitable order, you can use the result of "and" and "or" directly rather than merely passing it to a conditional. For example, (and (guard) foo) returns foo if the guard returns true; correspondingly (or (attempt) fail) will return fail if the attempt failed (i.e. the result of "attempt" is "#f).

Common Lisp behaves exactly the same way, substituting "t" and "nil" for "#t" and "#f". In C-like languages, && and || behave correspondingly.

expansion process

Re the syntax expansion process (p. 29):

Is it correct that a syntax-expander's right-hand side does not have access to top-level bindings defined in the same file?

For example, this code will fail, because when (an-expander) is expanded, some-var is unbound:

(define some-var 'foo)
(define-syntax an-expander (lambda (e) some-var))
(an-expander)

(I don't know if I have the syntax right, but the idea is that some-var occurs in the code that is run at expansion-time).

To have access to some-var inside an-expander's right-hand side, I would have to put some-var into a library imported "for-expand", right?

P.S. R6RS is great work. Congratulations!

Phase separation

To have access to some-var inside an-expander's right-hand side, I would have to put some-var into a library imported "for-expand", right?

Correct. This makes any dependencies between expansion phases explicit. This is generally a good thing -- otherwise, it can be all too easy to introduce ambiguous and confusing dependencies.

PLT Scheme's macro system uses this approach, and it works well in practice. For convenience, PLT recently introduced some additional forms such as define-for-syntax which allow a macro's dependencies to be defined in the same library, e.g.:

(define-for-syntax some-var (syntax foo))
(define foo 5)
(define-syntax an-expander (lambda (e) some-var))
(an-expander)  ; => 5

R6RS is conservative about such things, though. For example, it's possible some future local module/library feature could provide a different way of achieving this.

P.S. Thanks!

Formal operational semantics

Any comments about these?

Interactive semantics

I doubt many people have had a chance to look at the R6RS semantics in any detail yet. For a bit more background info, you might want to take a look at the paper for the R5RS version, which comes complete with pictures. ;) A great feature of both versions is that they're executable in the PLT Redex tool. This makes them much easier to follow and experiment with. Here's how Paul Snively described PLT Redex:

<neo>Whoa.</neo>This thing rocks!

The implementation for R6RS is here (first link on the page). It requires PLT's DrScheme to run.

[Edit: updated with link to semantics implementation.]

:-)

I stand by my earlier comment re: plt-redex. And to have an interactive formal semantics for a programming language is awesome. To me, it underscores Alan Kay's comment that Lisp (IIRC, he was specifically referring to the definitions of "eval" and "apply" from the Lisp 1.5 manual) are the Faraday's Equations of programming; anything computable can be computed with them, including themselves.

Hmmm. I wonder if Ott could be made to target plt-redex somehow?

how come the report got three times larger?

R5RS is 50 pages in volume. R6RS, the language and the library reports together, is 150 pages. Those of you who know, please elucidate: what is it there so much new that causes an increase that large?

Executive summary (for lambda-literate executives)

The R6RS base language report is similar in scope to R5RS. With the notable exception of the library feature, which makes Scheme libraries possible, most of the new features are specified in the libraries report.

The new features in the libraries report include a hygienic procedural macro system (syntax-case), a record mechanism, a Unicode library, a binary data type library ("bytevector"), an I/O system, and libraries for condition and exception handling.

Also specified are new libraries for arithmetic (fixnums, flonums, bitwise arithmetic), lists, hash tables, enumerations, and basic sorting and file system procedures.

In the base language report, some of the areas in which R5RS was underspecified have been clarified, including the semantics of eval and the semantics of a non-interactive top level. The new formal semantics is also more comprehensive, adding about 10 pages to the base language report.

Since most of the new features are specified as libraries, their impact on the base language is limited. The biggest change to the base language is the introduction of the library feature. Other than that, the main effect of the new features on the base language is support at the data type level for Unicode, records, bytevectors, conditions, and exceptions. The latter two are also used by the base language to report errors.

Most of the new features are designed to better support the development of code that's portable between Scheme implementations. This is discussed in the Guiding Principles section on page 4 of the current draft (another new page!)

Thanks! A very informative

Thanks! A very informative summary. It would be helpful to eventually include something of the kind, a bit more detailed, in the R6RS itself. Or perhaps, even more detailed, as a separate document to accompany the report.

Good idea

Thanks, something like this may be added to the r6rs.org web site, at least.