Imagine a bacon-wrapped Ferrari. Still not better than our free technical reports.
See all our reports

Frostbyte: The New JVM Language from ZeroTurnaround

ZeroTurnaround is proud to announce Frostbyte, a new stack-based language for the JVM. The language was born out of frustration of working with the standard Java software stack and tools. Hopefully this language will be the long awaited answer to the myriad of JVM languages that have hit the streets in the past couple of years. With some confidence, we believe that Frostbyte will solve both social and engineering problems that software developers have to deal with.

A key innovation in Frostbyte as a stack-based language is the use of inverse reverse Polish notation with parentheses. Instead of first putting things on the stack and then executing an instruction on it, we let you write it the other way around, which feels more natural.

Frostbyte code maps very closely to Java bytecode, and any overhead in code becomes blatantly obvious. Instead of adding in the whole kitchen sink, we chose to cherry-pick the features that make the language both easy and simple yet powerful enough to replace Java in most if not all applications.


Let’s look at a basic hello world example:

fun main :=
  (call echo „Hello World!“)

Frostbyte lets you define chunks of bytecode that are always inlined when called. For example, the standard library defines echo as a chunk:

chunk echo :=
  (with System (with (get out) (call println ...)))

And the expanded form of the hello world is:

fun main :=
  (with System (with (get out) (call println „Hello World!“)))

Instead of Strings, Frostbyte has Ropes as the main text type, but Ropes are implicitly converted to Strings, e.g. when interfacing with existing Java code.

fun main (args: Rope[]) :=
  (echo (with „Hello, “ (call concat (args head))))

If the above is saved in a file hello.fb, you can run it with the fb command.

> fb hello Jim
Hello, Jim

The Frostbyte language is fully internationalizable. In fact, the built-in default language is Estonian, but language is detected from each source file. Other languages are provided as simple translation files — English (British) and Russian are included by default. For example:


The Estonian translation of hello.fb would be:

fun esik(argumendid: Köis[]) :=
  (kaja (võttes „Hello, “ (kutsu jätka (võttes argumendid (kutsu pea)))))

You can also provide translation maps for your own code — the translations are stored as annotations in .class files. The Frostbyte IDE (coming soon) has knowledge of these translations and will suggest code completions based on your selected language.

Of course, no language introduction is complete without the Fibonacci example. There are several ways to do it. While if statement + recursion is one way, we are trying to deprecate the if statement, since it’s really just a degenerate form of pattern matching. One way to do pattern matching in Frostbyte is to describe the patterns in function arguments and provide a separate function body for each case.

fun fib (0) := 0
fib (1) := 1
fib (n) := + (call fib (- n 1)) (call fib (- n 2))

As you can see, operators like + and * don’t need the call keyword. You can also create your own operators by using the op keyword instead of fun.

Pattern matches can also appear as expressions in function bodies. Here’s an example in Estonian. We’ll also introduce code blocks, loops/closures and let (olgu) keyword.

// get current time as Aeg (Time) type
amps praegu: Aeg := pööra (võttes System (kutsu currentTimeMillis)) Aeg

// Funktsioon, mis leiab raamatukogust laenutatud raamatud, mille tagastamisega on hilinetud või mis on rikutud
fun leiaHilinenudRaamatud := (
 olgu raamatud := võttes Andmebaas (kutsu leiaLaenutatudRaamatud);
 võttes raamatud (kutsu koonda ( raamat ->
   ons? (< (võta tähtaeg) (kutsu praegu)) ->
     (uus Hilinemine raamat)
   ons? (võta rikutud?) ->
     (uus Rikkumine raamat)

For those few who don’t speak Estonian, a translation is in order:

koonda=collect (filter + map)
ons?=case (introduce a pattern)
tähtaeg=due date

Complex Example

Let’s look at a bit more complex example that introduces classes as well.

class Vector2(x: Double, y: Double) :=
 // dot product
 op ‌·(that: Vector2) :=
   + (* (get this x) (get that x)) (* (get this y) (get that y))

We can write (get this x) as a shorthand for (with this (get x)). But we can also use the with keyword to shorten the field accesses:

op ‌·(that: Vector2) :=
  (with this (
    + (* (get x) (get that x)) (* (get y) (get that y))

But even better, if we write with X or Y, then a tuple of X and Y is put on the stack, and any access to their fields or methods will alternate between X and Y.

op ·(that: Vector2) :=
 (with this or that (
   + (* (get x) (get x)) (* (get y) (get y))

We can then see some repeating patterns here and can reduce it down further

(with this or that (
   + (* dup (get x)) (* dup (get y))

dup will duplicate the next bytecode instructions, but combined with this or that means the first (get x) will be (in Java-speak) this.x and the next (get x) will be that.x . How cool is that.


I bet you are curious about the kind of bytecode generated by Frostbyte. Lets look at the expanded hello world again.

fun main := (with System (with (get out) (call println „Hello World!“)))

javap gives us this:

  0:   getstatic       #16; //Field java/lang/System.out:Ljava/io/PrintStream;
  3:   ldc             #22; //String Hello World!
  5:   invokevirtual   #24; //Method java/io/PrintStream.println:(Ljava/lang/String;)
  8:   return

So the translation is quite straightforward: with System (get out) in this case translates to getstatic, then “Hello World!” to ldc, and call to invokevirtual. call always translates to either invokestatic, invokevirtual or invokespecial, except when it’s used to expand a chunk, in which case it gets replaced with the chunk and any arguments are inserted into the bitemarks (e.g. in the echo chunk, is a bitemark).

chunk echo := (with System.out (call println ...))

Frostbyte 1.0 Roadmap

The language is still in development, but we are getting close to the first public Beta release. For 1.0, we have some more awesome things planned:

While we are still working towards the first publicly available version, here are some links for you to familiarize yourself with the language to be ready for the big release.

Into the Future

We think Frostbyte will make a real change to the way software is developed. ZeroTurnaround is confident that it will become the next Java and will solve most of the problems that plague developers around the world, such as difficulties dealing with concurrency, parallelism, and the CPU-memory gap.

The Frostbyte 2.0 compiler will have built-in AI that is able to make aesthetic judgments about your code and will outright disallow ugly code, over-abstractions and excessive copy-and-pasting *.

To enable the latter, the AI will have a connection to a centralized data cloud and will be able to compare your code to everyone else’s. It will automatically find copyright and patent infringements and end the software patent wars forever. The AI will utilize automated crowd sourcing to some extent and you can also play your part in improving everyone’s code!

Exciting times are ahead and we are glad to take part in inventing the future!

* we know some people want more freedom, and are working on ways to lift some of these constraints for commercial Frostbyte subscriptions.

  • The FrostByte language resembles FORTH language.

  • Fried Dust

    april first?

  • Rafał Wasielewski

    yes april first joke :D Kabanov-Raudjärv type inference :))

  • You have a bug in the translation table, the last row is reversed :)


  • Erkki Lindpere

    Good catch. I wondered why that wouldn’t compile in English.

  • Fred

    For sure the silliest idea I’ve seen in a while. Reverse Polish does not make any sense unless you are born in eastern Europe.
    And having many language supported is such a wrong idea. Now no key can understand your code. Great…

  • Oliver’s Dad

    I already use reverse/inverse Polish.  To use this format do I have to go to reverse x2/inverse x2 or would just square them exponentially.  If you have a clue what I’m talking about then my April1st response is either more funny or less funny (unless squared exponentially) than FrostByte.  Brilliant!

  • Finally! A programming language with proper Kabanov-Raudjärv type inference!! 
    (and stack based to boot!)
    I’ve looking for a language to ease the pain of Java but Clojure has too many parenthesis and   Scala has too many concepts (and let’s be honest: who really wants to learn ? )

  • Igor Maznitsa

    Looks good but being implemented in FORTH it would be less verbose

  • I know its a hard to catch bug, but luckily I am one of the few who have Frostbyte compiler built-in :)

  • Samuel Williams

    It is amazing how similar parts of this look to my developmental language Kai (

  • Andrey Breslav

    Seems like too few morphisms, does Varmo approve of this approach?