# HaxeFoundation/HaxeManual

Switch branches/tags
Nothing to show
Fetching contributors…
Cannot retrieve contributors at this time
783 lines (514 sloc) 36.1 KB
 \chapter{Language Features} \label{lf} \emph{\tref{Abstract types}{types-abstract}:} An abstract type is a compile-time construct which is represented in a different way at runtime. This allows giving a whole new meaning to existing types. \emph{\tref{Extern classes}{lf-externs}:} Externs can be used to describe target-specific interaction in a type-safe manner. \emph{\tref{Anonymous structures}{types-anonymous-structure}:} Data can easily be grouped in anonymous structures, minimizing the necessity of small data classes. \begin{lstlisting} var point = { x: 0, y: 10 }; point.x += 10; \end{lstlisting} \emph{\tref{Array Comprehension}{lf-array-comprehension}:} Create and populate arrays quickly using for loops and logic. \begin{lstlisting} var evenNumbers = [ for (i in 0...100) if (i\%2==0) i ]; \end{lstlisting} \emph{\tref{Classes, interfaces and inheritance}{types-class-instance}:} Haxe allows structuring code in classes, making it an object-oriented language. Common related features known from languages such as Java are supported, including inheritance and interfaces. \emph{\tref{Conditional compilation}{lf-condition-compilation}:} Conditional Compilation allows compiling specific code depending on compilation parameters. This is instrumental for abstracting target-specific differences, but can also be used for other purposes, such as more detailed debugging. \begin{lstlisting} \#if js js.Browser.alert("Hello"); \#elseif sys Sys.println("Hello"); \#end \end{lstlisting} \emph{\tref{(Generalized) Algebraic Data Types}{types-enum-instance}:} Structure can be expressed through algebraic data types (ADT), which are known as enums in the Haxe Language. Furthermore, Haxe supports their generalized variant known as GADT. \begin{lstlisting} enum Result { Success(data:Array); UserError(msg:String); SystemError(msg:String, position:PosInfos); } \end{lstlisting} \emph{\tref{Inlined calls}{class-field-inline}:} Functions can be designated as being inline, allowing their code to be inserted at call-site. This can yield significant performance benefits without resorting to code duplication via manual inlining. \emph{\tref{Iterators}{lf-iterators}:} Iterating over a set of values, e.g. the elements of an array, is very easy in Haxe courtesy of iterators. Custom classes can quickly implement iterator functionality to allow iteration. \begin{lstlisting} for (i in [1, 2, 3]) { trace(i); } \end{lstlisting} \emph{\tref{Local functions and closures}{expression-function}:} Functions in Haxe are not limited to class fields and can be declared in expressions as well, allowing powerful closures. \begin{lstlisting} var buffer = ""; function append(s:String) { buffer += s; } append("foo"); append("bar"); trace(buffer); // foobar \end{lstlisting} \emph{\tref{Metadata}{lf-metadata}:} Add metadata to fields, classes or expressions. This can communicate information to the compiler, macros, or runtime classes. \begin{lstlisting} class MyClass { @range(1, 8) var value:Int; } trace(haxe.rtti.Meta.getFields(MyClass).value.range); // [1,8] \end{lstlisting} \emph{\tref{Static Extensions}{lf-static-extension}:} Existing classes and other types can be augmented with additional functionality through using static extensions. \begin{lstlisting} using StringTools; " Me & You ".trim().htmlEscape(); \end{lstlisting} \emph{\tref{String Interpolation}{lf-string-interpolation}:} Strings declared with a single quotes are able to access variables in the current context. \begin{lstlisting} trace('My name is $name and I work in${job.industry}'); \end{lstlisting} \emph{\tref{Partial function application}{lf-function-bindings}:} Any function can be applied partially, providing the values of some arguments and leaving the rest to be filled in later. \begin{lstlisting} var map = new haxe.ds.IntMap(); var setToTwelve = map.set.bind(_, 12); setToTwelve(1); setToTwelve(2); \end{lstlisting} \emph{\tref{Pattern Matching}{lf-pattern-matching}:} Complex structures can be matched against patterns, extracting information from an enum or a structure and defining specific operations for specific value combination. \begin{lstlisting} var a = { foo: 12 }; switch (a) { case { foo: i }: trace(i); default: } \end{lstlisting} \emph{\tref{Properties}{class-field-property}:} Variable class fields can be designed as properties with custom read and write access, allowing fine grained access control. \begin{lstlisting} public var color(get,set); function get_color() { return element.style.backgroundColor; } function set_color(c:String) { trace('Setting background of element to $c'); return element.style.backgroundColor = c; } \end{lstlisting} \emph{\tref{Access control}{lf-access-control}:} The access control language feature uses the Haxe metadata syntax to force or allow access classes or fields. \emph{\tref{Type Parameters, Constraints and Variance}{type-system-type-parameters}:} Types can be parametrized with type parameters, allowing typed containers and other complex data structures. Type parameters can also be constrained to certain types and respect variance rules. \begin{lstlisting} class Main { static function main() { new Main("foo"); new Main(12); // use type inference } function new(a:A) { } } \end{lstlisting} \section{Conditional Compilation} \label{lf-condition-compilation} Haxe allows conditional compilation by using \expr{\#if}, \expr{\#elseif} and \expr{\#else} and checking for \emph{compiler flags}. \define{Compiler Flag}{define-compiler-flag}{A compiler flag is a configurable value which may influence the compilation process. Such a flag can be set by invoking the command line with \expr{-D key=value} or just \expr{-D key}, in which case the value defaults to \expr{"1"}. The compiler also sets several flags internally to pass information between different compilation steps.} This example demonstrates usage of conditional compilation: \haxe{assets/ConditionalCompilation.hx} Compiling this without any flags will leave only the \expr{trace("ok");} line in the body of the \expr{main} method. The other branches are discarded while parsing the file. These other branches must still contain valid Haxe syntax, but the code is not type-checked. The conditions after \expr{\#if} and \expr{\#elseif} allow the following expressions: \begin{itemize} \item Any identifier is replaced by the value of the compiler flag by the same name. Note that \expr{-D some-flag} from command line leads to the flags \expr{some-flag} and \expr{some\_flag} to be defined. \item The values of \type{String}, \type{Int} and \type{Float} constants are used directly. \item The boolean operators \expr{\&\&} (and), \expr{||} (or) and \expr{!} (not) work as expected, however the full expression must be completely contained by parentheses. \item The operators \expr{==}, \expr{!=}, \expr{>}, \expr{>=}, \expr{<}, \expr{<=} can be used to compare values. \item Parentheses \expr{()} can be used to group expressions as usual. \end{itemize} The Haxe parser does not parse \expr{some-flag} as a single token and instead reads it as a subtraction binary operator \expr{some - flag}. In cases like this the underscore version \expr{some_flag} has to be used. \paragraph{Working with compiler flags} Compiler flags are available at compile time, the following methods only work in macro context: \begin{itemize} \item To see if a compiler flag is set, use \expr{haxe.macro.Context.defined("any_flag")}. \item To get the value of a compiler flag, use \expr{haxe.macro.Context.definedValue("any_flag")}. \item To get a map of all compiler flags with its value use \expr{haxe.macro.Context.getDefines()}. \end{itemize} \paragraph{Haxelibs} By default, each used haxelib version is automatically added as flag, e.g. when you add \expr{-lib actuate}, the compiler adds \expr{-D actuate=1.8.7}. To test if a library exists in current context, use \expr{\#if actuate}. To check a specific haxelib version, use the operators, for example \expr{\#if (actuate <= "1.8.7")} \paragraph{Built-in Compiler Flags} An exhaustive list of all built-in defines can be obtained by invoking the Haxe Compiler with the \expr{--help-defines} argument. The Haxe Compiler allows multiple \expr{-D} flags per compilation. \paragraph{Related content} \begin{itemize} \item See also the \tref{Compiler Flags list}{compiler-usage-flags}. \end{itemize} \section{Externs} \label{lf-externs} Externs can be used to describe target-specific interaction in a type-safe manner. They are defined like normal classes, except that \begin{itemize} \item the \expr{class} keyword is preceded by the \expr{extern} keyword, \item \tref{methods}{class-field-method} have no expressions, \item all argument and return types are explicit, and \item the default \tref{visibility}{class-field-visibility} is \expr{public} (\expr{private} must be specified explicitly). \end{itemize} A common example from the \tref{Haxe Standard Library}{std} is the \type{Math} class, as an excerpt shows: \begin{lstlisting} extern class Math { static var PI(default,null) : Float; static function floor(v:Float):Int; } \end{lstlisting} We see that externs can define both methods and variables (actually, \expr{PI} is declared as a read-only \tref{property}{class-field-property}). Once this information is available to the compiler, it allows field access accordingly and also knows the types: \haxe{assets/Extern.hx} This works because the return type of method \expr{floor} is declared to be \type{Int}. The Haxe Standard Library comes with many externs for the \target{Flash} and \target{JavaScript} target. They allow accessing the native APIs in a type-safe manner and are instrumental for designing higher-level APIs. There are also externs for many popular native libraries on \tref{haxelib}{haxelib}. The \target{Flash}, \target{Java} and \target{C\#} targets allow direct inclusion of native libraries from \tref{command line}{compiler-usage}. Target-specific details are explained in the respective sections of \Fullref{target-details}. Some targets such as \target{Python} or \target{JavaScript} may require generating additional "import" code that loads an \expr{extern} class from a native module. Haxe provides ways to declare such dependencies also described in respective sections \Fullref{target-details}. \paragraph{Rest arguments and type choices} \since{3.2.0} The haxe.extern package provides two types that help mapping native semantics to Haxe: \begin{description} \item[\type{Rest}:] This type can be used as a final function argument to allow passing an arbitrary number of additional call arguments. The type parameter can be used to constrain these arguments to a specific type. \item[\type{EitherType}:] This type allows using either of its parameter types, thus representing a type choice. It can be nested to allow more than two different types. \end{description} We demonstrate the usage in this code sample: \haxe{assets/RestAndEitherType.hx} \paragraph{Visibility} Externs support the \expr{private} visibility modifier. However, because the default visibility in an extern class is \expr{public}, \expr{private} needs to be explicitly specified. Specifying \expr{private} members is helpful when an API intends to allow overriding functions. Also, Haxe cannot prevent subclasses from reusing field names unless if the fields are included in the extern definition. This is important on targets such as JavaScript where reusing a super class’s field name as a new field in a subclass is not supported. \begin{lstlisting} extern class ExampleSuperClass { private function new(); // Require subclassing to use. // Only allow subclasses access to this overridable function. private function overridableFunction():String; // This function is implicitly public: function doSomething():String; } \end{lstlisting} \section{Static Extension} \label{lf-static-extension} \define{Static Extension}{define-static-extension}{A static extension allows pseudo-extending existing types without modifying their source. In Haxe this is achieved by declaring a static method with a first argument of the extending type and then bringing the defining class into context through \expr{using}.} Static extensions can be a powerful tool which allows augmenting types without actually changing them. The following example demonstrates the usage: \haxe{assets/StaticExtension.hx} Clearly, \type{Int} does not natively provide a \expr{triple} method, yet this program compiles and outputs \expr{36} as expected. This is because the call to \expr{12.triple()} is transformed into \expr{IntExtender.triple(12)}. There are three requirements for this: \begin{enumerate} \item Both the literal \expr{12} and the first argument of \expr{triple} are known to be of type \type{Int}. \item The class \type{IntExtender} is brought into context through \expr{using Main.IntExtender}. \item \type{Int} does not have a \expr{triple} field by itself (if it had, that field would take priority over the static extension). \end{enumerate} Static extensions are usually considered syntactic sugar and indeed they are, but it is worth noting that they can have a dramatic effect on code readability: Instead of nested calls in the form of \expr{f1(f2(f3(f4(x))))}, chained calls in the form of \expr{x.f4().f3().f2().f1()} can be used. Following the rules previously described in \Fullref{type-system-resolution-order}, multiple \expr{using} expressions are checked from bottom to top, with the types within each module as well as the fields within each type being checked from top to bottom. Using a module (as opposed to a specific type of a module, see \Fullref{type-system-modules-and-paths}) as static extension brings all its types into context. \paragraph{Related content} \begin{itemize} \item \href{http://code.haxe.org/tag/static-extension.html}{Haxe snippets and tutorials about static extensions} in the Haxe Code Cookbook. \end{itemize} \subsection{In the Haxe Standard Library} \label{lf-static-extension-in-std} Several classes in the Haxe Standard Library are suitable for static extension usage. The next example shows the usage of \type{StringTools}: \haxe{assets/StaticExtension2.hx} While \type{String} does not have a \expr{replace} functionality by itself, the \expr{using StringTools} static extension provides one. As usual, the \target{JavaScript} output nicely shows the transformation: \lang{js}\begin{lstlisting} Main.main = function() { StringTools.replace("adc","d","b"); } \end{lstlisting} The following classes from the Haxe Standard Library are designed to be used as static extensions: \begin{description} \item[\type{StringTools}:] Provides extended functionality on strings, such as replacing or trimming. \item[\type{Lambda}:] Provides functional methods on iterables. \item[\type{haxe.EnumTools}:] Provides type information functionality on enums and their instances. \item[\type{haxe.macro.Tools}:] Provides different extensions for working with macros (see \Fullref{macro-tools}). \end{description} \trivia{using'' using}{Since the \expr{using} keyword was added to the language, it has been common to talk about certain problems with using using'' or the effect of using using''. This makes for awkward English in many cases, so the author of this manual decided to call the feature by what it actually is: Static extension.} \section{Pattern Matching} \label{lf-pattern-matching} \state{NoContent} \subsection{Introduction} \label{lf-pattern-matching-introduction} Pattern matching is the process of branching depending on a value matching given, possibly deep patterns. In Haxe, all pattern matching is done within a \tref{\expr{switch} expression}{expression-switch} where the individual \expr{case} expressions represent the patterns. Here we will explore the syntax for different patterns using this data structure as running example: \haxe[firstline=1,lastline=4]{assets/PatternMatching.hx} Some pattern matcher basics include: \begin{itemize} \item Patterns will always be matched from top to bottom. \item The topmost pattern that matches the input value has its expression executed. \item A \expr{_} pattern matches anything, so \expr{case _}: is equal to \expr{default:} \end{itemize} \paragraph{Related content} \begin{itemize} \item More about the \tref{switch expression}{expression-switch}. \item \href{http://code.haxe.org/tag/pattern-matching.html}{Haxe snippets and tutorials about pattern matching} in the Haxe Code Cookbook. \end{itemize} \subsection{Enum matching} \label{lf-pattern-matching-enums} Enums can be matched by their constructors in a natural way: \haxe[firstline=8,lastline=21]{assets/PatternMatching.hx} The pattern matcher will check each case from top to bottom and pick the first one that matches the input value. The following manual interpretation of each case rule helps understanding the process: \begin{description} \item[\expr{case Leaf(_)}:] matching fails because \expr{myTree} is a \expr{Node} \item[\expr{case Node(_, Leaf(_))}:] matching fails because the right sub-tree of \expr{myTree} is not a \expr{Leaf}, but another \expr{Node} \item[\expr{case Node(_, Node(Leaf("bar"), _))}:] matching succeeds \item[\expr{case _}:] this is not checked here because the previous line matched \end{description} \subsection{Variable capture} \label{lf-pattern-matching-variable-capture} It is possible to catch any value of a sub-pattern by matching it against an identifier: \haxe[firstline=24,lastline=30]{assets/PatternMatching.hx} This would return one of the following: \begin{itemize} \item If \expr{myTree} is a \expr{Leaf}, its name is returned. \item If \expr{myTree} is a \expr{Node} whose left sub-tree is a \expr{Leaf}, its name is returned (this will apply here, returning \expr{"foo"}). \item Otherwise \expr{"none"} is returned. \end{itemize} It is also possible to use = to capture values which are further matched: \haxe[firstline=32,lastline=36]{assets/PatternMatching.hx} Here, \expr{leafNode} is bound to \expr{Leaf("foo")} if the input matches that. In all other cases, \expr{myTree} itself is returned: \expr{case x} works similar to \expr{case _} in that it matches anything, but with an identifier name like \expr{x} it also binds the matched value to that variable. \subsection{Structure matching} \label{lf-pattern-matching-structure} It is also possible to match against the fields of anonymous structures and instances: \haxe[firstline=38,lastline=50]{assets/PatternMatching.hx} In the second case we bind the matched \expr{name} field to identifier \expr{n} if \expr{rating} matches \expr{"awesome"}. Of course this structure could also be put into the \type{Tree} from the previous example to combine structure and enum matching. \subsection{Array matching} \label{lf-pattern-matching-array} Arrays can be matched on fixed length: \haxe[firstline=52,lastline=60]{assets/PatternMatching.hx} This will trace \expr{1} because \expr{myArray[1]} matches \expr{6}, and \expr{myArray[0]} is allowed to be anything. \subsection{Or patterns} \label{lf-pattern-matching-or} The \expr{|} operator can be used anywhere within patterns to describe multiple accepted patterns: \haxe[firstline=63,lastline=68]{assets/PatternMatching.hx} If there is a captured variable in an or-pattern, it must appear in both its sub-patterns. \subsection{Guards} \label{lf-pattern-matching-guards} It is also possible to further restrict patterns with the \expr{case ... if(condition):} syntax: \haxe[firstline=71,lastline=79]{assets/PatternMatching.hx} The first case has an additional guard condition \expr{if (b > a)}. It will only be selected if that condition holds, otherwise matching continues with the next case. \subsection{Match on multiple values} \label{lf-pattern-matching-tuples} Array syntax can be used to match on multiple values: \haxe[firstline=82,lastline=87]{assets/PatternMatching.hx} This is quite similar to usual array matching, but there are differences: \begin{itemize} \item The number of elements is fixed, so patterns of different array length will not be accepted. \item It is not possible to capture the switch value in a variable, i.e. \expr{case x} is not allowed (\expr{case _} still is). \end{itemize} \subsection{Extractors} \label{lf-pattern-matching-extractors} \since{3.1.0} Extractors allow applying transformations to values being matched. This is often useful when a small operation is required on a matched value before matching can continue: \haxe{assets/Extractor2.hx} Here we have to capture the argument value of the \expr{TString} enum constructor in a variable \expr{temp} and use a nested switch on \expr{temp.toLowerCase()}. Obviously, we want matching to succeed if \expr{TString} holds a value of \expr{"foo"} regardless of its casing. This can be simplified with extractors: \haxe{assets/Extractor.hx} Extractors are identified by the \expr{extractorExpression => match} expression. The compiler generates code which is similar to the previous example, but the original syntax was greatly simplified. Extractors consist of two parts, which are separated by the \expr{=>} operator: \begin{enumerate} \item The left side can be any expression, where all occurrences of underscore \expr{_} are replaced with the currently matched value. \item The right side is a pattern which is matched against the result of the evaluation of the left side. \end{enumerate} Since the right side is a pattern, it can contain another extractor. The following example chains'' two extractors: \haxe{assets/Extractor4.hx} This traces \expr{12} as a result of the calls to \expr{add(3, 1)}, where \expr{3} is the matched value, and \expr{mul(4, 3)} where \expr{4} is the result of the \expr{add} call. It is worth noting that the \expr{a} on the right side of the second \expr{=>} operator is a \tref{capture variable}{lf-pattern-matching-variable-capture}. It is currently not possible to use extractors within \tref{or-patterns}{lf-pattern-matching-or}: \haxe{assets/Extractor5.hx} However, it is possible to have or-patterns on the right side of an extractor, so the previous example would compile without the parentheses. \subsection{Exhaustiveness checks} \label{lf-pattern-matching-exhaustiveness} The compiler ensures that no possible cases are forgotten: \begin{lstlisting} switch(true) { case false: } // Unmatched patterns: true \end{lstlisting} The matched type \type{Bool} admits two values \expr{true} and \expr{false}, but only \expr{false} is checked. \todo{Figure out wtf our rules are now for when this is checked.} \subsection{Useless pattern checks} \label{lf-pattern-matching-unused} In a similar fashion, the compiler detects patterns which will never match the input value: \begin{lstlisting} switch(Leaf("foo")) { case Leaf(_) | Leaf("foo"): // This pattern is unused case Node(l,r): case _: // This pattern is unused } \end{lstlisting} \section{String Interpolation} \label{lf-string-interpolation} With Haxe 3 it is no longer necessary to manually concatenate parts of a string due to the introduction of \emph{String Interpolation}. Special identifiers, denoted by the dollar sign \expr{\$} within a String enclosed by single-quote \expr{'} characters, are evaluated as if they were concatenated identifiers: \begin{lstlisting} var x = 12; // The value of x is 12 trace('The value of x is $x'); \end{lstlisting} Furthermore, it is possible to include whole expressions in the string by using \expr{\$$\left\{expr\right\}$}, with \expr{expr} being any valid Haxe expression: \begin{lstlisting} var x = 12; // The sum of 12 and 3 is 15 trace('The sum of $x and 3 is${x + 3}'); \end{lstlisting} String interpolation is a compile-time feature and has no impact on the runtime. The above example is equivalent to manual concatenation, which is exactly what the compiler generates: \begin{lstlisting} trace("The sum of " + x + " and 3 is " + (x + 3)); \end{lstlisting} Of course the use of single-quote enclosed strings without any interpolation remains valid, but care has to be taken regarding the \$character as it triggers interpolation. If an actual dollar-sign should be used in the string, \expr{\$\$} can be used. \trivia{String Interpolation before Haxe 3}{String Interpolation has been a Haxe feature since version 2.09. Back then, the macro \expr{Std.format} had to be used, being both slower and less comfortable than the new string interpolation syntax.} \section{Array Comprehension} \label{lf-array-comprehension} Array comprehension in Haxe uses existing syntax to allow concise initialization of arrays. It is identified by \expr{for} or \expr{while} constructs: \haxe{assets/ArrayComprehension.hx} Variable \expr{a} is initialized to an array holding the numbers 0 to 9. The compiler generates code which adds the value of each loop iteration to the array, so the following code would be equivalent: \begin{lstlisting} var a = []; for (i in 0...10) a.push(i); \end{lstlisting} Variable \expr{b} is initialized to an array with the same values, but through a different comprehension style using \expr{while} instead of \expr{for}. Again, the following code would be equivalent: \begin{lstlisting} var i = 0; var b = []; while(i < 10) b.push(i++); \end{lstlisting} The loop expression can be anything, including conditions and nested loops, so the following works as expected: \haxe{assets/AdvArrayComprehension.hx} \section{Map Comprehension} \label{lf-map-comprehension} Map comprehension in Haxe uses existing syntax to allow concise initialization for \type{Map}. Maps are initialized like arrays, but use the map literal syntax with the \ic{=>} operator. It is identified by \expr{for} or \expr{while} constructs: \haxe{assets/MapComprehension.hx} Variable \expr{a} is initialized to an \type{Map} holding keys from 0 to 4 and string values. The compiler generates code which adds the value of each loop iteration to the map, so the following code would be equivalent: \begin{lstlisting} var a = new Map(); for (i in 0...5) a.set(i, 'number${i}'); \end{lstlisting} Variable \expr{b} is initialized to an \type{Map} with the same keys and values, but through a different comprehension style using \expr{while} instead of \expr{for}. Again, the following code would be equivalent: \begin{lstlisting} var i = 0; var b = new Map(); while(i < 5) b.set(i, 'number \${i++}'); \end{lstlisting} The loop expression can be anything, including conditions and nested loops, so the following works as expected: \haxe{assets/AdvMapComprehension.hx} \section{Iterators} \label{lf-iterators} With Haxe it is very easy to define custom iterators and iterable data types. These concepts are represented by the types \type{Iterator} and \type{Iterable} respectively: \begin{lstlisting} typedef Iterator = { function hasNext() : Bool; function next() : T; } typedef Iterable = { function iterator() : Iterator; } \end{lstlisting} Any \tref{class}{types-class-instance} which \tref{structurally unifies}{type-system-structural-subtyping} with one of these types can be iterated over using a \tref{for-loop}{expression-for}. That is, if the class defines methods \expr{hasNext} and \expr{next} with matching return types it is considered an iterator, if it defines a method \expr{iterator} returning an \type{Iterator} it is considered an iterable type. \haxe{assets/Iterator.hx} The type \type{MyStringIterator} in this example qualifies as iterator: It defines a method \expr{hasNext} returning \type{Bool} and a method \expr{next} returning \type{String}, making it compatible with \type{Iterator}. The \expr{main} method instantiates it, then iterates over it. \haxe{assets/Iterable.hx} Here we do not setup a full iterator like in the previous example, but instead define that the \type{MyArrayWrap} has a method \expr{iterator}, effectively forwarding the iterator method of the wrapped \type{Array} type. \paragraph{Related content} \begin{itemize} \item See the \href{http://api.haxe.org/Iterator.html}{Iterator API documentation}. \item \href{http://code.haxe.org/tag/iterator.html}{Haxe snippets and tutorials about iterators} in the Haxe Code Cookbook. \end{itemize} \section{Function Bindings} \label{lf-function-bindings} Haxe 3 allows binding functions with partially applied arguments. Each function type can be considered to have a \expr{bind} field, which can be called with the desired number of arguments in order to create a new function. This is demonstrated here: \haxe{assets/Bind.hx} Line 4 binds the function \expr{map.set} to a variable named \expr{f}, and applies \expr{12} as second argument. The underscore \expr{_} is used to denote that this argument is not bound, which is shown by comparing the types of \expr{map.set} and \expr{f}: The bound \type{String} argument is effectively cut from the type, turning a \expr{Int->String->Void} type into \expr{Int->Void}. A call to \expr{f(1)} then actually invokes \expr{map.set(1, "12")}, the calls to \expr{f(2)} and \expr{f(3)} are analogous. The last line proves that all three indices indeed are mapped to the value \expr{"12"}. The underscore \expr{_} can be skipped for trailing arguments, so the first argument could be bound through \expr{map.set.bind(1)}, yielding a \expr{String->Void} function that sets a new value for index \expr{1} on invocation. \paragraph{Optional arguments} By default, trailing optional arguments are bound to their default values and do not become arguments of the result function. This can be changed by using an explicit underscore \expr{_} instead, in which case the optional argument of the original function becomes a non-optional argument of the result function. \haxe{assets/BindOptional.hx} \trivia{Callback}{Prior to Haxe 3, Haxe used to know a \expr{callback}-keyword which could be called with a function argument followed by any number of binding arguments. The name originated from a common usage were a callback-function is created with the this-object being bound.\\ Callback would allow binding of arguments only from left to right as there was no support for the underscore \expr{_}. The choice to use an underscore was controversial and several other suggestions were made, none of which were considered superior. After all, the underscore \expr{_} at least looks like it's saying fill value in here'', which nicely describes its semantics.} \section{Metadata} \label{lf-metadata} Several constructs can be attributed with custom metadata: \begin{itemize} \item \expr{class} and \expr{enum} declarations \item Class fields \item Enum constructors \item Expressions \end{itemize} These metadata information can be obtained at runtime through the \type{haxe.rtti.Meta} API: \haxe{assets/Meta.hx} We can easily identify metadata by the leading \expr{@} character, followed by the metadata name and, optionally, by a number of comma-separated constant arguments enclosed in parentheses. \begin{itemize} \item Class \type{MyClass} has an \expr{author} metadata with a single String argument \expr{"Nicolas"}, as well as a \expr{:keep} metadata without arguments. \item The member variable \expr{value} has a \expr{range} metadata with two Int arguments \expr{1} and \expr{8}. \item The static method \expr{method} has a \expr{broken} metadata without arguments. \end{itemize} The \expr{main} method accesses these metadata values using their API. The output reveals the structure of the obtained data: \begin{itemize} \item There is a field for each metadata, with the field name being the metadata name. \item The field values correspond to the metadata arguments. If there are no arguments, the field value is \expr{null}. Otherwise the field value is an array with one element per argument. \end{itemize} Allowed values for metadata arguments are: \begin{itemize} \item \tref{Constants}{expression-constants} \item \tref{Arrays declarations}{expression-array-declaration} (if all their elements qualify) \item \tref{Object declarations}{expression-object-declaration} (if all their field values qualify) \end{itemize} \paragraph{Compile-time Metadata} Metadata starting with \expr{:}, such as \expr{@:keep}, is available at compile time only; it is omitted at runtime. It may be used by macros or by the Haxe compiler itself. Unlike runtime metadata, arguments to compile-time metadata can be any valid expression. \paragraph{Built-in Compiler Metadata} An exhaustive list of all defined metadata can be obtained by running \expr{haxe --help-metas} from command line. \paragraph{Related content} \begin{itemize} \item See also the \tref{Compiler Metadata list}{cr-metadata}. \end{itemize} \section{Access Control} \label{lf-access-control} Access control can be used if the basic \tref{visibility}{class-field-visibility} options are not sufficient. It is applicable at \emph{class-level} and at \emph{field-level} and knows two directions: \begin{description} \item[Allowing access:] The target is granted access to the given class or field by using the \expr{:allow(target)} \tref{metadata}{lf-metadata}. \item[Forcing access:] A target is forced to allow access to the given class or field by using the \expr{:access(target)} \tref{metadata}{lf-metadata}. \end{description} In this context, a \emph{target} can be the \tref{dot-path}{define-type-path} to \begin{itemize} \item a \emph{class field}, \item a \emph{class} or \emph{abstract} type, or \item a \emph{package}. \end{itemize} Target does \emph{not} respect imports, so the fully qualified path has to be used. If it is a class or abstract type, access modification extends to all fields of that type. Likewise, if it is a package, access modification extends to all types of that package and recursively to all fields of these types. \haxe{assets/ACL.hx} Here, \expr{MyClass.foo} can be accessed from the \expr{main}-method because \type{MyClass} is annotated with \expr{@:allow(Main)}. This would also work with \expr{@:allow(Main.main)} and both versions could alternatively be annotated to the field \expr{foo} instead of the class \type{MyClass}: \haxe{assets/ACL2.hx} If a type cannot be modified to allow this kind of access, the accessing method may force access: \haxe{assets/ACL3.hx} The \expr{@:access(MyClass.foo)} annotation effectively subverts the visibility of the \expr{foo} field within the \expr{main}-method. \trivia{On the choice of metadata}{The access control language feature uses the Haxe metadata syntax instead of additional language-specific syntax. There are several reasons for that:\\ \begin{itemize} \item Additional syntax often adds complexity to the language parsing, and also adds (too) many keywords. \item Additional syntax requires additional learning by the language user, whereas metadata syntax is something that is already known. \item The metadata syntax is flexible enough to allow extension of this feature. \item The metadata can be accessed/generated/modified by Haxe macros. \end{itemize} Of course, the main drawback of using metadata syntax is that you get no error report in case you misspell either the metadata key (@:access for instance) or the class/package name. However, with this feature you will get an error when you try to access a private field that you are not allowed to, therefore there is no possibility for silent errors.} \since{3.1.0} If access is allowed to an \tref{interface}{types-interfaces}, it extends to all classes implementing that interface: \haxe{assets/ACL4.hx} This is also true for access granted to parent classes, in which case it extends to all child classes. \trivia{Broken feature}{Access extension to child classes and implementing classes was supposed to work in Haxe 3.0 and even documented accordingly. While writing this manual it was found that this part of the access control implementation was simply missing.} \section{Inline Constructors} \label{lf-inline-constructor} \since{3.1.0} If a constructor is declared to be \tref{inline}{class-field-inline}, the compiler may try to optimize it away in certain situations. There are several requirements for this to work: \begin{itemize} \item The result of the constructor call must be directly assigned to a local variable. \item The expression of the constructor field must only contain assignments to its fields. \end{itemize} The following example demonstrates constructor inlining: \haxe{assets/NewInline.hx} A look at the \target{JavaScript} output reveals the effect: \lang{js}\begin{lstlisting} Main.main = function() { var pt_x = 1.2; var pt_y = 9.3; }; \end{lstlisting}