On 21 Feb 2025, at 23:32, Alex Shinn <
alex...@gmail.com> wrote:
> I don't see that we need to change anything though.
> These forms are obviously not "unimplementable" as suggested, since many implementations exist.
Just because many implementations exist which are incorrect according to the specification does not mean that the specification is correct.
Your proposed solution – that all implementations have to coerce multiple values down to one value – is a real stretch, given it contradicts the places in the R7RS report which state that the effect of passing wrong numbers of values is an error. Moreover, the problematic specification of ‘when’ is observable in this case:
(call-with-values
(lambda ()
(when (some-condition)
(values 1 2)))
(case-lambda
((a) 'one-value)
((a b) 'two-values)))
The requirement that ‘when’ only ever return one value means this expression is only ever allowed to evaluate to the symbol one-value, regardless of the value of (some-condition). The requirement that the ‘when’ expressions are a tail sequence implies that this expression must be allowed to evaluate to the symbol two-values if (some-condition) is true. This contradiction applies no matter what an implementation does when returning multiple values to a single-value continuation (as per your allusion to CL semantics), and regardless of whether multiple values are represented internally as a single value (like in Chibi).
If you think it’s possible to use ‘guard’ to coerce multiple values into one value here without spoiling the tail context guarantee (and ideally without any other pointless performance overhead), I’d appreciate a demo of how that would work.
For what it’s worth, the historical cause here is the combination of two arbitrary changes from R6RS which appear to have been motivated more by the squaloid fantasies of certain WG1 members than by solid engineering considerations:
1. In R6RS, the return value of ‘when’ and ‘unless’ is specified in the case where the expressions are evaluated. (I.e. if the condition is true for ‘when’, and if it’s false for ‘unless’.) Namely, as you’d expect, you get the values of the last expression. The return value is unspecified only in the case where the expressions are not evaluated. This means the semantics of the trivial and obvious transformations of ‘when’ and ‘unless’ to an ‘if’ with no alternate expression – an implementation strategy which, as far as I know, there is absolutely no reason to deviate from – are the defined semantics of ‘when’ and ‘unless’ themselves.
2. In R6RS, a form whose return value is unspecified can return any number of unspecified values and not only one.
Reverting either one of these changes by erratum would fix the problem. (Heck, it would do just to say, as an exception to the usual rule that ‘unspecified result’ means only one value, that ‘when’ and ‘unless’ can return multiple unspecified values.)
For what it’s worth, in the absence of any erratum notification from WG1, for R7RS large I intend to draft the initial specification of ‘when’ and ‘unless’ reverting the first change back to the R6RS state of affairs. (WG2 might object to this, of course, in which case we’ll have to consider it more deeply.)
Daphne