The Future of Programming: WebAssembly & Life After JavaScript

By Eric Elliott

Recently we heard that the web platform is getting a new browser-native compile target called WebAssembly (see What is WebAssembly: The Dawn of a New Era for details). Wasm makes the web platform a more attractive compile target for other languages. That leaves us wondering what might come after JavaScript.

JavaScript has some great features, but I sincerely hope we move on as soon as possible. JavaScript is great and it taught us a lot, but programming will evolve. There will be life after JavaScript.

I’m not a fan of C++ (I’m a recovered user and abuser of C++), but I am a fan of many things built with it, including the Unreal Engine, which runs great when compiled to JavaScript. There’s no good reason to write everything in JavaScript forever. It’s time to look to the future.

I’ve been using and really enjoying CoffeeScript from time to time, which helped inspire a lot of the new ES6 features. CoffeeScript feels much simpler than JavaScript. It has a more concise syntax, yet adds a lot of expressive capability that did not exist in ES5. Of course, I’d simplify CoffeeScript even more by ridding it of the poisonous class keyword. I like to fiddle with Haskell, too. But these languages represent the present.

So what could we do next?

Whatever catches fire after JS, I hope it has these features:

  • Built-in immutable data structures and immutability by default.
  • Literal forms for objects, collections, and primitive types.
  • A better default number type for most use cases.
  • Custom structural types, including good support for low-level binary types (bonus if we get definable literal syntax).
  • Lambdas with closures.
  • Functional utility belt built-in. Similar to the RxJS Observable API.
  • Native support for object and factory composition. Something like built-in stamps.
  • Realtime guarantees for low-latency processing & precision scheduling for apps like gaming, music & video production, DSP, scientific applications, synchronization of distributed systems, etc…
  • Minimal syntax, similar to Ruby, Python, or CoffeeScript. Now that I’ve had a chance to get comfortable without curly braces and semicolons everywhere, I feel a lot less confined by syntax.

First-class Support for Reactive Programming

Baked into the language, a simple, consistent API around all of these:

  • Streams.
  • Continuous data sources (UI inputs, time, vector images, etc…).
  • Collections including arrays and objects.

This API should be used the same way regardless of whether data flows through the functions one value at a time (i.e. iterables / generators + yield), in response to emitted events (e.g. Node-style streams), or continuous data sources such as audio, electrical signals, UI inputs, sensors, even time-independent things like vector graphics, etc…

A built-in API like this could wrap all types, which has the potential to simplify the syntax, as well.

For a really insightful perspective about how all this reactive stuff works, check out A General Theory of Reactivity.

Better Tooling

Unreal Engine 4 Blueprint
Unreal Engine 4 Blueprint

  • A fantastic visual IDE for easily modeling and visualizing reactive relationships in the system. Think NoFlo with a much better UX.
  • Time-travel debugging (example with JavaScript) enabled by immutable data structures. Time-travel debugging lets you easily shuttle back and forth in the history of your live, running program.
  • Compile to JS & wasm great support for browsers and Node.
  • Better analysis tools both static and runtime / dynamic. Specifically designed to help make programs more predictable by analyzing reactive dependency graphs. These could create great visual reports, too, including complexity reports, and marble diagrams to help you further understand and predict the behavior of your program.

Marble diagram for .merge()
Marble diagram for .merge()

Visual IDEs Will be the Norm

Those familiar with flow-based/dataflow programming will rightly tell you that it’s nothing new. Visual programming tools have been around for decades, and have so far been unable to replace text-based programming.

What will push this over the edge is a radical rethinking of how to model programs visually that will reduce the visual clutter and wiring overhead that plagues most flow-based programming solutions.

Most of the innovation in this space is not happening in programming environments at all. Instead, it’s happening in production applications where data flow modeling is the primary task. Nowhere is this better illustrated than in audio production apps.

Audio production apps typically route raw audio through a network of effects processors. In programming terms, you could think of an effects processor as a functional map: a pure function called for each element in a list, where those elements correspond to an audio sample slice.

Most audio apps model this process visually by simulating the real machines and cables in skeuomorphic fashion. A skeuomorphic user interface is one that attempts to emulate the user interface of the original object being modeled in software.

The problem with skeuomorphic design is that it faithfully reproduces most of the user interface clutter and inefficiencies of the original. In data intensive applications such as audio production, that clutter looks remarkably familiar to programmers: The wires look a bit like spaghetti — something all good developers know we should avoid.

BayAreaModularMeet — George P. Macklin — (CC BY-SA 2.0)
BayAreaModularMeet — George P. Macklin — (CC BY-SA 2.0)

But recently, software such as Ableton Live and Renoise have found clever ways to rid themselves of wire clutter completely using channels and chains.

An Ableton Live effects channel. Data flows left to right.
An Ableton Live effects channel. Data flows left to right.

In other words, data flows through channels, and each channel consists of a chain of effects. No wires are needed, because the effects are applied in sequence.

Renoise channels, each with an effects chain. Data flows top to bottom.
Renoise channels, each with an effects chain. Data flows top to bottom.

In code, a channel might look something like this:

const channel = input => {  
  return input  

export default channel;

If you think about this carefully, it becomes clear that you could do a lot more than audio & Digital Signal Processing (DSP) with this model. For example, you could use it to visually model routes and middleware in Express, where routes are represented by channels, and middleware is represented by effects:

A hypothetical Renoise-inspired UI to program routes.
A hypothetical Renoise-inspired UI to program routes.

Of course, this implies that each effect in the chain needs to act on inputs with a shared API. That’s where functional and reactive programming concepts shine. It’s easy to provide a unified API over any type of collection, including a stream of network requests. In functional programming, those wrapping APIs are called functors. In plain English, a functor is something that can be mapped over.

If this sounds a bit like science fiction, take a look at Treeline. It does something very similar today. Take a look at this POST /signup route modeled in Treeline. It encrypts the user’s password, then creates the user model, then responds with status 200 OK. Each of those steps could be thought of as a channel effect:

Treeline: Data flows top to bottom.
Treeline: Data flows top to bottom.

Genetic Programming

Genetic programming is the process of simulating nature’s evolution system by producing populations of candidate programs and filtering out the programs that don’t pass the tests. The candidates that do pass the tests survive and form the basis of the next generation.

Genetic programming offers the possibility of continual, automated improvement on hot code and critical algorithms. There is real potential to point a genetic programming algorithm at a git repository and automatically push new generations of software to production when the population improves on prior deployed versions.

AI-Assisted Programming

Scott Ingram — Dual Neuron (CC BY-NC 2.0)
Scott Ingram — Dual Neuron (CC BY-NC 2.0)

Strong AI is here today. Many AI systems are beating humans at our own games across a variety of categories. One major advantage of AI is that it is capable of analyzing a large variety of alternatives very quickly. AI could examine the code you write, search for potential bugs & vulnerabilities, recognize patterns that could be abstracted, suggest tests that need to be written, or even recognize patterns in genetic programming populations and automatically adjust population and environment parameters to fine tune genetic programming algorithms.

In other words, long term, AI has a very real chance of becoming an invaluable programming tool. In fact, it’s easy to imagine a future where AI can produce programs without any human assistance at all.


Whatever comes next, expect it to be a quantum leap in technology and innovation. The future will be here sooner than you think.

  • Flavio Kodama

    There are life within javascript, but devs usually don’t have time to check. Because usually development is a continuous process, javascript is just a better rock in the pathway. Some people spend a lot of time coding to do things with that code, they are not coders, they are just making their our tools, cause available tools aren’t enough. #code_for_life , challenger than anything else.

    why such low wages for gaming industry? you know why.

    • Legolas

      if life give you tomatoes, don’t make ketchup, sell the fucking tomatoes!!

    • Epic Mac Fadden

      I can`t say how I did popped in here….
      There is a nice debate on “that” site which your opinion would be requested… just to know what is your position about the subject…. is the “Facegloria” post…

    • Gato Quadrado

      Please, supreme leader, give me some advice.
      Or, at least, step on me with your royal feet!

  • Tatsh

    *Of course, I’d simplify CoffeeScript even more by ridding it of the poisonous class keyword.*

    I have no idea what is so bad about some verbosity. Python has the class keyword and so do many other languages. I actually dislike languages that seemingly make you master syntax (Haskell would be one!) instead of just being readable from the start.

    JS with all its short keywords and literal syntaxes seems to also be planned to be less readable as time goes on. I get not wanting to type `new Array()`, but I do not get wanting to type `class` when that is what you are creating (an object (dictionary) definition usually with methods).

    • supersonicecho

      I agree. It is odd that people who blog about javascript consistently dislike ‘class’. None of their explanations for the dislike have ever been convincing. I have noticed that if one simply don’t use the word ‘class’ then no one complains. Call it an Object Template and somehow this magically makes the problems disappear.

      Note that ES6 is baking the ‘class’ keyword in. I wonder if once ES6 becomes the norm the ‘class’ haters move on or they keep fighting the irrational fight.

  • Dwight House

    Nothing will come after javascript. WebAssembly is a companion to JS, not a replacement. The creators of WebAssembly themselves have said so. Many have tried and all have failed to replace javascript. One can only join forces with it if one hopes for anything more than eventual obscurity. The husks of Java applets, ActiveX, Flash, Dart, and PNaCl lay dead and dying before it, serving as a warning to those who have the wisdom to examine history before striking at an impossibly powerful rival. Javascript’s allies, the frameworks, server implementations, and js-targeting languages are strong and growing stronger daily.

    • Tatsh

      Does not mean it is impossible. I do not consider the lack of diversity of language choice in the browser to be a good thing at all. There’s a difference between the markup language (which is relatively plain) as it is and then a scripting language to go with it. I used to love JS as is (including without jQuery) but then realised its major flaws and even though many of those are getting fixed now with ES6 (and more languages compile or transpile to JS), we will not see the fixes for a while without shims/shivs/whatever. WebAssembly is one of those in a way, except it is for fixing possibly the most important problem which is how slow JS can be compared to other languages, not a browser-specific or feature-missing issue.

      Arguably CSS is up for debate as it always has been about its ability to be used productively vs becoming a completely headache (and, what should be in it vs what should be implemented in JS). I rarely hear of people using raw CSS except for small projects.

      • nk01

        Agreed; the Javascript monopoly on client-side web scripting is restrictive and sub-optimal.

    • Sylvain Pollet

      If nothing comes after JavaScript, does that mean JavaScript is the end of the world ? The JS-targeting languages will become WASM-targeting languages. Plus you should consider WASM as an opportunity to add versioning to JavaScript and remove the bad parts of the language without the fear of breaking the web. Transpilers already opened the path.

  • josdejong

    Thanks, nice feature list. I miss one feature though, my #1 feature for the next generation programming languages would be a mixed (optional) type system like you have with TypeScript and Dart.

    • Eric Elliott

      Yep. Gradual structural types with inference. =)

  • Chris Emery

    I personally would like to see aspect oriented UML become gamified and animated.

  • PaulTopping

    I have to strongly disagree with the commenter that said “Nothing will come after javascript.” The point of WebAssembly and asm.js is to support other languages. Even asm.js can support a lot of languages in any browser environment — any environment that supports asm.js in fact so it includes server-side programming and native apps as well. The immediate goal of WebAssembly is to be simply a better asm.js as it will allow distribution of binary code, thereby eliminating an asm.js bottleneck. Beyond that, they’ve stated plans to support more exotic languages by essentially making the execution machine’s instruction set more powerful.

  • Sylvain Pollet

    I wish JavaScript could use WebAssembly to “reboot” the language. I mean, when you read the TC39 notes, it is sad to see that almost all the new ideas are constrained by backward compatibility. The fear of “breaking the web” is so high that we now got non-intuitive names for ES6 API like Object.assign, because they assume people have declared their own Object.merge or Object.extend method. It is time for JavaScript to break the chains that hold it in the past. We already have transpilers and alternative languages, we just needed the right compile target and here it comes.

  • Marco Aurélio – Corei

    Great article! Best regards from Goianésia/Goiás/Brazil

  • spjs

    “quantum leap” please. don’t. use. this. metaphor.

  • realB12

    I think it does not matter. More important than programming language is its global acceptance accross devices, frameworks, organisations and all the tooling around it.
    It is more important that the “language” remains free and will continue to evolve, rather to be locked in the best world of all worlds today to be an alien tomorrow.
    JS is not the best language, but the best common denomiator accross all languages, platforms and tooling, I think.
    Anyway, as a seasoned developer I am able to switch from C++, to C#, from ActionScript to JavaScript from .NET to Javaplatform, etc. So – what’s the matter ? As a pro – everything goes and as an enterpreneur I have to deal with whatever my customer comes and will come up with!
    And for my customer it is and will always be costs to be the primary factor. Costs is about salaries. Cheapest on many projekts is still JS-Coders and Architects doing things from scratch rather than embarking on pricy frameworks you need to spend months on going beyond the stuff that comes readymade out of the box.

  • Dan Shappir

    Great article, but I do have several issues with it:
    1. The article implies that a single language will “catch fire” after JavaScript – I disagree with this. In fact, the whole point for wasm is that any number of PLs can compile to it, thus becoming “native to the web”. I believe there will be multiple PLs in use, depending on the task at hand.
    2. In fact, some of the features specified by Eric are difficult to reconcile into a single PL, for example “Realtime guarantees for low-latency processing” requires lower-level programming than many of the other features listed. I assume Eric wants GC, yet GC doesn’t work well with realtime guarantees.
    3. Some big questions left out of the discussion, e.g. static or dynamic typing? enforced or optional? Personally, I would like static typing with type inference. Also, how should concurrency be handled?
    4. Eric implies favor of functional / OOP approach similar to what we have in JavaScript today, but more stringent. I would like more details. For example, it’s unclear how he would like to marry immutability with OOP.

    • Eric Elliott

      > The article implies that a single language will “catch fire” after JavaScript

      That was not my intent, but I do expect it will be a powerlaw, with a small handful of languages getting the majority of use (as is the case today).

      > I assume Eric wants GC, yet GC doesn’t work well with realtime guarantees.

      It does with real parallelism support.

      > 3

      Gradual structural types, please! And I don’t have many strong opinions about concurrency. I don’t mind callbacks or promises. I don’t have enough practice with CSP to fall in love or discover its cons.

      > it’s unclear how he would like to marry immutability with OOP.

      I see this as a very simple problem: Stamp-based OOP (stamps are composable factory functions employing prototypal and functional OO techniques), and instead of mutating data in-place, methods return a new object.

      • Dan Shappir

        > It does with real parallelism support

        AFAIK RTGC does exist, but has various problems and limitations associated with it. Not my area of expertise however.

        > Gradual structural types, please!

        When a PL evolves out of an existing dynamically typed PL, like TypeScript out of JavaScript, then this is definitely the way to go. But when PL is wholly new, I lean towards enforcing types (with inference, of course). Gradual structural types did not do Dart any favors.

        Oh, an a quality type system, please! JavaScript succeeded despite its type system, not thanks to it.

        > and instead of mutating data in-place, methods return a new object

        So the return value of every mutating method call is a new instance? Interesting – I need to think about this. It does seem to fly in the face of Alan Kay’s definition of OOP: “Objects communicate by sending and receiving messages”

        BTW what is ignored here is that what many people consider to be problems/limitations with JavaScript are, in fact, problems/limitations with the DOM. And while frameworks such as React go a long way to addressing these, they can only go so far. As a result, if we just replace JavaScript but the DOM stays as it is, improvements will be limited. How we can fix the DOM while maintaining the integrity of the web, I don’t know.

  • Anna Lezhikova

    Have you heard of Elm? Or neuroevolution through Erlang?


Learn Coding Online
Learn Web Development

Start learning web development and design for free with SitePoint Premium!

Get the latest in JavaScript, once a week, for free.