August 19, 2004
Anonymous, inline, and named functions in ActionScript
Terms like inline, anonymous, named, standard, etc. get thrown around a lot but are not always used correctly. Hopefully this post will shed some light of some of the function terminology that you may have come across in your ActionScript adventures.
-
Named Functions
A named function is of the form:
function foo(param1, param2, etc) {
// do stuff here
}
Named functions, no matter where they are defined on a frame, are placed at the front of the actions for a frame at compile time. Therefore, you can forward reference them. That is, I can call "foo()" before I defined the foo function and the function will still execute.
Named functions can only define functions in the timelines that they are written in.
-
Anonymous Functions
An anonymous function is defined like this:
bar = function(param1, param2, etc) {
// do stuff here
}
Anonymous functions are interesting beasts. Unlike named functions, when you create an anonymous function there is no way to reference the function via code. We can get around this with function literals.
When the function is created it returns a reference to itself. In the example above, we set a variable "bar" to reference the anonymous function we create.
Now, whenever bar is called, the anonymous function that it references will execute. Unlike named functions, anonymous functions cannot be forward referenced. If I make a call to bar before I set bar to reference the function, the call will fail.
When creating an anonymous recursive function, the function can reference itself by using the arguments.callee property. Consider this example:
// classic factorial recursion example
factorial = function(n) {
if (n <= 1) {
return n;
} else {
return n*arguments.callee(n-1); // call ourself to recurse
}
}
Note that in the above example, we can replace arguments.callee with factorial and the example will still work. However, there are times in which we don't have a variable to call the function with. In those cases, arguments.callee is the only solution. An example of this might be passing an anonymous function as a parameter to another function.
Function literals can define functions in any timeline/object, provided the path exists at the time of definition. For instance, to create a function inside of an object, we have to use a function literal like this:
obj = new Object();
obj.foo = function() {
return "bar";
}
trace(obj.foo()); // bar
- Inline Functions
Inline functions do not exist in Flash. This is a common misconception - people tend to refer to function literals as inline functions, which is incorrect.
The basic idea behind inline functions is to improve execution speed at the sacrifice of program size. Behind the scenes, the inline concept works something like this...
When a function is created, a block of data is created containing the function code. Then, when a program executes a function call, the program stores is current state, jumps to the location of the function block, executes the code it finds there (the function body), jumps back to where it left off in normal execution and restores its previous state.
Because of the state shuffling and the extra jumps to the function location, there is overhead associated with any function call. Inline functions are a way around this.
Instead of jumping to a block of memory, an inline function will just insert the function code directly into the program ("in line"). The code no longer has to jump to the function block and deal with remembering it's current state - it can just continue execution normally. This, however, leads to larger program sizes.
Image I call a function 10 times. With a function, the code is only inserted into the program 1 time and referenced 10 times through the 10 different function calls. Compare that to inline functions where the function code is inserted into the program 10 times at each different function call.
I realize that a lot of this information is old hat to a lot of people, but I still see some misuse of terms. Hopefully this post helps to clear things up a little for everyone...
Terms like inline, anonymous, named, standard, etc. get thrown around a lot but are not always used correctly. Hopefully this post will shed some light of some of the function terminology that you may have come across in your ActionScript adventures.
-
Named Functions
A named function is of the form:
function foo(param1, param2, etc) { // do stuff here }
Named functions, no matter where they are defined on a frame, are placed at the front of the actions for a frame at compile time. Therefore, you can forward reference them. That is, I can call "foo()" before I defined the foo function and the function will still execute.
Named functions can only define functions in the timelines that they are written in.
-
Anonymous Functions
An anonymous function is defined like this:
bar = function(param1, param2, etc) { // do stuff here }
Anonymous functions are interesting beasts. Unlike named functions, when you create an anonymous function there is no way to reference the function via code. We can get around this with function literals.
When the function is created it returns a reference to itself. In the example above, we set a variable "bar" to reference the anonymous function we create.
Now, whenever bar is called, the anonymous function that it references will execute. Unlike named functions, anonymous functions cannot be forward referenced. If I make a call to bar before I set bar to reference the function, the call will fail.
When creating an anonymous recursive function, the function can reference itself by using the arguments.callee property. Consider this example:
// classic factorial recursion example factorial = function(n) { if (n <= 1) { return n; } else { return n*arguments.callee(n-1); // call ourself to recurse } }
Note that in the above example, we can replace arguments.callee with factorial and the example will still work. However, there are times in which we don't have a variable to call the function with. In those cases, arguments.callee is the only solution. An example of this might be passing an anonymous function as a parameter to another function.
Function literals can define functions in any timeline/object, provided the path exists at the time of definition. For instance, to create a function inside of an object, we have to use a function literal like this:
obj = new Object(); obj.foo = function() { return "bar"; } trace(obj.foo()); // bar
- Inline Functions
Inline functions do not exist in Flash. This is a common misconception - people tend to refer to function literals as inline functions, which is incorrect.
The basic idea behind inline functions is to improve execution speed at the sacrifice of program size. Behind the scenes, the inline concept works something like this...
When a function is created, a block of data is created containing the function code. Then, when a program executes a function call, the program stores is current state, jumps to the location of the function block, executes the code it finds there (the function body), jumps back to where it left off in normal execution and restores its previous state.
Because of the state shuffling and the extra jumps to the function location, there is overhead associated with any function call. Inline functions are a way around this.
Instead of jumping to a block of memory, an inline function will just insert the function code directly into the program ("in line"). The code no longer has to jump to the function block and deal with remembering it's current state - it can just continue execution normally. This, however, leads to larger program sizes.
Image I call a function 10 times. With a function, the code is only inserted into the program 1 time and referenced 10 times through the 10 different function calls. Compare that to inline functions where the function code is inserted into the program 10 times at each different function call.
I realize that a lot of this information is old hat to a lot of people, but I still see some misuse of terms. Hopefully this post helps to clear things up a little for everyone...
