3. Introduction
Everyone likes JavaScript!
JavaScript is a very popular client-side language because:
It is a simple language.
It is a very dynamic language.
It is very closely tied to the DOM.
4. Introduction
Everyone likes JavaScript!
JavaScript is a very popular client-side language because:
It is a simple language.
It is a very dynamic language.
It is very closely tied to the DOM.
It is the only thing out there.
5. Problem observation
JavaScript is very well-suited for dynamic web pages.
Xopus is not a web page, but an application.
We observe some problems with the language:
There are only functions and objects.
No modules, classes, name spacing, explicit dependencies, etc.
No help to structure your program.
No such thing as ‘idiomatic JavaScript’.
7. Solving the problem
Luckily JavaScript is very dynamic, why not create us a paradigm
ourselves?
This presentation describes:
how we have created an ‘object oriented’ framework.
how we could keep this framework to be pure JavaScript.
how this framework can help us structure our programs.
how Xopus 4 uses this framework.
8. Framework
The framework supports:
Writing modules in an OO ‘extended subset’ of JS.
Hierarchically structuring programs into packages.
Some forms of program verification.
Making dependencies explicit.
Dependency resolution.
Consistent file-system layout.
9. Framework
The framework supports:
Writing modules in an OO ‘extended subset’ of JS.
Hierarchically structuring programs into packages.
Some forms of program verification.
Making dependencies explicit.
Dependency resolution.
Consistent file-system layout.
And:
Server side compilation to flattened form.
Serving the client efficient and possibly obfuscated code.
Even more!
10. Example
Package(quot;com.xopus.codequot; );
Import(quot;com.xopus.code.Foodquot; );
Extends(quot;com.xopus.code.Animalquot; );
Class(
function Monkey (name) { this.name = name; },
function getName () { return this.name; },
function favorite () { return new Food(quot;bananaquot; ) ; },
Static, function kind () { return quot;chimpquot; ; }
);
11. Example - compiled
(function (Food,Animal) {
var Monkey = comxopuscodeMonkey = function Monkey (name) { this.name = name; };
Monkey.prototype.Monkey = Monkey;
var Monkey prototype = Monkey.prototype;
Monkey prototype.getName = function Monkey getName () { return this.name; };
Monkey prototype.favorite = function Monkey favorite () { return new Food(quot;bananaquot; ); };
Monkey.kind = function Monkey kind () { return quot;chimpquot; ; };
for (var method in Monkey.prototype)
Monkey.prototype[method]. class = Monkey;
for (var prop in Animal.prototype)
if (Monkey.prototype[prop])
Monkey.prototype[Identifier({Animal:1}) + quot;$quot; + prop] = Animal.prototype[prop];
else
Monkey.prototype[prop] = Animal.prototype[prop];
}).apply(this, [comxopuscodeFood,comxopuscodeAnimal]);
12. Example - construction
(function (Food,Animal) {
var Monkey =
comxopuscodeMonkey =
function Monkey (name) {
this.name = name;
};
Monkey.prototype.Monkey = Monkey;
var Monkey prototype = Monkey.prototype;
...
}).apply(this, [comxopuscodeFood,comxopuscodeAnimal]);
13. Example - methods
Monkey prototype.getName =
function Monkey getName () { return this.name; };
Monkey prototype.favorite =
function Monkey favorite () { return new Food(quot;bananaquot; ); };
Monkey.kind = function Monkey kind () { return quot;chimpquot; ; };
for (var method in Monkey.prototype)
Monkey.prototype[method]. class = Monkey;
15. Example - inheritance
for (var prop in Animal.prototype)
if (Monkey.prototype[prop])
Monkey.prototype[Identifier({Animal:1}) + quot;$quot; + prop] =
Animal.prototype[prop];
else
Monkey.prototype[prop] = Animal.prototype[prop];
16. Compilation
Server side compilation (currently) uses SpiderMonkey.
Compilation entirely written in the JS framework.
Uses reflection, only possible compile time.
Compiler extensions for profiling, coverage, dependency
visualization.
17. Compilation
Server side compilation (currently) uses SpiderMonkey.
Compilation entirely written in the JS framework.
Uses reflection, only possible compile time.
Compiler extensions for profiling, coverage, dependency
visualization.
http://localhost/xopus/loader/test.html
console.dir(Loader.modules.map);
18.
19. Modules
The framework has support for:
Fully qualified package names.
Regular classes.
Interfaces and abstract classes.
Methods, put on prototype.
Constructors, always the first method.
(mandatory, constructor name defines class name)
20.
21. Dependencies
The framework also has support for:
Implementing interfaces.
Extending (possibly multiple) other classes.
Static decoration of other classes.
Dynamic decoration of instances.
No full checks on interface implementation yet, should be possible.
22. Annotations
Methods can be annotated with additional information:
Public, Private, Protected, Static.
Continuation, Test, Deprecated, API.
Anonymous static functions are special: class constructors.
Annotations can be used for:
Documentation.
Parametrize compilation.
For runtime reflection.
23. Unit testing
Package(quot;com.xopus.test.lang.jsquot; );
Extends(quot;com.xopus.code.dev.testing.TestCasequot; )
Tests(quot;com.xopus.code.lang.js.ArrayUtilquot; )
Class(
function ArrayUtilTest() { this.TestCase(); },
Static, function () { new ArrayUtilTest().start(); },
Test, function last()
{
var obj = {};
var arr = [1, 2, 3, obj];
this.assertTrue(
quot;last() should return the last value in the arrayquot;,
arr.last() === obj);
}
);
24.
25. Demo
Uses runtime Test annotation.
Can run entire packages - like com.xopus.*
Mac mini automatically tests everything.
http://localhost/xopus/tester/runner/runner.html?modules=com.xopus.test.lang&profiling=true
26.
27. Conclusion
Advantages:
More consistency, more structure
Framework for abstraction.
Framework for analyses.
No runtime overhead.
Disadvantages:
Code you debug not the code you write.
Minor compile-time overhead.
Requires server side machinery.