
Charming Python: Functional programming in Python - m3mb3r
http://www.ibm.com/developerworks/library/l-prog.html
======
gcr
This article was written in 2001, and python now includes first-class
constructs for many of these.

Map:

    
    
      >>> [ord(char) for char in "Hello"]
      [72, 101, 108, 108, 111]
    

Filter:

    
    
      >>> [x for x in xrange(10) if x % 2]
      [1, 3, 5, 7, 9]
    

For laziness, use parenthesis to turn the above list comprehensions into a
generator comprehension. Though I don't demonstrate it, you can work over
infinite sequences of objects this way with constant memory usage (without
allocating all of them upfront).

    
    
      >>> gen = (x for x in range(10) if x % 2)
      >>> gen
      <generator object <genexpr> at 0xb729f6bc>
      >>> for element in gen:
      ...    print element
      ... 
      1
      3
      5
      7
      9
    
    

Alice, the rabbit hole begins here -->
<http://docs.python.org/library/itertools.html>

~~~
yason
The functions are more first-class than list comprehensions and other
syntactic alternatives. It's easier, both conceptually and lexically, to
mangle, pass around, chain, and combine functions and function argument than
it is to write nested list comprehensions.

Not against list comprehensions per se, really. They're just a convenient
subset for most commonly idiomatic sequence-mangling-spells, but that's most
of what they're good for.

------
koenigdavidmj
They are using the old 'foo and bar or baz' style as a cheap substitute for
the ternary operator. That should be 'bar if foo else baz' in modern Python.

~~~
jacobolus
It’s an article from 2001....

------
RyanMcGreal
Note:

> Date: 01 Mar 2001

Some of this advice is deprecated.

------
CrLf
Although I'm fond of using some functional constructs where they make sense, I
don't like functional languages and this article is an example of why: in
search for a functional style, clear code becomes opaque and simple code
becomes complex.

------
albemuth
I think more people would read more ibm dev articles if they changed the css a
little bit

~~~
blhack
Readability does a really really good job of cleaning it up.

Is there a way to link to a readability version of a document? Like
<http://readability.org/?url=example.com>

------
barnaby
Is there an updated version of this? Would be really good to see the full list
of improvements in this space.

------
Swizec
Ever since I've dabbled a bit with Lisp my Python (and javascript) code has
become much more functional-y.

Still not sure whether this is a good or bad thing.

~~~
angusgr
I think it's a double-edged sword.

I've both written and read code in non-functional languages where the "easy"
way of doing it is thrown aside for the "cool functional" way of doing it.
Leading to code which was more fun to write, looks cooler, but is also hard to
read and written in a different idiom to the actual programming language. Bad.

I'm 100% guilty of this, although I try to stay vigilant. The other day I
refactored out a gnarly bit of a Python API, but caught myself feeling sad
because it meant deleting a bunch of clever lambda functions I was using to
work around it in the first place. Bad!

That said, the other side of the double-edged sword is great - things that
lead to giant tangled messes of procedural code can be turned into very nice
functional-style constructs. Also, I love having list comprehensions in
Python.

~~~
Swizec
Usually list comprehensions are a much cleaner way to write a map. This I
love.

Personally what I love most about using more functional code aren't the clever
lambda's and stuff, I actually try to avoid that because it looks weird in
Python. What's really awesome is enclosing named functions inside bigger
functions and using closures.

The result is code where:

1\. nobody can, by accident or intentionally, use inner functions of your
algorithm,

2\. self-documented code (function name says what the code block does)

3\. you aren't passing a gazillion parameters around

4\. or making everything messy with a bunch of unneeded OOP code. [I don't
like useless OOP code. Objects-just-for-the-sake-of-encapsulation are silly.]

edited for wall-of-text

~~~
tmoertel
> Usually list comprehensions are a much cleaner way to write a map.

But the first makes my intent clearer than the second:

    
    
        map(f, xs)
    
        [f(x) for x in xs]
    

In Python, where creating anonymous functions is syntactically expensive,
list-comprehension syntax may be cheaper in many cases, but it's not clearer.
When I want to map or filter something, I want to _say_ that I'm mapping or
filtering, not explain to Python how to map or filter that thing in terms of
list-comprehension syntax. Nor do I want to burden the reader with
interpreting that syntax to figure out that it's a mapping or filtering
operation.

I want my code to say what I mean, not just evaluate to what I mean.

~~~
markmark
>But the first makes my intent clearer than the second

That is entirely a matter of opinion. I would say python programmers with no
functional background would find the list comprehension clearer, because that
is the idiomatic python way.

May would have no idea what map even does without looking it up on the net.

~~~
tmoertel
> That is entirely a matter of opinion.

It isn't _entirely_ a matter of opinion, is it? When you use map to do your
mapping, aren't you are stating your intent in the language of the profession?
The name of the function, after all, is "map," and isn't this term's meaning
rather firmly established in mathematics and computer science? So, the idea of
calling a map a map has some precedent that we can use to justify the
practice, doesn't it?

Now, if your audience has no notion of what a mapping is, then, yes, there's a
level of semantic intent that you're not going to be able to communicate to
them. (At least until they learn the concept; it's common, worth learning, and
not hard to grasp.) But that doesn't mean that you should refuse to call an
important concept by its established name.

Concepts, after all, earn their names for a reason. If a concept has one, it's
probably best to use it.

------
exit
why doesn't python have anonymous functions (not just lambdas which can only
be expressions)?

~~~
bobbyi
It lets you define functions on the fly and use them, so the only difference
from anonymous functions is that you have to pick a name.

~~~
kgo
Yeah, I almost wish they didn't use the keyword 'lambda' at all. If you could
just write:

    
    
        def foo(x):
            def lambda():
              print x
            lambda;bar(callback=lambda);baz(42,lambda)
            def lambda():
              print x * x
            lambda;bar(callback=lambda);baz(42,lambda)
    

It'd stop this silly complaint. I just end up using 'def lambduh'

Slightly annoying that you need to define the function on the line before,
can't inline it, but not nearly as bad as people make it out to be.

