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.