I wish I had the speaker to give a little more with each slide though.
Functional programming with Python
31–40 of 51 posts
Re: Functional programming with Python
#32It seems to me if you want to write code like this, you shouldn't write it in Python. Python has much simpler, built-in ways to do most of the things he's suggesting. For instance, he says "good" for this code: reduce(operator.add, map(len, ss)) No! The simpler (and more efficient, as it doesn't have to build a list of results!) way to do that is using the built-in sum() with a generator expression: sum(len(s) for s…
$ python -m timeit 'import string;from operator import itemgetter;[itemgetter('slice') for x in string.letters]'
100000 loops, best of 3: 14.2 usec per loop
$ python -m timeit 'import string;from operator import itemgetter;[lambda x: x.slice for x in string.letters]'
100000 loops, best of 3: 10.4 usec per loop
> Also: namedtuple is great instead of "using classes as attribute containers".Er, OK. Just don't look at the implementation[1]. Cannot be unseen.
[1]: http://hg.python.org/cpython/file/2.7/Lib/collections.py#l23...
Re: Functional programming with Python
#33It seems to me if you want to write code like this, you shouldn't write it in Python. Python has much simpler, built-in ways to do most of the things he's suggesting. For instance, he says "good" for this code: reduce(operator.add, map(len, ss)) No! The simpler (and more efficient, as it doesn't have to build a list of results!) way to do that is using the built-in sum() with a generator expression: sum(len(s) for s…
> ...faster and often clearer than lambdas. $ python -m timeit 'import string;from operator import itemgetter;[itemgetter('slice') for x in string.letters]' 100000 loops, best of 3: 14.2 usec per loop $ python -m timeit 'import string;from operator import itemgetter;[lambda x: x.slice for x in string.letters]' 100000 loops, best of 3: 10.4 usec per loop > Also: namedtuple is great instead of "using classes as attribu…
Re: Functional programming with Python
#34It seems to me if you want to write code like this, you shouldn't write it in Python. Python has much simpler, built-in ways to do most of the things he's suggesting. For instance, he says "good" for this code: reduce(operator.add, map(len, ss)) No! The simpler (and more efficient, as it doesn't have to build a list of results!) way to do that is using the built-in sum() with a generator expression: sum(len(s) for s…
> ...faster and often clearer than lambdas. $ python -m timeit 'import string;from operator import itemgetter;[itemgetter('slice') for x in string.letters]' 100000 loops, best of 3: 14.2 usec per loop $ python -m timeit 'import string;from operator import itemgetter;[lambda x: x.slice for x in string.letters]' 100000 loops, best of 3: 10.4 usec per loop > Also: namedtuple is great instead of "using classes as attribu…
python -m timeit 'import string;from operator import itemgetter; getter=itemgetter('slice'); [getter(x) for x in string.letters]'Re: Functional programming with Python
#35Note that `reduce` has been, if not deprecated, then at least discouraged (not that I agree with this, but reduce gets taken away in Python 3, so it's probably good form to stop using it). The author does `reduce(operators.add, lst)` a lot; you can do that using `sum(lst)` instead.
Re: Functional programming with Python
#36I'm curious, on the Currying (Standard Library) slide, the author uses `attrgetter` from the `operator` module -- I've always used `getattr` to achieve the same thing. Am I missing something by not using `attrgetter`?
Short answer: not really. Long answer: In [1]: from operator import attrgetter In [2]: class Person: ...: def __init__(self, name): ...: self.name = name ...: In [3]: me = Person('walrus') In [4]: getattr(me, 'name') Out[4]: 'walrus' In [5]: attrgetter('name')(me) Out[5]: 'walrus' This is potentially useful if you're using `map`: In [6]: people = [me, Person('aschwo')] In [7]: list(map(lambda obj: getattr(obj, 'name'…
PS: map returns a list, no need to call list() on it.
Re: Functional programming with Python
#37Earlier quoted context omitted.
I was writing a really long response to your post, explaining how reduce/inject/fold is abstracting out an absurdly common iteration pattern, and using it can expose structural similarities between many superficially different computations, and how (unlike map and filter) it can't be expressed as a list comprehension, so removing it was super lame. But in the process of translating a comment I wrote in another forum…
If __add__ is taken to be any associative operation of a monoid, then Python's sum is merely equivalent to Haskell's mconcat, which is not nearly as general as reduce/foldl. Plus, unless you implement something akin to newtype wrappers for alternative monoid instances (hardly Pythonic), you're going to be restricted to a single foldable function for any given type. I think you were right the first time; removing redu…
Re: Functional programming with Python
#38I'm not sure I agree with "don't write classes". This is Python: classes are the state container. That's the structure Python provides for grouping related pieces of information together, and that's the structure all other Python libraries and programmers expect you to use. Now if you don't want to type the code every time, that's fine: use collections.namedtuple.
Re: Functional programming with Python
#39Forgot one big con: Python lambda functions aren't "proper" functions (ie. arbitrary multi-line code blocks). Guido van Rossum has addressed this many times, saying (in effect) "it adds undue complexity and would be un-Pythonic", eg: http://www.artima.com/weblogs/viewpost.jsp?thread=147358 This is one of my (very few!) gripes with FP in Python.
I fail to see how this makes them non-proper functions, a better way to put it is they are a subset of possible functions.
Re: Functional programming with Python
#40Earlier quoted context omitted.
I was writing a really long response to your post, explaining how reduce/inject/fold is abstracting out an absurdly common iteration pattern, and using it can expose structural similarities between many superficially different computations, and how (unlike map and filter) it can't be expressed as a list comprehension, so removing it was super lame. But in the process of translating a comment I wrote in another forum…
If __add__ is taken to be any associative operation of a monoid, then Python's sum is merely equivalent to Haskell's mconcat, which is not nearly as general as reduce/foldl. Plus, unless you implement something akin to newtype wrappers for alternative monoid instances (hardly Pythonic), you're going to be restricted to a single foldable function for any given type. I think you were right the first time; removing redu…
I don't have the math to back this up, so please correct me if you know otherwise (and especially if you can demonstrate otherwise, though I know this being wrong is not contingent on that), but: I'm pretty sure `mconcat` with a `map` (or a list comprehension) is exactly as general as `fold`.
> Plus, unless you implement something akin to newtype wrappers for alternative monoid instances (hardly Pythonic), you're going to be restricted to a single foldable function for any given type.
Again, I know this isn't an argument and demonstrates shitty memory on my part, but a single solid example here would be key to me understanding this debate:
What is an example of a type with more than 2 monoids on it, whose fold could not be cleanly expressed with a sum/product and a map/comprehension, which is not already included in the standard library (any/all/gcd/lcm/max/min)?
[I suspect there either won't be an easy answer, or it will be so basic that I'll be brutally embarrassed... this is all kinda talking out of my ass, I have no exposure to category theory outside of reading haskell papers]