Haxe, a statically-typed language that compiles to Python (and more)
Andy Li�
PyCon HK 2015
To the extent possible under law, Andy Li has waived all copyright and related or neighboring rights to these presentation slides. This work is published from: Hong Kong.
2
Haxe Foundation
Overview
3
4
Haxe
C#
Haxe features - JS/Java-like syntax
source code: pycon/hk/HelloWorld.hx
output: HelloWorld.py
5
package pycon.hk;
class HelloWorld {
static function main() {
var target = Sys.args()[0];
var speaker = {
first: "Andy",
last: "Li"
}
trace('${speaker.first} ${speaker.last}: Hello, $target!');
}
}
class pycon_hk_HelloWorld:
__slots__ = ()�
@staticmethod
def main():
target = python_internal_ArrayImpl._get(Sys.args(), 0)
speaker_first = "Andy"
speaker_last = "Li"
print(str((((((("" + ("null" if speaker_first is None else speaker_first)) + " ") + ("null" if speaker_last is None else speaker_last)) + ": Hello, ") + ("null" if target is None else target)) + "!")))
PS: showing only the output of the pycon_hk_HelloWorld class
Haxe features - static typing
6
class Typing {
static function main():Void {
var i = 123; // same as var i:Int = 123;
$type(i); // Int
// i = "123"; // error: String should be Int
var floats = [1.0, 1.1, 1.2];
$type(floats); // Array<Float>
$type(floats[0]); // Float
floats[0] = i;
trace(floats); // [ 123, 1.1, 1.2 ]
// floats[0] = "string"; // error: String should be Float
}
}
Haxe features - OOP
7
class Point {
public var x:Float;
public var y:Float;
public function new(x:Float, y:Float):Void {
this.x = x;
this.y = y;
}
public function offset(dx:Float = 0, dy:Float = 0):Point {
return new Point(x + dx, y + dy);
}
}
class Opts {
static function main():Void {
var p = new Point(0, 0);
var p2 = p.offset(1, 2);
trace(p2.x); //1
}
}
Haxe features - functional programming
source code: Functional.hx [output: Functional.py]
8
using Lambda; // static extension
import haxe.ds.*;
class Functional {
static function main() {
// Array comprehension
var evens:Array<Float> = [for (i in 0...15) if (i % 2 == 0) i];
trace(evens); // [ 0, 2, 4, 6, 8, 10, 12, 14 ]
// functional goodies from `using Lambda`
var maxMultipleOf4 = evens
.filter(function(i) return i % 4 == 0)
.fold(function(i, a) return Math.max(i, a), evens[0]);
trace(maxMultipleOf4); // 12
// enum (GADT) and pattern matching
function getAnyHigher(floats:Array<Float>, v:Float):Option<Float> {
for (f in floats)
if (f > v)
return Some(f);
return None;
}
switch (getAnyHigher(evens, 5)) {
case Some(value):
// string interpolation (not really FP, but still nice)
trace('In evens, $value is higher than 5');
case None:
trace("No value in evens is higher than 5");
}
}
}
What is Haxe?
True :D
False…
9
Why do we want�cross-platform?
10
11
12
http://forum7.hkgolden.com/view.aspx?type=CA&message=6029341
13
http://www.e-zone.com.hk/channelnews.php?id=6974
code reuse
14
platforms / languages come and gone…
15
test all languages!
with your own app!
16
https://attractivechaos.github.io/plb/
Why would one compile� Haxe to Python?
$ diff haxe python
17
the Python libs are great
18
static typing vs dynamic typing
19
functional vs imperative
20
the Haxe Python target
status and how-to
21
Current status
22
using Python lib in Haxe
23
the `untyped` keyword
source code: Untyped.hx
output: Untyped.py
24
class Untyped {
static function main():Void {
var l = untyped list("abc");
trace(l); // ['a', 'b', 'c']
}
}
# Generated by Haxe�
�class Untyped:
__slots__ = ()�
@staticmethod
def main():
l = list("abc")
print(str(l))�
Untyped.main()
python.Syntax
source code: PySyntax.hx
output: PySyntax.py
25
import python.Syntax;
class PySyntax {
static function main():Void {
var string = Syntax.pythonCode('"abc" # type : str');
trace(string);
}
}
# Generated by Haxe
class PySyntax:
__slots__ = ()
@staticmethod
def main():
string = "abc" # type : str
print(str(string))
PySyntax.main()
externs
26
import python.Tuple;
@:pythonImport("inspect") extern class Inspect {
static public function getdoc(object:Dynamic):String;
static public function getmembers
(object:Dynamic, ?predicate:haxe.Constraints.Function)
:Array<Tuple2<String,Dynamic>>;
static public function signature
(obj:Dynamic, ?follow_wrapped:Bool = true)
:Dynamic;
}
�
class Extern {
static function main():Void {
var getdocdoc = Inspect.getdoc(Inspect.getdoc);
trace(getdocdoc); // "Get the documentation string for an object..."
}
}
Example: Data analysis of a Haxe usage survey
27
Automatic generating externs
28
Function call with named arguments
A typical function in a Python lib:
29
pandas.read_csv(filepath_or_buffer, sep=', ', dialect=None, compression='infer', doublequote=True,escapechar=None, quotechar='"', quoting=0, skipinitialspace=False, lineterminator=None, header='infer',index_col=None, names=None, prefix=None, skiprows=None, skipfooter=None, skip_footer=0, na_values=None,true_values=None, false_values=None, delimiter=None, converters=None, dtype=None, usecols=None,engine=None, delim_whitespace=False, as_recarray=False, na_filter=True, compact_ints=False,use_unsigned=False, low_memory=True, buffer_lines=None, warn_bad_lines=True, error_bad_lines=True,keep_default_na=True, thousands=None, comment=None, decimal='.', parse_dates=False, keep_date_col=False,dayfirst=False, date_parser=None, memory_map=False, float_precision=None, nrows=None, iterator=False,chunksize=None, verbose=False, encoding=None, squeeze=False, mangle_dupe_cols=True, tupleize_cols=False,infer_datetime_format=False, skip_blank_lines=True)
54 arguments!
Function call with named arguments
30
import python.KwArgs;
class Kw {
static function test(a:Float, b:Float, c:Float):Void {
trace('$a, $b, $c');
}
static function main():Void {
test(1.1, 1.2, 1.3);
var kw:KwArgs<Dynamic> = {a: 2.1, b: 2.2, c: 2.3};
(untyped test)(kw);
(untyped test)(({a: 3.1, b: 3.2, c: 3.3}:KwArgs<Dynamic>));
}
}
Function call with named arguments
let’s add sugar :)
31
using PyHelpers;
...
test.call(c => 4.3, a => 4.1, b => 4.2);
...
var data = Pandas.read_csv.call(
dataPath,
sep => "\t",
parse_dates => [0],
header => 0
);
Future work (my personal wish list)
32
Made in Haxe
33
The super active Haxe community
34
image: http://www.silexlabs.org/limeopenfl-for-home-game-consoles/
Interested in Haxe?
35
36
Get in touch!