Formal comment #117 (enhancement)
Bodies should be more widely permitted
Reported by: Alan Watson
Component: baselibrary
Version: 5.91
I propose that bodies be allowed in the clauses of cond, case, do,
when, unless, and begin forms. Essentially, this would permit these
clauses to be have declarations and internal definitions.
This change simplies the description of the language. Currently, there
are three kinds of "sequences of forms":
- The bodies of binding forms.
- The sequences of expressions in cond, case, do, when, and unless
forms and non-splicing begin forms.
- The sequences of forms in splicing begin forms (those that are
spliced into bodies, library bodies, and script bodies as described
in section 9.5.7).
This proposal unifies the first two classes and thereby simplifies the
language and removes an arbitrary restriction.
This change is backwards compatible with R5RS.
Currently, this behaviour can be obtained by, for example, using a
(let () ...) form in the sequence, but this seems a bit of a hack.
This change is easy to implement. Consider an existing Scheme
implementation that allows only sequences of expression in the
contexts mentioned in (2) above. Such an implementation could be
converted to accept bodies in these contexts by modifying it to wrap
the sequences in (let () ...).
The changes to the draft are:
9.4: Add "begin", "cond", "case", and "do" to the list of forms that
have bodies. (I suggest not adding "when" and "unless" as these are
not in the base library.)
9.5.5: Replace the expression sequences in the first and third forms
or cond clauses and in both forms of case clauses with bodies. Add a
comment that these clauses establish new lexical regions.
9.5.7: Replace the expression sequences in the second form of begin
with a body. Add a comment that this form establishes a new lexical
region.
9.18: In the description of the values procedure, write "The
continuations of all non-final expressions within a body as well as
the continuations of the before and after arguments to dynamic-wind
take an arbitrary number of values."
9.19: Replace both expression sequences in the do form with
bodies. Add a comment that this form establishes new lexical regions
in these bodies.
20.1: Replace the expression sequences in when and unless forms with
bodies. Add a comment that these forms establish new lexical regions.
The syntax definitions of cond, case, do, when, and unless in 19.9,
20.1, and Appendix B do not need changing if begin takes a body.
RESPONSE:
As the comment observes, current practice for placing
definitions in an otherwise illegal context involves
the (let () ...) hack. That hack works fine, but is
considered inelegant. The comment's proposal would
reduce but not eliminate uses of the hack.
The main problem with this proposal is that it would
interact with the macro expander's determination of
the boundary between definitions and expressions.
The algorithm described in section 8 of the current
draft would have to be changed, and new scope rules
would have to be invented:
(let ((main (lambda (f)
(define (g) (f))
(begin (define (f) 13)
(g)))))
(main (lambda () 17)))
With the draft R6RS, the expression above evaluates
to 13. With the proposed change, it is unclear
whether it should evaluate to 13 or to 17.
The proposal would create many new opportunities for
placing declarations and definitions, without making
declarations and definitions available in all contexts.
This would provide a small increase in convenience, at
the cost of a small increase in confusion: programmers
have to know which syntactic constructs have bodies,
and that set would become larger under the proposal.
Confusion would also increase because the meaning of a
definition would depend upon whether it is followed by
an expression. Within a module body, for example:
; x can be exported
(begin (define x 3))
; y cannot be exported
(begin (define y 4) 5)
The benefits and costs of this proposal are small, but
its costs may be larger than its benefits. Also, a quick
study of existing code by some of the editors turned
up few locations where the change would be useful.
Therefore, the editors have decided not to allow bodies
more widely in the next draft of the report.