Are the critiques in "All the things I hate about Python" valid?
Steven D'Aprano
steve+comp.lang.python at pearwood.info
Sat Feb 17 13:05:27 EST 2018
On Sat, 17 Feb 2018 15:25:15 +1100, Chris Angelico wrote:
> 1) Type safety.
>
> This is often touted as a necessity for industrial-grade software. It
> isn't. There are many things that a type system, no matter how
> sophisticated, cannot catch;
The usual response to that is to make ever-finer-grained types, until the
type-system can prove the code is correct.
integers
positive integers
positive integers greater than 10
positive integers greater than 10 but less than 15003
positive odd integers greater than 10 but less than 15003
positive odd integers greater than 10 but less than 15003 divisible by 17
Of course, this has a few minor (ha!) difficulties... starting with the
hardest problem in computer science, naming things.
Even if you can come up with unique, concise names for these types that
won't overwhelm the reader, it isn't clear that the type system will
always be capable of representing such fine distinctions. How would you
specify two string types, one for personal names and one for family
names, so that the compiler can detect any attempt to assign a family
name to a personal name, or vise versa?
And of course, there are certain errors which *even in principle* cannot
be detected at compile-time:
- bad user input;
- memory exhaustion;
- out of disk space;
- I/O errors when reading or writing data;
- network failures;
- logic errors (your code does what told it to do perfectly,
it's just not what you wanted...)
etc.
> for some reason, though, we don't hear
> people saying "C is useless for industrial-grade software because it
> doesn't have function contracts".
You obviously don't speak to Eiffel programmers then :-)
> Anyway, if you want some system of type checking, you can use static
> analysis (eg tools like MyPy) to go over your code the same way a
> compiler might.
Indeed. Despite our criticisms of the *attitude* that static typing is a
panacea, it must be recognised that it is useful, and the bigger the
project, the more useful it is. And some type checkers are *very*
impressive. Google for "compiler found my infinite loop" for a classic
example of a compiler detecting at compile-time than a while loop would
never terminate.
(The language was ML, not C. The C type system isn't that good. In fact,
ironically proponents of languages in the ML family consider C and its
family to be weakly-typed.)
I can understand people saying that for sufficiently large projects, they
consider it indispensable to have the assistance of a type checker. That
in and of itself is no worse than saying that, as a writer, I find a
spell checker to be indispensable.
> "The first glaring issue is that I have no guarantee that is_valid()
> returns a bool type." -- huh? It's being used in a boolean context, and
> it has a name that starts "is_". How much guarantee are you looking for?
> *ANY* object can be used in an 'if', so it doesn't even matter. This is
> a stupidly contrived criticism.
I don't think so -- I think a lot of people really have difficulty coming
to terms with Python's duck-typing of bools. They just don't like, or
possibly even grok, the idea of truthy and falsey values, and want the
comfort of knowing that the value "really is" a True or False.
We can come up with some contrived justifications for this... what if
is_valid() contains a bug:
def is_valid(arg):
if some condition:
return arg # oops I meant True
return False
then static analysis would detect this. With truthiness, you can't tell:
what if *nearly* all the input args just happen to be truthy? Then the
code will nearly always work, and the errors will be perplexing.
But I consider that a fairly contrived scenario, and one with at least
two alternate solutions: code review, and unit tests.
But still, I do see the point that a static analyser could have picked up
that error even if you didn't have code review, even if the person
writing the unit tests never imagined this failure mode.
[...]
> Totally not true. The GIL does not stop other threads from running.
> Also, Python has existed for multiple CPU systems pretty much since its
> inception, I believe. (Summoning the D'Aprano for history lesson?)
If you're talking about common desktop computers, I think you're
forgetting how recent multicore machines actually are. I'm having
difficulty finding when multicore machines first hit the market, but it
seems to have been well into the 21st century -- perhaps as late as 2006
with the AMD Athelon 64 X2:
https://www.computerhope.com/history/processor.htm
The first public release of Python was 1991, so I'm not sure what sort of
support it had for multiple CPUs or multiple cores. Perhaps none.
By the way, multiple CPU machines are different from CPUs with multiple
cores:
http://smallbusiness.chron.com/multiple-cpu-vs-multicore-33195.html
One of the more interesting (although perhaps not cost-effective) uses
for multiple CPUs is a machine with two distinct hardware architectures,
running two distinct OSes, well before the days of virtualisation
technology. Back in the 1980s (1989, perhaps?) TI and Apple developed a
NuBus card containing a TI Lisp Machine CPU. For a mere $10,000 or so
($20K in today's money) you could simultaneously run a Lisp Machine in
your Macintosh II.
http://lemonodor.com/archives/2002/10/ti_microexplore.html
Certainly though there have been versions of Python without a GIL for a
long time:
Jython started as JPython, in 1997; IronPython was started around 2003 or
so, and reached the 1.0 milestone in 2006.
Fun fact: (then) Microsoft engineer Jim Hugunin created both JPython and
IronPython!
--
Steve
More information about the Python-list
mailing list