Some Big Recent Changes

Hello! It’s been a year… how about another post?

Here are some recent changes!

Switch to MoonJIT

Brat compiles to Lua and runs on LuaJIT.

The future of LuaJIT has been a bit hazy. It hasn’t seen even a beta release in three years. A few contenders for a successor have arisen - RaptorJIT, OpenResty fork, LuaVela, etc.

While RaptorJIT seems solid, work on it has also apparently stalled.

MoonJIT, however, appears to be plowing ahead and rapidly pulling in changes from the other forks. It may not be as principled or cautious as LuaJIT or RaptorJIT, but neither of those matter much for a little unimportant language like Brat.

When switching to MoonJIT, the Brat repository also switched to using a Git submodule to pull in MoonJIT. This is much better than including a copy of the MoonJIT repo the way it used to include LuaJIT!

Syntax Errors

Can you believe this has been Brat’s syntax error message for years:

lua: Method error: false has no method called 'ast'

Wat. Does. That. Even. Mean?

Now check out the current syntax error message:

Brat parser:
	A syntax error was encountered while parsing the code.
	Missing closing parenthesis for function arguments on line 1:

lua: Syntax error in a.brat

Wow! A specific error message! A file name! A line number! A code snippet! An arrow pointing at the relevant code! The words “Syntax error”!

There are a number of specific cases with nice error messages like this (missing parens, missing quotes, etc). Other syntax errors have a more generic message but otherwise look similar.


An extremely thin wrapper around LuaJIT’s FFI has been added.

All it can do currently is add and call C functions.

Still pretty cool!

Standard Library Cleanup

The following libraries/wrappers have been removed:

  • HTML
  • Mongrel2
  • Mustache
  • Turbo
  • ZeroMQ

These were all poorly-maintained, unused, and out-dated.

As you can see, they were also all web-related. That stuff is probably better in a separate library.

More Conditional Improvements


Passing Conditional Value to Branches

Recently catb0t made an awesome enhancement to conditionals.

Have you ever written code like this?

if thing = some_operation() then

and then people/linters got mad? I use this pattern all the time but it bothers me because it seems like there should be a better way.

Guess what! Now there is. Brat conditionals will pass the result of the condition to the branch:

true? some_operation
  { result |
    p result # prints whever some_operation returned!

This applies to true?, false?, null?, when, and when_equal.

Faster When

This inspired me to go back and look at the performance of when, which I know is abysmal.

You may remember that conditionals can be inlined under common circumstances. This means instead of actually calling the true? function (for example), the code will be converted to a regular Lua if/then. All the overhead for creating closures and calling the functions is removed.

Well, now when has the same super power! And it makes things really fast.

There are a couple example Brat programs which use when heavily.

The first two below are Conway’s Game of Life and Langton’s Ant. I modifed the programs slightly to actually exit and then calculated “frames per second”.

Quicksort uses a random 10,000 element array, so results do vary a little bit.

Example     | Before | After
Life        | 14fps    | 105 fps
Langton     | 2174 fps | 2500 fps
Quicksort   | 0.775s   | 0.085 s
Ackermann   | 0.247s   | 0.022 s

Except for Langton’s Ant, these improvements are huge. Quicksort and Ackermann are nearly 10 times faster!

Ten Years of Brat

Okay, it’s a little crazy that this silly little language has been under development for ten years!

There isn’t much to say, really, except it’s been a fun and educational (and sometimes frustrating) ten years of tinkering on this bratty language.

Recent Updates

Now for some recent news.

Brat works on OSX again.

The bootstrapping binary (“minibrat”) only worked on Linux. Now there is one for OSX, too (“minibrat-osx”). OSX has also been added to the TravisCI build to help ensure future compatibility.

Parsing is faster.

I spent a significant amount of time focused on making the parser go faster. It is still slow relative to industrial parsers, but much faster than it was!

There isn’t a lot of Brat code to test the parser on, but I’m seeing a 40-60% reduction in parse times.

Faster method name conversion.

Brat escapes quite a few symbols so they are usuable in variable/function names. When calling a method like has_method?, the string passed in must be escaped first.

This can be a bit slow, since it uses regular expressions which requires calling out to the Oniguruma regular expression library.

Now Brat caches these conversions and first attempts a native Lua pattern match before falling back to Oniguruma.

(Some future work involves automatically using native Lua patterns for Brat regular expressions, where possible.)

Symbols are back.

Symbols (:example) are immutable strings again. Fun!

What’s Next?

Who knows? That is what is great about hobbies. You can pick them up and put them down as you like!

More posts…

Fork me on GitHub