Libraries
what a library is, and the standard libraries at work
Table of Contents
A library is an ordinary X_eTaL file whose exported names are written
with l:; its other names are private to it. A program imports a
library with the u_se< macro, choosing the prefix its names get:
"s:" u_se< "Stats" makes the library's l:m_ean the program's
s:m_ean. The prefix is required, so every name says where it comes
from. Four libraries are built into xetal (their source is in
lib/); a library of your own is imported by its path. Every block
below is run by xetal through ob-xetal, and its result recorded
under it.
Stats
A small statistics library. Its whole source:
⍝# Stats: a small statistics library (a standard library, built into ⍝# xetal). Import it with an alias of your choice: "s:" u_se< "Stats". ⍝# It is a demo library, loaded only by that import: a small subset of ⍝# X_eTaL-libraries' Statistics, which has much more (a program may use ⍝# either). ⍝# Names with l: are exported; the others are private to this file. ⍝# The arithmetic mean, of Int or Float numbers. ⍝# >> "s:" u_se< "Stats" ⍝# >> s:m_ean 2 4 4 4 5 5 7 9 ⍝# 5.0 ˡm̲ean ← [[f̲loat '+ r̲/] ÷ [f̲loat t̲ally]] s̲quare ← { ⍵ × ⍵ } ⍝ private: not visible outside d̲eviations ← [f̲loat − ˡm̲ean] ⍝# The variance: the mean squared deviation from the mean. ⍝# >> "s:" u_se< "Stats" ⍝# >> s:v_ariance 2 4 4 4 5 5 7 9 ⍝# 4.0 ˡv̲ariance ← [ˡm̲ean [s̲quare d̲eviations]] ⍝# The standard deviation: the square root of the variance. ⍝# >> "s:" u_se< "Stats" ⍝# >> s:s_d 2 4 4 4 5 5 7 9 ⍝# 2.0 ˡs̲d ← { (ˡv̲ariance ⍵) ^ 0.5 } ⍝# The range: the largest minus the smallest. ⍝# >> "s:" u_se< "Stats" ⍝# >> s:r_ange 2 4 4 4 5 5 7 9 ⍝# 7 ˡr̲ange ← ['m̲ax r̲/ − 'm̲in r̲/] ⍝ typed: ⍝ l:m_ean := [[f_loat '+ r_/] / [f_loat t_ally]] ⍝ s_quare := { _r * _r } # private: not visible outside ⍝ d_eviations := [f_loat - l:m_ean] ⍝ l:v_ariance := [l:m_ean [s_quare d_eviations]] ⍝ l:s_d := { (l:v_ariance _r) ^ 0.5 } ⍝ l:r_ange := ['m_ax r_/ - 'm_in r_/]
s_quare and d_eviations have no l:, so a program cannot see
them; the rest it imports:
ˢ⁼u̲se< "Stats" ˢm̲ean 1 2 3 4 ⍝ typed: ⍝ "s:" u_se< "Stats" ⍝ s:m_ean 1 2 3 4
2.5
The mean is a Float for Int numbers too. The variance, the standard deviation and the range:
ˢv̲ariance 2 4 4 4 5 5 7 9 ˢs̲d 2 4 4 4 5 5 7 9 ˢr̲ange 3 9 1 7 ⍝ typed: ⍝ s:v_ariance 2 4 4 4 5 5 7 9 ⍝ s:s_d 2 4 4 4 5 5 7 9 ⍝ s:r_ange 3 9 1 7
4.0 2.0 8
Maybe
A value that may be missing, and the monad that chains computations
which can fail. A maybe is Church-encoded: a function of two
arguments, what to give when it is empty and what to do with its
value. j_ust x holds a value, n_othing holds none, and d m:o_r m
is the value, or d when there is none:
ᵐ⁼u̲se< "Maybe" ᵘd̲iv ← { a b → b = 0 ? 'ᵐn̲othing◆ ᵐj̲ust a ÷ b } -1 ᵐo̲r 100 ᵘd̲iv 4 -1 ᵐo̲r 100 ᵘd̲iv 0 ⍝ typed: ⍝ "m:" u_se< "Maybe" ⍝ u:d_iv := { a b -> b = 0 ? 'm:n_othing; m:j_ust a / b } ⍝ -1 m:o_r 100 u:d_iv 4 ⍝ -1 m:o_r 100 u:d_iv 0
25.0 -1.0
b_ind chains a step that can itself fail; the first failure gives
the default, and the steps after it never run:
ᵘh̲alf ← { ᵐj̲ust ⍵ ÷ 2 } -1 ᵐo̲r 'ᵘh̲alf ᵐb̲ind 100 ᵘd̲iv 4 -1 ᵐo̲r 'ᵘh̲alf ᵐb̲ind 100 ᵘd̲iv 0 ⍝ typed: ⍝ u:h_alf := { m:j_ust _r / 2 } ⍝ -1 m:o_r 'u:h_alf m:b_ind 100 u:d_iv 4 ⍝ -1 m:o_r 'u:h_alf m:b_ind 100 u:d_iv 0
12.5 -1.0
Combinators
Every bird Raymond Smullyan names in To Mock a Mockingbird that type-checks, under its letter. K keeps its first argument, C swaps the arguments of a function, and B composes (here negate after reverse):
ᶜ⁼u̲se< "Combinators" 1 ᶜK̲ 2 10 '− ᶜC̲ 3 'n̲eg 'r̲ev ᶜB̲ 1 2 3 ⍝ typed: ⍝ "c:" u_se< "Combinators" ⍝ 1 c:K_ 2 ⍝ 10 '- c:C_ 3 ⍝ 'n_eg 'r_ev c:B_ 1 2 3
1 -7 -3 -2 -1
The aviary meets them all.
Turtle
Turtle graphics as arrays: a walk is a vector of turns in degrees, one
before each step, and its points are running sums of cosines and sines,
two rows (x over y) that []P_ATH draws. Its whole source:
⍝ Turtle: turtle graphics as arrays (a standard library, built into ⍝ xetal). Import it with an alias of your choice: "t:" u_se< "Turtle". ⍝ A walk is a vector of turns in degrees, one before each step forward; ⍝ the turtle starts at the origin facing east (0 degrees, counting ⍝ anticlockwise). No turtle moves: the headings are a running sum of ⍝ the turns, the steps are their cosines and sines, and the positions ⍝ are running sums of the steps. Draw the points with []P_ATH. r̲adians ← { (f̲loat ⍵) × (p̲i @) ÷ 180 } ⍝ private ⍝ The points of a walk with steps of the given lengths, 2 rows (x over ⍝ y), starting at the origin: lengths ˡw̲alk turns; a single length ⍝ serves every step. ˡw̲alk ← { lengths turns → h ← r̲adians '+ s̲\ turns xs ← 0 c̲at '+ s̲\ (f̲loat lengths) × c̲os h ys ← 0 c̲at '+ s̲\ (f̲loat lengths) × s̲in h (2 c̲at t̲ally xs) r̲eshape xs c̲at ys } ⍝ The points of a walk of unit steps. ˡp̲oints ← { turns → 1 ˡw̲alk turns } ⍝ The walk with t degrees more turned before its first step: how pieces ⍝ of a curve are joined (60 ˡt̲urn w). ˡt̲urn ← { t w → (t + 1 t̲ake w) c̲at 1 d̲rop w } ⍝ A regular polygon of n sides, as a walk. ˡp̲olygon ← { n → n r̲eshape 360 ÷ n } ⍝ typed: ⍝ r_adians := { (f_loat _r) * (p_i @) / 180 } # private ⍝ l:w_alk := { lengths turns -> ⍝ h := r_adians '+ s_\ turns ⍝ xs := 0 c_at '+ s_\ (f_loat lengths) * c_os h ⍝ ys := 0 c_at '+ s_\ (f_loat lengths) * s_in h ⍝ (2 c_at t_ally xs) r_eshape xs c_at ys ⍝ } ⍝ l:p_oints := { turns -> 1 l:w_alk turns } ⍝ l:t_urn := { t w -> (t + 1 t_ake w) c_at 1 d_rop w } ⍝ l:p_olygon := { n -> n r_eshape 360 / n }
A square, one unit a side, its points rounded (the cosine of a right angle is only nearly 0):
ᵗ⁼u̲se< "Turtle" ᵗp̲olygon 4 f̲loor 0.5 + ᵗp̲oints ᵗp̲olygon 4 ⍝ typed: ⍝ "t:" u_se< "Turtle" ⍝ t:p_olygon 4 ⍝ f_loor 0.5 + t:p_oints t:p_olygon 4
90.0 90.0 90.0 90.0 0 0 -1 -1 0 0 1 1 0 0
Classic programs, drawn uses it for Koch's snowflake and Sierpinski's arrowhead.
TTTML
A machine that learns tic-tac-toe by playing itself: its model is an ordinary value, passed to the library's functions and returned by them. TTTML trains it and plays it.
A library of your own
Hello, library writes one and uses it. In short:
write the exported names with l: and save the file; a program then
imports it by name from beside it, or by its path, "g:" u_se< "lib/Geometry.xtl". In the live
demo, Save as a name like Geometry.xtl keeps it in the browser, and
"g:" u_se< "Geometry" imports it; saved under a standard library's
name (Stats.xtl), your copy is the one imported. A library cannot
define u: names, and a program cannot define l: names.