By Peter Wayner
Contributing writer, InfoWorld |
Was it Alexander Pope who said, “Hope springs eternal in the human breast”? Pope was a poet, not a hacker, but I believe he would understand the anticipation involved in discovering a new programming language. He would know that software developers are forever hopeful that this language, with its unique conflation of Unicode characters, will finally solve all of our problems, making coding easy with just a few clicks.
Pope surely would understand the desire for a new syntax so intuitive that we need only imagine an answer, and see it rendered into logical rules that are marvelous, elaborate, and above all correct. He would appreciate the yearning in our fingers to spin new code that looks as effortless and elegant as a triple axel, an inward three-and-a-half in the pike position, or a giant slalom run in the Olympics.
Most modern languages aren’t built for whimsy or demonstrating our coding prowess, however. They’re made in response to a common issue that the creators are eager to solve. While most developers will continue to do our everyday coding in one or more older, more established languages, we’re forever on the lookout for new tools to help us solve our coding problems. We can see this tendency, especially, in the rise of domain-specific languages, or DSLs. These languages are compact and focused. They’re not intended for general-purpose use. But some could earn a special place in your toolbox for exactly that reason.
Here are 11 newer languages that have found their niche. Some are DSLs, designed to do one thing and do it well. Others, seemingly, aspire to save the world. Even if they aren’t what you need right now, all of them have something to teach about making our computers do what they do, but better.
When you marry Clojure with React, this is what you get: a system that combines all the possibilities of reactive front ends with the solid, functional strength of Clojure. At its best, Reactive Clojure lets you lay out a complex collection of front-end components and string them together with functions. The Reactive framework fills in the details and ensures application data flows smoothly between your components and the database. Clojure brings the functional foundation to make even out-of-the-ordinary use cases possible—and debuggable.
Is it a match made in heaven? Time will tell. Reactive Clojure is a good option for writing the glue code that holds together front-end components. Its multithreaded model is a natural match for complex and reactive dashboards that report on multiple tasks simultaneously.
One of the more ironic games that programmers play is pushing most of our work to configuration files. These files, often encoded in JSON, YAML, or even XML, are a good coding idea that’s metastasized into elaborate ritual. In some cases, you don’t even need to write actual code; just endlessly jigger the various configuration files to do what you need.
It makes sense, then, that we have Nickel: a programming language for creating configuration files. Nickel is like a template with embedded logic, which you can use to craft configuration files that aren’t static. A parameter could be one value during the week and a different one on weekends. When it runs, Nickel creates a new configuration file that fits all the parameters it’s received.
Nickel’s structure is largely functional, and type checking is available, if it happens to help. A big theme is “correctness” because a well-written piece of Nickel code pretty much guarantees that the output will obey both the syntactic rules and any other rules you need enforced. Nickel’s compiler lets you write contracts, then checks to see that the output obeys them. Sure, there’s something funny about writing code to create configuration files that then boss around your code. But it’s a very practical solution for modern architectures.
Kobra‘s creators wanted a language that opened up machine learning to engineers, scientists, and other not-so-professional coders. The result is what they call a visual language for machine learning. Kobra’s editor composes code-like sequences with drag-and-drop tiles representing common built-in routines for statistical analysis and machine learning. The process feels like R with data frames constructed from tabular data and a collection of graphical display functions for creating dashboards and papers.
One of the cloud’s most useful features is the ability to start up and tear down servers to handle data surges. It once took weeks for a data-center hardware team to requisition, install, test, and configure a machine. Now, the cloud lets you do all of this in minutes, or even seconds.
Many devops teams have started writing code to the various APIs supported by the different clouds. Microsoft decided to go a bit further and create a simplified language for starting up machines in Azure, as part of its infrastructure-as-code philosophy.
The language, called Bicep, offers an efficient, declarative format to spell out most of the different bits that a developer might want to flip in a new instance. Some basic type-safety can help prevent errors and there’s a syntax-aware editor available in VS Code. The language itself is designed for higher-order thinking about infrastructure, with a strongly declarative structure that allows you to include instructions in any order, then let Azure’s resource manager optimize the execution.
A friend claims that his one requirement for choosing a bank is ensuring the bank’s accounting software uses integers to count pennies and not floating-point numbers for fractions of a dollar. The dangers of errors with floating point are well known and too great. How many bugs have been caused by tossing about numbers with not much care?
Frink is a “units aware” language created for just this problem. Each variable in Frink doesn’t just hold a number but also an indication of the unit of measure, be it tons, watts, feet, or meters. Unit conversion is easy thanks to the Frink configuration file. Frink’s core mechanism also uses arbitrary precision numbers to reduce problems with round off. It’s like type checking but for numerical units of measurement.
Sound synthesis might seem like a narrow focus, but it’s very useful for game development, virtual reality, and any application that relies on good sound quality. Enter Faust, a domain-specific language that gets its name from an amalgam of functional audio stream. Faust’s structure is purely functional, and all of its functions build up a sound-processing pipeline. Its back end breaks the incoming sound into a numerical representation, and the code itself is a set of functions that can be composed or combined into a final result. As an example, you could create an echo or a reverb by splitting your code output and introducing a delay. Faust’s code is transpiled into C++, C, LLVM bit code, WebAssembly, Rust, and a few other languages, so you can use it with nearly any project.
Anyone who writes code knows how a programmer would start a band: Instead of putting out an ad to find a drummer and then interviewing everyone who responds, just write some code to spell out the rhythms for a drum machine. Once that’s done, you might as well replace all the other band members with subroutines. You could even build an entire symphony orchestra that way.
Melrōse and Glicol are two music programming languages designed for this style of creating music. Both allow you to create elaborate compositions with just a few keystrokes. Melrōse works at a high level around the standard twelve-tone octave common in western music. Notes are grouped into sequences and the software handles much of the scut work like transposition. The output goes to any MIDI-capable instrument and the code can also react to incoming signals over the MIDI port, so the Melrōse code can be a band member.
Glicol is a Rust-based tool that accomplishes much of the same tasks but from a lower-level. The code integrates with digital signal processing to offer a wide range of musical options. The tool is designed to produce browser-ready sounds with its open source audio engine. Glicol’s developer says the language has “a low entry fee and high ceilings” to encourage collaboration with others of all skill levels.
The most efficient way to ship instructions to the computer is to encode them in binary and limit them to the basic set of operations used by CPUs. Each chip has its own favorite binary syntax and some languages like Pascal or Java have a neutral binary format meant to run on a local virtual machine. WebAssembly (Wasm) follows in these footsteps, offering web browsers predigested binary code combined with text in a standard format. WebAssembly’s goal is to replace the minified JavaScript code that forms the backbone of web applications with something that’s even more ready to run, with near native speed.
Many developers will use WebAssembly without writing it directly, using compilers that convert higher level languages into WebAssembly that will run in browsers. There’s also a move to create low-level languages that expose much of WebAssembly’s basic structure in a human readable form. Wase is one such option, offering a C-like syntax with strong typing.
WebAssembly is also finding a use outside of web browsers, as a general way to encode instructions with a stack machine similar to Java’s JVM. Redpanda, for instance, is a streaming data platform that offers developers the chance to tweak or modify the data as it comes down the pipe with code written in WebAssembly.
Technically, Java is not a new language. Indeed, one of the greatest things about Java is that its developers have done a great job maintaining compatibility with older versions. It’s usually pretty easy to compile code that’s 10 or even 20 years old for the latest JVMs. The code is not guaranteed to work, but it’s still easier to compile than almost any other language. The Java team has a suite of millions of integration tests, and it shows.
I include Java 17 in this list because it has been so modernized that it would be almost unrecognizable to a time traveler from the 1990s. Java 17 has so many extra features and extensions that change how we code.
Some, like the enhanced random number generator or the stricter floating point math semantics, address the challenges of writing very complex numerical code. Developers writing accounting systems can get away with using integers to hold the number of cents, but those tackling AI algorithms and complex linear algebra need floating point.
Others, like strong encapsulation and extended switch semantics, bring a mixture of discipline and flexibility to the core language. In all, it’s easier than ever to write stronger, safer, and more secure code thanks to all of these improvements. It’s still Java at its core, but the extras make a difference.
Copyright © 2022 IDG Communications, Inc.
Copyright © 2022 IDG Communications, Inc.