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)
|
Am Mi., 5. Feb. 2025 um 16:30 Uhr schrieb Daphne Preston-Kendal <xxxxxx@nonceword.org>: > > 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. It should be possible to prove the correctness of a program formally. For that, "very unlikely" is not enough. > > 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. Sure, but we have no existing clever implementation. > 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. This addresses my two points, but it should probably use `dynamic-wind` and not `begin0` as the first body may be exited early. (This could actually be used as an argument against `begin0` in general.) That said, all semantics suggested so far have another problem, which I haven't mentioned yet: A reference barrier on the key in the unbroken case is useless. The GC can break an ephemeron if, under the assumption that it is broken, the key will not be kept alive. I am going to post a "real life" example soon (I am currently ill, and my brain is not fully working) so that we have some concrete code to test potential syntax against. > 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). That; and a procedural interface means that we can still have compatibility with R4RS.