Suggestion: ephemeron-case Daphne Preston-Kendal (04 Feb 2025 10:08 UTC)
Re: Suggestion: ephemeron-case John Cowan (04 Feb 2025 11:35 UTC)
Re: Suggestion: ephemeron-case Vincent Manis (he/him) (04 Feb 2025 19:38 UTC)
Re: Suggestion: ephemeron-case Marc Nieper-Wißkirchen (05 Feb 2025 15:12 UTC)
Re: Suggestion: ephemeron-case Daphne Preston-Kendal (05 Feb 2025 15:30 UTC)
Re: Suggestion: ephemeron-case Marc Nieper-Wißkirchen (05 Feb 2025 18:04 UTC)
Re: Suggestion: ephemeron-case Daphne Preston-Kendal (05 Feb 2025 18:16 UTC)
(missing)
Fwd: Suggestion: ephemeron-case Marc Nieper-Wißkirchen (16 Mar 2025 13:19 UTC)

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