# Source

Code can be viewed on [codeberg](https://codeberg.org/darrenks/iogii) - not github due to them not respecting licenses by training LLMs on code without crediting said code when used in a response (iogii license is BSD 3). I realize that some will claim fair use and that such training will still happen, but this way I do not consent to it.

## Running Iogii Locally

Download the prepackaged ruby [1 file](iogii) and `chmod +x iogii` (requires ruby 2.7.2 - 4.0.0+). Now to run an iogii program named `prog.iog`:

    iogii prog.iog

The ruby and online interpreter are very inefficient. You can also execute iogii programs using an engine written in Haskell (about 25 times faster). To set that up download the [engine](engine.hs) and compile it with `ghc -O engine.hs` (requires ghc 8.0.2 - 9.14.1+).

Then to use the engine:

    iogii prog.iog --engine > prog.ism && engine prog.ism


## All source

[All source](iogii-VERSION.tgz) includes all the source used to develop, test, and generate this site. You can verify it on your system with `cd src; test/all`.

## Releases

### 1.2 - May 20, 2026 (Latest)

-   [All Source](iogii-1.2.tgz)
-   [Website Snapshot](snapshot.html?v=1.2)
-   [1 File](iogii-1.2) (packaged ruby files, `chmod +x` it)
-   [engine](engine-1.2.hs) (optional execution engine, `ghc -O` it)

Changes:

-   String ops can now be used generically ([doc](ops.html#asubcharsubops)).
-   `rangeBegin` is now `b` instead of `B` (less overloadable).
-   Add `sortedSet` op as `B` (overload) or `$,` ([updated doc](types.html#lowrankoverrides) about this type of overloading).
-   `min` can also be used as an overload with `V`.
-   Add `range` op as `|` (overload) or `{,`
-   First `}` now also sets the [implicit](syntax.html#implicitvalues) value if it would otherwise be unset (nil).

Note, I intend for this to be the last major release. Future releases will most likely only address bugs, usability, documentation, etc. as I believe the language has addressed all major pain points and there is unlikely to be any major improvement ideas found. I also feel it strikes the right balance between complexity and golfing prowess. That being said, please do continue to send any ideas / issues / etc.

### 1.1.4 - March 27, 2026

-   [All Source](iogii-1.1.4.tgz)
-   [Website Snapshot](snapshot.html?v=1.1.4)
-   [1 File](iogii-1.1.4) (packaged ruby files, `chmod +x` it)
-   [engine](engine-1.1.4.hs) (optional execution engine, `ghc -O` it)

Changes:

-   Simplified URL encoding of programs for online interpreter.
    -   Old URLs are not compatible but will forward to snapshotted version (hence this release to synchronize the website).
-   Minor engine optimizations.
-   `Cmd+/` to comment / uncomment in online interpreter.
-   Raw line mode is now done with a trailing `'` to program instead of leading space.

### 1.1.3 - March 17, 2026

-   [All Source](iogii-1.1.3.tgz)
-   [Website Snapshot](snapshot.html?v=1.1.3)
-   [1 File](iogii-1.1.3) (packaged ruby files, `chmod +x` it)
-   [engine](engine-1.1.3.hs) (optional execution engine, `ghc -O` it)

Changes:

-   `>` [Match algorithm](syntax.html#codeclassinlinegtcodematching) overhauled, now they prefer not to leave any unmatched (before if one loop function took in the result of another loop function it could do an outer match leaving the first `>` unmatched) - thanks tubular for pointing out a case where it was not optimal.
-   `a 0 mod` is now `a` instead of `0` (also thanks tubular for making this case).
-   `a 0 toBase` is now `[a]` (before errored)
-   Made arithmetic ops lazier. Rarely will be useful, but maybe could allow you to terminate some otherwise infinite computations.
    -   `0 b mult` is still `0` but without evaluating `b` (same for any element when using `prod`)
    -   `a 0 div` is still `0` but without evaluating `a`
    -   `a 0 pow` is still `1` but without evaluating `a`
    -   `0 b mod` is still `0` but without evaluating `b`

Buf fixes:

-   Fix a bug with using wrapped set implicits (here's a case that could have caused it `i)>2 k e)> 3k 5>`).
-   Online interpreter now starts from fresh state with each run (before identical warnings would be suppressed).

### 1.1.2 - Feb 6, 2026

-   [All Source](iogii-1.1.2.tgz)
-   [Website Snapshot](snapshot.html?v=1.1.2)
-   [1 File](iogii-1.1.2) (packaged ruby files, `chmod +x` it)
-   [engine](engine-1.1.2.hs) (optional execution engine, `ghc -O` it)

Changes:

-   Created an engine for executing iogii programs faster than pure ruby.
-   Removed Haskell code generation ability - there is no real point to it anymore as the engine is almost as fast and this was very bug prone. The previous release (1.1.1) fixed one issue that affected GHC 8.0.2 but introduced another.
-   Change the order in which some op's args are executed to ensure consistency between ruby and Haskell execution (they were just edge cases so shouldn't affect normal programs)

Bug fixes:

-   The order of `charClass` whitespace values in Haskell was backwards from ruby.

### 1.1.1 - Jan 12, 2026

-   [1 File](iogii-1.1.1)
-   [All Source](iogii-1.1.1.tgz)
-   [Website Snapshot](snapshot.html?v=1.1.1)

Bug fixes:

-   Change Haskell code generation so that it can work with older versions of Haskell for all programs (golf.shinh.org uses 8.0.2 which didn't work for some programs like just `W`).
-   When running iogii from the command line, don't block on input unless input could be used.

### 1.1 - July 4, 2025

-   [1 File](iogii-1.1)
-   [All Source](iogii-1.1.tgz)
-   [Website Snapshot](snapshot.html?v=1.1)

Changes:

-   Rename `baseFrom` from `#` to `X` and swap arg order, long name is now `fromBase`.
-   `fromBase` can no longer accept char type (revert to pre 1.0 behavior). The reason being that accepting char types would change coercion behavior of the op it is a low rank overload to, which is a bug (regardless of if it is `X` or `#`).
-   Add `bits` op (`p`) (reverse digit order from `toBase`) - Thank you lyphyser for a related suggestion and bringing my attention to this pain point.
-   Add `powOf2` op (`h`)
-   Add [raw lines mode](io.html#rawmodes)
-   Auto parse will now break command line args into lines when newlines present.

Minor changes:

-   Improve some error messages.
-   Manual tail call optimization for a few ops in ruby implementation (thanks lyphyser for the patch).
-   Remove some obsolete mnemonic names.

Bug fixes:

-   When omitting `"` on the last string in the program you can now end it with `\"` (before it would truncate it). E.g.

    "asdf\" -> "asdf\""

### 1.0.1 - April 28, 2025

-   [1 File](iogii-1.0.1)
-   [All Source](iogii-1.0.1.tgz)
-   [Website Snapshot](snapshot.html?v=1.0.1)

Bug fixes:

-   `foldr` on an empty list now returns initial value (previously returned default value for that type).

### 1.0 - April 16, 2025

-   [1 File](iogii-1.0)
-   [All Source](iogii-1.0.tgz)
-   [Website Snapshot](snapshot.html?v=1.0)

Changes:

-   `'` can be used with a UTF-8 char now
-   The `b` in byte strings (`""b`) can now be implicit if the string contained an invalid UTF-8 character (e.g. 128..255). Note that [code.golf](https://code.golf) does not accept solutions with invalid UTF-8 chars, so this is useless there.
-   Revert `iterate` to take initial value of type `a` and use `cons` instead of `append`. For 0.3 behavior you could replace `[initial] iterate [fn] >` with `[initial] expand [fn] tail append >` (or roll your own).
-   Implicit values can now be set more than once [see here](syntax.html#unmatchedendbrackets).
-   Rename `cut` from `%` to `#`
-   `baseFrom` can now accept chars too.
-   `rangeTo` can now accept chars, it starts from the zero of its type (space for char).
-   Add `isCharClass` op `%`.
-   Add `cutAny` and `scanAny` ops (`-` and `+`).
-   Add uppercase versions of string `D` `G` `K` that find first occurence of any substring - see [slicing ops](ops.html#slicingops).
-   Bug fixes:
    -   Negative indexes to `get` now return default value instead of first value.
    -   `init` on empty list now returns empty list instead of erroring (problem was in HS only).
    -   `mdup` / `mpeek` functions can now terminate immediately after a loop op. Thanks tubular for the report. See [this new syntax section](syntax.html#differencebetweenfunctionloopopandmetaopfunctions) for better clarification of mixed function behavior.
    -   Auto parse in ruby interpreter now counts input as strings if any numbers are not in minimal form, e.g. `--2` or `04`. Before only the Haskell code worked this way, thanks Yewzir for noticing.

### 0.3 (Beta) - March 18, 2025

-   [1 File](iogii-0.3-beta)
-   [All Source](iogii-0.3-beta.tgz)
-   [Website Snapshot](snapshot.html?v=0.3)

Apologies for the large number of major changes. I have no further plans for large changes and should just be making minor changes and fixing bugs/documentation in the future.

Changes:

-   Remove block syntax, now ops that create loops act like regular values syntactically
    -   Removes need for `!` and nested rotation trick, instead just place values that needed to be to the left of the arg to the left of the loop op.
    -   Allow `>,` to match previous loop creation ops skipping initial match
-   `>` in main function [overrides implicit values](syntax.html#unmatchedendbrackets) like how `@` did.
-   Additional implicit values beyond the initial input use the `$` of where they are used (they are also placed at beginning of unrotated program).
-   Auto input is removed from the stack if empty and implicits used instead.
-   Add [set next var](syntax.html#setnextvar) (`=`).
-   Remove `[`, `]`, and `@` ops, use new `=` instead.
-   `mdup` / `mpeek` cannot match `>` (this allows them to always be skipped when matching `>`, use set next var instead if you needed that).
-   Rename assignment from `~` to `set` and add `let` syntax (alias for `set` ... `del`).
-   Change [broadcasting](vectorization.html#broadcastingwithexcessrank) when there is excess rank.
-   Better handling of [ops with two generic types](types.html#opswithtwogenerictypes), e.g. sortBy.
-   Fix an assortment of bugs (please report any new ones!).
-   Support negation in data format, e.g. `1,2~,3 = [1,-2,3]`
-   Use the system's character encoding rather than bytes. You can force a string literal to still use bytes with `""b`.
-   `-` cannot subtract char from char (use `^` now), this is to uphold an invariant that makes circular type inference sound.
-   Change `charClass` op to be a unary function that returns all chars in given character class.
-   `iterate` takes a list to prepend instead of a single value
-   empty auto input is `nil` instead of empty string
-   Empty type defaults to Int when used as a scalar (before errored).
-   You can do a vectorized op with a list of empty type (nil), this would usually be useless since result will always be an empty list (before errored).
-   `keep` promotes first via repeat (to easily generate a fixed number of scalars for example).
-   `chunkWhen` returns rest of first list when second list runs out
-   Raw mode for stdin does not break input into lines (also created with `,` now).
    -   Add `lines` (`p`) low rank overload to approximate old behavior.
-   Add `peek`, `mpeek`, `consDefault`, `rightJustify`, `dropUntilAfterSubstring`, `keepUntilSubstring`, `getSubstring`, and `init` ops
-   Remove `or` (use `max` or `ifElse` instead)
-   Renaming of several ops, the purpose of which is to provide better mnemonics and make some ops more generic.
    -   `=` → `q` (equal)
    -   `s` → `&` (sortBy)
    -   `q` → `s` (len)
    -   `#` → `_` (sum)
    -   `P` → `.` (prod)
    -   `|` → `L` (abs) (low rank overload)
    -   `_` → `~` (negate / read)
    -   `|` → `.` (ord)
    -   `P` → `_` (words)
    -   `A` → `(,` (min) (now generic and not a low rank overload).
    -   `X` → `x` (max) (now generic and not a low rank overload).
    -   `x` → `\` (setDiff)
    -   `&` → `#` (reshape)
    -   `\` → `|` (chunkWhen)
    -   `W` → `#` (fromBase) (`W` not valid overload with new behavior of `a` `b` types).

### 0.2 (Alpha) - Dec 11, 2024

-   [1 File](iogii-0.2-alpha)
-   [All Source](iogii-0.2-alpha.tgz)
-   [Website Snapshot](snapshot.html?v=0.2)

Changes:

-   Clarified `reshape` behavior, explained in new [Ops](ops.html) page.
-   Fix bug with `,` following token that was split up, e.g. `nJ,`
-   Add Graphviz visualizations to online interpreter.
-   Support Haskell code generation (~50x speedup + no stack overflow limit)
-   Remove `pp`
-   `show` now prints like Haskell would
-   Rename `nuke` to `del`
-   Remove regex `match`
-   Add `charClass` [op](ops.html#charclass)
-   Output chars mod 256 rather than error if out of range
-   `expand` does not return the initial value now (thanks UnrelatedString for the suggestion).
-   Change `transpose` to insert default values so that truncation is never needed.
-   Support input from command line args after `--`.

### 0.1 (Alpha) - Nov 7, 2024

-   [1 File](iogii-0.1-alpha)
-   [All Source](iogii-0.1-alpha.tgz)
-   [Website Snapshot](snapshot.html?v=0.1)

Changes:

-   Add more string ops
    -   `charRange ^`
    -   `uppercase U`
    -   `lowercase L`
    -   `parts P` (split on whitespace)
    -   `chr |,` (convert int to char)
    -   `match +` to match regexes.
-   Allow unterminated strings.
-   Allow [implicit args](syntax.html#implicitargs).
-   Add auto parsing of input.
-   `@` also sets input if none present.
-   Make `pow ^` work more consistently for negative numbers and not overflow for large numbers.
-   Remove ops: `nfoldProd p`, `and y`
-   Add ops: `pad p`, `index .`, `get g`
-   Rename ops:
    -   `chunkWhen` `.` → `\`
    -   `transpose` `\` → `p` (pivot). So that it can be unvectorized and also provide nice overload for `prod`.
    -   `digits` `\` → `p` (it's like transposing a string)
    -   `last` `z` → `l`
    -   `len` `l` → `q` (quantity)
    -   `equal` `q` → `=`
    -   `assignment` `=` → `~`
    -   `generate` `g` → `K` (kCopy), no longer generic
    -   `if` → `y` (yes no)
    -   `sum` `_` → `#`
    -   `negate / read` `~` → `_`
    -   `pow10` `Z` → `H` (hyper)
    -   `sqrt` `H` → `u` (unsquare)
    -   `toBase` `#` → `D` (digitize)
    -   `fromBase` `#,` → `W` `baseFrom` (base was). Note that arg order is also swapped - necessary to have vectorized overload.

### 0.0 (Alpha) - Oct 29, 2024

Initial release. Uses Ruby 3.1.2.

-   [1 File](iogii-0.0-alpha)
-   [All Source](iogii-0.0-alpha.tgz)

SHA256 sum of 1 File: d325338fab8c0d44a94a2dd85c9deda61d32fe20521e4c125c99d142e37e5a5c

