Background

JSX is a statically-typed, object-oriented programming language compiling to standalone JavaScript. The reason why JSX was developed is our need for a more robust programming language than JavaScript. However, JSX is fairly close to JavaScript especially in its statements and expressions.

Statically-typed programming language is robust because certain sorts of problems, for example typos in variable names or missing function definitions, are detected at compile-time. This is important especially in middle- to large-scale software development in which a number of engineers may be engaged.

Therefore, JSX is designed as a statically-typed language. All the values and variables have a static type and you can only assign a correctly-typed value to a variable. In addition, all the functions including closures have types which are determined by the types of parameters and the return values, where you cannot call a function with incorrectly typed arguments.

Also, another important reason why JSX was developed is to boost JavaScript performance. JavaScript itself is not so slow but large-scale development tends to have many abstraction layers, e.g. proxy classes and accessor methods, which often have negative impact on performance. JSX boosts performance by inline expansion: function bodies are expanded to where they are being called, if the functions being called could be determined at compile-time. This is the power of the statically-typed language in terms of performance.

Run "Hello, World!"

Let's start by running our first JSX program: hello.jsx. We use the jsx command, which is the JSX compiler in the JSX distribution, to compile JSX source code to JavaScript.

Type as follows in the JSX distribution and/or repository, and then you will see it saying "Hello, world!".

$ bin/jsx --run example/hello.jsx
We will look into the hello.jsx source code in the next section.

Program Structure

Here is hello.jsx, the source code of the "Hello world!" example. You can see several features of JSX in this program, namely, static types and class structure within the source code.

class _Main {
    static function main(args : string[]) : void {
        log "Hello, world!";
    }
}
Class _Main has a static member function (a.k.a. a class method) named main, that takes an array of strings and returns nothing. _Main.main(:string[]):void is the entry point of JSX applications that is called when a user invokes an application from command line. JSX, like Java, does not allow top-level statements or functions.

The log statement is mapped to console.log() in JavaScript, which displays the arguments to stdout with a newline.

Next, we look into another typical library class, Point:

class Point {
    var x = 0;
    var y = 0;

    function constructor() {
    }

    function constructor(x : number, y : number) {
        this.set(x, y);
    }

    function constructor(other : Point) {
        this.set(other);
    }

    function set(x : number, y : number) : void {
        this.x = x;
        this.y = y;
    }

    function set(other : Point) : void {
        this.x = other.x;
        this.y = other.y;
    }
}
As you can see, member variables of Point, var x and var y, are declared without types, but their types are deducted from their initial values to be number.

You might be surprised at multiple definition of member functions: one takes no parameters and the others take parameters. They are overloaded by their types of parameters. When you construct the class with new Point(), the first constructor, which takes no parameters, is called. The second with two parameters will be called on new Point(2, 3) and the third with one parameter will be called as a copy constructor. Other forms of construction, e.g. new Point(42) or new Point("foo", "bar") will cause compilation errors of mismatching signatures. The Point#set() functions are also overloaded and the compiler know how to call the correct one.

Static Types

Basic type concept will be described in this section. Primitive types, object types, variant type, and Nullable types exist in JSX.

Primitive types, e.g. string, boolean, or number are non-nullable, immutable types.

var s : string = "hello";
var n : number = 42;
var b : boolean = true;
Object types, e.g. string[] (array of string), functions or Date, are nullable, mutable types.

var d : Date = new Date(); // Date
var f : function():void = function() : void { log "Hi!"; };
var a : string[] = ["foo"]; // the same as Array.<string>;
Variant type, which means "no static type information," is used for interacting with existing JavaScript APIs. Some JavaScript libraries may return a variant value, which type cannot be determined at compile time. All you can do on variant values is to check equality of a variant value to another variant value. You have to cast it to another type before doing anything else on the value.

Nullable type is a meta type which indicates a value may be null. For example, the return type of Array.<string>#shift() is Nullable.<string>. When you use a Nullable value, you have to make sure of the value is not null. Only primitive types can be marked Nullable. Object types and variants are nullable by default.

function shiftOrReturnEmptyString(args : string[]) : string {
    if (args.length > 0)
        return args.shift();
    else
        return "";
}
When the source code is compiled in debug mode (which is the default), the compiler will insert run-time type-checking code. An exception will be raised (or the debugger will be activated) when misuse of a null value as actual value is detected. Run-time type checks can be omitted by compiling the source code with the --release option.
Classes and Interfaces

JSX is a class-based object-oriented language, and its class model is similar to Java.

a class may extend another class (single inheritance)
a class may implement multiple interfaces
all classes share a single root class: the Object class
interface Flyable {
    abstract function fly() : void;
}

abstract class Animal {
    function eat() : void {
      log "An animal is eating!";
    }
}

class Bat extends Animal implements Flyable {
    override function fly() : void {
        log "A bat is flying!";
    }
}

abstract class Insect {
}

class Bee extends Insect implements Flyable {
    override function fly() : void {
        log "A bee is flying!";
    }
}

class _Main {

    static function main(args : string[]) : void {
        // fo bar
        var bat = new Bat();

        var animal : Animal = bat; // OK. A bat is an animal.
        animal.eat();

        var flyable : Flyable = bat; // OK. A bat can fly
        flyable.fly();

        // for Bee
        var bee = new Bee();

        flyable = bee; // A bee is also flyable
        flyable.fly();
    }
}
In the example, the Bat class extends the Animal class, so it inherits the Animal#eat() member function, and it can be assigned to a variable typed to Animal. The class also implements the Flyable interface overriding the Flyable#fly() member function, so it can be assigned to a variable typed Flyable. There's also another flyable class, Bee. By using the Flyable interface, it is possible to deal with both classes as a flyable being, even if the organ of a bee is completely different from that of a bat.

When overriding a member function, the use the override keyword is mandatory. Otherwise the compiler will report an error. In other words, you are saved from unexpected interface changes in the base classes which cause compilation errors in derived classes instead of undesirable runtime errors.
Functions and Closures

In JSX, functions are first-class objects and they have static types. You can declare a variable of a function type like var f : function(arg : number) : number, a function that takes a number as an argument and returns another number (or, just returns the same value as the argument; but it's not important here). The variable f can be called as f(42) from which you will get a number value.

It is possible to define closures (or anonymous functions). They are typically used to implement event listeners, which are popular in GUI programming. Closures are similar to JavaScript except for what this points at: when a closure is defined within a member function, it refers to the receiver of the member function. See the following example.
class _Main {
    var foo = 42;

    function constructor() {
        var f = function() : void {
            log this.foo;
        };

        f(); // says 42
    }

    static function main(args : string[]) : void {
        var o = new _Main();
    }
}
Modules

JSX has a module system. You can reuse JSX class libraries by the import statement. For example, the following program uses timer.jsx module, which exports the Timer class.

import "timer.jsx";

class _Main {

    static function main(args : string[]) : void {
        Timer.setTimeout(function() : void {
            log "Hello, world!";
        }, 1000);
    }

}
A module may export multiple classes, but you can specify what modules you import or name a namespace which the module is imported into.

Interface to Web Browsers

The js/web.jsx module provides the interface to web browser APIs, e.g. the window object and DOM APIs. The example below shows how to insert a text node into an HTML.

// hello.jsx
import "js/web.jsx";

class _Main {

    static function main(args : string[]) : void {
        var document = dom.window.document;

        var text = document.createTextNode("Hello, world!");
        document.getElementById("hello").appendChild(text);
    }

}
<!DOCTYPE html>
<html>
  <head>
    <title>Hello, world!</title>
    <script src="hello.jsx.js"></script>
  </head>
  <body>
  <p id="hello"></p>
  </body>
</html>
Once you compile hello.jsx by the following command, then you can access the HTML and you will see it saying "Hello, world!."

$ bin/jsx --executable web --output hello.jsx.js hello.jsx
Further Learning

More documents can be found on the wiki.
If you are looking for examples, please refer to the examples on this web site, the example directory of the distribution, or to the links on Resouces page of the wiki.
