[HN Gopher] Bringing the print statement back ___________________________________________________________________ Bringing the print statement back Author : Myrmornis Score : 95 points Date : 2020-07-14 20:16 UTC (2 hours ago) (HTM) web link (lwn.net) (TXT) w3m dump (lwn.net) | softwaredoug wrote: | Seems to violate "There should be one-- and preferably only one | --obvious way to do it." | open-source-ux wrote: | _" There should be one-- and preferably only one --obvious way | to do it."_ | | This principle is often repeated for Python, but does it have | any bearing on reality today? With every release of Python (and | indeed for many other languages), new features give you even | more ways of doing things. | | Python is 30 years old - it's no longer the small language it | may once have been, but is now chock-full of features. Maybe | once there was an "obvious way to do it", but I don't thing | this is true today. | enriquto wrote: | > Seems to violate "There should be one-- and preferably only | one --obvious way to do it." | | Just as representing a vector of numbers as a tuple, a list, a | dictionary, a numpy matrix or a numpy array. And don't get me | started on multidimensional arrays. | solox3 wrote: | Says the line with two different hyphenating styles. | | It's an Easter egg. | idoh wrote: | So pedantic but I love it. For the GP, what you are looking | for is them em dash (--) with no spaces around it, because | the dash is its own form of punctuation. | taylorlunt wrote: | Some style guides allow for surrounding the em dash with | spaces. It's a matter of preference. | kelnos wrote: | A double-dash is a perfectly valid substitute for an em | dash given that most (no?) keyboards have it on a key. | Seems like a waste of time to always have to look up an | escape code or copy/paste from somewhere when the intent of | "--" is clear. | idoh wrote: | I don't hold random comments on the internet to the | highest standard because I am not a monster. However they | are not equivalent and the em dash is a sign of extra | polish. | Veen wrote: | It's option-shift-hyphen on a Mac. And you can get at em | dashes on an iOS keyboard by long pressing the hyphen. | Not so difficult. | owl57 wrote: | These look like brackets, not binary operators. So, that's | one style, but a rather unobvious one, and also contradicts | PEP8, which says (as the very first thing in the section on | inline spaces!) to avoid whitespace immediately inside | brackets. | AlexMax wrote: | Sorry, but I think this is a poisonous, thought-terminating | cliche. | | Python has had multiple ways of doing many things for a very | long time, and the longer you program in any language, the more | you realize there are often many solutions to a problem and the | "best" approach either depends on context or you realize there | is no one "best" approach and go on preference. | | I think the idea should be judged on its own merits without | having to consult the Zen. That said, I seriously don't see the | point of it. Python 3 already forced everybody to convert all | their print statements to look like function calls, and now GVR | wants to bring the old style back as an option? It's just | parenthesis, what's the point? | | If he wants to put that new parser to work, how about taking | another look at multi-line lambdas? | BiteCode_dev wrote: | Ruby does this and I hate it. It makes it very hard to quickly | parse code: you have to ponder every line to identify what is | what. | | Parenthesis makes very clear what context you are in. | VWWHFSfQ wrote: | The only place I've ever liked function calls without parentheses | is Lua. But it only supports it with a single literal string or | table argument. | | So, boo. Hiss. | mumblemumble wrote: | OK, so I sort of get it. I love ML style syntax. I love the way | that it supports great things like partial application. | | What I do not like is TMTOWTDI. And I do not like Python | violating its own principles (namely, "explicit is better than | implicit"). As far as I am concerned, in Python, which does _not_ | have partial application, function application is handled by a | special `(...)` operator that explicitly applies whatever | function comes before the parens to whatever is inside the | parens. Making the parens optional gives you two different ways | to apply a function - and, by extension, one more place for | people to argue about style - one of which is just an implicit | version of the other. | | You've got to have a _way_ better reason to do that to a language | than just, "Hey, isn't this cool? And also, I miss the Python 2 | vs Python 3 wars, so wouldn't it be fun to give that pot another | stir for old time's sake?" | | I get it, the change from a print statement to a print function | caused some pain. But it did bring some practical benefits, and | the transition is in the past now, and, to quote the Zen of | Python again, "special cases aren't special enough to break the | rules." | mumblemumble wrote: | Another thought: This would create ambiguities in the language | that would harm its readability. Maybe not as far as the | computer is concerned, but certainly as far as the humans are | concerned. Is print(1, 2, 3) | | supposed to print 1 2 3 | | or (1, 2, 3) | | ? | | What about print (1, 2, 3) | | ? | | Are they the same? Should they be different? I know what the | answer is in Python 3.8. A few weeks or months of programming | in a Python where parens are optional, though, and I wouldn't | be so sure anymore. | tetha wrote: | > You've got to have a way better reason to do that to a | language than just, "Hey, isn't this cool? And also, I miss the | Python 2 vs Python 3 wars, so wouldn't it be fun to give that | pot another stir for old time's sake?" | | That was my first thought. Why would we turn a simple, binary | choice -- "< 3: statement, >= 3: function" into a big old... | maybe? | | The binary choice hurts, because it dictates changes. Sure. | People dislike change, but it's easy to support. | | However, there's one thing worse than change, and that's | inconsistency and uncertainty. like, in this case, going | "zoinks, your change wasn't actually necessary!". Except, now | we have both choices. So it'd be even more confusing. | riknos314 wrote: | This is on point. | | I'm also going to throw another reference to PEP-20 in the mix | here: "There should be one-- and preferably only one --obvious | way to do it." This implies either forcing parens everywhere or | not using them at all. Paired with "explicit is better than | implicit", I'd say that points pretty clearly at using parens | everywhere. | jcfields wrote: | As they say, the road to Perl is paved with good intentions. | | There are several languages that people like for this sort of | flexibility, but I think Python's relative rigidity has always | been one of its strengths. | flingo wrote: | This is insane, I love it. | | How long until this is a library on pypi? | aardvark291 wrote: | Seems a bit early/late for April Fools. | cjhanks wrote: | I really hope they do not do this. In and of itself it is not a | problem, Ruby code is perfectly readable when the style is | consistent. | | Software developers are often stubborn. The main result of this | change will be a mess of code which follows a mix of _all_ the | styles. That removes one of the greatest beauties of the Python | ecosystem, that there is a "right way" to do things. | mumblemumble wrote: | Agreed. I deeply love the concept of Pythonic. | | The Pythonic way to do it is (very) often not my favorite way | to do it. But, if I'm working in Python, I'm going to do it | that way, anyway. Because social factors matter, and choosing | your own convention rarely yields enough benefit to justify | choosing not to follow _the_ convention. | iovrthoughtthis wrote: | "I believe there are some other languages that support a similar | grammar (Ruby? R? Raku?) but I haven't investigated." | | Poor effort tbh but I've been excited about new possibilities | before too. | | Can anyone say which style of parser python used before and why | The bee PEG parser is more powerful. It's my understanding that | PEG parser are equivalent to RDPs. | ccmcarey wrote: | I don't see any benefits to this, Guido does a good job | mentioning many of the negatives .. and, aware of them all, I am | surprised he would push on. It seems an unreasonable increase in | complexity for no tangible gain. | rerx wrote: | I felt that the old print statement sometimes was handy when I | wanted to quickly throw some debugging lines into the code -- | just less hassle with parentheses. But I wouldn't want any of the | ambiguity GvR's suggestion would bring. | | For debugging comfort the print statement is half measures | anyway: Give us Julia's @show macro! | [deleted] | saiojd wrote: | I wish all languages just adopted ML syntax for function | application. | ris wrote: | > but I'll withdraw it if the response is a resounding "boo, | hiss" | | Boo, hiss. | | The parentheses-less function call is the second biggest obstacle | to ruby readability. | epicureanideal wrote: | This is more Ruby than Python. I specifically prefer Python more | because of its explicitness. | simzor wrote: | Hate the idea to be honest. In my opinion this will just bloat | the language, no need. Rather avoid the hundreds of different | standards like PHP. | enriquto wrote: | LOL, I totally love this! | tony wrote: | If you want to see some nice examples of PEP 617's (The new PEG | Parser) potential, see the draft of | https://www.python.org/dev/peps/pep-0622/ | | But `print 'hi world'` This would really spoil one of the nice | consistency things python 3 brought. | | Callables without parenthesis to distinguish the arguments. Can | you imagine what this is going to do to readability on open | source projects? | | This was back in June, and probably for the sake of conversation. | It got my (and a lot of others) attention, though. If that was | the case, mission accomplished. | | I'm all for the new parser enabled in Python 3.9 (and switched on | by default in 3.10): https://www.python.org/dev/peps/pep-0617/ | pavel_lishin wrote: | I loathe function calls without parentheses; it always looks | vaguely ambiguous to me. | enriquto wrote: | > I loathe function calls without parentheses; it always looks | vaguely ambiguous to me. | | But then again, throwing and catching exceptions through | arbitrary depths along the call stack is perfectly clear and | neat. | fernandotakai wrote: | i took me a while to get used to `print()` but now that i'm | used to it, when i see py2 code i get... confused? it doesn't | look right. | | same with `class Foo(object):` | pdonis wrote: | _> same with `class Foo(object):`_ | | That's still legal, and actually I prefer it even though it's | not required in Python 3, because explicit is better than | implicit. | geophile wrote: | What is the point? Why is this a desirable thing at all? TFA goes | directly into implementation and has not a word about why this is | desirable for readability, aesthetics, or any other criterion. | | Seems like the sort of faddish syntactic sugar that they love in | Swift. Please, not in Python. | scrollaway wrote: | I think "the point", given the wording of the email, is to | showcase the power of the new parser; not implement it. | | (I fucking hope) | kissgyorgy wrote: | This is the exact language Guide stopped being BDFL. STOP IT! | klyrs wrote: | The ambiguity of | | foo (boo, hiss) | | should immediately close the issue. What the heck is happening? | haecceity wrote: | >>> print (1, 2, 3) | | Is that supposed to be a function call with a tuple or function | call with 3 integers? | corbet wrote: | See also the article (https://lwn.net/Articles/823292/) written | about this idea. | nurettin wrote: | > I believe there are some other languages that support a similar | grammar (Ruby? R? Raku?) but I haven't investigated. | | Yes you did. And you want to take the good things from ruby. You | want no parentheses calls, block syntax instead of lambdas, | chainable map/filter/sort/reduce, accessor syntax, you want to | extend basic types so you can call methods on literals. You want | ruby all over you. Just admit it. | lizmat wrote: | Or Raku :-) | jeanvalmarc wrote: | If they'd done this right at the PY3K transition and _only_ | allowed the function-call-without-parenthesis syntax for `print` | calls it could have been a good idea. But now that the community | paid the decade-long price to get print as a normal function why | backtrack? | kbd wrote: | The optional parentheses for any function Guido proposes is | similar to how Nim works. It's pleasant within Nim but seems too | TMTOWTDI for Python. | SiVal wrote: | return (boo, hiss) | | There is something mature and responsible about a language that | tends to refuse a command if the meaning isn't obvious, forcing | you to make it obvious. If instead, you assign meanings to every | ambiguous statement, and to the inevitable exceptions and | exceptions to exceptions, you end up with JavaScript: "Oh, well, | too late now"-oriented design. | zaptheimpaler wrote: | Don't worry, its not coming back. Just goes to prove the old rule | - no one reads beyond the headline :) | | ---- | | > 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". > | | (Guidos response below): | | 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. | | ---- | marczellm wrote: | Check out xonsh which is an application of python + that sort of | idea to the problem space of shell scripting. | | https://xon.sh/ | dom96 wrote: | > I believe there are some other languages that support a similar | grammar (Ruby? R? Raku?) but I haven't investigated. | | I'm amazed that Guido is not aware of Nim which does precisely | this. It works brilliantly too. It would be incredible if Python | becomes more like Nim (Nim itself having been inspired a fair bit | by Python). | [deleted] | Daishiman wrote: | Too ambiguous. | | One thing I love about Python is that it's clear when I'm passing | a function/method as argument, or aliasing a class, or just | generally knowing when I'm calling something vs referencing it. | | This is a no-go from the start. | eatonphil wrote: | When I program in Standard ML or F# I always use parentheses to | make it clearer that a function call is happening. | vasili111 wrote: | I do not like this idea. I think it is better to stick to one | standard of syntax and do not create several ways of doing same | thing without added significant benefit. | HALtheWise wrote: | One really nice feature from Wolfram Mathematica that few other | languages seem to have is a special prefix-only syntax for | single-argument function application. In Mathematica, it's f@x | ==> f(x), and it's really convenient because it prevents needing | to move your cursor to the end to put in a closing paren. Since | it only works for single-argument functions, there's no | ambiguity. | beervirus wrote: | Allowing this syntax for all functions and methods seems | ridiculous, especially with the problems Guido mentions (like how | the first argument can't begin with a paren or bracket, wtf). But | a limited version of this feature that's specific only to the | print statement seems fine. If the parser already has the | complexity to issue a warning like: | | SyntaxError: Missing parentheses in call to 'print'. Did you mean | print(1, 2, 3)? | | Then why not just have it DWIM? | D13Fd wrote: | I seriously do not see any worthwhile benefit in this, and | significant cost. | | Benefits: You can use spaces instead of parenthesis. It's the | same number of characters and function arguments won't work with | spaces. | | Costs: Python has to support this forever. Increased complexity. | More difficult to read code, because you could be doing the same | thing in multiple ways. More style guidelines to enforce. | Confusion among new programmers about why they can't use function | arguments without parenthesis. Confusion among new programmers | about why they would use spaces instead of parenthesis (or the | reverse). | | Seriously, I do not see any reason why they would ever want to | add this in light of the seemingly obvious costs. | confeit wrote: | > Missing parentheses in call to 'print'. Did you mean print(1, | 2, 3)? | | Yes, Python, I meant _exactly_ that! I 've never seen this error | message in error. Now you know what I mean, please fix it | automatically, I know you can do that. Heck, throw a single | warning if you really want to enforce this. I can ignore warnings | that I don't care about. | coldtea wrote: | Yeah, generally please second-guess me Python, like my old pal | Clippy did, what could possibly go wrong? | confeit wrote: | > You're flying! How? | | > Python! I learned it last night! Everything is so simple! | Hello world is just: print "Hello, world!" | | > SyntaxError: Missing parentheses in call to 'print'. Did | you mean print("Hello, world!")? | | > I dunno... dynamic typing? _Whitespace?_ | | > Come join us! Programming is fun again! It's a whole new | world up here! | | > But how are you flying? | | > I just typed: imports antigravity as ag | | > TypeError: imports() takes 2 positional arguments but 3 | were given | coolreader18 wrote: | Nim does this, and the whitespace is significant[0][1]: | echo $foo # is parsed as echo($foo) | | [..] echo(1, 2) # pass 1 and 2 to echo | echo (1, 2) # pass the tuple (1, 2) to echo | | [..] proc optarg(x: int, y: int = 0): int = x + | y proc singlearg(x: int): int = 20*x | echo optarg 1, " ", singlearg 2 # prints "1 40" | let fail = optarg 1, optarg 8 # Wrong. Too many arguments for a | command call let x = optarg(1, optarg 8) # traditional | procedure call with 2 arguments let y = 1.optarg optarg 8 | # same thing as above, w/o the parenthesis assert x == y | | [0]: https://nim-lang.org/docs/manual.html#syntax-precedence | | [1]: https://nim-lang.org/docs/manual.html#procedures-command- | inv... | gen220 wrote: | Is there a justification for this behavior? | | This makes it quite hard to "sight-read" code with reasonably- | sized function names and arg lists: | do_some_thing_descriptive (some_arg_2, some_longer_arg) | | [ ... other code ] | do_some_very_descriptive_thing(some_arg_2, some_longer_arg) | | I imagine that each file would try to remain internally- | consistent with preferring one syntax over the other. | | IMO, in scenarios where a module must remain internally- | consistent on its one-of-many-ways to do it, for the sake of | legibility, there should be only one way to do it. Although, | I'm open to hearing any good-faith arguments to the contrary! | gtrubetskoy wrote: | Python becoming Tcl | vasili111 wrote: | Unfortunately Python will not get the strength of TCL such as | metaprogramming with this change. | AlexandrB wrote: | Yup, this looks a lot like Tcl! But Tcl lets you compose code | at runtime using its string lists. I doubt Python will. So why | introduce another redundant syntax? | enitihas wrote: | This sounds like a bad idea. It creates more ambiguities in the | language, and will require people to remember a lot more. It | works in ruby because in ruby you can't assign a function to a | variable like | | A = len | | But you can in python. | | It seems python is adding more and more implicit stuff in every | new release. | | I think the day we can import braces from __future__ might not be | far away. | tandav wrote: | I would more like to support some kind of pipes, eg.: | | 123 | add10 | str | print | | UPD: Some of my workarounds (dont try this at home lol): [twitter | thread] https://twitter.com/tandavaya/status/1155925017848242176 | drivers99 wrote: | Looks like forth (uses stack instead of pipes though). The | first line will define add10 (which is assumed to exist in your | example already, but I wanted to show how easy it was to | create). 123 puts 123 on the stack. add10 adds ten to the | number on the stack. "." prints (and removes) the top of the | stack. Don't have to convert it to a string in this case. | : add10 10 + 123 add10 . | geophile wrote: | Take a look at marcel: https://github.com/geophile/marcel. It | is a pipe-objects-instead-of-strings shell, implemented in | Python. But it is also an API allowing scripting from inside | Python, e.g. for file, size in | ls('/home/jao') | map(lambda f: (f, f.size)): | print(f'{file.name}: {size}') | bjourne wrote: | +1! I don't like your suggested syntax, but definitely, | something like that would be a great addition to Python. | Especially if it could be made to work with lists. Rough idea: | range(10) | @ + 2 | @ % 2 == 0 | print(@) | dasb wrote: | So, is this just a syntax change or is this adding a new | statement? | | If it's the latter, does that mean that the execution environment | is part of the language itself, instead of, for example, C where | environmental stuff is only accesible through the standard | library and the language per se is little more than a context- | free grammar? | coldtea wrote: | > _does that mean that the execution environment is part of the | language itself_ | | Yes, that has always be the case with Python in my | understanding - there are lots of built-ins... | pdonis wrote: | _> is this just a syntax change or is this adding a new | statement?_ | | It's just a syntax change; "print 1 2 3" is still an expression | just like "print(1, 2, 3)". | dmitriid wrote: | Elixir has this. And now the linter puts parentheses back IIRC | because of syntax ambiguity _to the human_. ___________________________________________________________________ (page generated 2020-07-14 23:01 UTC)