Sunday, April 15, 2012

Every few years I find a new language/platform for my experiments. I’d like to share them on the web, so I (mostly) limit myself to things that run in the browser. In the 1990s I used Java. In 2004, I started looking at Flash, but continued using Java. With help from Troy Gilbert, I switched to Flash in 2006, using the Motion-Twin Flash compiler (mtasc) instead of Adobe’s compiler. I continued using Flash, switching to Actionscript 3 and Adobe’s Flex compiler, to make Flash 9 and 10 applets. I also used Javascript for some projects. In an alternate history, Actionscript 3 was a possible future of Javascript/ECMAscript but that history didn’t come to pass. It’s a decent language, with things I miss from Javascript: static types, classes, packages, imports, etc. However, it’s time for a change of language.

I’ve switched from Actionscript to Haxe, Motion-Twin’s successor to mtasc. I’ve been watching Haxe over the years but was waiting for the right time. Unlike their mtasc compiler which can be used with the same source code as Adobe’s compiler, Haxe is a new language. It compiles to Javascript, Flash, Java, PHP, or C++, so it can be used for HTML5, Flash, iOS, Android, and webOS clients, as well as C++, Java, Node.JS, or PHP servers. I’m starting to work on new projects that are likely to involve: (1) HTML5 visualizations and games, (2) simple Flash games, and (3) C++ server code, so this seems like a good time to try Haxe. There are also libraries like NME that let me compile Haxe games to Windows, Mac, Linux, HTML5, Flash, iOS, Android, Blackberry, and webOS, if I want to go beyond web projects.

The language itself is nice. In addition to the things I’d expect (closures, packages, imports, classes, etc.), it contains things I’ve missed from my SML/OCaml days: typed unions, type inference, generics, and structural subtyping. It also has other nice features: external mixins, metadata, properties, explicit inlining, and macros. Everything’s an expression; there aren’t any statements. They understand the basics of covariance and contravariance. The compiler is written in OCaml. For a recovered programming language geek like me, there’s a lot going for it. It’s no Haskell or Scala but it’s a big step up from Actionscript. It’s also very … pleasant. I’m not sure how else to describe it.

I’ve not been using Haxe long, but have already had good luck with the multiplatform part, at least for Flash and Javascript. I had an algorithm for a Flash game, and I compiled it into Javascript and used it without any trouble. Since Actionscript, Javascript, and Haxe are all related, it works well. I’m less sure about how well it will work with C++, especially when it comes to garbage collection. There are probably lots of gotchas there. I also haven’t yet figured out how to use Javascript libraries from Haxe code; for my project I went the other way, using my Haxe library from Javascript code I wrote. I’ll learn more as I go.

I think the weakest part of Haxe is the ecosystem. The developers I have talked to so far are great; the language seems to attract good people. There’s a conference, a forum, and an IRC channel. However, the community is smaller than for Actionscript or Javascript: fewer people, fewer books, fewer web sites, fewer tutorials, fewer examples, fewer libraries. A few years ago when I chose Actionscript over Haxe, it was because I thought people would be using snippets of my code in their projects, I wanted to pick a language that lots of people used. That doesn’t seem to be helping me much. Instead, people read the code and learn from it, but write their own code, or they want to use my library as-is. So the number of people using the language is less important to me now. Supporting multiple platforms is becoming more important. With the map generation project, it was frustrating to have written everything for the client (Flash) and then later needing to run it on the server (C++). As HTML5 improves, I’m targeting more HTML5 and less Flash. Both of these tell me that cross-platform is becoming more important for my projects.

My current plan is to use Haxe for code I want to run across platforms, and use Javascript, Python, and C++ for code that is platform specific.

Update: [2013-Apr] Although I still use some Haxe, I'm not using it for cross-language coding much. For my web tutorials, I write in Javascript directly, except for core data structures and algorithms which I write in Haxe or Typescript, to get classes and type checking. For Flash projects, I use Haxe as a nicer Actionscript but I don't use the cross-language features, nor do I use NME for compiling to mobile. By the time I'm ready to write a game, the landscape (Typescript, Emscripten, Asm.js, ASC 2.0) may have changed enough that I'll re-evaluate then.

Labels: , ,

6 comments:

lightfoot256 wrote at April 16, 2012 1:35 AM

Another convert! Hurah! I'd been throwing Adobe a rope for a long time waiting for AS3 and the Flash platform (or rather their compiler/framework) to just be able to output native binaries for whatever platform and year after year they constantly failed to deliver. I'd been watching HaXe for a while but waiting for that point I could safely switch without too much of a headache.

Anyway; I eventually did it about a month ago; I love the workflow for creating iOS games and the ability to press a different button and get the native mac version, or the native windows version, or a html5 version! It's perfect. It's still a little rough around the edges but from the progress and support and the community around it (it's all open source - so if you find a bug, you can fix it, report it and it gets fixed! I've already fixed a bug, raised it and it was fixed within the day!) I can see it only getting better and better with time.

The biggest initial hurdle for me were the initial language changes and variants over as3; However it didn't take long to realise they're actually more useful than their counterparts; 'for' loops were initially irritating but now I can't see why we've been doing it the old way for so long :-D.

My biggest gripe however so far is the Class template system; In other languages I'd expect the template to be almost a huge macro allowing you to call functions on the "type" you're templating or even create objects of that type within it (example; a map template that initialises it's own map) however HaXe has a big whinge and moan about the type not being specified or available; There are work arounds but I guess at least HaXe has templates :-D.

Overall impressed with HaXe and NME; can't wait to see how it develops.

Chris

Steven Shaw wrote at April 16, 2012 7:04 PM

Nice to see you adopting haXe. I've been watching it for a while myself. It seems well-suited to browser-based games development in particular. Not much else compiles to Flash.

Have you tried the Java (or C#) backends? I thought they were dead but it seems they are recently alpha and in the haXe mainline.

I had hopes that NekoML would gain popularity but the non-C style syntax must be a barrier to some.

http://nekovm.org/doc/nekoml

Amit wrote at April 19, 2012 3:04 PM

lightfoot256: Getting used to Haxe after AS3 didn't take long for me (although I have yet to try macros or generics) but every once in a while I run into a situation where the more general for loop would be nicer. :)

I'm not quite sure what you mean by the limitations of class template parameters, as I haven't used them yet. Have you tried using constraints on those parameters to tell the compiler what they'll include? If you don't include the parameters the compiler has to assume there's nothing you can rely on.

NME looks promising. Right now I'm writing Stage3D so I haven't done much with NME, but I'll take a look at it for a future project.

Steven: Yes, it does seem nice for casual/browser/mobile games. I haven't tried the Java or C# backends. I don't have much use for those languages at the moment. I thought they were dead too, as the tweet announcing them was two years ago, but they seem to be alive again.

I didn't know about NekoML. Interesting. I don't have any use for Neko at the moment but I'll keep it in mind.

Christopher Lightfoot wrote at April 20, 2012 1:26 AM
This comment has been removed by the author.
Christopher Lightfoot wrote at April 20, 2012 1:26 AM

The problem I had was a 2D Map template that you initialised with a tile class; I wanted the map to be able to create instances of the tiles and assign them to the map array but HaXe wouldn't let me create instances of the tile type as it didn't know how to call the constructor of the tile class.

The constrains on the template seem to only work for initialising an instance of the template itself; they don't seem to aid the compiler (as I'd assume they would) in determine what methods are available on the class they're templating (i.e. the tile class).

The workaround was to provide an overridable method on the map class that created "instances" of tiles; and then subclass the template with a map class for each tile type; so for example:

class TileMap extends Map<Tile> {
private function createInstance() : Tile {
...;
}
}

Also love Mixins too; very useful :-D. Not tried macros yet either but they look fun; maybe I could write a better template system using macros...

Christopher Lightfoot wrote at April 20, 2012 7:48 AM
This comment has been removed by the author.