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