Sending events using closures
At the end of the day, closures are function pointers. However, it's not really clear how already-defined methods on classes could be assigned to a closure. For example, suppose I have the function-type
{ => double }, and I want to assign to it the method double getVat()?
But suppose it is possible, and I just misunderstood something in the proposal, or it's just not determined yet and lies somewhere in the blogsphere, currently having a flamewar on it. For this post, I'm making the assumption that it is possible and that the syntax is something like: Function-Type var = ClassName.MethodName.
Let's move on, then. Remember that a function-type such as { => double } vatGetter would eventually be translated to the following interface:
interface Function12<T> {
T invoke();
}
Function12<? extends Number> vatGetter;
And now let me add to the flame and add another idea: Events through closures. Suppose the { => double } closure would be translated to:
interface Function12<T> {
T invoke();
void addListener(Listener<Function12<T>> listener);
void removeListener(Listener<Function12<T>> listener);
void fireEvent();
}
And the implementation for addListener, removeListener and fireEvent would be made automatic, maybe even via some utility class already in existence. The benefit here is that methods could be responsible for setting off events for their value changes (suppose if the property they're encapsulating has changed, or if some variable which is used for the internal calculation has changed). This would make implementation of bindings and events in a much smoother way.
Don't think that this idea is specified only for getter methods: the T will always be the return value of the closure, so that any kind of method could be used. For example, imagine the method double addVat(double price) which adds VAT to a price specified. The closure will be defined as { double => double } and translated into:
interface Function13<T, R> {
T invoke(R p1);
void addListener(Listener<Function13<T>> listener);
void removeListener(Listener<Function13<T>> listener);
void fireEvent();
Which gives us the option to listen to changes in the way VAT is being calculated inside the calcVat method, for example if the value returned by getVat has changed. But, and behold this, since getVat itself can be listened to, we can do the following (in the static constructor, I suppose):
{ => double } vatGetter = VatCalculator.getVat;
{ double => double } vatCalc = VatCalculator.calcVat;
vatGetter.addListener( new Listener... {
vatCalc.fireEvent();
});
Or even a utility method such as Closures.bind(vatGetter, vatCalc). Note that I have no idea how "type-anonymous closures" are referenced, which are needed to define the aforementioned bind method; maybe { ? => ? }, as I've seen in the open issues document, but definitely there will be a solution for it.
Now, after binding the two, a setVat method could be implemented as:
void setVat(double v) {
this.vat = v;
getVat.fireEvent();
}
And anyone who is listening on the calcVat method will automatically get an event fired. This could be used to update a UI element, to start some web-service, or to update a database record. The possibilities, as they are with events, are endless - but the implementation can be simple.
Alright, this is all I have to say for the moment, and comments are always a pleasure!
Comments (4)