Re: Suggestion: ephemeron-case
Daphne Preston-Kendal 05 Feb 2025 15:29 UTC
On 5 Feb 2025, at 16:12, Marc Nieper-Wißkirchen <xxxxxx@gmail.com> wrote:
> Effectively, this means that `ephemeron-case` does not lead to
> error-free code. In the following example, referencing the `key`
> argument of the `helper-proc` will not maintain the reference barrier:
>
> (ephemeron-case eph
> ((key . value) (helper-proc key value))
> (else 'broken))
I don’t see how this is the case. The implementation would somehow need to both inline the helper-proc (in order to do the re-ordering optimization you were worried about when you introduced the reference-barrier procedure) but also discard the reference-barriering nature of the mention of ‘key’. This seems very unlikely.
> Another problem is that `reference-barrier` may be a costly operation
> for the optimiser (because it forbids reordering of code); it may be
> too costly if the barrier is invoked after every reference of the key.
This is why I suggest that the spec language should be that the key identifier is bound ‘as if to identifier syntax’, and is kept alive ‘as if by the reference-barrier procedure’. That would allow a clever implementation which works out that it can remove all but one (the last, after re-ordering of pure and unspecified-evaluation-order expressions) of the reference-barriers.
An alternative would be that ephemeron-case is specified as if implemented as follows:
(let ((k (ephemeron-key eph)) (v (ephemeron-key eph)))
(if (ephemeron-broken? eph)
(begin (broken-case))
(begin0
(begin (non-broken-case-with-vars k v))
(reference-barrier k))))
(i.e. reference barrier is invoked only once for the whole block) which might be better all around.
I do agree, though, that the procedural interface should stay because it does provide enhanced flexibility, and allows doing things which do not hinder optimizations which the ‘careful’ ephemeron-case form might accidentally prohibit (even with the above suggestion, this would include potentially collecting k before the end of the non-broken-case-with-vars block, if it is no longer needed after a certain point within that block).
Daphne