Email list hosting service & mailing list manager


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