4 ms·
I find that the more language you learn the better you can utilize all of them. Also, Python is a wonderful functional language when used functionally.
by ok_dad 3y ago
I find that the more language you learn the better you can utilize all of them.
Also, Python is a wonderful functional language when used functionally.
- agumonkey 3y agoIt really is a strong lesson. Every language will shift and twist your mind and expand your horizon. You might hate your colleagues then though.
- heavyset_go 3y agoPython's lack of multi-line anonymous functions is a hindrance to using it as a functional language, IMO.
- dragonwriter 3y agoMost functional languages don't have statements at all, and Python's anonymous functions can, as most, handle any single expression, regardless of complexity or size. Python having a statement heavy syntax and making complex expressions (while possible) awkward is the problem with its anonymous functions, not the fact that its anonymous functions are limited to a single expression.
- heavyset_go 3y agoDefinitely, I'm looking at this from a superficial level of writing functional programming inspired code in imperative languages. JS makes this a bit more comfortable with its style of anonymous functions.
- nomel 3y agoI take the Beyonce approach to functions: if you like it you should have put a name on it.
- heavyset_go 3y agoI generally agree with this rule, but there are rare occasions where it can get awkward if you're passing functions around, like with callbacks.
- chriswarbo 3y agoMulti-line lambdas are fine: Python will accept newlines in certain parts of an expression, and you can use '\' for others; e.g. f = lambda x: [ x + y for y in range(x) if y % 2 == 0 ] >>> f(5) [5, 7, 9] Lambdas which perform multiple sequential steps are fine, since we can use tuples to evaluate expressions in order; e.g. from sys import stdout g = lambda x: ( stdout.write("Given {0}\n".format(repr(x))), x.append(42), stdout.write("Mutated to {0}\n".format(repr(x))), len(x) )[-1] >>> my_list = [1, 2, 3] >>> new_len = g(my_list) Given [1, 2, 3] Mutated to [1, 2, 3, 42] >>> new_len 4 >>> my_list [1, 2, 3, 42] The problem is that many things in Python require statements, and lambdas cannot contain any; not even one. For example, all of the following are single lines: >>> throw = lambda e: raise e File "<stdin>", line 1 throw = lambda e: raise e ^^^^^ SyntaxError: invalid syntax >>> identity = lambda x: return x File "<stdin>", line 1 identity = lambda x: return x ^^^^^^ SyntaxError: invalid syntax >>> abs = lambda n: -1 * (n if n < 0 else return n) File "<stdin>", line 1 abs = lambda n: -1 * (n if n < 0 else return n) ^^^^^^ SyntaxError: invalid syntax >>> repeat = lambda f, n: for _ in range(n): f() File "<stdin>", line 1 repeat = lambda f, n: for _ in range(n): f() ^^^ SyntaxError: invalid syntax >>> set_key = lambda d, k, v: d[k] = v File "<stdin>", line 1 set_key = lambda d, k, v: d[k] = v ^^^^^^^^^^^^^^^^^^^^ SyntaxError: cannot assign to lambda >>> set_key = lambda d, k, v: (d[k] = v) File "<stdin>", line 1 set_key = lambda d, k, v: (d[k] = v) ^^^^ SyntaxError: cannot assign to subscript here. Maybe you meant '==' instead of '='?
- mixmastamyk 3y agoNeat. I tried it with print(), works fine. Don't need return in a lambda. Assignment now has the walrus. Leaves raise and few other odds and ends. Do believe you've cracked it! Don't think I'll use it much, but you never know... in a pinch.
- chriswarbo 3y agoAh yes, I've been doing this with stdout.write since Python 2; it didn't occur to me that when Python 3 turned print into a function that would make it usable in lambdas! You're right that the walrus makes assignment more usable; we can also call methods like .__setitem__ to get similar effects. Unfortunately the walrus seems to suffer the same broken/ambiguous scoping as assignment statements, e.g. >>> a = 1 >>> b = lambda: (print(a), a := 2) >>> b() Traceback (most recent call last): File "<stdin>", line 1, in <module> File "<stdin>", line 1, in <lambda> UnboundLocalError: cannot access local variable 'a' where it is not associated with a value > Don't need return in a lambda `return` is needed for early returns. Notice that my `abs` example is trying to do that with `return n` (to skip the `-1 *` operation, since `n` is non-negative in that case). > Leaves raise and a few other odds and ends Off the top of my head: yield, match, def, import, class, with, for, while, assert, try, except, async, await.
- nbelaf 3y agoIt is a poor functional language. List comprehensions (from Haskell) are nice, but the rest is garbage. Crippled lambdas, no currying, "match" is a clumsy statement, weird name spaces and a rigid whitespace syntax. No real immutability.
- dekhn 3y agofunctools.partial is currying, right?
- vore 3y agoNo, it’s partial application. Currying is when a 1-arity function either returns another 1-arity function or the result.
- dekhn 3y agohmm... that just sounds like a specific case of recursive application of partial functions? At least that's how I interepret the wikipedia explanation: "As such, curry is more suitably defined as an operation which, in many theoretical cases, is often applied recursively, but which is theoretically indistinguishable (when considered as an operation) from a partial application." (while I see partial as having value, I'm struggling to see if currying would really be a useful addition to a scripting language)
- bloaf 3y agoI use the toolz package for currying and a few other conveniences. That plus named tuples and a little discipline gets me 80+% of the benefits of pure functional. The biggest thing to me wasn't in your list: lack of tail call optimization means you have to be a bit careful about where you use recursion. I personally think long anonymous functions are an anti-pattern, naming your functionality is great for readability. I learned this from Wolfram language which makes heavy use of anonymous functions, I would often find myself returning from lunch to find my code which was perfectly clear that morning had become unintelligible. Today I try to limit anonymous functions to re-ordering arguments or "picking" functions that pull simple values out of more complicated data structures.