Some BNF, multiple values
Andre van Tonder 22 Oct 2005 15:25 UTC
I have taken the liberty of writing out a suggestion for a
slight alteration of the SRFI's LET syntax in a way that I find
more readable and perhaps less potentially confusing:
(define-type <name-spec> <formals> <record clause>*)
<record clause> --> <layout>
| <sealed>
| <opaque>
| <nondegenerative>
| <init!>
<layout> --> <layout clause>*
| (let (<binding spec>*) <layout>)
| (let* (<binding spec>*) <layout>)
| (letrec (<binding spec>*) <layout>)
| (let-values (<binding spec>*) <layout>)
| (let*-values (<binding spec>*) <layout>)
| (letrec-values (<binding spec>*) <layout>)
<layout clause> --> <parent clause>
| <fields clause>
Rationale:
==========
- Expressions in <parent clause> and <fields clause> are clearly inside the LET.
- Expressions in <init!>, <sealed> and <opaque> are clearly outside the LET.
- Nested LETs are now explicitly nested.
- References cannot precede bindings as they could in the SRFI.
- Multiple values supported.
- Multiple <binding spec>s per LET allowed.
- There is now only one <layout>, as opposed to the multiple
LET clauses allowed by the SRFI.
Simplifying multiple values:
============================
The following message has IMO the most beautiful suggestion for absorbing
LET[...]-VALUES into LET[...]:
http://srfi.schemers.org/srfi-71/mail-archive/msg00012.html
OCaml:
======
By the way, I noticed that OCAML uses (nestable) LET-clauses as part
of their class syntax in almost exactly this way for object initialization.
See the BNF in 6.9.2 at:
http://pauillac.inria.fr/ocaml/htmlman/manual017.html
Examples:
=========
(define x 10)
(define-type foo ()
(let ((x 1) ; more than one <binding spec> possible
(y 2))
(let ((z (+ x y))) ; nesting clearly reflects x and y bindings
(parent bar x y)
(fields (a mutable x) ; nesting clearly reflects x = 1 binding
(b mutable y)
(c mutable z))))
(init! (r)
(display x)))) ; clearly refers to *toplevel* x = 10
(define-type rational (x y)
(let-values (((n d) ; multiple values
(if (= y 0)
(values 1 0)
(let ((common (gcd x y)))
(values (/ x common)
(/ y common))))))
(parent number)
(fields (num immutable n)
(denom immutable d)))
(init! (r) (register! r)))
Cheers
Andre