Old Man Yells At Cloud
Steve D'Aprano
steve+python at pearwood.info
Wed Sep 20 09:59:42 EDT 2017
On Wed, 20 Sep 2017 02:55 pm, Pavol Lisy wrote:
> On 9/19/17, Steve D'Aprano <steve+python at pearwood.info> wrote:
>
> [...]
>
>> The point is, we all make the occasional silly error. Doesn't mean we should
>> cripple our functions and fill the language with special cases like the
>> print
>> statement to avoid such rare errors. If print had always been a function,
>> and
>> someone suggested making it a statement, who would be willing to accept all
>> those disadvantages for the sake of saving one character?
>
> I am not going to support print as a statement in this discussion!
>
> But what you are describing is some kind of alternative history which
> did not happen.
Right. The philosophical term is "counterfactual", the more common term
is "hypothetical situation".
https://en.wikipedia.org/wiki/Counterfactual_conditional
It is sometimes called the historical subjunctive, after the subjunctive
grammatical tense:
https://www.goodreads.com/quotes/606824-it-s-subjunctive-history-you-know-the-subjunctive-the-mood-used
See also:
https://en.wikipedia.org/wiki/Subjunctive_possibility
> Question was not about crippling function to statement. (Which function?)
>
> What I mean is that if we like to convince people that it was good
> decision then we need to use proper arguments.
The hypothetical question is a good argument. We want Python to be the language
it could possible be. Which would give us a better language?
1. Start with print statement, and change to print function. (This is what
really happened.)
2. Start with a print function, and change to a print statement. (This is a
hypothetical situation.)
I think that number 1 is *much better* than two.
Now consider that we already live in world number 1. print is now a function. To
anyone who argues that print was better as a statement, would you like to live
in world 2? Its not too late. We could say that the change in 1 was a terrible
mistake, and revert it, and then number 2 will be the actual world.
To make that come true, all you need do is make a strong enough argument for why
the print statement is *so much better* than the function that it is worth the
disruption of changing the language again.
But I'd be satisfied with any reason at all with the statement was better, apart
from:
(a) "you save one character (two keystrokes)"; and
(b) "that's what I was used to".
> For example some others which seems like not so proper to me:
>
> 1. "learn-unlearn" argument could be viewed differently from opposite
> camp (they need to unlearn statement)
Beginners and novices don't have to unlearn the print statement, because they
haven't learned it yet.
A beginner to Python hasn't learned anything yet. They start to learn the
language, and discover that `len` needs parentheses. `int` needs parens. `str`
needs parens. `math.sqrt` needs parens. `chr` needs parens. `open` needs
parens. `str.find` needs parens. Dozens upon dozens, hundreds, even thousands
of functions and methods all need parens.
Except for `print`, which looks like a function but isn't.
So for `print`, they need to unlearn the rule "always use parentheses when
calling a function" and replace it with "except for print", or "but print is
not a function, so the rule doesn't apply". Either way, print is an exception
that has to be unlearned from the general rule.
I agree, once you have learned that print is special, then moving to Python 3
means you have to unlearn that print is special. Its not special any more in
Python 3.
> 2. "print foo" save more than one character ("print foo ," more than
> two characters)
Count the characters more closely:
print foo # nine characters, including the space
print(foo) # ten characters, including the parentheses
The difference between ten and nine is one, as I said.
Suppressing the newline at the end is a little shorter:
print foo, # ten characters
print(foo, end='') # eighteen characters
but the loss of brevity is more than made up for by the gain in self-documenting
code.
Changing the separator between items is a big win for the print function:
print ', '.join(str(obj) for obj in (foo, bar, baz)) # 52 chars
# and builds up a potentially large string ahead of time
print(foo, bar, baz, sep=', ') # 30 chars
# and DOESN'T build up a large string ahead of time
# and is self-explanatory
> 3. "for sake of saving one character"? Could we really simplify
> motivation of opposite side to just this? (what about breaking old
> code?)
I don't know what the motivation of the "print should be a statement!" side is,
because they never say why it was better. (If they have said, I have never seen
it.) All they do is say "it was a terrible mistake to change, print was better
as a statement".
I *completely agree* that there was some pain in breaking backwards
compatibility. That's why Guido waited so many years before fixing his mistake
in making print a statement.
"print is a statement" was in Guido's list of regrets all the way back in 2002:
http://legacy.python.org/doc/essays/ppt/regrets/PythonRegrets.pdf
and it wasn't fixed until Python 3. He explains some of his reasons why here:
https://mail.python.org/pipermail/python-dev/2005-September/056154.html
Guido is not the only one who found that print was too limiting and best
avoided:
https://mail.python.org/pipermail/python-dev/2005-September/056164.html
I admit I haven't read ALL the posts discussing the question of print:
https://mail.python.org/pipermail/python-dev/2005-September/thread.html
but I'm still looking for a good argument beyond "don't want to type parens"
and "we've always done it that way" for keeping print a statement. The closest
I came to was Fredrik Lundh's post:
https://mail.python.org/pipermail/python-dev/2005-September/056247.html
The only problem with his arguments for keeping print a statement is that they
apply equally to print as a function!
Fredrik: A reserved word makes it easy to grep for.
You can grep for "print(" just as easily as "print".
Fredrik: It does the right thing under the hood: converts things to their
string representation, calls write repeatedly instead of allocating
a buffer large enough to hold all components, doesn't print un-
necessary trailing spaces, etc.
So does the print function.
Fredrik: Using a statement syntax makes it possible to use a readable
syntax for redirection (and other possible extensions); it's obvious
that this isn't printing to stdout:
print >>file, bacon(ham), spam, "=", eggs(number=count)
I suppose that Unix system admins might be used to > used for file re-direction,
but that's one of the most hated features of print statement, and its hardly
something that is easy to guess for people who haven't learned it.
print(args, file=sys.stderr) is surely more self-explanatory than
print >>sys.stderr, args
even if it takes a couple of extra characters.
Fredrik: It can print to anything that implements a "write" method.
And so can the print function.
So out for Fredrik's four arguments in favour of print statement, one is a
matter of opinion (he likes >>file, most people hate it) and the other three
hold equally for print as a function.
> BTW if python would only bring "from __cleverness__ import
> print_function" how many people would accept your reasons and use it?
Many people use "from __future__ import print_function".
Are you aware that Python 3 exists? print is already a function, and Python 2.7
supports it as a future import.
> And how many would rewrite old code?
*shrug*
Some people will upgrade old code to new versions of Python. Some people won't.
It depends on the program, whether it is worth upgrading or not.
But what I want to see are reasons why print as a statement was better. Not
just "that's what I'm used to".
--
Steve
“Cheer up,” they said, “things could be worse.” So I cheered up, and sure
enough, things got worse.
More information about the Python-list
mailing list