I just noticed that, in fact, both the R6RS and the R7RS version of let(rec)-syntax are backward-compatible with the R5RS, they are just not mutually compatible.

The body of an R5RS-let(rec)-syntax is not spliced into the surrounding context, and the R7RS retains this semantics making both compatible. R6RS, however, has splicing semantics.

In the R5RS, however, it says, however, that the <body> of a let(rec)-syntax should be a sequence of one or more expressions (while the R7RS allows the <body> to a sequence of definitions followed by one or more expressions).

In the absence of definitions, however, there is no semantic difference between splicing the body in the surrounding context or not. Thus the R6RS is as well backwards-compatible with the R5RS.

--

Marc

Marc Nieper-Wißkirchen <xxxxxx@nieper-wisskirchen.de> schrieb am Sa., 22. Juli 2017 um 13:16 Uhr:
For R7RS-large we can look forward and add a let(rec)-syntax/splicing. 

There are some edge cases that might need specification, though:

(let ()
  (let-syntax/splicing ((foo (syntax-rules () ((foo) 'foo)))
    (define-syntax foo (syntax-rules () ((foo) 'bar)))
    (foo)))

Does this evaluate to foo, bar, or is it an error? 

If we want to be able express the (non-splicing) let(rec) in terns of let(rec)-splicing by using the simple transformation

(let(rec)-syntax <bindings> <body>) => (let () (let(rec)-syntax/splicing <bindings> <body>),

the snippet from above will have to evaluate to bar.

Now, consider the following example:

(let ()
  (let-syntax/splicing ()
    (define let-syntax/splicing #f)
    #f))

This must be possible if we want this snippet to behave as a non-splicing let-syntax. It would, however, be violation of 5.4 of the R7RS, where is says:

"Macros can expand into definitions in any context that
permits them. However, it is an error for a definition to
define an identifier whose binding has to be known in order 
to determine the meaning of the definition itself, or of
any preceding definition that belongs to the same group
of internal definitions. Similarly, it is an error for an internal 
definition to define an identifier whose binding has
to be known in order to determine the boundary between
the internal definitions and the expressions of the body it
belongs to."

So I would like to see clear semantics for let(rec)-syntax/splicing that is in accordance with the rest of the R7RS. Possibly, let(rec)-syntax (non-splicing) won't be implementable with let(rec)-syntax/splicing then, meaning that we actually have too different binding constructs neither of which is expressible in terms of the other.
 
--

Marc