CS 498MC Martian Computing at the University of Illinois at Urbana–Champaign
The most fundamental container in Hoon (and Nock) is a cell: [* *]
. There are of course a number of specialty containers you’ve already seen:
core
[battery payload]
: thence doors, gates, etc.list
~[1 2 3]
vase
!>(
@rs.1.0)
, !>(~)
dime
: atom-aura pairContainers are supported to allow the ordered retrieval of information. Fundamentally, we can separate containers by access mode (sequential and random-access). An example of a sequential container would be a list; an example of a random-access container would be an associative array or dictionary—a map
, to Hoon.
Lists are simply rightwards-branching null-terminated sequences. They can be irregularly constructed using ~[1 2 3]
notation or using the :~
colsig rune:
=colormap :~ [135, 59, 97]
[144, 69, 147]
[131, 91, 193]
[103, 123, 220]
[73, 162, 218]
[58, 198, 189]
[71, 223, 145]
[113, 231, 108]
[173, 225, 95]
[233, 213, 117]
==
Access to list elements is accomplished using ++snag
by a zero-indexed convention:
(snag 3 `(list)`colormap)
Sometimes the Hoon typechecker has difficulty identifying a null-terminated tuple as a list. In that case, you may need to cast using the ++list
mold builder or the ++limo
wrapper which adds i
/t
faces. As always, frequently cast your expectations by mold using ^+
ketlus or ^-
kethep.
There are several tools to manipulate, combine, and separate lists and list elements: ++snap
, ++weld
, etc.
There is an ensemble of containers which are frequently used together: maps (key-value treaps); sets (ordered treaps); jars (maps of lists); and jugs (maps of sets).
If you want to look up data by key–value pairs, use the ++my
mold builder to construct a map
.
=alphabet `(map @ta cord)`(my ~[[%alpha 'α'] [%beta 'β'] [%gamma 'γ'] [%delta 'δ']])
To access a particular entry, use the ++get
arm in the following tendentious construction:
(~(get by alphabet) %alpha)
Notice that this returns a unit
, which also permits a bare ~
to be returned in case the entry is empty.
What is going on with that
~(get by alphabet)
bit?Essentially, this lookup needs to resolve to a gate which can accept a sample (the key) and produce a value. These arms in
++by
,++in
, etc., are doors which resolve to gates for key lookup.
To change or insert an entry, use the ++put
arm:
(~(put by alphabet) [%epsilon 'ε'])
(This returns a changed copy; it doesn’t alter the original dictionary.)
A set is a collection of discrete objects.
If you want to track set membership using a set
, use the ++sy
mold builder.
=fibs `(set @rs)`(sy ~[.1 .1 .2 .3 .5 .8 .13 .21])
To check set membership, use ++has
:
(~(has in fibs) .34)
To add or remove an item from a set, use ++put
and ++del
, respectively:
(~(put in fibs) .34)
(~(del in fibs) .1)
Slam a gate on each item in the set with ++run
:
(~(run in fibs) |=(a=@rs (add:rs .1 a)))
Slam a gate across all items in the set with ++rep
:
(~(rep in fibs) add:rs)
A jar is a map of lists. This is used internally for such operations as remembering ship names in order of preference and tracking %unix
events.
A jug is a map of sets. This is frequently used in the metadata store in Gall apps like Chat and Publish.
Once you have a map or a set, what do you do with it? One common technique is to ++turn
on a-map
by a-gate
:
(turn ~(tap in ~(key by a-map)) a-gate)
(turn ~(tap in ~(key by a-map)) a-gate)
That produces a list. If you want to preserve having a map, use ++urn
:
(~(urn by a-map) |=(a=(pair * *) q.a))
(See also ++stir
, the parser-combinator for sequences, which acts as a Map/Reduce algorithm.)
The bomb defusing exercise is a great refresher before we start on Gall next time. It also uses some of the container logic we developed above.
Dawid Ciezarkiewicz ~napter-matnep
has been working on a Hoon introduction, which may be worth your while to peruse as an alternative explanation of many elementary concepts in Hoon.
~napter-matnep
, “Hoon for Regular Programmers”All images in this lesson copyright Moebius.
Create a map of ZIP codes, mapping the ZIP code to a city name. (You may use any source.)
Create a second map of human names paired with ZIP codes (as if extracted from a database).
Demonstrate looking up a human’s city via their ZIP code.