Data and the Outside World
All of this is built in; no imports: is needed. lp9 build links only the libraries inference found a use for.
The names and answers follow Lambda Prelude. Where they differ, it is mostly that reading what somebody else wrote answers a Maybe instead of stopping the program.
Files and Processes
File read:, File write:contents:, File append:contents:, File listDir: and the rest. A path that cannot be read or written stops the program.
File open: answers a file held open for reading and writing (a FileHandle), with what an append-only log needs:
- No position.
readAt:size:says where to read, andappend:finds the end and writes there. Reading never moves where the next write lands. tryLocktakes an exclusive lock on the whole file without waiting, and answers false when it is held.ensure:closes it.
Child processes are OS exec: (runs to the end and answers the exit code, standard output and standard error), OS spawn: (answers the pid at once), OS running: and OS kill:. On Windows the children get no console window.
Databases
SQLite is built in. For PostgreSQL and for MariaDB and MySQL, LP-9 speaks each protocol itself, so nothing is put beside the executable. All three answer the same selectors.
db := DB open: 'orders.db'.
db exec: 'INSERT INTO orders (name, due, price) VALUES (:name, :due, :price)'
with: { name: 'stainless bar', due: (Date y: 2026 m: 10 d: 28), price: 1840.00s }.
rows := db query: 'SELECT name, price FROM orders WHERE due <= :d' with: { d: Date today }.
rows do: [ :r | ((r at: 'name') orElse: '(null)') displayNl ].
Parameters are named. :name becomes the connection's own placeholder (? on SQLite, $1 on PostgreSQL) and binds its value with its own type. A name the statement uses that is not given, and one given that it does not use, are both errors, so a misspelt key is found rather than bound as NULL.
A row's columns are Maybe[Str], and SQL NULL reads as absent.
withTx: commits if the block answers, rolls back if it fails, and lets the failure travel on. It works on SQLite and PostgreSQL alike.
PostgreSQL authenticates with SCRAM-SHA-256, and sslmode=require verifies the certificate. MariaDB takes mysql_native_password and MySQL 8's caching_sha2_password.
Two-Way SQL
A statement whose directives are SQL comments, so it runs as it is in a database tool, and render: turns it into the statement and its parameters. The language is Doma's, ported from Lambda Prelude's TORM.
Object subclass: #Find fields: (ids, active).
sql := SqlTemplate parse: 'SELECT id FROM users WHERE id IN /*ids*/(1, 2)
/*%if active */ AND active = 1 /*%end*/'.
r := sql render: (Find fields: { ids: #[ 3, 4, 5 ], active: true }) dialect: 'postgres'.
r text displayNl. "... IN ($1, $2, $3) AND active = 1"
(sql render: (Find fields: { ids: #[ 9 ], active: false }) dialect: 'sqlite') text displayNl.
"... IN (?)"
A WHERE whose conditions all fall away goes with its keyword. dao: makes methods from a directory of SQL files, and entity: ties a table to a class. Both are expanded as the file loads, so a template that does not parse stops the program before it runs.
Network
TCP connect:port:, TCP listen:, TLS wrapClient:host:, Http get:, Http post:body:contentType:.
- IPv6 beside IPv4; a connect tries addresses in Happy Eyeballs order (RFC 8305).
- TLS 1.2 and 1.3, client side, with the certificate checked against the system store.
- One deadline covers connecting, the handshake and every read of an HTTP request (30 seconds by default); the body is capped at 16 MiB by default.
- A call waits where it is made, and the other actors on that domain wait with it; put the actor that talks to the network on a worker domain to keep a screen drawing.
JSON and MessagePack
Json parse: answers a Maybe[Json], so text that is not JSON does not stop the program. A Json is one node of the document, and a leaf is read with the method for the type the program expects.
(Json parse: '{"name": "Alice", "total": 1234.50}') ifPresent: [ :o |
(o at: 'name') stringValue displayNl.
(o at: 'total') asDecimal displayNl ]. "1234.50"
The type of what is read is written where it is read, so everything computed from it is checked. A number with a point reads with asDecimal as an exact amount, and keeps its digits through a file and back; a Decimal is written as a string.
MsgPack parse: and MsgPack serialize: handle the same documents in MessagePack.
Tools for Text
Regexreads Perl syntax and answers as OCaml'sredoes. There are no back-references and no look-around, and a match takes time in proportion to the text.Hash:sha256:,sha512:,hmacSha256:key:,crc32:.Base64: the standard and the URL-safe alphabets; what cannot be read answers absent.Zlibwrites and reads a zlib stream.
The Clipboard and Images
Clipboard text and Clipboard text: s. Clipboard image reads the PNG a program put there, or else the bitmap of a screenshot.
Image decode: reads a PNG and answers Maybe[Image]; png writes one. Paint image:x:y:w:h: stretches a picture to a rectangle, and a copy at another size is made once and kept. A picture is an immutable value, so a description holding the same picture is the same piece and an unchanged region is not drawn again.
Dates and Times
Date, DateTime, Instant and TimeZone are in Design. To a database and to JSON, a Date goes as 2026-10-09 and an Instant as RFC 3339 in UTC with three fraction digits always, so the texts sort as the moments do.