[Python-ideas] Cofunctions - Back to Basics

Nick Coghlan ncoghlan at gmail.com
Thu Oct 27 06:13:59 CEST 2011


On Thu, Oct 27, 2011 at 1:30 PM, Greg Ewing <greg.ewing at canterbury.ac.nz> wrote:
> On 27/10/11 15:53, Nick Coghlan wrote:
>
>> That idea doesn't work when combined with the current idea in the PEP
>> for implicit cocall support inside cofunction definitions. Simple
>> method calls will see "Oh, this has __cocall__" and try to treat it
>> like a cofunction, when the underlying object is actually an ordinary
>> callable.
>
> That's why I've specified that the __cocall__ method can return
> NotImplemented to signal that the object doesn't support cocalls.
> When I say "implements __cocall__" I mean "has a __cocall__
> method that doesn't return NotImplemented".

Ah, I missed that. Could you add a pseudocode expansion, similar to
the one in PEP 343?

Something like:

    _make_call = True
    _cocall = getattr(obj, "__cocall__", None)
    if _cocall is not None:
        _cocall_result = _cocall(*args, **kwds)
        _make_call = _cocall_result is NotImplemented
    if _make_call:
        _result = obj(*args, **kwds)
    else:
        _result = _cocall_result


To expand on the "implicit concurrency" discussion, it's potentially
worth explicitly stating a couple more points:
    - thread preemption can already occur between any two bytecode instructions
    - exceptions can already be thrown by any expression

However, you currently handwave away the question of what constitutes
"some suitable form of synchronisation" when it comes to implicit
cofunction invocation. With threads, you can using the locking
primitives to block other threads. With explicit cocalls, you can
manually inspect a block of code to ensure it doesn't contain any
yield points. With implicit cocalls, how does one implement an
interpreter enforced guarantee that control will not be relinquished
to the scheduler within a particular block of code?

Perhaps the PEP needs a "with not codef:" construct to revert to
normal calling semantics for a section of code within a coroutine? You
could still explicitly yield from such a code block, but it would
otherwise be the coroutine equivalent of a critical section.

Cheers,
Nick.

-- 
Nick Coghlan   |   ncoghlan at gmail.com   |   Brisbane, Australia



More information about the Python-ideas mailing list