[Python-ideas] Python Reviewed

Steven D'Aprano steve at pearwood.info
Mon Jan 9 14:40:34 EST 2017


On Mon, Jan 09, 2017 at 07:25:45PM +0800, Simon Lovell wrote:

> The Good:
>     Syntactically significant new lines
>     Syntactically significant indenting
>     Different types of array like structures for different situations
>     Mostly simple and clear structures
>     Avoiding implicit structures like C++ references which add only 
> negative value
>     Avoiding overly complicated chaining expressions like 
> "while(*d++=*s++);"
>     Single syntax for block statements (well, sort of. I'm ignoring 
> lines like "if a=b: c=d")
>     Lack of a with statement which only obscures the code

Python has a `with` statement.

As a newcomer to this community, and apparently the language as well, do 
you understand how obnoxious and arrogant it comes across for you to 
declare what is and isn't "good" and "bad" about the language, 
particularly when you appear to know the language very well?

Most of your comments aren't even a little bit objective, they're 
subjective judgements based on (I expect) what you are used to, and 
nothing more. Matters of taste, at best, and yet you're stating them as 
objective fact. So if you feel that my response is a tad blunt or even 
brusque, perhaps you can understand why.



> The Bad:
>     Colons at the end of if/while/for blocks. Most of the arguments in 
> favour of this decision boil down to PEP 20.2 "Explicit is better than 
> implicit".

This is the first time I've heard this ridiculous explanation for the 
use of colons! Where did you get it from? It sounds like the sort of 
nonsense that gets highly voted on StackOverflow.

The reason for colons is a FAQ:

https://docs.python.org/3/faq/design.html#why-are-colons-required-for-the-if-while-def-class-statements



>     No end required for if/while/for blocks. 

Thank you Guido, for avoiding needing all those redundant and 
unnecessary "end" statements that other languages waste my time with.


>     This code block doesn't compile, even given that function "process" 
> takes one string parameter:
>         f=open(file)
>         endwhile=""
>         while (line=f.readline())!=None:
>             process(line)
>         endwhile

Assignment is not and should not be an expression, at very least not 
using the same = (pseudo-)operator which is used as an assignment 
statement. It may be acceptible with some other syntax that cannot be 
easily mistyped when you want == equality, but not = alone.

But what is that obfuscated code meant to do? Operate on the file, 
one line at a time? This is simpler:

with open(file) as f:
    for line in f:
        process(line)

and it has the advantage of also automatically closing the file when the 
`with` block gets exited.



>     Inadequacy of PEP249 - Python Database Specification.
[...]

I cannot comment on this.


>     Variables never set to anything do not error until they are used, 

Fair enough, that is a minor annoyance occasionally.


>     No do-while construct

What do you mean by "do-while" and how do you expect it to differ from 
"while"?



>     else keyword at the end of while loops is not obvious to those not 
> familiar with it. Something more like whenFalse would be clearer

Indeed. 

for...else and while...else are much more accurately described as 
for...then, while...then.

The code in the "else" block is *unconditionally* executed following the 
for... or while... block, which makes the block a "then" rather than 
"else". To avoid that block, you have to jump out of the entire 
compound block, using "break", "return" or "raise".

But we're stuck with the name now.



>     Changing print from a statement to a function in Python 3 adds no 
> positive value that I can see

Consistency: print doesn't need to be a special cased statement. It does 
nothing special that a function can't do. So why make it a statement?

As a function, it can be passed around as a first class value, used as a 
callback, monkey-patched or shadowed or mocked as needed. None of 
these things are possible with a statement.

It can use the same ordinary syntax as other functions, instead of the 
bizarre and ugly special case syntax used as a statement:


    # Python 3
    print(value, end='', file=sys.stderr)

    # Python 2
    print >>sys.stderr, value,  # note the magical trailing comma


If Python was invented today, what arguments could anyone make for 
having print be a statement instead of a function? "It saves typing two 
parentheses." Anything else?



>     Upper delimiters being exclusive while lower delimiters are 
> inclusive.

Dijkstra explained it well:

http://www.cs.utexas.edu/users/EWD/transcriptions/EWD08xx/EWD831.html

Half-open ranges are much superior for avoiding off-by-one errors than 
closed ranges.


> This is very counter intuitive. e.g. range(1,4) returns 
> [1,2,3]. Better to have the default base as one rather than zero IMO. Of 
> course, the programmer should always be able to define the lower bound. 
> This cannot be changed, of course.

It is true that starting counting at zero takes a bit of getting used 
to, and there are times when it is more convenient to start at one. But 
no one solution is ideal all the time, and we have to pick one system or 
the other, or else we end up with an overly complex syntax with marginal 
utility.


>     Lack of a single character in a method to refer to an attribute 
> instead of a local variable, similar to C's "*" for dereferencing a pointer

The lack of single-character syntax for many things helps prevents 
Python code looking like line noise.


>     Inability to make simple chained assignments e.g. "a = b = 0"

Python does support chained assignment.


>     Conditional expression (<true-value> if <condition> else 
> <false-value>) in Python is less intuitive than in C (<condition> ? 
> <true-value> : <false-value>). Ref PEP308. Why BDFL chose the syntax he 
> did is not at all clear.

What is "intuitive" to people who have learned C and C-influenced 
languages is a perplexing, mysterious enigma almost impossible to google 
for or look up in books.

    flag ? 1 : 2

means nothing to people who haven't memorized what it means. But 
Python's ternary syntax is actual grammatically correct English:

    1 if flag else 2

and it puts one of the values first, in the most important part, instead 
of the flag.


> The Ugly:
>     Persisting with the crapulence from C where a non zero integer is 
> true and zero is false - only ever done because C lacked a boolean data 
> type. This is a flagrant violation of PEP 20.2 "Explicit is better than 
> implicit" and should be removed without providing backwards compatibility.

Thanks for your opinion, but I prefer the status quo.

Welcome to the list.



-- 
Steve


More information about the Python-ideas mailing list