Docs
How i++ works, from one combinator to complex numbers.
The i combinator
i++ has a single primitive: i. It is the universal iota combinator, defined by
one reduction rule:
i x = x S K From that single rule you get the familiar SKI basis. The prelude defines:
I = i i
K = i (i I)
S = i K Once you have S and K, you can build B, C, T, and effectively any other combinator.
Application and grouping
Application is just juxtaposition: writing two terms next to each other applies the left to the right. Parentheses group sub-expressions.
f x y # means ((f x) y)
S (K K) I
i (i I) Definitions and modules
A definition binds a name to a term in the current session:
export ID = i i
ID x
# => x Use export to make a name visible to modules that import this one. Use import Module to load a module.
import Combinators
import Math Numbers
Numeric literals are complex numbers. Real integers, decimals, and imaginary values with j are all supported.
42
-3.14
2.5+4j
-7j The EML operator
When a number is applied to another number, i++ uses the EML binary operator:
a b = exp(a) - ln(b) That single operator is enough to recover exponentials, logarithms, and elementary arithmetic. The trick is choosing the right arguments:
x 1 = exp(x), becauseln(1) = 0. The prelude definesEXP = T 1— it applies its argument to1.1 x = e - ln(x). Wrap it again and the offset cancels:1 ((1 x) 1) = ln(x). That is why the prelude definesLN = B (B 1 EXP) 1.- Subtraction falls out directly:
(LN x) (EXP y) = x - y.
The underlying idea comes from EML — All elementary functions from a single binary operator.
Examples
import Combinators
import Math
EXP 1 # e
LN E # 1
(LN 5) (EXP 3) # 2
S K K x # x