Why functional Python matters

Dave Benjamin ramen at lackingtalent.com
Tue Apr 15 19:17:26 EDT 2003


In article <yfs7k9vcu2p.fsf at black132.ex.ac.uk>, Alexander Schmolck wrote:
> I think your life might be much happier if you just went to
> http://www.drscheme.org/, dowloaded Dr Scheme and used *that* for
> webdevelopment. Then you can use a real functional programming language and
> read books by people who actually have a real clue about functional
> programming (there is lots of *excellent* material available on-line and for
> free, like SICP and HTDP, the latter uses Dr Scheme -- also have a look at
> http://www.cs.brown.edu/courses/cs173/2001/Lectures/). Why settle for some
> second-rate immitation? [1]

I may just take your advice and investigate that. Thanks for the reference.
But keep in mind that I'm not saying "I don't like Python, it's not
functional enough". I'm saying "I love Python, it lets me work in both an FP
and OOP style, and this makes me happy. I just don't want to see FP support
drop out of the picture."

> (Dr Scheme *does* have web libraries, I've never used them but I'd suspect
> they shouldn't be too bad, because they seem to have hit on trick of using
> webdevelopment as application domain to bring things like continuations to the
> unwashed masses (viz. their sophomores) :).

Interesting.

> Ain't gonna happen. Anyway you can always replace 
> 
>   foo(lambda x: x+3)
> with: 
>   def bar(x): return x + 3
>   foo(bar)
> 

That's true, but then I have to name "bar". And part of the joy of FP is not
having to name *everything*. Naming things is important if you need to call
them up later, but it's a hassle to name intermediate values, just as it
would be a hassle to have to say:

result = list()
result.append(x)
result.append(y)
result.append(z)
return result

When Python lets you instead say:

return [x, y, z]

>> keyword-argument trick wasn't really that bad, once you got used to it. In
>> any case, with dynamic scoping, this problem has completely disappeared.
>                  ^^^^^^^^^^^^^^^
> not quite.

Am I using the wrong terminology here? I'm specifically talking about the
named-argument hack to get around Python's previous lack of nested scopes.
This specific problem, as far as I know, is gone now. Am I missing something?

> Only that python won't let you use rather helpful things like ``if`` as
> an expression, but never mind.

Well, this leads us to the ternary operator thing, which I'll let other
people argue about. ;) I'm happy with my short-circuiting and/or for now.

>> In fact, I believe that it is advantageous to design functions specifically
>> for use with map and filter. If you design this way, you will benefit from
>> cleaner syntax than list comprehensions can offer. For example:
> 
> I wonder how a function written for map would look different from one written
> for a list comprehension...

Well, I don't think people usually write functions for list comprehensions
at all. I've never done it. I've never made it an explicit part of my design
for an API that someone use my functions in list comprehensions. But this
could just be because I'm still learning where they fit in best.

However, I have written an API that consisted of functions that curried
their own arguments and could be used in a map, like this:

>>> addx = lambda x: lambda y: x + y
>>> map(addx(5), range(5))
[5, 6, 7, 8, 9]

>> Rather than remove these important functional built-ins, I would like to see
>> two last built-ins be added: unzip (to reverse the behavior of zip), and
> 
> There is already an unzip function and it's written ``zip(*...)``

Thanks, I didn't know this.

>> curry (see the example by Alex Martelli, et. al. in the Python Cookbook,
> 
> Why not just use lambda? Python's argument passing is fairly complex, so I'm
> not sure whether one (or rather two) curry function(s) would be worth the pain
> (at least not if you tell your emacs to display lambda as greek character).

Because it's a common operation in some contexts, and by naming it, its
behavior can be formalized. You can of course write curried functions, and
even self-currying functions (like my "addx" example above) with lambdas.

Perhaps it should go in the "functional" module, along with "compose" and
all that other fun stuff. I still like map/filter being global, though...

Thanks,
Dave





More information about the Python-list mailing list