# Why

## Why you might want to use iogii

-   Learn about laziness and circular programming, because it is actually useful in languages like Haskell.
-   Enjoy writing tacit code and using vectorization.
-   Know everything there is to know about the language you are golfing in so that you can focus on novel solutions to the problem rather than scouring docs and worrying if you just didn't know about an obscure language behavior.
-   Want the benefits of a code golf language but without "cheating" (use of an op that makes a problem too trivial).
    -   Very short solutions
    -   No tedium of parsing/unparsing
    -   Useful ops are all 1 character and cruftless syntax - the innate complexity of your solution will more directly correspond to the actual size of your solution.
-   Challenge yourself, iogii is very alien.

## 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](contact.html) me if you are aware of any such cases so I can properly cite them).

-   fold / scan using functions of a single argument using circular programming (scanl had surely been done before, scanr was pioneered in [atlas](../atlas)).
-   Tacit functions of single arguments by using the op that creates the function as a placeholder for the argument.
-   Place main program input tacitly by rotating your entire program.
-   [Set next var](syntax.html#setnextvar) to set vars using only a single character without having to designate any characters as vars (all characters can be ops that are only overriden if that op is not used). This is non trivial since how do you know when they are being used as an op versus a var? No it isn't based on arity of the final program since that would be ambiguous when using multiple of them (plus implicit values make that impossible).
-   Type inference on circular programs with ops that allow overriding and vectorization that is always guaranteed to uniquely converge without any type annotations.
-   Control of vectorization using only a single number (via commas / capitalization) and `repeat` to control broadcasting. No additional concepts / syntax needed.

## 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):

-   4 types (int, char, list, empty).
-   83 ops + special symbols, with few special cases (not including debugging ops)
-   95 meaningful characters (ascii printable only)
-   2085 lines (61654 bytes) of ruby code with comments, blank lines removed, and indentation removed.
-   27833 bytes if we replace all identifiers and strings with 1 character (since these typically only serve to provide error messages or make code easier to understand). Iogii implementation is not golfed (what do you think I am??), so this is a more invariant measure of its complexity.
-   59777 bytes of for this site's documentation (not including the quickref).

2000 lines of ruby is significant, but consider that this code implements a lazy language in a strict language, can also compile to an engine, 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](https://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](https://codegolf.meta.stackexchange.com/questions/8798/golfing-class-of-a-language)

    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:

-   Simple
-   Tacit
-   Vectorized
-   Plain ascii characters only
-   Typical ops that are found in mainstream languages (as opposed to golf specific ops)
-   Not too many ops
-   Eliminate the tedium of repetitive parts of codegolf (e.g. input parsing).
-   Functional

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)



