Warts on a snake: Ugly bits in Python syntax

27 Jul

Opera python I point out this post not to comment on its subject but just as an example of Python code and to remark that the otherwise pretty and compact Python syntax is blighted by a few things:

  1. The ‘self’ as the first parameter of every class method is cluttery and is only necessary as the artifact of Python’s conceptual distinction between bound and unbound methods. I think Javascript got this right: when a function bar is invoked as foo.bar, foo gets passed to the function as the keyword ‘this’ (though I would choose the keyword ‘me’ instead for brevity).
  2. Another thing Javascript got right is not requiring quote marks around identifier-like names used as keys in object literals. Where Python requires {‘foo’:bar}, Javascript allows {foo:bar}. Of course, in Javascript, keys can only be strings while Python allows any kind of (immutable) object, so some syntax would be needed to distinguish between foo to mean the string ‘foo’ and foo to mean the object referenced by foo. I suggest something like @foo to mean ‘the object held by foo‘.
  3. The pseudo-special names beginning and ending in underscores are just ugly and annoying to read and type because it can be difficult to tell the difference between one underscore and two adjacent underscores.
  4. The colons after if, elif, else, etc. look fine, but they’re annoying to type and easy to forget to include. A delimiter is needed for one-liners, e.g. if foo: print bar , but should be omitted for multi-liners (and this omission should be compulsory).

3 Responses to “Warts on a snake: Ugly bits in Python syntax”

  1. Will McGugan July 28, 2007 at 12:45 am #

    I’m guessing that your objections to Python are because you are coming from another language that you are accustomed to. If you went from Python to Javascript you would dislike the opposite things in Javascript.

    1) I don’t find it cluttely. Although it was a little odd coming from C++, but Python is so lean generally that it is a fine trade-off.

    2) dict(foo=bar)

    3) Ugly is subjective, but if you have a good code font, it is easy to tell the difference. Although they do merge in to one on the web.

    4) Annoying to type? Don’t like pressing two keys at the same time? At least you don’t need to use { and } as much in Python.

  2. Brian Will July 28, 2007 at 10:30 pm #

    Hi, Will,

    I learned Python after C, C++, and Java, but well before Javascript and others, and I think every other language is far worse off than Python. I was only saying that fixing a few things would remove a few blemishes from the language.

    1) The whole bound/unbound business is simply unnecessary except as a protection against methods being called as functions and functions being called as methods. I imagine Python enforces this distinction for the same reason it requires functions to be called with the right number of arguments: as a kind of error checking (though I imagine there’s some kind of efficiency argument behind these decisions as well). However, I’ve never found these features—especially the bound/unbound distinction—to be much protection against errors. When I make easy to catch errors in Python or any other dynamic language, it’s almost always a mistyped name that trips me up, not the number of arguments to a call or anything like that. Besides, I’m considerably less likely to get the number of arguments wrong than I am to get the types wrong, something dynamic languages don’t protect against at all. Once you give up type checking, you might as well go all the way and require programmers to rely upon a function’s documentation to call it the right way, not by other kinds of protections in the language, which are simply too weak in comparison to type checking to do much good.

    2) If we’re going to use dict() to create dictionaries, there’s no point in having a dictionary literal syntax at all.

    3) The double _ convention is no more sound than Ruby’s use of the easily mistaken | character, and it’s simply not necessary: to understand the significance of a __x__ name, you have to recognize the name and know it’s significance, so why not name it something cleaner? I just don’t think these names need to stand out enough to warrant the heavy look.

    4) Typing a colon involves shifting and a pinky finger, and colons are often hard to see. Strenuous? No. Annoying? Often enough to matter, especially, I find, when coming back to Python after an absence.

  3. Scott Enderle February 6, 2008 at 3:01 pm #

    I don’t mean to be argumentative but I have to agree with Will’s position.

    1) I happen to see this as an example of Python’s self-documenting tendencies. The self argument could be left explicit, but a) I find that the consistency of idiom (“self is just another argument”) actually makes it easier to read; and b) it clarifies the concept for people who are learning to program object-oriented code. You might scoff at the latter; but a language like python encourages good coding practices by making them easier, and learning the concepts behind the language you use is a good coding practice.

    Another advantage: there’s nothing stopping you from using “me” instead of “self”, except convention. But in javascript you have to use “this.”

    2. I think typing @ is harder than typing two single quotes.

    And again, Python self-documents: {‘foo’:bar} actually conveys the sense that “foo” is a name. But what does @foo mean? It’s nowhere near as intuitive.

    3. I honestly have no opinion about double-underscores. But I don’t see how they’re any more annoying than any other set-this-apart convention (would INIT() be any better?). It ought to have some kind of visual impact, and things with visual impact are a little annoying. That’s the whole point.

    4. Actually, I agree that this might not be necessary, except on single-line statements. But somewhere in the back of my head I suspect that I am wrong to feel this way. I guess Python has its grips in me…

Leave a Reply