Skip to content

Data & I/O

Use this when reading or writing files, parsing CSV/JSON, or accessing environment variables. For network I/O see HTTP.

ilo has built-in support for reading and writing files and accessing environment variables. All I/O builtins return R (Result) types, use ! to auto-unwrap.

rd path reads a file with format auto-detected from the extension:

ExtensionReturns
.csvR _ t — list of lists (grid)
.tsvR _ t — list of lists (grid)
.jsonR _ t — parsed JSON value
otherR _ t — raw text string
ilo
load p:t>R _ t;rd p

Force a specific format with a second argument:

ilo
load p:t>R _ t;rd p "json"

rdl path reads a file as a list of lines:

ilo
lines p:t>R L t t;rdl p

rdb string format parses a string in a given format - useful for data received from HTTP responses:

ilo
parse s:t>R _ t;rdb s "json"

lsd dir returns the entries of dir (filenames only, not full paths), sorted lexicographically. Both file and directory entries are included. Missing directories surface as Err; empty directories return [], not Err.

Renamed from ls in 0.12.1 so the natural ls=rdl! p binding for “lines” stays free for user code.

ilo
entries d:t>R (L t) t;lsd d

walk dir does a depth-first traversal of dir and returns every path it finds relative to dir, sorted. Symlinks are not followed (matches the safer of the two find defaults and avoids the cycle trap that bites recursive globs in symlinked trees).

Unreadable subdirectories (most commonly permission-denied: sandbox roots, sibling-user homes, /var/db on macOS) are silently skipped. The locked dir’s own entry is still in the result; just its contents are not enumerated. This means walk / or walk ~/ produce useful output instead of aborting on the first locked sibling. An unreadable root still returns Err, so “starting point unreadable” is distinguishable from “some descendant unreadable”.

ilo
all p:t>R (L t) t;walk p

glob dir pat returns the paths under dir (relative, sorted) that match a shell-style pattern. */?/[abc] match within a single path segment; ** matches any number of nested segments (including zero), so **/*.ilo finds every .ilo file in the tree, including ones in dir itself. No matches returns [], not Err. Shares walk’s traversal, so unreadable subdirectories are skipped silently here too.

ilo
ilo-files d:t>R (L t) t;glob d "**/*.ilo"
csv-here d:t>R (L t) t;glob d "*.csv"

dirname, basename, and pathjoin are pure-text path operations. No I/O, no Result wrapper, total on all inputs. Unix forward-slash semantics; Windows backslash handling is a 0.13.0 concern.

dirname path returns the POSIX parent directory:

  • dirname "/a/b/c.txt""/a/b"
  • dirname "/""/" (root is its own parent, POSIX)
  • dirname "/a""/" (single-component absolute path)
  • dirname "foo.txt""" (no directory component; POSIX returns "." here, ilo returns "" so the cat round-trip below stays clean)
  • dirname "foo/""" (trailing slash stripped, no directory component remains)
  • dirname """"

basename path returns the POSIX final path segment:

  • basename "/a/b/c.txt""c.txt"
  • basename "/""/" (root is its own basename, POSIX edge)
  • basename "foo/""foo" (trailing slash stripped first)
  • basename """"

pathjoin parts joins a list of segments with /, collapsing duplicate separators at joints and dropping empty segments. The list form (not variadic) avoids the arity-inference trap that fmt’s variadic shape lives with:

  • pathjoin ["a" "b" "c.txt"]"a/b/c.txt"
  • pathjoin ["a/" "/b/" "c.txt"]"a/b/c.txt" (joint slashes deduped)
  • pathjoin []""
  • pathjoin ["foo"]"foo"
  • pathjoin ["/" "a"]"/a" (leading absolute root preserved)
  • pathjoin ["" "a" ""]"a" (empty segments dropped)

Round-trip:

ilo
-- Split a path and rejoin it; the result equals the original.
roundtrip p:t>t;pathjoin [dirname p basename p]

wr path data writes data to a file. Format can be specified as a third argument:

ilo
save>R t t;wr "out.txt" "hello world"

Structured output with format:

ilo
csv>R t t;wr "out.csv" [[1,2],[3,4]] "csv"
json>R t t;wr "data.json" [1,2,3] "json"

env key reads an environment variable, returning R t t:

ilo
home>R t t;env "HOME"

Auto-unwrap with !:

ilo
home>t;env! "HOME"

.env and .env.local files in the working directory are loaded automatically.

FunctionSignatureDescriptionExample
rdbt t > R _ tParse data (format: "json", "csv")rdb data "json"
jptht t > R t tExtract JSON pathjpth data "users.0.name"
jdmp_ > tDump value as JSON stringjdmp [1,2,3]
jpart > R _ tParse JSON string to valuejpar '{"a":1}'
FunctionSignatureDescriptionExample
now> nCurrent Unix timestamp (seconds)now
sleepn > _Pause current engine for ms millisecondssleep 100
dtfmtn t > R t tFormat Unix epoch as text (strftime, UTC)dtfmt 1700000000 "%Y-%m-%d"
dtparset t > R n tParse text to Unix epoch (strftime, UTC)dtparse "2024-01-15" "%Y-%m-%d"

Any function returning R (Result) can be called with ! to auto-unwrap:

ilo
r=$url -- r is R t t (Result)
v=$!url -- v is t (auto-unwrapped, propagates error)
data=rdb! r "json" -- auto-unwrap parse result

See Error Handling for full details on !, ?, ??, and Result types.

Long formShort form
readrd
writewr
readbufrdb