iogiiDocsSourceQuick RefOnline InterpreterContact
IOSyntaxTypesVectorizationCircular ProgrammingOpsExamples ⸱ Why

Why

Why you might want to use iogii

Novel ideas in iogii

Here are some of the ideas that are new in iogii. As far as I know these are all original ideas, but it wouldn't surprise me if some of them had been done before, please contact me if you are aware of any such cases so I can properly cite them).

Is iogii simple?

It may be insulting to call iogii simple, since I expect it to be very difficult to understand for even experienced programmers. There was a great article about how simple does not mean easy (unfortunately I cannot find it now). Its point was that easy is more related to familiarity than simplicity. Almost all of the ideas in iogii are not mainstream. Basic familiarity with functional programming will help. But there are many unfamiliar ideas beyond that.

Still, is it actually simple? That is a relative question, but here are some facts about iogii and its implementation (these numbers are as of March 24, 2025 and will be slightly inaccurate after that):

2000 lines of ruby is significant, but consider that this code implements a lazy language in a strict language, can also compile to Haskell (every op is implemented twice), implements static type inference, can parse a rotated program, has error handling, and provides a web interface with graphical representations of programs. Clearly it could be much shorter...

Things like type inference and parsing rotated programs are difficult to do, but they are good abstractions in that the way that iogii is designed and implemented,they always work, you don't actually have to think about them or even understand them to use them. So I would also not consider it fair to call them complicated.

To put all this in perspective, there are more bytes in the iogii documentation (if you include the quickref) than the iogii implementation, 2x more if we look at the minified version of the implementation. So hopefully you will believe me that there isn't hidden complexity that I'm just pretending doesn't exist.

It certainly isn't as simple as brainfuck, lambda calculus etc. But I would argue it is far simpler than any golf language that is as concise as it is. I would just call it what it is: 83 mostly familiar ops, with a handful of highly unusual concepts.

I haven't computed precise stats on it yet, but from my experience comparing it to Nibbles, it is competitive if we multiply program size by log(95)/log(256) ~ 0.82 to compensate for the fact that we could trivially encode iogii programs using all values of a byte.

Why I created iogii

I created Golfscript in 2007. It was arguably the first golf language, and successful due to being easy to learn and more concise than any other language - it didn't have to compete with any other golf languages yet. Shortly after, I left the code golf scene for other life things, and during this time golf languages flourished at codegolf.stackexchange.com. This site shows solutions from all languages next to each other, and although silly to compare solutions from more concise languages like Perl against more verbose languages like Java, one cannot help but think the Perl solution is better if it is half the size. A consequence of this is that code golf languages optimized to out do one another in code size at all costs. Including adding obscene amounts of complexity and overfitting the problem space of typical code golf problems. This made code golf not really about golf at all, but language optimization. It should be no surprise that the more special cases and ops specifically targeted for certain kinds of problems the better that language will be at solving those problems, so for me this was not an interesting game to play.

When I had more free time and checked in on the code golf scene in 2020, I saw that most golf languages had around 400 ops and used unicode characters. I'm sure there were some good ideas in these languages besides just adding more ops, but I had no interest in learning so many ops just to play a game. I didn't like the direction golf languages were going and I might have felt some responsibility for them heading in that direction in the first place. It seemed people thought the intent of Golfscript was to allow for the shortest possible solutions. Although I don't understand how they thought it didn't occur to me to use any characters other than symbols for ops... (Golfscript mainly uses only the 32 keyboard symbols).

Anyway I created Nibbles in 2021 with the goal of bringing simplicity back to golf languages. By having fewer ops and heavy type overloading it makes each instruction half a byte (hence the name). This put a simple language at not so much of a disadvantage. However in order to actually become the best (shortest for typical golf problems), I did have to complicate it (e.g. several two nibble ops via overloading useless op combos, special map/fold modes, etc). In the end, I would say I strayed too far from my goal of simplicity.

Nibbles also was not tacit, vectorized, nor did it allow circular programming (which I didn't even know existed yet). These aren't that big of deal breakers for code size, it only cost half a byte per argument use to not be tacit, and vectorization was not compatible with heavily overloading ops by rank. And circular programming would rarely be useful in Nibbles since it has ops for fold, etc. But it just feels better to write tacit code and work with vectorized values rather than explicit looping constructs.

I realized it was foolish to play this game of language optimization because more complicated languages will always win. Vyxal is surely shorter now, it followed suite of using sub-byte instructions by compressing solutions based on training on all existing open source Vyxal solutions (vyncode). The language has the most ops of any code golf language and now let's you use compression trained on the answers to the very problems you are solving. Not to pick on Vyxal, it just takes the next logical step that golf languages were taking and definitively proves the power of complexity + domain specific targetting.

You can see a ranking of languages on codegolf.stackexchange here

Vyxal:                            2076
Thunno 2:                         2062
Nibbles:                          2029
Jelly:                            2028
...
Golfscript:                       1295
...
Python:                            901
...

Note that these elo ratings are calculated by the author of Vyxal, and most Vyxal programs use flags which he does not count towards the length of solutions. (Nibbles does not use flags). Clearly this is not in the spirit of fairness, any language could take their entire solution in as flags. However I do believe Vyxal with vyncode is more concise than Nibbles because I would guess that many of those vyxal solutions are not actually using vyncode). It should be clear that a complex language can always have the advantage over a simple one since it could do everything the simple one, but with more special cases.

So even though it is foolish to play this game of code golf lang optimization, I spent so much time on Nibbles that I couldn't stop thinking about code golf languages. I thought about what actually makes using esoteric languages fun for code golf. I wanted to figure out how to make a tacit language and how vectorization should work. I wanted tacit programming to be simple and easy (for there to always be an obvious plan to make any program optimally tacit). I didn't find anything. Although I would bet there are some good solutions out there that I was ignorant of (for example J's trains can make any program tacit by using something that resembles abstraction elimination - thanks tubular for that insight).

I learned about circular programming and realized you can do a scanl with it and thus a fold. This could allow you to do a fold using a function of only one arg instead of two. This seemed like a good step towards tacit. When I later realized that you could even do a scanr with circular programming I thought this stuff was very cool and elegant (since now you can fold in a truly lazy way, without having to get the last element). It is remarkable that you can create a Turing Complete language using only ifElse, nil, head, tail, cons, vectorization, and let expressions. And in a direct way too, not like a turing tarpit. So I created Atlas to show off how useful these techniques could be. And I optimized it for golf somewhat, since that is just what I do. Atlas explored vectorization, circular programming, and infix notation, but didn't yet try to tackle tacit.

I liked Atlas, but I wanted something that was actually tacit, so I created iogii. The language I wished existed - rather than optimizing for some other goal.

Here is what I was after:

Be free of the goal of optimizing for code size on the average code golf problem. But obviously it will be very good at that compared to normal languages. This is why I do not call it a code golf language (that term no longer means what I want it to), but a language that is fun for code golf.

A bonus goal was to teach the concept of circular programming.

I would have preferred to keep it symbol only like Golfscript or Atlas, but with vectorization + postfix notation there isn't enough opportunity for overloading so I needed more characters and letters have the nice property of having two versions of them. I think symbol programs are more aesthetic for golf, but I actually find the letter ops easier to remember and thus use.

Infix notation was surprisingly effective, parenthesis weren't needed that often with proper design of ops so that a constant is more likely to be on the right. Still never needing parenthesis is nice, and more importantly, postfix is simpler, so I went with that. Another thing I didn't like about Atlas was having list and vector types, it rarely required converting between the two, but just made things more complicated and arbitrary what the type of an op is.

I didn't have everything figured out when I started iogii, but I have finally arrived at a syntax that perfectly encompasses what I was after. Folds are done with as few extra characters as possible and input can always be implicit. Using values multiple times can still sometimes require 2 explicit characters, but it is definitely impossible to always handle this with one tacit op, I am satisfied with iogii's compromise here. I have no regrets about the design of iogii and thus no need to ever create another golfish language - something I could not say after previous languages, but I could not have made it without making them first.

-darrenks (March 4, 2025)