Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

A lab with names in it

A laboratory notebook works because every sample has a label: you can point at it, ask about it, and know later which answer came from which sample. The REPL is that kind of lab. Every sample, and every question you ask about one, has a name, and the kernel keeps track of which answers came from what.

This chapter’s sample is the recorded week of earthquakes. Every cell below runs in this page’s kernel, so there is nothing to install: press Run. The commands are the same ones the ikigai REPL takes, and the last section runs a few of them at a shell.

1. The sample has a name

urn:file:quakes-2024-01-01.geojson is the recorded week. Before reading it, ask what it is. describe asks a resource to describe itself, and text/plain asks for the description in words:

quakes-window — A recorded week of earthquakes
USGS earthquakes of M4.5 and up from 2024-01-01 to 2024-01-08, 178 events, as GeoJSON, recorded once and never changed: the window "Exploring without Rust" runs on.
verbs: Source, Meta
[computed]

It answers Source (it can be read) and Meta (it can describe itself), and nothing else: in this page the recorded week cannot be changed. The last line is the verdict: the kernel computed this description rather than finding it in its cache.

Reading the whole thing would print 125,765 bytes of GeoJSON, which is a lot of text to scroll past. So the next section asks a question instead.

2. A question is a resource too

urn:json:query is a resource that answers a question about another resource. It takes the name of the thing to read (src) and a question written in jq (q). This chapter uses only small questions; Reshaping JSON with jq is about the language. How many earthquakes does the week hold, and what is the first one in the file?

178
[computed]
M 5.1 - 77 km ESE of Fangale’ounga, Tonga
[computed]

USGS lists the newest first, so the first is the last earthquake of the week, in Tonga. as=text/plain asks for the answer as plain text rather than as JSON, so the title comes back without quotation marks.

Nothing about the question is special to this file. src is any name the kernel can read, and the query reads it through the kernel, with the same permissions you have.

3. A pipe

| hands one answer to the next resource as its input. Here the place of the first earthquake goes to urn:iki:fn:toUpper, which capitalizes text:

77 KM ESE OF FANGALE’OUNGA, TONGA
[2 computed]

Two resolutions: the question, then toUpper over its answer. toUpper knows nothing about earthquakes or JSON. It takes text, and the pipe gives it text.

4. A map

Many resources in ikigai treat their input as a list, one item per line. .. runs the next resource once for each line and joins the answers. This question asks for the places of the first three earthquakes, one per line (join("\n") is jq for “one per line”; inside the quoted program, \" is a quotation mark), and maps toUpper over them:

77 KM ESE OF FANGALE’OUNGA, TONGA
BALLENY ISLANDS REGION
BALLENY ISLANDS REGION
[2 cached · 2 computed]

Look at the tally: four resolutions, the question and three calls to toUpper, and two of them were cached. Two earthquakes in a row were in the Balleny Islands region, so the map asked toUpper the same question twice, and the second time the kernel already had the answer. And the Tonga place is the one the pipe above capitalized, so that answer was already there too. That is the cache at work with no instruction from you: an answer is kept under the name and the arguments that produced it, and the same request finds it.

5. A fork

( a ; b ) sends the same input to each branch and joins the answers in order:

77 KM ESE OF FANGALE’OUNGA, TONGA
BALLENY ISLANDS REGION
BALLENY ISLANDS REGION
Balleny Islands region
Balleny Islands region
77 km ESE of Fangale’ounga, Tonga
[1 cached · 2 computed]

reverseList reverses the order of the lines. The question itself was cached by the cell above, which is why this tally counts it as cached.

6. What a question read

trace resolves a request and shows what it did: who asked, with what authority, and every resource it read on the way, each with its own verdict. Ask a question this page has not asked yet, the earliest earthquake of the week (the last in the file):

trace  urn:json:query
  client      ikigai repl  ·  capability: root (full authority)
  transport   embedded · in-process
 
urn:json:query   json-query · computed · ThreadId(1) · — · answered-by=urn:iki:space:json   → 54b  "M 4.7 - 272 km N of Saipan, Northern Ma…
└─ urn:file:quakes-2024-01-01.geojson   quakes-window · cached · ThreadId(1) · —

The query was computed, and the line under it is the recorded week, which the query read and found in the cache. The — is where a duration would go; this page’s kernel has no clock (the kernel in the browser says why). No one told the kernel that this question depends on that file. It saw the query read it, and it remembers. Trace a question that is already cached and the tree stops at the top: nothing was read.

7. What hangs from the sample

That memory has a name too. Every cached answer hangs from one or more threads: named dependencies the kernel can cut. Reading the recorded week hangs the answer from the thread named after the file, and anything computed from that answer hangs from it as well. urn:kernel:dependents lists what hangs from a thread:

dependents of urn:file:quakes-2024-01-01.geojson  (cut 0 times)
  10 live cached entries hang from it — a cut makes them stale, and the next read of each recomputes it
  urn:file:quakes-2024-01-01.geojson  application/geo+json       122.8 KB  1 thread    root
  urn:iki:fn:reverseList              text/plain                     81 B  3 threads   root
  urn:iki:fn:toUpper                  text/plain                     22 B  3 threads   root
  urn:iki:fn:toUpper                  text/plain                     35 B  3 threads   root
  urn:iki:fn:toUpper                  text/plain                     81 B  3 threads   root
  urn:json:query                      application/json                3 B  2 threads   root
  urn:json:query                      application/json               54 B  2 threads   root
  urn:json:query                      text/plain                     35 B  2 threads   root
  urn:json:query                      text/plain                     43 B  2 threads   root
  urn:json:query                      text/plain                     81 B  2 threads   root
[uncacheable]

Every question this chapter asked is there, and so is every toUpper answer computed from one: they all depend on the file, whether they read it directly or through another answer.

Now cut the thread. A cut says “this changed”: every answer that hangs from it becomes stale, and the next request for it is computed again. cache asks whether an answer is in the cache without computing anything:

cached
cut urn:file:quakes-2024-01-01.geojson
[uncacheable]
not cached
178
[computed]

The answer is the same, 178, because the recorded week did not really change. At a shell it can: write to the file and the write cuts the thread for you, or edit it with another program, and the CLI notices and cuts it. Golden threads in practice is the chapter on threads.

8. The same lab at a shell

Everything above works in the ikigai REPL too, against the copy you downloaded in A week of earthquakes. The REPL also has resources this page does not, such as the text tools under urn:text:, which work like their Unix namesakes. USGS’s file puts each earthquake on a line of its own, so grep and wc can already count them. In the REPL you started with --files ~/quakes, type the lines after each ikigai> (the prompt is the REPL’s, not yours to type). Each answer is printed with its tally:

ikigai> source urn:file:quakes-2024-01-01.geojson | urn:text:wc
178
[1 computed · 1 uncacheable]
ikigai> source urn:file:quakes-2024-01-01.geojson | urn:text:grep pattern=Japan | urn:text:wc
62
[1 cached · 2 uncacheable]
ikigai> source urn:file:quakes-2024-01-01.geojson | urn:text:grep pattern="Noto Peninsula" | urn:text:wc
1
[1 cached · 2 uncacheable]

The book’s checks replay this block against ikigai-cli 0.2.6, over the same file the download fetches, so these answers are the ones you get.

178 lines, one per earthquake. 62 of the lines mention Japan, most of them aftershocks of the New Year’s Day earthquake, and one line names the Noto Peninsula itself: the main shock. Counting lines is a crude way to ask about JSON (a place name in another field would count too), and Reshaping JSON with jq asks the same questions properly.

The 1 computed in the first tally is the file, read once and kept: the later lines found it in the cache, which is their 1 cached. None of the text tools’ answers were kept, which is every uncacheable. The kernel says why, if you ask:

source urn:kernel:uncached

It printed this, on ikigai-cli 0.2.5:

uncached (why a computed read was not cached; the last 64, most recent first)
  urn:text:wc        ×1  one-shot content b3:236f4cfad7f59de75883fed22dcbc1c0c8a7982e0fc989f1d526f0271e335199; upstream  [root]
  urn:text:grep      ×1  one-shot content b3:4b04300f5127c249fc59806380cb1a6ab4e2a4d6c9f2f5997dcc33e09b0be210  [root]
  urn:text:wc        ×1  one-shot content b3:aedbd75b64018f949e9dabc1a83829e1bc9559c7c1877715b2a1eb17e893a1e9; upstream  [root]
  urn:text:grep      ×1  one-shot content b3:4939de7f64f2a335e38e45e1a998737dc6e20fa39b99171c1c8321e1397d7696  [root]
  urn:text:wc        ×1  one-shot content b3:f06db695a3cfc70b1fd99f5e02b5b3528bc5d8589feb3d7403b9fd8a5662232d  [root]

[uncacheable]

The pipe hands each text tool what came before it as a stream, read as it arrives, under a content id made up for that one hand-over (the b3: names, which are new every time, so this block is not replayed with the one above). An answer built on input that can be read only once is never stored (one-shot content), and a wc after a grep was handed a stream that was itself one-shot (upstream). The same tools over a short value typed on the line are cached as usual. This is a gap in the text tools, recorded as ledger #2530, not something to work around: for now, the questions worth caching go through urn:json:query, as the page’s do. (On ikigai-cli 0.2.4 the counts were the same, but a text tool reading the file itself was tallied as computed, and the reason given for it was the cache’s policy.)

Next, the same questions about data that is not yours and not still: Somebody else’s resource.