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.

Literate documents · Live demo · Repository