Daniil Korostelev

About me

  • Coding since 7 y.o. (Speccy, Fido, Quake mods, fun years)
  • First love: Python (UI and then server dev)
  • Then a bit of C and C++
  • Then some ActionScript3 and JavaScript
  • Then C# and Unity... and Haxe \o/
  • OCaml somewhere inbetween
  • Currently a Haxe dev at Forge of Empires
  • Still keeping an eye on different tech

About HAXE

  • Created by Nicolas Cannasse (Motion Twin/Shiro Games)
  • 1.0 released in 2006, 4.1.4 released in 2020
  • Open souce, independent, supported by foundation partners
  • General-purpose, but originally comes from gamedev



Some code

good things

  • Multi-target compiler
  • Powerful type system
  • Expressive syntax
  • Static analyzer and optimizer
  • Fast compile times, compiler cache
  • Trivial-to-easy native interop
  • Compile-time code generation
  • Small (compiler+std - 6-8mb zipped)

Multi-target compiler

  • Single codebase -> multiple target platforms
  • Common standard library across targets
  • Cheap or zero-cost abstractions for target-specific things
  • Conditional compilation and native code injection
  • Eval (built-in interpreter)
  • Lua
  • C#
  • Python
  • Java
  • Neko
  • JavaScript
  • JVM
  • HashLink (and C, kinda)
  • C++ (and CPPIA)
  • PHP
  • SWF (Flash)

Type system: trivial stuff

...yep, it has those


  • AKA function pointer, delegate, callback, etc
  • Describes function arguments and return type
  • Can include argument names for readability
  • Helps with architectural bloat, but beware of callback hell :)


  • unspecified types are inferred from context
  • very useful for local vars anonymous function args

(keep some balance for good readability and errors)


  • Array<T>, Map<K, V>
  • and any custom types and functions
  • type parameter constraints
  • type parameters are erased from run-time (Java-like)
  • @:generic for C++-like templating

TYPE System: enum

  • NOT a glorified number (C-style)
  • also known as sum / algebraic / variant type
  • great for defining variants of data
  • Processed using pattern matching (more on this later)
  • Exhaustiveness checking
  • Type parameters and even GADT are supported

TYPE SYSTEM: structure type (and anonymous objects)

  • Objects are checked by structure, not type name
  • Type-safe duck-typing (AKA structural typing)
  • Complemented by anonymous objects
  • Useful for config objects, multiple return, etc.

(may have some run-time costs, depending on the target)

type system: typedef

  • Gives types new names
  • Useful for anonymous types (function, structure)
  • Useful for shortening parametrized types
  • Can have type parameters on their own

type system: abstract type

  • Gives types new meanings
  • Compile-time abstractions over types
  • Eliminated from run-time (zero cost abstraction)
  • Methods, operator overloading, implicit casting
  • enum abstract for "classic" enums
  • Helps against "primitive obsession"

Type system: abstract type

Example #1: type safety

Type system: abstract type

Example #2: moar abstraction!

  • Branching by matching object structure against a pattern
  • Patterns can be simple, like basic constants (classic switch)
  • Or complex, checking inner structure of values
  • Supports or-patterns, variable capture, guards, extractors
  • The way to extract arguments from enum values

example #1: enum

example #2: structure

SYNTAX: for loops

  • NOT a "C-for" (no init;cond;step)
  • Declarative, based on iterators
  • Supports key => value¬†iteration
  • Standard Array, Map are iterable
  • Standard simple Int iterator
  • Custom iterators (zero cost with inlining)
  • Create Array/Map with for loops
  • Short and declarative
  • Supports conditions and inner loops

syntax/type system: static extensions

  • Static helper methods for any type
  • Use like it was a member method
  • First argument is the type to attach to
  • Enable with using MyExtensions;

syntax/type system: import.hx

  • Global or per-directory imports/usings
  • Literally a file named import.hx¬†containing imports
  • Nice for widely used "framework" things
  • No separation between statements and expressions
  • Almost anything can be used in a value place
  • Often more declarative and less imperative
  • Useful to avoid repetition in code
  • Compile-time code generation
  • NOT textual replacement (C-like)
  • Procedural AST processing
  • Extensive compiler API
  • Can replace expressions in place
  • Can change and define new types
  • Access to system API (filesystem, sockets, etc)
  • Lots of use cases:
    • syntax sugar
    • DSLs
    • boilerplate generation
    • pre-calculation and embedding
    • types from static data (e.g. assets)
    • custom static analysis


less useless macro

example: embedding

example: type-safe asset access

example: ui components

example: shader language

example: serialization

example: web routing

  • Dead code elimination
  • Tail recursion elimination
  • Explicit inlining
  • Const/copy propagation
  • Loop unrolling
  • etc.
  • Care required for untyped parts

...doesn't take 7.5m years to calculate

bad things (compared to big players)

  • Well-unknown
  • Small community
  • No big-tech support
  • Not enough quality libraries
  • Standard lib is barebones
  • Some undefined behaviour
  • Tooling is still lacking

thank you!


By Dan Korostelev