Programming

Python

Python is (one of) the best programming language(s) (at the current moment), at least, for most tasks. For example, it (used to) run this website (Updike.org). See below for some opining on the subject of language design.

Beefs

  • Weird scoping (global) and lack of lexical closures (they do exist but mutating non-local, non-global variables (i.e. up one level in scope) is awkward). Any language that allows variables to come into scope at runtime is susceptible to this problem and tradeoffs are always required (though Haskell makes it abundantly (and syntactically) easy to bring variables into scope with where and things get worked out at compile time, sort of the best of both worlds...)
  • Can't compile to native code (Psyco makes things somewhat better). This is really not that bad for most uses because it runs really pretty fast. IronPython should help here.
  • Can't make macros (though macros are not usually neccessary in a language like Haskell because of lazy evaluation). No ternary operator (or way to make one short of eval, which is worse than (a and b) or c) (Update: ternary operator on its way.) No real way to extend the language to do unintended things (think domain specififc languages with slightly expanded syntax, e.g. new control structures or infix operators, etc.) beyond just hacking the source code or building an interpreter inside it.

An Observation

I'm surprised that I didn't notice sooner, but it looks like the features that are constantly being added to languages like Python (generators, enumerate, etc.) are unnecessary because you get them for free in a language like Haskell (or you can do it yourself in like 10 lines of code, define your own operators (prefix and infix) that look like builtin keywords).

Examples from Python 2.4 New Features:

  • String substitution: make your own % operator or string interpolation with Template Haskell. (Haskell is still weak at this and I would prefer a standard built in way like shell scripts, Python, or Perl. It's so nice.)
  • Integers/Long Integers: type classes addressed this from the start.
  • Reverse iteration: true first class functions with lexical scoping, monads, etc. let you implement this functionality in a totally (more) transparent way (or use lazy reverse and there, you're done! laziness lets you extend the language in very powerful and interesting ways)
  • Function decorators: use function composition. Most of the time the type system and type classes give you this stuff anyway! It's a pretty cool way to bring things together but it seems to admit that the language wasn't powerful enough on its own. Polymorphic types, monad transformers, etc. help out here.
  • Decimal data type: write your own; the number tokens (3.45, 1.234, etc.) are constructors that can be overloaded to be used in any type class. The Haskell number classes and type classes are the most elegant solution to the number zoo problem; even the elegant Scheme number tower shows wear compared to Haskell's number system (though arguably, Haskell's number system could be even more Algebraic and less implementation-geared but there are always tradeoffs).
  • Set types (very nice): write your own (Python lets you do this as well.) In Haskell, most of the time, lists suffice (laziness can prevent things from being allocated up front and list traversal can be changed into a simple loop). The Haskell Data.Set type is built in Haskell and is immutable and purely functional, with good performance.

Other features:

  • Iterators (lazy lists give this for free and are infinitely more lightweight and succint)
  • Ternary operator: Haskell case expressions and laziness let you make a function "myif" that is the same as an expression "if" (i.e. ternary operator), and you don't need macros to do it.

The older language changes (1.5.2 -> 2.0 or 2.0 -> 2.1 -> 2.2 -> 2.3) would probably give even more, better examples, but one other thing is apparent: Python has awesome libraries! Haskell's libraries tend to be more clean (and all written in Haskell itself) but probably nowhere near as extensive or heavily used and extended, etc. They are there and the community rocks, but the libs are not quite like Python where a distro of 2.4 will always have what you need, sort of an all-in-one solution. Update: Haskell Platform and hackage / cabal help a lot with this.