Haxe notes
Mar. 24th, 2013 08:09 pmI found myself with a bit of free time, so I decided to try getting back into programming for fun and see what Haxe is like these days.
There are no number-to-string formatting functions
Haxe has no printf. You have to install it from a third-party library, polygonal.
haxelib install polygonal
This leads directly to....
"Class not found : de.polygonal.core.fmt.Sprintf"
Haxe must use the -lib flag to include libraries installed by haxelib, here: -lib polygonal
In haxe 3.0, this leads to:
"haxe.Int32 has been removed, use normal Int instead"
In an age when most platforms are 64-bit, haxe 3.0 takes away the ability to access 32-bit fields in a future-proof manner. Since all I care about is getting Haxe to recognize the type name, I tried to use an abstract type to add Int32 back into the lexicon as an Int but that did not make a difference.
Trying to replace haxe.Int32 produces "Type name should start with an uppercase letter", so that is not going to work. Instead, I added to StdTypes.hx:
@:coreType @:notNull @:runtimeValue abstract Int32 to Int from Int { }
It still does not work and produces the same "Int32 has been removed" error, so I gave up and decided to edit the polygonal library directly.
# Very klugey Haxe 2-to-3 script for Polygonal.
for i in `find . -type f -name \*.hx`; do
if grep -H haxe.Int32 "$i" >& /dev/null; then
sed -i "s/import haxe.Int32;//" "$i";
sed -i "s/using haxe.Int32;//" "$i";
sed -i "s/haxe.Int32/Int/g" "$i";
fi;
if grep -H IntHash "$i" >& /dev/null; then
sed -i "s/\bIntHash *<\([^>]*\)>/Map<Int,\1>/g" "$i";
sed -i "s/\bIntHash\b/Map/g" "$i";
fi;
if grep -H "@:macro" "$i" >& /dev/null; then
sed -i "s/@:macro/macro/g" "$i";
fi;
That mostly works gets Sprintf.hx to parse; there are a few unused variable warnings to squelch, and I haven't yet built anything that runs to be able to test it.
Other problems that I ran into:
"Missing underlying type declaration or @:coreType declaration"
... because "coreType" is case-sensitive.
You cannot extend a class from an abstract class.
abstract A(Class<String>) { function asdf(); }
class Foo extends A { } // "Should extend by using a class"
class Foo implements A { } // "Should implement by using an interface"
There appears to be no solution for this.
Abstracts can be extended from a class, so the thought comes to mind of turning abstract/class relationships upside down and implementing abstracts from a class.
Operator overloading doesn't work.
The haxe docs say that operator overloading works in an abstract, but is silent on whether you can overload operators for a class. You can use the same syntax in a class, but in my experience it does not work in practice.
class Foo {
var x:Float;
public function new(x:Float){ this.x = x; }
@:commutative @:op(A + B) public function add (A:Foo, B:Foo): Foo {
return new Foo(A.x + B.x);
}
static public function main(){
var a:Foo = new Foo(1);
var b:Foo = new Foo(2);
var c = a + b; // Error: "Cannot add Foo and Foo"
// I have also gotten the error "Foo should be Int".
}
}
All in all, Haxe is better documented than it used to be, but it is still a pain in the ass to work with if you're not already used to working with it.