7 ms·
Functional Programming in Python [pdf]
- tromp 11y agohttps://en.wikipedia.org/wiki/Python_Bridge https://en.wikipedia.org/wiki/Python_Bridge "Python Bridge, officially known as High Bridge, is a bridge that spans the canal between Sporenburg and Borneo Island in Eastern Docklands, Amsterdam. It was built in 2001 and won the International Footbridge Award in 2002. The bright red bridge spans 90 meters and was designed by Adriaan Geuze of the architectural firm West 8" Coincidentally, Amsterdam can be considered the birthplace of Python, where Guido used to work at the Center for Mathematics and Computer Science (CWI). And now for some obligatory functional python. Run with python lambda.py 2>&1 | head -c 200 to avoid filling your screen with exhausted recursion depth. Notice any pattern in the output? import sys def c(j,t): sys.stdout.write(j('.')('P')) return t (lambda z:lambda y:z(z(y(lambda p:lambda n:(lambda s:lambda z:z(lambda x: lambda y:y)(lambda d:p(s)(y(s))(d)))(lambda x:lambda a:lambda s:lambda p: p(a)(lambda y:s(n(x))(y))))(lambda c:lambda a:lambda s:z(lambda y:s(c)(y) ))))(y(lambda p:lambda b:lambda t:t(c(b,p)))))(lambda s:lambda p:p(lambda x:lambda y:x)(s))(lambda f:(lambda q:q(q))(lambda x:f(lambda y:x(x)(y))))
- rectangletangle 11y agoThis reads like Lisp.
- aaronchall 11y agoYes it's quite possible to write obfuscated Python. See the docs: https://docs.python.org/2/faq/programming.html#is-it-possible-to-write-obfuscated-one-liners-in-python https://docs.python.org/2/faq/programming.html#is-it-possibl...
- delluminatus 11y agoEven knowing a lot about FP, I still found this worth skimming for the esoteric Python syntax. When it comes to constructing dictionaries with list comprehensions, I would always do something like this: dict([n, 2 ** n] for n in range(5)) But they pointed out an actual "dict comprehension" that I didn't even realize existed: { n: n ** 2 for n in range(5) } And there is a similar "set comprehension": { n ** 2 for n in range(5) } Always amazes me how you can use Python for so many years and still encounter new features in the language.
- sibsibsib 11y agoit was added in python 2.7 / 3.0
- rectangletangle 11y agoThis is part of the generalized comprehension syntax. You can also do lazy generator comprehensions. a = (i for i in range(10) if i % 2 == 0) print(list(a)) You can omit the parenthesis, and use them in calls which expect an iterable. b = max(i for i in range(0, 10) if i % 2 == 0) print(b)
- delluminatus 11y agoIt's not exactly the same, which is what I thought was interesting. My first example did use a generator expression inside the dict() constructor, but in that case you need to specify the key and value in a tuple or a list. With the dictionary comprehension you can just separate the key and value with a colon, which is more natural. It might just be sugar on top of a generator expression but it is definitely a special case, syntactically speaking.
- aaronchall 11y agoYes, in Python 2.7 onward: s = {i**2 for i in range(10) if i} and the colon is what makes the dict comprehension different from the set comprehension: d - {i:i**2 for i in range(10) if i}
- aaronchall 11y agoAlthough Raymond Hettinger has also called them generator "comprehensions" in the early proposals, the current documentation calls them "generator expressions". And good examples. Here's how you make those set/dict whatever comprehensions in Python 2.6, before the native syntax is used: s = set(i for i in xrange(10) if not i%2)
- rectangletangle 11y agoSeems like a comprehension is just a particular form of Python expression.
- metalliqaz 11y agoHard to tell from a quick scan, but it appears to be slightly more informative than the classic document in the python docs: https://docs.python.org/dev/howto/functional.html https://docs.python.org/dev/howto/functional.html
- agumonkey 11y agoJust in case, a few years back I've seen an article on functional programming in python. Mostly arithmetic but the patterns were very pretty (think Euclid algorithm generalized). I never managed to find it again. If that rings a bell to someone, I'll be forever virtually indebted. - http://www.ibm.com/developerworks/library/l-prog/ http://www.ibm.com/developerworks/library/l-prog/ - http://kachayev.github.io/talks/uapycon2012/#/ http://kachayev.github.io/talks/uapycon2012/#/ - http://anandology.com/python-practice-book/functional-programming.html http://anandology.com/python-practice-book/functional-progra... - http://maryrosecook.com/blog/post/a-practical-introduction-to-functional-programming http://maryrosecook.com/blog/post/a-practical-introduction-t... - http://rosettacode.org/wiki/Numerical_integration#Python http://rosettacode.org/wiki/Numerical_integration#Python
- mattchew 11y agoDon't think this is the one you're thinking of, but I do like Mary Rose Cook's intro to fp using Python: http://maryrosecook.com/blog/post/a-practical-introduction-to-functional-programming http://maryrosecook.com/blog/post/a-practical-introduction-t...
- agumonkey 11y agoIndeed, this is quite newer, and a gradual introduction to FP idioms (with good successes). Mine wasn't introductory and just threw out ways to decompose the problem into counter intuitive (think ~monad) blocks. I'll edit my post to list those I've found so far. Thanks a lot anyway.
- benkuykendall 11y agoYeah. Python has the functional programming features I expect of any modern language. However, I feel that Python has a lot of unneeded syntax. I always prefer apply() over * and map() and filter() over list comprehensions. func(*args) apply(func, args) [func(a) for a in collection] map(func, collection) [a for a in collection if func(a)] filter(func, collection) I don't see why people use all of this special syntax.
- rectangletangle 11y agoIt's easy to read, though that is pretty subjective.
- RMarcus 11y agoIn Python3, you are really looking at... (func(a) for a in collection) map(func, collection) as equivalent. If you want a list (and not a generator), you would need to do this: [func(a) for a in collection] list(map(func, collection)) For me, the first set (comprehensions) of notation has a more mathematical feel to it, i.e. { x^2 | x \in 0...10 }. Just replace the bar with "for" and it's almost the same thing. I believe the documentation for `filter` even mentions that it is equivalent to the comprehension[1]. [1] https://docs.python.org/3/library/functions.html#filter https://docs.python.org/3/library/functions.html#filter
- jshen 11y agoI've always found the list comprehension harder to read for non trivial examples. It may just be a matter of which a person learned first.
- dozzie 11y agoNot quite. I learned map and filter much earlier, and still I use more list comprehensions, both in Python and in Erlang.
- m_mueller 11y ago> It may just be a matter of which a person learned first. I think this is the case, for me map is much harder to read. But I also think that comprehensions go back to math sets, so I was familiar with this even before learning any programming. Therefore comprehensions clicked immediately for me and it's by far my favourite python feature.
- zepolud 11y agoFunny how things turned out. I still remember this post[1], it was profoundly disappointing to see Guido's way of thinking. Much of the damage was reversed but it still left an indelible impression that there's a lack of vision for what's going to be important if the language is to stay relevant in the future. [1] http://www.artima.com/weblogs/viewpost.jsp?thread=98196 http://www.artima.com/weblogs/viewpost.jsp?thread=98196
- mewwts 11y agoI actually find his arguments rather convincing, even though I'm partial to a functional approach to programming, myself.
- tarmil 11y agoSome are still pretty bullshit though. > Why drop lambda? Most Python users are unfamiliar with Lisp or Scheme, so the name is confusing To which I'd reply: Why drop class? Most Python users are unfamiliar with C++ or Java, so the name is confusing.
- JustSomeNobody 11y agoAre they? I'd probably argue just the opposite, that most python developers are very familiar with C++ or (most of them) Java.
- svisser 11y agoRemoving features does not mean there is a lack of vision. The purpose of Python is not the same as, say, Haskell. Design decisions should therefore be viewed as such - it's not about a steady increase of functional features and a decrease of procedural features.
- currysausage 11y agoThere should be one -- and preferably only one -- obvious way to do it. [1] You may not agree with it, but it's a vision. [1] https://www.python.org/dev/peps/pep-0020/ https://www.python.org/dev/peps/pep-0020/
- deleted 11y ago[deleted]
- fuzzythinker 11y agoUse mochi if you really want to use FP in python. https://github.com/i2y/mochi https://github.com/i2y/mochi
- Scramblejams 11y agoInteresting, thanks for the link. Do you know if it has any multicore (i.e. parallel) support? I looked but all I could see was support for concurrency.
- fuzzythinker 11y agoFor parallel programming, you need either: https://docs.python.org/dev/library/multiprocessing.html#module-multiprocessing.pool https://docs.python.org/dev/library/multiprocessing.html#mod... or http://www.parallelpython.com/ http://www.parallelpython.com/ or use the GPU using many available libraries.
- deleted 11y ago[deleted]
- agentultra 11y agoNice, short little book! `compose` can be simpler: def compose(fn, *fns): def _composer(f, g): return lambda *args: f(g(*args)) return reduce(_composer, fns, fn) This little function is really, really cool because it allows you to build up more interesting functions by piecing together a bunch of small, useful ones. def upper(s): return s.upper() def exclaim(s): return s + '!' # instead of this really_angry = lambda s: exclaim(exclaim(upper(s))) really_angry('napster bad') # NAPSTER BAD!! # we can do this really_angry = compose(upper, exclaim, exclaim) really_angry('fire good') # FIRE GOOD!! # and import operator as op from functools import partial as p max(map(compose(p(op.add, 1), p(op.mul, 3)), (1, 2, 3, 4))) `compose` is a neat function and worth exploring. This is a cool book and I always hope Python gets more light shone on its FP-friendly features.
- hajile 11y agoFor compose to really shine, you need to be able to curry/partially apply functions. This part of things is made much more difficult than necessary because of Python's unnecessarily neutered lambda syntax (in fact, I don't think one can claim that Python is FP friendly until this decision is corrected). It's also worth noting that reduce() was removed as a builtin for Python 3.
- nine_k 11y agoI'd love let-like syntax in lambdas, something along the lines of lambda x: f(y) + g(y) for y = expensive_computation(x) In Python 3, `reduce` can be trivially imported from `functools`.
- gamegoblin 11y agoThe ugly hack around this would be lambda x: (lambda y: f(y) + g(y))(expensive_computation(x))
- gamegoblin 11y agoIt's possible to hack currying into python with a decorator like: https://gist.github.com/grantslatton/9221084 https://gist.github.com/grantslatton/9221084 (I made this for fun, use at your own risk)
- melling 11y agoIt's becoming more common to see "Functional Programming in X". Why don't we use functional languages like oCaml or Haskell more often? Are we making the jump in two steps instead of one? I've never written more than a few lines of either so I can't tell if something "better" is waiting for me in functional land.
- SirensOfTitan 11y agoProbably because its easier to see the use of functional paradigms in languages you're familiar with. OCaml and Haskell are great languages, but they require a lot of new learning at once.
- truncate 11y agoYou are right about it being nice to see functional code in your language. However, from my learning experience I understood the functional style much better by using actual functional language. I started with Scheme which has very minimal easy to understand syntax. Many courses ask students to try forget whatever they know about programming before introducing functional style. If that helps (for me it did), I think starting with new language would be nice decision.
- pekk 11y agoThere are many steps between functional programming in, say, Python, and writing everything in Haskell. Many differences. Not everybody has the same opinion of all those differences.
- amelius 11y agoI'm often missing a feature to make language X act in a purely functional way (i.e., to disable side effects completely in a relevant part of the code). Also missing is a way to select between strict or lazy evaluation.
- jimbokun 11y agoI made this comment earlier today about Elixir being more approachable for people coming from another dynamic language: https://news.ycombinator.com/item?id=9942407 https://news.ycombinator.com/item?id=9942407
- stared 11y agoI am curious why lists do not have ".map" and ".filter" methods? IMHO it would be so better for chaining, now using a few maps and filters is inconvenient and looks unreadable. Plus, something shorter for "lambda"... It's one of not too man aspects, where I prefer JavaScript (especially ES6) to Python.
- icebraining 11y agoThat would require any new container classes to implement each of those methods again (and will probably still lack useful ones, like groupby) whereas currently they can just implement iteration and get the rest for free. You could have both approaches, but that would go against one of Python's core principles ("There should be one-- and preferably only one --obvious way to do it.").
- zkanda 11y agoFP Library in Python: https://github.com/kachayev/fn.py https://github.com/kachayev/fn.py
- TazeTSchnitzel 11y agoFunctional programming? In a language with no tail calls and no function expressions? I mean sure, you can do it, but you'd have an easier time in a language which supports those.
- JustSomeNobody 11y agoMostly OT, but I like the short form books oreilly and packt are producing. I never liked the trend in technical books where every single one had to have 6 chapters of language tutorial, etc.
- Juha 11y agoFor anyone wanting a quick intro to fp in Python I stumbled into this awesome presentation (50 slides) about Functional Programming in Python. I especially like his short but clear examples: http://kachayev.github.io/talks/uapycon2012/#/ http://kachayev.github.io/talks/uapycon2012/#/ . Good intro before getting deeper into the linked book.