It's also worth noting that I've commissioned Chris Pasillas, a friend from Cal Poly who studied Computer Engineering before getting his degree in Music with piano performance and composition. Chris drafted at least one sketch for each of the faces of the Tale World this week. The sketches are in the Tale Subversion repository. Each sketch is denoted by a number and a name for each face and tension level. Tension levels include "town", "adventure", and "battle". He's also working on a motif for each face. Please send us your comments and suggestions.
Sunday, May 13, 2007
Chiron Automated Tests
It's worth nothing that I've posted the current results for automated unit testing for Javascript library.
The automated test system uses a web browser, an HTTP daemon, a client web page, and a batch of javascript unit test files. A script launches the daemon with an argument list containing a manifest of all of the javascript unit test files. The daemon serves all of the Chiron files, a logger, a reporter, and a test file-name iterator. The script then opens a web browser and navigates to the client page. The client page supplants the usual test.js module with its own autoTest.js module (in an aspect oriented fashion) so that the unit test assertions and timers get logged to the server via an HTTP request. Then, the client page iteratively requests a test URL from the server and opens the test in a new window. After all of the unit tests have run, the client opens the test results page.
In the future, I would like to use up a database and leave the test daemon running before and after each Subversion commission so that test results can be gathered from a suite of platforms. Then, there would be a catalog of performance and coverage trends.
Saturday, May 12, 2007
Cixar Javascript Library and Names
The name "Cixar Javascript Library", or CJL, has numerous virtues. It has a three letter acronym, a full name long enough to asphyxiate a cheetah, conjures absolutely no mental image, nor alludes to any works of art or literature.
I'd like to announce that, having rigorously contemplated the issue from a vantage about two feet above my naval (that is, half of a meter for our dear friends huddled safely distant from the sanity interference field), I've decided to name the Cixar Javascript Library. My requirements are succinct:
- one word,
- allegorical, preferably ambiguous,
- eminently brandable,
- subtly humorous,
- an alternate spelling in Unicode,
- If possible, the name must enamour an attractive girl no more than five years older or younger than me before Monday.
I browsed Wikipedia and discovered Ajax's centaur tutor, Chiron. So, there you have it, the library's name is Chiron. I leave it as an exercise for the reader and my fate/doom to discover whether it will suffice. However, I will explicitly state that brandability is fulfilled. Chiron, it turns out (back me up on this, Wikipedia), was really half-cow, the only Centauren to grace the Hellenic Pantheon.
For prospective users of Chiron, I have a question of nomenclature preference. Use of the Chiron library requires the HTML author to include exactly one script tag in their header, modules.js (13KB shrunk but not compressed). From there the author can opt to use whatever modules they will.
Central to the Chiron library is a module currently called javascript.js that contains exceptions (KeyError), the type system (type), common types (Dict, List, Iter), and a wealth of common functions (forEach, stripEnd) (currently 36KB shrunk but not compressed). Since I would like to give the user the option of not loading this module, most modules explicitly include it, even though in a language like Python, these primitives would be implicitly available.
I called the module javascript.js since it would include primitives that in Python would be part of the language. In Python, this module would probably be called __builtins__.py. In any other Javascript library, precedent suggests that that module would be called base.js.
Which of the following should I call this module of language primitives?
- javascript.js,
- builtins.js,
- base.js,
- your idea here.
Please send me an email and weigh in.
Javascript and Load Time
I conducted a quick experiment to assess whether it is worth worrying about the size and distribution of Javascript modules. I gathered the following numbers on my Linux box at home (fast) connected to Cixar (fast) over my home Internet connection (average today).
ping cixar.com | 30ms | |
ping google.com | 80ms | |
HTTP overhead | 30ms | |
bandwidth | 0.1KB/ms | |
patience | 1500ms | |
maximum size | 150KB | |
Chiron core | 100KB | |
Chiron core shrunk | 50KB | |
Chiron core shrunk compressed | 13KB |
I've decided not to worry about the size or distribution of Chiron until its core is five times bigger.
Friday, May 11, 2007
Higher Order Functions in Javascript
Recently I discovered that a friend of mine isn't using "Higher Order Functions" in their Javascript. I cried. However, I fear, this is common-place, perhaps some artifact of a latent and ubiquitous fear of closures instilled by Internet Explorer and the folklore that arises in the absence of reliable, or believable, information. In any case, I'm resolved to expound the virtues of this lesser known programming paradigm among object oriented language aficionados.
Higher Order Functions are functions that accept or return functions. This variety of insanity is possible in functional languages, or languages that provide closures. It is of course possible to accept and return function pointers in C or its ilk, but these are not sufficient for Higher Order Functions because you cannot create functions that can refer to the local variables of the function that instantiated them. This is the crux.
It is helpful to think of a name space as an Object. Calling a function creates a local name space, rooted in the name space in which the function is declared. Unlike in assembly languages, these name spaces can persist, as Objects do, long past the lifetime of the function call that created them. Like Objects, a name space exists as long as a reference exists referring to it. However, among name spaces, the only way to refer to a name space is to create a name space rooted therein. This means that the local variables of a function call exist as long as another function's name space refers to it.
Permit me to offer a practical example, one that any one can use every day of the week. Sort functions in most languages accept an optional comparator function as an argument. C++'s Boost library for example accepts predicates. This is, of course, an insane hack since C++ isn't designed for functional fu. Python provides sorted and accepts a comparator. You don't have to believe me; the important point is that Javascript follows suit.
This is the default sort behavior.
var items = [3, 1, 2]; items.sort(); assert(items == [1, 2, 3]);
A comparator is a function that accepts two arguments and returns an integer indicating whether the arguments are equivalent, sorted in ascending order or in descending order. The result of a comparison call can be compared to 0 (on the right hand side of an expression) with ==, > and < and the result will be exactly the same as if the operands were replaced with the comparison arguments respectively. So, if compare(a, b) == 0, then a == b, if compare(a, b) < 0 then a < b. The simplest compare function provides these results for numbers.
var compare = function (a, b) { return b - a; }
This example, provides a reverse comparator; a comparator that will sort numbers in descending order.
var compare = function (a, b) { return -(b - a); }; var items = [3, 1, 2]; items.sort(compare); assert(items == [3, 2, 1]);
Of course, there are all manner of objects that you might want to sort, and not all of them are strings and numbers. Supposing you had an array of people, you might want to sort them by their last name. You can do this with a comparator.
var compare = function (a, b) { if (a.lastName b.lastName) { return -1; } else if (a.lastName == b.lastName) { return 0; } else { return 1; } }; people.sort(compare);
Of course, it would be cumbersome to give highly descriptive names to every block of code you wrote and used once, so it's no more reasonable to have to name all of your comparators. You can just use an anonymous function.
people.sort(function (a, b) { if (a.lastName b.lastName) { return -1; } else if (a.lastName == b.lastName) { return 0; } else { return 1; } });
However, you will find that all of your comparators will have the same shape. They will probably all test equality and lessity. It would be beneficial if you had a function that would create comparators for you just based on the attribute of the object you want to compare. Enter higher order functions. Let's construct one such function.
We want to create a function that accepts two elements and returns a number reflecting their transitive relationship, a comparator, based on some attribute. So, its clear that our function will accept an attribute name, and return a function.
/* the higher order function: */ var by = function (attribute) { /* the comparator: */ return function (a, b) { }; };
Lets see the function in full.
/* the higher order function: */ var by = function (attribute) { /* the comparator: */ return function (a, b) { if (a[attribute] b[attribute]) { return -1; } else if (a[attribute] == b[attribute]) { return 0; } else { return 1; } }; };
The important leap here is that the comparator can refer to the attribute from its enclosing name space, even though that function will have completed and been popped off the "stack" long before we ever call our comparator.
We can use our mighty by function to sort people by last name much more readably and succinctly.
people.sort(by('lastName'));
For good or ill, this will work for rigid arrays of arrays (tables) as well, if you provide an integer instead of an attribute name. I say this with half of a heart because it's a Pyrrhic victory. The price of being able to perform member selection and array indexing with the same, generic syntax is the inability to distinguish member selection for associative array (or hash) indexing, but that is a tale of woe for another day.
var table = [ ['Kris', 'Kowal', 3], ['Ryan', 'Paul', 2], ['Ryan', 'Witt', 1] ]; table.sort(by(1));
In any case, this demonstrates the power of higher order functions in your every day life. If you don't like the for (var i = 0; i length; i++) pattern (as you ought be weary of by now), modern Javascript implementations provide a higher order function, Array.forEach. From the pantheon of functions you will also find map, fold or reduce, filter, compose, partial, and others. Happy coding.