[Python-ideas] Python Reviewed
Simon Lovell
simon58500 at bigpond.com
Mon Jan 9 06:25:45 EST 2017
Python Reviewed
Having used a lot of languages a little bit and not finding satisfactory
answers to these in some cases often asked questions, I thought I'd join
this group to make a post on the virtues and otherwise of python.
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
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". Well, no. if/while/for blocks are already explicit. Adding
the colon makes it doubly explicit and therefore redundant. There is no
reason I can see why this colon can't be made optional except for
possibly PEP20.13 "There should be one-- and preferably only one
--obvious way to do it". I don't agree that point is sufficient to
require colons.
No end required for if/while/for blocks. This is particularly a
problem when placing code into text without fixed width fonts. It also
is a potential problem with tab expansion tricking the programmer. This
could be done similarly to requiring declarations in Fortran, which if
"implicit none" was added to the top of the program, declarations are
required. So add a "Block Close Mandatory" (or similar) keyword to
enforce this. In practice there is usually a blank line placed at the
end of blocks to try to signal this to someone reading the code. Makes
the code less readable and I would refer to PEP20.7 "Readability counts"
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
I note that many solutions have been proposed to this. In C, it
is the ability to write "while(line=fgets(f))" instead of
"while((line=fgets(f))!=NULL)" which causes the confusion. No solutions
have been accepted to the current method which is tacky:
f=open(file)
endwhile=""
endif=""
while True:
line=f.readline
if line = None:
break
endif
process(line)
endwhile
Inadequacy of PEP249 - Python Database Specification. This only
supports dynamic SQL but SQL and particularly select statements should
be easier to work with in the normal cases where you don't need such
statements. e.g:
endselect=""
idList = select from identities where surname = 'JONES':
idVar = id
forenameVar = forename
surnameVar = surname
dobVar = dob
endselect
endfor=""
for id in idList:
print id.forenameVar, id.dobVar
endfor
as opposed to what is presently required in the select case
which is:
curs = connection.cursor()
curs.execute("select id, forename, surname, dob from
identities where surname = 'JONES'")
idList=curs.fetchall()
endfor=""
for id in idList:
print id[1], id[3]
endfor
I think the improvement in readibility for the first option
should be plain to all even in the extremely simple case I've shown.
This is the sort of thing which should be possible in any
language which works with a database but somehow the IT industry has
lost it in the 1990s/2000s. Similarly an upgraded syntax for the
insert/values statement which the SQL standard has mis-specified to make
the value being inserted too far away from the column name. Should be
more like:
endinsert=""
Insert into identities:
id = 1
forename = 'John'
surname = 'Smith'
dob = '01-Jan-1970'
endinsert
One of the major problems with the status quo is the lack of
named result columns. The other is that the programmer is required to
convert the where clause into a string. The functionality of dynamic
where/from clauses can still be provided without needing to rely on
numbered result columns like so:
endselect=""
idList = select from identities where :where_clause:
id = id
forename = forename
surname = surname
dob = dob
endselect
Ideally, the bit after the equals sign would support all
syntaxes allowed by the host database server which probably means it
needs to be free text passed to the server. Where a string variable
should be passed, the :variable syntax could be supported but this is
not often required
Variables never set to anything do not error until they are used,
at least in implementations of Python 2 I have tried. e.g.
UnlikelyCondition = False
endif=""
if UnlikelyCondition:
print x
endif
The above code runs fine until UnlikelyCondition is set to True
No do-while construct
else keyword at the end of while loops is not obvious to those not
familiar with it. Something more like whenFalse would be clearer
Changing print from a statement to a function in Python 3 adds no
positive value that I can see
Upper delimiters being exclusive while lower delimiters are
inclusive. 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.
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
Inability to make simple chained assignments e.g. "a = b = 0"
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.
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.
More information about the Python-ideas
mailing list