without an e

embrace the heresy [01/04/2007 06:13:40]

Python, ladies and gentlemen, is not a functional programming language. Functions are first class objects. There's a lambda keyword. And it has two beautiful functional constructs in the form of generators and list comprehensions. But if you try to write your whole program in a functional style, you always seem to be going against the grain of the language.

In a functional language, everything is an expression, meaning everything returns a value. In python, some things return values, but many things don't. The things that don't return a value are called statements. For example, the if construct is a statement. The while and for loops are statements. And so on.

Things are getting better. Ever since list comprehensions were introduced, we've been able to use for in an expression, and you could use a limited form of if as an expression inside the list comprehension: [x for x in xs if x > 2]. And now, as of python 2.5, you can finally use if as an expression anywhere: (x = 1 if True else 2).

But if you like this style, and you start trying to use it everywhere, you run into problems. The most common example is wanting to create an anonymous function on the fly (a lambda) but needing to use a statement - perhaps an assignment (because python doesn't have a let construct). At that point, you have to go to another part of the code and define a function.

There's no technical reason why you can't do these things. The python virtual machine would certainly allow it. The problem is that the syntax is deliberately designed to prevent using a functional style. For example, Ruby and Smalltalk have a very nice syntax for anonymous blocks - like lambda done right. For a while it looked like python might get these too, but instead we got the with block.

The general sentiment seems to be that some functional features are nice, but only in small doses inside the standard object-oriented/imperative paradigm.

This is one reason people leave for ruby. Ruby isn't quite a functional language either, but it has many more features. But I have two problems with ruby: first, with the exception of Rails, the libraries aren't all that spectacular, and second... Well, ruby just isn't that much better than python. If I'm going to relearn everything, why would I bother with ruby? Why not just jump straight to lisp? Well, because the lisp libraries are even worse off.

No, what I want is functional python.

And that, my friends, is heresy.

But: so what?

There could be.... advantages.

The great marketing genius Seth Godin is always talking about how you've got to be remarkable if you want to get attention. My little web framework is not terribly remarkable. Why? Because it's just like all the others. Why? Because I put up with the things I didn't like about python rather than doing what I really wanted. I figured nobody would ever use it if I made it look like lisp. When Rails and Django came along, I figured I might as well throw in the towel.

But what if I made heresy the selling point of my little web framework? Not because people want to be heretics, but because I can't be the only one out there that loves python but wants something more. It might be a small community, and a lot of people would just plain hate it, but the people that stayed would very likely fall in love with it.

So, I think it's finally time to settle on a name for this dang framework. Something that embraces the heresy of functional python. A symbol even.

Ladies and gentlemen, I have found such a symbol. Prepare yourself, for I give you... The Scarlet Lambda!

the scarlet lambda

Ruby, Python and Lisp aren't the only games in town. If you're so hung up on functional programming, why not go the whole hog: Haskell?
by Mark Reid [01/11/2007 05:51:15]
Python is not a *pure* functional programming language. There's a difference between functional programming languages and pure functional programming languages.
by Dan P [01/11/2007 19:06:03]
Why not go the whole hog and use Erlang. With Erlang you get a fully functional language, excellent library support, your own Erlang web server (yaws), your own Erlang distributed database (mnesia), first class functions and closure, full access to the parse tree and the ability to do metaprogamming on the fly, hot code replacement where a module can be instructed to replace itself with a more up-to-data version, n-physical tier debugging, applications that can be instructed to start on physical machines and fail over to other ones as part of a standard configuration. What more could you want? http://erlang.org
by Gordon Guthrie [01/11/2007 07:07:46]
I am with you. I really like python, but it is such a "lisp hold up" that i would prefer a scheme dialect with a good set of libraries. Until then use : http://oakwinter.com/code/functional/ L.
by Lionel Barret [01/11/2007 15:30:23]
I guess the other thing worth mentioning for those that want to use Python for functional programming is that there has been resistance to Tail-Call-Optimization. Without TCO, many of the Scheme/Lisp techniques are closed off, as function recursion can no longer be trusted for iterations. Of course, the downside to having TCO is that the stack no longer has an exact accounting of the history of function calls - which is why Guido has shunned TCO in Python.
by Chris Rathman [01/11/2007 15:14:42]
Been kind of a hobby project of mine to translate SICP into a number of different programming languages such as Python and Ruby (link is on attached to my name below). From a Python perspective, not have anonymous functions is in my opinion not that big a deal. You have to step aside and give the function a name in it's own construction, but sometimes that's not a bad idea. From a Ruby perspective, the lambda is more general, but you have the headache of lambda functions can not be interchanged with named functions (lambdas have special invocation syntax of call). The bigger hassle is that Python doesn't natively support chained lists. What Python calls a list is better described as a Vector (or Array). Now you can build iterators over arrays (maps, folds, etc...), but what you can't do is build a list in pieces from a recursive function. Of course, you can roll your own cons and lists functions, like I did for the SICP translation, but it'd be a lot easier if there were native support. Anyhow, my vote goes for less fretting over the crippled lambda, and more weight to functional data structures (lists, trees, streams, etc...).
by Chris Rathman [01/11/2007 15:04:54]
Forgive my ignorance, but isn't the fundamental requirement of a functional programming language be that functions are first class objects? Aren't functions in Python first class objects? Claiming Python is not a functional language because it does not implement lamdba the way some functional languages do is a little misguided.
by Mystilleef [01/11/2007 13:55:13]
I work in python too and I like functional programming. After a couple of years of happy python coding I gave a look at Erlang and I find it really amazing. Gordon has already explained some of the features you get with Erlang. What I can add is that Erlang hasn't yet all the python libraries, but it's really worth a look. Also for web programming give a look at erlyweb (rails for erlang) and erlhive. They are young projects but promising.
by Filippo Pacini [01/11/2007 08:12:59]
You have spoken my mind! I have been carousing with Erlang, Scheme, Lisp, Scala, for exactly the reasons you have layed out, but none seem to match: * The amount of batteries included, and * A friendly and concise interpreter shell to have a conversation with. I haven't given up on these other languages, but they are all much more cumbersome than Python for me right now... So when can I evaluate your functional python? :)
by casey [01/11/2007 11:16:02]
I've had some similiar thoughts, and I find that as I grow as a Python programmer my style becomes more (though obviously not purely) functional. My interest in true functional programming led me to choose Haskell as my try-to-learn-it-in-2007 language.
by paul Bissex [01/12/2007 09:54:18]
Lovely logo.
by Andrew Sidwell [01/04/2007 10:05:37]
Nice! The lambda keyword is one of the things that annoys me the most when Pythoning.
by Edward O'Connor [01/04/2007 10:57:12]
Of course, you don't have to do go somewhere else to define your function: def abc(arg, lst): def inner(poop): if (poop == arg): return True elif poop > 5: return True return [x for x in lst if inner(x)] >>> print abc(3, range(10)) [3, 6, 7, 8, 9]
by dbt [01/04/2007 11:11:06]
Well thanks, guys! :) To dbt: sorry my crappy blog killed your syntax. Yes, you can define nested functions, but the case I had in mind when I wrote that is a dictionary full of functions (a dispatch mechanism). I use that a lot, and I often want to define methods right inside the dict, next to the key - sort of like haskell's pattern matching.
by Michal Wallace [01/04/2007 12:49:39]

(new comments disabled for now)