Haxe 4.2 added initial support for function overloads, I just want to share my excitement for them to anyone who may have missed that feature addition!
Huge thanks to the people working on this stuff (ncannasse, simn, ReallyUniqueName, Gama11, nadako and many others!)
Overloads let you specialize functions based on their argument types. For example, say you’re writing a document library and you want a function to append content. Content might be in the form of text, images or tables, each of which you handle differently when appending. With overloads, you can write a single function called ‘append’ that behaves different depending on the type it’s called with:
append(image: Text)
append(image: Image)
append(image: Table)
In haxe 4.2, you can implement this with the overload
keyword. The present limitations are:
- The overload functions must be
inline
- The overload functions must be
extern
(However, the new overload feature is not just for externs! This is a requirement right now to ensure the compiler really does inline)
So append would look like:
overload extern inline function append(image: Text) { /* append-text implementation */ }
overload extern inline function append(image: Image) { /* append-image implementation */ }
overload extern inline function append(image: Table) { /* append-table implementation */ }
Here’s a try-haxe for this example
(I imagine we can shorten that keyword list in future iterations of overload
)
This enables something I’ve wanted in a programming language for a long time: the ability to write mathematical operations with the expressiveness of shader-code! For example, in shader-code, functions like sin
and cos
work with any vector type as well as numbers, which is a lot nicer than having sin(x)
, sinVec2(v)
, sinVec3(v)
and sinVec4(v)
. With overload
this is now possible in haxe too!
Taking this shader example to completion, we can write a vector library that matches the GLSL-specification (including compile-time swizzling!). This lets you compile expressions like this as haxe:
var speed = sin(vec2(Math.random(), Math.random()));
var tangent = speed.yx * vec2(-1, 1);
var transformedTangent = mat2(2) * tangent;
trace('length: ${length(transformedTangent)}');
Into efficient target code like this (for js):
let x = Math.random();
let tangent_x = Math.sin(Math.random()) * -1.;
let tangent_y = Math.sin(x);
let transformedTangent_x = 2. * tangent_x + 0. * tangent_y;
let transformedTangent_y = 0. * tangent_x + 2. * tangent_y;
console.log("Test.hx:8:","length: " + Math.sqrt(transformedTangent_x * transformedTangent_x + transformedTangent_y * transformedTangent_y));
Inlining and haxe’s analyzer means that no vector or matrix objects are allocated here, which has historically been an issue with trying to write expressive math libraries in languages like JavaScript. So you can now have both expressive math and great performance
You can play with this example on try-haxe here: Try Haxe !
Or install vector-math from haxelib
haxelib install vector-math
More details on the vector-math github page
* this is similar to Hxsl, the haxe shading language in heaps but the new feature here is you can now generate target source code instead of shader-code