diff --git a/haxe.html.markdown b/haxe.html.markdown index afb9d1a3..c2f47012 100644 --- a/haxe.html.markdown +++ b/haxe.html.markdown @@ -7,10 +7,10 @@ contributors: --- Haxe is a web-oriented language that provides platform support for C++, C#, -Swf/ActionScript, Javascript, Java, and Neko byte code (also written by the -Haxe author). Note that this guide is for Haxe version 3. Some of the guide -may be applicable to older versions, but it is recommended to use other -references. +Swf/ActionScript, Javascript, Java, PHP, Python, Lua, Hashlink and Neko byte code +(the latter two also written by the Haxe author). Note that this guide is for +Haxe version 3. Some of the guide may be applicable to older versions, but it is +recommended to use other references. ```csharp /* @@ -26,16 +26,14 @@ references. Multiline comments are also used to generate javadoc-style documentation for haxedoc. They will be used for haxedoc if they immediately precede a class, class function, or class variable. - */ -// Double slashes like this will give a single-line comment - +// Double slashes like this will give a single-line comment. /* This is your first actual haxe code coming up, it's declaring an empty - package. A package isn't necessary, but it's useful if you want to create a - namespace for your code (e.g. org.yourapp.ClassName). + package. A package isn't necessary, but it's useful if you want to create + a namespace for your code (e.g. org.yourapp.ClassName). Omitting package declaration is the same as declaring an empty package. */ @@ -47,8 +45,9 @@ package; // empty package, no namespace. must be lower case while module names are capitalized. A module contain one or more types whose names are also capitalized. - E.g, the class "org.yourapp.Foo" should have the folder structure org/module/Foo.hx, - as accessible from the compiler's working directory or class path. + E.g, the class "org.yourapp.Foo" should have the folder structure + org/module/Foo.hx, as accessible from the compiler's working directory or + class path. If you import code from other files, it must be declared before the rest of the code. Haxe provides a lot of common default classes to get you started: @@ -64,34 +63,27 @@ import Lambda.array; // you can also use "*" to import all static fields import Math.*; -/* - You can also import classes in a special way, enabling them to extend the - functionality of other classes like a "mixin". More on 'using' later. - */ +// You can also import classes in a special way, enabling them to extend the +// functionality of other classes like a "mixin". More on 'using' later. using StringTools; -/* - Typedefs are like variables... for types. They must be declared before any - code. More on this later. - */ +// Typedefs are like variables... for types. They must be declared before any +// code. More on this later. typedef FooString = String; // Typedefs can also reference "structural" types, more on that later as well. typedef FooObject = { foo: String }; -/* - Here's the class definition. It's the main class for the file, since it has - the same name (LearnHaxe3). - */ -class LearnHaxe3{ +// Here's the class definition. It's the main class for the file, since it has +// the same name (LearnHaxe3). +class LearnHaxe3 { /* If you want certain code to run automatically, you need to put it in a static main function, and specify the class in the compiler arguments. In this case, we've specified the "LearnHaxe3" class in the compiler arguments above. */ - static function main(){ - + static function main() { /* Trace is the default method of printing haxe expressions to the screen. Different targets will have different methods of @@ -103,17 +95,13 @@ class LearnHaxe3{ */ trace("Hello World, with trace()!"); - /* - Trace can handle any type of value or object. It will try to print - a representation of the expression as best it can. You can also - concatenate strings with the "+" operator: - */ + // Trace can handle any type of value or object. It will try to print + // a representation of the expression as best it can. You can also + // concatenate strings with the "+" operator: trace( " Integer: " + 10 + " Float: " + 3.14 + " Boolean: " + true); - /* - In Haxe, it's required to separate expressions in the same block with - semicolons. But, you can put two expressions on one line: - */ + // In Haxe, it's required to separate expressions in the same block with + // semicolons. But, you can put two expressions on one line: trace('two expressions..'); trace('one line'); @@ -122,14 +110,11 @@ class LearnHaxe3{ ////////////////////////////////////////////////////////////////// trace("***Types & Variables***"); - /* - You can save values and references to data structures using the - "var" keyword: - */ + // You can save values and references to data structures using the + // "var" keyword: var an_integer:Int = 1; trace(an_integer + " is the value for an_integer"); - /* Haxe is statically typed, so "an_integer" is declared to have an "Int" type, and the rest of the expression assigns the value "1" to @@ -150,46 +135,36 @@ class LearnHaxe3{ Haxe uses platform precision for Int and Float sizes. It also uses the platform behavior for overflow. (Other numeric types and behavior are possible using special - libraries) - */ - - /* + libraries.) + In addition to simple values like Integers, Floats, and Booleans, Haxe provides standard library implementations for common data structures like strings, arrays, lists, and maps: */ - var a_string = "some" + 'string'; // strings can have double or single quotes + // Strings can have double or single quotes. + var a_string = "some" + 'string'; trace(a_string + " is the value for a_string"); - /* - Strings can be "interpolated" by inserting variables into specific - positions. The string must be single quoted, and the variable must - be preceded with "$". Expressions can be enclosed in ${...}. - */ + // Strings can be "interpolated" by inserting variables into specific + // positions. The string must be single quoted, and the variable must + // be preceded with "$". Expressions can be enclosed in ${...}. var x = 1; var an_interpolated_string = 'the value of x is $x'; var another_interpolated_string = 'the value of x + 1 is ${x + 1}'; - /* - Strings are immutable, instance methods will return a copy of - parts or all of the string. - (See also the StringBuf class). - */ + // Strings are immutable, instance methods will return a copy of + // parts or all of the string. (See also the StringBuf class). var a_sub_string = a_string.substr(0,4); trace(a_sub_string + " is the value for a_sub_string"); - /* - Regexes are also supported, but there's not enough space to go into - much detail. - */ + // Regexes are also supported, but there's not enough space here to go + // into much detail. var re = ~/foobar/; trace(re.match('foo') + " is the value for (~/foobar/.match('foo')))"); - /* - Arrays are zero-indexed, dynamic, and mutable. Missing values are - defined as null. - */ + // Arrays are zero-indexed, dynamic, and mutable. Missing values are + // defined as null. var a = new Array(); // an array that contains Strings a[0] = 'foo'; trace(a.length + " is the value for a.length"); @@ -197,20 +172,17 @@ class LearnHaxe3{ trace(a.length + " is the value for a.length (after modification)"); trace(a[3] + " is the value for a[3]"); //null - /* - Arrays are *generic*, so you can indicate which values they contain - with a type parameter: - */ + // Arrays are *generic*, so you can indicate which values they contain + // with a type parameter: var a2 = new Array(); // an array of Ints var a3 = new Array>(); // an Array of Arrays (of Strings). - /* - Maps are simple key/value data structures. The key and the value - can be of any type. - */ - var m = new Map(); // The keys are strings, the values are Ints. + // Maps are simple key/value data structures. The key and the value + // can be of any type. + // Here, the keys are strings, and the values are Ints: + var m = new Map(); m.set('foo', 4); - // You can also use array notation; + // You can also use array notation: m['bar'] = 5; trace(m.exists('bar') + " is the value for m.exists('bar')"); trace(m.get('bar') + " is the value for m.get('bar')"); @@ -219,19 +191,15 @@ class LearnHaxe3{ var m2 = ['foo' => 4, 'baz' => 6]; // Alternative map syntax trace(m2 + " is the value for m2"); - /* - Remember, you can use type inference. The Haxe compiler will - decide the type of the variable the first time you pass an - argument that sets a type parameter. - */ + // Remember, you can use type inference. The Haxe compiler will + // decide the type of the variable the first time you pass an + // argument that sets a type parameter. var m3 = new Map(); m3.set(6, 'baz'); // m3 is now a Map trace(m3 + " is the value for m3"); - /* - Haxe has some more common datastructures in the haxe.ds module, such as - List, Stack, and BalancedTree - */ + // Haxe has some more common datastructures in the haxe.ds module, such + // as List, Stack, and BalancedTree. ////////////////////////////////////////////////////////////////// @@ -243,10 +211,10 @@ class LearnHaxe3{ trace((4 + 3) + " is the value for (4 + 3)"); trace((5 - 1) + " is the value for (5 - 1)"); trace((2 * 4) + " is the value for (2 * 4)"); - trace((8 / 3) + " is the value for (8 / 3) (division always produces Floats)"); + // Division always produces Floats. + trace((8 / 3) + " is the value for (8 / 3) (a Float)"); trace((12 % 4) + " is the value for (12 % 4)"); - //basic comparison trace((3 == 2) + " is the value for 3 == 2"); trace((3 != 2) + " is the value for 3 != 2"); @@ -257,6 +225,7 @@ class LearnHaxe3{ // standard bitwise operators /* + ~ Unary bitwise complement << Signed left shift >> Signed right shift @@ -264,15 +233,17 @@ class LearnHaxe3{ & Bitwise AND ^ Bitwise exclusive OR | Bitwise inclusive OR + */ - //increments + // increments var i = 0; trace("Increments and decrements"); - trace(i++); //i = 1. Post-Incrementation - trace(++i); //i = 2. Pre-Incrementation - trace(i--); //i = 1. Post-Decrementation - trace(--i); //i = 0. Pre-Decrementation + trace(i++); // i = 1. Post-Increment + trace(++i); // i = 2. Pre-Increment + trace(i--); // i = 1. Post-Decrement + trace(--i); // i = 0. Pre-Decrement + ////////////////////////////////////////////////////////////////// // Control Structures @@ -292,10 +263,8 @@ class LearnHaxe3{ // there is also a "ternary" if: (j == 10) ? trace("equals 10") : trace("not equals 10"); - /* - Finally, there is another form of control structures that operates - at compile time: conditional compilation. - */ + // Finally, there is another form of control structure that operates + // at compile time: conditional compilation. #if neko trace('hello from neko'); #elseif js @@ -303,43 +272,40 @@ class LearnHaxe3{ #else trace('hello from another platform!'); #end - /* - The compiled code will change depending on the platform target. - Since we're compiling for neko (-x or -neko), we only get the neko - greeting. - */ + + // The compiled code will change depending on the platform target. + // Since we're compiling for neko (-x or -neko), we only get the neko + // greeting. trace("Looping and Iteration"); // while loop var k = 0; - while(k < 100){ + while (k < 100){ // trace(counter); // will print out numbers 0-99 k++; } // do-while loop var l = 0; - do{ + do { trace("do statement always runs at least once"); } while (l > 0); // for loop - /* - There is no c-style for loop in Haxe, because they are prone - to error, and not necessary. Instead, Haxe has a much simpler - and safer version that uses Iterators (more on those later). - */ + // There is no c-style for loop in Haxe, because they are prone + // to error, and not necessary. Instead, Haxe has a much simpler + // and safer version that uses Iterators (more on those later). var m = [1,2,3]; - for (val in m){ + for (val in m) { trace(val + " is the value for val in the m array"); } // Note that you can iterate on an index using a range // (more on ranges later as well) var n = ['foo', 'bar', 'baz']; - for (val in 0...n.length){ + for (val in 0...n.length) { trace(val + " is the value for val (an index for n)"); } @@ -354,8 +320,11 @@ class LearnHaxe3{ var modified_n = [for (val in n) val += '!']; trace(modified_n + " is the value for modified_n"); - var filtered_and_modified_n = [for (val in n) if (val != "foo") val += "!"]; - trace(filtered_and_modified_n + " is the value for filtered_and_modified_n"); + var filtered_and_modified_n + = [for (val in n) if (val != "foo") val += "!"]; + trace(filtered_and_modified_n + + " is the value for filtered_and_modified_n"); + ////////////////////////////////////////////////////////////////// // Switch Statements (Value Type) @@ -375,24 +344,23 @@ class LearnHaxe3{ case "rex" : favorite_thing = "shoe"; case "spot" : favorite_thing = "tennis ball"; default : favorite_thing = "some unknown treat"; - // case _ : favorite_thing = "some unknown treat"; // same as default + // same as default: + // case _ : favorite_thing = "some unknown treat"; } - // The "_" case above is a "wildcard" value - // that will match anything. + // The "_" case above is a "wildcard" value that will match anything. trace("My dog's name is " + my_dog_name + ", and his favorite thing is a: " + favorite_thing); + ////////////////////////////////////////////////////////////////// // Expression Statements ////////////////////////////////////////////////////////////////// trace("***EXPRESSION STATEMENTS***"); - /* - Haxe control statements are very powerful because every statement - is also an expression, consider: - */ + // Haxe control statements are very powerful because every statement + // is also an expression, consider: // if statements var k = if (true) 10 else 20; @@ -410,6 +378,7 @@ class LearnHaxe3{ + ", and his other favorite thing is a: " + other_favorite_thing); + ////////////////////////////////////////////////////////////////// // Converting Value Types ////////////////////////////////////////////////////////////////// @@ -434,14 +403,13 @@ class LearnHaxe3{ ////////////////////////////////////////////////////////////////// /* - As mentioned before, Haxe is a statically typed language. All in all, static typing is a wonderful thing. It enables precise autocompletions, and can be used to thoroughly check the correctness of a program. Plus, the Haxe compiler is super fast. - *HOWEVER*, there are times when you just wish the compiler would let - something slide, and not throw a type error in a given case. + *HOWEVER*, there are times when you just wish the compiler would + let something slide, and not throw a type error in a given case. To do this, Haxe has two separate keywords. The first is the "Dynamic" type: @@ -456,11 +424,10 @@ class LearnHaxe3{ The other more extreme option is the "untyped" keyword: */ - - untyped { - var x:Int = 'foo'; // this can't be right! - var y:String = 4; // madness! - } + untyped { + var x:Int = 'foo'; // this can't be right! + var y:String = 4; // madness! + } /* The untyped keyword operates on entire *blocks* of code, skipping @@ -474,74 +441,66 @@ class LearnHaxe3{ of the type models work should you resort to "Dynamic" or "untyped". */ + ////////////////////////////////////////////////////////////////// // Basic Object Oriented Programming ////////////////////////////////////////////////////////////////// trace("***BASIC OBJECT ORIENTED PROGRAMMING***"); - - /* - Create an instance of FooClass. The classes for this are at the - end of the file. - */ + // Create an instance of FooClass. The classes for this are at the + // end of the file. var foo_instance = new FooClass(3); // read the public variable normally - trace(foo_instance.public_any + " is the value for foo_instance.public_any"); + trace(foo_instance.public_any + + " is the value for foo_instance.public_any"); // we can read this variable - trace(foo_instance.public_read + " is the value for foo_instance.public_read"); - // but not write it - // foo_instance.public_read = 4; // this will throw an error if uncommented: + trace(foo_instance.public_read + + " is the value for foo_instance.public_read"); + // but not write it; this will throw an error if uncommented: + // foo_instance.public_read = 4; // trace(foo_instance.public_write); // as will this. - // calls the toString method: + // Calls the toString method: trace(foo_instance + " is the value for foo_instance"); // same thing: - trace(foo_instance.toString() + " is the value for foo_instance.toString()"); + trace(foo_instance.toString() + + " is the value for foo_instance.toString()"); - - /* - The foo_instance has the "FooClass" type, while acceptBarInstance - has the BarClass type. However, since FooClass extends BarClass, it - is accepted. - */ + // The foo_instance has the "FooClass" type, while acceptBarInstance + // has the BarClass type. However, since FooClass extends BarClass, it + // is accepted. BarClass.acceptBarInstance(foo_instance); - /* - The classes below have some more advanced examples, the "example()" - method will just run them here. - */ + // The classes below have some more advanced examples, the "example()" + // method will just run them here. SimpleEnumTest.example(); ComplexEnumTest.example(); TypedefsAndStructuralTypes.example(); UsingExample.example(); - } - } -/* - This is the "child class" of the main LearnHaxe3 Class - */ -class FooClass extends BarClass implements BarInterface{ +// This is the "child class" of the main LearnHaxe3 Class. +class FooClass extends BarClass implements BarInterface { public var public_any:Int; // public variables are accessible anywhere public var public_read (default, null): Int; // enable only public read public var public_write (null, default): Int; // or only public write - public var property (get, set): Int; // use this style to enable getters/setters + // Use this style to enable getters/setters: + public var property (get, set): Int; // private variables are not available outside the class. // see @:allow for ways around this. var _private:Int; // variables are private if they are not marked public // a public constructor - public function new(arg:Int){ + public function new(arg:Int) { // call the constructor of the parent object, since we extended BarClass: super(); this.public_any = 0; this._private = arg; - } // getter for _private @@ -555,47 +514,40 @@ class FooClass extends BarClass implements BarInterface{ return val; } - // special function that is called whenever an instance is cast to a string. - public function toString(){ + // Special function that is called whenever an instance is cast to a string. + public function toString() { return _private + " with toString() method!"; } // this class needs to have this function defined, since it implements // the BarInterface interface. - public function baseFunction(x: Int) : String{ + public function baseFunction(x: Int) : String { // convert the int to string automatically return x + " was passed into baseFunction!"; } } -/* - A simple class to extend -*/ +// A simple class to extend. class BarClass { var base_variable:Int; - public function new(){ + public function new() { base_variable = 4; } - public static function acceptBarInstance(b:BarClass){ - } + public static function acceptBarInstance(b:BarClass) {} } -/* - A simple interface to implement -*/ +// A simple interface to implement interface BarInterface{ public function baseFunction(x:Int):String; } + ////////////////////////////////////////////////////////////////// // Enums and Switch Statements ////////////////////////////////////////////////////////////////// -/* - Enums in Haxe are very powerful. In their simplest form, enums - are a type with a limited number of states: - */ - +// Enums in Haxe are very powerful. In their simplest form, enums +// are a type with a limited number of states: enum SimpleEnum { Foo; Bar; @@ -603,12 +555,12 @@ enum SimpleEnum { } // Here's a class that uses it: - -class SimpleEnumTest{ - public static function example(){ - var e_explicit:SimpleEnum = SimpleEnum.Foo; // you can specify the "full" name +class SimpleEnumTest { + public static function example() { + // You can specify the "full" name, + var e_explicit:SimpleEnum = SimpleEnum.Foo; var e = Foo; // but inference will work as well. - switch(e){ + switch(e) { case Foo: trace("e was Foo"); case Bar: trace("e was Bar"); case Baz: trace("e was Baz"); // comment this line to throw an error. @@ -621,18 +573,16 @@ class SimpleEnumTest{ You can also specify a default for enum switches as well: */ - switch(e){ + switch(e) { case Foo: trace("e was Foo again"); default : trace("default works here too"); } } } -/* - Enums go much further than simple states, we can also enumerate - *constructors*, but we'll need a more complex enum example - */ -enum ComplexEnum{ +// Enums go much further than simple states, we can also enumerate +// *constructors*, but we'll need a more complex enum example +enum ComplexEnum { IntEnum(i:Int); MultiEnum(i:Int, j:String, k:Float); SimpleEnumEnum(s:SimpleEnum); @@ -641,13 +591,11 @@ enum ComplexEnum{ // Note: The enum above can include *other* enums as well, including itself! // Note: This is what's called *Algebraic data type* in some other languages. -class ComplexEnumTest{ - public static function example(){ +class ComplexEnumTest { + public static function example() { var e1:ComplexEnum = IntEnum(4); // specifying the enum parameter - /* - Now we can switch on the enum, as well as extract any parameters - it might of had. - */ + // Now we can switch on the enum, as well as extract any parameters + // it might of had. switch(e1){ case IntEnum(x) : trace('$x was the parameter passed to e1'); default: trace("Shouldn't be printed"); @@ -663,33 +611,27 @@ class ComplexEnumTest{ // enums all the way down var e3 = ComplexEnumEnum(ComplexEnumEnum(MultiEnum(4, 'hi', 4.3))); switch(e3){ - // You can look for certain nested enums by specifying them explicitly: + // You can look for certain nested enums by specifying them + // explicitly: case ComplexEnumEnum(ComplexEnumEnum(MultiEnum(i,j,k))) : { trace('$i, $j, and $k were passed into this nested monster'); } default: trace("Shouldn't be printed"); } - /* - Check out "generalized algebraic data types" (GADT) for more details - on why these are so great. - */ + // Check out "generalized algebraic data types" (GADT) for more details + // on why these are so great. } } class TypedefsAndStructuralTypes { public static function example(){ - /* - Here we're going to use typedef types, instead of base types. - At the top we've declared the type "FooString" to mean a "String" type. - */ + // Here we're going to use typedef types, instead of base types. + // At the top we've declared the type "FooString" to mean a "String" type. var t1:FooString = "some string"; - /* - We can use typedefs for "structural types" as well. These types are - defined by their field structure, not by class inheritance. Here's - an anonymous object with a String field named "foo": - */ - + // We can use typedefs for "structural types" as well. These types are + // defined by their field structure, not by class inheritance. Here's + // an anonymous object with a String field named "foo": var anon_obj = { foo: 'hi' }; /* @@ -699,8 +641,7 @@ class TypedefsAndStructuralTypes { that structure, we can use it anywhere that a "FooObject" type is expected. */ - - var f = function(fo:FooObject){ + var f = function(fo:FooObject) { trace('$fo was passed in to this function'); } f(anon_obj); // call the FooObject signature function with anon_obj. @@ -728,15 +669,14 @@ class TypedefsAndStructuralTypes { typedef Surface = java.awt.geom.GeneralPath; #end - That would give us a single "Surface" type to work with across - all of those platforms. + That would give us a single "Surface" type to work with across + all of those platforms. */ } } class UsingExample { public static function example() { - /* The "using" import keyword is a special type of class import that alters the behavior of any static methods in the class.