[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Old Man Yells At Cloud

On Tue, 19 Sep 2017 05:56 am, Roel Schroeven wrote:

> I do prefer Python 3's print-as-a-function because "special cases aren't
> special enough to break the rules", but I feel there's a case to be made
>   for Python 2's print-as-a-statement because "(although) practicality
> beats purity" sometimes.

Nobody has successfully made the argument that print was *better* as a
statement, or given any convincing reason why print *should* be a statement.

(For example, del needs to be a statement, not a function, because it needs to
operate on *names* not the objects bound to the names.)

All they have managed to successfully argue is that they're used to print
without parens and can't unlearn the habit.

The one advantage of print statement is that you save a single character when
typing it. Be still my beating heart.

Compared to that, the disadvantages:

- it makes print a special thing that can't be treated as a first-class 
  value, it can't be passed to functions or used as a callback or bound
  to a name;

- because it is special, beginners have to unlearn the practice of using
  parens for calling functions, and stop writing print(x);

- it suffers a silent failure if you inadvertently parenthesise multiple
  arguments: `print(x, y)` is *not* the same as `print x, y`;

- it has bizarre syntax that nobody would find normal if it wasn't for
  long-experience; I mean, really, you end the argument list with a 
  comma to suppress printing newlines? who thought that was a good idea?

- it is difficult to control the print statement, since you can't 
  pass keyword arguments; it's one size fits all;

- which is why we ended up with that awful `print >>file, args` hack;

- it can't be mocked, shadowed, monkey-patched or replaced for testing;

- and you can't even write help(print) in the interactive interpreter
  because its a syntax error.

Of course an experienced Python coder can work around all these problems. The
main way to work around them is to *stop using print*.

By not using the print statement, you avoid all those disadvantages, and you end
up with a proper function that has no surprises, no bizarre syntax, doesn't use
a comma as a cryptic signal to suppress printing a newline, and can easily be
extended with keyword args.

(I sometimes monkey-patch the print function with one that takes a "verbosity"
flag that controls whether or not it actually prints.)

Oh, and for the record: sometimes I forget the parens too. And sometimes I
write "def MyClass(ParentClass): ...". Sometimes I forget to add self to
methods. Sometimes I even write dicts like {key, value}, or lists like [a;b;c].

Once I managed to write a whole class with a dozen or two methods writing NONE
instead of None *every single time* it came up. I have no idea what I was
thinking that day.

(So sue me for not using test-driven-development.)

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?

?Cheer up,? they said, ?things could be worse.? So I cheered up, and sure
enough, things got worse.