Shoddy Documentation

Quick Reference

Every builtin word, type, and syntax form — plus a map of the machines.

Case-insensitive; convention is PascalCase for words and types, camelCase for variables. Indexes are 1-based: counting starts at 1. Everything is immutable — values never change; "update" words return new values. Every word on this page is built into the mill. The standard library (the machines, brought in with Include) is mapped in The machines below; each machine’s full word reference lives on its own page.

Program structure

FormMeaning
Def Name(p As t, ...) As rFunction, expression-syntax body. Last value = result; no RETURN. Implicit binding of parameters.
Def Name ( a b -- c )Function, concatenative (stack) body; the signature is documentation. ( a b -- c ) reads: takes a and b off the stack, leaves c — inputs before the dashes, outputs after.
Def Main()Entry point.
Type Name ↵ fieldsRecord declaration: indented field As Type lines. Declare before use.
Type Name = v1(f, ...) | v2Sum type: each variant is a constructor/pattern. Bare variant = zero fields (construct as v2()).
Include "FILE.SHODDY"Include-once, left margin. Resolved relative to the including file, then SHODDYLIB, then the machine library beside the running mill. A file from a machine library is a machine: you get the words it declares, not the ones it includes in turn, and it is built if it has no DLL. One of your own files is spliced flat.
Include "FILE.SHODDY" As QEverything that file declares gets the prefix Q — and nothing it includes in turn, so a name never depends on its dependencies' include lists.
Name In QThe namespaced name — collapses to the single word QName. Only needed when a bare name is ambiguous between two namespaces.
Redef Name(...)Def with the duplicate/builtin check waived. Without it, redeclaring a name or shadowing a builtin is an error.
Rem ...  or  ' ...Comment to end of line.
F(a,↵ b)Line continuation: unclosed ( { [ pulls the next line in. Continuation indent is free; parenthesize any long expression to wrap it.
Let x = exprImmutable binding; one per name. At the left margin: a program-wide constant, evaluated once before Main (the outermost scope).

Indentation is structure. A line with an unclosed bracket continues onto the next physical line (continuation indent is free); a statement may also continue on deeper-indented lines (pipelines). Reserved characters, never in names: ! % # $ ? ; \ Operators need spaces around them: count + 1, not count+1.

Types

TypeNotes
NumberA 64-bit floating-point number (what most languages call a double; IEEE); the only numeric type. Exact for whole numbers up to 253.
StringImmutable. Escapes: \" \\ \n \t \r
BooleanTrue / False. Never a number.
Quotation [ t -- u ]Function value; closes over its environment (lexical) — it remembers the variables from where it was written.
List Of tA cons list — a linked list; literal { 1, 2, 3 }. Walk it front to back (recurse).
Array Of tFixed length; Nth jumps straight to position k (O(1)). Index into these.
records (Type)Nominal — matched by type name, not by shape; constructor + accessors + With + Case patterns.

Annotations are parsed, but checked only when the program runs. Type variables: single lowercase letters (t, u).

Operators (loose → tight)

LevelOperatorsNotes
1OrShort-circuit in expression bodies: the right side runs only if the answer is still open. Strict words in stack bodies: both sides have already run.
2And
3= <> < > <= >=Numbers or strings; = / <> also booleans, records (structural), arrays.
4+ - && is string concatenation.
5* / ModDivision / Mod by zero abort.
6^Groups from the right (right-assoc); -n ^ 2 = -(n^2) (classic BASIC).
prefixNot, unary -

Conditionals & matching

If cond Then            Select Case expr
    result                  Case 0                  ' equality
Else                        Case 1, 2, 3            ' any-of
    other                   Case 4 To 10            ' inclusive range
                            Case Is > 10            ' comparison (Is optional)
Ifte(c, t, f)  ' inline     Case Person(n, a) Where a < 18   ' destructure + guard
                            Case Order(Person(n, _), it, t)  ' patterns nest; _ = ignore
                            Case Else               ' default (else non-match aborts)

Both are expressions: each branch/clause block yields the value. The tested value is evaluated once. Pattern names bind for guard and body; sub-patterns nest to any depth. Case Type(...) is always a pattern; equality vs a record: Case = Type(...) (or bare Case None for a zero-field variant).

Function values

FormMeaning
NameBare non-local name in argument position is passed, not called: Map(xs, Square)
>=(100)Section: operator with trailing args pre-loaded = [ 100 >= ]
Fn(x, ...) => exprInline lambda.
[ words ]Raw quotation (stack code).
Call(f, a, b)Apply f to a, b (≡ a b f Call).
(Name)Parenthesize to force a bare name to evaluate instead of quote.

The big four (+ friends)

WordMeaning
Map(xs, f)New sequence, f applied to each. Keeps input's kind.
Filter(xs, p)Keep items where p is True.
Fold(xs, z, f)Combine items into one value, left to right, starting from z (a left fold): Fold(xs, 0, +) sums.
Each(xs, f)Run f per item (for effects).
Times(n, f)Run f n times.
Range(a, b)List of a..b inclusive.

Lists & arrays

WordMeaning
{ a, b, c }List literal (elements are expressions).
First / Rest / Prepend(x, xs) / IsEmptyList recursion kit (First/IsEmpty also arrays).
Nth(xs, k)k-th item; instant on arrays (O(1)).
SetNth(xs, k, v)Copy with position k = v.
Length / Reverse / ConcatBoth kinds (Concat: same kind).
Sort(xs)Ascending; all numbers or all strings. Keeps input's kind.
ToArray / ToListConvert.
Dim(n, v)Array of n copies of v.

Records

FormMeaning
Person("ann", 34)Constructor, positional (arity checked).
Person(Name = "ann", Age = 34)Constructor, named fields.
Age(p)Accessor: every field name is a function. Dispatches on the record's type.
With(p, Age = 35, ...)Copy with fields changed.
P1 = P2Structural equality: equal when all fields are equal.

Strings

WordMeaning
&Concatenate.
Len(s)Length.
Left / Right(s, n)First / last n chars.
Mid(s, START, n)n chars from START (1-based).
Instr(s, SUB)Position of SUB, 0 if absent.
InstrFrom(s, SUB, FROM)The same, searching from FROM onward without copying the tail. A FROM past the end is 0, not an error.
Upper / Lower(s)Case conversion.
Str(n) / Val(s)Number ↔ string. Val stops the program on a non-number.
IsNumeric(s)True exactly when Val(s) would succeed.
ValOr(s, FALLBACK)Val that hands back FALLBACK instead of stopping.
Chr(n) / Asc(s)Code ↔ character.
CodeAt(s, k)Code of the k-th character. Refuses past the end, where Mid would trim — this is how you read a character, not Asc(Mid(s, k, 1)).
Codes(s) / FromCodes(a)Whole string ↔ Array Of Number, exactly. FromCodes can build a NUL, which Chr cannot.

Split, Join, Trim, Replace, StartsWith, EndsWith, StrRep — and IsBool/ToBool/ToBoolOr/ToBoolOpt, PadLeft/PadRight/PadZero, ToFixed, Commas: str.shoddy. All of those are literal; matching on a stated rule instead — RxRead, RxFind, RxFindAll, RxReplace, RxSplit, RxQuote — is regex.shoddy. Every error and warning message, with causes and fixes: the errors page.

Absence and failure

Predeclared by the language. No Include, and no accessor words — Select Case is the only way in, so the check cannot be skipped.

Some(v) / None()Type Option = Some(Value) | None. Absence when the only possible reason is "not there".
Ok(v) / Err(why, at)Type Result = Ok(Value) | Err(Why, At). Failure the caller could act on. At is 0 when there is no position.
Case Some(x) / Case NoneMatching. Building an empty variant takes parentheses, matching one does not.
Some(1) = Some(1)True — variants compare structurally, and None() = None() too.

There is no Value(o): an accessor on a sum type is partial — defined for one variant only — so it would compile and then fail at run time on the very case the type exists to make you handle. Pick Option when the reason is always the same and Result when it isn't.

Math

WordMeaning
Abs Min Max
Sqr(n)Square root (negative aborts).
Floor Ceil Round
Sin Cos Tan AtnRadians.
Exp LogLog is natural log.
Pi()3.14159... — zero-argument function, not a bare constant.
NegateSign flip (what unary - compiles to).
Sgn(n) / Fix(n)Sign (-1, 0, 1) / truncate toward zero.
Asin Acos Atn2(y, x)Inverse trig; Atn2 recovers the full-circle angle.
Tanh(x)Hyperbolic tangent — saturates to ±1, never overflows.
Log10(n)Base-10 log.
Wrap(a, b)Floored modulo: result carries b's sign (angles, indexes).
Erf(x)Error function — the curve behind normal (bell-curve) probabilities.
GammaP(a, x)Regularized lower incomplete gamma — the curve behind the chi-square test's probabilities (its CDF).
BetaI(a, b, x)Regularized incomplete beta — the curve behind the t and F tests' probabilities (their CDFs).
RndUniform [0,1): evenly spread from 0 up to, not including, 1. Impure.
Seed(n)Make Rnd reproducible.

There are no bitwise operators and no integer type. Number bases, bit operations, masks and fields, two's complement, the codes and truth tables are all words in bool.shoddy.

Time

WordMeaning
Ticks()Monotonic (only ever counts up) milliseconds, fractional — for measuring, never wall time.
Sleep(ms)Yield the thread for ms.
Clock()Wall clock now → 7-element Array: year, month, day, hour, minute, second, ms.

Elapsed, TimeIt, SleepUntil, Stamp, DateOf, TimeOf, FormatDuration: clock.shoddy.

I/o, errors, testing

WordMeaning
Print(v)Any value + newline. Effectful — it acts on the world outside the program; keep in Main.
Input(prompt)Print prompt, read a line → String.
InputLine(prompt)As Input, but → a 2-element Array [atEof, text]: Nth(r, 1) is True only at genuine end of stream, Nth(r, 2) is the line. Tells EOF apart from a blank line, which Input cannot.
InKey()One pending keystroke → String, "" if none. Non-blocking, no echo; arrows and PF1–4 arrive as VT100 application-mode sequences for EvalKey.
Error(MSG)Abort with message + line number.
Assert(COND, MSG)Abort unless COND.
ReadFile(path)Whole file → String (missing file aborts).
TryReadFile(path)ReadFile that reports failure instead of aborting → Result: Ok(text), or Err(why, 0) with why = CANNOT READ 'path' (…) ending NO SUCH FILE / IS A DIRECTORY / ACCESS DENIED / UNREADABLE. The only way to ask whether a path can be read.
WriteFile(path, s)Write, overwriting.
TryWriteFile(path, s)WriteFile that reports failure instead of aborting → Boolean. The only way to ask whether a path can be written.
AppendFile(path, s)Append.
FileExists(path)→ Boolean.
DeleteFile(path)Remove the file.
TryDeleteFile(path)DeleteFile that reports failure instead of aborting → Boolean. True if the file went; False if it was not there or could not be removed. FileExists narrows that window without closing it — a file that exists can still be locked when the delete lands.
Args()→ List Of String; program's command-line arguments.

Line-oriented I/O — ReadLines, WriteLines, AppendLine: file.shoddy.

Binary random-access files

1-based byte positions; GET/PUT advance the position. Fixed field sizes make record offsets computable: Name(12) + Score(8) = 20-byte records, record k at 1 + (k-1)*20.

WordMeaning
BOpen(path)→ handle. Read/write, creates if absent; up to 16 open.
TryTcpRequest(host, port, secure, msg)The whole request/response as one guarded word: connect, optionally TLS, send, read to the end of the reply, close → Result. Ok(reply), or Err(why, 0) with why = CANNOT REACH 'host:port' (…) ending NETWORK IS DISABLED / NO SUCH HOST / REFUSED / TIMED OUT / TLS HANDSHAKE FAILED… No socket is ever visible, and it cannot hang — the read is deadline-bounded, unlike net.shoddy's RecvAll.
TryScribblerOpen(w, h)ScribblerOpen that reports failure instead of aborting → Result: Ok(slot), or Err(why, 0) with why = CANNOT OPEN A WINDOW (…). Answers a slot number, not a window, so a reckoner seed can keep one in its named resource table — an ordinary program takes the window from ScribblerOpen and never sees a slot.
ScribblerOf(n)The window a slot names. For the seed that holds the slot; aborts on one that is not open.
ScribblerShut(n)Close the window a slot names and free the slot → Boolean. False for a slot already let go, so closing twice cannot end the run.
NetAllowed()→ Boolean; whether the mill was started with --allow-net. The one word in the socket family that is not gated — the question has to stay askable when the answer is no, since every other TCP word aborts when the network is off.
TryTcpConnect(host, port)TCPConnect that reports failure instead of aborting → Result: Ok(handle), or Err(why, 0) with why = CANNOT REACH 'host:port' (…) ending NETWORK IS DISABLED / TOO MANY OPEN SOCKETS / TIMED OUT / NO SUCH HOST OR REFUSED. Lets a word connect, ask and close inside its own body without a mistyped hostname ending the run.
TryBOpen(path)BOpen that reports failure instead of aborting, and opens an existing file only → Result: Ok(handle), or Err(why, 0) with why = CANNOT OPEN 'path' (…) ending NO SUCH FILE / IS A DIRECTORY / ACCESS DENIED / UNREADABLE / TOO MANY OPEN FILES. The only way to pre-flight a binary read: BOpen creates the file when it is missing, so asking with BOpen changes the very thing you asked about.
BClose(h)Close.
Seek(h, pos)Move to byte pos (1-based).
BPos(h) / BSize(h)Current position / file size in bytes.
PutNum(h, n) / GetNum(h)8-byte IEEE double.
PutBool(h, b) / GetBool(h)1 byte.
PutStr(h, s, Len)Fixed Len-byte field, zero-padded; over-length aborts.
GetStr(h, Len)Read Len bytes, padding stripped.

Reading past end of file aborts. All effectful, like Print. Record-at-a-time helpers — GetRec, PutRec, AppendRec, AllRecs: recio.shoddy. The same words also serialize whole values — a header (magic, counts), then the payload — as in neural.shoddy’s NetSaveBin/NetLoadBin; guide chapter 10 teaches both uses.

TCP/IP sockets — gated (--allow-net)

Handles are Numbers, like file handles (up to 16 open). Payloads are Strings, one byte per character (the Latin-1 convention). Every readiness op is non-blocking: Recv yields "" when nothing has arrived, Accept yields 0 when no client waits — poll (optionally around Sleep). Off unless the mill is run with --allow-net.

WordMeaning
TCPConnect(host, port)→ handle. Connects (bounded 10s handshake); aborts if unreachable.
TCPListen(host, port)→ handle. Binds an IP literal ("127.0.0.1" for loopback, "0.0.0.0" for any).
TCPAccept(h)→ connection handle, or 0 if none is waiting. Non-blocking.
TCPSend(h, s)Send all bytes of s.
TCPRecv(h, max)Up to max bytes → String; "" when nothing pending or the peer closed.
TCPEof(h)→ Boolean. True once the peer has closed (tells "" apart from "no data yet").
TCPPoll(h)→ Boolean. Would Recv/Accept find something now?
TCPPeer(h)→ remote "ip:port", or "".
TCPClose(h)Shut down and close.
TCPSecure(h, host)Upgrade a connected socket to TLS in place; host drives SNI and certificate name validation. A secured handle then reads blocking and TCPPoll refuses it.

All effectful, like Print. Friendly client/server helpers — Connect, SendLine, RecvAll, Request, HttpGet, Listen, Serve1: net.shoddy.

Scribbler — graphics window

A pixel buffer in a window; y grows downward, colours are r,g,b 0–255. Every word returns the scribbler (or its answer) — rebind Let sc = ... and chains read functionally. Nothing shows until Blit. The window needs mill run/mill dap; ScribblerOpen aborts under bare dotnet.

WordMeaning
ScribblerOpen(w, h)→ handle; opens the window.
ScribblerClose(sc)Close (idempotent — closing twice is safe).
ScribblerTitle(sc, s)Window title.
ScribblerPixel(sc, x, y, r, g, b)The one drawing primitive.
ScribblerGetPixel(sc, x, y)→ 3-element Array r,g,b (out of bounds reads 0,0,0).
ScribblerFill(sc, r, g, b)Flood the whole buffer.
ScribblerText(sc, x, y, scale, r, g, b, s)8×8 font text, integer scale.
ScribblerWidth / ScribblerHeight(sc)Buffer size.
ScribblerBlit(sc)Push the buffer to the window — draw whole frame, blit once.
ScribblerPoll / ScribblerWait(sc)→ raw 8-element event array (kind 0 = none; Wait blocks at zero CPU). Use NextEvent/PeekEvent instead.
ScribblerSetInterval(sc, ms)Tick events every ms (0 = off) — prefer SetFps.
ScribblerSave(sc, path)Write the buffer to path as a PNG. Consults no window and does not blit — saving and showing are separate requests. Alpha is dropped.
ScribblerPlace(sc, x, y)Ask for the window's top-left corner at desktop pixel x, y. A request, not a command.

Typed events (ScribblerEvent, NextEvent, PeekEvent, SetFps) and drawing words (DrawLine, FillRect, FillCircle, DrawPolygon, FloodFill): scribbler.shoddy.

Sound

Channels 1–8. Never blocks, never fails the program: audible under mill run/mill dap; silent no-op headless (woven output via bare dotnet, no audio device). Bad arguments raise even in silence.

WordMeaning
Sound(freq, ms)Fire-and-forget blip, anonymous voice pool (pool full: oldest stolen, silently).
NoteOn(ch, freq)Hold freq on channel ch until NoteOff. On a sounding channel: retune in place, no re-attack.
NoteOff(ch)Release the held note (nothing held: no-op).
SoundQueue(ch, freq, ms)Append to ch's queue; notes play back-to-back, sample-accurate. freq 0 = rest. >5 min queued ahead aborts.
SoundQueued(ch)→ ms already queued ahead on ch, 0 once drained. The only way to see that cap coming — measure your score, add this, and refuse before queueing rather than after.
SoundStop(ch)Silence now: release held note, flush queue.
SoundGain(ch, vol)Channel volume 0–1, sticky until set again.
SoundWave(ch, wave)Channel timbre, sticky: 0 square (default), 1 triangle, 2 sine. Re-voices a held note in place; the Sound pool is square only.

Notes and music — MidiFreq, NoteFreq, MmlNotes, Play(ch, mml): buzzer.shoddy.

The machines — standard library map

Bring a machine in with Include "machines/NAME.shoddy" (or compile it once with mill machine). This is the map; each page carries the machine’s full word reference, a user’s guide, and examples — start at the machines index.

Graphics & interaction

MachineWhat it gives you
buzzerSound — note names, MIDI numbers, and a GW-BASIC-subset MML player over the Sound/NoteOn/SoundQueue builtins.
keysPhysical-key classification — raw key codes folded into friendly GameKeys for hotkeys and game controls.
scribblerA pixel-buffer drawing surface in a window, over the Scribbler* builtins — the event decoder and shape-drawing layer.
terminalThe raw console words — Print, Input, InputLine, InKey and Args. Documentation only: it declares nothing, because all five are builtins.
turtlePurely functional turtle graphics — a Turtle value threaded through the program, drawing into a scribbler.
vt100VT100 terminal escape codes — cursor movement, colour, and clearing.

Core numerics

MachineWhat it gives you
boolThe binary layer — number bases, bit operations, masks and fields, two's complement, the codes, the logic gates, truth tables and Quine–McCluskey minimisation. Shoddy has no bitwise builtins; this is why you need none.
clockTiming over the Ticks/Sleep/Clock builtins — monotonic measuring and wall-clock stamping.
engEngineering mathematics — trigonometry and hyperbolics, complex numbers, numeric calculus and root-finding, polynomials, number theory, the discrete distributions, units and physical constants.
ephemerisThe sky as arithmetic — sidereal time, altitude and azimuth for any observer, the sun and moon as sky positions, moonrise and phase, and the five naked-eye planets.
geoThe Earth as arithmetic — great-circle distance and bearing, courses, cross-track and crossings, coordinate formats, horizon distance, and the sun's position, rise and set for any point. Pure and sphere-based.
julianThe calendar as arithmetic — the one place the Gregorian leap rules are spelled: dates, serials, the astronomical Julian day, date arithmetic and weekdays.
mathThe derived math layer over the numeric builtins — E, Tau, Log2, LogBase, and friends.

Sequences & text

MachineWhat it gives you
regexRegular expressions as a compiled value — a Pike VM. It never backtracks because backreferences and lookaround are left out, so no input can hang it and none can end the session.
seqSequences — Map/Filter/Fold and friends, over both List and Array.
sinqQuerying a sequence — ordering by a key, grouping, joining, the set words, and a walker for a record graph that holds itself. The half of a query seq and stats could not express.
strString helpers built on Instr/Left/Right/Mid/Len — surgery, boolean conversions, number formatting.

Algebra

MachineWhat it gives you
algSymbolic algebra over an expression type — exact rationals, a parser and printer, differentiation, factorisation, integration, limits and series, and a bridge that turns a formula into a function value.
linLinear algebra over matrix's Matrix — determinants, inverses, systems, rank, the LU/QR/Cholesky factorisations and eigenvalues.
matrixMatrices — dimensioned, flat row-major storage, O(1) access.
sparseMatrices that are mostly zeros — stored by column, a row index and a value per entry and nothing for the gaps. The working form for big thin problems; matrix stays the everyday grid.

Money & finance

MachineWhat it gives you
finFinance: time value of money, loans, appraisal, depreciation, dates and bonds.
moneyExact money — whole cents in a Number, no floating-point drift.

Statistics & machine learning

MachineWhat it gives you
neuralFeed-forward neural networks — one hidden Tanh layer, mini-batch SGD with momentum (learning by many small corrections), gradients as net-shaped values. Two heads over one backward pass: regression on squared error, classification on softmax (scores turned into probabilities) and cross-entropy.
plotterStatistical charts — histogram, bar, pie, box, scatter — stats doing the arithmetic, scribbler doing the drawing.
randomRandom numbers, built on the Rnd builtin — seedless by construction; shuffling and sampling too.
statsStatistics — descriptive measures, correlation and regression, and the classic tests with real p-values from the Erf/GammaP/BetaI builtins.

Markup & data formats

MachineWhat it gives you
csvCSV to RFC 4180, both directions — quoted cells, doubled quotes, line breaks inside a cell, and dialects for tabs, semicolons and comment lines. Rows, or a sheet with named columns, or straight into your own Type.
htmlHTML, forgivingly — implied end tags, void and raw-text elements, an entity table, and the same tree xml builds.
jsonJSON to RFC 8259, both directions — a total reader that returns errors as values, compact and pretty writers, and path navigation.
xmlXML 1.0, both directions — a total reader that returns errors as values, elements, attributes, comments, CDATA and the doctype all kept.

Data & storage

MachineWhat it gives you
dictDictionaries as association lists of Pair — honest, simple key/value lookup.
fileLine-oriented text file I/O, built on the whole-file builtins.
isamIndexed-sequential files — a keyed database over a fixed-record binary file, index kept on disk as a B+tree in a companion .idx file.
recioRecord-oriented binary I/O — fixed-size records and the offset arithmetic that sits under isam.
shakerReversible obfuscation — a four-round Feistel network over a list of Numbers, with a checksum so tampering is caught. Not a cryptosystem.

Networking

MachineWhat it gives you
httpsAn HTTP client over TLS — build a request, fetch it, take the reply apart. The parsing half is pure.
netTCP/IP client and server over the non-blocking TCP* builtins — connect, request/response, and a poll-driven accept loop. Gated behind --allow-net.

Optimization

MachineWhat it gives you
mipInteger programming by branch and bound over simplex — for the answers that have to be whole numbers, with honest sensitivity once the decisions are taken.
mpsReading and writing MPS linear-programming files — the format that feeds simplex.
simplexLinear programming via the simplex method.

Runtime stack

MachineWhat it gives you
cuttleA heterogeneous runtime stack any mill can hold as a value, and the pure algebra over it — Shoddy's own concatenative core, reified.
lineshaftThe language's own control-flow and execution-failure words — Call, Ifte, Error and Assert. Documentation only: it declares nothing, because all four are builtins.
reckonerAn interpreter for whitespace-tokenized RPN lines over cuttle's stack: dictionary, registers, modes, history and the combinators.

Stack dialect

WordEffect
Dup( a -- a a )
Drop( a -- )
Swap( a b -- b a )
Over( a b -- a b a )
Rot( a b c -- b c a )
Nip( a b -- b )
Tuck( a b -- b a b )
Depth( -- n ) stack size
Take A, bPop into immutable names (top → rightmost).
[ code ]Quote without running.
cond If Then / ElsePostfix conditional (indented branches).

Bare Def Name bodies are pure postfix. In Def Name() bodies both dialects mix: adjacency is stack flow.

Desugaring (surface → core)

SurfaceCore
f(A, b)A b f
A + b * cA b c * +
XS Filter(p)XS p Filter
Let x = ee Take x
Map(xs, f)XS [ f ] Map
>=(100)[ 100 >= ]
Fn(x) => body[ Take x body ]
If c Then a Else bc [ a ] [ b ] Ifte
Call(f, A, b)A b f Call
Age(p)p Age