The big languages are popular for a reason: They offer a huge foundation of open source code, libraries, and frameworks that make finishing the job easier. This is the result of years of momentum in which they are chosen time and again for new projects, and expertise in their nuances grow worthwhile and plentiful.
Sometimes the vast resources of the popular, mainstream programming languages aren’t enough to solve your particular problem. Sometimes you have to look beyond the obvious to find the right language, where the right structure makes the difference while offering that extra feature to help your code run significantly faster without endless tweaking and optimizing. This language produces vastly more stable and accurate code because it prevents you from programming sloppy or wrong code.
The following nine languages should be on every programmer’s radar. They may not be the best for every job—many are aimed at specialized tasks. But they all offer upsides that are worth investigating and investing in. There may be a day when one of these languages proves to be exactly what your project — or boss — needs.
Kotkin: Java reconsidered
Java is a great language that supports some of the most popular platforms ever, but it’s getting a bit old and the pain points are becoming a bit too well-known. Kotlin is the brain-child of the JetBrains team in Russia, the ones who have brought us wonderful IDEs like IntelliJ. Kotlin is meant to compile quickly, co-exist with Java, and fix some of the worst issues that occupy the time of Java developers.
The best part may be the attention paid to nullable values, the bane of all object-oriented programmers. If you feel that half of your code is checking for null values, the Kotlin developers heard your screams. Kotlin takes a great step toward solving this problem, if not once and for all, then at least most of the time by forcing developers to explicitly call out the variables that might be null. Then it automatically checks for some of the worst mistakes we can make with them.
This cautious strategy has proven to be popular because it allows team to adopt the language slowly. The Kotlin group has gained many fans in big development teams at major banks, consulting groups, and app firms.
Erlang: Functional programming for real-time systems
Erlang began deep inside the spooky realms of telephone switches at Ericsson, the Swedish telco. When Ericsson programmers began bragging about its “nine 9s” performance, by delivering 99.9999999 percent of the data with Erlang, the developers outside Ericsson started taking notice.
Erlang’s secret is the functional paradigm. Most of the code is forced to operate in its own little world where it can’t corrupt the rest of the system through side effects. The functions do all their work internally, running in little “processes” that act like sandboxes and only talk to each other through mail messages. You can’t merely grab a pointer and make a quick change to the state anywhere in the stack. You have to stay inside the call hierarchy. It may require a bit more thought, but mistakes are less likely to propagate.
The model also makes it simpler for runtime code to determine what can run at the same time. With concurrency so easy to detect, the runtime scheduler can take advantage of the very low overhead in setting up and ripping down a process. Erlang fans like to brag about running 20 million “processes” at the same time on a Web server.
If you’re building a real-time system with no room for dropped data, such as a billing system for a mobile phone switch, then check out Erlang.
Go: Simple and dynamic
Google wasn’t the first organization to survey the collection of languages, only to find them cluttered, complex, and often slow. In 2009, the company released its solution: a statically typed language that looks like C but includes background intelligence to save programmers from having to specify types and juggle malloc calls. With Go, programmers can have the terseness and structure of compiled C, along with the ease of using a dynamic script language.
While Sun and Apple followed a similar path in creating Java and Swift, respectively, Google made one significantly different decision with Go: The language’s creators wanted to keep Go “simple enough to hold in one programmer’s head.” Rob Pike, one of Go’s creators, famously told Ars Technica that “sometimes you can get more in the long run by taking things away.” Thus, there are few zippy extras like generics, type inheritance, or assertions, only clean, simple blocks of if-then-else code manipulating strings, arrays, and hash tables.
The language is reportedly well-established inside of Google’s vast empire and is gaining acceptance in other places where dynamic-language lovers of Python and Ruby can be coaxed into accepting some of the rigor that comes from a compiled language.
If you’re a startup trying to catch Google’s eye and you need to build some server-side business logic, Go is a great place to start.
OCaml: Complex data hierarchy juggler
Some programmers don’t want to specify the types of their variables, and for them we’ve built the dynamic languages. Others enjoy the certainty of specifying whether a variable holds an integer, string, or maybe an object. For them, many of the compiled languages offer all the support they want.
Then there are those who dream of elaborate type hierarchies and even speak of creating “algebras” of types. They imagine lists and tables of heterogeneous types that are brought together to express complex, multileveled data extravaganzas. They speak of polymorphism, pattern-matching primitives, and data encapsulation. This is just the beginning of the complex, highly structured world of types, metatypes, and metametatypes they desire.
For them, there is OCaml, a serious effort by the programming language community to popularize many of the aforementioned ideas. There’s object support, automatic memory management, and device portability. There are even OCaml apps available from Apple’s App Store.
An ideal project for OCaml might be building a symbolic math website to teach algebra.
Strong typing has many advantages like catching some bugs early and improving the general quality of tools. Adding types allows the smart editors to help you with smart suggestions as you craft your masterpiece. Code completion is much faster and more accurate when the code completion routines know something about the functions and the arguments. That means less movement of the fingers on the keyboard. The TypeScript lovers are sure that advantages like these will lure anyone who is on the fence about the power of a strongly determined language.
Rust: Safe and usable systems language
The front-end programmers aren’t the only ones having fun. Rust is like a refurbished version of C with plenty of polymorphic typing mixed in under the hood. It has won “most loved programming language” from Stack Overflow voters for the last two years in a row, an honor that is also reflected in Stack Overflow’s index of language popularity. Just a few years ago, Rust was hovering around 50 on the list, and this year it jumped to 18.
Why? Perhaps because Rust cleans up many of the gnarly issues with C without doing too much handholding or insisting that the developers don virtual straightjackets. System programmers love not relying upon garbage collection, a great service until it kicks in at exactly the most inappropriate time. Rust makes you feel like you’re in charge of what happens to the number in the memory, not waiting for some service to do the work for you.
The typing system is general and flexible, offering the kind of polymorphism that is inspired by Haskell, at least in the abstract. When it’s implemented, though, the compiler customizes the structure for each type, something the developers like to call “monomorphism.” The language adds a few other limits to keep developers from going off the rails. Each value, for instance, is “owned”—which really means it can only be consumed once, preventing a tangled web of references from other parts of the program that act as if they have full control over a value.
All of these features plus a few more—like race-condition-free threading—mean that the new programmer can start writing system code without running into some of the worst anti-patterns that have long bedeviled C programers. You get all of the hard-core, high-performance fun of writing C with a compiler that will catch many of the worst mistakes before the code even runs.
Scala: Functional programming on the JVM
If you need the code simplicity of object-oriented hierarchies for your project but love the functional paradigm, you have several choices. If Java is your realm, Scala is the choice for you.
Scala runs on the JVM, bringing all the clean design strictures of functional programming to the Java world by delivering code that fits with the Java class specifications and links with other JAR files. If those other JAR files have side effects and other imperative nasty headaches, so be it. Your code will be clean.
The type mechanism is strongly static and the compiler does all the work to infer types. There’s no distinction between primitive types and object types because Scala wants everything to descend from one ur-object call Any. The syntax is much simpler and cleaner than Java; Scala folks call it “low ceremony.” You can leave your paragraph-long CamelCase variable names back in Java Land.
Scala offers many of the features expected of functional languages, such as lazy evaluation, tail recursion, and immutable variables, but have been modified to work with the JVM. The basic metatypes or collection variables, like linked lists or hash tables, can be either mutable or immutable. Tail recursion works with simpler examples, but not with elaborate, mutually recursive examples. The ideas are all there, even if the implementation may be limited by the JVM. Then again, it also comes with all the ubiquity of the Java platform and the deep collection of existing Java code written by the open source community. That’s not a bad trade-off for many practical problems.
If you must juggle the data in a thousand-processor cluster and have a pile of legacy Java code, Scala is a great solution.
Haskell: Functional programming, pure and simple
For more than 20 years, the academics working on functional programming have been actively developing Haskell, a language designed to encapsulate their ideas about the evils of side effects. It is one of the purer expressions of the functional programming ideal, with a careful mechanism for handling I/O channels and other unavoidable side effects. The rest of the code, though, should be perfectly functional.
The community is very active, with more than a dozen variants of Haskell waiting for you to explore. Some are stand-alone, and others are integrated with more mainstream efforts like Java (Jaskell, Frege) or Python (Scotch). Most of the names seem to be references to Scotland, a hotbed of Haskell research, or philosopher/logicians who form the intellectual provenance for many of the ideas expressed in Haskell. If you believe that your data structures will be complex and full of many types, Haskell will help you keep them straight.
Julia: Bringing speed to Python land
The world of scientific programming is filled with Python lovers who enjoy the simple syntax and the freedom to avoid thinking of gnarly details like pointers and bytes. For all its strengths, however, Python is often maddeningly slow, which can be a problem if you’re crunching large data sets as is common in the world of scientific computing. To speed up matters, many scientists turn to writing the most important routines at the core in C, which is much faster. But that saddles them with software written in two languages and is thus much harder to revise, fix, or extend.
Julia is a solution to this complexity. Its creators took the clean syntax adored by Python programmers and tweaked it so that the code can be compiled in the background. That way, you can set up a notebook or an interactive session like with Python, but any code you create will be compiled immediately.
The guts of Julia are fascinating. They provide a powerful type inference engine that can help ensure faster code. If you enjoy metaprogramming, the language is flexible enough to be extended. The most valuable additions, however, may be Julia’s simple mechanisms for distributing parallel algorithms across a cluster. A number of serious libraries already tackle many of the most common numerical algorithms for data analysis.
The best news, though, may be the high speeds. Many basic benchmarks run 30 times faster than Python and often run a bit faster than C code. If you have too much data but enjoy Python’s syntax, Julia is the next language to learn.