Skip to content

Instantly share code, notes, and snippets.

@bmaupin
Last active July 14, 2022 15:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save bmaupin/67af52c1a99cc9b0542a4c70e8949a9c to your computer and use it in GitHub Desktop.
Save bmaupin/67af52c1a99cc9b0542a4c70e8949a9c to your computer and use it in GitHub Desktop.
Modern high-level languages that compile to native binaries

Goal

A simple way to write native applications (particularly CLI applications but optionally GUI applications) in a modern language (e.g. not C++/Qt) that's fun to use (e.g. not Go). This is primarily for small utilities where speed isn't a big concern. Binary size is a mild concern. Most of the rest is just icing on the cake (cross-compile support, etc).

Summary

Language High-level Garbage-collected Cross-compiling REPL Backed by large organization Cross-platform GUI library Comments
👉 TypeScript with pkg yes yes yes yes yes yes This isn't really "native" but may be the best option for something quick and dirty without having to resort to less-fun languages (like Go). See test-javascript-executables for ways to get the binary as small as possible.
Kotlin with GraalVM yes yes no yes yes yes Fun to write (unlike Go) and truly cross-platform (unlike Swift) although binaries may be large and not super efficient and ⚠ no cross-compiling support (see workaround)
Dart yes yes no no yes yes Without cross-compilation or a REPL, the only advantage this might have over Go is that it looks like it's probably enjoyable to use
Go ⚠ no yes yes ⚠ no yes no Probably best choice to build small, fast, cross-platform binaries, but ⚠ terribly pedantic and not fun to write, made worse by lack of REPL
Swift yes yes ⚠ no yes yes no Not a terrible choice, but ⚠ not truly open or cross-platform (e.g. see comments here, here, here; IBM has stopped working on Swift; Swift for TensorFlow has been abandoned)
Kotlin Native yes yes yes ⚠ Can't use JVM libraries, no REPL?
Nim yes yes non-trivial ⚠ no ⚠ no ⚠ No REPL, hasn't gained enough traction to prove it will be around for a while yet, footguns (significant whitespace)
Crystal yes yes ⚠ no ⚠ no ⚠ No REPL, hasn't gained enough traction to prove it will be around for a while yet, footguns, Ruby syntax
Zig ⚠ no ⚠ no yes ⚠ no ⚠ no ⚠ No REPL, too low-level (no exceptions, no built-in string types), not garbage-collected
Rust ⚠ no ⚠ no ⚠ no yes ⚠ No REPL, too low-level, not garbage-collected, too complex, too many footguns, slow compilation

Notes

  • Kotlin with GraalVM
    • Pros
    • Cons
      • GraalVM may not support 100% of Kotlin JVM code yet
      • Large-ish binary size (probably not a big deal except for very small CLI utilities, ~5 MB overhead)
  • Kotlin Native
    • Pros
    • Cons
      • Kotlin Native can't use JVM libraries
  • Swift
  • Nim
    • Pros
      • Garbage collected
    • Cons
      • Python syntax (i.e. whitespace is significant)
      • Cross-compiling seems to require some legwork
      • Footguns (macros, operator overloading)
  • Crystal
    • Cons
      • Ruby syntax (one more thing to learn)
      • Footguns (macros, operator overloading)
  • Go
    • Pros
      • Backed by Google
      • Very fast
      • Great concurrency support
      • Great tools
      • Spec is consise and simple enough you can hold most of the language in your head
      • Cross-compiling is super simple
    • Cons
      • Not fun to write 😕
        • Very pedantic; compiles will fail with unused libraries, variables, etc
        • No exceptions, only error codes, which must all be handled explictly which is annoying to do and the code ends up littered with error code handling
      • No REPL for quick hacking
      • Too low-level: have to deal with pointers and dereferencing
  • Zig
    • Pros
      • Cross-compiling supported out of the box
      • Very small binaries
      • Simple with no footguns (macros, operator overloading)
    • Cons
      • Not backed by any major organization
      • Memory must be managed manually 😬
      • No native string support
      • Too low-level: have to deal with pointers and dereferencing
  • Rust
    • Pros
      • Very safe
    • Cons
      • Memory must be managed manually 😬
      • Very complex
      • Lots of footguns (macros, operator overloading, etc)
      • Slow to compile
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment