The ????(to be named) language specifications

Introduction

A new language, codename Flexible have just been announced. The goal is to have one single language running on several platforms :

Different APIs

Before starting with language specification I want to clarify one point. Different platforms means different APIs. There is no MovieClips in Neko and there is no Database access in Javascript. So we will have one single programming language but each platform will keep its own APIs. Only if you only use the common APIs in one class you'll be able to compile this class for each platform.

My First Class

The syntax is Java/ActionScript/C++ like.

A source code file is composed of a package name followed by several type declarations. In order to enforce the conventions, packages names are composed of several identifiers which are starting with a lowercase letter while type identifiers are always starting with an uppercase letter. The following types are available :

Here's one single sample mixing a class and an enumeration :

    package my.pack {

        enum Color {
            red;
            green;
            blue;
        }

        class Colors {
            static function toInt( c : Color ) : Int {
                return if( c == red ) 0xFF000
                  else if( c == green ) 0x00FF00
                  else 0x0000FF;
            }
        }
    }

We can notice several things here :

The Type System

The Type System is more rich that usual OO languages. There is several kind of types available :

As we said before, all objects fields (members and methods) must be fully typed (although you can use the Dynamic type if you want to get dynamic behavior). That means that inside a method, we know all the types. You don't have then to declare local variable types since they will get inferred for you by the compiler.

Several common types are already defined in the language. Most of them are abstracts.

Class Parameters

You can define class parameters in order to have one single class implementing different behavior. This is a way to get polymorphism :

    native class Array<T> {
        function new() : Void;
        function get( pos : Int ) : T;
        function set( pos : Int, elt : T ) : Void;
        ...
    }

Then you can use different kind of Arrays by specifying the type parameter. For example Array<Int> is an array of integers and Array<Array<Float>> is a two dimentional array containing floats. You can of course define your own parametrized types. If you want them not to be fully abstract, you can specify some requirements in the type parameter :

    class MyClass<T extends MyObject> {
        var o : T;
        function foo() : Void {
            o.myMethod();
        }
        ...
    }

Iterators

A nice feature of the language is to be able to define your own iterators and play with them. An iterator is a function of the form : Void -> X where X is the iterated type. You can use the for...in syntax in order to execute iterators. The most simple iterator is the Int iterator which can easily be built using the operator ... :

    for i in 1...10 {
        // ...
    }

Or the usual for loop :

    for i in 0...arr.length {
        foo(arr[i]);
    }

But you can also define you own iterators. You can simply implement the iterator() method in your class. This method must return another function that will return one object each call or the special value done when finished. Here's a simple integer enumerator sample. Please note that it is not really useful since there is already the ... operator, but it's good sample to understand how it works behind the scene :

    class IntIter {
        var min : Int;
        var max : Int;

        function new( min : Int, max : Int ) {
            this.min = min;
            this.max = max;
        }

        function iterator() {
            var cur = min;
            return function() {
                if( cur == max )
                    return done;
                return cur++;
            }
        }
    }

As this class shows, you can call several times the iterator() method in order to have several parallel iterators. Once your iterator is implemented, you can simply use it with the for...in syntax, this way :

    var iter = new IntIter(0,10);
    for i in iter {
        // ...
    }

The variable name in the iterator is automaticaly declared and its type is bound to the iterator type. If the iterator is a function, then it must be of the form Void -> X as previously said. If it's an object like the sample here, then it's a shortcut for writing iter.iterator().

Going Dynamic

When you want to have dynamic behavior, you can either type some variables as Dynamic or have your classes extends or implements Dynamic. Dynamic can have an optional type parameter that determine the type of the object fields when accessed. For exemple :

    class XML {

        var attributes : Dynamic<String>
        ....

    }

In that case, all objects fields of attributes will have the type String. Dynamic classes are then Strongly typed Object-Hashes. You can write as well Dynamic<Dynamic<String>> which will give you a two-level objects access (if you find any use for it...). Actually , Dynamic without type parameter is a shortcut for the infinite declaration : Dynamic<Dynamic<Dynamic<....>>> which would otherwise takes too much time to write.

Another possibility to get dynamic behavior is to set your code into an untyped { } block :

    function iKnowWhatImDoing( o : SomeObject ) : SomethingElse {
        untyped {
            return o.someStrangeMethod();
        }
    }

Syntax

Here's the syntax grammar (still in the works) :

    ident := [a-z][a-zA-Z0-9]*
    type-name := [A-Z][a-zA-Z0-9]*

    package-name := (ident . )* ident

    type-path := (package-name .)? type-name type-params

    type-params :=
        | ε
        | < type-path+ >

    type-option :=
        | ε
        | : type-path

    program := package package-name? { (type-declaration | import | ; )* }

    type-declaration :=
        | class type-name { class-field* }
        | enum type-name { (ident | ; )* }

    import := import type-path

    class-field :=
        | field-style* var ident type-option
        | field-style* function ident ( parameter-list? ) type-option { expr* }

    field-style :=
        | public
        | private
        | static
        | native

    parameter_list := ident type-option (, parameter-list)?

    expr := TODO

And now ?

A lot more will come later :)

Author

Nicolas Cannasse