On 4 Dec 2023, at 11:54, Marc Nieper-Wißkirchen <xxxxxx@gmail.com> wrote:
> Before you write a sample implementation, please explain why you want to deviate from R6RS in the first place.
You argued previously that totally forbidding re-entry into a procedure before its final definition has been evaluated would be a wart. I agree.
(N.B. for everyone else reading: we are talking about re-entry into the procedure body-top level.)
SRFI 245 doesn't really offer a solution to this problem:
(lambda ()
<expr 1>
<expr 2>
(let ((x 2))
<expr 3>))
Here, it works when call/cc is used to jump more than once into the expressions <expr 1> and <expr 2> before the let-expression is evaluated and the procedure left. Now assume the programmer finds the last let-expression aesthetically not appealing, and so they replace it, according to SRFI 245, by
(lambda ()
<expr 1>
<expr 2>
(define x 2)
<expr 3>)
Suddenly, the program no longer works because the continuation of the initializing expression of `x' is invoked more than once. This is one of the action-at-distance effects, which I called a wart.
Thus, the change SRFI 245 wants to introduce compared to R6RS doesn't actually solve the problem.
Interestingly, SRFI 251 does not have this problem. SRFI 251 rewrites the body with the definition into
(lambda ()
<expr 1>
<expr 2>
(letrec* ((x 2))
<expr 3>))
This works perfectly even in the presence of call/cc.
This can be seen as an argument in favor or SRFI 251 versus SRFI 245.
> Besides, I do find this part of the SRFI 245 far less compelling than the original R6RS semantics (it is not very natural to group expressions with a definition that probably has nothing to do with the expressions).
This is an implementation detail in practice, of course. I find the insertion of ‘dummy’ variables and a ‘side-effect-free expression returning an unspecified value’ at least as unnatural.
Such is subjective, of course. But there are two hints as to why the R6RS semantics may be more natural, also in an objective sense: (1) Only the actual form is touched and no form (definition) that follows. (2) The R6RS semantics have a clear efficient implementation (which is often a sign of the correct semantics). Point (2) can become moot of you can come up with an implementation not more complicated than R6RS.
But in both cases these details are just operational definitions of what the expander internally does.
It has observational consequences.
One also has to answer the question of whether the benefits are worth deviating from an existing standard.