|
@@ -1,1507 +0,0 @@
|
|
|
-<html>
|
|
|
-<head>
|
|
|
-<title>The haXe Programming Language</title>
|
|
|
-<link rel="stylesheet" type="text/css" href="style.css"/>
|
|
|
-</head>
|
|
|
-
|
|
|
-<body>
|
|
|
-
|
|
|
-<div class="content">
|
|
|
-
|
|
|
-<h1>The haXe Programming Language</h1>
|
|
|
-
|
|
|
-<script type="text/javascript" src="menu.js"></script>
|
|
|
-
|
|
|
-<h2>Introduction</h2>
|
|
|
-
|
|
|
-<p>
|
|
|
- This Language Reference document will quickly introduce you the haXe programming language syntax and features. Here's today menu :
|
|
|
-</p>
|
|
|
-
|
|
|
-<ol>
|
|
|
- <li><a href="#types">Base Types</a></li>
|
|
|
- <li><a href="#classes">Classes</a></li>
|
|
|
- <li><a href="#expr">Expressions</a></li>
|
|
|
- <li><a href="#tinf">Type Inference</a></li>
|
|
|
- <li><a href="#inherit">Class Inheritance</a></li>
|
|
|
- <li><a href="#tparams">Class parameters</a></li>
|
|
|
- <li><a href="#enums">The power of Enum</a></li>
|
|
|
- <li><a href="#packages">Packages and Imports</a></li>
|
|
|
- <li><a href="#dynamic">Dynamic and Untyped</a></li>
|
|
|
- <li><a href="#tother">Other Types</a></li>
|
|
|
- <li><a href="#tsub">Subtyping</a></li>
|
|
|
- <li><a href="#iter">Iterators</a></li>
|
|
|
- <li><a href="#cond">Conditional Compilation</a></li>
|
|
|
-</ol>
|
|
|
-
|
|
|
-<a name="types"></a>
|
|
|
-<h2>Base Types</h2>
|
|
|
-
|
|
|
-<p>
|
|
|
- The syntax is Java/ActionScript/C++ like.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- A source code file is composed of an optional <em>package name</em> followed by several <em>imports</em> and <em>type</em> declarations. In order to enforce the conventions, packages names are composed of several <em>identifiers</em> which are starting with a lowercase letter while <em>type identifiers</em> are always starting with an uppercase letter.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- There is several kind of types. The two important ones are <em>classes</em> and <em>enums</em>. Here are some of the <em>basic types</em> as declared in the standard library :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>enum</k> Void {
|
|
|
- }
|
|
|
-
|
|
|
- <k>class</k> Float {
|
|
|
- }
|
|
|
-
|
|
|
- <k>class</k> Int <k>extends</k> Float {
|
|
|
- }
|
|
|
-
|
|
|
- <k>enum</k> Bool {
|
|
|
- <k>true</k>;
|
|
|
- <k>false</k>;
|
|
|
- }
|
|
|
-
|
|
|
- <k>enum</k> Dynamic<T> {
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- Let's see each type one by one :
|
|
|
-</p>
|
|
|
-
|
|
|
-<ul class="big">
|
|
|
- <li><strong>Void</strong> is declared as an <em>enum</em>. An enumeration list a number of valid <em>constructors</em>. An empty enumeration such as <code>Void</code> does not have then any instance. However, it's still a valid type that can be used.</li>
|
|
|
- <li><strong>Float</strong> is a floating point number class. It doesn't have any method so it can be greatly optimized on some platforms.</li>
|
|
|
- <li><strong>Int</strong> is an integer. It doesn't have methods either but it inherits from <code>Float</code>, so it means that everywhere a <code>Float</code> is requested, you can use an <code>Int</code>, while the contrary is not true. And that seems pretty correct.</li>
|
|
|
- <li><strong>Bool</strong> is an enumeration, like <code>Void</code>, but it has two instances <code>true</code> and <code>false</code>. As you can see, even <em>standard</em> types can be defined easily using the hAxe type system. It means also you can use it to define your own types.</li>
|
|
|
- <li><strong>Dynamic</strong> is an enum with a <em>type parameter</em>. We will explain how to use type parameters later in this document.</li>
|
|
|
-</ul>
|
|
|
-
|
|
|
-<p>
|
|
|
- Let's see now how you can practically use classes.
|
|
|
-</p>
|
|
|
-
|
|
|
-<a name="classes"></a>
|
|
|
-<h2>Classes</h2>
|
|
|
-
|
|
|
-<p>
|
|
|
- We will quickly introduce the structure of classes that you might already be familiar with if you've done some OO programming before :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>package</k> my.pack;
|
|
|
- <g>/*
|
|
|
- this will define the class my.pack.MyClass
|
|
|
- */</g>
|
|
|
- <k>class</k> MyClass {
|
|
|
- <g>// ....</g>
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- A Class can have several <em>variables</em> and <em>methods</em>.
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>package</k> my.pack;
|
|
|
-
|
|
|
- <k>class</k> MyClass {
|
|
|
-
|
|
|
- <k>var</k> id : Int;
|
|
|
-
|
|
|
- <k>static var</k> name : String = <t>"MyString"</t>;
|
|
|
-
|
|
|
- <k>function</k> foo() : Void {
|
|
|
- }
|
|
|
-
|
|
|
- <k>static function</k> bar( s : String, v : Bool ) : Void {
|
|
|
- }
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- Variables and methods can have the following <em>flags</em> :
|
|
|
-</p>
|
|
|
-
|
|
|
-<ul class="big">
|
|
|
- <li><b>static</b> : the field belongs to the Class itself and not to <em>instances</em> of this class. Static identifiers can be used directly in the class itself. Outside of the class, it but must be used with the class name (for example : <code>my.pack.MyClass.name</code>).
|
|
|
- </li>
|
|
|
- <li><b>public</b> : the field can be accessed by other classes. <b>By default, all fields are <code>private</code></b>.</li>
|
|
|
- <li><b>private</b> : the field access is restricted to the class itself and all the classes that will <code><k>extends</k></code> this class. This is better to ensure that the class internal state is not accessible.</li>
|
|
|
-</ul>
|
|
|
-
|
|
|
-<p>
|
|
|
- All class variables <b>must</b> be declared with a type (you can use <code>Dynamic</code> if you don't know which type to use). Function arguments and return types are optional but are still stricly checked as we will see when introducing <em>type inference</em>.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- Static variables <em>can</em> have an initial value although it's not required.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>Constructor</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- The class can have only one constructor, which is the not-static function called <code><k>new</k></code>. This is a keyword that can also be used to name a class function :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>class</k> Point {
|
|
|
- <k>public var</k> x : Int;
|
|
|
- <k>public var</k> y : Int;
|
|
|
-
|
|
|
- <k>public function new</k>() {
|
|
|
- <k>this</k>.x = 0;
|
|
|
- <k>this</k>.y = 0;
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- We will now introduce the <em>expressions</em> that can be used to implement functions or to initialize static variables.
|
|
|
-</p>
|
|
|
-
|
|
|
-<a name="expr"></a>
|
|
|
-<h2>Expressions</h2>
|
|
|
-
|
|
|
-<p>
|
|
|
- In <b>hAxe</b>, all expressions have the same level. It means that you can nest them together recursively without any problem. For example : <code>foo(if (x == 3) 5 else 8)</code>. As this exemple shows, it also means that every expression is <em>returning</em> a value of a given <em>type</em>.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>Constants</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- The following constant values can be used :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
-0; <g>// Int</g>
|
|
|
--134; <g>// Int</g>
|
|
|
-0xFF00; <g>// Int</g>
|
|
|
-
|
|
|
-123.0; <g>// Float</g>
|
|
|
-.14179; <g>// Float</g>
|
|
|
-13e50; <g>// Float</g>
|
|
|
--1e-99; <g>// Float</g>
|
|
|
-
|
|
|
-"hello"; <g>// String</g>
|
|
|
-"hello \"world\" !"; <g>// String</g>
|
|
|
-'hello "world" !'; <g>// String</g>
|
|
|
-
|
|
|
-true; <g>// Bool</g>
|
|
|
-false; <g>// Bool</g>
|
|
|
-
|
|
|
-null; <g>// Unknown<0></g>
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- You can notice that <code>null</code> have a special value that can be used for any type but have different behavior than <code>Dynamic</code>. It will be explained in details when introducing <em>type inference</em>.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>Operations</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- The following usual operations can be used, with that order of priority :
|
|
|
-</p>
|
|
|
-
|
|
|
-<ul class="big">
|
|
|
- <li><code>v = e</code> : assign a value to an expression, return <code>e</code></li>
|
|
|
- <li><code>+= -= *= /= %= &= |= ^= <<= >>= >>>=</code> : assign after performing the corresponding operation</li>
|
|
|
- <li><code>e1 || e2</code> : If <code>e1</code> is <code>true</code> then <code>true</code> else evaluate <code>e2</code> . Both <code>e1</code> and <code>e2</code> must be <code>Bool</code>.</li>
|
|
|
- <li><code>e1 && e2</code> : If <code>e1</code> is <code>false</code> then <code>false</code> else evaluate <code>e2</code> . Both <code>e1</code> and <code>e2</code> must be <code>Bool</code>.</li>
|
|
|
- <li><code>e1...e2</code> : Build an integer iterator (see later about Iterators).</li>
|
|
|
- <li><code>== != > < >= <= === !==</code> : perform normal or physical comparisons between two expressions sharing a common type. Return <code>Bool</code>.</li>
|
|
|
- <li><code>| & ^</code> : perform bitwise operation between two <code>Int</code> expressions. Return <code>Int</code>.</li>
|
|
|
- <li><code><< >> >>></code> : perform bitwise shifts between two <code>Int</code> expressions. Return <code>Int</code>.</li>
|
|
|
- <li><code>e1 + e2</code> : perform addition. If both expressions are <code>Int</code> then return <code>Int</code> else if both expressions are either <code>Int</code> or <code>Float</code> then return <code>Float</code> else return <code>String</code>.</li>
|
|
|
- <li><code>e1 - e2</code> : perform substraction between two <code>Int</code> or <code>Float</code> expressions. Return <code>Int</code> if both are <code>Int</code> and <code>Float</code> either.</li>
|
|
|
- <li><code>e1 % e2</code> : modulo of two numbers, same return type as substract.</li>
|
|
|
- <li><code>e1 * e2</code> : multiply two numbers, same return type as substract.</li>
|
|
|
- <li><code>e1 / e2</code> : divide two numbers, return <code>Float</code>.</li>
|
|
|
-</ul>
|
|
|
-
|
|
|
-<h3>Unary operations</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- The following unary operations are available :
|
|
|
-</p>
|
|
|
-
|
|
|
-<ul class="big">
|
|
|
- <li><code>!</code> : boolean <em>not</em>. Inverse the expression <code>Bool</code> value.</li>
|
|
|
- <li><code>-</code> : negative number, change the sign of the <code>Int</code> or <code>Float</code> value.</li>
|
|
|
- <li><code>++</code> and <code>--</code> can be used before or after an expression. When used before, they first increment the corresponding variable and then return the incremented value. When used after, they increment the variable but returns the value it had before incrementation. Can only be used with <code>Int</code> or <code>Float</code> values.</li>
|
|
|
- <li><code>~</code> : one-complement of an <code>Int</code>.</li>
|
|
|
-</ul>
|
|
|
-
|
|
|
-<h3>Parenthesis</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- Expressions can be delimited with parenthesis in order to give a specific priority when performing operations. The type of <code>( e )</code> is the same as <code>e</code> and they both evaluates to the same value.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>Blocks</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- Blocks can execute several expressions. The syntax of a block is the following :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
-{
|
|
|
- e1;
|
|
|
- e2;
|
|
|
- <g>// ...</g>
|
|
|
- eX;
|
|
|
-}
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- A block evaluates to the type and value of the <em>last expression</em> of the block. For example :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
-{ f(); x = 124; <k>true</k>; }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- This block have type <code>Bool</code> and will evaluate to <code>true</code>.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- As an exception, the empty block <code>{ }</code> evaluates to <code>Void</code>.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>Local Variables</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- Local variables can be declared into Blocks using <code><k>var</k></code>, as the following samples are showing :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
-{
|
|
|
- <k>var</k> x;
|
|
|
- <k>var</k> y = 3;
|
|
|
- <k>var</k> z : String;
|
|
|
- <k>var</k> w : String = <t>""</t>;
|
|
|
- <k>var</k> a, b : Bool, c : Int = 0;
|
|
|
-}
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- A variable can be declared with an optional type and an optional initial value. If no value is given then the variable is <code>null</code> by default. If no type is given, then the variable type is <code>Unknown</code> but will still be strictly typed. This will be explained in details when introducing <em>type inference</em>.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- Several local variables can be declared in the same <code><k>var</l></code> expression.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- Local variables are only defined until the Block they're declared in is closed. They can no longer be accessible after that time.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>Identifiers</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- An identifier can be of two kinds. A <em>variable identifier</em> starts with an lowercase letter while a <em>type identifier</em> starts with an uppercase letter. As a consequence, it's not possible to have a variable name starting with an uppercase letter. This is a good way to enforce some <em>code conventions</em>.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- When a variable identifier is found, it is <em>resolved</em> using the following order :
|
|
|
-</p>
|
|
|
-
|
|
|
-<ul>
|
|
|
- <li>local variables, last declared having priority</li>
|
|
|
- <li>class members (current class and inherited fields)</li>
|
|
|
- <li>current class static fields</li>
|
|
|
- <li>enum constructors that have been either declared in this file or <em>imported</em></li>
|
|
|
-</ul>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>enum</k> Axis {
|
|
|
- x;
|
|
|
- y;
|
|
|
- z;
|
|
|
- }
|
|
|
-
|
|
|
- <k>class</k> C {
|
|
|
- <k>static var</k> x : Int;
|
|
|
- <k>var</k> x : Int;
|
|
|
-
|
|
|
- <k>function new</k>() {
|
|
|
- <g>// x means member variable this.x</g>
|
|
|
- {
|
|
|
- <k>var</k> x : String;
|
|
|
- <g>// x means the local variable</g>
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- <k>function</k> f(x : String) {
|
|
|
- <g>// x means the function parameter</g>
|
|
|
- }
|
|
|
-
|
|
|
- <k>static function</k> f() {
|
|
|
- <g>// x means the class static variable</g>
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- <k>class</k> D {
|
|
|
- <k>function new</k>() {
|
|
|
- <g>// x means the x Axis</g>
|
|
|
- }
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- <em>Type identifiers</em> are resolved according to the imported packages, as we will explain later.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>Field access</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- Object access is done using traditional dot-access :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- o.field
|
|
|
-</pre>
|
|
|
-
|
|
|
-<h3>Calls</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- You can call functions as usual using parenthesis and commas in order to delimit arguments. You can call methods by using dot access on objects :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- f(1,2,3);
|
|
|
- object.method(1,2,3);
|
|
|
-</pre>
|
|
|
-
|
|
|
-<h3>New</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- The <code><k>new</k></code> keyword is used in expressions to create a Class instance. It needs a class name and can take parameters :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- a = <k>new</k> Array();
|
|
|
- s = <k>new</k> String(<t>"hello"</t>);
|
|
|
-</pre>
|
|
|
-
|
|
|
-<h3>Arrays</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- You can create arrays directly from a list of values by using the following syntax :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>var</k> a : Array<Int> = [1,2,3,4];
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- Please notice that the type Array takes one <em>type parameter</em> that is the type of items stored into the Array. This way all operations on arrays are safe. As a consequence, all items in a given Array must be of the same type.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- You can read and write into an Array by using the following traditional bracket accesses :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- first = a[0];
|
|
|
- a[1] = value;
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- The array index must be of type <code>Int</code>.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>If</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- Here are some examples of <code><k>if</k></code> expressions :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>if</k> (life == 0) destroy();
|
|
|
- <k>if</k> (flag) 1 <k>else</k> 2;
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- Here's the generic syntax of <code><k>if</k></code> expressions :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>if</k> <em>expr-cond</em> <em>expr-1</em> [<k>else</k> <em>expr-2</em>]
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- First <code>expr-cond</code> is evaluated. It must be of type <code>Bool</code>. Then if <code>true</code> then <code>expr-1</code> is evaluated, either, if there is an <code>expr-2</code> then it is evaluated instead.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- If there is no <code>else</code>, the <code><k>if</k></code> expression has type <code>Void</code>. If there is an <code>else</code>, then <code>expr-1</code> and <code>expr-2</code> must be of the same type and this will be the type of the <code><k>if</k></code> expression :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>var</k> x : Void = <k>if</k>( flag ) destroy();
|
|
|
- <k>var</k> y : Int = <k>if</k>( flag ) 1 <k>else</k> 2;
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- In <b>haXe</b>, <code>if</code> are actually similar to ternary C <code>a?b:c</code> syntax.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- As an exception, if an <code>if</code> block is not supposed to return any value (like in the middle of a Block) then both <code>expr-1</code> and <code>expr-2</code> can have different types and the <code>if</code> block type will be <code>Void</code>.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>While</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- While are standard loops that are using a precondition or a postcondition :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>while</k> <em>expr-cond</em> <em>expr-loop</em>;
|
|
|
- <k>do</k> <em>expr-loop</em> <k>while</k> <em>expr-cond</em>;
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- For example :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>var</k> i = 0;
|
|
|
- <k>while</k>( i < 10 ) {
|
|
|
- <g>// ...</g>
|
|
|
- i++;
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- Or using <code>do...while</code> :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>var</k> i = 0;
|
|
|
- <k>do</k> {
|
|
|
- <g>// ...</g>
|
|
|
- i++;
|
|
|
- } <k>while</k>( i < 10 );
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- Like for <code>if</code>, the <code>expr-cond</code> in a while-loop type must be of type <code>Bool</code>.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>For</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- For loops are little different from traditional C <code>for</code> loops. They're actually used for <em>iterators</em>, which will be introduced later in this document. Here's an exemple of a for loop :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>for</k> i <k>in</k> 0...a.length {
|
|
|
- foo(a[i]);
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<h3>Return</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- In order to exit from a function before the end or to return a value from a function, you can use the <code>return</code> expression :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>function</k> odd( x : Int ) : Bool {
|
|
|
- <k>if</k>( x % 1 == 0 )
|
|
|
- <k>return true</k>;
|
|
|
- <k>return false</k>;
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- The <code>return</code> expression can be used without argument if the function does not require a value to be returned :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>function</k> foo() : Void {
|
|
|
- <g>// ...</g>
|
|
|
- <k>if</k>( abort )
|
|
|
- <k>return</k>;
|
|
|
- <g>// ....</g>
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<h3>Break and Continue</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- Theses two keywords are useful to exit earlier for a <code>for</code> or <code>while</code> loop or to go to the next iteration of a loop :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>var</k> i = 0;
|
|
|
- <k>while</k>( i < 10 ) {
|
|
|
- <k>if</k>( i == 7 )
|
|
|
- <k>continue</k>; <g>// skip this iteration</g>
|
|
|
- <g>// ...</g>
|
|
|
- <k>if</k>( flag )
|
|
|
- <k>break</k>; <g>// stop earlier</g>
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<h3>Exceptions</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- Exceptions are a way to do non-local jumps. You can <code>throw</code> an exception and <code>catch</code> it from any calling function on the stack :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>function</k> foo() {
|
|
|
- <g>// ...</g>
|
|
|
- <k>throw new</k> Error("invalid foo");
|
|
|
- }
|
|
|
-
|
|
|
- <g>// ...</g>
|
|
|
-
|
|
|
- <k>try</k> {
|
|
|
- foo();
|
|
|
- } <k>catch</k>( e : Error ) {
|
|
|
- <g>// handle exception</g>
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- There can be several <code>catch</code> after a <code>try</code>, in order to catch different type of exceptions. They're tested in the order they're declared.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- All the <code>try</code> and the <code>catch</code> expressions must have the same returning type except when no value is needed (same as <code>if</code>).
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>Switch</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- Switchs are a way to express multiple <code>if...else if... else if</code> if equality on the same value :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>if</k>( v == 0 )
|
|
|
- e1
|
|
|
- <k>else if</k>( v == foo(1) )
|
|
|
- e2
|
|
|
- <k>else if</k>( v == 65 )
|
|
|
- e3
|
|
|
- <k>else</k>
|
|
|
- e4;
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- Will translate to the following <code>switch</code> :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>switch</k>( v ) {
|
|
|
- <k>case</k> 0:
|
|
|
- e1;
|
|
|
- <k>case</k> foo(1):
|
|
|
- e2;
|
|
|
- <k>case</k> 65:
|
|
|
- e3;
|
|
|
- <k>default</k>:
|
|
|
- e4;
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- Switchs in <b>haXe</b> are different from traditional switchs : all <em>cases</em> are separate expressions so after one case expression is executed the switch block is automatically exited. As a consequence, <code>break</code> can't be used in a <code>switch</code> and the position of the <code>default</code> case is not important.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- On some <em>platforms</em>, switchs on constant values (especially constant integers) might be optimized for better speed.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- Switchs can also be used on <code>enum</code> with a different semantic. It will be explained later in this document.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>Local Functions</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- Local functions are declared using the <code>function</code> keyword but they can't have a name. They're <em>values</em> just like literal integers or strings :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>var</k> f = <k>function</k>() { <g>/* ... */</g> };
|
|
|
- f(); <g>// call the function</g>
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- Local functions can access its parameters, the current class statics, but also the local variables that where declared before it :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>var</k> x = 10;
|
|
|
- <k>var</k> add = <k>function</k>(n) { x += n; };
|
|
|
- add(2);
|
|
|
- add(3);
|
|
|
- <g>// now x is 15</g>
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- However, local functions declared in methods cannot access the <code><k>this</k></code> value. You then need to declare a local variable such as <code>me</code> :
|
|
|
-</p>
|
|
|
-
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>class</k> C {
|
|
|
-
|
|
|
- <k>var</k> x : Int;
|
|
|
-
|
|
|
- <k>function</k> f() {
|
|
|
- <g>// WILL NOT COMPILE</g>
|
|
|
- <k>var</k> add = <k>function</k>(n) { <k>this</k>.x += n };
|
|
|
- }
|
|
|
-
|
|
|
- <k>function</k> f2() {
|
|
|
- <g>// will compile</g>
|
|
|
- <k>var</k> me = <k>this</k>;
|
|
|
- <k>var</k> add = <k>function</k>(n) { me.x += n };
|
|
|
- }
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<h3>Anonymous Objects</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- Anonymous objects can be declared using the following syntax :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>var</k> o = { age : 26, name : "Tom" };
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- Please note that because of the <em>type inference</em>, anonymous objects are also strictly typed.
|
|
|
-</p>
|
|
|
-
|
|
|
-<a name="tinf"></a>
|
|
|
-<h2>Type Inference</h2>
|
|
|
-
|
|
|
-<p>
|
|
|
- <em>Type Inference</em> means that the type information is not only checked in the program, it's also <em>carried</em> when typing, so it doesn't have to be resolved immediatly. For example a local variable can be declared without any type (it will have the type <code>Unknown</code>) and when first used, its type will be set to the corresponding one.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>Printing a Type</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- Anywhere in your program, you can use the <code>type</code> operation to know the type of a given expression. At compilation, the <code>type</code> operation will be removed and only the expression will remain :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>var</k> x : Int = type(0);
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- This will print <code>Int</code> at compilation, and compile the same program as if <code>type</code> was not used.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- This is useful to quickly get a type instead of looking at the class or some documentation.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>Local variable inference</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- Type Inference enables the whole program to be strictly typed without any need to put types everywhere. In particular, local variables does not need to be typed, their types will be inferred when they are first accessed for reading or writing :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>var</k> loc;
|
|
|
- type(loc); <g>// print Unkown<0></g>
|
|
|
- loc = <t>"hello"</t>;
|
|
|
- type(loc); <g>// print String</g>
|
|
|
-</pre>
|
|
|
-
|
|
|
-<h3>Function types inference</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- A class method or local function types are also optional. It means that the first time the function is used, the type will be set to the type it was used with, just like local variables. It can be tricky since it will obviously depends on the order in which the program is typed. Here's an exemple that shows some problem :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>function</k> f( posx ) {
|
|
|
- <g>// ....</g>
|
|
|
- }
|
|
|
- <g>// ...</g>
|
|
|
-
|
|
|
- f(134);
|
|
|
- f(12.2); <g>// Error : Float should be Int</g>
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- In that case the first call to <code>f</code> set the type of <code>posx</code> to <code>Int</code>, and the second call compilation fails because a <code>Float</code> is not an <code>Int</code>. However if we reverse the two calls to <code>f</code>, the type is set to <code>Float</code> which was the intended type, and it can now accept <code>Int</code> as well.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- In that exemple, the two calls are just near each other so it's quite easy to understand and fix, but in more large programs with more complex cases, fixing such compilation problems can be tricky. There is however always an easy solution which is to set the type of the function when an error of this kind happens. Then the call that was responsible for the problem will be displayed when recompiling.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>User Choice</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- Using type inference is a choice. You can simply not type your variables and functions and let the compiler <em>infer</em> the types for you, or you can type all of them in order to have more control on the process. The best is maybe in the middle, by adding some typing in order to improve code documentation and still be able to write quickly some functions without typing everything.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- In all cases, and unless you use <em>dynamics</em> (they will be introduced later), your program will be strictly typed and any wrong usage will be detected instantly at compilation.
|
|
|
-</p>
|
|
|
-
|
|
|
-<a name="inherit"></a>
|
|
|
-<h2>Class Inheritance</h2>
|
|
|
-
|
|
|
-<p>
|
|
|
- When declared, a class can <em>extends</em> one Class and <em>implements</em> several classes or interfaces. It means that it will get several <em>types</em> at the same time. For example :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>class</k> D <k>extends</k> A, <k>implements</k> B, <k>implements</k> C {
|
|
|
-
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- This means that every <em>instance</em> of D will have the <em>type</em> D but you will be able to use it also where a A, B or C instance is required. This means that every <em>instance</em> of D have also the <em>types</em> A , B and C.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>Extends</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- When <em>extending</em> a class, your class <em>inherits</em> from all <em>public</em> and <em>private</em> not-static fields. You can then use them in your class as if they where declared here. You can also <em>override</em> a method by redefining it (it needs to have some number of arguments and same types). Your class don't inherit <em>static</em> fields.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- When a <em>method</em> is <em>overriden</em>, then you can still access the <em>superclass</em> method using <code>super</code> :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>class</k> B <k>extends</k> A {
|
|
|
- <k>function</k> foo() : Int {
|
|
|
- <k>return super</k>.foo() + 1;
|
|
|
- }
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- In your class constructor you can call the <em>superclass</em> constructor using also <code>super</code> :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>class</k> B <k>extends</k> A {
|
|
|
- <k>function new</k>() {
|
|
|
- <k>super</k>(36,<t>""</t>);
|
|
|
- }
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<h3>Implements</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- When <em>implementing</em> a class or an interface, your class is <em>required</em> to implement all the fields <em>declared</em> or <em>inherited</em> by the class it implements, with same type and name. However the field might already be <em>inherited</em> from a superclass.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>Interfaces</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- <em>Interface</em> are classes prototypes. They are declared using the <code><k>interface</k></code> keyword. By default, all interfaces fields are <em>public</em>. Interfaces cannot be instancied.
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>interface</k> PointProto {
|
|
|
- <k>var</k> x : Int;
|
|
|
- <k>var</k> y : Int;
|
|
|
-
|
|
|
- <k>function</k> length() : Int;
|
|
|
- <k>function</k> add( p : PointProto ) : Void;
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-
|
|
|
-<a name="tparams"></a>
|
|
|
-<h2>Class parameters</h2>
|
|
|
-
|
|
|
-<p>
|
|
|
- A class can have several <em>type parameters</em> that can be used to get <em>extensible behavior</em>. For example, the <code>Array</code> class have one type parameter :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>class</k> Array<T> {
|
|
|
-
|
|
|
- <k>function new</k>() {
|
|
|
- <g>// ...</g>
|
|
|
- }
|
|
|
-
|
|
|
- <k>function</k> get( pos : Int ) : T {
|
|
|
- <g>// ...</g>
|
|
|
- }
|
|
|
-
|
|
|
- <k>function</k> set( pos : Int, val : T ) : Void {
|
|
|
- <g>// ...</g>
|
|
|
- }
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- Inside the <code>Array</code> class, the type <code>T</code> is <em>abstract</em> and then its fields and methods are not accessible. However when you declare an array you need to specify its type : <code>Array<Int></code> or <code>Array<String></code> for example. This will act the same as if you had replaced all types <code>T</code> in <code>Array</code> declaration by the type you're specifying.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- Type parameter is very useful in order to get strict typing of <em>containers</em> such as <code>Array</code>, <code>List</code>, <code>Tree</code>... You can define your own <em>parametrized</em> classes with several <em>type parameters</em> for your own usage when you need it.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>Constraint Parameters</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- While it's nice to be able to define <em>abstract</em> parameters, it is also possible to define several <em>constraints</em> on them in order to be able to use them in the class implementation. For example :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>class</k> EvtQueue<T : Event, EventDispatcher> {
|
|
|
- <k>var</k> evt : T;
|
|
|
- <g>// ...</g>
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- In this class, the field <code>evt</code>, although it's a class parameter, the typer knows that it has both types <code>Event</code> and <code>EventDispatcher</code> so it can actually access it like if it was <em>implementing</em> both classes. Later, when an <code>EvtQueue</code> is created, the typer will check that the <em>type parameter</em> will either <em>extends</em> or <em>implements</em> the two types <code>Event</code> and <code>EventDispatcher</code>.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- Type parameters constraints are a powerful advanced feature, that can be really useful to write generic code that can be reused in different applications.
|
|
|
-</p>
|
|
|
-
|
|
|
-
|
|
|
-<a name="enums"></a>
|
|
|
-<h2>The Power of Enum</h2>
|
|
|
-
|
|
|
-<p>
|
|
|
- <em>Enums</em> are another type than <em>classes</em> and are declared with a finite number of <em>constructors</em>. Here's a small sample :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>enum</k> Color {
|
|
|
- red;
|
|
|
- green;
|
|
|
- blue;
|
|
|
- }
|
|
|
-
|
|
|
- <k>class</k> Colors {
|
|
|
- <k>static function</k> toInt( c : Color ) : Int {
|
|
|
- <k>return switch</k>( c ) {
|
|
|
- <k>case</k> red: 0xFF000;
|
|
|
- <k>case</k> green: 0x00FF00;
|
|
|
- <k>case</k> blue: 0x0000FF;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- When you have a fixed number of values and that you want to ensure that only theses values are used then <em>enum</em>s are the best thing since they ensure that other values cannot be constructed.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>Constructors parameters</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- The previous <code>Color</code> sample shows three <em>constant constructors</em> for an <em>enum</em>. It is also possible to have parameters for constructors :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>enum</k> Color2 {
|
|
|
- red;
|
|
|
- green;
|
|
|
- blue;
|
|
|
- grey( v : Int );
|
|
|
- rgb( r : Int, g : Int, b : Int );
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- This way, there is an infinite number of <code>Color2</code> possible, but they are five different constructors possible for it. The following values are all <code>Color2</code> :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- red;
|
|
|
- green;
|
|
|
- blue;
|
|
|
- grey(0);
|
|
|
- grey(128);
|
|
|
- rgb( 0x00, 0x12, 0x23 );
|
|
|
- rgb( 0xFF, 0xAA, 0xBB );
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- We can also have a recursive type, for exemple to add <code>alpha</code> :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>enum</k> Color3 {
|
|
|
- red;
|
|
|
- green;
|
|
|
- blue;
|
|
|
- grey( v : Int );
|
|
|
- rgb( r : Int, g : Int, b : Int );
|
|
|
- alpha( a : Int, col : Color3 );
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- The following are valid <code>Color3</code> values :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- alpha( 127, red );
|
|
|
- alpha( 255, rgb(0,0,0) );
|
|
|
-</pre>
|
|
|
-
|
|
|
-<h3>Switch on Enum</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- Switch have a special semantic when used on an <em>enum</em>. If there is no <code>default</code> case then it will check that all <em>enum constructor</em> are used, and you'll get an error if not. For exemple, using the first <code>Color</code> <em>enum</em> :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>switch</k>( c ) {
|
|
|
- <k>case</k> red: 0xFF000;
|
|
|
- <k>case</k> green: 0x00FF00;
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- This will cause an <em>compile error</em> telling that the constructor <code>blue</code> is not used. In that case you can either add a case for it or add a default case that does something. It's very useful since when you add a new constructor to your <em>enum</em>, compiler errors will display in your program the places where the new constructor have to be handled.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>Switch with Constructor Parameters</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- If enum constructor have parameters, they <em>must</em> but listed as variable names in a <em>switch</em> case. This way all the variables will be locals accessibles in the <code>case</code> expression and corresponding to the type of the enum constructor parameter. For example, using the <code>Color3</code> enum :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>class</k> Colors {
|
|
|
- <k>static function</k> toInt( c : Color3 ) : Int {
|
|
|
- <k>return switch</k>( c ) {
|
|
|
- <k>case</k> red: 0xFF000;
|
|
|
- <k>case</k> green: 0x00FF00;
|
|
|
- <k>case</k> blue: 0x0000FF;
|
|
|
- <k>case</k> grey(v): (v << 16) | (v << 8) | v;
|
|
|
- <k>case</k> rgb(r,g,b): (r << 16) | (g << 8) | b;
|
|
|
- <k>case</k> alpha(a,c): (a << 24) | (toInt(c) & 0xFFFFFF);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- Using <code>switch</code> is the only possible way to access the enum constructors parameters.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>Enum Type Parameters</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- Enum, as classes, can also have type parameters. The syntax is the same so here's a small sample of a parametrized linked <code>List</code> using an <em>enum</em> to store the cells :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>enum</k> Cell<T> {
|
|
|
- empty;
|
|
|
- cons( item : T, next : Cell<T> );
|
|
|
- }
|
|
|
-
|
|
|
- <k>class</k> List<T> {
|
|
|
- <k>var</k> head : Cell<T>;
|
|
|
-
|
|
|
- <k>public function new</k>() {
|
|
|
- head = empty;
|
|
|
- }
|
|
|
-
|
|
|
- <k>public function</k> add( item : T ) {
|
|
|
- head = cons(item,head);
|
|
|
- }
|
|
|
-
|
|
|
- <k>public function</k> length() : Int {
|
|
|
- <k>return</k> cell_length(head);
|
|
|
- }
|
|
|
-
|
|
|
- <k>private function</k> cell_length( c : Cell<T> ) : Int {
|
|
|
- <k>return switch</k>( c ) {
|
|
|
- <k>case</k> empty : 0;
|
|
|
- <k>case</k> cons(item,next): 1 + cell_length(next);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- Using both <em>enum</em> and <em>classes</em> together can be pretty powerful in some cases.
|
|
|
-</p>
|
|
|
-
|
|
|
-<a name="packages"></a>
|
|
|
-<h2>Packages and Imports</h2>
|
|
|
-
|
|
|
-<p>
|
|
|
- Each file can contain several <em>classes</em>, <em>enums</em> and <em>imports</em>. They are all part of the <em>package</em> declared at the beginning of the class. If <em>package</em> is not declared than the default empty package is used. Each <em>type</em> has then a <em>path</em> corresponding to the <em>package</em> name followed by the <em>type</em> name.
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <g>// file my/pack/C.hx</g>
|
|
|
- <k>package</k> my.pack;
|
|
|
-
|
|
|
- <k>enum</k> E {
|
|
|
- }
|
|
|
-
|
|
|
- <k>class</k> C {
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- This file declares two <em>types</em> : <code>my.pack.E</code> and <code>my.pack.C</code>. It's possible to have several classes in the same file, but the type name must be <em>unique</em> in the whole application, so conflicts can appear if you're not using packages enough (this does not mean that you have to use long packages names everywhere).
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- When using packages, your files should be placed into subdirectories having the same name of it. In general the name of the file is the one of the main <em>class</em> defined into it.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- The file extension for <b>hAxe</b> is <code>.hx</code>.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>Imports</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- Imports can be used to have access to all the types of a file without needing to specify the package name.
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>package</k> my.pack2;
|
|
|
- <k>class</k> C2 <k>extends</k> my.pack.C {
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- Is identical to the following :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>package</k> my.pack2;
|
|
|
- <k>import</k> my.pack.C;
|
|
|
-
|
|
|
- <k>class</k> C2 <k>extends</k> C {
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- The only difference is that when using <k>import</k> you can use <em>enum constructors</em> that were declared in the <code>my/pack/C.hx</code> file.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>Type Lookup</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- When a type name is found, the following lookup is performed, in that order :
|
|
|
-</p>
|
|
|
-
|
|
|
-<ul class="big">
|
|
|
- <li>current class type parameters</li>
|
|
|
- <li>standard types</li>
|
|
|
- <li>types declared in the current file</li>
|
|
|
- <li>types declared in imported files (if the searched package is empty)</li>
|
|
|
- <li>if not found, the corresponding file is loaded and the type is searched inside it</li>
|
|
|
-</ul>
|
|
|
-
|
|
|
-<h3>Enum Constructors</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- In order to use enum constructors, the file in which the <em>enum</em> is declared must first be imported, or you can use the full type path to access constructors as if they were static fields of the <em>enum</em> type.
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>var</k> c : my.pack.Color = my.pack.Color.red;
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- As an exception, in <code>switch</code>, if the type of the <em>enum</em> is known at compile time, then you can use directly constructors in cases without the need to import.
|
|
|
-</p>
|
|
|
-
|
|
|
-<a name="dynamic"></a>
|
|
|
-<h2>Dynamic</h2>
|
|
|
-
|
|
|
-<p>
|
|
|
- When you want to get some <em>dynamicly typed</em> behavior and get free from the type system, you can use the <code>Dynamic</code> type which can be used in place of <em>any</em> type without any compiler check :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>var</k> x : Dynamic = "";
|
|
|
- x = true;
|
|
|
- x = 1.744;
|
|
|
- x = <k>new</k> Array();
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- Also, a <code>Dynamic</code> have an infinite number of fields, all having the type <code>Dynamic</code>, it can be used as an <code>Array</code> for bracket syntax, etc...
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- While this can be useful sometimes, please be careful not to break your program safety by using too many dynamic variables. An <em>untyped</em> variable is not a <code>Dynamic</code> but an <code>Unknown</code>, and is still stricly typed. This was explained in <em>type inference</em>.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>Dynamic Parameter</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- As it was said when listing standard library types, <code>Dynamic</code> <em>can</em> also take a type parameter. When you use <code>Dynamic<String></code>, it has different behavior.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- <code>Dynamic<String></code> cannot be used in place of any other type. However, it has an infinite number of fields which all have the type <code>String</code>. This is useful to encode Hashtables where items are accessed using <em>dot</em> syntax :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>var</k> att : Dynamic<String> = xml.attributes;
|
|
|
- x.name = <t>"Nicolas"</t>;
|
|
|
- x.age = <t>"26"</t>;
|
|
|
- <g>// ...</g>
|
|
|
-</pre>
|
|
|
-
|
|
|
-<h3>Implementic Dynamic</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- Any class can also <em>implement</em> a Dynamic with or without type parameter. In that case, the class fields are typed when they exists, or they have a dynamic type either :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>class</k> C <k>implements</k> Dynamic<Int> {
|
|
|
- <k>public var</k> name : String;
|
|
|
- <k>public var</k> address : String;
|
|
|
- }
|
|
|
- <g>// ...</g>
|
|
|
- <k>var</k> c = <k>new</k> C();
|
|
|
- <k>var</k> n : String = c.name; <g>// ok</g>
|
|
|
- <k>var</k> a : String = c.address; <g>// ok</g>
|
|
|
- <k>var</k> i : Int = c.phone; <g>// ok : use Dynamic</g>
|
|
|
- <k>var</k> co : String = c.country <g>// error : is an Int</g>
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- Dynamic behavior is <em>inherited</em> by subclasses. When several classes are implementing different Dynamic kinds in a class hierarchy, the last Dynamic definition is used.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>Untyped</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- One other way to do dynamic things is to use the <code>untyped</code> keyword. When an expression is said untyped, no type-check will be done so you can do a lot of dynamic operations at once :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>untyped</k> { a["hello"] = 0; }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- Since an <code>untyped</code> expression type is always <code>Dynamic</code>, one other usage of untyped is to do an <em>unsafe cast</em> from one type to another. :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>var</k> x : A = ...;
|
|
|
- <k>var</k> y : B = <k>untyped</k> x;
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- Be careful to use untyped expressions only when you really need them and when you know what you're doing.
|
|
|
-</p>
|
|
|
-
|
|
|
-<a name="tother"></a>
|
|
|
-<h2>Other Types</h2>
|
|
|
-
|
|
|
-<p>
|
|
|
- Up to know, we have seen the following types :
|
|
|
-</p>
|
|
|
-
|
|
|
-<ul>
|
|
|
- <li>class instance</li>
|
|
|
- <li>enum instance</li>
|
|
|
- <li>dynamic</li>
|
|
|
-</ul>
|
|
|
-
|
|
|
-<p>
|
|
|
- There is three additional important types :
|
|
|
-</p>
|
|
|
-
|
|
|
-<ul class="big">
|
|
|
- <li><b>Anonymous Type</b> : an anonymous type is the type of an anonymously declared object. It is also the type of a Class identifier (corresponding to all the static fields) or an Enum identifier (liting all the constructors). Here's an example that shows it :
|
|
|
- <pre>
|
|
|
- <k>enum</k> State {
|
|
|
- on;
|
|
|
- off;
|
|
|
- disable;
|
|
|
- }
|
|
|
-
|
|
|
- <k>class</k> C {
|
|
|
- <k>static var</k> x : Int;
|
|
|
- <k>static var</k> y : String;
|
|
|
-
|
|
|
- <k>function</k> f() {
|
|
|
- <g>// print { id : Int, city : String }</g>
|
|
|
- type({ id : 125, city : "Kyoto" });
|
|
|
- }
|
|
|
-
|
|
|
- <k>function</k> g() {
|
|
|
- <g>// print { on : State, off : State, disable : State }</g>
|
|
|
- type(State);
|
|
|
- }
|
|
|
-
|
|
|
- <k>function</k> h() {
|
|
|
- <g>// print { x : Int, y : String }</g>
|
|
|
- type(C);
|
|
|
- }
|
|
|
- }
|
|
|
- </pre>
|
|
|
- </li>
|
|
|
-
|
|
|
- <li><b>Function Type</b> : when you want to define function types, you can define them by listing the arguments followed by the return type and separated with arrows. For exemple <code>Int -> Void</code> is the type of a function taking an Int as argument and returning Void. And <code>Color -> Color -> Int</code> takes two Color arguments and returns an Int.
|
|
|
- <pre>
|
|
|
- <k>class</k> C {
|
|
|
- <k>function</k> f(x : String) : Int {
|
|
|
- <g>// ...</g>
|
|
|
- }
|
|
|
-
|
|
|
- <k>function</k> g() {
|
|
|
- type(f); <g>// print String -> Int</g>
|
|
|
- }
|
|
|
- }
|
|
|
- </pre>
|
|
|
- </li>
|
|
|
-
|
|
|
- <li><b>Unknown Type</b> : when a type is not declared, it is used with the type <code>Unknown</code>. The first time it is used with another type, it will change to it. This was explained in more details in <em>type inference</em>. The <code>id</code> printed with the <code>Unknown</code> type is used to differenciate several unknowns when printing a complex type.
|
|
|
- </li>
|
|
|
-
|
|
|
- <pre>
|
|
|
- <k>function</k> f() {
|
|
|
- <k>var</k> x;
|
|
|
- type(x); <g>// print Unknown<0></g>
|
|
|
- x = 0;
|
|
|
- type(x); <g>// print Int</g>
|
|
|
- }
|
|
|
- </pre>
|
|
|
-</ul>
|
|
|
-
|
|
|
-<p>
|
|
|
- The diversity of types expressible with <b>haXe</b> enable more powerful models of programming by providing high-level abstractions that don't need complex classes relationships to be used.
|
|
|
-</p>
|
|
|
-
|
|
|
-<a name="tsub"></a>
|
|
|
-<h2>Subtyping</h2>
|
|
|
-
|
|
|
-<p>
|
|
|
- The following types should have now be fully introduced in previous sections :
|
|
|
-</p>
|
|
|
-
|
|
|
-<ul>
|
|
|
- <li>class instance</li>
|
|
|
- <li>enum instance</li>
|
|
|
- <li>dynamic (with optional parameter)</li>
|
|
|
- <li>anonymous</li>
|
|
|
- <li>unknown (with an id)</li>
|
|
|
- <li>function</li>
|
|
|
-</ul>
|
|
|
-
|
|
|
-<p>
|
|
|
- When two types need to be used together, the compiler don't rely on simply checking <em>type equality</em>. For example an <code>Int</code> can be used everywhere a <code>Float</code> is required. In order to check if a type is allowed where another is requested, the compiler is using <b>subtyping</b>.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- Classes have their own <em>subtyping</em> relationship that was explained in <em>class heritance</em>. A Class instance can then be used instead of another Class instance if it's a subtype of it according to <em>extends</em> and <em>implements</em> statements.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- An Enum does not have subtype other then itself.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- <em>Type Parameters</em> must be <em>the sames</em> in order to have subtyping. For example, <code>Array<Int></code> is NOT a subtype of <code>Array<Float></code>.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- Anonymous types are using <em>structural</em> subtyping. An anonymous type B is a subtype of an anonymous type A is B is <em>included</em> into A. It means for example that <code>{ x : Int, y : Int, z : Int }</code> is a subtype of <code>{ x : Float, y : Float }</code>.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- Dynamic without parameter is a subtype of every type. Dynamic with a parameter is only subtype of Dynamic with the same parameter.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- Unknown is the subtype of every type as well. When testing for subtype, it will actually <em>become</em> this type and will no longer be an <em>Unknown</em>.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- A Function of the form <code>A1 -> A2 -> B</code> is the subtype of <code>B1 -> B2 -> A</code> if <code>B1</code> is the subtype of <code>A1</code>, <code>B2</code> is the subtype of <code>A2</code> and <code>B</code> is the subtype of <code>A</code>. Not so easy to understand but it's correct.
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- Subtyping is important in order to be able to get more extensible programs.
|
|
|
-</p>
|
|
|
-
|
|
|
-<a name="iter"></a>
|
|
|
-<h2>Iterators</h2>
|
|
|
-
|
|
|
-<p>
|
|
|
- An iterator is an object which implements the <code>Iterator</code> interface (The type <code>T</code> is the iterated type) :
|
|
|
-
|
|
|
-</p>
|
|
|
-
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>interface</k> Iterator<T> {
|
|
|
- <k>function</k> hasNext() : Bool;
|
|
|
- <k>function</k> next() : T;
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- You can use the <c><k>for</k></c> syntax in order to execute iterators. The most simple iterator is the <c>IntIter</c> iterator which can easily be built using the operator <c>...</c> (three dots). For example this will list all numbers from 0 to 9 :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>for</k> i <k>in</k> 0...10 {
|
|
|
- <g>// ...</g>
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- Or the usual <c><k>for</k></c> loop :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>for</k> i <k>in</k> 0...arr.length {
|
|
|
- foo(arr[i]);
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- You don't need to declare the variable <code>i</code> before using a for, since it will be automatically declared. This variable will only be available inside the <c><k>for</k></c> loop.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h3>Implementing Iterator</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- You can also define you own iterators. You can simply implement the <c>Iterator</c> interface in your class. This method must return an object implementing the <code>Iterator</code> interface. Here's for example the <code>IntIter</code> class that is part of the standard library and can iter both backward and forward :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre> <k>class</k> IntIter <k>implements</k> Iterator<Int> {
|
|
|
- <k>var</k> min : Int;
|
|
|
- <k>var</k> max : Int;
|
|
|
-
|
|
|
- <k>public function new</k>( min : Int, max : Int ) {
|
|
|
- <k>this</k>.min = min;
|
|
|
- <k>this</k>.max = max;
|
|
|
- }
|
|
|
-
|
|
|
- <k>public function</k> hasNext() {
|
|
|
- <k>return</k>( min != max );
|
|
|
- }
|
|
|
-
|
|
|
- <k>public function</k> next() {
|
|
|
- <k>if</k>( min < max )
|
|
|
- <k>return</k> min++;
|
|
|
- <k>else</k>
|
|
|
- <k>return</k> min--;
|
|
|
- }
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- Once your iterator is implemented, you can simply use it with the <c><k>for</k>...<k>in</k></c> syntax, this way :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>var</k> iter = <k>new</k> IntIter(0,10);
|
|
|
- <k>for</k> i <k>in</k> iter {
|
|
|
- <g>// ...</g>
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>The variable name in the <code>for</code> is automatically declared and its
|
|
|
-type is bound to the iterator type. It cannot be accessible after the iteration is done.</p>
|
|
|
-
|
|
|
-<h3>Iterable Objects</h3>
|
|
|
-
|
|
|
-<p>
|
|
|
- If an object has a method <code>iterator()</code> taking no arguments and returning an iterator, it is said <em>iterable</em>. It doesn't have to implement any type. You can use such class directly into a <code>for</code> expression without the need to call the <code>iterator()</code> method :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- <k>var</k> a : Array<String> = ["hello","world","I","love","haXe","!"];
|
|
|
- <k>for</k> txt <k>in</k> a {
|
|
|
- tf.text += txt + " ";
|
|
|
- }
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- This sample will build the string by listing an array elements using an iterator. It is same as calling <code>a.iterator()</code> in the <code>for</code> expression.
|
|
|
-</p>
|
|
|
-
|
|
|
-<a name="cond"></a>
|
|
|
-<h2>Conditional Compilation</h2>
|
|
|
-
|
|
|
-<p>
|
|
|
- Sometimes you might want to have a single library using specific API depending on the platform it is compiled on. At some other time, you might want to do some optimizations only if you turn a flag ON. For all that, you can use <em>conditional compilation macros</em> :
|
|
|
-</p>
|
|
|
-
|
|
|
-<p>
|
|
|
- Here's an example of multiplaform code :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- #flash8
|
|
|
- <g>// haXe code specific for flash player 8</g>
|
|
|
- #else flash
|
|
|
- <g>// haXe code specific for flash platform (any version)</g>
|
|
|
- #else js
|
|
|
- <g>// haXe code specific for javascript plaform</g>
|
|
|
- #else neko
|
|
|
- <g>// haXe code specific for neko plaform</g>
|
|
|
- #else error <g>// will display an error "Not implemented on this platform"</g>
|
|
|
- #end
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- Here's another example for turning on some logs only if <code>mydebug</code> flag is used when compiling the code :
|
|
|
-</p>
|
|
|
-
|
|
|
-<pre>
|
|
|
- #mydebug
|
|
|
- trace("Some debug infos");
|
|
|
- #end
|
|
|
-</pre>
|
|
|
-
|
|
|
-<p>
|
|
|
- You can define your own variables by using the <b>haXe</b> compiler commandline options.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h2>And Now ?</h2>
|
|
|
-
|
|
|
-<p>
|
|
|
- Now that you have a good understanding of the language, you can go to the next section : <a href="tutos.html">Tutorials</a>.
|
|
|
-</p>
|
|
|
-
|
|
|
-<h2>Author</h2>
|
|
|
-
|
|
|
-<p>
|
|
|
- <a href="mailto:[email protected]">Nicolas Cannasse</a>
|
|
|
-</p>
|
|
|
-
|
|
|
-<h2 class="end">Eof</h2>
|
|
|
-
|
|
|
-</div>
|
|
|
-
|
|
|
-</body>
|
|
|
-</html>
|