The Joy of Haxe
medium.com
medium.com
Five years on from starting with Haxe at FontStruct, I’m genuinely surprised to find that I feel no regret whatsoever regarding our decision to go with the technology.
I absolutely adore the language. Not only is it awesome at transpiling/compiling to native across this whole spectrum of targets, the language itself keeps surprising me with how versatile it is; with great type inferencing, compile time macros, platform-conditional compilation, and more.I've launched iOS, Android, Web, Windows and Mac apps that all shared the same code base. I can't see myself ever wanting to go back to using a single-target language again. I highly recommend trying it if you're on the fence. [0]
Note: I am not affiliated with Haxe, just a huge fan.
... shudders
Conditional compilation is a horrible, horrible idea period, and is particularly easy to turn into an indecipherable brittle mess in haxe. This was made worse by the previous authors of the code we inherited, but is really a case where it’s the tool’s (haxe’s) fault for implementing the feature in a way that makes it an intrinsic foot gun.
Lastly, it was a big turn off to our candidates, and many people we interviewed expressed lack of interest in working with it.
I will agree to your point about abandoned third party tools but that happens with any language? It’s just more pronounced on a less popular one. I will also agree about the code it produces: the point of a transpiled language isn’t for its output to necessarily be readable but first and foremost fast. You wouldnt expect c to produce understandable assembly in all cases, would you? Plus it maps all lines to your Haxe source so you shouldn’t even have to debug large blocks of native code anyway.
What necessarily does Haxe do that makes for conditional compilation to be so bad? AFAIK it works in the exact same way other cross platform frameworks have it (eg, Unity)- it’s probably the cleanest way to do it; I certainly wouldn’t say it promotes brittle code practices at all, but ofc, like anything, can be misused.
I can see it being a potential turnoff to candidates given it’s relatively unknown status... but the language itself reads and writes like a C-style OOP language: there’s nothing that should necessarily turn people off besides that it’s an unknown, especially anyone coming from a C or Java background.
I would like to argue about this philosophy. When your target output is not readable, then you restrict the developer to work inside your upper-level language. This is fine if your upper layer is robust and transparent enough to reason about. In C's case, there is rarely a case one needs to work at the assembly level to reason/debug. Is this the case for Haxe? Now if you even imply that developer need work in your output layer even one percent of the time, then it is responsible to make sure the output is readable. Otherwise, it is a gun shooting the foot -- even only 1% of the time.
The background is that I love C. I find C very straightforward to reason about and very simplistic to allow more logic to be spelled out in a clean way (than C++ for example). Now the above passage -- putting assembly as an analogy to C -- sounds prickly.
The manual doesn't really go into enough detail to imply you'd need to fiddle with the outputted code but I'd imagine any case would be a bug rather than a feature.
I think the analogy is accurate: Haxe is not meant to be used to compile to native and then modified in native further. It can be... but the general usecase is to write everything in Haxe and not have to then modify the transpiled result. Similar to typescript in a way... you can add JavaScript after the fact, but most likely you’d directly add native untyped JavaScript within your Typescript code, not directly to your transpiled result.
One thing that gets me is that the Input/Output section of the official manual [0] has gone unwritten for quite a while, now. [1]
Some libraries that work on top of Haxe can give you a standard API that’ll let you not have to conditional compile (OpenFL, NME), but in general there’s a lot of trade offs that need to be considered at a platform level for drawing that conditional paths for drawing aren’t too uncommon.
For his new game, Return of the Obra Dinn, he went with Unity because of its 3D capability:
https://forums.tigsource.com/index.php?topic=40832.0
> I'm gonna use Unity for this one. I fell in love with Haxe/OpenFL on my last project but unfortunately the 3D situation is not that great there yet. Also, it's time to finally see why 90% of the indie scene is using Unity. I have a good amount of experience with 3D games and the few days I've played around with Unity so far have been pretty productive. The animated title screen scene up there (with post-processing shaders and all) was created in one day. I now have unrealistically high hopes.
In my current project I ultimately switched off of Unity for 3D due to its less than stellar WebGL support (and I wanted to target web), but with Haxe I simply changed my target to JS and got to reuse most of my code. The ability to switch/add targets at any point of your product’s lifecycle is incredible.
It's nice to see a project with such a dedicated community.
It's a shame that most developers started using TypeScript instead of Haxe; that seems like a missed opportunity. TypeScript was pretty painful to use in its early days; it shows the importance of positioning and marketing.
It's not a surprise at all that the likes of Microsoft and Google and Mozilla are able to promote and push new languages to significant widespread adoption.
*Not so obscure anymore; Motion-Twin is well known for the hit game Dead Cells, and their former employee, Nicolas Cannasse, who is credited with inventing Haxe, went on to found his own studio with its own successful games (Northgard especially)
If corporate support is a definite factor, Dart would have taken off way earlier than now. A bigger factor in TypeScript's success would be the ability to gradually migrate the projects as it's a superset of JavaScript. How do you start migrating? Flip the file extensions from .js to .ts with loose compiler options, then gradually add typing as the options are tightened. It's factors like these that drive spread of language, not "huge corporation with infinite budget and a large full time team of contributors and evangelists." Dart had no short of those and still not much accepted.
you can target mobile with Flutter, and also command-line etc.
Now the Flutter project is Dart's last hope to keep it relevant outside Google.
It remains to be seen how serious Google is about Flutter, as the Android team only gives political correct answers when inquired about Flutter vs Android.
There are other languages pushed by a big corporation that fail so having the big corporation is a necessary but not sufficient condition.
But you might be remembering the old Dart IDE, which was based on Eclipse.
Drives me nuts.
I find that searching on "golang" generally does the trick.
From an external perspective, Google's enthusiasm for Dart seemed half-hearted at best. Its launch was encumbered by rocky political issues, with half the community terrified that they were looking at a new VBScript, and Google's competitors actively stoking said terrors. It could've jeopardized Chrome's ascendance by turning off tech people, on whom any new software depends for propagation, and giving MS/Apple/Mozilla some room to doubt Google's commitment to the extant web, and that was surely enough to make pouring heavy resources into it a non-starter from a business perspective. It's naive to believe that any technical considerations entered into it.
Take a look at Kubernetes if you want to see what happens when Google is committed to using that G-Juice to cram something down the community's throat.
In short, some folks at Google had ambitions for Dart to eventually become a web standard with an interpreter built in to browsers, with compile-to-JavaScript used for the transition. That was a radical, unpopular idea and didn't happen even for Chrome, but Dart lives on as a nice compile-to-JavaScript language, and has new life on mobile due to Flutter.
Microsoft had a much more conservative strategy with Typescript and executed on it better. Having modest goals was a big win there.
Remember how developers shunned Windows Phone and paid lip service to firefox os, and everything else apart from IOS and android?
Well, you can see how the power is surely corrupting Google. If you don't see it now, give it time. But it's even too late right now.
No amount of bitching will make Microsoft, Apple, Google, Amazon, Facebook and other "big bullies" play nice. What will? Strong, credible competitive threats.
You think Intel processors are expensive? Without AMD Intel processors would cost 4x as much. How much battery life would Intel PCs have without ARM? In fact, I assure you that without AMD, ARM would also be dead because Intel would have simply forbidden their partners from using ARM - the same way Google discourages top android manufacturers from using android forks.
About ur catholic reference - there's only one reason why Catholic churches are "pretty chill these days." And that's competition. New protestant churches are sprouting like grasses everywhere - competition has diluted the power of the church.
Competition is the key to niceness. Just look at the behavior of US ISPs.
The reason it's not all about power/competition is that corruption is very easy to get into your system; be that individual, corporate or otherwise; and tricky as hell to weed out. Once you've been there and done that, the bar is set lower for relapse.
If Chrome team actually cared about Dart and went ahead with Dartium's integration, Dart's future would have been much different.
Then the Angular team decided to dump Dart and go with Typescript.
So politics as usual.
And in addition to not having full support from Google, there was not and probably would never have been buy-in from Mozilla or Microsoft. Also the language IMHO didn't offer much more than JavaScript, and 6to5 -> Babel was gaining traction at the same time. It wasn't a good recipe for success.
I think it was smart of Google of giving it a fair trial and cut its loss when it was time before it got embarrassing or "coffeescript costly" for many developers.
The problem is that all of those new "beautiful" languages is that they trade pragmatism for purity, but at the end, we all have stuff to build, and at the end of the day, a well known, well tested, and good enough language with some modern construct (a la TypeScript and ES2016+) can become a very powerful tool to build small to big code base, whereas a beautiful near perfect languages would have brought us lot of development frictions or little exhilaration.
There is a reason why the Chrome team was not really into it, and they might have been right, but regardless, they should not be blamed for Dart's fall. As developers, I do not think we want another GWT or Google Gear kind of experience.
TypeScript is successful because it solves the right problem the right way, i.e., adding type without changing everything else around it.
See the discussions of soundness versus usability in typescript where they took a lot of heat from some people, but I believe absolutely have made the correct compromises.
Disclaimer: have never used Typescript.
-- My love list --
- The generated JavaScript is usually faster and smaller after compile-time optimizations, for example, objects can be inlined so they become stack-only and don't hit the GC. Example: https://try.haxe.org/#0F337
- It's expressive (but familiar); nearly everything is an expression and switch statements support pattern matching:
var animal = { species: "cat", breed: "bengal", age: 15 };
var friendliness = switch animal {
case { species: "cat", breed: "russian-blue" }: 100;
case { species: "cat", breed: _, age: age } if (age < 5): 300;
case { species: "dog", breed: "golden-retriever" }: 1000;
default: -1;
}
- Fast compile times (for sizable projects you get hundreds of milliseconds rather than seconds – and faster still with incremental builds enabled)- No need for separate tools like webpack:
> You can perform arbitrary compile-time behavior (like processing and embed assets or generating code) by marking haxe code as a macro
> Generates a single bundle by default
> Dead code elimination built-in
-- The downsides --
- Not many people know about it so it's usually better to stick with TypeScript with clients
- The smaller community means if you might have to be more hands-on, both in learning haxe and when it comes to working with haxe libraries – i.e. fixing a bug upstream rather than waiting for the community to fix it
- The package manager is more bare-bones than npm (personally I _much_ prefer this – I find `npm` and `node_modules` can be a nightmare to work with) but there's a general ask in the community for more advanced package management
[0] https://haxe.org/manual/target-javascript-injection.html
[1] https://haxe.org/manual/target-javascript-external-libraries...
I also like purescript - which I like to think of as 'typescript, where the types have teeth' (I like that I can also pull in a js lib and use it)
So like Lisp, Scheme, Haskell, ML and so on?
[0] https://github.com/vshaxe/eval-debugger
[1] https://haxe.org/manual/debugging-source-map-javascript.html
Haxe seems to be much more conservative in development. Haze is aquiring arrow functions but I think there was quite a degree of initial resistance to the notion. I proposed a change to allow the new Javascript style consice object literals (simply allowing {fish,cheese} instead of {fish:fish,cheese:cheese} but was shut down with a 'we don't like it'
I would prefer to use a independent language over one developed by a megacorp, but I fear Haxe will fall behind TypeScript due to their resistance to change.
My own personal experience has motivate me to move to something else. The proposal I mentioned above left somewhat of a bad taste. The process went contrary to the processes listed. Notably The proposer is supposed to call a vote after discussion had concluded. Instead it was just shut down with a "we had a meeting and decided against it". I could give no counterargument because there was no argument to counter. I'm not against languages having a dictatorial model for development, but having a facade of an open process that carries no weight seems wrong.
As for the process, I think it has become a little more stringent for sure. To submit a request for consideration you’d need to submit a proposal on GitHub with attention paid to impact to existing code and impact on future Haxe features- perhaps your feature request wasn’t deemed to be thought out enough? It also looks like you’d get more explicit consideration if you are a sponsor of the language (https://haxe.org/foundation/support-plans.html)
So yes, while it isn’t a completely open vote, I also think most languages’ directions are decided by committee in a similar way. I’m sure the Haxe community would love to see examples of other communities with better practices to learn from.
In which case surely it should be discussed, rather than shut down with "no"?
This thread had me interested in Haxe, but reading these comments about the unfriendly, negative responses to proposals has put me right off.
That said, you can always file an issue in github and have a discussion there. For Haxe it’s a very active location for discussion there.
I'll bite: what should @Lerc have done differently in his proposal (https://github.com/HaxeFoundation/haxe-evolution/pull/51)?
I think general consensus was reached without a formal vote. Discussion was limited but explanation was given: language clarity would be impacted. A few main contributors agreed. @lerc didn’t provide much of a counterargument.
That said, what would you have wanted to see done differently? A formal vote held? This proposal seemed to be a matter of preference, with no real consensus on clarity. Workarounds were even proposed. What would be your ideal resolution? Not shutting down the discussion as haphazardly? How much further should it have gone?
That being said, this particular proposal seems like a matter of opinion (on the level of tabs vs spaces) to which no amount of argument would have really swayed people. Definitely something to learn from here. Thank you for sharing your story!
They are soliciting contributions by promising an open process ( see https://github.com/HaxeFoundation/haxe-evolution#voting-proc... ) but disregarding those processes when they feel like it.
Ironically, the discussion we are having here is much closer to the level of engagement that should have happened there.
As a sidenote, I'm just curious, what do you personally think of the proposal? Would you like to have the concise object literal notation in Haxe?
On the sidenote, I personally don't run into many (if any) situations where I would use concise object literal notation. I'm on the fence as to the issue of clarity and whether it would help/detract/be neutral for Haxe.
The style of concise object literals is fairly inconsistent with the rest of the language at the current time, and I could see how it could lead to clarity/confusion issues. Because I believe it's more of a syntactic sugar than anything else I am leaning to agree that macros may be the way to go for it.
A little discussion about the proposal. Some didn't seem to like it because of 'language clarity'. Some group of core developers discussed it and rejected it.
I don't know what one expects but I have seen quite some language proposals (rejected) and this didn't seem inappropriate to me. They don't want it.. accept it or move on. They gave a reason. If you think it's sufficient is another thing and mostly about opinion.
Why the automatic defense of the Haxe team? Frankly, small communities like this sometimes come across as cult-like in their response to criticism, and it isn't a good look.
Here's the proposal in question: https://github.com/HaxeFoundation/haxe-evolution/pull/51
Here's the process which wasn't followed: https://github.com/HaxeFoundation/haxe-evolution. Very little discussion, no public vote, even though the proposer put in the effort and clearly wanted to engage.
When someone puts in the effort to make a proposal like this, this bait and switch is not a way to keep them around, and insulting them in HN comments isn't any better.
>perhaps your feature request wasn’t deemed to be thought out enough?
Why jump to finding fault with the OP, rather than accepting feedback about the process? AFAICT you didn't actually check OP's proposal before assuming it was lacking. And OP's experience isn't unique.
You're evangelizing Haxe in this thread, but here you just paper over valid criticism:
- "arrow functions are slated for the next major release": sure, it only took four years!
- "I also think most languages’ directions are decided by committee in a similar way": I'm not aware of any other language that has a proposal process inviting community participation, but doesn't follow it and discusses those proposals in private. Point me to one. Surely you can understand that this can be frustrating when someone tries to participate and is shut out.
- "I’m sure the Haxe community would love to see examples..."
I would be pleasantly surprised if I saw the Haxe Foundation engage in some introspection and actually take steps to change or at least be more transparent. So far I don't see any introspection, only defensiveness.
And FWIW, I used to be part of that internal Slack channel for team members and was a Haxe contributor. I tried to make progress on these issues for years before giving up.
I do evangelize the language and have not myself run into these issues as of yet. If they do exist my hope is also to have them resolved, not to justify them away and keep the status quo.
Change proposals are subjective, so people can have different opinions on whether a change should be accepted or whether it was well-formulated enough. What bugs me though is that the Haxe team has a documented process for considering and voting on these proposals, which they don't follow. If Nicolas doesn't like a feature, it's essentially vetoed. If he changes his mind later, it'll be implemented without any further discussion. Most discussion happens in an internal Slack channel so there's no transparency. It's essentially a BDFL masquerading as a democracy, and it can be frustrating to try to contribute as an outsider if you don't realize that. See inline XML for example (https://github.com/HaxeFoundation/haxe-evolution/pull/26) - a lot of discussion, open questions remaining, seemed like Nicolas was generally resistant. Then suddenly, there's a PR and it's merged, and it will be in the next version of Haxe.
IMO, this is not the way to run an open source project. And in my experience, the team is resistant to feedback and takes things personally, so I've lost confidence that it will change.
I don't think that you get a good language by having design by committee. I'm all for democratic process and contributions in many different areas, but you simply can't apply that to language design, but you really need a way to understand and see the big picture, and not only reason about a particular local feature.
The only thing we could do better here would be to spend more time motivating my decisions so they seem less random to people from outside, but it's time consuming to do so and I'm sadly lacking the time for it.
I understand how this can be badly perceived but you shouldn't put ill intend behind what has happened to your proposals.
Also, I saw you started designing your own language, which is very different from Haxe from what I have seen, so it seems to me what you wanted Haxe to be was simply not what it is and will be.
If you don't feel design decisions can be made effectively by a committee and prefer to steer these decisions yourself, that's understandable - just remove the language about the core team voting on proposals or reaching consensus, because in practice it's not how the process actually works.
Basically what I'm saying is that for Haxe to be truly crossplatform, it requires Haxe-native frameworks in the target domain. But that doesn't really seem to be the case outside of games, so that advantage is lost.
I really like the language (after reading the tutorial at least), but I'm not sure where would using it make sense. For backend stuff it just seems completely inferior to Typescript (considering library support especially).
Flash (a browser plugin) being dead does not make ActionScript (a programming language) dead
you can use ActionScript to publish with Adobe AIR and Haxe AFAIK can do that too
Then explore the code cookbook for more advance usage and patterns https://code.haxe.org/