
A short list of things I don’t like about Python - mace
http://jessenoller.com/2009/05/26/a-short-list-of-things-i-dont-like-about-python/
======
daeken
Agreed on every point, but I have to add a few things.

\- No real metaprogramming is a big problem for me. I want decorators to be
able to manipulate the AST (I'm playing around with a way to do this:
<http://pastie.org/490836> ) at the very least, and preferably real macros
that can add new syntax.

\- Anonymous functions. I want real anonymous functions in Python, not lambda
or anything like it. After a long time of hacking Nemerle code, I go back to
Python and cry when I write lambdas.

\- Tail call recursion. Another functional programming thing that I'd
absolutely love to see, just because it's so incredibly useful.

Sadly, I know none of these will likely be implemented, as they're just not
the Python way, but it doesn't change the fact that I love Python and would
love to see these changes.

~~~
ubernostrum
I can't help thinking that certain languages impose their own variation of the
Blub syndrome, namely in leading to the conclusion that one particular way of
thinking about programming should be the One True Way to think about
programming.

Various Lisps, for example, produce the well-known "when all you have is an
AST, everything looks like a macro" syndrome; Scheme inculcates a desire to
use tail recursion even when counting on one's fingers; etc.

This is, incidentally, precisely the same criticism proponents of functional
programming typically level at proponents of, say, object-oriented
programming. And I've no doubt that, if the popularities of those paradigms
were reversed, comments like this one would be the usual snipe from OOP fans
at their "unenlightened" functional brethren and sistren.

At any rate, I'm very far from being convinced that this is a healthy thing
for either the programmers affected, or for the state of the art in general.

~~~
rw
When you can modify the semantics of the _entire language_ , you can use any
paradigm you want.

~~~
sethg
...which is great, until you want to use one paradigm and you also want to
take advantage of a certain library, and you discover that the library uses a
completely different paradigm. Either you put up with an impedence mismatch
between your code and the library, or you discover that in this language all
paradigms are equal but some are more equal than others.

------
tsuraan
The author makes the assertion that flat is better than nested, and indeed
it's one of the rules in "import this", but I just don't see it. I spend about
half my time in python, and about half in erlang. Erlang makes python look
pretty deeply nested, since it pretty much lacks support for any namespace
nesting, but honestly, I prefer Java's namespaces. If I were to write a
library in Java (god forbid), I'd start it in net.tsuraan.whatever. I'd know
that I'm not going to have namespace clashes with the standard library,
apache, nor anybody else that is half-way sane. In python, the root namespace
is pretty crowded, and you need to step carefully to avoid namespace clashes.
In erlang, it's even harder. Why do people like flat namespaces, as opposed to
reasonably nested ones?

~~~
jnoller
noooo, I wasn't making that assertion - I was saying the argument against my
gripe about nesting bits of the stdlib deeper would be responded with "flat is
better than nested". The "flat" crowd always whips that one out when someone
suggests nesting it a bit more. I am a fan of nesting it just a little bit
deeper than what it is today.

~~~
tsuraan
It reads as though you generally do agree with the flat is better than nested
though; your argument appears to be more against how the system is currently
organized, rather than being concerned with the ability to write libraries
without worrying much about namespace clashes. I'd love to see the entire
python standard library moved into a root-level "python" namespace; I'm
guessing that would be about as popular as curly braces with the general
python crowd...

Heck, even the ability to root your imports, like import .email would bring in
the root-level email library, would be pretty nice. I'm sure I've seen the
idea shot down before, but I can't recall what the reasoning was.

~~~
jnoller
Relative imports are in python, which allows you to dictate where a "foo"
module is imported from

------
zmimon
Yay for another person like me who wants to be able to sprinkle just a little
static-typing goodness back into the dynamic typing orgy everyone is having
these days.

I don't mean huge cumbersone Java or C++-esque typing, just the simple ability
to declare to the compiler (or to humans trying to read my code) - 'object foo
is a Foo, please give me a hand and tell me if you can deterministically
figure out that it is not, or if it is doing something that Foos are never
allowed to do'.

~~~
silentbicycle
While it's not caught at compile time, why not use assert?

    
    
      assert(type(x == "float"))
    

should be a very clear declaration to others reading the code, and assert is
also not limited to type checking.

I like static typing in some circumstances, but adding it to Python would be a
major change to the language. I'd rather just use OCaml when static typing is
really important, and save scripting languages for the niches in which they
excel.

~~~
jnoller
asserts are stripped out when python is run in optimized mode. Not to mention
sprinkling them around your code is infuriating for people dealing with your
code :) I'd also point you to the links to guido's writeup I put in the post,
I agree: it changes the language too much to be a positive net gain.

~~~
silentbicycle
> sprinkling them around your code is infuriating for people dealing with your
> code

Would this necessarily be any less true of static type annotations, though?
And as for them being stripped out, yes - it's for making debugging easier,
not performance.

------
adw
This is a pretty minor thing compared to a lot of the warts here - to be
honest, I'm not in the league of most of you as a programmer, I suspect - but
two pretty simple things I've found surprising/annoying and have managed to
shoot myself in the foot with:

* loops leaking their control variables: I get why this is useful sometimes, but it particularly bites with list comprehensions, especially as generator expressions don't leak. Apparently the list-comprehension part of this goes away in Python 3 ([http://mail.python.org/pipermail/python-3000/2008-April/0131...](http://mail.python.org/pipermail/python-3000/2008-April/013189.html)).

* How mutable default argument values behave. Now, this one's even mentioned in the tutorial - [http://docs.python.org/tutorial/controlflow.html#default-arg...](http://docs.python.org/tutorial/controlflow.html#default-argument-values) \- so I've really got no excuse, but that hasn't stopped me getting it wrong before!

~~~
jnoller
Mutable arguments are considered harmful; and will probably cause cancer,
plague, locusts and other end-of-the-world problems.

~~~
adw
Yeah, that's more or less what happens. What you'd, admittedly naively, want,
though, is a way of saying "a new empty dictionary, please", so you don't wind
up having to write this kind of thing:

    
    
      def f(a, d=None):
          if d is None: 
              d = {}
    

which, okay, it's a minor deal, and I know _why_ it happens, but it's the kind
of thing I forget you need to do!

------
tow21
Macros. Macros macros macros. Even if I can't have full-on lisp-y AST macros,
I'd kill for relatively simple CPP-ish textual macros, just to cut down on
boilerplate code.

Not that the chances are any good, and I can understand why - it would be
decidedly un-Pythonic. But it's just mildly frustrating at times when I find
myself writing the same coupe of lines of code twenty times within a file,
because scoping rules insist they have to be there (reading from locals() is
often where it hits me))

~~~
euccastro
I have used exec and eval as something way better than _relatively simple CPP-
ish textual macros_. What's better, you have all the power of Python string
manipulation. If you're reading from locals() a lot you're in evil land
anyway. :)

~~~
j_baker
exec and eval can be powerful. But that's their problem. They're a little bit
_too powerful_.

------
rbanffy
I think this whole "things I hate in $language" misses a very important point.

There is an immensely rich universe of languages you can chose from today. If
you want Lisp-ish lambdas and macros, you should, by all means, go with Lisp.
If you want to build your own DSL, you may as well chose Ruby. If you want
pythonic indentation-as-structure, you should go with Python and, if you love
the "do this if that" thing, you should consider Perl.

Having said that, I would love if Python threads had better support for multi-
processors. It's not like changing syntax and turning Python into something it
isn't, it's just properly implementing something that should be there from day
1.

~~~
jnoller
I don't think it misses anything. My post is mainly around things I want to
make better, to make python better. I am definitely a fan of using the right
tool for the right job: that means using the language which fits the domain.
This is why I don't think arguments for "more functional programming" features
or "be erlang" hold a lot of water for Python; if that's what you want, you
need to go use those tools.

~~~
rbanffy
I agree with your points and, having done a lot of Zope/Plone programming in
the past, your #1 is by far my #1 too. More than once I have sworn if I knew
enough of the inner workings of CPython, I would solve the problem myself,
even if it took years of labor, even if I had to rewrite each and every module
out there ;-)

I think my rather inadequately thought out response was because most of the
comments here in HN were about changing Python into something else. I am truly
sorry I implied your article was about turning Python into something unnatural
and I most certainly owe you an apology.

~~~
jnoller
It's nothing. But I wholly agree that many of the comments here and elsewhere
are very much in the vein of "man wouldn't it be great if python was
OCaml?!!", which is about as useful a comment as a hole in my head.

~~~
silentbicycle
Python isn't OCaml. It's not Prolog, Haskell, awk, or SQL either, and trying
to bend it into those is largely missing the point.

A more interesting question is, "In what circumstances is Python an excellent
fit, and OCaml a poor one?", and vice versa.

------
j_baker
Man, I was ready to reply with a nasty comment until I saw who the blog post
was from. :-)

~~~
jnoller
Heh. No reason to flame me ;)

------
T_S_
He forgot one: "Everything is a run-time error."

~~~
jerf
Somebody stopped reading before 5 and 6.

