Closures (also referred to as Blocks) are supported in many functional programming languages like SmallTalk, Lisp, Javascript..the newest ones being C# 2.0 and Ruby. So what are closures?
A closure is a block of code that can be passed as an argument to another method. At a most basic level, they are functions defined inside a scope of some sort. You can then pass the function around and call it whenever, and the function continues to execute as if it were still inside the scope it was defined in.
Example 1: Assume that the Remove.invoke method takes in two parameters: the service to call, and the callback function to invoke when the service call finishes.
function getSomethingById(id) {
Remote.invoke("http://domain.com/neat_service/" + id, function(response) {
recordSomethingById(id, response);
});
}
What's going to happen is that when the request finishes, the server's response is going to be passed as an argument to the callback function. This callback function is going to be invoked LONG after this bit of code actually runs to completion (because the remoting request is asynchronous). But still, as you observe, the callback function can use variables that are defined outside the callback, but inside the outer function (e.g. the id parameter), even though the outer function has long since returned. That forms the essence of a closure.
Example 2:
function counter(num)
{
var enclosedVar = num;
return function() {enclosedVar++};
}
Here - as you observe the inner anonymous function defines a closure over the local variable "enclosedVar". The function "counter" returns a reference to this closure, which can then later be executed at any point of time. Note that the local variable "enclosedVar" does not go out of scope, as far as the closure is concerned.
We can put this closure to use as follows:
var myIncFunction1 = counter(5);
var myIncFunction2 = counter(10);
The function references returned by the counter method can be stored in a variable and invoked as follows:
print(myIncFunction1()); // prints value 5
print(myIncFunction1()); // prints value 6
print(myIncFunction2()); // prints value 10
print(myIncFunction2()); // prints value 11
Note that we will get the output as mentioned above, because the two separate calls to counter method actually created two independent closures.
Closures as inside-out objects:
Rightfully referred to as that. Objects are data that have sub-routines attached to them, where as, closures are sub-routines with some data associated with them.
Passing code around, instead of data:
If I have to sort a collection of things, where the collection can possibly contain different types of data, I will have to write separate sort methods in order to handle the various types of data. However, with closures and the ability to pass code / functions as arguments, I can write one single "sort" method that accepts the collection as one parameter and the code to do the actual comparison as the second parameter. Found one code snippet that shows how this can be done:
function sort(collection, comparator) {
var n = collection.length;
for (var i=0; i < n - 1; i++) {
for (var j=0; j < n - i - 1; j++)
if (comparator(a[j+1], a[j])) {
swap(collection, j, j + 1);
}
}
}
}
c = [
{name: "barney", height: 195, weight: 80},
{name: "heather", height: 182, weight: undefined},
{name: "jerry", height: 185, weight: 81}
]c_by_height = sort(c, function(a, b) {
return a.height < b.height;
});
c_by_name_reverse = sort(c, function(a, b) {
return a.name > b.name;
});
So - here the sort method is pretty much generic, we can write different comparators to handle the actual comparison and pass those comparators around.
One good link that gives examples of closures in Javascript: http://blog.morrisjohns.com/javascript_closures_for_dummies
Tuesday, October 17, 2006
Monday, October 16, 2006
J2ME MIDP 2.0 - A world away from the J2SE world
I have been working on J2ME (Java 2 Micro Edition), particularly MIDP 2.0 (Mobile Information Device Profile) for the last 3 months or so. We have been exploring this profile to develop a POC application that will run on MIDP 2.0 enabled cell phones. Coming from a J2SE background, where we don't really think much about memory and where UI capabilities are assumed to be good, I many times found myself saying.. "What? You cannot even do this? How am I supposed to construct a good-looking UI application then?".
Some obvious things I expected but did not find support for that in MIDP:
1. No file support by default: By default the MIDP 2.0 does not provide you with file IO APIs. So that means you cannot write to / read from files. There is a separate JSR 75, called File Connection Optional Package that provides APIs for accessing file systems on a device.
2. No nesting of panel / container components: In J2ME MIDP 2.0 user interface API, there can be only one outermost container component. This can be a Form, a List or a TextBox. It is not possible to create a container or a panel with child componentns and include that panel as a child of the Form. I found this very restrictive when it comes to building complex, good looking UI screens.
3. Very limited Layout support: Forget all the fancy GridLayout, FlowLayout and GridBagLayouts here! All you can specify is that I want a new line after a component or before a component and that I want all the 3 text fields to appear on one row. And that too, I observed is not necessarily the effect you will get in the end. It all depends on the screen size and the KVM implementation on the device I guess.
4. Key pressed events for characters: Don't you expect that if MIDP 2.0 does provide you with a KeyListener and does generate a keyPressed event, that it should generate these events for character keys as well? Well - you can, but in the case of MIDP 2.0 and cell phone world - it is too much to expect. The reason is that, the keycodes generated for the character keys are / can be different on different cell phones. That is why, MIDP 2.0 as a standard, does not mandate generation of key events for the character keys. Standard key codes and event generation can be assumed only for digits: 0 to 9 and some other keys like # and *.
We were trying to develop a custom text field component and therefore wanted to catch the events for character keys. One of the ways I got to know from someone to implement it, is to have a timer task, set a particular time interval, and map consecutive key presses to characters. For example: If digit 2 is pressed thrice in quick succession, interpret it as 3. Find this a very crude way of doing it and obviously restricts my code to a English key pad.
5. Standard components do not let me set the foreground and background colors: All I wanted was to have a different background color for a label component. I had to develop a custom label component just for that so that I could set the desired background and foreground colors.
The purpose of this blog is not to point out only the negatives or the limitations, the point I am trying to make here is only the absence of some of the things we take for granted in the PC world!
Some obvious things I expected but did not find support for that in MIDP:
1. No file support by default: By default the MIDP 2.0 does not provide you with file IO APIs. So that means you cannot write to / read from files. There is a separate JSR 75, called File Connection Optional Package that provides APIs for accessing file systems on a device.
2. No nesting of panel / container components: In J2ME MIDP 2.0 user interface API, there can be only one outermost container component. This can be a Form, a List or a TextBox. It is not possible to create a container or a panel with child componentns and include that panel as a child of the Form. I found this very restrictive when it comes to building complex, good looking UI screens.
3. Very limited Layout support: Forget all the fancy GridLayout, FlowLayout and GridBagLayouts here! All you can specify is that I want a new line after a component or before a component and that I want all the 3 text fields to appear on one row. And that too, I observed is not necessarily the effect you will get in the end. It all depends on the screen size and the KVM implementation on the device I guess.
4. Key pressed events for characters: Don't you expect that if MIDP 2.0 does provide you with a KeyListener and does generate a keyPressed event, that it should generate these events for character keys as well? Well - you can, but in the case of MIDP 2.0 and cell phone world - it is too much to expect. The reason is that, the keycodes generated for the character keys are / can be different on different cell phones. That is why, MIDP 2.0 as a standard, does not mandate generation of key events for the character keys. Standard key codes and event generation can be assumed only for digits: 0 to 9 and some other keys like # and *.
We were trying to develop a custom text field component and therefore wanted to catch the events for character keys. One of the ways I got to know from someone to implement it, is to have a timer task, set a particular time interval, and map consecutive key presses to characters. For example: If digit 2 is pressed thrice in quick succession, interpret it as 3. Find this a very crude way of doing it and obviously restricts my code to a English key pad.
5. Standard components do not let me set the foreground and background colors: All I wanted was to have a different background color for a label component. I had to develop a custom label component just for that so that I could set the desired background and foreground colors.
The purpose of this blog is not to point out only the negatives or the limitations, the point I am trying to make here is only the absence of some of the things we take for granted in the PC world!
Subscribe to:
Posts (Atom)