Issues with PEP 482 (1)
Hi, I still think that there are several issues that need addressing with PEP 492. This time, one issue at a time :) "async" The "Rationale and Goals" of PEP 492 states that PEP 380 has 3 shortcomings. The second of which is: """It is not possible to natively define a coroutine which has no yield or yield from statements.""" This is incorrect, although what is meant by 'natively' is unclear. A coroutine without a yield statement can be defined simply and concisely, thus: @coroutine def f(): return 1 This is only a few character longer than the proposed new syntax, perfectly explicit and requires no modification the language whatsoever. A pure-python definition of the "coroutine" decorator is given below. So could the "Rationale and Goals" be correctly accordingly, please. Also, either the "async def" syntax should be dropped, or a new justification is required. Cheers, Mark. #coroutine.py from types import FunctionType, CodeType CO_COROUTINE = 0x0080 CO_GENERATOR = 0x0020 def coroutine(f): 'Converts a function to a generator function' old_code = f.__code__ new_code = CodeType( old_code.co_argcount, old_code.co_kwonlyargcount, old_code.co_nlocals, old_code.co_stacksize, old_code.co_flags | CO_GENERATOR | CO_COROUTINE, old_code.co_code, old_code.co_consts, old_code.co_names, old_code.co_varnames, old_code.co_filename, old_code.co_name, old_code.co_firstlineno, old_code.co_lnotab, old_code.co_freevars, old_code.co_cellvars) return FunctionType(new_code, f.__globals__) P.S. The reverse of this decorator, which unsets the flags, converts a generator function into a normal function. :?
Mark, I'm sorry but you have to view the proposal as a whole. Discussing it point by point in isolation doesn't make any sense, as with any complex subject. Thanks, Yury On 2015-04-28 2:44 PM, Mark Shannon wrote:
Hi,
I still think that there are several issues that need addressing with PEP 492. This time, one issue at a time :)
"async"
The "Rationale and Goals" of PEP 492 states that PEP 380 has 3 shortcomings. The second of which is: """It is not possible to natively define a coroutine which has no yield or yield from statements.""" This is incorrect, although what is meant by 'natively' is unclear.
A coroutine without a yield statement can be defined simply and concisely, thus:
@coroutine def f(): return 1
This is only a few character longer than the proposed new syntax, perfectly explicit and requires no modification the language whatsoever. A pure-python definition of the "coroutine" decorator is given below.
So could the "Rationale and Goals" be correctly accordingly, please. Also, either the "async def" syntax should be dropped, or a new justification is required.
Cheers, Mark.
#coroutine.py
from types import FunctionType, CodeType
CO_COROUTINE = 0x0080 CO_GENERATOR = 0x0020
def coroutine(f): 'Converts a function to a generator function' old_code = f.__code__ new_code = CodeType( old_code.co_argcount, old_code.co_kwonlyargcount, old_code.co_nlocals, old_code.co_stacksize, old_code.co_flags | CO_GENERATOR | CO_COROUTINE, old_code.co_code, old_code.co_consts, old_code.co_names, old_code.co_varnames, old_code.co_filename, old_code.co_name, old_code.co_firstlineno, old_code.co_lnotab, old_code.co_freevars, old_code.co_cellvars) return FunctionType(new_code, f.__globals__)
P.S. The reverse of this decorator, which unsets the flags, converts a generator function into a normal function. :? _______________________________________________ Python-Dev mailing list Python-Dev@python.org https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/yselivanov.ml%40gmail.com
Hello, On Tue, 28 Apr 2015 19:44:53 +0100 Mark Shannon wrote: []
A coroutine without a yield statement can be defined simply and concisely, thus:
@coroutine def f(): return 1
[]
A pure-python definition of the "coroutine" decorator is given below.
[]
from types import FunctionType, CodeType
CO_COROUTINE = 0x0080 CO_GENERATOR = 0x0020
def coroutine(f): 'Converts a function to a generator function' old_code = f.__code__ new_code = CodeType( old_code.co_argcount, old_code.co_kwonlyargcount,
This is joke right? This code has nothing to do with *Python*. This code deals with internal implementation details of *CPython*. No other Python implementation would have anything like that (because then it would be just another CPython, and there's clearly no need to have two or more CPythons). The code above is as helpful as saying "you can write some magic values at some magic memory addressed to solve any problem you ever have". All that is rather far away from making coroutine writing in Python easier and less error-prone, which is the topic of PEP482. -- Best regards, Paul mailto:pmiscml@gmail.com
On 28/04/15 20:39, Paul Sokolovsky wrote:
Hello,
On Tue, 28 Apr 2015 19:44:53 +0100 Mark Shannon wrote:
[]
A coroutine without a yield statement can be defined simply and concisely, thus:
@coroutine def f(): return 1
[]
A pure-python definition of the "coroutine" decorator is given below.
[]
from types import FunctionType, CodeType
CO_COROUTINE = 0x0080 CO_GENERATOR = 0x0020
def coroutine(f): 'Converts a function to a generator function' old_code = f.__code__ new_code = CodeType( old_code.co_argcount, old_code.co_kwonlyargcount,
This is joke right? Well it was partly for entertainment value, although it works on PyPy.
The point is that something that can be done with a decorator, whether in pure Python or as builtin, does not require new syntax. Cheers, Mark.
Hello, On Tue, 28 Apr 2015 21:00:17 +0100 Mark Shannon wrote: []
CO_COROUTINE = 0x0080 CO_GENERATOR = 0x0020
def coroutine(f): 'Converts a function to a generator function' old_code = f.__code__ new_code = CodeType( old_code.co_argcount, old_code.co_kwonlyargcount,
This is joke right? Well it was partly for entertainment value, although it works on PyPy.
The point is that something that can be done with a decorator, whether in pure Python or as builtin, does not require new syntax.
And that's exactly not what Python is and not how it evolves. Unlike Scheme, it doesn't offer some minimal orthogonal basis out of which everything can be derived by functional application. Instead, it's more pragmatic and offers plethora of (well defined, unlike many other languages) concepts and implementations to choose from. And if so happens that practice shows that some concepts needs "slight" redefinition, such concept is defined as first-class, despite the fact that it matches 90% semantics of another concept. Fortunately, on implementation level, those 90% of semantics are shared, so it is not outright "bloat". The current wishful thinking of this PEP is that more people will know and use "await", while "yield from" will keep being understood and used by quite not every Python programmer. (Just to state the obvious, all the above is actually my own trying to grasp it, and is reverse causation - trying to explain Python progress in terms of how this particular PEP482 and its older friends progress, it may be quite different for other aspects of language. I for one rather surprised that BDFL is so positive about this PEP).
Cheers, Mark.
-- Best regards, Paul mailto:pmiscml@gmail.com
On Tue, Apr 28, 2015 at 11:44 AM, Mark Shannon wrote:
Hi,
I still think that there are several issues that need addressing with PEP 492. This time, one issue at a time :)
"async"
The "Rationale and Goals" of PEP 492 states that PEP 380 has 3 shortcomings. The second of which is: """It is not possible to natively define a coroutine which has no yield or yield from statements.""" This is incorrect, although what is meant by 'natively' is unclear.
A coroutine without a yield statement can be defined simply and concisely, thus:
@coroutine def f(): return 1
This is only a few character longer than the proposed new syntax, perfectly explicit and requires no modification the language whatsoever. A pure-python definition of the "coroutine" decorator is given below.
So could the "Rationale and Goals" be correctly accordingly, please. Also, either the "async def" syntax should be dropped, or a new justification is required.
So here's *my* motivation for this. I don't want the code generator to have to understand decorators. To the code generator, a decorator is just an expression, and it shouldn't be required to understand decorators in sufficient detail to know that *this* particular decorator means to generate different code. And it's not just generating different code -- it's also the desire to issue static errors (SyntaxError) when await (or async for/with) is used outside a coroutine, or when yield [from] is use inside one. The motivation is clear enough to me (and AFAIR I'm the BDFL for this PEP :-). -- --Guido van Rossum (python.org/~guido)
On 28/04/15 21:06, Guido van Rossum wrote:
On Tue, Apr 28, 2015 at 11:44 AM, Mark Shannon mailto:mark@hotpy.org> wrote:
Hi,
I still think that there are several issues that need addressing with PEP 492. This time, one issue at a time :)
"async"
The "Rationale and Goals" of PEP 492 states that PEP 380 has 3 shortcomings. The second of which is: """It is not possible to natively define a coroutine which has no yield or yield from statements.""" This is incorrect, although what is meant by 'natively' is unclear.
A coroutine without a yield statement can be defined simply and concisely, thus:
@coroutine def f(): return 1
This is only a few character longer than the proposed new syntax, perfectly explicit and requires no modification the language whatsoever. A pure-python definition of the "coroutine" decorator is given below.
So could the "Rationale and Goals" be correctly accordingly, please. Also, either the "async def" syntax should be dropped, or a new justification is required.
So here's *my* motivation for this. I don't want the code generator to have to understand decorators. To the code generator, a decorator is just an expression, and it shouldn't be required to understand decorators in sufficient detail to know that *this* particular decorator means to generate different code. The code generator knows nothing about it. The generated bytecode is identical, only the flags are changed. The decorator can just return a copy of the function with modified co_flags.
And it's not just generating different code -- it's also the desire to issue static errors (SyntaxError) when await (or async for/with) is used outside a coroutine, or when yield [from] is use inside one.
Would raising a TypeError at runtime be sufficient to catch the sort of errors that you are worried about?
The motivation is clear enough to me (and AFAIR I'm the BDFL for this PEP :-).
Can't argue with that. Cheers, Mark.
On Tue, Apr 28, 2015 at 1:22 PM, Mark Shannon wrote:
On 28/04/15 21:06, Guido van Rossum wrote:
On Tue, Apr 28, 2015 at 11:44 AM, Mark Shannon mailto:mark@hotpy.org> wrote:
Hi,
I still think that there are several issues that need addressing with PEP 492. This time, one issue at a time :)
"async"
The "Rationale and Goals" of PEP 492 states that PEP 380 has 3 shortcomings. The second of which is: """It is not possible to natively define a coroutine which has no yield or yield from statements.""" This is incorrect, although what is meant by 'natively' is unclear.
A coroutine without a yield statement can be defined simply and concisely, thus:
@coroutine def f(): return 1
This is only a few character longer than the proposed new syntax, perfectly explicit and requires no modification the language whatsoever. A pure-python definition of the "coroutine" decorator is given below.
So could the "Rationale and Goals" be correctly accordingly, please. Also, either the "async def" syntax should be dropped, or a new justification is required.
So here's *my* motivation for this. I don't want the code generator to have to understand decorators. To the code generator, a decorator is just an expression, and it shouldn't be required to understand decorators in sufficient detail to know that *this* particular decorator means to generate different code.
The code generator knows nothing about it. The generated bytecode is identical, only the flags are changed. The decorator can just return a copy of the function with modified co_flags.
The situation may be different for other Python implementations though. The minimal changes to the code object are an implementation tactic -- the syntactic marking of coroutines is fundamental (like in the past the choice to recognize generators syntactically, albeit in that case by the presence of yield in their body).
And it's not just generating different code -- it's also the desire to issue static errors (SyntaxError) when await (or async for/with) is used outside a coroutine, or when yield [from] is use inside one.
Would raising a TypeError at runtime be sufficient to catch the sort of errors that you are worried about?
No.
The motivation is clear enough to me (and AFAIR I'm the BDFL for this PEP :-).
Can't argue with that.
Cheers, Mark.
-- --Guido van Rossum (python.org/~guido)
Hi Mark, Mark Shannon wrote:
Hi,
I still think that there are several issues that need addressing with PEP 492. This time, one issue at a time :)
"async"
The "Rationale and Goals" of PEP 492 states that PEP 380 has 3 shortcomings. The second of which is: """It is not possible to natively define a coroutine which has no yield or yield from statements.""" This is incorrect, although what is meant by 'natively' is unclear.
A coroutine without a yield statement can be defined simply and concisely, thus:
@coroutine def f(): return 1
This is only a few character longer than the proposed new syntax, perfectly explicit and requires no modification the language whatsoever. A pure-python definition of the "coroutine" decorator is given below.
So could the "Rationale and Goals" be correctly accordingly, please. Also, either the "async def" syntax should be dropped, or a new justification is required.
Cheers, Mark.
As was previously mentioned, new async syntax is a major point of PEP 492. Coroutine-based concurrent programming is something that a lot of languages and platforms are adopting as a first class feature. Just look at the list of references in the PEP. While the specific coroutine definition point you are arguing about can certainly be debated about, you seem to disregard the other points PEP 492 is raising, which boil down to making coroutines a first class object in Python, with all the robustness and support that implies. Decorators in Python are an auxiliary feature that has nothing to do with core language semantics. Also, "async for" and "async with" are just as important in concurrent programs, as regular "for" and "with" are in sequential programs. Saying "no we don't need new syntax", when lots of folks think we do, is just a contradiction without real argument. Elvis
participants (5)
-
Elvis Pranskevichus
-
Guido van Rossum
-
Mark Shannon
-
Paul Sokolovsky
-
Yury Selivanov