PyWart: The problem with "print"

Chris Angelico rosuav at gmail.com
Tue Jun 4 03:30:25 EDT 2013


On Tue, Jun 4, 2013 at 11:37 AM, Rick Johnson
<rantingrickjohnson at gmail.com> wrote:
> The print function is the very definition of a "syntactic sugar".
>
> For example:
>     print("some sting")
>
> is much more readable than:
>
>     sys.stdout.write("some string"+"\n")
> ...
> Again, the removal of a print function (or print statement)
> will not prevent users from calling the write method on
> sys.stdout or sys.stderr (or ANY "stream object" for that matter!)

And you could abolish ALL of the builtins by requiring that you import
ctypes and implement them all yourself. That is not the point of the
term. If print() is mere syntactic sugar, then everything is syntactic
sugar for Brainf* code.

The point of syntactic sugar is that there is a trivially-equivalent
underlying interpretation. For instance, in C, array subscripting is
trivially equivalent to addition and dereferencing:

a[i]   <->   *(a+i)

This is syntactic sugar. The Python print() function does much more
than write(), so it is NOT syntactic sugar.

> Many times you'll get a result (or an input) that you expect
> to be a Boolean, but instead is a string. A good example of
> poor coding is "dialog box return values". Take your
> standard yes/no/cancel dialog, i would expect it to return
> True|False|None respectively, HOWEVER, some *idiot* decided
> to return the strings 'yes'|'no'|'cancel'.

Why True|False|None? Why should they represent Yes|No|Cancel?
Especially, *why None*? What has None to do with Cancel?

> However, with Python's implicit conversion to Boolean, the
> same conditional will ALWAYS be True: because any string
> that is not the null string is True (as far as Python is
> concerned). This is an example of Python devs breaking TWO
> Zens at once:
>
>  "explicit is better than implicit"
>  "errors should NEVER pass silently"

Right, because it's Python's fault that you can't use implicit boolean
conversion to sanely test for something that has three possible
outcomes. I think there's something in the nature of a boolean test
that makes this awkward, but I can't quite see it... hmm, some kind of
integer issue, I think...

> Obviously you don't appreciate the value of "explicit enough".
>
>   if VALUE:
>
> is not explicit enough, however
>
>   if bool(VALUE)
>
> or at least:
>
>   if VALUE == True
>
> is "explicit enough".

Why? The 'if' implies a boolean context. In C, it's common to compare
integers for nonzeroness with a bare if; it's also common, though far
from universal, to compare strings for nullness - effectively
equivalent to "is not None". You don't need to be any more explicit
than that.

Granted, the definitions of truthiness differ from language to
language. In C, a NULL pointer is false and any actual pointer is
true, so an empty string is true (to the extent that C even has the
concept of strings, but leave that aside). In Pike, any array is true,
but the absence of an array can be indicated with (effectively) a
null, whereas Python deems that an empty list is false. Still, most
languages do have some system of coercion-to-boolean. (Notable
exception: REXX. An IF statement will accept *only* the two permitted
boolean values, anything else is an error.)

> However, if i choose to be explicit and use:
>
>   "if len(VALUE) > 0:
>
> then the code will fail when it should: at the comparison
> line.  Because any object that does not provide a __len__
> method would cause Python to raise NameError.

I thought you were dead against wasting CPU cycles! Your code here has
to calculate the actual length of the object, then compare it with
zero; the simple boolean check merely has to announce the presence or
absence of content. This is a HUGE difference in performance, and you
should totally optimize this down for the sake of that. Don't bother
measuring it, this will make more difference to your code than
replacing bubble sort with bogosort!

ChrisA



More information about the Python-list mailing list