Overview

If you already had a chance to take a look at examples you could be overwhelmed by these unknown circles, dots, arrows and loops. On this page I’ll explain the main idea behind them. It’s actually a system of composable tokens that let you read any code unambiguously.

Operators list

Some available operators (without mentioning all possible compositions between them):

hehohahulolulayiyoyayuypysyioyaiyokyokl

(In case you want to get an information about any operator, you don’t have to go here, just use a search bar - it works.)

Formula

Operators could be decomposed into simpler glyps (just like hanzi). This is a simplified formula to bake a working operator:

backtick + functor type + argument type + kleisli? + backtick

Varieties

Since everything in Я is built on natural transformations (well, there are rare unnatural ones), we operate on a notion of functors. To bake an operator we need too choose the type of a functor and its argument.

Functor types:

(  ) - [H]om functor
(`li`) - [L]imit functor
(`yi`) - [Y]oneda functor

Argument types:

(  ) - , [I]dentity
(`ho`) - o, c[O]variant position
(`ha`) - a, contr[A]variant position
(`hu`) - u, factor through [U]nit object
(`hd`) - d, left a[D]junction
(`hj`) - j, right ad[J]unction

Argument types, but only for Yoneda functors (monoidal):

(`p`) - p, target is [P]roduct
(`s`) - s, target is [S]um

Argument types, but only for Hom functors:

(`he`) - Cast to a supertype

We can try to combine them together:

(yu) - `hu`
(la) - `la`
(ho) - `ho`
(yi) - `yi`
(la) - `lu`
(hd) - `hd`
(yj) - `yj`
(li) - `li`
(yp) - `yp`

Additionaly, we can add Kleisli arrows (but only for Yoneda functors):

 (yok) - `yok`
(yakl) - `yakl`

Associativity

All operators are left associative. It means that you will read the code from left to right as you get used to (until you are from Middle East region).

Composition

Many operators are composed from other ones, you need to put ' between them. You are free to try to compose any operators to each other - highly likely you’re going to succeed.

      (ya) - `ya`
      (yo) - `yo`
   (ya'yo) - `ya'yo`
   (yo'ya) - `yo'ya`
   (ya'ya) - `ya'ya`
   (yo'yo) - `yo'yo`
(ya'yo'yo) - `ya'yo'yo`
(yo'ya'yo) - `yo'ya'yo`
(ya'ya'yo) - `ya'ya'yo`
(yo'yo'yo) - `yo'yo'yo`
(ya'yo'ya) - `ya'yo'ya`
(yo'ya'ya) - `yo'ya'ya`
(ya'ya'ya) - `ya'ya'ya`
(yo'yo'ya) - `yo'yo'ya`

Precedence

The length of the symbol define its precedence. Longer glyphs takes less precedence. So it will be easily to figure out how expressions are related to each other visually.

How to calculate precedence? Here is the formula:

10 - operator length = precedence

In case of operators composition like ho’yokl take the first operator precedence - ho which is 9.

If you want to decrease precedence of any operator - just add _ symbol to the end, and it should be expanded visually:

       (ha) - `ha`         (9)
      (ha_) - `ha_`        (8)
     (ha__) - `ha__`       (7)
    (ha___) - `ha___`      (6)
   (ha____) - `ha____`     (5)
  (ha_____) - `ha_____`    (4)
 (ha______) - `ha______`   (3)
(ha_______) - `ha________` (2)

Type operators

To make code look more readable, there are some type operators you can use as well:

  (a `AR` o) ~ (AR a o)
 (t `T'I` i) ~ (T'I t i) ~ (t i)
 (i `I'T` t) ~ (I'T i t) ~ (t i)
(t `JNT` tt) ~ (JNT t tt)
 (e `LM` ee) ~ (Product e ee)
 (e `ML` ee) ~ (Sum e ee)
(e `T'TT'I` ee) ~ (T'TT'I e ee)
(e `TT'T'I` ee) ~ (TT'T'I e ee)