[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Some BNF, multiple values

This page is part of the web mail archives of SRFI 76 from before July 7th, 2015. The new archives for SRFI 76 contain all messages, not just those from before July 7th, 2015.

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>


- 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[...]:


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:



(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)))