This blog is highly personal, makes no attempt at being politically correct, will occasionaly offend your sensibility, and certainly does not represent the opinions of the people I work with or for.
Introducing Atlas
Atlas is a triple star system in the Pleiades open cluster (M45). It is also known as 27 Tauri.

It all started two days ago when Nicky posted the following comment to my entry on Pleiades Enhancements "Few more entries and you will have re-implemented Smalltalk in Javascript. :-)". What had happened is that I had given to the Pleiades root object a native way to handle the addition (or redefinition) of new methods and accidentally the code started to look more like a classical object oriented language when it came to program managers (Pleiades primary objects managing their collections of delegates to achieve a particular encapsulated effect or feature).

I pondered Ni's remark, and even thought I am not going to re-implement Smalltalk in Javascript the way the Cappuccino folks implemented Objective-C in Javascript (not because I cannot do it, and even if it's one of the truly interesting languages after Lisp, but because the syntactic glamour is not worth the pain of parsing, lexing, tokenizing and other syntactic enjoyments), I nevertheless thought that Pleiades deserved a better handling of object's methods and even more reflexivity.

So, I have re-implemented the entire Pleiades objects model. Wasn't difficult at all, but was a bit tedious. In the beginning Pleiades had its root object, called PrimaryObject, and a small tree of object hierarchy. Extending the hierarchy was a bit painful due to my initial use of javascript's native prototyping scheme (not bad at all, but can be a pain due to cross browsers inconsistencies in the way it works). It would not have been possible for users of the Pleiades framework (mainly me so far), to extend the Hierarchy without a good knowledge of it. As a result of my own laziness my coding was moving toward building more complex structures on a 'has-object' basis rather than 'is-object' basis. In other words I was overusing the decorator pattern rather than relying on a somehow more familiar classical inheritance.

Atlas has changed all this. Atlas' PrimaryObject is a Pleiades root object to which I have added two methods to handle Delegates (the entire purpose of this, was to facilitate the task of Pleiades' garbage collector).

Then I have re-implemented the existing Pleiades' object tree above Atlas' PrimaryObject using the new method definition thing. Now the entire structure is much better designed, doesn't rely at all on Javascript's understanding of inheritance and let users of Pleiades either extend the objects that I provide or define their on stuff directly from Atlas PrimaryObject as easily as I did in my code sample two days ago. Something worth noticing about Atlas, is that methods are defined by (and referred to using) strings (even containing spaces); therefore '@1 2[ ; 90q' could be the name of a method.

Now, with Atlas being the new way to create objects, I have a framework which still natively supports object's persistence (when an object is spawned somewhere it doesn't disappear under javascript own garbage collection); which still natively (because before being Atlas objects are Pleiades objects) understand Pleiade's primary purpose: broadcasting; and behave under class extension the very same way that your PHP or Java objects do. With the difference that overriding a parent's method really overrides it, there is no way to do the PHP's parent::MethodName(), which as far as I am concerned not at all a problem. I may regret having said that, but if one day I do, it will take me only few hours to implement it.

As a consequence of all this, a pattern has emerged in my code. A manager (or more generally anything which has and manages delegates) talks to them using classical (kind of) method calls, and unrelated parts of the structure (UI elements or not) simply subscribe to each other state changes (and more generally communicate with each other) using the broadcasts. There is obviously a bridge between both worlds: a method can send a broadcast, and the effect of receiving a particular broadcast of interest may be that a method will be fired. Writing the HypGL documentation I realized that some parts of it expose their functionalities (API) as a set of channels (for incoming and outgoing messages) and message types, and not at all as functions and their signatures... This is admittedly an extremely powerful form of encapsulation.

Now that methods definitions are handled the Atlas way, automatic delegation, reflection, objects rewriting their own code, etc. are natural consequences. Of course, Pleiades and Atlas are implemented in javascript because I use javascript, but any language which has a basic idea of what an array is and treats its functions as first class citizen can host them.

I remember that all this work on frameworks started because I was looking for ideas for Hypercube version 4. Well I decided that there would not be any version 4 (not for web GUI related reasons anyway) and that HypGL would continue to be build above Pleiades/Atlas on one side and the Yahoo UI on the other side (this latter used by objects whose purpose in life is to do web page rendering).

And last thing, someone was asking whether I do not have any memory leaks given the object persistence. Not really actually. This comes from the fact that managers carefully run the .Destroy method on their delegates when it's the good time, and otherwise "floating" Pleiades objects, when I create them, I often fire their .DestroyOnBroadcast(label) method. I know that a subsequent event happening somewhere will send a notification which will kill those who must die. And last, it is always possible (when creating an object) to specify their life time, this uses the Transformers. In this latter case the scheduled transformation consists in one own .Destroy() method.


The Selector, one of my favorite and most handly Pleiades object, now an Atlas object, is defined below. It uses a delegate -- an Atlas.Division() object-- for its rendering and reacts to one of it own broadcasts: a user click on some parts of its delegate screen rendering. An interesting thing here is that the broadcast channel used by the delegate is the Selector's own unique identifier (a string admittedly known only by those two guys -- even me has got no direct power on what it is).

[ add a comment ]