The reason this currently doesn't cause a conflict is because we call the method on a copy of array[0]
, which turns that access into an instantaneous one. I personally find this unintuitive, and it tends to create some micro performance problems when we're blocked from optimizing, but it might be challenging to change for source-compatibility reasons.
Is there a more-current reference that details this behavior, or is it simply a 'bug' in the implementation of the semantics proposed by SE-0176?
Thank you for your persistence and shedding light on this inconsistency. This needs to be clarified and properly documented.
When we deal with ordinary (non-inout
) arguments to a function/method, the read access to the variable is already finished by the time we are inside the function: The value held in the variable is passed (logically copied) into the argument holder, and then the function starts to run. In this case, the value of the argument is independent of the variable holding the same value outside the function and no overlap occurs.
The current behavior treats self
in a non-mutating method as if it is a normal argument passed to the unbound method (to return the bound method). What you quoted from SE-0176 and @John_McCall's comment indicate that self
should not be treated as a normal argument, but a special one that is held in a prolonged read state for the duration of the method call.
Besides source compatibility, implementing this behavior is tricky. We remain stuck with curried functions as unbound method signatures and this prohibits a fix, because even if we come up with an attribute to mark an argument (self
in this case) to be subject to prolonged read access, it won't solve this, as that prolonged access will finish once the resulting bound method is returned. Moreover, calling other methods and passing down self
needs to be carefully considered. We would have to add a prolonged-read attribute and either ban unbound methods altogether or implement SE-0042 besides other things...