In Python 3.10 we will no longer be burdened by the old parser (though 3rd party tooling needs to catch up). One thing that the PEG parser makes possible in about 20 lines of code is something not entirely different from the old print statement. I have a prototype: Python 3.10.0a0 (heads/print-statement-dirty:5ed19fcc1a, Jun 9 2020, 16:31:17) [Clang 11.0.0 (clang-1100.0.33.8)] on darwin Type "help", "copyright", "credits" or "license" for more information. Cannot read termcap database; using dumb terminal settings.
print 2+2 4 print "hello world" hello world print "hello", input("Name:") Name:Guido hello Guido print 1, 2, 3, sep=", " 1, 2, 3
But wait, there's more! The same syntax will make it possible to call *any* function:
len "abc" 3
Or any method:
import sys sys.getrefcount "abc" 24
Really, *any* method:
class C: ... def foo(self, arg): print arg ... C().foo 2+2 4
There are downsides too, though. For example, you can't call a method without arguments:
print <built-in function print>
Worse, the first argument cannot start with a parenthesis or bracket:
print (1, 2, 3) 1 2 3 C().foo (1, 2, 3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: C.foo() takes 2 positional arguments but 4 were given print (2+2), 42 4 (None, 42) C().foo [0] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'method' object is not subscriptable
No, it's not April 1st. I am seriously proposing this (but I'll withdraw it if the response is a resounding "boo, hiss"). After all, we currently have a bunch of complexity in the parser just to give a helpful error message to people used to Python 2's print statement:
print 1, 2, 3 File "<stdin>", line 1 print 1, 2, 3 ^ SyntaxError: Missing parentheses in call to 'print'. Did you mean print(1, 2, 3)?
And IIRC there have been a number of aborted attempts at syntactic hacks to allow people to call functions (like print) without parentheses, although (I think) none of them made it into a PEP. The PEG parser makes this much simpler, because it can simply backtrack -- by placing the grammar rule for this syntax (tentatively called "call statement") last in the list of alternatives for "small statement" we ensure that everything that's a valid expression statement (including print() calls) is still an expression statement with exactly the same meaning, while still allowing parameter-less function calls, without lexical hacks. (There is no code in my prototype that checks for a space after 'print' -- it just checks that there's a name, number or string following a name, which is never legal syntax.) One possible extension I didn't pursue (yet -- dare me!) is to allow parameter-less calls inside other expressions. For example, my prototype does not support things like this:
a = (len "abc") File "<stdin>", line 1 a = (len "abc") ^ SyntaxError: invalid syntax
I think that strikes a reasonable balance between usability and reduced detection of common errors. I could also dial it back a bit, e.g. maybe it's too much to allow 'C().foo x' and we should only allow dotted names (sufficient to access functions in imported modules and method calls on variables). Or maybe we should only allow simple names (allowing 'len x' but disallowing 'sys.getrefcount x'. Or maybe we should really only bring back print statements. I believe there are some other languages that support a similar grammar (Ruby? R? Raku?) but I haven't investigated. Thoughts? -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
On 06/09/2020 05:06 PM, Guido van Rossum wrote:
One thing that the PEG parser makes possible in about 20 lines of code is something not entirely different from the old print statement. I have a prototype:
print 2+2 4 print "hello world" hello world
There are downsides too, though. For example, you can't call a method without arguments:
print <built-in function print>
What happens with "print ," ? (Just curious.)
No, it's not April 1st. I am seriously proposing this (but I'll withdraw it if the response is a resounding "boo, hiss"). After all, we currently have a bunch of complexity in the parser just to give a helpful error message to people used to Python 2's print statement:
While I will happily admit that too many parentheses make it hard to read code, for me at least too few is also a problem. Besides the mental speed-bump of a missing parenthesis (that I could possibly get used to) we would then have more exceptions to memorize as to when the outer-pair of parentheses are needed and when they aren't. Here's a line of code from one of my code bases: Path(table._fnxfs_root) / table._fnxfs_path / column.path Would I need that first set of parens? Path table._fnxfs_root / table._fnxfs_path / column.path I don't think the extra mental complexity is worth it, and I certainly don't mind using parentheses with print. -- ~Ethan~
Hi Guido, Excited about the possibilities of the new PEG parser ! Have there been any consideration to allow this new call syntax to actually quote the expression given as parameter ? Or have a different meaning than a normal call ? In IPython/Jupyter we use the fact that this is not valid syntax currently to provide magics/macros: In [2]: timeit time.sleep(0.1) 103 ms ± 422 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) (the timeit "function" will here actually get a string but that's a detail). In ambiguous case users can force the resolution with an extra % which allows assignments.: In [3]: res = %timeit -o time.sleep(0.1) 103 ms ± 549 µs per loop (mean ± std. dev. of 7 runs, 10 loops each) In [4]: res Out[4]: <TimeitResult : 103 ms ± 549 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)> We would be excited to have something similar available in core Python. -- Matthias On Tue, 9 Jun 2020 at 17:07, Guido van Rossum <guido@python.org> wrote:
In Python 3.10 we will no longer be burdened by the old parser (though 3rd party tooling needs to catch up).
One thing that the PEG parser makes possible in about 20 lines of code is something not entirely different from the old print statement. I have a prototype:
Python 3.10.0a0 (heads/print-statement-dirty:5ed19fcc1a, Jun 9 2020, 16:31:17) [Clang 11.0.0 (clang-1100.0.33.8)] on darwin Type "help", "copyright", "credits" or "license" for more information. Cannot read termcap database; using dumb terminal settings.
print 2+2 4 print "hello world" hello world print "hello", input("Name:") Name:Guido hello Guido print 1, 2, 3, sep=", " 1, 2, 3
But wait, there's more! The same syntax will make it possible to call *any* function:
len "abc" 3
Or any method:
import sys sys.getrefcount "abc" 24
Really, *any* method:
class C: ... def foo(self, arg): print arg ... C().foo 2+2 4
There are downsides too, though. For example, you can't call a method without arguments:
print <built-in function print>
Worse, the first argument cannot start with a parenthesis or bracket:
print (1, 2, 3) 1 2 3 C().foo (1, 2, 3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: C.foo() takes 2 positional arguments but 4 were given print (2+2), 42 4 (None, 42) C().foo [0] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'method' object is not subscriptable
No, it's not April 1st. I am seriously proposing this (but I'll withdraw it if the response is a resounding "boo, hiss"). After all, we currently have a bunch of complexity in the parser just to give a helpful error message to people used to Python 2's print statement:
print 1, 2, 3 File "<stdin>", line 1 print 1, 2, 3 ^ SyntaxError: Missing parentheses in call to 'print'. Did you mean print(1, 2, 3)?
And IIRC there have been a number of aborted attempts at syntactic hacks to allow people to call functions (like print) without parentheses, although (I think) none of them made it into a PEP. The PEG parser makes this much simpler, because it can simply backtrack -- by placing the grammar rule for this syntax (tentatively called "call statement") last in the list of alternatives for "small statement" we ensure that everything that's a valid expression statement (including print() calls) is still an expression statement with exactly the same meaning, while still allowing parameter-less function calls, without lexical hacks. (There is no code in my prototype that checks for a space after 'print' -- it just checks that there's a name, number or string following a name, which is never legal syntax.)
One possible extension I didn't pursue (yet -- dare me!) is to allow parameter-less calls inside other expressions. For example, my prototype does not support things like this:
a = (len "abc") File "<stdin>", line 1 a = (len "abc") ^ SyntaxError: invalid syntax
I think that strikes a reasonable balance between usability and reduced detection of common errors.
I could also dial it back a bit, e.g. maybe it's too much to allow 'C().foo x' and we should only allow dotted names (sufficient to access functions in imported modules and method calls on variables). Or maybe we should only allow simple names (allowing 'len x' but disallowing 'sys.getrefcount x'. Or maybe we should really only bring back print statements.
I believe there are some other languages that support a similar grammar (Ruby? R? Raku?) but I haven't investigated.
Thoughts?
-- --Guido van Rossum (python.org/~guido) Pronouns: he/him (why is my pronoun here?) _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/NCQX6Z... Code of Conduct: http://python.org/psf/codeofconduct/
On Tue, Jun 9, 2020 at 8:08 PM Guido van Rossum <guido@python.org> wrote:
I believe there are some other languages that support a similar grammar (Ruby? R? Raku?) but I haven't investigated.
Lua has a similar feature: a name (including a dotted name or index[ing], which are identical in Lua) immediately followed by a string literal or table literal is syntactic sugar for calling the named function/callable with that string or table as its only argument. This is commonly used with print() and require(), and also is sometimes used (with table literals) to simulate calling a function with named arguments. Lua allows this to be chained: for example, the line `require "math" "test"` is the same as `require("math")("test")`, calling the result of `require("math") with the argument "test". (Incidentally, `require "math"` returns a non-callable table, so actually running that will generate an error message saying "attempt to call a table value". So it's a bad example, but there are legitimate use cases for this.) However, Lua only supports this for single arguments (two or more require the parentheses) and only for an argument that is a string literal or table literal, nothing else (in particular, numbers and names require the parentheses).
Hi, Just curious, why would bringing back Python 2’s print statement be a good idea? Warm Regards, Sadhana Srinivasan On Wed, Jun 10, 2020 at 2:39 AM, Jonathan Goble <jcgoble3@gmail.com> wrote:
On Tue, Jun 9, 2020 at 8:08 PM Guido van Rossum <guido@python.org> wrote:
I believe there are some other languages that support a similar grammar (Ruby? R? Raku?) but I haven't investigated.
Lua has a similar feature: a name (including a dotted name or index[ing], which are identical in Lua) immediately followed by a string literal or table literal is syntactic sugar for calling the named function/callable with that string or table as its only argument. This is commonly used with print() and require(), and also is sometimes used (with table literals) to simulate calling a function with named arguments.
Lua allows this to be chained: for example, the line `require "math" "test"` is the same as `require("math")("test")`, calling the result of `require("math") with the argument "test". (Incidentally, `require "math"` returns a non-callable table, so actually running that will generate an error message saying "attempt to call a table value". So it's a bad example, but there are legitimate use cases for this.)
However, Lua only supports this for single arguments (two or more require the parentheses) and only for an argument that is a string literal or table literal, nothing else (in particular, numbers and names require the parentheses).
If f and g are unary functions, f g 0 is evaluated as f(g(0))? Asking because you didn't mention composition. That is, could we have `print "hello", input "Name:"` instead of `print "hello", input("Name:")`? Overall, I am against this because I like the "explicitness" of using parenthesis for function calls, and have never found their presence to be an issue. Additionally, I prefer when there is only one way of doing something, even if I don't like the way itself, as that is one less thing to think about. The "the first argument cannot start with a parenthesis or bracket" part (which is understandable) adds even more complexity to this.
FWIW... As someone who has spent at least the last 5 years trying (unsuccessfully) to reprogram 15 years of muscle memory of print as a statement, I vote +1 to print without parens. As someone who teaches Python and groans at explaining exceptions, I'm -0 on print without parens and -1 on other calls without parens. Cheers, Naomi On Tue, 9 Jun 2020 at 19:09, Guido van Rossum <guido@python.org> wrote:
In Python 3.10 we will no longer be burdened by the old parser (though 3rd party tooling needs to catch up).
One thing that the PEG parser makes possible in about 20 lines of code is something not entirely different from the old print statement. I have a prototype:
Python 3.10.0a0 (heads/print-statement-dirty:5ed19fcc1a, Jun 9 2020, 16:31:17) [Clang 11.0.0 (clang-1100.0.33.8)] on darwin Type "help", "copyright", "credits" or "license" for more information. Cannot read termcap database; using dumb terminal settings.
print 2+2 4 print "hello world" hello world print "hello", input("Name:") Name:Guido hello Guido print 1, 2, 3, sep=", " 1, 2, 3
But wait, there's more! The same syntax will make it possible to call *any* function:
len "abc" 3
Or any method:
import sys sys.getrefcount "abc" 24
Really, *any* method:
class C: ... def foo(self, arg): print arg ... C().foo 2+2 4
There are downsides too, though. For example, you can't call a method without arguments:
print <built-in function print>
Worse, the first argument cannot start with a parenthesis or bracket:
print (1, 2, 3) 1 2 3 C().foo (1, 2, 3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: C.foo() takes 2 positional arguments but 4 were given print (2+2), 42 4 (None, 42) C().foo [0] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'method' object is not subscriptable
No, it's not April 1st. I am seriously proposing this (but I'll withdraw it if the response is a resounding "boo, hiss"). After all, we currently have a bunch of complexity in the parser just to give a helpful error message to people used to Python 2's print statement:
print 1, 2, 3 File "<stdin>", line 1 print 1, 2, 3 ^ SyntaxError: Missing parentheses in call to 'print'. Did you mean print(1, 2, 3)?
And IIRC there have been a number of aborted attempts at syntactic hacks to allow people to call functions (like print) without parentheses, although (I think) none of them made it into a PEP. The PEG parser makes this much simpler, because it can simply backtrack -- by placing the grammar rule for this syntax (tentatively called "call statement") last in the list of alternatives for "small statement" we ensure that everything that's a valid expression statement (including print() calls) is still an expression statement with exactly the same meaning, while still allowing parameter-less function calls, without lexical hacks. (There is no code in my prototype that checks for a space after 'print' -- it just checks that there's a name, number or string following a name, which is never legal syntax.)
One possible extension I didn't pursue (yet -- dare me!) is to allow parameter-less calls inside other expressions. For example, my prototype does not support things like this:
a = (len "abc") File "<stdin>", line 1 a = (len "abc") ^ SyntaxError: invalid syntax
I think that strikes a reasonable balance between usability and reduced detection of common errors.
I could also dial it back a bit, e.g. maybe it's too much to allow 'C().foo x' and we should only allow dotted names (sufficient to access functions in imported modules and method calls on variables). Or maybe we should only allow simple names (allowing 'len x' but disallowing 'sys.getrefcount x'. Or maybe we should really only bring back print statements.
I believe there are some other languages that support a similar grammar (Ruby? R? Raku?) but I haven't investigated.
Thoughts?
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/> _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/NCQX6Z... Code of Conduct: http://python.org/psf/codeofconduct/
-- Naomi Ceder @NaomiCeder • https://www.naomiceder.tech https://www.manning.com/books/the-quick-python-book-third-edition
On Tue, Jun 9, 2020 at 5:49 PM Naomi Ceder <naomi.ceder@gmail.com> wrote:
FWIW...
As someone who has spent at least the last 5 years trying (unsuccessfully) to reprogram 15 years of muscle memory of print as a statement, I vote +1 to print without parens.
As someone who teaches Python and groans at explaining exceptions, I'm -0 on print without parens and -1 on other calls without parens.
-1 overall for me... even though I *liked* the Python 0-2 print statement syntax for being "different" and readable without the need for shift-key-awkwardness of ()s including the shell like use of >>sys.stderr up front to redirect the output. This "difference" excused it from auto-inserting magic spaces between everything and repurposing >> - it was "special". Today's function though, it just fits in better with the overall language. It is consistent. It is obviously a function the likes of which anyone could define. As soon as callables can magically be called using a space instead of ()s a whole new world of typos and misunderstandings of what is what and what belongs with what comes up. Modifications to code that need to change calling formats require more complicated edits, etc. I realize that many other high level languages feature this kind of "treat a callable as a command" syntax. But I've never felt it was consistent as it was purely a style choice which syntax to use and when, so why cause conflict and require that decision? Useful for small scripting mentality, but not while programming and engineering reusable maintainable code. In large Perl code bases of yore, the style norm was to not use this style of call or if used, limit it solely to built-ins. We've got one way of doing things that people understand and works, why do we need yet another? We aren't Perl, Ruby, Rexx, Lua, Tcl, ... I love that the new parser allows us to even explore these possibilities. We should be very cautious about what syntax changes we actually adopt. -gps
I think I have almost the same feeling as Naomi and Gregory. After 10+ years of print statement being an error, typing it as one remains my SECOND most common syntax error. My FIRST most common is omitting the colon that introduces blocks... Which we also don't actually need. I've made that mistake for 20+ years. And I never used 0.8 or whatever version didn't have colon, only since 1.4. Despite my occasional typos, I don't think I want the inconsistency of being able to make calls either with or without parens. I've used TCL, REXX, Ruby, REBOL, Haskell, and bash with pleasure, and enjoy their "arguments after a space." I've used Perl even more, and never enjoyed it. :-) But different languages are pleasant in their different consistency, and this feels out of place in modern Python.
Gregory P. Smith writes:
I love that the new parser allows us to even explore these possibilities. We should be very cautious about what syntax changes we actually adopt.
Meter needle wrapped around pin at +1 (twice! :-) BTW:
We aren't Perl, Ruby, Rexx, Lua, Tcl, ...
This made me wince. YMMV.
Wouldn't this break backwards compatibility with everything the whole way back to 3.0? I fear a future with where I have to run a 2to3 type tool on third-party dependencies just to get them to work with my 3.7 code base. --Edwin On 6/9/2020 8:06 PM, Guido van Rossum wrote:
In Python 3.10 we will no longer be burdened by the old parser (though 3rd party tooling needs to catch up).
One thing that the PEG parser makes possible in about 20 lines of code is something not entirely different from the old print statement. I have a prototype:
Python 3.10.0a0 (heads/print-statement-dirty:5ed19fcc1a, Jun 9 2020, 16:31:17) [Clang 11.0.0 (clang-1100.0.33.8)] on darwin Type "help", "copyright", "credits" or "license" for more information. Cannot read termcap database; using dumb terminal settings.
print 2+2 4 print "hello world" hello world print "hello", input("Name:") Name:Guido hello Guido print 1, 2, 3, sep=", " 1, 2, 3
But wait, there's more! The same syntax will make it possible to call *any* function:
len "abc" 3
Or any method:
import sys sys.getrefcount "abc" 24
Really, *any* method:
class C: ... def foo(self, arg): print arg ... C().foo 2+2 4
There are downsides too, though. For example, you can't call a method without arguments:
print <built-in function print>
Worse, the first argument cannot start with a parenthesis or bracket:
print (1, 2, 3) 1 2 3 C().foo (1, 2, 3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: C.foo() takes 2 positional arguments but 4 were given print (2+2), 42 4 (None, 42) C().foo [0] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'method' object is not subscriptable
No, it's not April 1st. I am seriously proposing this (but I'll withdraw it if the response is a resounding "boo, hiss"). After all, we currently have a bunch of complexity in the parser just to give a helpful error message to people used to Python 2's print statement:
print 1, 2, 3 File "<stdin>", line 1 print 1, 2, 3 ^ SyntaxError: Missing parentheses in call to 'print'. Did you mean print(1, 2, 3)?
And IIRC there have been a number of aborted attempts at syntactic hacks to allow people to call functions (like print) without parentheses, although (I think) none of them made it into a PEP. The PEG parser makes this much simpler, because it can simply backtrack -- by placing the grammar rule for this syntax (tentatively called "call statement") last in the list of alternatives for "small statement" we ensure that everything that's a valid expression statement (including print() calls) is still an expression statement with exactly the same meaning, while still allowing parameter-less function calls, without lexical hacks. (There is no code in my prototype that checks for a space after 'print' -- it just checks that there's a name, number or string following a name, which is never legal syntax.)
One possible extension I didn't pursue (yet -- dare me!) is to allow parameter-less calls inside other expressions. For example, my prototype does not support things like this:
a = (len "abc") File "<stdin>", line 1 a = (len "abc") ^ SyntaxError: invalid syntax
I think that strikes a reasonable balance between usability and reduced detection of common errors.
I could also dial it back a bit, e.g. maybe it's too much to allow 'C().foo x' and we should only allow dotted names (sufficient to access functions in imported modules and method calls on variables). Or maybe we should only allow simple names (allowing 'len x' but disallowing 'sys.getrefcount x'. Or maybe we should really only bring back print statements.
I believe there are some other languages that support a similar grammar (Ruby? R? Raku?) but I haven't investigated.
Thoughts?
-- --Guido van Rossum (python.org/~guido <http://python.org/~guido>) /Pronouns: he/him //(why is my pronoun here?)/ <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/NCQX6Z... Code of Conduct: http://python.org/psf/codeofconduct/
On Tue, Jun 9, 2020, 8:47 PM Edwin Zimmerman <edwin@211mainstreet.net> wrote:
Wouldn't this break backwards compatibility with everything the whole way back to 3.0? I fear a future with where I have to run a 2to3 type tool on third-party dependencies just to get them to work with my 3.7 code base.
My interpretation was that this would be syntactic sugar, not a deprecation and replacement. In other words, the existing syntax would still be valid forever.
On 6/9/2020 9:21 PM, Jonathan Goble wrote:
On Tue, Jun 9, 2020, 8:47 PM Edwin Zimmerman <edwin@211mainstreet.net <mailto:edwin@211mainstreet.net>> wrote:
Wouldn't this break backwards compatibility with everything the whole way back to 3.0? I fear a future with where I have to run a 2to3 type tool on third-party dependencies just to get them to work with my 3.7 code base.
My interpretation was that this would be syntactic sugar, not a deprecation and replacement. In other words, the existing syntax would still be valid forever. Correct, what I was trying to say is code bases all over the world that run on previous versions will start seeing this when they import a third party dependency that uses this "syntatic sugar":
print "This doesn't work before 3.10" SyntaxError: Missing parentheses in call to 'print'. Did you mean print("This doesn't work before 3.10")?
On Tue, Jun 9, 2020, 9:33 PM Edwin Zimmerman <edwin@211mainstreet.net> wrote:
On 6/9/2020 9:21 PM, Jonathan Goble wrote:
On Tue, Jun 9, 2020, 8:47 PM Edwin Zimmerman <edwin@211mainstreet.net> wrote:
Wouldn't this break backwards compatibility with everything the whole way back to 3.0? I fear a future with where I have to run a 2to3 type tool on third-party dependencies just to get them to work with my 3.7 code base.
My interpretation was that this would be syntactic sugar, not a deprecation and replacement. In other words, the existing syntax would still be valid forever.
Correct, what I was trying to say is code bases all over the world that run on previous versions will start seeing this when they import a third party dependency that uses this "syntatic sugar":
print "This doesn't work before 3.10" SyntaxError: Missing parentheses in call to 'print'. Did you mean print("This doesn't work before 3.10")?
No different than any other newly introduced syntax (such as the walrus operator). Libraries won't introduce the new syntax until they're ready to drop support for the last version of Python without that syntax. Like any syntax change, it won't commonly appear in the wild until around two to four years after release.
I have a question. Is there a very good reason that the language allows spaces between function names and the parentheses?
print (1,2,3) 1 2 3
Does *anybody* specifically make use of this...? Perhaps I am missing something obvious. Anyway if this were changed so that this kind of call were not allowed, if the proposal were to be accepted couldn't the parser differentiate between these, and parse them differently?
print(1,2,3) 1 2 3 print (1,2,3) (1, 2, 3)
--- Ricky. "I've never met a Kentucky man who wasn't either thinking about going home or actually going home." - Happy Chandler
On 10/06/20 1:56 pm, Ricky Teachey wrote:
I have a question. Is there a very good reason that the language allows spaces between function names and the parentheses?
print (1,2,3)
Python, in common with many other languages, allows whitespace between any pair of lexical tokens. It would be very surprising to disallow it in just this one context. Also, some style guides require a space there, so changing it now would likely break a lot of code. -- Greg
Why is this being proposed? I think we would need a very strong reason to consider this, and so far I haven't seen any justification other than "because we can". -- Greg
On Tue, Jun 9, 2020 at 6:33 PM Greg Ewing <greg.ewing@canterbury.ac.nz> wrote:
Why is this being proposed?
I think we would need a very strong reason to consider this, and so far I haven't seen any justification other than "because we can".
There was definitely something of that... I was looking at the new PEG parser and realized that *if people wanted it* this would be easy to do. So I spent a pleasant hour or two coding it up to my satisfaction. But I was also trying to satisfy some demand. When Python 3 was young, print becoming a function was one of the most frequent complaints, and it's still occasionally seen on Twitter. I found at least two StackOverflow issues about it, but the combined upvote count was less than 100. An early post in this thread reminded me that IPython has a feature called "autocall" that allows exactly this syntax. I don't know how popular it is. However, apparently there the form `f x+1` ends up calling `f("x+1")` (i.e. stringifying the argument), so introducing similar syntax in Python with different semantics would hardly be helpful. (If someone wants to start a debate on argument quoting, please start a new thread, so we can lay this one to rest.) All in all, it's clear that there's no future for this idea, and I will happily withdraw it. -- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
Nevertheless, it's nice to see how powerful the new parser is! Any chance this would allow us to have a multi-line with statement? with self.context_manager_one(some, parameters, that, are, passed) \ as return_value_one, \ self.context_manager_two(self.p, slice(None), None) \ as return_value_two: but with parentheses instead of backslash continuations? On Wednesday, June 10, 2020 at 12:55:01 PM UTC-4, Guido van Rossum wrote:
On Tue, Jun 9, 2020 at 6:33 PM Greg Ewing <greg...@canterbury.ac.nz <javascript:>> wrote:
Why is this being proposed?
I think we would need a very strong reason to consider this, and so far I haven't seen any justification other than "because we can".
There was definitely something of that... I was looking at the new PEG parser and realized that *if people wanted it* this would be easy to do. So I spent a pleasant hour or two coding it up to my satisfaction.
But I was also trying to satisfy some demand. When Python 3 was young, print becoming a function was one of the most frequent complaints, and it's still occasionally seen on Twitter. I found at least two StackOverflow issues about it, but the combined upvote count was less than 100.
An early post in this thread reminded me that IPython has a feature called "autocall" that allows exactly this syntax. I don't know how popular it is. However, apparently there the form `f x+1` ends up calling `f("x+1")` (i.e. stringifying the argument), so introducing similar syntax in Python with different semantics would hardly be helpful. (If someone wants to start a debate on argument quoting, please start a new thread, so we can lay this one to rest.)
All in all, it's clear that there's no future for this idea, and I will happily withdraw it.
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
On Tue, Jun 09, 2020 at 05:06:37PM -0700, Guido van Rossum wrote:
But wait, there's more! The same syntax will make it possible to call *any* function:
len "abc" 3
As you point out later on, there are issues with zero-argument calls and calls where the first argument starts with parens. Ruby allows parens-less function calls. Run this in Ruby and weep: #!/usr/bin/ruby def a(x=4) x+2 end b = 1 print "a + b => ", (a + b), "\n" print "a+b => ", (a+b), "\n" print "a+ b => ", (a+ b), "\n" print "a +b => ", (a +b), "\n" For those who don't have Ruby installed, here is the output: a + b => 7 a+b => 7 a+ b => 7 a +b => 3 In case it's not obvious, the problem isn't the call to print, but the call to function `a`. (Tested in Ruby 2.5). There's also yet another precedence rule to learn: sqrt x + 1 means what? Given Python's execution model where we have statements and functions, I think that it is a feature that they have different syntax. If I see words separated by spaces: import math del spam while condition if obj assert condition I know that they are special syntactic forms, even if I'm reading code using some new statement I had missed learning about: # Python 7 code, fallen through a wormhole require thing demand permission spam contacts verb object I don't think we should give up that nice clean distinction between function calls which always require parens, and statements which don't require parens, merely to add a second way to call functions that saves one char: func(x) func x I'd be more interested in the idea if there was more benefit than just the avoidance of a pair of parens. Something that either can't be done at all, or can only be done with difficulty. Something like IPython's %magic syntax perhaps? -- Steven
On Wed, 10 Jun 2020 at 08:30, Steven D'Aprano <steve@pearwood.info> wrote:
Given Python's execution model where we have statements and functions, I think that it is a feature that they have different syntax. If I see words separated by spaces:
import math del spam while condition if obj assert condition
I know that they are special syntactic forms, even if I'm reading code using some new statement I had missed learning about:
# Python 7 code, fallen through a wormhole require thing demand permission spam contacts verb object
I don't think we should give up that nice clean distinction between function calls which always require parens, and statements which don't require parens, merely to add a second way to call functions that saves one char:
Agreed. On Wed, 10 Jun 2020 at 08:47, Serhiy Storchaka <storchaka@gmail.com> wrote:
10.06.20 03:06, Guido van Rossum пише:
No, it's not April 1st. I am seriously proposing this (but I'll withdraw it if the response is a resounding "boo, hiss").
Well you have my "boo, hiss". I like programming languages which have such feature, but they have it from start, it is an integral part of programming culture for these languages, and Python is built on very different (and often opposite) design principles.
Also agreed. There are languages with parenthesis-less function calls. They are typically languages with a strong emphasis and cultural bias for building DSLs using the language. Python, though, has always resisted such "build your own DSL" styles, and any attempt to write code in such a style looks out of place. While it wouldn't be impossible to alter that bias, it would be quite a significant culture shift, and I'd be surprised if it came without pain (I can imagine new libraries written with the intention of being used "DSL style" being awkward to use from "function style" code). On the other hand, paren-less calls *in a REPL* are more common, and probably more comfortable (e.g., things like IPython's magic syntax). Whether this is something that could be implemented *only* in the REPL, I don't know (probably not - things like the `code` module would need to be able to support it as well) but that might be a possibility. It's certainly the only place where I feel that paren-less calls look OK *for Python*. Paul
10.06.20 03:06, Guido van Rossum пише:
No, it's not April 1st. I am seriously proposing this (but I'll withdraw it if the response is a resounding "boo, hiss").
Well you have my "boo, hiss". I like programming languages which have such feature, but they have it from start, it is an integral part of programming culture for these languages, and Python is built on very different (and often opposite) design principles. Who it will help? Will it help to translate old code from Python 2? Not at all, because of many differences in syntax. Will it help beginners? Not at all, it will make learning Python harder because of more complex rules and weird special cases. Will it help professional Python programmers? Not at all, they will need to learn new rules for uncommon syntax which they are not able to use for many years due to compatibility with older Python versions. Also it will add a headache when modify code (add parentheses for the first argument or reformatiing the code in multiple lines). Saving one key press is not worth it. Will it help programmers experienced in other programming languages? Not at all, because of multiple subtle differences between different languages. Looks it will make Python worse for everybody.
After all, we currently have a bunch of complexity in the parser just to give a helpful error message to people used to Python 2's print statement:
And the proposed feature will be incompatible with this error message. So we will lost a helpful error message too.
On 10/06/2020 01:06, Guido van Rossum wrote:
print 2+2 4 print "hello world" hello world
Bearing in mind that I'm a reactionary old curmudgeon who hates change, this gets a tepid -0.5 from me. It put me in mind of Tcl. Now I don't use Tcl a lot, and mostly that's in convoluted environments driving test equipment, but I find it gets really hard to read surprisingly quickly. -- Rhodri James *-* Kynesim Ltd
Eh, I find that readability suffers in most of the examples shown. Let's save this for custom infix operators or something. That seems like a much more interesting discussion to me.
I wouldn't mind if this *only *worked for the specific characters "print". However, I think that allowing developers to call complex methods without parentheses will lead to very difficult to read code.I think that surrounding arguments with non-whitespace buffer characters is important for readability. It makes things feel contained. For the print function it seems less bad because there is only one argument and oftentimes it is surrounded by quotes, which mitigates the lack of a buffer character. I dread reading someone else's code that includes heavy usage of this pattern for generic function calls. In summary: "boo, hiss". For generic method calls I think this is a terrible idea. However, I would seriously consider a special case grammar change that only allows functions (or variables?) named "print" to be called this way. I think this has benefits for backwards-compatibility, although I will still personally use parens around my prints (because being surrounded by parens looks so freakin' good) it wouldn't make me tear out my hair out to see: `print x` in code reviews. On Tue, Jun 9, 2020 at 8:09 PM Guido van Rossum <guido@python.org> wrote:
In Python 3.10 we will no longer be burdened by the old parser (though 3rd party tooling needs to catch up).
One thing that the PEG parser makes possible in about 20 lines of code is something not entirely different from the old print statement. I have a prototype:
Python 3.10.0a0 (heads/print-statement-dirty:5ed19fcc1a, Jun 9 2020, 16:31:17) [Clang 11.0.0 (clang-1100.0.33.8)] on darwin Type "help", "copyright", "credits" or "license" for more information. Cannot read termcap database; using dumb terminal settings.
print 2+2 4 print "hello world" hello world print "hello", input("Name:") Name:Guido hello Guido print 1, 2, 3, sep=", " 1, 2, 3
But wait, there's more! The same syntax will make it possible to call *any* function:
len "abc" 3
Or any method:
import sys sys.getrefcount "abc" 24
Really, *any* method:
class C: ... def foo(self, arg): print arg ... C().foo 2+2 4
There are downsides too, though. For example, you can't call a method without arguments:
print <built-in function print>
Worse, the first argument cannot start with a parenthesis or bracket:
print (1, 2, 3) 1 2 3 C().foo (1, 2, 3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: C.foo() takes 2 positional arguments but 4 were given print (2+2), 42 4 (None, 42) C().foo [0] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'method' object is not subscriptable
No, it's not April 1st. I am seriously proposing this (but I'll withdraw it if the response is a resounding "boo, hiss"). After all, we currently have a bunch of complexity in the parser just to give a helpful error message to people used to Python 2's print statement:
print 1, 2, 3 File "<stdin>", line 1 print 1, 2, 3 ^ SyntaxError: Missing parentheses in call to 'print'. Did you mean print(1, 2, 3)?
And IIRC there have been a number of aborted attempts at syntactic hacks to allow people to call functions (like print) without parentheses, although (I think) none of them made it into a PEP. The PEG parser makes this much simpler, because it can simply backtrack -- by placing the grammar rule for this syntax (tentatively called "call statement") last in the list of alternatives for "small statement" we ensure that everything that's a valid expression statement (including print() calls) is still an expression statement with exactly the same meaning, while still allowing parameter-less function calls, without lexical hacks. (There is no code in my prototype that checks for a space after 'print' -- it just checks that there's a name, number or string following a name, which is never legal syntax.)
One possible extension I didn't pursue (yet -- dare me!) is to allow parameter-less calls inside other expressions. For example, my prototype does not support things like this:
a = (len "abc") File "<stdin>", line 1 a = (len "abc") ^ SyntaxError: invalid syntax
I think that strikes a reasonable balance between usability and reduced detection of common errors.
I could also dial it back a bit, e.g. maybe it's too much to allow 'C().foo x' and we should only allow dotted names (sufficient to access functions in imported modules and method calls on variables). Or maybe we should only allow simple names (allowing 'len x' but disallowing 'sys.getrefcount x'. Or maybe we should really only bring back print statements.
I believe there are some other languages that support a similar grammar (Ruby? R? Raku?) but I haven't investigated.
Thoughts?
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/> _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/NCQX6Z... Code of Conduct: http://python.org/psf/codeofconduct/
-- -Dr. Jon Crall (him)
On Wed, Jun 10, 2020, 8:04 PM Jonathan Crall <erotemic@gmail.com> wrote:
I wouldn't mind if this *only *worked for the specific characters "print".
I often swap out 'print' for 'pprint', depending on the presentation I'm assuming for. Obviously, I need a 'from pprint import pprint' earlier. It "just works" and is seamless. It would become an impedance mismatch if it didn't include 'pprint'. But what about my 'custom_print' I use occasionally...
On Wed, Jun 10, 2020 at 08:00:26PM -0400, Jonathan Crall wrote:
I wouldn't mind if this *only *worked for the specific characters "print".
I would. What's so special about print? It's just a function. I use `iter` much more than print. Should we make a special exception for only 'iter' too? Or instead? `print` is especially problematic, because zero-argument form of print is possible. This makes it a landmine waiting for the unwary: print x, y, z # works print x # works # now print a blank line print # silent failure That's especially going to burn people who remember Python 2, where it did print a blank line instead of evaluating to the `print` object. -- Steven
What's so special about print? It's just a function.
I'd argue it's a pretty special function given its history. Just because it's used less frequently that something else doesn't mean it's not "special" in some sense. `iter x` never worked, whereas `print x` used to work, which is the only reason I'm giving it special status. Regardless, I'd rather not have this feature. As you said it's not 100% backwards compatible, so the usefulness is limited. On Thu, Jun 11, 2020 at 11:49 AM Steven D'Aprano <steve@pearwood.info> wrote:
On Wed, Jun 10, 2020 at 08:00:26PM -0400, Jonathan Crall wrote:
I wouldn't mind if this *only *worked for the specific characters "print".
I would. What's so special about print? It's just a function.
I use `iter` much more than print. Should we make a special exception for only 'iter' too? Or instead?
`print` is especially problematic, because zero-argument form of print is possible. This makes it a landmine waiting for the unwary:
print x, y, z # works print x # works # now print a blank line print # silent failure
That's especially going to burn people who remember Python 2, where it did print a blank line instead of evaluating to the `print` object.
-- Steven _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/ICVRZK... Code of Conduct: http://python.org/psf/codeofconduct/
-- -Dr. Jon Crall (him)
On 11/06/2020 16:45, Steven D'Aprano wrote:
On Wed, Jun 10, 2020 at 08:00:26PM -0400, Jonathan Crall wrote:
I wouldn't mind if this *only *worked for the specific characters "print". I would. What's so special about print? It's just a function.
I use `iter` much more than print. Should we make a special exception for only 'iter' too? Or instead?
`print` is especially problematic, because zero-argument form of print is possible. This makes it a landmine waiting for the unwary:
print x, y, z # works print x # works # now print a blank line print # silent failure
That's especially going to burn people who remember Python 2, where it did print a blank line instead of evaluating to the `print` object.
No problem! If the new super-duper all-singing-and-dancing-and-make-the-tea parser can cope with 'print' without parens, it can cope with print followed by nothing. Good addition to the proposal, actually. :-) (Repeated for clarity: I'm in favour of the proposition for 'print' only.)
On 06/11/2020 01:18 PM, Rob Cliffe via Python-ideas wrote:
If the new super-duper all-singing-and-dancing-and-make-the-tea parser can cope with 'print' without parens, it can cope with print followed by nothing. Good addition to the proposal, actually. :-) (Repeated for clarity: I'm in favour of the proposition for 'print' only.)
If print prints a blank line, how are you going to access the "print" function as an object? An academic question at this point as Guido has withdrawn the proposal. -- ~Ethan~
On 2020-06-11 22:15, Ethan Furman wrote:
On 06/11/2020 01:18 PM, Rob Cliffe via Python-ideas wrote:
If the new super-duper all-singing-and-dancing-and-make-the-tea parser can cope with 'print' without parens, it can cope with print followed by nothing. Good addition to the proposal, actually. :-) (Repeated for clarity: I'm in favour of the proposition for 'print' only.)
If print
prints a blank line, how are you going to access the "print" function as an object?
Context: it's in a statement, on its own, just the name "print".
An academic question at this point as Guido has withdrawn the proposal.
On 12/06/2020 00:17, MRAB wrote:
On 2020-06-11 22:15, Ethan Furman wrote:
On 06/11/2020 01:18 PM, Rob Cliffe via Python-ideas wrote:
If the new super-duper all-singing-and-dancing-and-make-the-tea parser can cope with 'print' without parens, it can cope with print followed by nothing. Good addition to the proposal, actually. :-) (Repeated for clarity: I'm in favour of the proposition for 'print' only.)
If print
prints a blank line, how are you going to access the "print" function as an object?
Context: it's in a statement, on its own, just the name "print". Yes, that's what I meant. Yes it's backward incompatible, and while one sometimes puts an identifier on a line by itself (I've done it myself) e.g. try: foo except NameError: <do something> it must be rare to do that with 'print', especially outside the REPL.
An academic question at this point as Guido has withdrawn the proposal.
He's allowed to change his mind if there's enough support for it. _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/FIMRTB... Code of Conduct: http://python.org/psf/codeofconduct/
On Wed, Jun 10, 2020 at 10:08 AM Guido van Rossum <guido@python.org> wrote:
One thing that the PEG parser makes possible in about 20 lines of code is something not entirely different from the old print statement. I have a prototype:
Python 3.10.0a0 (heads/print-statement-dirty:5ed19fcc1a, Jun 9 2020, 16:31:17)
print 2+2 4
But wait, there's more! The same syntax will make it possible to call *any* function:
len "abc" 3
Or any method:
import sys sys.getrefcount "abc" 24
A lot of people have been boo-hissing at this, but would it be possible to restrict it to just simple or dotted names (you mentioned that this part is possible), and only at the REPL? I can think of a lot of situations where I'd be doing something like:
len("93e8a1b2688b3fc0dc413c182273a14f5dbd39a23d7845d363c5f9b98283ecaaa7a642578afe55442b7a00ae4ce335c7" ... ) 96
and I'm having to remember to put that close parenthesis on it, and it doesn't up-arrow correctly, etc, etc. Would be convenient to use the space syntax there. It wouldn't be appropriate to use a __future__ import if it isn't intended to be brought in eventually, but the same kind of mechanism would be an effective way to introduce this (instead of magically recognizing a REPL, you just configure it to run the "from __alternate__ import no_parens_calls" statement). As a feature, it feels like the sort of thing that everyone's style guides would frown on, but it'd be very convenient for quickly scribbling stuff in the REPL. ChrisA
On Wednesday, June 10, 2020, at 19:14 -0500, Chris Angelico wrote:
On Wed, Jun 10, 2020 at 10:08 AM Guido van Rossum <guido@python.org> wrote:
One thing that the PEG parser makes possible in about 20 lines of code is something not entirely different from the old print statement. I have a prototype:
Python 3.10.0a0 (heads/print-statement-dirty:5ed19fcc1a, Jun 9 2020, 16:31:17)
print 2+2 4
But wait, there's more! The same syntax will make it possible to call *any* function:
len "abc" 3
Or any method:
import sys sys.getrefcount "abc" 24
A lot of people have been boo-hissing at this, but would it be possible to restrict it to just simple or dotted names (you mentioned that this part is possible), and only at the REPL? ...
I retrained my muscle memory moving from print to print(). I have almost zero use cases of passing end and sep to the function, although I did have a few cases of ending my print statements with a comma. I still think that print makes a better statement than an expression or a function call; YMMV. Okay, enough background. I, too, thought about the convenience of not having to type the parentheses at the REPL, but then I can't paste my code from the REPL into my program, and that's no good at all.
len("93e8a1b2688b3fc0dc413c182273a14f5dbd39a23d7845d363c5f9b98283ecaaa7a642578afe55442b7a00ae4ce335c7" ... ) 96
and I'm having to remember to put that close parenthesis on it, and it doesn't up-arrow correctly, etc, etc. Would be convenient to use the space syntax there.
Well, yeah, but that 93e8a1b2688b3fc0dc413c182273a14f5dbd39a23d7845d363c5f9b98283ecaaa7a642578afe55442b7a00ae4ce335c7 probably came from your clipboard (and it's still there, or still sitting in a terminal window, or ...), so even if you had to retype/paste the whole thing, it's not too bad. And who has the time to retrain the "len" muscle memory *not* to type the parentheses? ;-)
I seem to remember reading somewhere that some very early Lisp systems had a REPL that allowed you to omit the parentheses around a top-level call. But that feature seems to have sunk without trace in the swamps of history. I can't see a good reason for Python to refloat it. -- Greg
Of course ipython has a %autocall magic which, if set to 1: Lets you type `print 42, 43, 46, sep='-'` and have it work. Shows you the actual call so you can paste it If you use the %save magic to output to a file saves the actual call, (with parenthesis). You can set this as your preference. There are other benefits as well. So I would suggest simply pip install ipython and type one extra letter when starting your python REPL. Steve Barnes -----Original Message----- From: Greg Ewing <greg.ewing@canterbury.ac.nz> Sent: 11 June 2020 07:51 To: python-ideas@python.org Subject: [Python-ideas] Re: Bringing the print statement back I seem to remember reading somewhere that some very early Lisp systems had a REPL that allowed you to omit the parentheses around a top-level call. But that feature seems to have sunk without trace in the swamps of history. I can't see a good reason for Python to refloat it. -- Greg _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/T7OJHU... Code of Conduct: http://python.org/psf/codeofconduct/
After thinking about it for a day, my opinions are: +1 for the limited idea of bringing back the print statement with positional arguments only, as syntactic sugar (and not a replacement) for the print function +0 on a print statement with keyword arguments (again, as syntactic sugar) -1 on removing the print function -1 on parentheses-less function calls for anything else.
On 11/06/20 2:08 pm, Jonathan Goble wrote:
+1 for the limited idea of bringing back the print statement with positional arguments only, as syntactic sugar (and not a replacement) for the print function
Would that apply only to the actual built-in print function, or would it work for any visible name spelled 'print'? If the latter, I can imagine some creative abuses as people contrive for their favourite function of the moment to be called 'print' so that they can call it without parens... -- Greg
On Tue, Jun 9, 2020 at 8:11 PM Guido van Rossum <guido@python.org> wrote:
In Python 3.10 we will no longer be burdened by the old parser (though 3rd party tooling needs to catch up).
One thing that the PEG parser makes possible in about 20 lines of code is something not entirely different from the old print statement. I have a prototype:
Python 3.10.0a0 (heads/print-statement-dirty:5ed19fcc1a, Jun 9 2020, 16:31:17) [Clang 11.0.0 (clang-1100.0.33.8)] on darwin Type "help", "copyright", "credits" or "license" for more information. Cannot read termcap database; using dumb terminal settings.
print 2+2 4 print "hello world" hello world print "hello", input("Name:") Name:Guido hello Guido print 1, 2, 3, sep=", " 1, 2, 3
But wait, there's more! The same syntax will make it possible to call *any* function:
len "abc" 3
Or any method:
import sys sys.getrefcount "abc" 24
Really, *any* method:
class C: ... def foo(self, arg): print arg ... C().foo 2+2 4
There are downsides too, though. For example, you can't call a method without arguments:
print <built-in function print>
Worse, the first argument cannot start with a parenthesis or bracket:
print (1, 2, 3) 1 2 3 C().foo (1, 2, 3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: C.foo() takes 2 positional arguments but 4 were given print (2+2), 42 4 (None, 42) C().foo [0] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'method' object is not subscriptable
No, it's not April 1st. I am seriously proposing this (but I'll withdraw it if the response is a resounding "boo, hiss"). After all, we currently have a bunch of complexity in the parser just to give a helpful error message to people used to Python 2's print statement:
Boo! Hiss!
print 1, 2, 3 File "<stdin>", line 1 print 1, 2, 3 ^ SyntaxError: Missing parentheses in call to 'print'. Did you mean print(1, 2, 3)?
And IIRC there have been a number of aborted attempts at syntactic hacks to allow people to call functions (like print) without parentheses, although (I think) none of them made it into a PEP. The PEG parser makes this much simpler, because it can simply backtrack -- by placing the grammar rule for this syntax (tentatively called "call statement") last in the list of alternatives for "small statement" we ensure that everything that's a valid expression statement (including print() calls) is still an expression statement with exactly the same meaning, while still allowing parameter-less function calls, without lexical hacks. (There is no code in my prototype that checks for a space after 'print' -- it just checks that there's a name, number or string following a name, which is never legal syntax.)
One possible extension I didn't pursue (yet -- dare me!) is to allow parameter-less calls inside other expressions. For example, my prototype does not support things like this:
a = (len "abc") File "<stdin>", line 1 a = (len "abc") ^ SyntaxError: invalid syntax
I think that strikes a reasonable balance between usability and reduced detection of common errors.
I could also dial it back a bit, e.g. maybe it's too much to allow 'C().foo x' and we should only allow dotted names (sufficient to access functions in imported modules and method calls on variables). Or maybe we should only allow simple names (allowing 'len x' but disallowing 'sys.getrefcount x'. Or maybe we should really only bring back print statements.
I believe there are some other languages that support a similar grammar (Ruby? R? Raku?) but I haven't investigated.
Thoughts?
I think its really interesting to see how flexible the new parser can be. Regardless of any actual merits, this is a really cool demonstration of that. However, I have a few immediate negatives to draw from this as an actual proposal. First, ambiguity is a factor that Python has always done a really great job of avoiding for the sake of its users. I think this kind of implied call syntax is absolutely the kind of ambiguity that makes a language hard to debug, hard to read, and hard to learn. Second, I don't think we should discount a certain marketing aspect to a change like this. Like it or not, Python 3's changes were contentious for a lot of users. It took way longer than some of us thought to drag the community into the modern incarnation of the language, and there isn't only a small portion of the community that might still be a little bitter about it. Or, who still have to deal with the split between 2 and 3 even today, EOL be damned. What message do we send if we undo one of the most visible changes *now*? We'd send a message that it was all a mistake, and because of the visibility of such a quintessential line of Python print "Hello, World!" It wouldn't just send a message that this one change was a mistake, but that the whole ordeal had always been a mistake. That isn't a can of worms I want to open or ammunition I want to give to naysayers. --
--Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/> _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/NCQX6Z... Code of Conduct: http://python.org/psf/codeofconduct/
-- CALVIN SPEALMAN SENIOR QUALITY ENGINEER cspealma@redhat.com M: +1.336.210.5107 [image: https://red.ht/sig] <https://red.ht/sig> TRIED. TESTED. TRUSTED. <https://redhat.com/trusted>
print (1, 2, 3) 1 2 3
The only real advantage of print being a keyword (exec too, which had tons of benefits such adding stuff to local scope) was the fact of it actually being a keyword and not a gimmick to call functions without parentheses. So this is the worst of 2 worlds. Not a keyword, so no special powers or special syntax like the trailing comma and all the confusion brought to it like you pointed out, such as unable to print tuples without a trailing comma. Which is one of the reasons why `%` formatting is so awful... I'm -1 on this
Can I just write "boo, hiss"? In any case, even if those may be made unambiguous for the current parser (I have no idea if that's true), they're visually ambiguous for a human reader. With parentheses, it's immediate what are function calls. Without, it's far less obvious whether such calls are involved or not. Regards Antoine. On Tue, 9 Jun 2020 17:06:37 -0700 Guido van Rossum <guido@python.org> wrote:
In Python 3.10 we will no longer be burdened by the old parser (though 3rd party tooling needs to catch up).
One thing that the PEG parser makes possible in about 20 lines of code is something not entirely different from the old print statement. I have a prototype:
Python 3.10.0a0 (heads/print-statement-dirty:5ed19fcc1a, Jun 9 2020, 16:31:17) [Clang 11.0.0 (clang-1100.0.33.8)] on darwin Type "help", "copyright", "credits" or "license" for more information. Cannot read termcap database; using dumb terminal settings.
print 2+2 4 print "hello world" hello world print "hello", input("Name:") Name:Guido hello Guido print 1, 2, 3, sep=", " 1, 2, 3
But wait, there's more! The same syntax will make it possible to call *any* function:
len "abc" 3
Or any method:
import sys sys.getrefcount "abc" 24
Really, *any* method:
class C: ... def foo(self, arg): print arg ... C().foo 2+2 4
There are downsides too, though. For example, you can't call a method without arguments:
print <built-in function print>
Worse, the first argument cannot start with a parenthesis or bracket:
print (1, 2, 3) 1 2 3 C().foo (1, 2, 3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: C.foo() takes 2 positional arguments but 4 were given print (2+2), 42 4 (None, 42) C().foo [0] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'method' object is not subscriptable
No, it's not April 1st. I am seriously proposing this (but I'll withdraw it if the response is a resounding "boo, hiss"). After all, we currently have a bunch of complexity in the parser just to give a helpful error message to people used to Python 2's print statement:
print 1, 2, 3 File "<stdin>", line 1 print 1, 2, 3 ^ SyntaxError: Missing parentheses in call to 'print'. Did you mean print(1, 2, 3)?
And IIRC there have been a number of aborted attempts at syntactic hacks to allow people to call functions (like print) without parentheses, although (I think) none of them made it into a PEP. The PEG parser makes this much simpler, because it can simply backtrack -- by placing the grammar rule for this syntax (tentatively called "call statement") last in the list of alternatives for "small statement" we ensure that everything that's a valid expression statement (including print() calls) is still an expression statement with exactly the same meaning, while still allowing parameter-less function calls, without lexical hacks. (There is no code in my prototype that checks for a space after 'print' -- it just checks that there's a name, number or string following a name, which is never legal syntax.)
One possible extension I didn't pursue (yet -- dare me!) is to allow parameter-less calls inside other expressions. For example, my prototype does not support things like this:
a = (len "abc") File "<stdin>", line 1 a = (len "abc") ^ SyntaxError: invalid syntax
I think that strikes a reasonable balance between usability and reduced detection of common errors.
I could also dial it back a bit, e.g. maybe it's too much to allow 'C().foo x' and we should only allow dotted names (sufficient to access functions in imported modules and method calls on variables). Or maybe we should only allow simple names (allowing 'len x' but disallowing 'sys.getrefcount x'. Or maybe we should really only bring back print statements.
I believe there are some other languages that support a similar grammar (Ruby? R? Raku?) but I haven't investigated.
Thoughts?
Guido van Rossum wrote:
print 2+2 4 print "hello world" hello world print "hello", input("Name:") Name:Guido hello Guido print 1, 2, 3, sep=", " 1, 2, 3 But wait, there's more! The same syntax will make it possible to call any function: len "abc" 3 Or any method: import sys sys.getrefcount "abc" 24 Really, any method: class C: ... def foo(self, arg): print arg ... C().foo 2+2 4 There are downsides too, though. For example, you can't call a method without arguments: print <built-in function print>Worse, the first argument cannot start with a parenthesis or bracket: print (1, 2, 3) 1 2 3 C().foo (1, 2, 3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: C.foo() takes 2 positional arguments but 4 were given print (2+2), 42 4 (None, 42) C().foo [0] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'method' object is not subscriptable No, it's not April 1st. I am seriously proposing this (but I'll withdraw it if the response is a resounding "boo, hiss"). After all, we currently have a bunch of complexity in the parser just to give a helpful error message to
print 1, 2, 3 File "<stdin>", line 1 print 1, 2, 3 ^ SyntaxError: Missing parentheses in call to 'print'. Did you mean print(1, 2, 3)? And IIRC there have been a number of aborted attempts at syntactic hacks to allow people to call functions (like print) without parentheses, although (I think) none of them made it into a PEP. The PEG parser makes this much simpler, because it can simply backtrack -- by placing the grammar rule for
In Python 3.10 we will no longer be burdened by the old parser (though 3rd party tooling needs to catch up). One thing that the PEG parser makes possible in about 20 lines of code is something not entirely different from the old print statement. I have a prototype: Python 3.10.0a0 (heads/print-statement-dirty:5ed19fcc1a, Jun 9 2020, 16:31:17) [Clang 11.0.0 (clang-1100.0.33.8)] on darwin Type "help", "copyright", "credits" or "license" for more information. Cannot read termcap database; using dumb terminal settings. people used to Python 2's print statement: this syntax (tentatively called "call statement") last in the list of alternatives for "small statement" we ensure that everything that's a valid expression statement (including print() calls) is still an expression statement with exactly the same meaning, while still allowing parameter-less function calls, without lexical hacks. (There is no code in my prototype that checks for a space after 'print' -- it just checks that there's a name, number or string following a name, which is never legal syntax.) One possible extension I didn't pursue (yet -- dare me!) is to allow parameter-less calls inside other expressions. For example, my prototype does not support things like this:
a = (len "abc") File "<stdin>", line 1 a = (len "abc") ^ SyntaxError: invalid syntax I think that strikes a reasonable balance between usability and reduced detection of common errors. I could also dial it back a bit, e.g. maybe it's too much to allow 'C().foo x' and we should only allow dotted names (sufficient to access functions in imported modules and method calls on variables). Or maybe we should only allow simple names (allowing 'len x' but disallowing 'sys.getrefcount x'. Or maybe we should really only bring back print statements. I believe there are some other languages that support a similar grammar (Ruby? R? Raku?) but I haven't investigated. Thoughts?
One additional drawback ... if anytime sooner or later you would wanted to introduce scoped variables like in `Rust` with keyword `var` or `let` it could make some problems ... ```python let x = 3 # Parser will think that it is the function let ```
-1 because it will introduce potential ambiguities and will generate stylistic battles between developers. It will also add questions when teaching python, having to explain the potentially different syntax one might find around. On Wed, 10 Jun 2020 at 01:07, Guido van Rossum <guido@python.org> wrote:
In Python 3.10 we will no longer be burdened by the old parser (though 3rd party tooling needs to catch up).
One thing that the PEG parser makes possible in about 20 lines of code is something not entirely different from the old print statement. I have a prototype:
Python 3.10.0a0 (heads/print-statement-dirty:5ed19fcc1a, Jun 9 2020, 16:31:17) [Clang 11.0.0 (clang-1100.0.33.8)] on darwin Type "help", "copyright", "credits" or "license" for more information. Cannot read termcap database; using dumb terminal settings.
print 2+2 4 print "hello world" hello world print "hello", input("Name:") Name:Guido hello Guido print 1, 2, 3, sep=", " 1, 2, 3
But wait, there's more! The same syntax will make it possible to call *any* function:
len "abc" 3
Or any method:
import sys sys.getrefcount "abc" 24
Really, *any* method:
class C: ... def foo(self, arg): print arg ... C().foo 2+2 4
There are downsides too, though. For example, you can't call a method without arguments:
print <built-in function print>
Worse, the first argument cannot start with a parenthesis or bracket:
print (1, 2, 3) 1 2 3 C().foo (1, 2, 3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: C.foo() takes 2 positional arguments but 4 were given print (2+2), 42 4 (None, 42) C().foo [0] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'method' object is not subscriptable
No, it's not April 1st. I am seriously proposing this (but I'll withdraw it if the response is a resounding "boo, hiss"). After all, we currently have a bunch of complexity in the parser just to give a helpful error message to people used to Python 2's print statement:
print 1, 2, 3 File "<stdin>", line 1 print 1, 2, 3 ^ SyntaxError: Missing parentheses in call to 'print'. Did you mean print(1, 2, 3)?
And IIRC there have been a number of aborted attempts at syntactic hacks to allow people to call functions (like print) without parentheses, although (I think) none of them made it into a PEP. The PEG parser makes this much simpler, because it can simply backtrack -- by placing the grammar rule for this syntax (tentatively called "call statement") last in the list of alternatives for "small statement" we ensure that everything that's a valid expression statement (including print() calls) is still an expression statement with exactly the same meaning, while still allowing parameter-less function calls, without lexical hacks. (There is no code in my prototype that checks for a space after 'print' -- it just checks that there's a name, number or string following a name, which is never legal syntax.)
One possible extension I didn't pursue (yet -- dare me!) is to allow parameter-less calls inside other expressions. For example, my prototype does not support things like this:
a = (len "abc") File "<stdin>", line 1 a = (len "abc") ^ SyntaxError: invalid syntax
I think that strikes a reasonable balance between usability and reduced detection of common errors.
I could also dial it back a bit, e.g. maybe it's too much to allow 'C().foo x' and we should only allow dotted names (sufficient to access functions in imported modules and method calls on variables). Or maybe we should only allow simple names (allowing 'len x' but disallowing 'sys.getrefcount x'. Or maybe we should really only bring back print statements.
I believe there are some other languages that support a similar grammar (Ruby? R? Raku?) but I haven't investigated.
Thoughts?
-- --Guido van Rossum (python.org/~guido) Pronouns: he/him (why is my pronoun here?) _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/NCQX6Z... Code of Conduct: http://python.org/psf/codeofconduct/
-- Kind regards, Stefano Borini
+1 because print is a debugging tool mostly used in short lived temporary code as such the parenthesis do not matter and do not provide any value. A lot of debugger use print to instrumentalize their code during development or debugging, as in: "I want to dump some variable and run my test again" or something like that. This means that they are writing a line of code that has a lifetime of a few minutes if not seconds. I believe that the parenthesis don't matter in the vast majority of cases where a developer writes a print statement: because they would delete afterwards ie. with git checkout -p or something. As such, PEP8 would have to decide that parenthesis are the way to go, even though bare print statements are nicer for debugging than parenthesis based debug statements.
On Mon, Oct 19, 2020 at 19:28 J. Pic <jpic@yourlabs.org> wrote:
+1 because print is a debugging tool mostly used in short lived temporary code as such the parenthesis do not matter and do not provide any value.
A lot of debugger use print to instrumentalize their code during
development or debugging, as in: "I want to dump some variable and run my test again" or something like that. This means that they are writing a line of code that has a lifetime of a few minutes if not seconds. I believe that the parenthesis don't matter in the vast majority of cases where a developer writes a print statement: because they would delete afterwards ie. with git checkout -p or something.
As such, PEP8 would have to decide that parenthesis are the way to go, even though bare print statements are nicer for debugging than parenthesis based debug statements.
-1 Respectfully, I disagree on the facts presented here. print is often not used as a disposable debugging tool. For example, it is sometimes used to write to files other than stdout. On the other hand, assert has no parentheses, and gets committed for posterity everywhere. I confess I haven't really understood the value proposition of having such a distinction between this kind of special statement and any other built in function. I never have, and clearly the early Python makers did, so feel free to discount my arguments as someone who "doesn't get it", but I nevertheless see both print and assert as contrary to some parts of the Zen of Python:
Special cases aren't special enough to break the rules. … There should be one-- and preferably only one --obvious way to do it.
On Tue, Oct 20, 2020 at 01:29:42PM +0900, Stephen J. Turnbull wrote:
Michael Smith writes:
On the other hand, assert has no parentheses, and gets committed for posterity everywhere.
ISTR that assert was not converted to a function along with print because it's a control flow construct.
Correct. Not only can the entire `assert` be turned into a no-op by the compiler, but the second part of the assertion is only evaluated if the assert fails: py> assert True, wibble() py> assert False, wibble() Traceback (most recent call last): File "<stdin>", line 1, in <module> NameError: name 'wibble' is not defined You can't do that with a function call. `print`, on the other hand, does absolutely nothing that can't be handled by a function. There's nothing special about `print`. -- Steve
J. Pic writes:
+1 because print is a debugging tool mostly used in short lived temporary code as such the parenthesis do not matter and do not provide any value.
Sez you. In *my* "business process automation" (I'm a professor), its primary use is for normal output. In debugging such code, I often replace the print function rather than add logger logging. If you want to save keystrokes, an editor macro (which avoids the shift-keystrokes required by parentheses on all keyboard layouts I know of) or "p = print" are probably more effective.
I believe that the parenthesis don't matter in the vast majority of cases where a developer writes a print statement: because they would delete afterwards ie. with git checkout -p or something.
Certainly not true for me.
print is now a function, and as such can be passed to something that expects a callable. We would lose this if it were restored to a statement. Consequently this would be a breaking change, so I don't see it happening. On Tue, 2020-10-20 at 01:21 +0200, J. Pic wrote:
+1 because print is a debugging tool mostly used in short lived temporary code as such the parenthesis do not matter and do not provide any value.
A lot of debugger use print to instrumentalize their code during development or debugging, as in: "I want to dump some variable and run my test again" or something like that. This means that they are writing a line of code that has a lifetime of a few minutes if not seconds. I believe that the parenthesis don't matter in the vast majority of cases where a developer writes a print statement: because they would delete afterwards ie. with git checkout -p or something.
As such, PEP8 would have to decide that parenthesis are the way to go, even though bare print statements are nicer for debugging than parenthesis based debug statements. _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/PGWCRA... Code of Conduct: http://python.org/psf/codeofconduct/
On Tue, Oct 20, 2020 at 3:47 PM Paul Bryan <pbryan@anode.ca> wrote:
print is now a function, and as such can be passed to something that expects a callable. We would lose this if it were restored to a statement. Consequently this would be a breaking change, so I don't see it happening.
Did you read the post that opened this thread? :) ChrisA
Yeah, I should have done that instead of replying without context. 🤦 On Tue, 2020-10-20 at 17:43 +1100, Chris Angelico wrote:
On Tue, Oct 20, 2020 at 3:47 PM Paul Bryan <pbryan@anode.ca> wrote:
print is now a function, and as such can be passed to something that expects a callable. We would lose this if it were restored to a statement. Consequently this would be a breaking change, so I don't see it happening.
Did you read the post that opened this thread? :)
ChrisA _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/5LDKR6... Code of Conduct: http://python.org/psf/codeofconduct/
No, the proposal was to keep print a function, but to allow alternative syntax without brackets (that would still call it as a function). Best wishes Rob Cliffe On 20/10/2020 05:38, Paul Bryan wrote:
printis now a function, and as such can be passed to something that expects a callable. We would lose this if it were restored to a statement. Consequently this would be a breaking change, so I don't see it happening.
On Tue, 2020-10-20 at 01:21 +0200, J. Pic wrote:
+1 because print is a debugging tool mostly used in short lived temporary code as such the parenthesis do not matter and do not provide any value.
A lot of debugger use print to instrumentalize their code during development or debugging, as in: "I want to dump some variable and run my test again" or something like that. This means that they are writing a line of code that has a lifetime of a few minutes if not seconds. I believe that the parenthesis don't matter in the vast majority of cases where a developer writes a print statement: because they would delete afterwards ie. with git checkout -p or something.
As such, PEP8 would have to decide that parenthesis are the way to go, even though bare print statements are nicer for debugging than parenthesis based debug statements. _______________________________________________ Python-ideas mailing list -- python-ideas@python.org <mailto:python-ideas@python.org> To unsubscribe send an email to python-ideas-leave@python.org <mailto:python-ideas-leave@python.org> https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/PGWCRA... Code of Conduct: http://python.org/psf/codeofconduct/
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/ZEC2F5... Code of Conduct: http://python.org/psf/codeofconduct/
Well personally I don't need print at all, I just read code and imagine the output in my head and that's perfectly fine for me (I don't even need a tty). Nonetheless, I believe the majority of Python users are not necessarily familiar with PDB and would be using print as their main debugging tool, in which case the print statement will not be kept in runtime code in which case parenthesis have a cost but no added value. At the same time, Guido says he can remove that cost for no extra cost, so there's that: how do we find a good reason to not remove a cost for free ? Sounds like a win/win situation, both for most users and for the new pegparser. Besides that, I completely agree with your points.
On Tue, Oct 20, 2020 at 06:02 J. Pic <jpic@yourlabs.org> wrote:
Well personally I don't need print at all, I just read code and imagine the output in my head and that's perfectly fine for me (I don't even need a tty).
Nonetheless, I believe the majority of Python users are not necessarily familiar with PDB and would be using print as their main debugging tool, in which case the print statement will not be kept in runtime code in which case parenthesis have a cost but no added value.
At the same time, Guido says he can remove that cost for no extra cost, so there's that: how do we find a good reason to not remove a cost for free ? Sounds like a win/win situation, both for most users and for the new pegparser.
I guess it sounds like getting something good for free, but I think it's really just violating the principle of least astonishment. Sometime, someone is going to ask, "why is this program not printing to stdout?" just like many programmers before have run python -O and didn't read the fine print. I just don't think print is special enough to break the rules. If we want to talk about changing the rules in general, I'd be interested in a tangential discussion of DCE if someone wants to talk about that in another thread.
20.10.20 12:54, J. Pic пише:
At the same time, Guido says he can remove that cost for no extra cost, so there's that: how do we find a good reason to not remove a cost for free ? Sounds like a win/win situation, both for most users and for the new pegparser.
It may have closer to zero cost of the initial implementation, but the cost of maintaining, supporting in different standard and third-party modules, teaching and learning, and using is far from zero. Just look how many special cases Python 2 print has: print without arguments, printing a tuple, print >>, print with trailing comma. And the latter feature ("soft" space) is not supported by files in Python 3, so you would need to change them too, and all file-like objects in the world. Getting rid of the print statement was one of the largest achievements of Python 3 (after all-unicode).
Couldn't agree more. On 2020. 10. 20. 16:43, Serhiy Storchaka wrote:
20.10.20 12:54, J. Pic пише:
At the same time, Guido says he can remove that cost for no extra cost, so there's that: how do we find a good reason to not remove a cost for free ? Sounds like a win/win situation, both for most users and for the new pegparser. It may have closer to zero cost of the initial implementation, but the cost of maintaining, supporting in different standard and third-party modules, teaching and learning, and using is far from zero.
Just look how many special cases Python 2 print has: print without arguments, printing a tuple, print >>, print with trailing comma. And the latter feature ("soft" space) is not supported by files in Python 3, so you would need to change them too, and all file-like objects in the world.
Getting rid of the print statement was one of the largest achievements of Python 3 (after all-unicode). _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/2X2VRT... Code of Conduct: http://python.org/psf/codeofconduct/
Agree with Serhiy. IIRC Ruby allows skipping brackets for a function call, this is very confusing sometimes On Tue, Oct 20, 2020, 18:54 Antal Gábor <antalgabor1993@gmail.com> wrote:
Couldn't agree more.
On 2020. 10. 20. 16:43, Serhiy Storchaka wrote:
20.10.20 12:54, J. Pic пише:
At the same time, Guido says he can remove that cost for no extra cost, so there's that: how do we find a good reason to not remove a cost for free ? Sounds like a win/win situation, both for most users and for the new pegparser. It may have closer to zero cost of the initial implementation, but the cost of maintaining, supporting in different standard and third-party modules, teaching and learning, and using is far from zero.
Just look how many special cases Python 2 print has: print without arguments, printing a tuple, print >>, print with trailing comma. And the latter feature ("soft" space) is not supported by files in Python 3, so you would need to change them too, and all file-like objects in the world.
Getting rid of the print statement was one of the largest achievements of Python 3 (after all-unicode). _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/2X2VRT... Code of Conduct: http://python.org/psf/codeofconduct/
Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/67ZO7K... Code of Conduct: http://python.org/psf/codeofconduct/
tl;dr *boo* *hiss* I can only imagine the new Python programmer's look of confusion, turning to disgust, turning to giving up. """ Whatever you do, don't write 'print space object', that's old Python 2. ... oh but, except waitasec, but if you're using Python 3.10 or greater then you can use the new print statement, but see you can't just write 'print', you have to pass it an object. But it's different than the print function, just trust me. they're different. ... Your program crashed? Oh see, you're using Python 3.8, and the new print statement was not in that version of Python. Didn't I mention Python three *TEN* ? ... No, no, not the same, they are two different things, called 'print'. ... Right, right, yeah I know the Python 2 code you read on the internet used a bare print statement. ... No, sorry, what you're referring to is the print *STATEMENT*. ... Here, read this article explaining the history of the print statement in Python. ... See, the print statement was reintroduced to help you, make sense? ... No, sorry, what you're referring to the print *FUNCTION*. ... Hey, uhh.. why are you logging off the online Python tutorial? Don't you want to learn Python? But it's a fun easy language to get you started in programming! """ Re-introducing the print statement is too much finicky history revolving around one function, erm sorry, statement. This is too much confusion for newbies. Experienced users will have a more communication overhead or ambiguity in clarifying precisely which 'print'. If it's for debugging then call it "debug" or something like that. -James T Moon
On Mon, Oct 19, 2020, at 22:41, James T Moon wrote:
tl;dr *boo* *hiss*
I can only imagine the new Python programmer's look of confusion, turning to disgust, turning to giving up.
Ten years from now, hopefully, Python 2 will be a distant memory, and Python 3.8 will be, at the very least, long out of support and unlikely to be the system new users are learning Python on, and none of the dialogue you've just written will have to take place at all. Does anyone else remember when xkcd first mentioned python? The main selling point it had for it [and the one that was actually literally true, vs 'import antigravity' which was a semi-satirical bit about the batteries-included philosophy] was 'Hello world is just print "Hello, world!"' Wouldn't it be nice if that were true again, even if the details of how it works [and other things like how you print to other files] aren't quite the same as they used to be?
On Fri, 23 Oct 2020 at 06:35, Random832 <random832@fastmail.com> wrote:
Does anyone else remember when xkcd first mentioned python? The main selling point it had for it [and the one that was actually literally true, vs 'import antigravity' which was a semi-satirical bit about the batteries-included philosophy] was 'Hello world is just print "Hello, world!"'
For reference the XKCD is https://xkcd.com/353/. I think the point of the XKCD is not the difference between print "Hello World" and print("Hello World") but all the other clutter normally needed (importing stdio.h in C and main function comes to mind) and the other batteries included (anti-gravity as a joke, but more seriously, all the lovely modules the users can use by default).
Wouldn't it be nice if that were true again, even if the details of how it works [and other things like how you print to other files] aren't quite the same as they used to be?
I disagree as do many in this thread.
On Fri, 23 Oct 2020 at 06:59, Henk-Jaap Wagenaar <wagenaarhenkjaap@gmail.com> wrote:
On Fri, 23 Oct 2020 at 06:35, Random832 <random832@fastmail.com> wrote:
Does anyone else remember when xkcd first mentioned python? The main selling point it had for it [and the one that was actually literally true, vs 'import antigravity' which was a semi-satirical bit about the batteries-included philosophy] was 'Hello world is just print "Hello, world!"'
For reference the XKCD is https://xkcd.com/353/.
For information, you don't need to know that URL. If you "import antigravity" in a Python session, your browser will open this webpage automatically :-) Paul
That makes me think of ruby where you can omit some of the function call. On Wed, Jun 10, 2020, 02:08 Guido van Rossum <guido@python.org> wrote:
In Python 3.10 we will no longer be burdened by the old parser (though 3rd party tooling needs to catch up).
One thing that the PEG parser makes possible in about 20 lines of code is something not entirely different from the old print statement. I have a prototype:
Python 3.10.0a0 (heads/print-statement-dirty:5ed19fcc1a, Jun 9 2020, 16:31:17) [Clang 11.0.0 (clang-1100.0.33.8)] on darwin Type "help", "copyright", "credits" or "license" for more information. Cannot read termcap database; using dumb terminal settings.
print 2+2 4 print "hello world" hello world print "hello", input("Name:") Name:Guido hello Guido print 1, 2, 3, sep=", " 1, 2, 3
But wait, there's more! The same syntax will make it possible to call *any* function:
len "abc" 3
Or any method:
import sys sys.getrefcount "abc" 24
Really, *any* method:
class C: ... def foo(self, arg): print arg ... C().foo 2+2 4
There are downsides too, though. For example, you can't call a method without arguments:
print <built-in function print>
Worse, the first argument cannot start with a parenthesis or bracket:
print (1, 2, 3) 1 2 3 C().foo (1, 2, 3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: C.foo() takes 2 positional arguments but 4 were given print (2+2), 42 4 (None, 42) C().foo [0] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'method' object is not subscriptable
No, it's not April 1st. I am seriously proposing this (but I'll withdraw it if the response is a resounding "boo, hiss"). After all, we currently have a bunch of complexity in the parser just to give a helpful error message to people used to Python 2's print statement:
print 1, 2, 3 File "<stdin>", line 1 print 1, 2, 3 ^ SyntaxError: Missing parentheses in call to 'print'. Did you mean print(1, 2, 3)?
And IIRC there have been a number of aborted attempts at syntactic hacks to allow people to call functions (like print) without parentheses, although (I think) none of them made it into a PEP. The PEG parser makes this much simpler, because it can simply backtrack -- by placing the grammar rule for this syntax (tentatively called "call statement") last in the list of alternatives for "small statement" we ensure that everything that's a valid expression statement (including print() calls) is still an expression statement with exactly the same meaning, while still allowing parameter-less function calls, without lexical hacks. (There is no code in my prototype that checks for a space after 'print' -- it just checks that there's a name, number or string following a name, which is never legal syntax.)
One possible extension I didn't pursue (yet -- dare me!) is to allow parameter-less calls inside other expressions. For example, my prototype does not support things like this:
a = (len "abc") File "<stdin>", line 1 a = (len "abc") ^ SyntaxError: invalid syntax
I think that strikes a reasonable balance between usability and reduced detection of common errors.
I could also dial it back a bit, e.g. maybe it's too much to allow 'C().foo x' and we should only allow dotted names (sufficient to access functions in imported modules and method calls on variables). Or maybe we should only allow simple names (allowing 'len x' but disallowing 'sys.getrefcount x'. Or maybe we should really only bring back print statements.
I believe there are some other languages that support a similar grammar (Ruby? R? Raku?) but I haven't investigated.
Thoughts?
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/> _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/NCQX6Z... Code of Conduct: http://python.org/psf/codeofconduct/
My little contribution I will always prefer expressions over statements. So, -1 for bringing back a statement for something that we have a function for. Functions are first citizens, statement are not Now if we are talking about parenthesesless expressions, if we're designing a language from scratch I would upvote this, but today in python I don't really know if is worth, mainly because parameterless function can't be called this way without breaking a lot of code, and this is the most elegant part of parenthesesless calls, they would make properties obsolete. This is the charm of Ruby IMHO Em sex, 23 de out de 2020 19:51, Robert Vanden Eynde <robertve92@gmail.com> escreveu:
That makes me think of ruby where you can omit some of the function call.
On Wed, Jun 10, 2020, 02:08 Guido van Rossum <guido@python.org> wrote:
In Python 3.10 we will no longer be burdened by the old parser (though 3rd party tooling needs to catch up).
One thing that the PEG parser makes possible in about 20 lines of code is something not entirely different from the old print statement. I have a prototype:
Python 3.10.0a0 (heads/print-statement-dirty:5ed19fcc1a, Jun 9 2020, 16:31:17) [Clang 11.0.0 (clang-1100.0.33.8)] on darwin Type "help", "copyright", "credits" or "license" for more information. Cannot read termcap database; using dumb terminal settings.
print 2+2 4 print "hello world" hello world print "hello", input("Name:") Name:Guido hello Guido print 1, 2, 3, sep=", " 1, 2, 3
But wait, there's more! The same syntax will make it possible to call *any* function:
len "abc" 3
Or any method:
import sys sys.getrefcount "abc" 24
Really, *any* method:
class C: ... def foo(self, arg): print arg ... C().foo 2+2 4
There are downsides too, though. For example, you can't call a method without arguments:
print <built-in function print>
Worse, the first argument cannot start with a parenthesis or bracket:
print (1, 2, 3) 1 2 3 C().foo (1, 2, 3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: C.foo() takes 2 positional arguments but 4 were given print (2+2), 42 4 (None, 42) C().foo [0] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'method' object is not subscriptable
No, it's not April 1st. I am seriously proposing this (but I'll withdraw it if the response is a resounding "boo, hiss"). After all, we currently have a bunch of complexity in the parser just to give a helpful error message to people used to Python 2's print statement:
print 1, 2, 3 File "<stdin>", line 1 print 1, 2, 3 ^ SyntaxError: Missing parentheses in call to 'print'. Did you mean print(1, 2, 3)?
And IIRC there have been a number of aborted attempts at syntactic hacks to allow people to call functions (like print) without parentheses, although (I think) none of them made it into a PEP. The PEG parser makes this much simpler, because it can simply backtrack -- by placing the grammar rule for this syntax (tentatively called "call statement") last in the list of alternatives for "small statement" we ensure that everything that's a valid expression statement (including print() calls) is still an expression statement with exactly the same meaning, while still allowing parameter-less function calls, without lexical hacks. (There is no code in my prototype that checks for a space after 'print' -- it just checks that there's a name, number or string following a name, which is never legal syntax.)
One possible extension I didn't pursue (yet -- dare me!) is to allow parameter-less calls inside other expressions. For example, my prototype does not support things like this:
a = (len "abc") File "<stdin>", line 1 a = (len "abc") ^ SyntaxError: invalid syntax
I think that strikes a reasonable balance between usability and reduced detection of common errors.
I could also dial it back a bit, e.g. maybe it's too much to allow 'C().foo x' and we should only allow dotted names (sufficient to access functions in imported modules and method calls on variables). Or maybe we should only allow simple names (allowing 'len x' but disallowing 'sys.getrefcount x'. Or maybe we should really only bring back print statements.
I believe there are some other languages that support a similar grammar (Ruby? R? Raku?) but I haven't investigated.
Thoughts?
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/> _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/NCQX6Z... Code of Conduct: http://python.org/psf/codeofconduct/
_______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/UCXI3H... Code of Conduct: http://python.org/psf/codeofconduct/
This idea reminds me of a similar feature in Groovy. I really like this feature because it allows application developers to let users write Python code that is very English-like (more than Python already is).
On several functional languages that allow function invocations without enclosing arguments in parentheses all functions take a single argument. For multiple arguments the single argument is a tuple. For no arguments the single argument is an empty tuple. I've read the comments and I see more fear than dislike in them. Because the feature is mostly implemented, I think it would be good to add it to the language with a __future__ guard. Then the community as a whole can evaluate the pros and cons. I would implement the feature for *all* expressions (including arguments/parameters). -- Juancarlo Añez mailto:apalala@gmail.com On Tue, Jun 9, 2020 at 8:09 PM Guido van Rossum <guido@python.org> wrote:
In Python 3.10 we will no longer be burdened by the old parser (though 3rd party tooling needs to catch up).
One thing that the PEG parser makes possible in about 20 lines of code is something not entirely different from the old print statement. I have a prototype:
Python 3.10.0a0 (heads/print-statement-dirty:5ed19fcc1a, Jun 9 2020, 16:31:17) [Clang 11.0.0 (clang-1100.0.33.8)] on darwin Type "help", "copyright", "credits" or "license" for more information. Cannot read termcap database; using dumb terminal settings.
print 2+2 4 print "hello world" hello world print "hello", input("Name:") Name:Guido hello Guido print 1, 2, 3, sep=", " 1, 2, 3
But wait, there's more! The same syntax will make it possible to call *any* function:
len "abc" 3
Or any method:
import sys sys.getrefcount "abc" 24
Really, *any* method:
class C: ... def foo(self, arg): print arg ... C().foo 2+2 4
There are downsides too, though. For example, you can't call a method without arguments:
print <built-in function print>
Worse, the first argument cannot start with a parenthesis or bracket:
print (1, 2, 3) 1 2 3 C().foo (1, 2, 3) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: C.foo() takes 2 positional arguments but 4 were given print (2+2), 42 4 (None, 42) C().foo [0] Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: 'method' object is not subscriptable
No, it's not April 1st. I am seriously proposing this (but I'll withdraw it if the response is a resounding "boo, hiss"). After all, we currently have a bunch of complexity in the parser just to give a helpful error message to people used to Python 2's print statement:
print 1, 2, 3 File "<stdin>", line 1 print 1, 2, 3 ^ SyntaxError: Missing parentheses in call to 'print'. Did you mean print(1, 2, 3)?
And IIRC there have been a number of aborted attempts at syntactic hacks to allow people to call functions (like print) without parentheses, although (I think) none of them made it into a PEP. The PEG parser makes this much simpler, because it can simply backtrack -- by placing the grammar rule for this syntax (tentatively called "call statement") last in the list of alternatives for "small statement" we ensure that everything that's a valid expression statement (including print() calls) is still an expression statement with exactly the same meaning, while still allowing parameter-less function calls, without lexical hacks. (There is no code in my prototype that checks for a space after 'print' -- it just checks that there's a name, number or string following a name, which is never legal syntax.)
One possible extension I didn't pursue (yet -- dare me!) is to allow parameter-less calls inside other expressions. For example, my prototype does not support things like this:
a = (len "abc") File "<stdin>", line 1 a = (len "abc") ^ SyntaxError: invalid syntax
I think that strikes a reasonable balance between usability and reduced detection of common errors.
I could also dial it back a bit, e.g. maybe it's too much to allow 'C().foo x' and we should only allow dotted names (sufficient to access functions in imported modules and method calls on variables). Or maybe we should only allow simple names (allowing 'len x' but disallowing 'sys.getrefcount x'. Or maybe we should really only bring back print statements.
I believe there are some other languages that support a similar grammar (Ruby? R? Raku?) but I haven't investigated.
Thoughts?
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/> _______________________________________________ Python-ideas mailing list -- python-ideas@python.org To unsubscribe send an email to python-ideas-leave@python.org https://mail.python.org/mailman3/lists/python-ideas.python.org/ Message archived at https://mail.python.org/archives/list/python-ideas@python.org/message/NCQX6Z... Code of Conduct: http://python.org/psf/codeofconduct/
participants (42)
-
Andrew Svetlov
-
Antal Gábor
-
Antoine Pitrou
-
Bernardo Sulzbach
-
Brandt Bucher
-
Calvin Spealman
-
Chris Angelico
-
Dan Sommers
-
Daniel.
-
David Mertz
-
Edwin Zimmerman
-
Ethan Furman
-
Greg Ewing
-
Gregory P. Smith
-
Guido van Rossum
-
Henk-Jaap Wagenaar
-
J. Pic
-
James T Moon
-
Jonathan Crall
-
Jonathan Goble
-
Josiah (Gaming32) Glosson
-
João Bernardo
-
Juancarlo Añez
-
Matthias Bussonnier
-
Michael Smith
-
MRAB
-
Naomi Ceder
-
Neil Girdhar
-
Paul Bryan
-
Paul Moore
-
Random832
-
redradist@gmail.com
-
Rhodri James
-
Ricky Teachey
-
Rob Cliffe
-
Robert Vanden Eynde
-
sadhanasrinivasan@pm.me
-
Serhiy Storchaka
-
Stefano Borini
-
Stephen J. Turnbull
-
Steve Barnes
-
Steven D'Aprano