Frictionless Bananas

Write-up by: Jeremy Sawicki
Team name: Frictionless Bananas
Team members: eulerscheZahl, frictionless, Illedan, nikaj, sullyper
Languages: Littleman, C++, Blub
Source code: source.zip

Unlike most recent years where I have competed alone, I participated with a team of five people this year. For most of the contest we were on the leaderboard as team L1, but at the last minute we adopted the Frictionless Bananas name. This page describes my work on the 2026 ICFP Programming Contest.

Teasers

There were some hints before the contest that the task would involve a made-up programming language or virtual machine. The web page talked about little men running around inside a computer, and there was an animated footer that appeared to show one of the little men. I even noticed some interesting comments in footer.js, but those were apparently not meant as teasers because they were eventually removed.

What was less clear was whether we would be implementing the language to run code provided by the organizers, writing our own code in the language, or something else.

I have been working on a hobby compiler project for 5+ years, with the goal of being able to quickly add new target architectures. The ICFP Programming Contest was the motivation for the project. The contest often tends to be related to programming languages, so I was hoping there would eventually be a contest that involves writing code for a made-up architecture where a compiler would be useful.

Based on the teasers, I spent the week before the contest getting into practice by adding two new target architectures: Little Man Computer and Befunge. The former was mostly a red herring, although it was the first time I supported a machine with an accumulator, which turned out to be relevant. I chose Befunge because I was expecting a 2D language (even though the footer was technically only 1D).

Lightning round

When I saw the lightning round, I concluded that a compiler was not likely to be helpful. The problems were too small, more like puzzles that need to be hand-optimized. It felt more like a Zachtronics game than a programming contest—fun, but not quite what I was expecting. In fact, I didn’t write any code at all during the first day, other than hand-coding solutions in the editor.

Full round

Things changed a bit during the full round. Some of the new problems seemed too big to solve by hand. Still, it was not clear how to adapt a compiler to the unusual Littleman language.

I eventually wrote a fairly efficient solution to the Memory problem, supporting constant time reads and writes. It uses the Split instruction to create many men, each responding to a single address. I realized it could serve as the storage for compiled code. I came up with a design where I/O uses the same interface: reads from address 0 come from input, writes to address 0 go to output, and writes to addresses 1-3 go to the display. Generated code can be laid out in one large room, with memory and I/O accessible from anywhere in constant time, without needing to be near a particular pipe.

Compiler

My compiler implements a language that is conceptually somewhere between C and C++. There are no classes, just functions for code and structs for data. On the other hand, there are references, function / operator overloading, and templates. Most constructs are similar to C or C++ for familiarity, except in cases where a change seemed merited (e.g. different variable declaration syntax, no headers / forward declarations). Some nice optimizations are implemented on the intermediate representation, including global value numbering, function inlining, and loop unrolling. The set of primitive types and built-in operations are defined by the individual targets, so the language can be a bit different depending on the target. I jokingly call the language Blub, based on a Paul Graham essay.

For the Littleman target, my implementation is incomplete. In particular, I did not implement function calls. It did not seem necessary for the contest problems. Inline functions are fine, since they don’t exist at code generation time.

Examples

Here are solutions to some problems using the compiler, as well as the Memory implementation that they are based on:

Final note

Thank you very much to the organizers for a wonderful contest. It was very well put together and a lot of fun to participate in.


The Frictionless Bananas