4 ms·
Forgot one big con: Python lambda functions aren't "proper" functions (ie. arbitrary multi-line code blocks). Guido van Rossum has addressed this many times, s
by beambot 14y ago
Forgot 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 http://www.artima.com/weblogs/viewpost.jsp?thread=147358
This is one of my (very few!) gripes with FP in Python.
- jewbacca 14y agoI don't know if this is a problem if you're going hardcore with your FP -- one line is one expression, and multiple expressions are probably going to be stateful, which should probably be factored out into something with a name. In Haskell, the only places (that occur to me right now) where you'll have multiple lines are: * Pattern matching function arguments * Giving things names with `let` or `where` * In a monadic `do` block, which is just sugar that reduces to single-expression chain of lambdas And all of these are language design decisions that require more than just multi-statement lambdas.
- samdk 14y ago...or anywhere you're using a 'let' statement. I write a lot of OCaml, and I write a lot of multi-line anonymous functions that aren't stateful. I think it's less common to do this in Haskell, but that's more because it's Haskell than because there aren't any side effects. Random other tidbit that doesn't deserve its own comment: In Python, instance.method is the same as doing ClassName.method(instance). This can be helpful when using map/filter, because you get to do map(ClassName.method,lst) instead of map(lambda x: x.method,lst).
- koenigdavidmj 14y agoOr you can do operator.methodgetter("method") and not need to know the class name.
- ville 14y agooperator.methodcaller('method') #ftfy
- jewbacca 14y agoNOTE: Ooops, it seems the 'edit' window expired on my comment. Expanding, unfortunately, in a separate comment: ---- I don't know if this is a problem if you're going hardcore with your FP. When we're talking about "lines" in Python, one line is exactly one statement, and if you're doing FP, that statement is an expression. Multiple statements are going to be either stateful, or declaring a temporary name for an intermediate value. I am probably not being sufficiently imaginative right now, but I can't think of any fully-fledged functional pattern which would require multiple statements in a lambda, which would not be better abstracted out and given a name, and I would genuinely like to hear some examples of cases where a multi-statement lambda make for "better" code (or to hear how my presentation of this problem might be flawed, because I haven't done any serious Python programming recently enough to be very close to the issue). ---- In Haskell, a language where the syntax has been exhaustively designed to facilitate FP, the only places where you'll see multiple lines (I'm pretty sure this is exhaustive, without using GHC extensions, eg. Arrow `proc` blocks) are: * Pattern matching function arguments * Giving things names with `let` or `where` * In a monadic `do` block -- which is just sugar that reduces to single-expression chain of lambdas, and are not equivalent to multi-statement lambdas
- vsbuffalo 14y agoAnd you can't pass them as simple functions to do stuff via the multiprocessing module because they can't be pickled. I don't understand this infatuation with FP in Python. To me the essence of functional programming is immutable state. Python has mutable state to the core. List comprehensions are novel syntax for many FP-esque operations (so much so that map, reduce, & filter were almost removed from Python at some point) yet, to their core they're full of mutable-state disgustingness. For example: >>> a = range(12) >>> [a.pop(i) for i in range(3)] [0, 2, 4] >>> a [1, 3, 5, 6, 7, 8, 9, 10, 11] As long as list methods have methods that change state of the object, even when processing said object, Python handles FP at a very superficial syntactic level.
- icebraining 14y agoYou could always use tuples; they're essentially immutable lists. >>> a = tuple(3*x for x in range(5)) >>> a[2] 6 >>> map(lambda x: str(x), a) #can be iterated ['0', '3', '6', '9', '12'] >>> a[2] = 9 TypeError: 'tuple' object does not support item assignment >>> a.pop() AttributeError: 'tuple' object has no attribute 'pop'
- vsbuffalo 14y agoYea, but still gross. map() isn't even an endomorphism.
- omaranto 14y agoI'm not sure what you mean. map is not supposed to be an endomorphism, rather it takes a function f and returns a list homomorphism.
- haldean 14y agoI think it'd be nice if it were an endomorphism, though; Making map(f, tuple) -> tuple, map(f, list) -> list, etc. would save users from having to write tuple(map(f, tuple)) (which is something I've done a bunch).
- rat87 14y agoI fail to see how this makes them non-proper functions, a better way to put it is they are a subset of possible functions.
- beambot 14y agoYes, single-expression functions are a subset of all possible functions... but that's not exactly what I was getting at. I put "proper" in quotes just to signify that they have subtle differences that, from a purely type-based abstraction, are different from named functions. For example, you can't serialize (pickle) a lambda function.