Essentially it allows you to compile parts of your code to WebAssembly when targeting JS. The performance right now is slightly underwhelming, although I’m hopeful this can improve in the future.
Mostly, I wanted to learn more about AI and its strengths and weaknesses. For people who like walls of text, I’ve documented my journey here: Using AI to write a transpiler - DEV Community
Anyway, I think it’s a pretty cool flex, showing just how powerful Haxe macros can be and how clearly superior Haxe is to TypeScript, if anyone still had doubts
I agree that Haxe + LLMs can be a really powerful combination. I’ve been digging into LLMs for the last few months, and lately I’ve been deep into agentic / AI-assisted coding (a.k.a. “vibe”, though I’m not too fond of the term :P).
Not wanting to hijack this thread, but since we’re talking about it, here’s another transpiler that’s quite experimental, but that I hope to start using soon: https://github.com/fullofcaffeine/reflaxe.elixir.
There are many valid concerns about AI, but I can’t deny these are exciting times to build! And I’ve finally been able to tame Haxe and its (poorly documented) libs. Who knows, maybe LLMs can finally help increase Haxe’s adoption!
Funnily enough, I was actually looking at targeting BEAM myself (had it on my radar for a while), but shied away from it when I read that there are severe limitations around mutability. I may have misread though
Yes, Elixir’s data structures are immutable. The Haxe→Elixir compiler tansforms mutable structures to the equivalent immutable ones in Elixir. It’s certainly a potential weak spot that needs more testing and understanding from my part, but so far, from the tests, it seems to work, at least for the tests and examples that I have as harness
My goal is to support two paradigms: “portable” mode, where you can just use the Haxe stdlib as is and the compiler does the heavy lifting of transforming, or being closer to Elixir’s paradigms and APIs, where the compiler has to do less (mostly relying on externs). The todoapp example is a mix of both. You can see idioms that are close to Elixir’s, but it also uses for loops, which are lowered into idiomatic Elixir Enum.* (and sometimes comprehensions):
Pure iteration loops (for (x in xs) { … }) → Enum.each(xs, fn x → … end)
Range loops (for (i in 0…n)) → Enum.each(0..(n - 1)//1, fn i → … end)
Loops that accumulate/update a value (e.g. result += …, building a list/string) → Enum.reduce(collection_or_range, init, fn item, acc → … end)
If the loop needs early-exit / break-continue semantics → Enum.reduce_while(…) (or a recursive encoding when needed)
When enabled via -D elixir.feature.idiomatic_comprehensions=true, some “map/filter/collect” loops can become Elixir comprehensions (for x ← xs, … do … end) instead of Enum.*.
Anyway, it’s been fun and somewhat expensive experiment that I wouldn’t have been able to do without the help of SOTA LLMs. Hope to put it to good use, I also really like BEAM as a runtime, but prefer Haxe as a language. Ah! There’s a great potential for additional abstractions that can add to the overall Elixir/Phoenix/BEAM ergonomics, like compile-time Ecto checks, for example: reflaxe.elixir/docs/07-patterns/ECTO_INTEGRATION_PATTERNS.md at main · fullofcaffeine/reflaxe.elixir · GitHub .