On Tue, 19 Sep 2017 18:43:43 -0700, Rick Johnson wrote: > On Tuesday, September 19, 2017 at 12:55:14 PM UTC-5, Chris Angelico > wrote: >> On Wed, Sep 20, 2017 at 3:44 AM, Stefan Ram <r...@zedat.fu-berlin.de> >> wrote: >> > Steve D'Aprano <steve+pyt...@pearwood.info> did *not* write [it was >> > edited/abbreviated by me - S. R.]: >> > |disadvantages: >> > |0 - it makes print a special thing > > No more "special" than any other reserved word in Python.
The other reserved words are either: - values, like None, which can be included in expressions; - operators, like `is`, `or`, and `not`; - block statements, like `for x in seq` or `while flag` which require a block; - statements, like `import` and `del`, which operate on names rather than values. (Did I miss any?) print is the only one which could be a function, and looks like a function (apart from the lack of parens). Hence people keep trying to do things like use it in lambdas: https://www.quora.com/Why-does-putting-print-inside-a-Python-lambda- function-raise-a-syntax-error Since it *could* be a function, but isn't, that makes it special in a special way. >> > |1 - beginners have to unlearn > > Only if they decide to move to Python3 *AND* only if they decide to use > the print function at _all_. Even if you don't use print, you will still have to read other people's code that uses it. And its not just a Python 3 issue. Long before there was a Python 3, people would over-generalise from function calls and add extraneous brackets around print's argument. It wouldn't matter if you were printing a single value, but if you printed two arguments, you would actually print a tuple instead. Here are some more recent examples: https://stackoverflow.com/questions/38254008/ https://stackoverflow.com/questions/36345800/ but if you have plenty of time on your hands to search the archives of this mailing list (newsgroup) you'll find people occasionally writing "print(...)" all the way back to Python 2.0 or 1.5. Very possibly including me. >> > |2 - `print(x, y)` is *not* the same as `print x, y`; > > Well, duh! Duh to *you and me*, perhaps, but not so obvious to everyone. See links above. And especially not obvious to beginners, who have to learn that print is magically and unlike all other functions, doesn't require parentheses. [...] > I'll leave the remaining feature implementations as an exercise for the > reader... I already said that you can work around the crippling limitations of print by avoiding it. So why have a standard print (pseudo-)function if it is so crippled and limited that it has to be worked around to be useful for anything more complicated than "Hello World"? For the microscopic cost of requiring parens when calling the print function, you gain all the features of a function. That's a great tradeoff. Beginners have to learn to use parens for every other function they use. Having one more is an insignificant cost. And for advanced programmers, now you have a print function that is actually useful. >> > |5 - it can't be mocked, shadowed, monkey-patched or replaced for >> > testing; > > So wrap sys.stdout.write with your own function and then mock it until > it crys and runs home to mommy; shadow it until it reports you as a > stalker; and monkey patch it until your sewing hand becomes racked with > arthritic pain! You aren't thinking it through far enough. If it's *my* code, I can just use my editor to search for "print foo" and replace it with "awesome_print(foo)" and I'm done. But if I'm using a library or some other piece of code that uses print, and I can't edit the source code (maybe I don't even have the source code), I need to mock it (etc). Now I'm completely out of luck, because you can't shadow or replace the print statement. I *might* be able to hack up some sort of magic replacement for stdout, but that's easier said than done, and if the library is printing to other files I'm screwed. What am I going to do, chase down every single call to print? How? By scanning the .pyc files and disassembling the byte-code? Sure, if you are willing to invest sufficiently large time, money and effort, there's a solution. But something which should take literally five seconds: import nasty_library_that_uses_print as nasty nasty.print = lambda *args: logger(*args) # or similar could take weeks of development effort to get right. >> > |6 - and you can't even write help(print) in the interactive >> > interpreter > > Hmm, neither can you get help for these: > > # PYTHON 2.x > >>> help(del) > SyntaxError: invalid syntax Indeed you can't. But there is a very good reason why del, if, else etc are statements. They *have to be*. For example, you can't write del as a function, because if you do, it won't receive the names of the variables, only their values. It's a trade-off. With del, if, else etc, the value of them being statements far outweighs the disadvantages. But for print, its the other way around. As I've said, apart from saving *one* character (okay, if it makes Rick feel better, two keystrokes on a QWERTY keyboard), what actual concrete, positive benefit is there in making print a statement? If print had always been a function, what arguments are there for making it a statement? -- Steven D'Aprano “You are deluded if you think software engineers who can't write operating systems or applications without security holes, can write virtualization layers without security holes.” —Theo de Raadt -- https://mail.python.org/mailman/listinfo/python-list