5 ms·
Actually, a lambda expression is never a closure, though it can evaluate to a closure. Confusing lambda expressions with closures is like confusing the string
by ScottBurson 11y ago
Actually, a lambda expression is never a closure, though it can evaluate to a closure.
Confusing lambda expressions with closures is like confusing the string "new Foo()" with the object it constructs. In each case, the former is a syntactic entity, the latter an implementation construct.
- kough 11y agoOk, sure, the author means "result of compiling a lambda expression". I think it's reasonable phrasing given that this is describing compiler transformations pre-interpretation rather than interpreter behavior.
- ScottBurson 11y agoMy quibble is not really with the author, who knows what he's talking about. But I've seen lots of people using "closure" as if it were something in the source code.
- ajuc 11y agoIs this an array? int xs[10]; Is this a function? int f(int x) { return 2*x; } I think it's overly pedantic to require people to say "function defined by this code".
- ScottBurson 11y agoTo a language implementor, these distinctions are not pedantic at all. A declaration of an array is a thing with a type, a name, and a size, each of which we have to pay attention to. It's really nothing like a sequence of consecutive locations in memory. To a language user, certainly, such distinctions usually don't matter. But conflating "lambda expression" and "closure" is particularly problematic. On the one hand, as this article points out, not all lambda expressions are evaluated by constructing closures. On the other, it's certainly not the case that all closures come from lambda expressions -- in many languages (certainly Scheme, Common Lisp, JavaScript, and Python, and I think Ruby and PHP) you can perfectly well create a closure from a named function; it's done all the time. Here's an example in Python: def f(a): def g(b): return a + b return g See? f returns a closure, but there's no lambda expression in the code. So given that lambda expressions and closures, though related, are not in 1-to-1 correspondence, I think it's important to understand the distinction.
- bandrami 11y agoEven passing over that, it's only a closure if it keeps a lexical environment. (lambda (x) (+ x 1)) doesn't close over anything, so it's not a closure, nor does it evaluate to one. For that matter, (let ((x 0)) (lambda (x) (+ x 1))) isn't really a closure in any sense because the environment can be inlined out.
- agumonkey 11y agoI call them free closures.
- waldrews 11y agoDoesn't (lambda (x) (+ x 1)) capture +? You could evaluate (lambda (x) (+ x 1)) in a scope of, say, (let ((+ *)) (lambda (x) (+ x 1))) - in some lisps.
- bandrami 11y agoAh, I guess in Scheme it does (I use Common Lisp, where the two namespaces are different). But even then you would need the actual environment there for it to be a closure. The lambda expression is only half of a closure. It's "let over lambda" that is a closure.
- recursive 11y agoMaybe it's just me, but that is just linguistic shorthand. Arguing that point sounds like saying "No, I didn't take the train. I rode on the train."
- PeCaN 11y agoThere's a subtle but important difference. They're not necessarily tied to each other anyway. For example in Python you frequently have lots of named functions that capture some variables in an outer scope, and are closures but not lambdas.
- recursive 11y agoYes. You can do the same thing in javascript. But it's pointless to say that "the source code that, when evaluated, creates a named function, is itself not a function" is just pointless lawyerism.
- adwf 11y agoPointless until you start dealing with macros. It can be important in some cases to know whether the closure "code" has been evaluated at that point or not.