Hacker News new | ask | show | jobs
by sillysaurus3 3724 days ago
It's not really limited. You just have to name your lambda before you use it.

  def make_adder(n):
    def f(a):
      return n + a
    return f
Using this style, you can make the inner function as complicated as you want. You can have statements, or anything else.
3 comments

Lambdas are anonymous functions so an inner def is not the same thing. The fact that you have to "adapt" Python to get non-crippled lambdas suggests it should have been the last choice for teaching a text like SICP.
The reason lambdas are powerful -- one of the only reasons -- is because it's a closure. The fact that you can reference variables outside of the function is the power, not whether it has a name. A label is just a convenience. (Or in this case, an inconvenience.)

If my understanding is flawed, I'd like it to be corrected, though.

Higher-order functions (funargs) do not equal first-class functions (lambdas). It happens to be that any language which supports first-class function must also support higher-order functions, but the reverse is not necessarily true.
That does not match my understanding of first class functions, nor Wikipedia's.[1] Python's inner defs are not anonymous functions (which is what people usually mean by lambdas) but they are definitely first class - they can be returned from a function, stored in a data structure and so on. I agree with the grandparent that the need to label the closure is just an inconvenience, not a disqualification.

You can't have anonymous lambdas that aren't first class (how would you reference them?) but you can have first class functions that are not technically anonymous.

[1]https://en.m.wikipedia.org/wiki/First-class_function

From TFWikipedia: "Some programming language theorists require support for anonymous functions (function literals) as well."

I suppose I wasn't aware that that wasn't a universal requirement, but count me in with that group. I think it's useful to make a distinction between "higher-order" and "first-class" for this very reason (i.e., we can talk about languages that do make a distinction without resorting to overloaded terms).

I mean, consider a language where this is the case:

  > "hello," .. " world"
  ==> "hello, world"

  > 2 + 2
  ==> SYNTAX ERROR

  > def a = 2
  ==> #<number "a">

  > a + a
  ==> 4
Would you consider such a language to have first-class integers?

Sort of on a tangent, but while I'm reminded of it: as far as Python's "lambdas" go, they're brutally gimped compared to Python's notion of a function, since what is allowed (and even required) of a function body in Python is much different than what is allowed of a "lambda" body.

> Would you consider such a language to have first-class integers?

Yes, I still would, because integers can be bound to variables, passed to and returned from functions, and stored in fields of objects.

I would think that the language had a silly syntactic restriction -- which is the same thing I think about Python -- but it wouldn't materially change how I would write programs. It's just that, before any expression using an integer literal, I would have to name the literal.

Well, same here. If you want to use a function too complicated to fit in Python's restricted lambda expression syntax, you have to use a named local function. I agree that it's silly, and I'd never design a language like that myself, but again it wouldn't materially change how I write programs -- it just means that what would have fit in one expression would now, in some cases, require multiple statements.

Trying to draw a fine distinction between "higher-order" and "supporting first-class functions" doesn't appeal to me; I think of the latter as the definition of the former. (I'm sure I would have trouble remembering which was supposed to be which.)

But again, I have no problem with criticizing the design decision -- just not using these terms :-)

It's no secret that Guido has a little bit of a distaste for functional paradigms. From the man himself:

"About 12 years ago, Python aquired lambda, reduce(), filter() and map(), courtesy of (I believe) a Lisp hacker who missed them and submitted working patches. But, despite of the PR value, I think these features should be cut from Python 3000."

http://www.artima.com/weblogs/viewpost.jsp?thread=98196

Are lists comprehensions (the proposed alternative) less "functional" than map/reduce/filter?
It's not technically a lambda at that point. By definition, lambda expressions are anonymous functions.
The point is that it gets the job done. Being able to omit a function name doesn't add any more power to a language; it's just syntactic sugar.