#import "../template.typ": conf #import "graphics.typ" #show: conf.with(title: [iOwO design], subtitle: [don't worry, we're just dreaming]) // highlight important terms in bold #let expand(it) = { ("(" + upper(it.first()) + "|" + it.first() + ")" + it.clusters().slice(1).join() + "s?") } #let singlify(it) = { it = lower(it) if it.ends-with("s") { it = it.slice(0, -1) } it } #let terminate-recursion(it) = { let clusters = it.text.clusters() clusters.insert(1, "\u{FEFF}") clusters.join() } // even though it looks like this could be automated with a `query`, // this'd require wrapping the whole document in a show rule // at which point `query` doesn't find anything anymore #let terms = ( "source", "ast", "graph IR", "runtime", "optimizer", "scheduler", "VM", "command", "pipeline", "input", "argument", "consumer", "output", "streamer", "modifier", ) #let terms-trigger = regex(terms.map(expand).join("|")) #show raw: it => { // avoid making terms in codeblocks bold show terms-trigger: terminate-recursion it } #show terms-trigger: strong // color codeblocks // haskell hl seems to work ok for this #show raw.where(lang: "iowo", block: true): it => { raw(it.text, lang: "haskell", block: true) } // actual content lol #outline( indent: auto, fill: line( length: 100%, stroke: ( cap: "round", join: "round", thickness: 0.5pt, paint: luma(75%), ), ), ) = Type data model == Requirements - Color-aware - It can handle colors and colorspaces for images - OpenColorIO? - number/number type support - custom types (structs/enums) - algebraic enums - traits (`Numeric`...) = Execution stages #graphics.stages-overview == Source ```iowo open base.png >| open stencil.png >| mask |> (invert | show) |> show ``` Functional and pipeline-based. However, in contrast to classic shell commands, commands can have multiple outputs and multiple inputs. === Commands The foundation of actually "doing" something. - Can have any, even infinite, amount of inputs and outputs. - Their amounts may or may not be equal. - Inputs and outputs must have their types explicitly declared. - An command with - at least one output is called a streamer. - at least one input is called a consumer. - _both_ at least one input and at least one output is _both_ a streamer and a consumer, and culminatively called a modifier. - May also contain spaces in its name. ==== Inputs - Based on position. - Inputs can be provided both through the pipeline and ad-hoc. - Ad-hoc inputs are called arguments. - So all of these are equivalent: ```iowo 1 | add 2 add 1 2 [ 1 2 ] | add ``` ==== Outputs - Also based on position. === Pipelines - Exchange data between streamers and consumers. ==== Simple forwarding In the simplest case, where inputs map to outputs bijectively#footnote[one to one], pipelines are just pipes and forward unchanged: ```iowo open owo.png | invert | save owo.png ``` ==== Splitting To handle each output of a streamer individually, they can be _split_: ```iowo mask |> invert -- would invert the unmasked part |> show -- would show the masked part ``` ==== Combination To throw multiple streamers into the inputs of a consumer, they can be _combined_: ```iowo open base.png >| open stencil.png >| mask ``` However, since lists are automatically spliced into inputs, this is equivalent to the above: ```iowo [ open base.png, open stencil.png, ] | mask ``` === Comments Done with any of `--` or `//`. === Data types ==== Lists - Signified by `[]` braces. - If thrown into a pipeline, it automatically works like a streamer. - Can be delimited by commas. - Must be delimited by commas if a contained streamer takes an input. - May have a trailing comma. - Outputs of streamers are spliced into the contained list. - In effect, they are automatically flattened. == Graph IR The parsed representation of the source, and also what the runtime operates on. In a way, this is the AST, except that it's not a tree. === Optimizer Merges and simplifies commands in the graph IR. == Runtime === Scheduler Looks at the graph IR and decides when the VM should execute what. === VM = Open questions - @input - At which position are arguments injected into command inputs? - How could that be controlled if set to e.g. the end by default? - Not all inputs are order-independent, e.g. `div` - Should inputs and outputs really be positional? - Could make more complex commands hard to read - But keyworded could also make code very noisy - Maybe a middle ground, such that at most 1 input is allowed to be positional? - @pipeline - We need some way to reshuffle and reorder outputs and inputs in a pipeline - @splitting - How would one split different outputs into a list? - Should outputs that are not thrown into a consumer be automatically displayed in some kind of debug view? - Or should that be done instead using a debug `show` command or the like? - Should consumers be called sinks instead? - Shorter - More ambiguous if only looking at the first char though