Nim language draws from best of Python, Rust, Go, and Lisp

Nim compiles and runs fast, delivers tiny executables on several platforms, and borrows great ideas from numerous other languages

New languages emerge to fill niches that the existing ones don't satisfy. Google's Go combined the speed of C with the rapid development cycles of interpreted languages like Python. Rust came about because Mozilla wanted a systems-level language that included memory safety in its design.

Nim, a language that's been in development since 2008, is making a case as a mix of the best of many worlds: The compilation speed and cross-platform targeting of Go, the safe-by-default behaviors of Rust, the readability and ease of development of Python, and even the metaprogramming facilities of the Lisp family.

Nim for nimble

While the language is still in a pre-1.0 state -- the most recent release is 0.16, unveiled earlier this month -- Nim has enough of its approach nailed down to give prospective users a strong sense of development in the language. (A recently completed book also provides a thorough guided tour.)

Nim's syntax is strongly reminiscent of Python's, as it uses indented code blocks and some of the same syntax (such as the way if/elif/then/else blocks are constructed). Like Go or Rust, it uses strong types, and it has many of the same kinds of language features: first-class functions; distinct types, to make it more difficult to accidentally cast one kind of variable as another; and object-oriented programming, but with composition emphasized over inheritance. Nim also allows templates and generics, the latter omitted from Go to the dismay of some users.

The Nim compiler emits C code by default, but can also produce C++, Objective-C, or JavaScript, with others possible through different compiler back ends. That said, C is a smart default, since it means Nim can interface with the entire galaxy of existing C software, and C libraries can be easily wrapped with Nim interfaces and repurposed.

Compiled code is cached, so a big project with minimal changes to one module will recompile only that module. A macro facility allows code to be changed at compile time by Nim code rather than by a preprocessor. The resulting executables are tiny -- a "hello, world" compiles to around 150K in Windows -- and have no external dependencies save for those you specify.

Memory management in Nim is by default garbage-collected by a deferred reference counting system. You can enable real-time garbage collection at compile so that the seconds and minutes spent on garbage collection cycles is constrained, or you can disable garbage collection entirely and use manual memory management where needed. Thus, a developer can begin coding quickly to produce a garbage-collected program, but gradually transform to be manually managed.

By contrast, Rust has all-manual memory management that's checked at compile time -- excellent for those who want both safety and control by default, but at the expense of some flexibility and development speed.

What it takes to get to 1.0

No language will see much adoption unless it has a robust standard library and a good selection of third-party modules. Nim aims to supply both and includes the Nimble package manager as part of its standard deployment. The number of packages available for Nim isn't near what's available in Go or Rust yet, though.

Nim's biggest disadvantage right now is the relatively small community of users involved in its development -- an understandable drawback given its status as an independent work. Development is led by the language's creator, Andreas Rumpf, but it's not a full-time effort. Compiler bugs still pop up regularly. Even moderately old code examples may no longer be useful due to changes, and it can be hard to find out what those changes are without closely following the project's development. (The "windows" package, for interfacing with the Win32 API, is being revamped and is now listed as "oldwinapi" in Nimble.)

Still, Nim helps develop software that eventually needs to be made robust and fast, but without as much of the steep learning curve or cognitive overhead usually associated with existing languages for such development. In that sense it's somewhat closer to Go: It's easy to dive into and start getting results from almost immediately, but with few long-term costs (performance, particularly) later on down the line. While Nim has more in the language than Go, its code tends to be less verbose than Rust's.

Concern is rising regarding the challenge of creating robust software that runs infrastructure and the fast-moving development cycles need languages that complement them. It's hard not to notice the latter exacerbating the former, which explains the rise of languages and development tools that attempt to address those issues. Even if Nim is still in the comparatively early stages, it's worth watching as part of that process.

[This article was edited to correct an inaccuracy about Nim's default garbage collection system. It uses deferred reference counting by default, not a mark-and-sweep system.]