Saturday, July 26, 2014

The programming language Noop was not an official Google product, though it was often given credit for being so. Dedication to testability was what made Noop so unique and exciting, and what generated hype about its eagerly-awaited first release.

Why Noop Didn't Die

The Java community is probably the most dedicated to unit testing, which is not reflected in the language's design or standard library. A couple of really bad ideas like URL equivalence reading from static DNS calls exemplify the lack of now-common practices such as Dependency Injection. It becomes a full career to explain how to write testable code (see: Misko Hevery, the author of that article I justcited on Dependency Injection). There isn't a language in existence yet which makes testability inevitable.

Wake, like Noop, resolves the issue entirely. In Wake your program startup is dependency injected. This means you can simply declare:

every Main is:
needs Printer;

and your startup class will get a Printer, the Printer gets what it needs, etc. Then in your test cases you can pass in any Printer you wish to verify its output.

As you can see in this example, Wake has removed the new keyword, requiring all new objects to be created by injectable providers. This means statements you used to write as new Printer() are now Printer from PrinterProvider, a simple change that allows PrinterProvider to return any (more testable) implementation of Printer which it desires.

New Language, New Tricks

We didn't stop at testability.

A huge goal of Wake is to make the smoothest syntax of any statically-typed language. Type inference is one option, but it doesn't play as well with OOP languages as it does with functional ones. The easiest solution we saw was to stop requiring developers to name their typed variables.

greet(Person) {
// code
}

Here we have a method that works on a Person, which in java we would've defined as Person person, or worse, Person p. This syntax is only possible in a language which scrapped static methods because they are death to testability.

This foreach statement takes a list of Entity objects named Entity[], and lowers it to the variable Entity so that you can execute code on each. For those who are curious, foreach operates on expressions, not variable names. This means the above could have been written as foreach(getEntities()) save(Entity). This is a concept only possible in a language which understands your program's types, and lets your variables be named directly after them.

It is also worth noting that Wake currently compiles to Javascript. Not to spill too many beans, but we're hoping to create several more compile targets in the future. Maybe Wake will become a swiss army knife for our constantly diverging platforms.

If you are looking to try something new, advise the direction of the project, or even hack at the compiler (written in C++), then Wake might be the next (or at least the newest) language to be worthy of your excitement or contributions.