forked from HaxeFoundation/HaxeManual
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path10-std.tex
469 lines (316 loc) · 24.5 KB
/
10-std.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
\chapter{Standard Library}
\label{std}
\state{NoContent}
Standard library
\section{String}
\label{std-String}
\define[Type]{String}{define-string}{A String is a sequence of characters.}
%TODO: utf8 crap %
\section{Data Structures}
\label{std-ds}
\state{NoContent}
\subsection{Array}
\label{std-Array}
An \type{Array} is a collection of elements. It has one \tref{type parameter}{type-system-type-parameters} which corresponds to the type of these elements. Arrays can be created in three ways:
\begin{enumerate}
\item By using their constructor: \expr{new Array()}
\item By using \tref{array declaration syntax}{expression-array-declaration}: \expr{[1, 2, 3]}
\item By using \tref{array comprehension}{lf-array-comprehension}: \expr{[for (i in 0...10) if (i \% 2 == 0) i]}
\end{enumerate}
Arrays come with an API \href{http://api.haxe.org/Array.html}{API} to cover most use-cases. Additionally they allow read and write \tref{array access}{expression-array-access}:
\haxe{assets/ArrayAccess.hx}
Since array access in Haxe is unbounded, i.e. it is guaranteed to not throw an exception, this requires further discussion:
\begin{itemize}
\item If a read access is made on a non-existing index, a target-dependent value is returned.
\item If a write access is made with a positive index which is out of bounds, \expr{null} (or the \tref{default value}{define-default-value} for \tref{basic types}{types-basic-types} on \tref{static targets}{define-static-target}) is inserted at all positions between the last defined index and the newly written one.
\item If a write access is made with a negative index, the result is unspecified.
\end{itemize}
Arrays define an \tref{iterator}{lf-iterators} over their elements. This iteration is typically optimized by the compiler to use a \tref{\expr{while} loop}{expression-while} with array index:
\haxe{assets/ArrayIterator.hx}
Haxe generates this optimized \target{Javascript} output:
\begin{lstlisting}
Main.main = function() {
var scores = [110,170,35];
var sum = 0;
var _g = 0;
while(_g < scores.length) {
var score = scores[_g];
++_g;
sum += score;
}
console.log(sum);
};
\end{lstlisting}
Haxe does not allow arrays of mixed types unless the parameter type is forced to \tref{\type{Dynamic}}{types-dynamic}:
\haxe{assets/ArrayDynamic.hx}
\trivia{Dynamic Arrays}{In Haxe 2, mixed type array declarations were allowed. In Haxe 3, arrays can have mixed types only if they are explicitly declared as \expr{Array<Dynamic>}.}
\subsection{Vector}
\label{std-vector}
A \type{Vector} is an optimized fixed-length \emph{collection} of elements. Much like \tref{Array}{std-Array}, it has one \tref{type parameter}{type-system-type-parameters} and all elements of a vector must be of the specified type, it can be \emph{iterated over} using a \tref{for loop}{expression-for} and accessed using \tref{array access syntax}{types-abstract-array-access}. However, unlike \type{Array} and \type{List}, vector length is specified on creation and cannot be changed later.
\haxe{assets/Vector.hx}
\type{haxe.ds.Vector} is implemented as an abstract type (\ref{types-abstract}) over a native array implementation for given target and can be faster for fixed-size collections, because the memory for storing its elements is pre-allocated.
\subsection{List}
\label{std-List}
A \type{List} is a \emph{collection} for storing elements. On the surface, a list is similar to an \Fullref{std-Array}. However, the underlying implementation is very different. This results in several functional differences:
\begin{enumerate}
\item A list can not be indexed using square brackets, i.e. \expr{[0]}.
\item A list can not be initialized.
\item There are no list comprehensions.
\item A list can freely modify/add/remove elements while iterating over them.
\end{enumerate}
See the \href{http://api.haxe.org/List.html}{List API} for details about the list methods. A simple example for working with lists:
\haxe{assets/ListExample.hx}
\subsection{GenericStack}
\label{std-GenericStack}
A \type{GenericStack}, like \type{Array} and \type{List} is a container for storing elements. It has one \tref{type parameter}{type-system-type-parameters} and all elements of the stack must be of the specified type. See the \href{http://api.haxe.org/haxe/ds/GenericStack.html}{GenericStack API} for details about its methods. Here is a small example program for initializing and working with a \type{GenericStack}.
\haxe{assets/GenericStackExample.hx}
\trivia{FastList}{In Haxe 2, the GenericStack class was known as FastList. Since its behavior more closely resembled a typical stack, the name was changed for Haxe 3.}
The \emph{Generic} in \type{GenericStack} is literal. It is attributed with the \expr{:generic} metadata. Depending on the target, this can lead to improved performance on static targets. See \Fullref{type-system-generic} for more details.
\subsection{Map}
\label{std-Map}
A \type{Map} is a container composed of \emph{key}, \emph{value} pairs. A \type{Map} is also commonly referred to as an associative array, dictionary, or symbol table. The following code gives a short example of working with maps:
\haxe{assets/MapExample.hx}
See the \href{http://api.haxe.org/Map.html}{Map API} for details of its methods.
Under the hood, a \type{Map} is an \tref{abstract}{types-abstract} type. At compile time, it gets converted to one of several specialized types depending on the \emph{key} type:
\begin{itemize}
\item \type{String}: \type{haxe.ds.StringMap}
\item \type{Int}: \type{haxe.ds.IntMap}
\item \type{EnumValue}: \type{haxe.ds.EnumValueMap}
\item \type{\{\}}: \type{haxe.ds.ObjectMap}
\end{itemize}
The \type{Map} type does not exist at runtime and has been replaced with one of the above objects.
Map defines \tref{array access}{types-abstract-array-access} using its key type.
\subsection{Option}
\label{std-Option}
An option is an \tref{enum}{types-enum-instance} in the Haxe Standard Library which is defined like so:
\begin{lstlisting}
enum Option<T> {
Some(v:T);
None;
}
\end{lstlisting}
It can be used in various situations, such as communicating whether or not a method had a valid return and if so, what value it returned:
\haxe{assets/OptionUsage.hx}
\section{Regular Expressions}
\label{std-regex}
Haxe has built-in support for \emph{regular expressions}\footnote{http://en.wikipedia.org/wiki/Regular_expression}. They can be used to verify the format of a string, transform a string or extract some regular data from a given text.
Haxe has special syntax for creating regular expressions. We can create a regular expression object by typing it between the \expr{\textasciitilde/} combination and a single \expr{/} character:
\begin{lstlisting}
var r = ~/haxe/i;
\end{lstlisting}
Alternatively, we can create regular expression with regular syntax:
\begin{lstlisting}
var r = new EReg("haxe", "i");
\end{lstlisting}
First argument is a string with regular expression pattern, second one is a string with \emph{flags} (see below).
We can use standard regular expression patterns such as:
\begin{itemize}
\item \expr{.} any character
\item \expr{*} repeat zero-or-more
\item \expr{+} repeat one-or-more
\item \expr{?} optional zero-or-one
\item \expr{[A-Z0-9]} character ranges
\item \expr{[\textasciicircum\textbackslash r\textbackslash n\textbackslash t]} character not-in-range
\item \expr{(...)} parenthesis to match groups of characters
\item \expr{\textasciicircum} beginning of the string (beginning of a line in multiline matching mode)
\item \expr{\$} end of the string (end of a line in multiline matching mode)
\item \expr{|} "OR" statement.
\end{itemize}
For example, the following regular expression matches valid email addresses:
\begin{lstlisting}
~/[A-Z0-9._\%-]+@[A-Z0-9.-]+\.[A-Z][A-Z][A-Z]?/i;
\end{lstlisting}
Please notice that the \expr{i} at the end of the regular expression is a \emph{flag} that enables case-insensitive matching.
The possible flags are the following:
\begin{itemize}
\item \expr{i} case insensitive matching
\item \expr{g} global replace or split, see below
\item \expr{m} multiline matching, \expr{\textasciicircum} and \expr{\$} represent the beginning and end of a line
\item \expr{s} the dot \expr{.} will also match newlines \emph{(Neko, C++, PHP and Java targets only)}
\item \expr{u} use UTF-8 matching \emph{(Neko and C++ targets only)}
\end{itemize}
\subsection{Matching}
\label{std-regex-match}
Probably one of the most common uses for regular expressions is checking whether a string matches the specific pattern. The \expr{match} method of a regular expression object can be used to do that:
\haxe{assets/ERegMatch.hx}
\subsection{Groups}
\label{std-regex-groups}
Specific information can be extracted from a matched string by using \emph{groups}. If \expr{match()} returns true, we can get groups using the \expr{matched(X)} method, where X is the number of a group defined by regular expression pattern:
\haxe{assets/ERegGroups.hx}
Note that group numbers start with 1 and \expr{r.matched(0)} will always return the whole matched substring.
The \expr{r.matchedPos()} will return the position of this substring in the original string:
\haxe{assets/ERegMatchPos.hx}
Additionally, \expr{r.matchedLeft()} and \expr{r.matchedRight()} can be used to get substrings to the left and to the right of the matched substring:
\haxe{assets/ERegMatchLeftRight.hx}
\subsection{Replace}
\label{std-regex-replace}
A regular expression can also be used to replace a part of the string:
\haxe{assets/ERegReplace.hx}
We can use \expr{\$X} to reuse a matched group in the replacement:
\haxe{assets/ERegReplaceGroups.hx}
\subsection{Split}
\label{std-regex-split}
A regular expression can also be used to split a string into several substrings:
\haxe{assets/ERegSplit.hx}
\subsection{Map}
\label{std-regex-map}
The \expr{map} method of a regular expression object can be used to replace matched substrings using a custom function:
\haxe{assets/ERegMap.hx}
This function takes a regular expression object as its first argument so we may use it to get additional information about the match being done.
\subsection{Implementation Details}
\label{std-regex-implementation-details}
Regular Expressions are implemented:
\begin{itemize}
\item in JavaScript, the runtime is providing the implementation with the object RegExp.
\item in Neko and C++, the PCRE library is used
\item in Flash, PHP, C\# and Java, native implementations are used
\item in Flash 6/8, the implementation is not available
\end{itemize}
\section{Math}
\label{std-math}
Haxe includes a floating point math library for some common mathematical operations. Most of the fuctions operate on and return \type{floats}. However, an \type{Int} can be used where a \type{Float} is expected, and Haxe also converts \type{Int} to \type{Float} during most numeric operations (see \Fullref{types-numeric-operators} for more details).
Here are some example uses of the math library. See the \href{http://api.haxe.org/Math.html}{Math API} for all available functions.
\haxe{assets/MathExample.hx}
\subsection{Special Numbers}
\label{std-math-special-numbers}
The math library has definitions for several special numbers:
\begin{itemize}
\item NaN (Not a Number): returned when a mathmatically incorrect operation is executed, e.g. Math.sqrt(-1)
\item POSITIVE_INFINITY: e.g. divide a positive number by zero
\item NEGATIVE_INFINITY: e.g. divide a negative number by zero
\item PI : 3.1415...
\end{itemize}
\subsection{Mathematical Errors}
\label{std-math-mathematical-errors}
Although neko can fluidly handle mathematical errors, like division by zero, this is not true for all targets. Depending on the target, mathematical errors may produce exceptions and ultimately errors.
\subsection{Integer Math}
\label{std-math-integer-math}
If you are targeting a platform that can utilize integer operations, e.g. integer division, it should be wrapped in \emph{Std.int()} for improved performance. The Haxe Compiler can then optimize for integer operations. An example:
\begin{lstlisting}
var intDivision = Std.int(6.2/4.7);
\end{lstlisting}
\todo{I think C++ can use integer operatins, but I don't know about any other targets. Only saw this mentioned in an old discussion thread, still true?}
\subsection{Extensions}
\label{std-math-extensions}
It is common to see \Fullref{lf-static-extension} used with the math library. This code shows a simple example:
\haxe{assets/MathStaticExtension.hx}
\haxe{assets/MathExtensionUsage.hx}
\section{Lambda}
\label{std-Lambda}
\section{Reflection}
\label{std-reflection}
Haxe supports runtime reflection of types and fields. Special care has to be taken here because runtime representation generally varies between targets. In order to use reflection correctly it is necessary to understand what kind of operations are supported and what is not. Given the dynamic nature of reflection, this can not always be determined at compile-time.
The reflection API consists of two classes:
\begin{description}
\item[Reflect:] A lightweight API which work best on \tref{anonymous structures}{types-anonymous-structure}, with limited support for \tref{classes}{types-class-instance}.
\item[Type:] A more robust API for working with classes and \tref{enums}{types-enum-instance}.
\end{description}
The available methods are detailed in the API for \href{http://api.haxe.org//Reflect.html}{Reflect} and \href{http://api.haxe.org//Type.html}{Type}.
Reflection can be a powerful tool, but it is important to understand why it can also cause problems. As an example, several functions expect a \tref{String}{std-String} argument and try to resolve it to a type or field. This is vulnerable to typing errors:
\haxe{assets/ReflectionTypo.hx}
However, even if there are no typing errors it is easy to come across unexpected behavior:
\haxe{assets/ReflectionMissingType.hx}
The problem here is that the compiler never actually ``sees'' the type \type{haxe.Template}, so it does not compile it into the output. Furthermore, even if it were to see the type there could be issues arising from \tref{dead code elimitation}{cr-dce} eliminating types or fields which are only used via reflection.
Another set of problems comes from the fact that, by design, several reflection functions expect arguments of type \tref{Dynamic}{types-dynamic}, meaning the compiler cannot check if the passed in arguments are correct. The following example demonstrates a common mistake when working with \expr{callMethod}:
\haxe{assets/ReflectionWrongUsage.hx}
The commented out call would be accepted by the compiler because it assigns the string \expr{"f"} to the function argument \expr{func} which is specified to be \expr{Dynamic}.
A good advice when working with reflection is to wrap it in a few functions within an application or API which are called by otherwise type-safe code. An example could look like this:
\haxe{assets/ReflectionWrap.hx}
While the method \expr{reflective} could interally work with reflection (and \type{Dynamic} for that matter) a lot, its return value is a typed structure which the callers can use in a type-safe manner.
\section{Serialization}
\label{std-serialization}
Many runtime values can be serialized and deserialized using the \type{haxe.Serializer} and \type{haxe.Unserializer} classes. Both support two usages:
\begin{enumerate}
\item Create an instance and continuously call the \expr{serialize}/\expr{unserialize} method to handle multiple values.
\item Call their static \expr{run} method to serialize/deserialize a single value.
\end{enumerate}
The following example demonstrates the first usage:
\haxe{assets/SerializationExample.hx}
The result of the serialization (here stored in local variable \expr{s}) is a \tref{String}{std-String} and can be passed around at will, even remotely. Its format is described in \Fullref{std-serialization-format}.
\paragraph{Supported values}
\begin{itemize}
\item \expr{null}
\item \type{Bool}, \type{Int} and \type{Float} (including infinities and \expr{NaN})
\item \type{String}
\item \type{Date}
\item \type{haxe.io.Bytes} (encoded as base64)
\item \tref{\type{Array}}{std-Array} and \tref{\type{List}}{std-List}
\item \type{haxe.ds.StringMap}, \type{haxe.ds.IntMap} and \type{haxe.ds.ObjectMap}
\item \tref{anonymous structures}{types-anonymous-structure}
\item Haxe \tref{class instances}{types-class-instance} (not native ones)
\item \tref{enum instances}{types-enum-instance}
\end{itemize}
\paragraph{Serialization configuration}
Serialization can be configured in two ways. For both a static variable can be set to influence all \type{haxe.Serializer} instances, and a member variable can be set to only influence a specific instance:
\begin{description}
\item[\expr{USE_CACHE}, \expr{useCache}:] If true, repeated objects are serialized by reference. This can avoid infinite loops for recursive data at the expense of longer serialization time. By default, this value is \expr{false}.
\item[\expr{USE_ENUM_INDEX}, \expr{useEnumIndex}:] If true, enum constructors are serialized by their index instead of their name. This can make the serialization string shorter but breaks if enum constructors are inserted into the type before deserialization. By default, this value is \expr{false}.
\end{description}
\paragraph{Deserialization behavior}
If the serialization result is stored and later used for deserialization, care has to be taken to maintain compatibility when working with class and enum instances. It is then important to understand exactly how unserialization is implemented.
\begin{itemize}
\item The type has to be available in the runtime where the deserialization is made. If \tref{dead code elimination}{cr-dce} is active, a type which is used only through serialization might be removed.
\item Each \type{Unserializer} has a member variable \expr{resolver} which is used to resolve classes and enums by name. Upon creation of the \type{Unserializer} this is set to \expr{Unserializer.DEFAULT_RESOLVER}. Both that and the instance member can be set to a custom resolver.
\item Classes are resolved by name using \expr{resolver.resolveClass(name)}. The instance is then created using \expr{Type.createEmptyInstance}, which means that the class constructor is not called. Finally, the instance fields are set according to the serialized value.
\item Enums are resolved by name using \expr{resolver.resolveEnum(name)}. The enum instance is then created using \expr{Type.createEnum}, using the serialized argument values if available. If the constructor arguments were changed since serialization, the result is unspecified.
\end{itemize}
\paragraph{Custom (de)serialization}
If a class defines the member method \expr{hxSerialize}, that method is called by the serializer and allows custom serialization of the class. Likewise, if a class defines the member method \expr{hxUnserialize} it is called by the deserializer:
\haxe{assets/SerializationCustom.hx}
In this example we decide that we want to ignore the value of member variable \expr{y} and do not serialize it. Instead we default it to \expr{-1} in \expr{hxUnserialize}. Both methods are annotated with the \expr{:keep} metadata to prevent \tref{dead code elimination}{cr-dce} from removing them as they are never properly referenced in the code.
\subsection{Serialization format}
\label{std-serialization-format}
Each supported value is translated to a distinct prefix character, followed by the necessary data.
\begin{description}
\item[\expr{null}:] \expr{n}
\item[\type{Int}:] \expr{z} for zero, or \expr{i} followed by the integer itself (e.g. \expr{i456})
\item[\type{Float}:]
\begin{description}
\item[\expr{NaN}:] \expr{k}
\item[negative infinity:] \expr{m}
\item[positive infinity:] \expr{p}
\item[normal Float:] \expr{d} followed by the float display (e.g. \expr{d1.45e-8})
\end{description}
\item[\type{Bool}:] \expr{t} for \expr{true}, \expr{f} for \expr{false}
\item[\type{String}:] \expr{y} followed by the url encoded string length, then \expr{:} and the url encoded string (e.g. \expr{y10:hi\%20there for "hi there".}.
\item[\type{String} (cached):] \expr{R} followed by the string cache ID (e.g. \expr{R456}). String caching is always enabled.
\item[name-value pairs:] a serialized string representing the namee, followed by the value
\item[structure:] \expr{o} followed by the list of name-value pairs, followed by \expr{g} (e.g. \expr{oy1:xi2y1:kng} for \expr{\{x:2, k:null\}})
\item[\type{List}:] \expr{l} followed by the list of serialized items, followed by \expr{h} (e.g. \expr{lnnh} for a list of two \expr{null} values)
\item[\type{Array}:] \expr{a} followed by the list of serialized items, followed by \expr{h}. For multiple consecutive \expr{null} values, \expr{u} followed by the number of \expr{null} values is used (e.g. \expr{ai1i2u4i7ni9h for [1,2,null,null,null,null,7,null,9]})
\item[\type{Date}:] \expr{v} followed by the date itself (e.g. \expr{d2010-01-01 12:45:10})
\item[\type{haxe.ds.StringMap}:] \expr{b} followed by the name-value pairs, followed by \expr{h} (e.g. \expr{by1:xi2y1:knh} for \expr{\{"x" => 2, "k" => null\}})
\item[\type{haxe.ds.IntMap}:] \expr{q} followed by the key-value pairs, followed by \expr{h}. Each key is represented as \expr{:<int>} (e.g. \expr{q:4n:5i45:6i7h} for \expr{\{4 => null, 5 => 45, 6 => 7\}})
\item[\type{haxe.ds.ObjectMap}:] \expr{M} followed by serialized value pairs representing the key and value, followed by \expr{h}
\item[\type{haxe.io.Bytes}:] \expr{s} followed by the length of the base64 encoded bytes, then \expr{:} and the byte representation using the codes \expr{A-Za-z0-9\%} (e.g. \expr{s3:AAA} for 2 bytes equal to \expr{0}, \expr{s10:SGVsbG8gIQ} for \expr{haxe.io.Bytes.ofString("Hello !")})
\item[exception:] \expr{x} followed by the exception value
\item[class instance:] \expr{c} followed by the serialized class name, followed by the name-value pairs of the fields, followed by \expr{g} (e.g. \expr{cy5:Pointy1:xzy1:yzg} for \expr{new Point(0, 0)} (having two integer fields \expr{x} and \expr{y})
\item[enum instance (by name):] \expr{w} followed by the serialized enum name, followed by the serialized constructor name, followed by the number of arguments, followed by the argument values (e.g. \expr{wy3:Fooy1:A0} for \expr{Foo.A} (with no arguments), \expr{wy3:Fooy1:B2i4n} for \expr{Foo.B(4,null)})
\item[enum instance (by index):] \expr{j} followed by the serialized enum name, followed by \expr{:}, followed by the constructor index, followed by the number of arguments, followed by the argument values (e.g. \expr{wy3:Foo0:0} for \expr{Foo.A} (with no arguments), \expr{wy3:Foo1:2i4n} for \expr{Foo.B(4,null)})
\item[custom:] \expr{C} followed by the class name, followed by the custom serialized data, followed by \expr{g}
\item[cache references:] \expr{r} followed by the cache index
\end{description}
\section{Json}
\label{std-Json}
Haxe provides built-in support for (de-)serializing \emph{JSON}\footnote{http://en.wikipedia.org/wiki/JSON} data via the \type{haxe.Json} class.
\subsection{Parsing JSON}
\label{std-Json-parsing}
Use the \expr{haxe.Json.parse} static method to parse \emph{JSON} data and obtain a Haxe value from it:
\haxe{assets/JsonParse.hx}
Note that the type of the object returned by \expr{haxe.Json.parse} is \expr{Dynamic}, so if the structure of our data is well-known, we may want to specify a type using \tref{anonymous structures}{types-anonymous-structure}. This way we provide compile-time checks for accessing our data and most likely more optimal code generation, because compiler knows about types in a structure:
\haxe{assets/JsonParseTyped.hx}
\subsection{Encoding JSON}
\label{std-Json-encoding}
Use the \expr{haxe.Json.stringify} static method to encode a Haxe value into a \emph{JSON} string:
\haxe{assets/JsonStringify.hx}
\subsection{Implementation details}
\label{std-Json-implementation-details}
The \type{haxe.Json} API automatically uses native implementation on targets where it is available, i.e. \emph{JavaScript}, \emph{Flash} and \emph{PHP} and provides its own implementation for other targets.
Usage of Haxe own implementation can be forced with \expr{-D haxeJSON} compiler argument. This will also provide serialization of \tref{enums}{types-enum-instance} by their index, \tref{maps}{std-Map} with string keys and class instances.
Older browsers (Internet Explorer 7, for instance) may not have native \emph{JSON} implementation. In case it's required to support them, we can include one of the JSON implementations available on the internet in the HTML page. Alternatively, a \expr{-D old_browser} compiler argument that will make \type{haxe.Json} try to use native JSON and fallback to its own implementation in case it's not available can be used.
\section{Xml}
\label{std-Xml}
\section{Input/Output}
\label{std-input-output}
\section{Sys/sys}
\label{std-sys}