macro librarylib/Combinators.xtlm
Combinators as macros: the birds of the Combinators library written in at compile time instead of applied when the program runs. Import both under one alias: "c:" u_se< "Combinators" finds Combinators.xtl (c:Y_, c:B_, ...) and this file (c:Y_<, c:B_<).
Recursion
ᵐY̲< : Char -> Char -> Char
Define the function named on the left by the lambda on the right, whose first parameter is the function itself: the knot c:Y_ ties when the program runs is tied here, by writing the name in place of the self parameter. The result is plain named recursion, with no lazy parameter and no combinator left to run.
ᶜ⁼u̲se< "Combinators"
"u:f_act" ᶜY̲< "{ ~s_elf n -> n <= 1 ? 1; n * s_elf n - 1 }"
ᵘf̲act 5 120
ᵐY̲< ← { name lambda → n̲ot ⎕S̲TATEMENT @ ? "misplaced-macro call" ⎕R̲EJECT "c:Y_< defines a function: it stands as a statement of its own" t ← t̲rim lambda a ← w̲here "->" s̲tarts t (n̲ot "{" m̲atch 1 t̲ake t) ∨ (0 = t̲ally a) ? "bad-macro-argument right" ⎕R̲EJECT yShape ps ← w̲ords ((f̲irst a) − 2) t̲ake 1 d̲rop t 2 > t̲ally ps ? "bad-macro-argument right" ⎕R̲EJECT yShape self ← s̲trip d̲isclose f̲irst ps rest ← j̲oin '{ p → " " c̲at d̲isclose p } m̲ap 1 d̲rop ps body ← ((f̲irst a) + 1) d̲rop t (t̲rim name) c̲at " := {" c̲at rest c̲at " ->" c̲at (self w̲ord t̲rim name)_ body }
Composition
ᵐB̲< : Char -> Char -> Char
The function on the left applied to the result of the one on the right, as one lambda written in place (the Bluebird, B f g x = f (g x)); either may be a name, a derived function or a lambda.
ᶜ⁼u̲se< "Combinators"
ᵘs̲umTo ← "'+ r_/" ᶜB̲< "r_ange"
ᵘs̲umTo 4 10
ᵐB̲< ← { f g → "{ " c̲at (t̲rim f) c̲at " " c̲at (t̲rim g) c̲at " _r }" }
yShape : Char
yShape ← "c:Y_< takes a lambda whose first parameter is the function itself: { s_elf n -> ... }"
t̲rim : Char -> Char
t̲rim ← { t → m ← n̲ot t m̲ember? " \n\t" 0 = '+ r̲/ 0 + m ? "" i ← w̲here m (1 + (f̲irst r̲ev i) − f̲irst i) t̲ake ((f̲irst i) − 1) d̲rop t }
j̲oin : Box Char -> Char
j̲oin ← { b → d̲isclose '{ x y → e̲nclose (d̲isclose x) c̲at d̲isclose y } r̲/ b }
s̲tarts : (Num a, Truthy a) => Char -> Char -> a
s̲tarts ← { w t → '{ i → w m̲atch (t̲ally w) t̲ake (i − 1) d̲rop t } e̲ach r̲ange t̲ally t }
nameChars : Char
nameChars ← "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_:"
w̲ord : Char -> Char -> Char -> Char
w̲ord ← { w r t → n ← t̲ally w e ← " " c̲at t c̲at " " ok̲ ← { i → (i + n − 1) > t̲ally t ? 0◆ n̲ot ((i s̲elect e) m̲ember? nameChars) ∨ (i + n + 1) s̲elect e m̲ember? nameChars } h ← (w s̲tarts t) ∧ 'ok̲ e̲ach r̲ange t̲ally t c ← 0 < ('+ s̲\ 0 + h) − '+ s̲\ 0 + (n r̲eshape 0) c̲at (0 − n) d̲rop 0 + h p̲ ← { i → (i s̲elect h) ? r◆ (i s̲elect c) ? ""◆ i s̲elect t } j̲oin 'p̲ m̲ap r̲ange t̲ally t }