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

Reply via email to