Names are case-insensitive. The convention is PascalCase for words and
types, camelCase for variables. Indexes are 1-based: counting starts at 1.
Everything is immutable: values never change, and “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
| Form | Meaning |
| Def Name(p As t, ...) As r | Function, expression-syntax body. Last value = result; no RETURN. Implicit binding of parameters. |
| Def Name ( a b -- c ) | Function, 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 ↵ fields | Record declaration: indented field As Type lines. Declare before use. |
| Type Name = v1(f, ...) | v2 | Sum type: each variant is a constructor/pattern. Bare variant = zero fields (construct as v2()). Each variant field is also an accessor word, except on the predeclared Option and Result. |
| 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 Q | Everything 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 Q | The namespaced name. It 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 = expr | Immutable binding: a name's value never changes. A later Let of the same name inside a body makes a new binding that hides the earlier one. Anything that already captured the earlier one keeps it. At the left margin: a program-wide constant, evaluated once before Main (the outermost scope). A repeated Let there is a duplicate-definition error. |
| Self-call in last position | A Def that calls itself as its last step runs in constant stack: the call becomes a loop. Two Defs that call each other do not, and use stack on every call. |
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
| Type | Notes |
| Number | A 64-bit floating-point number (what most languages call a double; IEEE); the only numeric type. Exact for whole numbers up to 253. |
| String | Immutable. Escapes: \" \\ \n \t \r |
| Boolean | True / False. Never a number. |
| Quotation [ t -- u ] | Function value. It closes over its environment: it remembers the variables from where it was written. |
| List Of t | The sequence for recursion. Literal { 1, 2, 3 }. Rest and Prepend copy the list, so a First/Rest walk slows down sharply on a long list. To visit every item, use Fold or Map, or ToArray once and index with Nth. |
| Array Of t | Fixed 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 and Case patterns. |
Annotations are documentation. The mill reads them and never checks them. Each operation checks its own operands when it runs, so a wrong type stops the program at the first word that cannot use it. Type variables: single lowercase letters (t, u).
Operators (loose → tight)
| Level | Operators | Notes |
| 1 | Or | Short-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. |
| 2 | And |
| prefix | Not | Looser than comparison: Not x = 1 means Not (x = 1). Tighter than And. |
| 3 | = <> < > <= >= | Numbers or strings; = / <> also booleans, records (structural), arrays and lists, item by item: { 1, 2 } = { 1, 2 }. Only functions compare by identity. |
| 4 | + - & | & is string concatenation. |
| 5 | * / Mod | Division / Mod by zero abort. Mod keeps the sign of the left side: -7 Mod 3 is -1. |
| 6 | ^ | Groups from the right (right-associative). -n ^ 2 = -(n^2) (classic BASIC). |
| prefix | 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 Empty ' the empty list
Case Prepend(x, more) ' a list: its head and its tail
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.
To test equality against a record instead: Case = Type(...) (or bare
Case None for a zero-field variant).
Function values
| Form | Meaning |
| Name | Bare non-local name in argument position is passed, not called: Map(xs, Square) |
| >=(100) | Section: operator with trailing args pre-loaded = [ 100 >= ] |
| Fn(x, ...) => expr | Inline 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. |
| Mod(a, b) or -(x * x) | Not a call. In an argument, an operator followed by ( builds a section, so the program fails somewhere else. Write a Mod b and 0 - x * x. |
The big four (+ friends)
| Word | Meaning |
| 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: 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
| Word | Meaning |
| { a, b, c } | List literal (elements are expressions). |
| First / Rest / Prepend(x, xs) / IsEmpty | List recursion kit, O(1) each (First/IsEmpty also arrays). |
| Nth(xs, k) | k-th item; O(1) on arrays, and on lists after the first call. |
| SetNth(xs, k, v) | Copy with position k = v. |
| Length / Reverse / Concat | Both kinds (Concat: same kind). |
| Sort(xs) | Ascending; all numbers or all strings. Keeps input's kind. |
| Taken(xs, n) / DropN(xs, n) | The first n / everything after them (lists). |
| ZipWith(xs, ys, f) | f over the pairs, up to the shorter. |
| Shuffle(xs) / Sample(xs, n) / DropAt(xs, k) | Random order / n distinct draws / without the k-th (random). |
| ToArray / ToList | Convert. |
| Dim(n, v) | Array of n copies of v. |
Records
| Form | Meaning |
Type Person Name As String Age As Number | Declaration, at the left margin, before first use. One indented field per line. As Type on a field is optional. |
| Person("ann", 34) | Constructor, positional (arity checked). |
| Person(Name = "ann", Age = 34) | Constructor, named fields. |
| Age(p) | Accessor: every field name is a function, including the fields of a sum type's variants. Dispatches on the record's type. |
| With(p, Age = 35, ...) | Copy with fields changed. |
| P1 = P2 | Structural equality: equal when all fields are equal, lists included. |
Strings
| Word | Meaning |
| & | Concatenate; O(1), the text is laid down when first read. |
| Len(s) | Length. |
| Split(s, SEP) / Join(xs, SEP) | Cut at every SEP, empties kept / glue with SEP between. |
| 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
match literal text. Matching on a pattern 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 None | Matching. 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 is not.
Math
| Word | Meaning |
| Abs(n) / Min(a, b) / Max(a, b) | Absolute value / the smaller / the larger. Min and Max take exactly two. |
| Sqr(n) | Square root (negative aborts). |
| Floor Ceil Round | Round rounds half up: Round(2.5) is 3, Round(-2.5) is -2. |
| Sin Cos Tan Atn | Radians. |
| Exp Log | Log is natural log. |
| Pi() | 3.14159..., a zero-argument function, not a bare constant. |
| Negate | Sign 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. It saturates to ±1 and 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). |
| Rnd | Uniform [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
| Word | Meaning |
| 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
| Word | Meaning |
| Print(v) | Any value + newline. Effectful: it acts on the world outside the program. Keep it 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 to PF4 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. |
| TryReadLines(path) | The file as its lines → Result: Ok(lines), a List Of String, or the same Err(why, 0) as TryReadFile. \r\n and \n both end a line, a final newline is not an extra empty line, and a file of any length loads. ReadLines in file.shoddy is the aborting form over it. |
| 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.
| Word | Meaning |
| BOpen(path) | → handle. Read/write, creates if absent; up to 16 open. |
| 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 check a binary read in advance: 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 of magic number and 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.
| Word | Meaning |
| 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. |
| TCPConnect(host, port) | → handle. Connects (bounded 10s handshake); aborts if unreachable. |
| 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. |
| 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. |
| 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, and colours are r,g,b
0 to 255. Every word returns the scribbler (or its answer), so rebind
Let sc = ... and chains read functionally. Nothing shows until Blit.
The window needs mill run/mill dap. ScribblerOpen aborts
under bare dotnet.
| Word | Meaning |
| ScribblerOpen(w, h) | → handle; opens the window. |
| 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. |
| ScribblerClose(sc) | Close (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 the 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 to 8. Never blocks, never fails the program: audible
under mill run/mill dap; a silent no-op headless (woven
output via bare dotnet, no audio device). Bad arguments raise an error even
in silence.
| Word | Meaning |
| 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 "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
| Machine | What it gives you |
 | buzzer | Sound: note names, MIDI numbers, and a GW-BASIC-subset MML player over the Sound/NoteOn/SoundQueue builtins. |
 | keys | Physical-key classification: raw key codes folded into friendly GameKeys for hotkeys and game controls. |
 | scribbler | A pixel-buffer drawing surface in a window, over the Scribbler* builtins: the event decoder and shape-drawing layer. |
 | terminal | The raw console words: Print, Input, InputLine, InKey and Args. Documentation only: it declares nothing, because all five are builtins. |
 | turtle | Purely functional turtle graphics: a Turtle value threaded through the program, drawing into a scribbler. |
 | vt100 | VT100 terminal escape codes: cursor movement, colour, and clearing. |
Core numerics
| Machine | What it gives you |
 | bool | The 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. |
 | clock | Timing over the Ticks/Sleep/Clock builtins: monotonic measuring and wall-clock stamping. |
 | eng | Engineering mathematics: trigonometry and hyperbolics, complex numbers, numeric calculus and root-finding, polynomials, number theory, the discrete distributions, units and physical constants. |
 | ephemeris | The 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. |
 | geo | The 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. |
 | julian | The calendar as arithmetic, and the one place the Gregorian leap rules are spelled out: dates, serials, the astronomical Julian day, date arithmetic and weekdays. |
 | math | The derived math layer over the numeric builtins: E, Tau, Log2, LogBase, and friends. |
Sequences & text
| Machine | What it gives you |
 | regex | Regular 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. |
 | seq | Sequences: the helpers around the Map/Filter/Fold builtins (Any, All, CountIf, Append, Zip and friends), over both List and Array. |
 | sinq | Querying 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. |
 | str | String helpers built on Instr/Left/Right/Mid/Len: cutting and joining, boolean conversions, number formatting. |
Algebra
| Machine | What it gives you |
 | alg | Symbolic 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. |
 | lin | Linear algebra over matrix's Matrix: determinants, inverses, systems, rank, the LU/QR/Cholesky factorisations and eigenvalues. |
 | matrix | Matrices: dimensioned, flat row-major storage, O(1) access. |
 | sparse | Matrices 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
| Machine | What it gives you |
 | fin | Finance: time value of money, loans, appraisal, depreciation, dates and bonds. |
 | money | Exact money: whole cents in a Number, no floating-point drift. |
Statistics & machine learning
| Machine | What it gives you |
 | neural | Feed-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. |
 | plotter | Statistical charts (histogram, bar, pie, box, scatter): stats doing the arithmetic, scribbler doing the drawing. |
 | random | Random numbers, built on the Rnd builtin and seedless by construction. Shuffling and sampling too. |
 | stats | Statistics: descriptive measures, correlation and regression, and the classic tests with real p-values from the Erf/GammaP/BetaI builtins. |
Markup & data formats
| Machine | What it gives you |
 | csv | CSV 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. |
 | html | HTML, forgivingly: implied end tags, void and raw-text elements, an entity table, and the same tree xml builds. |
 | json | JSON to RFC 8259, both directions: a total reader that returns errors as values, compact and pretty writers, and path navigation. |
 | xml | XML 1.0, both directions: a total reader that returns errors as values, elements, attributes, comments, CDATA and the doctype all kept. |
Data & storage
| Machine | What it gives you |
 | dict | Dictionaries as association lists of Pair: simple key/value lookup. |
 | file | Line-oriented text file I/O, built on the whole-file builtins. |
 | isam | Indexed-sequential files: a keyed database over a fixed-record binary file, with the index kept on disk as a B+tree in a companion .idx file. |
 | recio | Record-oriented binary I/O: fixed-size records and the offset arithmetic that sits under isam. |
 | shaker | Reversible obfuscation: a four-round Feistel network over a list of Numbers, with a checksum so tampering is caught. Not a cryptosystem. |
Networking
| Machine | What it gives you |
 | https | An HTTP client over TLS: build a request, fetch it, take the reply apart. The parsing half is pure. |
 | net | TCP/IP client and server over the non-blocking TCP* builtins: connect, request/response, and a poll-driven accept loop. Gated behind --allow-net. |
Optimization
| Machine | What it gives you |
 | mip | Integer programming by branch and bound over simplex: for the answers that have to be whole numbers, with sensitivity once the decisions are taken. |
 | mps | Reading and writing MPS linear-programming files: the format that feeds simplex. |
 | simplex | Linear programming via the simplex method. |
Runtime stack
| Machine | What it gives you |
 | cuttle | A heterogeneous runtime stack any mill can hold as a value, and the pure algebra over it: Shoddy's own stack core, as a value you can hold. |
 | lineshaft | The language's own control-flow and execution-failure words: Call, Ifte, Error and Assert. Documentation only: it declares nothing, because all four are builtins. |
 | reckoner | An interpreter for whitespace-tokenized RPN lines (reverse Polish notation: values first, then the operator) over cuttle's stack: dictionary, registers, modes, history and the combinators. |
Stack dialect
| Word | Effect |
| 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, b | Pop into immutable names (top → rightmost). |
| [ code ] | Quote without running. Words and literals only: If, Then, Else and Take are refused inside. Use Ifte. |
| cond If Then / Else | Postfix conditional (indented branches). |
Bare Def Name bodies are pure postfix.
In Def Name() bodies both dialects mix: adjacency is stack flow.
Desugaring (surface → core)
| Surface | Core |
| f(A, b) | A b f |
| A + b * c | A b c * + |
| XS Filter(p) | XS p Filter |
| Let x = e | e Take x |
| Map(xs, f) | XS [ f ] Map |
| >=(100) | [ 100 >= ] |
| Fn(x) => body | [ Take x body ] |
| If c Then a Else b | c [ a ] [ b ] Ifte |
| Call(f, A, b) | A b f Call |
| Age(p) | p Age |