3 ms·
The print function was one of the worst offenders. It is a pointless vanity feature (Guido prefers the new syntax), hardly worth the economic cost of upgrading
by alextgordon 11y ago
The print function was one of the worst offenders. It is a pointless vanity feature (Guido prefers the new syntax), hardly worth the economic cost of upgrading all Python code in existence to adopt it.
- marvy 11y agoActually, he prefers the old syntax. The new syntax is there because he got swayed by practical considerations. For instance, back in July 2000, there was this: https://www.python.org/dev/peps/pep-0214/ https://www.python.org/dev/peps/pep-0214/ Where he basically said "Maybe print should be a function, but... nah". Two years later, he says he regrets it: http://legacy.python.org/doc/essays/ppt/regrets/PythonRegrets.pdf http://legacy.python.org/doc/essays/ppt/regrets/PythonRegret... And the benefits are explained here: https://www.python.org/dev/peps/pep-3105/ https://www.python.org/dev/peps/pep-3105/
- lisper 11y agoCould have had the best of both worlds by giving the print function a different name from the print statement (e.g. printf for the function). Then the print statement could have been deprecated gracefully. (And then the print function could have been renamed print if anyone really cared at that point.)
- eru 11y agoOr alternatively they could have remove the mandatory parentheses around function calls, and kept the old syntax and made print a function. (Sorry, trolling. ML-style function call syntax would clash a lot with other parts of Python.)
- marvy 11y agoI don't know ML, but I really do wish Python had this feature. The only problem I see is that this makes it hard to refer to a function without calling it (see below). How does ML solve this? def g(): return 5 assert g() == 5 assert g != 5 Without parenthesis, how can the language distinguish the last two lines? How does ML do it? Would the same trick work in Python? I know Ruby has optional parenthesis, but functions aren't quite as first class there as they are in Python, which is why the have Proc and whatnot.
- cheepin 11y agoYour example, g actually takes the unit tuple, and returns 5. In ML, in general, you have to disambiguate with parentheses sometimes, but the compiler is very strict about types, so it's usually pretty easy to tell where they need to be. Look here: http://try.ocamlpro.com/ http://try.ocamlpro.com/ Try this code: let g() = 5 g() == 5 g != 5 First line defines the function. Second line should evaluate to true. Third line doesn't type check because a function is not the same type as a literal.
- eru 11y agoExactly. My favourite ML-style language is Haskell, and there we almost never want to call a function with the unit-tuple as an argument. Haskell does differentiate between IO-actions and functions. Here is an example: main = do let printFive = print 5 print 1 printFive print 6 printFive Will print 1 5 6 5 The type systems helps enormously keeping things straight here, but the basic concept would work in a non-statically typed language, too.
- marvy 11y ago> the basic concept would work in a non-statically typed language, too How? How do I compare. say, two functions for equality, without comparing the return value instead?
- eru 11y agoOh, I should have been more explicit: The decoupling of function calling and IO actions can work in non-statically typed languages, too. Your question concerns a different topic. To give something like an answer: that problem can only occur with `functions' of zero arguments. Haskell sidesteps the issue by requiring all functions to have exactly one argument.
- marvy 11y agoOkay, that's cheating. Or rather, that's fine for them, but is no help in porting this idea to Python, which definitely has functions of zero arguments, and they aren't even that rare. (Although comparing functions for equality is rare, but it should at least be possible.)
- makecheck 11y agoIt is one of the easiest changes to adopt though. I added a "from __future__ import print_function" to 2.x code and was able to switch file-by-file without a problem. As a function, occasionally it is more verbose but it is also a lot more flexible (they can add anything they want as new keyword arguments) and it's compatible with any other feature of the language that would use a function.
- Too 11y agoThe print must have been the easiest function of them all to convert automatically with 2to3 since in py2 it's a language keyword, it's not possible to assign it to a variable, you can't construct it with strings to __dict__ lookups or any other types of dynamic programming hacks. If people can't even convert print then the migration is quite a lost case. Second of all it's such a silly syntactic difference that if people are honestly bothered enough by it to stay on python 2 i just lost all hope for that community. Besides, the reason for changing it was not vanity with syntax, it was to move it from a language keyword into a standard function so it could be used in all the ways described above, marvys links describe this better.
- alextgordon 11y agoAfter you run 2to3, you still have to go through the changes and manually audit them for correctness. Since pretty much everything has at least one print statement, its removal ensured that everything had to be converted. If Guido&co had tried to maintain backwards compatibility, they could have more easily made the important semantic changes (like unicode strings). Users would have been enthusiastic to upgrade, instead of angry that their time and money was being wasted on irrelevant syntax details.
- Too 11y agoIf everything has at least one print statement you are doing it wrong. Functions in modules should return data, it is then the task of the view to present this data, which could be as simple as printing it or could involve rendering it to html, pdf, a gui, sending an email or whatever. People know that global variables are a bad thing but fail to realize that print "foo" is essentially equivalent to global_variable_output_buffer+="foo". It simply shouldn't be scattered around everywhere. This is not just academic nonsense, I was once given the task to parallelize the code in a large python code base, and to send the output in an email instead of printing to console. It would have been an easy job but a lot of the code was using print just the way you describe it causing intermingled output in the console when run in parallel.