Saturday, March 31, 2007

Five things I hate about Python

It's been a meme of late to blog about 5 things you hate about your favorite programming language, in order to qualify you to complain about other languages. (It proves your "objectivity.") What I really wanted to do is blog about things I like about Python, but to go along with the current theme, here is my list of the top 5 things I hate about Python.

  1. Lack of support for blocks - I have a bit of an esoteric desire here: I want to use Python-like syntax to build a DSL for compiling into hardware description language, essentially using Python as a macro language on top of the DSL. I want to be able to create my own control structures (hardware_if:...., etc.). Python doesn't let me do this.

  2. Stdlib organization (or lack thereof) - Maybe this is inevitable, as the stdlib is made up of all sorts of things integrated from other packages, but it would be nice to have something closer to what the C# and Java people rave about in their respective languages.

  3. Inefficient tail calls (tail recursion) - Maybe not important to too many people since Python has such cool iteration support, but it would be nice to be able to write a tail-recursive function and know that it will be optimized into a loop.

  4. No "nonlocal" rebinding of functions - This will be fixed in Python 3, which is cool, but it's not there right now. Basically, you can read variables from enclosing scopes right now, but you can't "rebind them", that is, assign the name to a new object. All assignments are either in the local scope (default) or module scope (if you declare the name "global"). And honestly, the main reason I hate this is that it gives Paul Graham one more negative thing to say about Python relative to LISP.

  5. No dictionary comprehensions - And it's not gonna happen any time soon. List comprehensions are wonderful, and I'd like to build a dict in the same way. I know I can do dict((k,v) for k,v in seq). But I don't like the double-left-paren there. OK, so it's a nit. But wouldn't it be nicer just to say {k:v for k,v in seq}?



Well, there it is. 5 things I hate. Now I can get on to writing about the things I like.

12 comments:

  1. I too work with Hardware. ASIC & FPGA designs; Verilog VHDL, Specman ...

    Earlier this year I wrote a preprocessorfor those translate_off/translate_on comments used to remove source fro consideration by synthesizers in Python. I next went on to write a Verilog preprocessor to handle all the backtic macros of Verilog; `define `ifdef `reset `include etc.

    I did both in Python without blocks so it ca be done.

    - Paddy.

    ReplyDelete
  2. P.S. The thing I hate about Python is it not having a constrained random generator a-la SystemVerilog or Specman-e or Vera.

    - Paddy.

    ReplyDelete
  3. You can definitely use Python to preprocess files of a different syntax, but that's not really what I was thinking of. What I'd like to to be able to create a domain-specific language for hardware design that really looks like Python. Something like:

    defmodule mymod(s1, s2, s3):
     myfor(unrolled=True) i in range(10):
    ...

    With blocks, I'd then be able to use operator overloading and such to build up a parse tree which I could then synthesize into RTL. Without them, I can use Python as a macro language, but not much else. In fact, Cog is a great tool by Ned Batchelder that can be used to give pretty much any language a Python pre-processor. I'd just like to go a bit beyond that.

    ReplyDelete
  4. I think tail call elimination is more trouble than its worth. It messes up tracebacks since scopes disappear in ways that will be mysterious to most programmers. You can avoid this, but then it's just a funny little optimization that avoids some recursion limits -- but not all limits, and not in a way most people will understand, and probably slowing things down as a result. Maybe as a -OO option or something it would be reasonable, otherwise it's kind of lame IMHO.

    ReplyDelete
  5. Re: Ian Bicking

    First off, (and way off topic), I really enjoyed your talks at PyCon on WSGI and Zdjango Gears. I can honestly say I have never laughed harder at any technical conference.

    You may be right on tail call elimination being more trouble than it's worth. I've never hacked on the Python interpreter, so I'm not really in a position to judge. However, it does seem that Python has a substantial function call overhead (IIRC), and tail call elimination would seem to remove that overhead when the optimization could be applied. So I guess I don't know how this particular optimization could possibly slow things down. (Though again, I don't hack the interpreter source, so I can't say authoritatively).

    And hopefully this post made clear that these 5 things are not particularly large obstacles to my use of Python. Just some evidence that I'm not a completely off-base fanboy. None of these things are show-stoppers for me (and I like a lot more about python than I hate).

    ReplyDelete
  6. Anonymous11:02 AM

    I just stumbled across your blog and find it very informative! I noticed the comment about writing HDL in Python. Are you familiar with MyHDL (http://myhdl.jandecaluwe.com/doku.php)?

    I have had good success using MyHDL and Python as a verification language and for writing HDL. I am not familiar with the "block" structure but MyHDL uses generators to describe hardware blocks (oopps may have overloaded a term).

    ReplyDelete
  7. Anonymous12:11 PM

    I'll throw my two cents in. It's not a gripe with Python per se, but with its standard library: the datetime module is weak. I can't compare a datetime.datetime instance with a datetime.date instance without jumping through hoops, its arithmetic is weak, and in most ways it's vastly inferior to Egenix's mx.DateTime library. Yet software like Django uses it, which means I spend a lot of time converting values between it and mx.DateTime. Not fun. I hope they pitch the module for Python 3000 and roll mx in instead.

    ReplyDelete
  8. Anonymous7:30 AM

    This comment has been removed by a blog administrator.

    ReplyDelete
  9. Anonymous4:47 AM

    For DSL that can be created from an already working functional language. I would recommend to look at Metalua. It is essentially an extension to Lua that lets one create new Syntax constructs (or change the original ones) in Lua.

    The way it works is that you give it a Lua source file as an input, and then it gives you the AST of that source file with powerfull Node matching functions. So that you can transform that source code either in place (into another LUa file) or into something different.
    I used it to create Lua-based DSL and transform it into javascript. There is a mailing for metalua as well.
    Some people use it introduce new operators or other syntactic constructs into Lua.


    I kind of thought that Python decorators can be used for DSL, but I do not think they are meant for this task.

    ReplyDelete
  10. @anonymous:

    Thanks for the tip on Metalua! I will definitely look into it.

    ReplyDelete
  11. Have you looked at the parser / ast modules? Gives you access to python parse trees. Might be what you're looking for.

    ReplyDelete
    Replies
    1. Thanks for the comment! I have done a few things with the parser and ast modules. Lots of stuff has changed since I wrote this (for instance, dict comprehensions now exist). Blocks would still be nice, but I've discovered I don't really want macros all that badly (see other posts on this blog re: MetaPython).

      Delete