Type checking mainly starts pulling its weight in large codebases, or otherwise in long-lived and large programs maintained by rotating groups of people over long periods.
1. no multiline lambda function? - breaks flow of writing fp code
2. default-arguments are 'shared' by default? - have to 'break' this sharing by assigning 'None'... - very unintuitive / I don't know any language that does this...
Anyway, not everything in python is 'pragmatic', and adding types is one of the first steps in going in the right direction.
sort(items, key=lambda x: x.size)
but really anything much bigger should have a name stamped on it dammit. I find JS largely unintelligible due to lambda overuse and nesting.seems you're confused between "limitation" and "feature"...
it's a limitation due to python's "no-braces/indentations-only" policy -- can't think of a way to mark where a lambda starts and ends clearly and cleanly with indentation-only...
Python prefers different tools (comprehensions) to accomplish most of the same goals.
In Rust it's difficult to mess with memory: it's a limitation but also a feature. In Haskell you cannot mutate, a limitation if there ever was one, but also a feature.
for rust, it counts as a 'feature' because it provides safety guarantee, and they're opt-in (can use unsafe)
as for haskell, that immutability also provides guarantee of 'referential-transparency', which the users/libraries can use to their advantange.
But in python's case, you have to define the multi-line function *outside* the chaining, and 'forcing to name things' isn't always good (especially for constantly-changing code)
def hideEmail(user): return { ...user, email: user.hideEmail? '': user.email, }
users.map(hideEmail)
// later: def hideEmailAndPhone(user): return { ...user, email: user.hideEmail? '': user.email, phoneNo: ... // same stuff }
users.map(hideEmailAndPhone) ---
As for JS/TS, you can have 'named-callback-fn':
users.map(function hidePrivateFields(user) { ... })
and it's not difficult to come up with 'named-lambda-fn' standard
users.map(hidePrivateFields(user) => { ... })
(lamada x:
(x+x)
/x)(n)
Will work, though in Python I usually just create an outside function and pass that in.But yes, not everything in Python is nice for working with fp code. Using tuples, coming from Clojure, is painful. Things like returning exceptions for `StopIteration`is annoying. Mutability of lists outside of a lexical scope without using deepcopy. Though functools and itertools makes it more bearable.
But I also don't think types is the answer. I think something like Racket's contracts or Clojure's spec is closer to what I'd prefer. Gradual typing is nice though.
(
lambda x:
x
+
x
)(5)