11 ms·
Guido was right, there should be no lambda in Python (2018)
- saagarjha 4y agoIt seems to me that the author understands what lambdas are used for and why they don’t really act as lambdas. Still, they’re useful, so it seems like the actual point is that the keyword just exists to punish people who use it with syntactic overhead.
- erwinh 4y agoCurious what did more to reframe the lambda keyword into a generic term for simple functions, AWS lambda or python lambda
- heavyset_go 4y agoI think the colloquial usage has roots in Python's use of it, I've been hearing about anonymous functions being called lambdas for a long time. The Lambda service's name seems to play on that prior colloquial usage.
- richardxia 4y agoScheme has the lambda special form, predating Python by decades, and its version also allows for multiple parameters in a non-curried way. SICP served as a classical textbook in computer science for multiple generations of students, so I think that a lot of people's first introduction to lambdas as anonymous functions came from Scheme: https://sarabander.github.io/sicp/html/1_002e3.xhtml#g_t1_002e3_002e2 https://sarabander.github.io/sicp/html/1_002e3.xhtml#g_t1_00...
- Snarwin 4y agoAnd the use of the LAMBDA keyword goes all the way back to John McCarthy's original paper on Lisp from 1960: https://archive.org/details/recursive-functions-symbolic-expressions/page/n5/mode/2up https://archive.org/details/recursive-functions-symbolic-exp...
- erwinh 4y agoWow wasn't aware of this long history. My hot take for which I'm sure I'll get some hate is all languages should just include js-style arrow functions
- Jtsummers 4y agoProbably little hate, it's a long existing style. Haskell, Erlang, the entire ML line of languages, and probably many more have all used it since last century. It came from mathematical notation, and it is concise.
- stormbrew 4y agoAside from the scheme example in the sibling reply, ruby has had a lambda, as a special kind of proc, for a very very long time and it is similarly not a "real lambda." Honestly it's likely that for most of the history of the term it's been more used for "incorrect" meanings than "correct" ones.
- nicoburns 4y agoI wish python would support multi line lambdas. Having to define a separate function often makes thing considerably less readable in my experience.
- version_five 4y agoSee below. Not very satisfying, but a lot of though has gone on around it: https://stackoverflow.com/questions/1233448/no-multiline-lambda-in-python-why-not https://stackoverflow.com/questions/1233448/no-multiline-lam...
- nopenopenopeno 4y agoPython supports multi-line lambdas (use parentheses). However, it does not support lambda functions. Python lambdas can only be expressions.
- epx 4y agoI am not fan of Ruby but this is a thing that Ruby nailed on (blocks).
- dragonwriter 4y ago> I wish python would support multi line lambdas It does, it just doesn’t support statements (not even one) in lambdas, since a lambda (however many lines it takes up) contains a single expression.
- raymondh 4y agoIt does. Just add parentheses.
- sublinear 4y ago"there should be no lambda in Python" According to this blog post there isn't, and yet there is? I'm more confused by the way this was written than Python's implementation of the "lambda" keyword.
- akprasad 4y agoMy paraphrase: There should be no lambda keyword in Python because the lambda keyword implies idiomatic support for lambda calculus, which Python does not have. (I infer that the author supports renaming the keyword to something like inline instead.)
- kllrnohj 4y agoThe author says as much in the post. There's some discussion of inline towards the end.
- thrown_22 4y agoThe original lambda calculus also didn't have implicit currying for multi-variable functions. If you wanted to curry a function you had to write out λx.λy.λz. x (y z) If you wrote the much more user friendly λ x y z . x (y z) And tried currying it then it would fail. The author is complaining that Python doesn't use a dialect of lambda functions used in Haskell. Which is true. Python isn't Haskell and shouldn't be.
- Arnavion 4y agoClickbait title. Author wants Python to have lambdas. They just want them to not be called lambdas because they don't support currying and are niche compared to lambdas in functional languages.
- toomim 4y ago
- recursive 4y agoGender doesn't really add anything material to this conversation. This is useless nit-picking.
- Godel_unicode 4y ago
- recursive 4y agoWho's we? You and me? Some people care, some people don't.
- HelloNurse 4y ago> datetime.date(2018, 3, 4) > datetime.date(2018)(3)(4) It's very obvious that the first of these date() function must be a function of three arguments (year, month, day) and the second, if the two calls are meant to return the same result, must be a function of one argument (year) that returns a function of one argument (month) that returns a function of one argument (day) that returns, presumably, a date. Syntactic sugar to call one date() as if it was the completely different other one would be recklessly dangerous. In particular, there are default parameters: date(1848) might legitimately mean something like 1/1/1848 (defaulting day and month to 1 and 1), not "give me a curried factory of dates in 1848".
- tantalor 4y ago> In Python our functions are not curried Sure you can do that... def add(a, b): return a + b incr = lambda b: add(1, b) # like incr = l_add 1 incr(3) # ouputs 4 Is this whole article a complaint that Python isn't Haskell? What is the point?
- green_on_black 4y agoThe point is we should start the 3to5 migration earlier (Haskell is just a codename).
- memco 4y agoThere’s also functools.partial as another option. incr = partial(add, 1) incr(3)
- quietbritishjim 4y agoBoth you and the parent comment have mistook partial function application for currying. Partial function application: incr = partial(add, 1) # or def incr(x): return add(x, 1) z = incr(4) (Side note: parent comment made a classic mistake, you shouldn't use a lambda if you're just going to assign it to a local variable, you should use a nested function definition.) Currying is function that returns a function: def curried_add(x): def inner(y): return add(x, y) return inner z = curried_add(1)(4)
- Izkata 4y agoOn top of that I figured the article meant automatic currying.
- tantalor 4y agoNo, not going to do any of that.
- memco 4y agoIn my defense, I did not say partial is currying, just that it is an alternative to a lambda in Python. I agree with your points, and with Izkata that the more relevant nuance is not that Python cannot curry, but that it doesn't do currying as fluently as Haskell, which I think was GP's point about the article. The crux of the article seems to have very little support for the argument of the title that lambdas shouldn't be in Python, but instead only seeks to make clear that "we do not use lambda with the intention of using lambda calculus." It's strongest contribution is to suggest that inline anonymous functions would be a helpful addition to the addition for Python to be able to do lambda calculus.
- shrimpx 4y agoThe author makes a bunch of tenuous assumptions; that lambda calculus is all about currying; and that the “lambda” keyword brings lambda calculus to Python; that lambda is undesirable because Python doesn’t have nice currying syntax. Anyway I think Guido hates lambda because it feels like an appendage in Python, due to list comprehensions and due to expression-only bodies, restriction which was put in place probably because passing multi-line nameless functions as arguments is awkward in a whitespace-sensitive language/it just didn’t feel Pythonic to Guido to be passing large inline functions to functions.
- p1necone 4y agoImo the whole whitespace sensitivity thing was a mistake to begin with. It makes code harder to read, harder to write and harder to parse with only the benefit of being a little easier to understand to absolute beginners (and I'm not even sure about that last one).
- gleenn 4y agoAnd harder to copy-paste!
- thaumasiotes 4y agoTechnically, it has the benefit that code cannot be incorrectly indented - it can't be formatted to look like the scope is one way when in reality it's another way.
- kimmeld 4y agoCode can absolutely be incorrectly indented in python and to make matters worse it changes the functionality of the code when it is.
- thaumasiotes 4y agoCode can be indented in a way you didn't mean for it to be. But it cannot be incorrectly indented in the sense I just described, because the indentation changes the functionality of the code. The indentation can never mislead you about the structure of the code.
- ColFrancis 4y ago> l_add needs the arguments passed one at a time. We never see this syntax with multiple parenthesis in Python. It works and it has many benefits built in, but it would be a paradigm shift to expect pythonistas to start writing their programs this way, it’s just not Pythonic. He makes a big point about currying in his particular manner, but what's wrong with f = lambda x,y: x+y g = lambda y: f(3,y) That's also currying right? I've always been a little confused as to why the style he advocates is necessarily better. I'm not a functional guy so I'm maybe I'm missing something, what is the benefit of syntactic sugar for partial application to the first (or last) argument of a function? What if I want partial application of a function with the middle argument specified? Now you're out of luck and have to do the above anyway. ETA: on the main point > In Python, we do not use lambda with the intention of using lambda calculus. Our syntax needs to encode our intention in the places we have used it, and where we will use it. These use cases are inline, anonymous functions. That seems needlessly nitpicking. Wikipedia has "lambda function" as a synonym for anonymous function so it seems pretty widespread in our language at this point. https://en.wikipedia.org/wiki/Anonymous_function https://en.wikipedia.org/wiki/Anonymous_function
- Jtsummers 4y agoNot quite, that is partial application. Actual currying would allow you to do partial application this way, making it less explicit: > g = f(3) # no second parameter provided g = <unary function> # however it would be indicated in the python shell To get it in Python you'd need to do this: f = lambda x: lambda y: x + y g = f(3) # result is a function, or funcallable, or whatever Python calls the resultant type This makes the currying explicit. In general, currying is taking an n-ary function and reducing it to a series of n unary functions. These three are equivalent, in Haskell(ish, rusty): f x y = x + y g x = \y -> x + y h = \x -> \y -> x + y In Haskell, you don't have to use the explicit form of `h` (or the explicit form in the Python example) if you don't want to (and it would probably be weird if you used it extensively).
- thaumasiotes 4y ago> Actual currying would allow you to do partial application this way, making it less explicit > To get it in Python you'd need to do this: > f = lambda x: lambda y: x + y > This makes the currying explicit. In general, currying is taking an n-ary function and reducing it to a series of n unary functions. Something's gone wrong; your example of explicit currying conflicts with your definition of currying. `f` is a unary function.
- andrewstuart 4y agoLambda has to be the least intuitive part of Python. even the name of it "Lambda" makes it sound like some deep computer science complex thing, inaccessible to beginners. In JavaScript I constantly use anonymous functions everywhere and they are easy to understand and use. The same concept in Python is clunky, hard to understand and definitely not easy to use. JavaScript absolutely trounces Python when it comes to compact, minimal, highly expressive anonymous functions. JavaScripts arrow functions are so elegant and so compact and so effective that they completely change the way I program JavaScript. No such equivalent exists in Python.
- sirk390 4y agolambdas are very useful for example for sorting data using a key function. Maybe the auther is saying that it should be called differently, or have a different syntax and the title is just clickbait.
- thoweiruo2343 4y agotldr; 'etymology/provenance' is not inline with current use; hence don't use. rather silly tbh. you'd have to stop using most words in english (let alone entire systems plagiarized from other cultures) if you take such a stance. as for the debate, actually, one could argue python would benefit greatly by going the other direction: make multi-line definitions of lambda possible (ala all the lisps).
- danuker 4y agoShameless plug: use `fn` in Hy. https://docs.hylang.org/en/stable/api.html#fn https://docs.hylang.org/en/stable/api.html#fn Still no currying, though. But an anonymous function can be `fn` instead of `lambda`.
- yazzku 4y ago"however there is nothing that lambda can do that can’t be done with the usual def foo(args, kwargs): ... syntax" Defining a function inline with no name?
- z9znz 4y agoNo offense to people who are good people and put in great effort, but that alone does not mean one is infallible. Python is a very poorly designed language, and when I would sometimes dig to find out why things here how they were, Guido was behind many of the decisions which I believe were bad.
- ironSkillet 4y agoPython is a very poorly designed language...from your perspective...for a subset of tasks that you deem to have higher importance than others. I'm definitely not saying python is anywhere near perfect, and yes it certainly has design flaws (as does any complex system). But obviously it's done a lot of things right to gain the reach that it has.
- kimmeld 4y agoBeing actively updated and maintained when Perl wasn’t helped Python dramatically.
- z9znz 4y ago> But obviously it's done a lot of things right to gain the reach that it has. Indeed it has. It is a very accessible (and even moreso "available") language. But it has so many odd (and frankly wrong) peculiarities that big projects tend to become more difficult more quickly because of the mess that is most Python code. Some of the footguns are so rediculous that you cannot believe they exist; and even more astounding is the apologist arguments for why they should be the way they are. This one is my favorite: https://stackoverflow.com/questions/1132941/least-astonishment-and-the-mutable-default-argument https://stackoverflow.com/questions/1132941/least-astonishme... Since it is so accessible and has such a rich ecosystem, someone with little skill can cobble together a system which works well enough to get to production. But that junior developer pay rate cost (and ease of hiring) will mean that as the project matures and more and more features are added, the code more rapidly becomes incomprehensible. Everything being mutable, no types (except for bolted on, visually noisy, non-runtime linters), OOP missing some of the key information hiding features, awkward or half-baked functional features, and time/space performance problems all combine to make Python a terrible choice for non-prototype level projects.
- SeanLuke 4y agoI use lambda and closures (in Lisp), or awful approximation hacks of it (as one-element arrays of anonymous subclasses in Java) ALL THE TIME in graphical interfaces and many other contexts. Not once have I ever used lambdas for currying. In fact as a rule I yank out code I find using lambdas for that purpose as inevitably it can be done more readably with an iterator or for-loop. But I agree that there should be no lambdas in Python-- but just Python -- because Python's enforced indendentation syntax rules are so hostile to those multi-statement lambdas and closures which are absolutely trivial in a language like Lisp. The hobbled lambdas that remain are, well, basically gunk for currying.
- kjeetgill 4y ago> as one-element arrays of anonymous subclasses in Java. When's the last time you used Java? I remember having to use anonymous classes but we've had lambdas for a good 8 years now? Or is it that you don't like how lambdas "fullfil" a SAM interface instead of having a true Function representation. If it's the latter, I'm sincerely very curious what we're missing out on since I'm mostly used to it.
- SeanLuke 4y agoJust last night I put out the latest versions of two open source tools totaling about 500K lines in Java. Sure I enforce an old style but I think I'm up to date with the latest in Java. It's funny how Java developers perceive "lambdas" as (param, param) -> { code } blocks to be used in consumers and iterators etc. This is a weird mutation of the general concept due to Java's lack of functions: as a Lisp developer I don't perceive lambda expressions like that at all. The use of lambda expressions is much more general than this: it's simply the creation of function pointers for many tasks. For me, nearly 100% of the time it's to create them to be stashed away as callbacks. And in Java, the only realistic way to do this still is with anonymous classes.
- kjeetgill 4y agoNot trying to be defensive or anything: do you have any examples? I'd love to take a peek at what patterns and designs Java's lambdas don't work well for.
- raymondh 4y agoPython's lambda is powerful enough to write a Y-combinator: https://twitter.com/raymondh/status/1352018456401440769 https://twitter.com/raymondh/status/1352018456401440769
- solidsnack9000 4y agoI think the author is right that the meaning of `lambda` in the Python is really `anonymous def` and could be more succinctly and simply explained without any reference to lambdas at all. The Lambda Calculus really is formally about single argument functions. Here is one of many good references for that: https://plato.stanford.edu/entries/lambda-calculus/ https://plato.stanford.edu/entries/lambda-calculus/ Hence, the multi-argument lambdas of Python are something of a contradiction in terms, or a kind of artistic license. Now that I think about it, I can't think of a good reason not to use `def` for the anonymous function syntax in Python: def (x, y, z...): <expr>
- thrown_22 4y ago>The Lambda Calculus really is formally about single argument functions. It needn't be: https://personal.utdallas.edu/~gupta/courses/apl/lambda.pdf https://personal.utdallas.edu/~gupta/courses/apl/lambda.pdf Currying is just an easy way to deal with multi-argument functions. You then need to add a bunch of syntactic sugar to avoid the issues the the author complains about here (something that Haskell has done). You could just as easily go the opposite route and add a bunch of different syntactic sugar and deal with multi-variable functions directly (as python does).
- overgard 4y agoLambdas are fine as is. They'd be better if there was an optional brace syntax to disambiguate scope (optional!) so you could do full functions. Never understood why that's a sticking point in the python community, you'd still have 99% whitespace based scoping, but with braces or begin/end if you need it. Feels like one of those decisions they just dug their heels in on as a matter of ideology rather than practicality. Also though, I kind of feel like currying/partial application is one of the most overhyped feature of all time. With lexical scoping and closures, the number of times I've needed it is: never. Admittedly I'm not using lisp or haskell every day, but I feel like most of the greatest features of those languages have been generally stolen where possible, and yet currying always seems like an afterthought.
- pharmakom 4y agoIf it were available it would be part of how libraries are designed and you would use it all the time.
- overgard 4y agoI mean, it essentially is available though, "from functools import partial". I just have never seen any examples other than the perfunctory useless math ones: mult_10 = partial(mult, 10) mult_10_20 = partial(mult_10, 20) print(mult_10_20(30)) The only context I can think of off the top of my head where currying might be useful is binding a "this" or "self" object, but, if I'm using a class I already get that. Maybe you could use it to pass through some set of context objects, but then, you could already do that by just creating a data structure to hold those objects.
- moleperson 4y agoEven if Python used the anonymous function syntax proposed, people would still call them "lambdas". If you want to have aa keyword for this, you might as well name it after what most people are going to type into Google when searching for it.
- rurban 4y agoNot necessarily. In Perl we called lambda "anonymous sub" for ages, and nobody mixed those up. We also use a handy keyword less syntax to generate, store and use such lambda's. Thus I'm on the "Worse is Better" side, python cannot write proper compilers and cannot decide on proper syntax. lambda: sub($x) {$x+1} decl sub{shift+1}(args) call or ruby-like: {shift+1}->list