forked from HaxeFoundation/HaxeManual
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path06-language-features.tex
513 lines (324 loc) · 25.5 KB
/
06-language-features.tex
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
\chapter{Language Features}
\label{lf}
\state{NoContent}
\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. As a consequence, these 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.
\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}
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.
\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 and
\item all argument and return types are explicit.
\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-reference}. 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}.
\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 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.
\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:
\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}
\subsection{Enum matching}
\label{lf-pattern-matching-enums}
Enums can be matched by their constructors in a natural way:
\haxe[firstline=8,lastline=22]{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=25,lastline=32]{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=34,lastline=39]{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=41,lastline=53]{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.
A limitation with regards to class instances is that you cannot match against fields of their parent class.
\subsection{Array matching}
\label{lf-pattern-matching-array}
Arrays can be matched on fixed length:
\haxe[firstline=56,lastline=64]{assets/PatternMatching.hx}
This will trace \expr{1} because \expr{array[1]} matches \expr{6}, and \expr{array[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=67,lastline=72]{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=75,lastline=83]{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=86,lastline=91]{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}
\todo{Comprehensions are only listing Arrays, not Maps}
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 a = [];
while(i < 10) a.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{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<T>} and \type{Iterable<T>} respectively:
\begin{lstlisting}
typedef Iterator<T> = {
function hasNext() : Bool;
function next() : T;
}
typedef Iterable<T> = {
function iterator() : Iterator<T>;
}
\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<T>} 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<String>}. 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<T>} has a method \expr{iterator}, effectively forwarding the iterator method of the wrapped \type{Array<T>} type.
\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 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.
\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{debug} 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, as well as a \expr{:noCompletion} 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.
\item Metadata starting with \expr{:} is omitted. This kind of metadata is known as \emph{compiler metadata}.
\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}
\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}
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 (@:acesss 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:
\begin{lstlisting}
Main.main = function() {
var pt_x = 1.2;
var pt_y = 9.3;
};
\end{lstlisting}
\section{Remoting}
\label{lf-remoting}