← Back to Blog

Protocols That Refuse to Die

2026-04-19 nicheshowcase

This release is a love letter to protocols that refuse to die. Every module this week speaks to something old, weird, or infrastructural — and every one of them is, again, the first of its kind in the Lateralus ecosystem.

◉ Uniqueness, again — enforced before shipping

- gh api repos/bad-antics/<repo>/contents/<path> → all 5 paths returned 404 - grep -rE 'can_bus|exif|snmp|postscript|sexpr_expand' --include='*.ltl' → zero hits

The five newcomers:

- lateralus-stdlib/hw/can_bus.ltl — CAN 2.0A/B + CAN-FD + ISO-TP + DBC-style signal extraction - lateralus-stdlib/img/exif.ltl — JPEG/TIFF EXIF parser with GPS decode - lateralus-stdlib/net/snmp.ltl — SNMPv2c agent, BER codec, OID trie, UDP loop - lateralus-compiler/macro/sexpr_expander.ltl — hygienic pattern-based macro expander - lateralus-examples/niche/postscript_interpreter.ltl — ~300-line PostScript Level-1

◉ The CAN bus is a feature, not a bug

Classic CAN carries 0-8 bytes per frame at 11 or 29 bits of ID. CAN-FD extends the payload to 64 bytes and adds a bit-rate-switch flag. ISO-TP (ISO 15765-2) turns the 8-byte window into arbitrary-length messages via a 4-frame protocol: Single, First, Consecutive, Flow Control. We ship all of it, plus DBC-style signal extraction so you can write:

let speed_kmh = extract_signal(frame.data, SignalSpec {
    name: "VehicleSpeed", start_bit: 24, length: 16,
    scale: 0.01, offset: 0.0, signed: false, unit: "km/h",
})

◉ EXIF is a TIFF in a JPEG in a trench coat

img/exif.ltl cracks open the APP1 segment of a JPEG, notices the Exif\0\0 magic, then hands the rest to the TIFF parser. The 0th IFD gives you make/model/orientation; the EXIF sub-IFD at tag 0x8769 carries exposure/ISO/lens; the GPS sub-IFD at 0x8825 gets decoded into signed decimal degrees. Vendor MakerNote blobs are surfaced as raw bytes — we won't pretend to know every camera company's private format.

◉ SNMP, because every device still speaks it

The MIB is a prefix trie. Get walks to a node and calls its getter; GetNext does an in-order traversal and emits the first OID greater than the request; Set walks to a node and invokes its setter. Register a metric in one line:

mib_register(&mut root, [1,3,6,1,2,1,1,3,0],
             Some(|| Value::TimeTicks(uptime_cs())),
             None)

Wire up serve_udp("0.0.0.0:161", b"public", &mut root) and snmpwalk works immediately.

◉ S-expression macros for Lateralus

We already have declarative match! macros. compiler/macro/sexpr_expander.ltl adds the bigger hammer: define a pattern (with $x and $xs... variadics) and a template, and the compiler substitutes bindings, hygienically renames every template-introduced identifier with a __gensym<N> suffix, and splices the result back into the AST.

macro! swap($a, $b) => {
    let tmp = $a;
    $a = $b;
    $b = tmp;
}

The tmp above can never capture a tmp at the call site, because the expander gives it a fresh name before splicing.

◉ PostScript Level-1 in ~300 lines

niche/postscript_interpreter.ltl tokenizes, builds procedures with { ... }, maintains an operand stack and a dict stack, and implements the subset of operators needed to draw paths and text: moveto, lineto, closepath, stroke, fill, setlinewidth, show, showpage, plus arithmetic, def, dup, exch, pop. The output is a stream of DrawEvents that a separate renderer turns into SVG or a raster bitmap — the interpreter itself is pure.

72 72 moveto (Hello, world!) show showpage

◉ What's the pattern?

Fifteen modules in a row, zero duplicates. The ecosystem now covers: borrow checking, LSP, GraphQL, WASM, HTTP, capability tracking, FASTA, Game Boy ROMs, LoRa, MIDI, CAN, EXIF, SNMP, macros, and PostScript. The only pattern is that every one of them used pipelines, sum types, and pattern matching to land under 400 lines of code.

That's the pitch.

Try it in the playground

Every snippet on this page runs in your browser. No install, no signup.

▶ Open Playground Star on GitHub