5

I have found following definition at http://en.wikipedia.org/wiki/Closure_(computer_science)

In programming languages, a closure (also lexical closure or function closure) is a function or reference to a function together with a referencing environment—a table storing a reference to each of the non-local variables (also called free variables or upvalues) of that function.[1] A closure—unlike a plain function pointer—allows a function to access those non-local variables even when invoked outside of its immediate lexical scope.

is it true all occasions ? can't lambda functions (those creates a closure) keep refereeing to local variable that would be in out of scope when the lambda is called? isn't this is the behavior of GO?


PS: I am still wondering why they use "lambda" term

For this got the answer https://cstheory.stackexchange.com/questions/18443/lambda-term-usage-in-programming


Following post might find helpful for other readers,

What is the difference between a 'closure' and a 'lambda'?

Community
  • 1
  • 1
nish1013
  • 3,658
  • 8
  • 33
  • 46
  • 1
    Technically, lambdas don't capture any context. Closures "enclose" (hence their name) the *surrounding context* or part of it which is also called their *environment* in your quote. But they are sometimes used interchangeably. For examples, C++11 lambdas are technically closures as soon as they capture some context. (However I don't know anything about GO lambdas) – leemes Jul 24 '13 at 09:49
  • 2
    You might find this question interesting: http://stackoverflow.com/q/220658/592323 – leemes Jul 24 '13 at 09:52
  • @leemes sorry wording wasn't right . Just edited the question. – nish1013 Jul 24 '13 at 09:52
  • I don't get the real question. Do you ask if you can capture local variables and call the lambda *after* they become invalid, i.e. when the surrounding scope is left? In C++11, this is undefined behavior (dereferencing references to variables which are already "dead"). You can however capture *by value* (the variable values are copied into the closure, so there is no dereferencing taking place). Again, don't know about GO. – leemes Jul 24 '13 at 09:55
  • You may also find my article on closures helpful: http://mortoray.com/2012/10/24/what-is-a-closure/ – edA-qa mort-ora-y Jul 24 '13 at 09:58
  • My question is regarding Go , whether it allows to refer to reference type local variables from a closure ? and if so why such inconsistency among languages as C++ not allowing it for an e.g. – nish1013 Jul 24 '13 at 10:01
  • I found sth which might answer this question. http://livingcode.org/entries/2009-11-13_go-language-and-functional-programming/ Read the part right after the code. – leemes Jul 24 '13 at 10:02
  • Ah, you might have understood that wrong... From your quote: "... access those non-local variables ..." They mean non-local to the *closure itself* (since a closure is a function it can have its own local variables). So they mean any *captured* variables. These can still be local in the *surrounding* function. – leemes Jul 24 '13 at 10:07
  • :) oh I see, how could accept above comment as the answer? – nish1013 Jul 24 '13 at 10:12
  • Also see [does-go-have-lambda-expressions-or-anything-similiar](http://stackoverflow.com/questions/11766320/does-go-have-lambda-expressions-or-anything-similiar) – nawfal Jul 05 '14 at 15:29

1 Answers1

7

Quoting the Go language specification:

Function literals

A function literal represents an anonymous function.

FunctionLit = "func" Function .
func(a, b int, z float64) bool { return a*b < int(z) }

A function literal can be assigned to a variable or invoked directly.

f := func(x, y int) int { return x + y }
func(ch chan int) { ch <- ACK }(replyChan)

Function literals are closures: they may refer to variables defined in a surrounding function. Those variables are then shared between the surrounding function and the function literal, and they survive as long as they are accessible.

So yes, in Go the closure is guaranteed to have access to any variable visible in the scope where the function literal was defined. The Go compiler recognizes variables "captured" in a scope and forces them to the heap instead of the defining context stack (if any - there can be also TLD [top level declaration] closures).

Community
  • 1
  • 1
zzzz
  • 87,403
  • 16
  • 175
  • 139
  • AFAIK, in C++: Accessing memory where local variables used to be _after_ the function exits is undefined behavior. – zzzz Jul 24 '13 at 10:32
  • @jnml: in C++, lambdas can capture variables by value or by reference. If it is captured by value, then of course it can be accessed after the function exits. – newacct Jul 24 '13 at 21:19
  • @newacct: Values have no lexical scope, so "capturing" a value is not what the concept of a closure is about (IMO). Values are not captured, they're assigned, passed, used as operands etc. That's why I talked about the "reference" case only in the comment. – zzzz Jul 24 '13 at 21:29
  • @jnml: When you capture by reference, it is also passed and assigned -- it is just passed by reference and assigned to an internal variable of reference type. Whether capturing by value or reference, variable scope is lexical -- the variable corresponds to the variable of that name in the nearest enclosing scope in the code. I think you are hung up on the fact that when it's captured by value, there are 2 independent copies of the variable, one inside the closure and one outside. But that's not relevant to the concept of a closure, which is that it captures variables (doesn't say how). – newacct Jul 24 '13 at 22:02
  • @newacct: That's why it's better to avoid the not enough well defined term "reference". It's better to talk about POVs (Plain Old Values) and POPs (Plain Old Pointers). The distinction is then clear. (Umm, only until someone notices that a pointer is a value as well ;-) – zzzz Jul 25 '13 at 07:24