
Why `print` became a function in Python 3 - joeyespo
http://www.snarky.ca/why-print-became-a-function-in-python-3
======
mathgenius
I was at europython 2006 when Guido announced that the print statement was
getting axed. It was a bit of a shock to me. I think everyone in the audience
was altogether not quite sure where/why python 3000 was coming and so willing
to patiently listen to what the master had to say about all of it.

Guido's reasoning seemed to be that since a bunch of junior devs at google
couldn't refactor their print statements into logging statements the print
statement had to go.

I don't seem to have this issue: for me the print statement is 99% used as a
debugging tool. When I'm debugging I pepper my code with print statements
until it tells me what is going wrong. So two extra parens every time i do
this just seems unreasonable to me. Excuse my whining, but there it is.

I was also at europython in 2007 when Guido once again went over the changes
being wrought by python 3. This time when he got to the print statement I let
out a loud "BOO!" Guido was somewhat surprised and remarked: "well no-one said
anything about this when I announced it at last year's europython!"

Doh.

------
t0mk
I miss print as a statement. Especially when I try to debug fast in dummy
scripts, and when debugging in REPL (bpython, ipython). I always forget it's a
function, and then I have to move the cursor before the printed symbol, type
the left parenthesis, move after the symbol, then the right one. It's kind of
annoying.

~~~
masklinn
> I miss print as a statement.

I don't. It's a habit change so sure once in a while I still forget the
parens, but the function form is way more readable when doing anything beyond
a bare print[0] — not to mention it can plain do more useful stuff — and I can
now put a print function in a lambda instead of needing bullshit like

    
    
        sys.stdout.write(' '.join(map(str, [a, bunch, of, vars])))
    

[0] no magical easy to miss terminal comma or sigil soup for non-stdout
printing, clear and readable keyword parameters instead

~~~
t0mk
You mention print in lambda, and it's also in the article. I don't think
that's good enough reason for killing the usability of print statement in
repl.

I'd consider it quite a weird piece of code if I'd see print in lambda, or
passed to something from functools. If "sys.stdout.write" would be there
instead of the "print", I'd see it equally weird. Both is (probably
unnecessary) giving away the simplicity of Python.

I debug in REPL quite a lot and I don't do functional magic with print at all
(at the moment). That's dragging me away from Python 3. Other people might
have it different.

~~~
ubertaco
>I don't think that's good enough reason for killing the usability of print
statement in repl.

I really don't think the difference between

    
    
        print(some_var)
    

and

    
    
        print some_var
    

constitutes "killing usability".

> I'd consider it quite a weird piece of code if I'd see print in lambda

Granted, I don't do much Python these days (I have become enamored with more
strongly-typed langs lately), but my impression is that lambdas are uncommon
in python, instead preferring relatively-inexpensive toplevel function defs
instead.

> I debug in REPL quite a lot and I don't do functional magic with print at
> all (at the moment)

Consider a case where I'm debugging why my function foo(x) is failing for at
least one of [42, 333, -57, 0, None, 33], but I don't know which one. It's not
unheard of to do some step-by-step binary-search stuff like this:

    
    
        >> [print(foo(x)) for x in test_cases[0:3]]
        # repl doesn't blow up
        >> [print(foo(x)) for x in test_cases[3:]]
        # repl blows up as expected
        >> [print(foo(x)) for x in test_cases[4:]]
        # repl doesn't blow up, so now I know that foo(0) has a bug
    

Now, you might look at this and point out that I don't actually need to
print(foo(x)) at all, that the REPL will display the resulting arrays anyways.
And you're right! So even here, the difference between "print(x)" and "print
x" doesn't "kill usability", since it's a moot point either way.

I think in day-to-day use, even at a REPL, it's a "six of one, half-dozen of
another" scenario with no major wins either way. In teaching Python, it's a
win because it's more consistent -- you don't have to teach people "this is
how it looks to call a function -- except print, it's not really a real
function, it's special, so make sure you remember this one exception." And in
building Python, it means one fewer special case to maintain for the
interpreter and language.

------
xamuel
"Oh no!! We have to write one extra character to print something!" It's almost
as bad as if someone forced you to put an unnecessary colon at the end of
every single scope-starting line...

------
Dylan16807
I appreciate making the grammar simpler. But, uh, these examples are terrible.
It takes longer to type ellipsis_ than it does to type ,'...'

------
guest1539
It became a function because it always should have been one. However, since it
wasn't always a function, they didn't have the common sense to pick a NEW
function name (puts, println, write, writeln, echo, say, show, ...) and
politely deprecate the old print syntax. Shortsighted and pointless.

~~~
Ao7bei3s
It's neither shortsighted nor pointless.

This way people will actually switch. Programmers won't change without being
forced.

Also, Python 3 was their one chance to break backwards compatibility. And
there are so many breaking changes in there that people will have to change
their codebase to work with Py3k anyway. Your suggestion just delays breaking
compatibility (or actually, causes a later release to break backwards
compatibility when it wouldn't have been necessary otherwise) ...unless you're
arguing for keeping the old print in indefinitely. Why deprecate it then? And
old cruft with "oh, we have that but don't use it" labels attached is
definitely confusing. And the label would be ignored by too many "that's-the-
way-I've-learned-it-and-it-still-works-so-whats-the-problem" programmers.

This is one of the most trivial changes 2to3 makes; it can be done 100%
reliably statically, it's very local and very mechanical, and if you don't get
it right you get a syntax error on startup (instead of exceptions at runtime
(e.g. unicode strings) or even different behavior (e.g. integer division)).
The print statement->function change is just not that big of a problem when
updating codebases to py3k. It's very visible (because everyone knows print),
but the other changes will take much more work and be much harder to debug, so
why get hung up over it?

~~~
criddell
> This way people will actually switch.

Is that important?

~~~
has2k1
_print_ as a statement requires a special syntax rule. When people switch that
special case goes away. Maybe that does not account for much on the whole, but
language designers tend to be irked by such things.

~~~
GFK_of_xmaspast
As a user, I don't care how irksome the language designer finds these things.

~~~
Dylan16807
It makes the language tricker to learn.

~~~
emidln
Err, what? Maybe you mean that an arbitrary distinction between statements and
expressions makes the language trickier to learn than it otherwise might be.
But once you have that distinction, print being a function vs a statement
isn't trickier one way or the other.

~~~
Dylan16807
Print fits much better with python's functions than its statements. I think it
is notably tricker if the most common piece of code you pass arguments to has
no parentheses, but everything else does.

