#
Chapter 40
`shared.ss`: Graph Constructor Syntax

To load: `(require (lib "shared.ss"))`

`(`shared` ``(`shared-binding ``···`)` body-expr `···`1`)` SYNTAX

Binds variables with shared structure according to `shared-bindings` and then evaluates the `body-expr`s, returning the result of the last expression.

The `shared` form is similar to `letrec`. Each `shared-binding` has the form: ``

(`variable` `value-expr`)

The `variable`s are bound to the result of `value-expr`s in the same way as for a `letrec` expression, except for `value-expr`s with the following special forms (after partial expansion):

- `(cons `car-expr` `cdr-expr`)`

- `(list `element-expr` `···`)`

- `(box `box-expr`)`

- `(vector `element-expr` `···`)`

- `(`prefix:`make-`name` `element-expr` `···`)` where `prefix:name` is the name of a structure type (or, more generally, is bound to expansion-time information about a structure type)

The `cons` above means an identifier that is `module-identifier=?` either to the `cons` export from `mzscheme` or to the top-level `cons`. The same is true of `list`, `box`, and `vector`. In the ``prefix:`make-`name`` case, the expansion-time information associated with `prefix:name` must provide a constructor binding and a complete set of field mutator bindings.

For each of the special forms, the cons cell, list, box, vector, or structure is allocated with undefined content. The content expressions are not evaluated until all of the bindings have values; then the content expressions are evaluated and the values are inserted into the appropriate locations. In this way, values with shared structure (even cycles) can be constructed.

Examples: ``

(shared ([a (cons 1 a)]) a) ; => infinite list of 1s
(shared ([a (cons 1 b)]
[b (cons 2 a)])
a) ; => (1 2 1 2 1 2 `···`)
(shared ([a (vector b b b)]
[b (box 1)])
(set-box! (vector-ref a 0) 2)
a) ; => #(#&2 #&2 #&2)