What are function closures?

18 posts

Flag Post

The following is an excerpt from Essential AS3.

Note, however, that within a function closure, the this keyword always refers to the global object, no matter where the function is defined. To access the current object within a nested function in an instance method, assign this to a variable, as shown in the following code:

public function m ( ) {
    var currentObject = this;

    function f ( ) {
    // Access to currentObject is granted here
    trace(currentObject);  // Displays the object through
                           // which m( ) was invoked
    }
}

I’ve got 2 questions:
1. What do they mean by “global object”?
2. What’s a function closure? This totally came out of nowhere, it was not defined earlier. I tried Googling it, but I didn’t really understand the definitions I found.

Thanks.

 
Flag Post

This looks like a helpful read. It might be a bit complicated, however. It covers scope and function closures for AS3.

Global Object will be the class the function exists in usually.

 
Flag Post

Why would you put a function definition inside a function definition instead of either next to it (if it needs to be part of the same class) or as a static function in a separate class entirely (if it’s a general purpose function that many different classes may need)?

I’m not seeing what good could ever come out of this nested function construct. Any ideas?

 
Flag Post

A closure is a function that uses (and preserves) the state of its defining environment. The local function in your example only actually preserves currentObject so it’s a fairly poor example. I’d use:

public function adder(x:int) : Function {
 return function(y:int) : int { return x + y; }
}

This is a function that returns a closure: inside the local function, the variable x is retained from its enclosing scope.

I’ve never quite worked out what this ends up referring to inside a local function or closure, but it’s always a good idea to use a variable to get the object you actually want.

 
Flag Post
Originally posted by BobJanova:

I’ve never quite worked out what this ends up referring to inside a local function or closure, but it’s always a good idea to use a variable to get the object you actually want.

In JavaScript, this would refer to the returned function. Since ActionScript is based on ECMAScript, it is probably the same.

 
Flag Post
Originally posted by Eu_Plon_Ka:

In JavaScript, this would refer to the returned function. Since ActionScript is based on ECMAScript, it is probably the same.

As UG already stated, it’s global object.

 
Flag Post
Originally posted by BobJanova:

A closure is a function that uses (and preserves) the state of its defining environment. The local function in your example only actually preserves currentObject so it’s a fairly poor example. I’d use:

public function adder(x:int) : Function {
 return function(y:int) : int { return x + y; }
}

This is a function that returns a closure: inside the local function, the variable x is retained from its enclosing scope.

I’ve never quite worked out what this ends up referring to inside a local function or closure, but it’s always a good idea to use a variable to get the object you actually want.

It refers to the class in which the function is defined. eg.

public class MyObject {
  public function adder(x:int) : Function {
   return function(y:int) : int { return x + y; trace(this); }
  }
}

The trace will return “[Object MyObject]” as it refers back to the class scope.

 
Flag Post

Okay thanks for the clarification. That’s rarely a useful thing! (I mean the class object, not clarification, which is often useful :-).)

 
Flag Post
Originally posted by Draco18s:

It refers to the class in which the function is defined. eg.

public class MyObject {
  public function adder(x:int) : Function {
   return function(y:int) : int { return x + y; trace(this); }
  }
}

The trace will return “[Object MyObject]” as it refers back to the class scope.

1.) the trace will not return anything, it will not be executed
2.)

Originally posted by NineFiveThree:
Originally posted by Eu_Plon_Ka:

In JavaScript, this would refer to the returned function. Since ActionScript is based on ECMAScript, it is probably the same.


As UG already stated, it’s global object.

 
Flag Post

Sorry I didn’t reply yet.

Originally posted by UnknownGuardian:

Global Object will be the class the function exists in usually.

Thanks UG, that’s what I thought. I read the article you posted about function closures, but I still don’t really understand what they are.

Originally posted by BobJanova:

A closure is a function that uses (and preserves) the state of its defining environment.

What’s a defining environment?

Thanks for the help, everyone.

 
Flag Post

Are you familiar with recursion? You know how it magically “remembers” the values of all variables before each call to the recursive function?

EDIT Not sure if this is a great way to explain it.

 
Flag Post

I know what a recursive function is, but I don’t know what you mean by remembering the values of all variables before the function’s call.

Is it urgent that I understand function closures at the moment? I didn’t learn about them yet in the book; the term just showed up once and hasn’t shown up since. I imagine I’ll figure out what they are sooner or later, right?

 
Flag Post

It’s definitely not critical. They can be useful in some situations (particularly in a more FP style of coding), but you can code for years without using one and not miss out on a great deal.

I don’t think recursion is a great parallel, to be honest. Let’s go back to my example from before:

public function adder(x:int) : Function {
 return function(y:int) : int { return x + y; }
}

Let’s say we assign and use that function:

var f:Function = adder(6);
trace(f(5)); // prints: 11

In the second line there, you’re running the closure code: return x+y. y is the argument to the function – but where does x come from? It’s been retained from the enclosing scope, that of the function adder which returns the closure.

In this case x is an argument to adder, but it could be a local variable or anything which is available in that scope (including instance variables, though that would be a weird thing to do).

 
Flag Post
Originally posted by BobJanova:

It’s definitely not critical. They can be useful in some situations (particularly in a more FP style of coding), but you can code for years without using one and not miss out on a great deal.

I don’t think recursion is a great parallel, to be honest. Let’s go back to my example from before:

public function adder(x:int) : Function {
 return function(y:int) : int { return x + y; }
}

Let’s say we assign and use that function:

var f:Function = adder(6);
trace(f(5)); // prints: 11

In the second line there, you’re running the closure code: return x+y. y is the argument to the function – but where does x come from? It’s been retained from the enclosing scope, that of the function adder which returns the closure.

In this case x is an argument to adder, but it could be a local variable or anything which is available in that scope (including instance variables, though that would be a weird thing to do).

I almost said I didn’t even understand that code, but I think I might have figured it out.

So you have a function called adder that returns a nameless function? The nameless function returns x + y.

In the second part, you assign the variable f to adder(6). Then you trace f, which gives the argument 6 as we know, and the (5) gives the nameless function the argument 5. The nameless function adds 6 + 7.

Is that really a nameless function? What’s going on there? I’m confused, haha.

 
Flag Post

Pretty much, except it’s 6+5, not 6+7 (I’m guessing that was just a typo). A closure is an anonymous function that preserves its environment (or scope or whatever you want to call it).

var f1:Function, f2:Function, f3:Function;

function defineFunctions(x:int) : void {
 // This is an anonymous function, not a closure, because it evaluates
 // based on only its own arguments
 // Note that its parameter 'x' is used not the 'x' from defineFunctions
 f1 = function(x:int, y:int) : int { return x * y; }

 // This is a closure (also a type of anonymous function) because it
 // uses the value of 'x' from defineFunctions, its enclosing scope. 'x'
 // is preserved after defineFunctions finishes executing
 f2 = function(y:int) : int { return x * y; }

 // This is also a closure because it uses the value of 'local' from within its
 // enclosing scope; it doesn't have to be parameters.
 var local:int = x + 10;
 f3 = function(y:int) : int { return local * y; }
}
 
Flag Post

Thanks, Bob. I think I get it now. Yes, the 7 was a typo.

Originally posted by BobJanova:

A closure is an anonymous function that preserves its environment (or scope or whatever you want to call it).

Does the function really have to be anonymous though?

 
Flag Post
Originally posted by GameBuilder15:

Does the function really have to be anonymous though?

No, but naming it is a bit pointless.

 
Flag Post
Originally posted by NineFiveThree:
Originally posted by Draco18s:

It refers to the class in which the function is defined. eg.

public class MyObject {
  public function adder(x:int) : Function {
   return function(y:int) : int { return x + y; trace(this); }
  }
}

The trace will return “[Object MyObject]” as it refers back to the class scope.

1.) the trace will not return anything, it will not be executed

Thank you for being pedantic.