Saturday, December 26, 2009

3.0.0rc1 Due Soon

With event support checked in, I'm updating the docs and gearing up for a build. This should be about the wrap up for v3. I'm not sure that I will crack open $interface and thoughts of $template are brewing, so I'll probably leave both of these for v4.

Thursday, December 24, 2009

Events - Part 7 (The Final Chapter)

This will be my final write up on Events (at least I hope so!). I've checked in the code and am content to let it rest for v3. After I post this, I will start updating the related docs. The classes involved are now:

  • Event - This class is probably the most obvious. It is the class that is the base for all event description objects. These objects are created for each event and contain the details related to that event. Other than the data specific to the event type, all events have a consume method. This method can be called on an Event object to indicate that no further propogation or bubbling should be performed.

    NOTE: it is actually the presence of a consume method that duck types an object as an Event Object.

  • EventSource - This class is analagous to the Observable class in ExtJS. This is the base class for objects that fire events. If deriving from EventSource is not possible, the mixinEventSource method can be used to bolt on these features to any class. The most important methods on an EventSource are on and fireEvent.

  • EventHandler - This class is a base class for destroyable objects that need to also disconnect from event subscriptions. As with EventSource, if this base class cannot be used, the mixinEventHandler method can bolt on the appropriate functionality. The only method provided is mon. This works exactly like on except that it is called on the EventHandler object and the EventSource object is the first parameter. This approach was copied from ExtJS (those folks are clever).

  • EventModel - This is very much a behind the scenes kind of thing. This is the class that implements the mechanics of connecting event subscribers to the event firing mechanism. The EventSource.on method does a lot of higher-level work, but then calls EventModel.subscribe to connect a method to an event. Similarly, the EventSource.fireEvent method calls EventModel.create and EventModel.fire. The EventModel then is responsible for the following:

    • Connecting a method to (and disconnecting a method from) a named event on a source object.
    • Creating event objects given parameters.
    • Firing an event object (including bubbling).


This division of labor allows EventSource to be connected to the basic EventModel or an implementation of the DOM event model. I've sketched out how that would look in domevents.js, but am not worried about implementing and testing it or anything. In fact, the domevents.js file is not including in any of the build targets - it is purely proof of concept.

This accomplished the design goals of making an event subscription interface that would apply to both types of events and even reuses a good bit of the higher-level logic required. When the docs are posted I will explain in more detail how all the pieces are used. The good news is that it is very similar to ExtJS. If you are curious, the code comments already document all this. Perhaps one day I'll figure out a good solution to javadoc-like extraction of comments from JavaScript...


P.S. Merry Christmas!

Saturday, October 31, 2009

Events - Part 6 (Events Reloaded)

It's time for a confession. I'm afraid that my hiatus was only partially due to life getting busy. A bigger part was that I realized an error in my thinking related to events. Since I'm not inclined to revise history and pretend that I always had things squared in my mind, I'll let you read my older postings for details. I did go back and strike-through all the statements that are now changed (to avoid confusion).

The root of my wrong thinking came to light when I started to implement event bubbling. Until that point, my abstraction of event types seemed to fit. Essentially, each event had an EventType and possibly its own Event class. Both firing and listening for events on an object required that the event be declared on that object. Then bubbling happened.

The problem with bubbling is that the listener is attached to a different object than the object that fires the event. While it makes sense that an event must be declared to be fired by an object, the listener had to be less constrained. But, if the mechanism for listening were tied up with the event type (as I had it) and the event type is not knowable, we reach an impasse.

What I realized was that event handling had to be determined at the object level, not at the event level. So that meant EventType had to be refactored. More precisely, EventType had to go. That caused a bit of rework. And quite a bit of delay.

I think I've got everything put back together now, so I'll try to post a rejoinder on events soon. And post the code to SVN, of course.

Sunday, July 19, 2009

Events - Part 5

Now comes the fun part - listening for events. There are many special needs that arise when listening for and responding to events, so this will be more involved than the source-side of the discussion. Let's start as simply as possible.


var obj = new Base();

obj.on("foo", this.onFoo, this);

// The following will get an exception (obj has no "bar" event):
obj.on("bar", ...); // throws


In this simple example, some instance method of another object wants to listen to foo events from a Base object. The arguments are the event name ("foo"), the method to call (this.onFoo) and the instance scope to use when calling the method (this).

If you are familiar with ExtJS, you'll notice that this is pretty familiar and that is deliberate. I think ExtJS has a very clean model for event connection, so I followed its pattern. This continues for multiple event connections:


obj.on(
{
foo : this.onFoo,
bar : this.onBar,
scope: this // applied to onFoo and onBar
});

// Or:
obj.on(
{
foo : this.onFoo,
bar : { fn : that.onBar, scope: that },
scope: this // applies only to onFoo
});


And there is also the ability to filter out bubbled events (more on those next time).


obj.on(
{
foo : this.onFoo,
scope: this,
target: obj
});


And lastly, there is the ability to be fired only a certain number of times (often 1 for "just once"). This is a bit different than ExtJS.


obj.on(
{
foo : this.onFoo,
scope: this,
only: 1
});
// calls onFoo only 1 time (then disconnects)

// or
obj.on(
{
foo : this.onFoo,
bar : { fn : that.onBar, scope: that, only: 2 },
scope: this // only applies to this.onFoo
});
// calls onBar twice, but onFoo remains indefinitely


If you are really familiar with ExtJS, you're probably thinking I've missed a few things here. You are right if you noticed that "delay" and "buffer" are not present. I opted to implement these features in a more general way.

Not Now!

It is often the case that an event needs to be handled "really soon" after it is detected, but not immediately. Perhaps some of the state hasn't settled yet and you need to let the callstack unwind all the way out before doing the processing for the event. This kind of delaying is not limited to event handling, so I implemented that feature as a Function.prototype extension.


obj.on("foo", this.onFoo.delayed(10), this);


Everytime "foo" fires, the onFoo method is called 10msec later. The more complex buffer approach is also implemented as a Function.prototype extension, and has more flexibility as well.


// 10msec delay after LAST firing of foo
obj.on("foo", this.onFoo.buffered(), this);

// call 25msec after the LAST firing of foo:
obj.on("foo", this.onFoo.buffered(25), this);

// call 25msec after the FIRST firing of foo:
obj.on("foo", this.onFoo.buffered(-25), this);

// call 10msec after the LAST firing of foo but with
// the args from the FIRST:
obj.on("foo",
this.onFoo.buffered(
{
args: "first",
delay: 10
}),
this);


As you can see, the buffered method has a few more bells and whistles. Its 2nd argument is an optional "scope" parameter that determines the "this" context used for the method call. Since this is also handled by the eventing mechanism, it is not needed in this case but might be useful elsewhere.

Everyone Out Of The Pool!

It's all too easy. Fun and games really. Buy what happens when want to stop listening? Consider this ExtJS scenario:


var obj = new Base();

obj.on("foo", function () { ... }, this);


This works just fine - unless you need to disconnect such a thing. Which you cannot do as coded. This is because to disconnect a listener in ExtJS (and most other systems, e.g. our beloved DOM), you have to supply the same arguments passed at the time of connection. This can be very restrictive because you cannot use function literals or any form of function producer (like bind, head, tail, etc.).

I decided that the way window.setTimeout works is much better: it produces a token which is later used to deconstruct things via window.clearTimeout. In this case, however, the object returned by on has a destroy method which enables us to use the handy zjs.destroy function.


var obj = new Base();

this.unfoo = obj.on("foo", this.onFoo, this);

// ... later ...
zjs.destroy(this.unfoo);


A simple way to handle multiple such connections would be:


var obj = new Base();

this.unall = [ obj.on("foo", this.onFoo, this),
obj2.on("bar", ... ),
obj3.on("bif", ... ),
obj4.on("jax", ... ),
obj5.on("raz", ... ) ]

// ... later ...
zjs.destroy(this.unall); // destroys each array element


While this is a departure from most other event subscription approaches, it really simplifies the process by which cleanup is accomplished. And just in case you were curious: if the on method connected multiple event listeners, the returned object's destroy method would, of course, disconnect all of them.

Miscellaneous

Wrapping up, there is a helper method behind the delayed method that can be useful:


this.method.later(10, this);


This is very similar to the defer method provided by ExtJS, but it uses the destroyable object return value approach for consistency:


var t = this.method.later(10, this);

zjs.destroy(t); // never mind

Events - Part 4 (OBSOLETE)

At last it is time to show some examples. The simpler side to illustrate is the event source, so let's start there. I've already shown how to declare events, but here's a complete example.


Base : $class(zjs.EventSource,
{
$events :
[
/**
Documentation for the foo event.
*/
"foo"
]
}),

Derived : $class("Base",
{
$events :
[
/**
Documentation for the bar event.
*/
"bar"
]
})


The above class hierarchy defines two events. The Base class defines the foo event while the Derived class inherits foo and adds the bar event.

Ready... Aim...

Now that we've declared our events, let's fire one.


this.fireEvent("foo", { x: 42 });


The above will use the zjs.Event class for events and this call will place an x property on the event instance with the value of 42. Any number of properties can be added, which forms the contract between the event source and the listener(s).

Special Cases

Perhaps an event needs a special class to represent it. This can be done by deriving a class from zjs.EventType and putting an instance in the $events array.


SpecialEventType : $class(zjs.EventType,
{
ctor : function ()
{
$super(arguments).call(this, "specevent");
},

create : function (target, params)
{
return new MySpecialEvent(target, params);
}
}),

MySpecialEvent : $class(zjs.Event,
{
ctor : function (target, params)
{
$super(arguments).call(this, "specevent", target, params);
}
}),

SpecialFellow : $class(
{
$events :
[
new SpecialEventType()
]
})


To handle the case where zjs.EventSource cannot be used as a base class:


RockAndHardPlace : $class(SomeOtherBase,
{
$events :
[
"sameoldthing"
],

fireEvent : function (name, params)
{
return zjs.fireEvent(this, name, params);
},

on : function ()
{
return zjs.subscribeEvent.apply(this, arguments);
}
})

Saturday, July 18, 2009

Events - Part 3 (OBSOLETE)

Events are implemented in 3 classes:


  • EventType: A stateless class that manages subscribing and (optionally) generating/firing events of its kind.
  • EventSource: A base class that provides convenient methods to subscribe to and fire events.
  • Event: A base class from which events can derive.

As I mentioned earlier, I wanted to events to be 1st class citizens, but at a glance it would seem that EventSource is contrary to that end as it requires event-generating classes to ultimately derive from EventSource. To clear this up, lets look at the contents of EventSource:


EventSource : $class(
{
fireEvent : function (name, params)
{
return zjs.fireEvent(this, name, params);
},

on : function (name, fn, scope, opt)
{
return zjs.subscribeEvent.apply(this, arguments);
}
})


As can be seen, the real work of subscribing and firing events is handled by methods in the ZJS namespace. Thus, classes that derive from a base which does not trace back to EventSource can likewise provide these convenience methods with ease.

I have previously discussed EventType, but not in sufficient detail to see how one might implement a custom event type.


EventType : $class(
{
subscribe : function (obj, fn) // Required
{
},

// Optional (required to programmatically create and fire events):

create : function (params)
{
},

deliver : function (obj, ev)
{
}
})


The subscribe method is given the source object and the function to be called when the source object fires this type of event. Event types are assumed to know their name (e.g., "click"). The return value of the subscribe method is an object whose destroy method will unsubscribe the function.

The create and deliver methods are used to programmatically fire events. This can be done with DOM events, but is seldom an important use case. Even so, these methods can be implemented to create and fire DOM events. Outside the DOM, however, events must be created and fired in code since the browser will not know of them or when they should trigger.

As with browser-generated events, events in ZJS are objects. This is different than ExtJS where events are simply function calls that happen to have some arguments. For example, firing an event would be something like this in ExtJS:


this.fireEvent("foo", this, x, 42);


In ZJS, events are always a single object (as it is with DOM events). The reason for this (beyond simple consistency which would likely have been enough reason) is because there are behaviors for events themselves that are not related to their data members. The most important of these is the ability to control the propagation of an event. Further, by passing a single object, the event source is free to refactor and extend the data it supplies. The need for a container object with DOM events is plain because these events often have over a dozen properties!

The zjs.Event class is a basic implementation of a custom event. Obviously, a DOM event would not derive from zjs.Event, so it really serves as both an example of the interface to which events should conform as well as an implementation for the cases where it does fit. The method exposed by zjs.Event that should be supplied by all event types is consume.

In the DOM, there are two ways to effect event propagation. On the one hand, a DOM event's bubbling around for other event subscribers can be stopped. On the other, the default behavior provided by the browser for the event can be canceled (most of the time). In my experience, it is seldom that I want to cancel only one of these, so the consume method would handle both for this type of event.

Well, I think I've covered all the building blocks and concepts. Next time I'll put together an example of defining, firing and handling events.

Friday, July 17, 2009

Events - Part 2

Last time I talked about events in ZJS v3. There were many ways I considered for implementing events, but in the end I settled on a nested object to contain the event type definitions and linked that object to both the class and the instance (via the prototype). In other words:


$namespace(foo,
{
Bar : $class(
{
$events :
[
"beforechange",

"change"
]
});
});

var b = new foo.Bar();

assertTrue(b.$events === foo.Bar.$events);

// This is redundant given the first assert, but for clarity:
assertTrue(foo.Bar.prototype.$events === foo.Bar.$events);


The above could have been implemented "directly" in the $class and $mixin logic, but I decided to indulge of bit of architectural overkill and instead I added the concept of Class Plugins. This reduced the footprint of events in the core logic to about 3 lines of code which delegated the work to the plugin.

In the past I had briefly considered making $static work like the above. This would have made it much more direct to reach the statics of your class (this.$static) and would have allowed statics from base classes to be "inherited" due to the prototype chain on the $static object. For various reasons I decided against this, but now, with two uses cases in hand that had the same basic pattern, I figured a more general solution wouldn't be a bad idea. That and the logic in $class and $mixin was already complex enough that I shuddered to think of making it even more so.

With the plugin approach, the extra core code looks like this:


$class.plugins = {};

...

if (name in $class.plugins)
return $class.plugins[name].process(klass, v);


The above test is performed on each member of the object literal being mixed in to a class. The only method that is necessary for a Class Plugin object is the process method that accepts the class (i.e., the constructor function) and the value on which to operate. For convenience, there is a class that implements the machinery (described for chaining and adding to the prototype as well as the class) called zjs.ClassPlugin. The implementation of the "$events" plugin simply derives from zjs.ClassPlugin.

As can probably be guessed, the interesting work of converting an array of strings into something useful for event handling takes place in the plugin. In fact, it was this difference in behavior regarding what to do with the values that pushed me solidly into the whole plugin approach. You see, with events in ExtJS, you call addEvents and pass a bunch of strings. That's it. The string is simply the event name and that is sufficient to declare the fact that an event exists.

In ZJS, these strings are converted into zjs.EventType objects. I'll cover the details next time, but basically the EventType handles subscribing for events as well as creating event instances and triggering delivery of said events. Because these are the key differences between hand rolled events and true DOM events, one can implement EventTypes that do these jobs.

While the zjs.EventType class implements the necessary apparatus for custom events, I have also implemented a proof of concept DomEventType. I wanted to do this to prove to myself that the mechanism can be extended in that direction. It seemed reasonable to pick DOM events because they require a completely different approach to all aspects of their life cycle.

Because of the EventType abstraction, the zjs.EventSource class can provide a consistent interface to any type of event. But that is a story for next time.

Sunday, July 5, 2009

Events - Part 1

Recently I started using ExtJS at work. I have to say that I really like it. They've done a great job at consistency and predictability. It's not perfect (what is really?) and I do a fair bit of fighting with it to make it do what I need. But, of the large JavaScript frameworks out there, I have to give my vote for the winner being ExtJS.

There was a key concept in ExtJS (and YUI and others I'm sure) that I hadn't given enough thought to in ZJS: events. The reason I had skipped over eventing in ZJS is its entanglement with the DOM and browser. The core features of ZJS ($class, $namespace, et.al.) do not require a browser. They are deliberately language-centric and can run in just about any JavaScript host. For example, I've tested ZJS core.js under Rhino and WSH (Window Script Host).

Well, ExtJS reminded me that I can implement events in a similar manner. It will be limited somewhat in environments that don't have asynchronous notifications flying about, but ExtJS had good use for events from its Store objects and grids. The Store would fire events whenever data was loaded, for example, which did not require any advanced features.

In ExtJS, the event source classes derive from Ext.util.Observable. This class provides the addListener (a.k.a. "on") and removeListener (a.k.a. "un") methods and many others as well. A class that publishes events does so like this:


foo.Bar = Ext.extend(Ext.util.Observable,
{
constructor : function ()
{
this.addEvents(
"beforechange",

"change"
);
}
});


This creates some minimal bookkeepping for each event which is expanded when (or if) a listener comes along. This helps keep the memory footprint down. There are two things that bother me about this approach for events.


  • Events are 3rd class citizens in the object model. They are not added to a class like other pieces - rather a method of a specific base class does the work.
  • Being defined on the instances and not on the class not only wastes memory but also means there is no data about events at the class level (without an instance).

Events should be treated similarly to the methods and properties of a class - ideally declared in some fashion. There should be no required base class to expose events. Events should be inheirtable and have zero per instance overhead (until a listener arrives). Lastly (for now), the mechanism should be extensible enough to support DOM events and their many quirks.

Here's the syntax I've settled on:


$namespace(foo,
{
Bar : $class(
{
$events :
[
"beforechange",

"change"
]
});
});


Next time I'll cover how the above syntax was implemented and how to make use of it.

Friday, July 3, 2009

JSLint

One of the most frustrating things about writing in JavaScript has to be the general lack of help catching syntax errors. This is closely followed by the lack of ability to check for semantic errors. Due to JavaScript's late binding nature, and its history of being a component of the browser, these kinds of tools are only now (and slowly) appearing.

Some time ago I discovered jslint. Like many such tools, the only way to use it was to paste your code into the textarea of a web page and then click a button to get the report. While this works and does find your problems, it is not ideal for continuous use and is tedious to use for resolving more than a handful of reported issues. What I wanted was a JavaScript "compiler": something that could be integrated into the normal development cycle to find errors as I write code. Some time back I incorporated jsmin into the ZJS build process as an Ant task. Since the code for jsmin was written in JavaScript, I used a <scriptdef> to wrap the code in the necessary boilerplate.

As I wrote last time, I have recently extended <jsmin> to produce <jsbuild>. Where <jsmin> is purely fileset based, <jsbuild> actually reads the files to determine dependencies. Since I was already in the code, I figured I might as well dig in and include jslint as well. The code for jslint (5000+ lines) is a tad larger than jsmin (300+ lines)! And it had a particular philosophy on code style that I couldn't tweak via its provided options. You see, jslint likes this:


if (x == 4) {
doSomething();
}


But hates this:


if (x == 4)
doSomething();


This is clearly documented (see "Required Blocks") and when I asked Mr. Crockford if he would consider adding an option to not generate warnings for this style, he replied with a rather blunt "Nope.". Given the plethora of options (30 or more) in jslint, I was taken aback by his refusal to accommodate such a simple aesthetic difference of opinion. He's entitled, of course, and I cannot exactly complain since he is giving away the code for jslint. So I added the "reqblocks" option to his code as I incorporated it into ZJS.

It turns out that it was an utterly trivial insertion of a single "if" statement - the hard part, as you might imagine, was figuring out where to place it!

So now with the guts of <jslint> ready to go, I added a bit more logic to <jsbuild> to be able to invoke a nested sequential task whenever it decided to generate its output. The build script now looks like this:


<jsbuild out="${build.dir}/@{tag}/src/zjs/zjs-all.js"
level="@{jsmin}" verbosity="quiet"
packages="zjs=${src.dir}/zjs" modules="zjs.**">
<comment>${jscomment}</comment>
<onbuild>
<jslint src="${build.dir}/@{tag}/src/zjs/zjs-all.js"
report="${build.dir}/@{tag}/zjs-all-lint.html"
options="reqblocks=false,strict=false,onevar=false,undef=true,browser=true,forin=true"
console="true" globals="false" if="'debug' == '@{tag}'"
/>
</onbuild>
</jsbuild>


I experimented with <jslint> all by itself against each individual file:


<jslint options="reqblocks=false,strict=false,onevar=false,undef=true,browser=true,forin=true"
console="true" globals="false">
<fileset dir="${src.dir}/zjs">
<include name="*.js"/>
</fileset>
</jslint>


The <jslint> task supports the nested <fileset> or the "src" attribute, but what I found was that jslint gets cranky when dealing with files that depend on each other. It complains about any globals defined in file 1 and used in file 2. This is because I had to invoke jslint anew for each file for its reports to have the proper line numbers.

Things worked much better when jslint was invoked against the output file from <jsbuild> since it had included (almost) all dependencies. While there may still be gaps (due to excluded modules or packages), the result was much closer to what I wanted. The last detail I had to sort out was how to streamline dealing the numerous reports spewing from jslint. By default, the jslint report looked like this:

Problem at line 1234 character 17: Missing semicolon.
return x

The "problem" with this format was that the NetBeans output window just viewed it as dumb text. I wanted to be able to click on the output and jump to the offending code. I also did not want to write a NetBeans plug-in to do the necessary hyperlink magic!

And it turns out I didn't have to. It dawned on that tools like javac and Ant were unaware of NetBeans and its output window, yet their output was getting linked to the source. I figured there must be some recognizer in NetBeans that translates certain output patterns into hyperlinks. To test this out, I remembered that the output of javac for the same diagnostic would have looked like this:

/foo/inputfile.js:1234: Missing semicolon.
return x
^

With a little HTML stripping (the jslint report is laden with HTML) and some regex juju, I translated the jslint output into the javac format - and bingo! Links in my output window! Granted they go to my generate zjs-all.js file, but that's good enough for now! Well, that and the "if" attribute on jslint so I can run it only on the debug build - jslint also doesn't like the output of jsmin as its input. Go figure.

Future: As the dust settled, I realized what is really called for in <jslint>: a hybridization with <jsbuild>. If I could express the same package paths and scan for dependencies, I could squeeze the last of the noise out. I could produce a temporary buffer that contained all the dependent files for each input file (even those I would normally filter out in my <jsbuild>) and pass that to jslint. I could then scrub all the messages from jslint that did not apply to the lines coming from the target input file and rebase the line numbers as well. With a little caching of these files and dependencies to speed things up, I could see getting a convenient and super accurate result pointing at the proper source files.

This would easily take 4-8 hours or more and I'm just not feeling like it today. I'll just sit happy with my now jslint clean build of ZJS!

Sunday, June 28, 2009

JSBuild

I finally did it. I broken down and cracked open my <jsmin> Ant task. It worked fine when crunching down file-for-file. When compiling multiple files into one, however, things got a bit problematic. The reason is probably obvious: the constituent files cannot be concatenated together in just any old order if you want to produce a usable result.

For the longest time I have lived with that problem by adding a set of specific files and then dragging in the rest wildcard style. Some reordering is not a problem after all. What was called for was an Ant task that understood how to navigate module dependencies and produce a file that would always work. The groundwork was already in place with the $requires functionality. This approach is already being used by $import.

So, here's what the new <jsbuild> task looks like in action:


<jsbuild out="${build.dir}/debug/src/zjs/zjs-all.js"
level="1" verbosity="quiet"
packages="zjs=${src.dir}/zjs" modules="zjs.**">
<comment>${jscomment}</comment>
</jsbuild>


I'll document this more fully on the ZJS wiki, but the basic idea is that jsbuild will compile a list of modules from one or more packages. The list of modules can use wildcards like “*” for every module in a package or “**” for every module in a package or any of its subpackages. There can also be a list of excluded modules.

While ZJS has been growing, it remains small by any objective measure. If the maintenance of this kind of thing was a frustration on the small scale, one can only imagine how bad things would get on a large scale! So while build process improvements aren't exactly the focus of ZJS, it is something we all have to grapple with. The jsmin and now jsbuild Ant tasks help elevate JavaScript in this area just like the high level OO mechanics of ZJS do for coding. And it doesn't hurt that the build process can leverage things defined by ZJS (like $requires) to eliminate redundant dependency information.

Enjoy!

Why namespace?

Last time I alluded to the deepened relationship between classes and namespaces in ZJS v3. I want to expand a bit on that note because of the significance of scoped lookup. Without scoped lookup, there were many compromises when writing code. Often I would be writing a class hierarchy with a base class and one or more derived classes collected together. This required annoying hoop jumping to complete one call to $namespace to get the base class registered and then make another call to add the derived class. Of course, this had to be repeated once for each derived class. For example:


$namespace(“foo.bar”,
{
Base : $class(
{
})
});
$namespace(foo.bar,
{
Derived : $class(foo.bar.Base
{
})
});


Also, when defining the derived class I had to specify the full name of its base even though it was in the same namespace. It got the job done, but it was awkward. Granted, JavaScript has different notions of scope compared to other languages, so while these deficiencies were understandable, they were, nonetheless, counter-intuitive at times (especially for new comers).

From the very beginning of ZJS I decided that namespace population should be done intelligently. The primary reason was to help detect errors and avoid overwriting members of the namespace. In later versions, I added ways to express the desire to overwrite namespace members in a controlled way as well as adding members conditionally. In fact, the overridding feature even has the ability to use $super to call the overridden method. As it turns out, the ability to conditionally override a namespace method can be quite handy when dealing with browser differences.

Other libraries don't provide a method quite like $namespace. For example, in ExtJS, the Ext.namespace method simply creates the namespace and does not populate it. The approach taken by ExtJS is perhaps the closest to ZJS, though I think this:


Ext.namespace(“foo.bar”);
foo.bar.Base = Ext.extend(Object,
{
...
});
foo.bar.Derived = Ext.extend(foo.bar.Base,
{
...
});


Is decidedly less pleasing. I suppose one could always use a bulk update method:


Ext.namespace(“foo.bar”);
Ext.apply(foo.bar,
{
Base : Ext.extend(Object,
{
...
})
});
Ext.apply(foo.bar,
{
Derived : Ext.extend(foo.bar.Base,
{
...
})
});


This looks more like the ZJS version but has some distinct draw backs. For starters, it still does not look declarative: Ext.apply is clearly an imperative statement. It is also a tad more verbose because “foo.bar” must be repeated. Finally, and more importantly, Ext.apply will blindly overwrite things already present in the namespace.

By encapsulating the tasks of namespace creation and namespace population, the $namespace design has enabled the addition of several new and more flexible techniques for populating namespace that flow very naturally from the original definition. I already have some ideas on what other features might be useful in $namespace and I have every confidence that they can be added with minimal impact.

Tuesday, June 16, 2009

Why classes?

I want to continue with the philosophical ground work underlying ZJS. I have already touched on the centrality of “class” to OO programming. There is some debate, though, on this topic as it relates to JavaScript. For example, this excellent article by Douglas Crockford (a JavaScript luminary) describes how he has moved away from the classical style all together.

Even so, every major JavaScript framework (e.g., ExtJS, Dojo and YUI) that I have used includes, at its core, a class emulation mechanism. I don't think this can be solely attributed to the desire for familiarity of expression on the part of those coming from more classical languages. As I see it, the reason for this is that the “class as a unit of functionality” paradigm is extremely compelling.

Sidebar: I was very disappointed when the C Standards committee decided to not include “class” in its future plans. Their reasoning, as I understand it, for shunning classes was a total strawman argument: the logical culmination of that path would be C++ (which I suppose many C programmers view as over-bloated). It does not take formal training in logic to see that this argument is vacuous. It would have been beneficial to C even if classes only supported single inheritance. In fact, C++ won the hearts of many while it was in that state of its evolution.

Sorry for that. Now that I'm back from my rant, I imagine you can tell where ZJS began: I wanted to see how close to a classical, declarative style I could get with JavaScript. Of course, the first question to answer was “what is a class?” or alternatively “what features should class emulation provide?”. For starters, the inheritance mechanism provided by JavaScript (the prototype chain) is a single link list of object-to-prototype. Virtually all class emulation approaches are built around the prototype chain and for good reason. So this answered the first part of the question: single inheritance. While multiple inheritance can be simulated, I think it goes against the core of the language and wouldn't work well with other features that I had in mind. This approach worked out well for Java and C# and, while multiple inheritance is available in C++, it is typically shunned by practitioners.

These languages are not, however, dynamic languages and as a result, as Douglas Crockford again pointed out, JavaScript can be a more capable language. I do think these capabilities come from JavaScript being a dynamic language more than from its use of “prototypal” inheritance. So, when I set out to emulate constructs (like class) from static languages, I wanted to avoid limiting the dynamic capabilities of JavaScript.

For this reason the core mechanism for class definition in ZJS uses the more general concept of $mixin. What $mixin does is provide a means to extend an already defined class. This is not inheritance because $mixin does not create a new class: it modifies an existing class. By defining classes in this manner, users of libraries are able to safely inject logic into library-defined base classes.

In the version 3 of ZJS, $class is now even more connected with $namespace to provide scoped lookup support which, to my knowledge, is unique in the JavaScript world. Not to boast or anything; I have found many good ideas and inspiration in other libraries. For example, the whole concept of conditional members I borrowed (and extended) from base2.

I mentioned in my previous post that I have little hope that the JavaScript community will ever converge on any library as a platform on which most (or even many) other libraries are built. This is sad because there would many benefits to a common solution to these problems. The first would be a single learning exercise for users instead of learning a new approach for each library. A second benefit would be interoperability between libraries. Today, one must use the appropriate, library-defined mechanism to extend or derive from one of its classes. I won't continue, but I still hold out hope that these ideas can cross-pollinate and eventually lead to similar features and (hopefully) syntax in other libraries.

In summary, on the aesthetic level of syntax, I think ZJS has achieved as elegant a solution as can be had in JavaScript. See my comparisons for examples in various frameworks. I am interested to hear what others think, so do drop a comment or two if you have chance.

Saturday, June 13, 2009

Why ZJS?

In my enthusiasm to get the blog off the ground, I started off with a rather deep article. It's probably a reasonably obvious concept, but I wanted to rewind back to the beginning. I wanted to write about ZJS, why I created it and what I hope to accomplish.

My programming language background is C, C++, Java and (lately) C#. This family of languages shares many things with JavaScript, but JavaScript is clearly a different creature. On the surface, JavaScript looks more like C because functions are one of its primary means of organization. In fact, my early exposure to JavaScript never gave me any idea that it was more than a type-less derivative of C with some homage to OO concepts – we could have objects with properties.

When I was put into my first large project involving JavaScript, I did what I usually do: I tried to find better ways of organizing my code and started to learn all that I could about the language itself. It was then that I discovered closures, object literals and a whole universe of libraries attempting to fill in the missing pieces. These missing pieces come, I suppose, from the lack of declarative ability in JavaScript.

Everything in JavaScript is imperative. You don't declare functions, you create them! You can create a function more than once, and the second will simply overwrite the first! Amazing. Well, to me anyway. You see, one of the things that I found that profoundly impacted my entire way of thinking as I moved from C to C++ was the ability to declare things. Not just functions, but a mystical new thing called a “class”.

As I see it, the concept of a “class of objects” is one of the most powerful tools of thought we have in the realm of programming languages. Even when stripped of many of the things that we might define as very important (like interfaces, access protection and even inheritance), the act of grouping code and data in to a cohesive bundle is, by itself, a massive improvement over the alternative.

That alternative is an amorphous and monolithic mass of code. Without the class, a maintainer is lucky if the original authors had followed any convention to aid in understanding: either of function names, order of placement, separation into files or some comments. I've only had the pleasure of working on one project (in C) where the creators had the discipline to establish rigorous naming conventions and followed standards that produced an intuitive and well structured program. That was a good thing, because it was a mere 300,000 or so lines of code. A medium sized program really, but of a size that maintenance would have been intolerably painful otherwise.

Fast forward about 15 years from that experience and I found myself trying to deal with a significantly smaller body of JavaScript code (only about 10,000 lines). It was a mess. Functions seemed to be randomly placed, had few if any comments (wouldn't want to pay for their download after all) and was generally a nightmare to maintain. The sad part is that it had been written by a team of senior level Java programmers who would never have considered doing such violence in that language.

So that's the baggage I carry. I wanted very much to push the boundaries (at least of my understanding) and see just how far one could take the features in JavaScript towards a more declarative style of object oriented programming. At the same time, however, I didn't want to strip the language of its most powerful, dynamic features by creating a framework that didn't mesh with its spirit.

So, what do I hope to see from all this? Of course I would love to see other libraries or widget toolkits build on top of ZJS so that we could stop reinventing the wheel. While that would be ideal, I think that outcome is highly improbable for numerous reasons. Even so, I think there is every chance that those working on other libraries might be inspired by what they find in ZJS and mimic its solutions. Without trying to boast, I think ZJS has achieved a level of succinctness and expressiveness that puts it above just about any other approach of which I am aware. Granted this is highly subjective, but it was that lack of crisp expression of intent without compromising the language that prompted me to start ZJS in the first place.

As I see it, if other libraries imitated (or outright copied) some of the things found in ZJS, I would be delighted. In the meantime, I'll continue to enhance ZJS and treat it like my little think tank. There are many areas I still want to address or redress. I suppose there will always be room for improvement! And I welcome any feedback along those lines: positive or negative.

Sunday, June 7, 2009

Scoped Lookup (Now in 3.0.0b1)

This was originally posted to the ZJS News wikipage 31-May-2009, but was moved here instead.

The massive rewrite required of the internals of $namespace, $mixin and $class to support base-class-by-name is done! I was surprised at just how differently things had to be done to defer resolution of class names! The first 80% went quickly: support for classes added to a namespace. The second 80% was worse: support for inner classes.

The code is not much larger than it was without this feature. It's just more interesting.

In the end, the unit test now looks something like this:


A : $class(
{
ctor : function ()
{
$super(arguments).call(this);
}
}),

B : $class("A",
{
ctor : function ()
{
$super(arguments).call(this);
}
}),

C : $class("A",
{
N : $class(
{
Q : $class("N",
{
})
})
}),

D : $class("B",
{
N : $class("E.E2",
{
ctor : function ()
{
$super(arguments).call(this);
},

Q : $class("N",
{
ctor : function ()
{
$super(arguments).call(this);
}
})
})
}),

E : $class("C",
{
E2 : $class("E3",
{
ctor : function ()
{
$super(arguments).call(this);
}
}),

E3 : $class("B",
{
ctor : function ()
{
$super(arguments).call(this);
}
})
})


Remember, this is just to test the mechanism in a worst-case way; don't ever try something like this in a real program! If you do, at least don't say you got the idea from me!

Welcome

It's now come full circle. I started the ZJS project on Google Code as an offshoot of my "other" blog and now I've started this blog as a place to drop off my thoughts on ZJS development.

Being a developer first and foremost, I find it almost relaxing to work on ZJS in my spare time. I've enjoyed adding lots of features that I think others may find useful, but I've had no good forum to discuss (or at least expose) what I've done and why things have been done in certain ways.

So here it is. Ask any questions you like and I'll try address whatever topics come up. Or just leave some comments if you've looked at ZJS: favorable or otherwise.