Monday, January 26, 2009

Joose 2.0 Call for Testers

Hey,

we are in the final phases of prerating the next release of Joose. Please click on this link to the test suite and report any cases of green or especially non-green output.

Notice that the test suite will prompt you for Google Gears authorization if you have Gears installed. It is, however, not neccessary to run the tests.

Thank You!

Positive Results so far:
  • FF 3.05 OSX
  • Safari 3 OSX
  • IE8 beta Windows XP
  • FF 2 Windows XP
  • Chrome Windows XP
  • Opera 9.62

Sunday, January 18, 2009

Multi-method dispatch for JavaScript

Once again, reporting live from the because-you-can department:
Jeremy has created an initial implementation of multi-method dispatch in Joose. It allows you to define a set of methods in a class that have the same name but differ with respect to the signature of the argument types. Once you call such a method-name, the dispatcher will look for the most appropriate method (based on the runtime types of the parameters (Are they still parameters or are they already arguments at this stage? (I think still parameters))).
Here is a link to the raw test-suite, that is currently passing.

The implementation hasn't been hooked up to a class-builder syntax and probably needs a lot of edge case work and performance tuning. However, I think it is a great example of what can be done with JS and I'm eager to try it out in practice to check whether it gives value to every-day JavaScript programming.

Typed Method Signatures in Joose/JavaScript (parseInt never again)

Typed method signatures have landed in Joose. This is what you get from the new feature:
  • You can define type constraints, classes and roles that a method parameter must match
  • If the type checks fail there is a runtime exception
  • If you enable coercions, Joose tries it's best to convert the parameter types to the one you want!
That is why I call type coercions the death of parseInt (and friends). JavaScript client side programming deals with a lot of user provided string data that needs to be validated and converted to domain values. With type coercions, once you have defined your types (or the use the built-in types), input validation and conversion is completely transparent to your code.

Lets consider this example: If you want to write code that adds the number 3 to the value of this input field: (Just an input-field with a 2 inside (for the feed readers))

To make this reliable, you need to
  • check whether the value of the input field is actually something that can be added to (in a numerical sense)
  • convert the value from a string to a number
This is where Joose type coercions can help you. Here is the code doing all that using type coercions:
    // Make a class thats adds to its instance variable "amount"
Class("Adder", {
has: {
amount: { is: "rw" }
},
methods: {
// add is a method with a signature
add: {
signature: [Joose.Type.Int], // the first parameter must be an integer
method: function add (num) {
return num + this.amount // add the argument num to our instance var amount
},
coerce: true // enable coercions for arguments
}
}
})

// Make an adder that always adds 3
var addTo3 = new Adder({ amount: 3 })

// add 3 to the value of the input field
alert(addTo3.add(form.addMe.value));
If you would run the above code without type constraints and coercions the result of the method would actually be "23". The code above, however, does the right thing and alerts 5.
This is obviously a lot of code for such a trivial use case, but once things start to become more complicated you save a lot of typing, produce code that might have less bugs and document your parameters a little more thoroughly. The extra benefit of the Joose built in types is that we already wrote unit tests for them (allthough there is always room for more) so you don't have to.
I'm aware that a lot of JavaScript purist will find this totally over the top, but as we go into writing ever more complex JS applications things like this have their place. I, personally, find it great that I get extra security while being lazy at the same time.

Thanks again for the great input from the discussion on the best builder syntax. The current syntax is not final, however. I chose it, because
  • it fits well into Joose
  • the types are close to the actual signatures
It is not ideal, because
  • unless, you repeat (which is bad) the method name in the function declaration, your methods will be called "method" in firebug and similar tools.
  • is is pretty verbose
New ideas that would eliminate these short comings are very welcome.
You might have noticed, that coercions needs to be enabled by opt-in. This is due to the fact, that coercions come with a pretty heavy performance penalty. It is absolutely no problem in a use case where you have a "front-end" function to parse user input (DOM access is magnitudes slower) but might be too big for your canvas ray tracer.

Tuesday, January 13, 2009

ToDo List for Joose 2.0

  • Finish Types implementation (stricter RegExes, more tests)
  • Implement experimental support for typed method parameters
  • Finish Dojo bridge in addition to the Ext and PureMVC helpers (not really neccessary but would be nice)
  • Make the traits implementation more spec compliant (Based on Joseph Hurst's work on JSTraits)
Meanwhile Nikolay is working in a branch to refactor Joose's internals to make them easier comprehensible. This work, however, won't be included into the next release.

Any wishes for the next release?

Sunday, January 11, 2009

A PureMVC/Joose example

I changed the strategy a little with the Joose2PureMVC bridge. It no longer "joosifies" all classes of the framework but rather allows subclassing classes of the PureMVC framework using Joose. The reason is that I had to use too much dark magic to make the it work and it proved not be very stable.

If you care: The dark magic involved getting the meta data of the super class in a setTimeout call because the Objs.js system used in the PureMVC code changes prototypes after class declaration.

To try it out you can download I converted some code of an example app from the PureMVC website to use the Joose bridge. You can download it here. I joosified a single class that you can see at the very end of the file bin/employee_admin_demo.js.

The object system used by the PureMVC JS port requires to write a lot of boilerplate code for inheritance and calling the constructors of the super classes. This is all eliminated with Joose.

If you don't want to download the example app, here is the source code of the Joose class:
Module("org.puremvc.js.demos.js.employeeadmin.view", function () {

var EventS = Objs.load("net.tekool.events.EventS");
var Relegate = Objs.load("net.tekool.utils.Relegate");
var IMediator = Objs.load("org.puremvc.js.interfaces.IMediator");
var INotification = Objs.load("org.puremvc.js.interfaces.INotification");
var Mediator = Objs.load("org.puremvc.js.patterns.mediator.Mediator");
var Notification = Objs.load("org.puremvc.js.patterns.observer.Notification");
var ApplicationFacade = Objs.load("org.puremvc.js.demos.js.employeeadmin.ApplicationFacade");
var UserVO = Objs.load("org.puremvc.js.demos.js.employeeadmin.model.vo.UserVO");
var UserProxy = Objs.load("org.puremvc.js.demos.js.employeeadmin.model.UserProxy");
var UserList = Objs.load("org.puremvc.js.demos.js.employeeadmin.view.components.UserList");

Class("UserListMediator", {
meta: PureMVC,
isa: Mediator,

after: {
initialize: function () {
var userList = this._getUserList();
userList.addEventListener( UserList.NEW, Relegate.create(this,this._onNew) );
userList.addEventListener( UserList.DELETE, Relegate.create(this,this._onDelete) );
userList.addEventListener( UserList.SELECT, Relegate.create(this,this._onSelect) );
var userProxy = this._facade.retrieveProxy( UserProxy.NAME );
userList.setUsers(userProxy.getUsers());
}
},

methods: {
_getUserList: function() {
return this._viewComponent;
},
_onNew: function( event ) {
var user = new UserVO();
this.sendNotification( ApplicationFacade.NEW_USER, user );
},
_onDelete: function( event ) {
var selectedUser = this._getUserList().selectedUser ;
if(selectedUser == null)
return;
this.sendNotification
(
ApplicationFacade.DELETE_USER,
this._getUserList().selectedUser
);
},
_onSelect: function( event ) {
this.sendNotification
(
ApplicationFacade.USER_SELECTED,
this._getUserList().selectedUser
)
},
listNotificationInterests: function() {
return [
ApplicationFacade.CANCEL_SELECTED,
ApplicationFacade.USER_UPDATED,
ApplicationFacade.USER_ADDED,
ApplicationFacade.USER_DELETED
];
},
handleNotification: function( note ) {
var userList = this._getUserList();
var userProxy = this._facade.retrieveProxy( UserProxy.NAME );
switch( note.getName() )
{
case ApplicationFacade.CANCEL_SELECTED:
userList.deSelect();
break;
case ApplicationFacade.USER_UPDATED:
userList.setUsers( userProxy.getUsers() );
userList.deSelect();
break;
case ApplicationFacade.USER_ADDED:
userList.setUsers( userProxy.getUsers() );
userList.deSelect();
break;
case ApplicationFacade.USER_DELETED:
userList.setUsers( userProxy.getUsers() );
userList.deSelect();
break;
}
}
}
})
});

Thursday, January 8, 2009

Joosifying PureMVC

Based on Nickolay's work for Ext I implemented a Joose to PureMVC bridge. PureMVC is a MVC framework that was originally implemented for Flash/ActionScript3 but which has implementations for JavaScript, Java, C# and other languages.

Using the new Joose bridge you can use Joose to build PureMVC applications. You can use Joose's facilities to inherit from the PureMVC base classes and apply Joose-roles to all instances and classes included in PureMVC. The code works on the sample application. There seems to be no test suite in the main repository, so it cant be fully verified.

The bridge code is actually very simple. PureMVC uses a simple JavaScript class framework called objs.js. This framework provides a method called "register" to register classes and a method called "extend" to inherit from a super class. The bridge code overrides these methods. Thus automatically all classes from PureMVC can be turned into Joose classes without any further changes to the actual code of the framework.

You can download the code from the Joose repository. Just replace the file objs.js from the PureMVC download with the file from Joose and you are good to go.
The code was only minimally tested but seems to work. If there is further interest or as soon as I have a work project that uses the framework I'll invest further time in it.

Tuesday, January 6, 2009

Suggestions for method signature syntax

There have been some great suggestions for Joose's syntax for method signatures. More comments would be great.

Work to release Joose 2.0 is under way. Might happen next weekend.

Sunday, January 4, 2009

Type constraints for method parameters (and return values)

As an add on to type constraints for instance variables (see last post) we think about adding them to method parameters and maybe even method return values. The hard part here is not the implementation but rather to find a nice syntax to declare these constraints. Here are a couple examples of possible definitions for typed method signatures:
    Class("TypedMethodParas", {
methods: {
typed1: [
[Joose.Type.Int, Joose.Type.Date],
function (int, date) {
// ...
}
],

typed2: {
takes: [Joose.Type.Int, Joose.Type.Date],
does: function (int, date) {
// ...
},
returns: Joose.Type.Int
},

typed3: Method(Joose.Type.Int, Joose.Type.Date, function (int, date) {
//
},
Joose.Type.Int)
}
})

Which one do you like best? Do you have better ideas? Is this feature even worthwhile?

Go to Comments

Type Contraints and Type Coercions in Joose

There is a new feature in the upcoming Joose 2.0 that is called type constraints that has great potential of changing the nature of many JavaScript applications:

Joose type constraints are only somewhat related to types in the traditional sense of computer science. They allow the programmer to define a set of contraints which a value that is stored in a variable will have to fulfil. As they apply to values rather than containers these checks are performed at runtime rather than compile time.

In this class definition the attribute "anAttribute" is constrained to the type Joose.Type.MySmallNumber:
Class('MyClass', {
has: {
anAttribute: {
is: 'rw', // TypeConstraints only work for rw attributes
isa: Joose.Type.MySmallNumber, // use the MySmallNumber constraint
coerce: true // turn on coercions for this attribute
}
}
})
The definition of the type itself looks like this:
Type('MySmallNumber', {
uses: Joose.Type.Int, // this is a specilization of the Joose.Type.Int Class
where: function (value) {
if ( value > 1 && value < 5 ) { // we only accept Ints between 1 and 5
return true;
}
return false;
}
});
This type specializes the built-in type Joose.Type.Int which only accepts integers. Only values greater than 1 and smaller than 5 are accepted. If you assign values to instance variables which do not match this constraint, the program will throw an exception (As an alternative you may also add an onError callback as a second parameter to a setter-Method to handle the exception).

Type Coercions
The real magic starts when we add in so called type coercions. Type coercions are rules how values can be tranformed from one type to another (kind of like casting). Here is an example of the above type with one coercion rule:
Type('MySmallNumber', {
uses: Joose.Type.Int, // this is a specilization of the Joose.Type.Int Class
where: function (value) {
if ( value > 1 && value < 5 ) { // we only accept Ints between 1 and 5
return true;
}
return false;
},
coerce: [{ //optional coercion definition list
from: Joose.Type.Str, //coercion from string to number
via: function(str) {
return new Number(Str); //perform our coercion
}
}]

});
This coercion transforms values that have the built-in type Joose.Type.Str to integers.

Joose provides a set of built-in types for your convenience. These are organized in a hierarchy. Things that are further down the hierarchy need to match all the contraints of parent-types.

Joose type constraint hierarchy
This diagram has been created with the Joose sample app blok.


Conclusion
Type coercions have been proven to be extremely useful in JavaScript code because many tasks in JavaScript deal with user provided data that is in string form. Coercions provide a very convenient way to transform this string data into meaningful things. After the definition of the types your application code can basically "ignore" things like data validation and conversion. This makes the code more expressive and should reduce errors because it is harder to forget to validate data.

Further topics
Defining inline types
Localization
Type constraint API

This post serves as a draft for the future documentation for Joose's type contraint system and will then move to the Joose wiki page on type constraints.
If you want to play with the features, you will have to download the Joose 2.0 release candidate.

Friday, January 2, 2009

Aspect Oriented Programming with Roles/Traits and Joose

Joose is different from other JavaScript frameworks because it focuses on only providing tools for making the programming with JavaScript for robust and productive. There are no facilities for DOM access or AJAX. Joose is thus complementary to using a more traditional Ajax library and also works nicely in non-browser environments like Rhino.

Many JavaScript libraries with the notable Exception of jQuery provide some helper methods to make things like class or prototype inheritance a more pleasant experience. Joose's capabilities, however, go way beyond these basic features. My personal favorite feature in Joose is the combination of Roles (sometimes also called Traits) and method modifiers.

Here is the definition from the Traits research page:
Traits are a simple composition mechanism for structuring object-oriented programs. A Trait is essentially a parameterized set of methods; it serves as a behavioral building block for classes and is the primitive unit of code reuse. With Traits, classes are still organized in a single inheritance hierarchy, but they can make use of Traits to specify the incremental difference in behavior with respect to their superclasses.
In Joose creating a role (aka trait) is as easy as writing
Role("Eq", {
requires: "equalTo",

methods: {
notEqualTo: function (other) {
return !this.equalTo(other)
}
}
})
This role can be applied to things that implement the method equalTo and gives them the method notEqualTo. Things here means classes and (because this is JavaScript!) objects.
Applying to a class looks like this:
Class("TestClass", {
does: Eq
}
Applying to an object is a one liner:
Eq.meta.apply(myObject)
So much for simple traits. Where things get really interesting is when the concept of roles is combined with the concept of method modifiers (I call them M&Ms). M&Ms allow augmenting methods with extra functionality by doing stuff before or after a method is executed (The full list of modifiers is before, after, around, override and augment).
In this example Test derives from SuperClass and modifies SuperClass's add method with a before-modifier:
Class("Test") {
isa: SuperClass,
before: {
add: function () { this.result += "3" }
}
}
Now it is also possible to define method modifiers in roles. When the role is applied the method modifiers are applied to the methods of the target class or object.
From here on I'll use real world examples from the Joose example app blok. Things placed on blok's viewport are instances of the class Shape. Shapes can be resized, dragged, styled, edited, etc. All of these "behaviors" are implemented as roles that are applied to shapes.
A shape keeps a jQuery object in it's instance variable called $ that represents the DOM node of the actual shape-html on the viewport. Whenever the DOM node receives or looses focus the respective methods "focus" and "blur" are called on the shape object. The method "place" is called to place a shape on the view port. One of the roles that can be applied to shapes is the Focusable role. This role gives a shape the ability to actually receive a visual recognizable focus (aka an outline). Here is the implementation of the Focusable role:
Module("block.ui.role", function () {
Role("Focusable", {
after: {
place: function () {
var me = this;
this.$.mousedown(function focusClick (e) {
e.preventDefault()
document.manager.switchFocus(me, e.shiftKey)
return false;
})
},

focus: function () {
this.$.append('<div class="focusDiv"></div>')
},

blur: function () {
this.$.find(".focusDiv").remove()
}
}
})
})
This particular role augments the methods "place", "focus", and "blur". When the shape that uses this role is placed on the view port a mousedown event is added to the jQuery object. This event is than delegated to the global document.manager singleton-object that manages focus on the page (This object later calls the focus and blur methods on the shape objects. This is different from the browser's understanding of focus, because shapes may keep focus while a control elsewhere is used). When the shape receives focus an extra div is added to the jQuery object (this is not done using only css classes for stupid technical reasons). When the focus is lost, the div is removed again.

The examples should demonstrate that roles are great ways to assemble "reusable units of behavior" (as the orginal authors put it). Using method modifiers further reduces conflict potential between multiple roles because an unlimited number of M&Ms can be applied to the same method. Thus other roles like Resizable, Draggable, Connectable or Editable can be safely added to the same shape.

I particularly like the pattern outlined above because it feels really JavaScript-y. The use of roles makes the pattern superior to simple aspect oriented techniques using only method modifiers because multiple related modifiers can be applied in a single stepped.

I hope this post was interesting, now go play with Joose :)

PS: Thanks to Moose for comming up with all these concepts so that I could copy them for JavaScript.

Earlier post on the same subject.

Thursday, January 1, 2009

Comet or no comet?

People seem to be quite emotional whether UniversalComet deserves the word comet in the name, so here is some background on the technical details.
The UniversalComet API described in the last two posts uses a very simple/naive technique called polling to achieve the effect of near instant delivery of messages. The reasons for this kind of implementation are very simple and related to the fact that the application is implemented on top of Google App Engine (GAE):
  • GAE only allows a single unified response for HTTP requests. This means that techniques involving multi-part responses with multiple script-tags do not work.
  • The GAE quota system puts severe penalties on calls to sleep. Thus it is not really possible to implement a system where you would minimize the number of HTTP requests by waiting on the server until a reponse is available (even very short delays within 1 second are not accepted). I'm actually in touch with Google about this topic and there is hope that this limitation might be removed.
  • There is also a related issue on the GAE issue tracker.
Thus it made sense to use the simple polling implementation. On the other hand, it is true, that Google App Engine is currently not the right platform for implementing scalable comet solution (Although it deals quite well with the current traffic amount). One would have to look for custom hosting or a more liberal services like EC2 instead. However, App Engine is great to deploy just-for-fun proof-of-concept applications without having to worry all the hard stuff behind the scenes.

Anyway, the motivation behind UniversalComet was not really to explore implementation techniques for comet but rather an experiment to provide a very convenient way to give an URL to visitors of a website through which they can be contacted in near realtime by means of simple HTTP requests which I still think is a very interesting idea.