These runes modify the subject. (Or more precisely, they evaluate at least one of their subexpressions with a modified subject.)
Overview
Hoon doesn't have variables in the ordinary sense. If you want to bind a name to a value, e.g., a
to 12
, you do so by pinning 12
to the subject and associating the name with it. This sort of operation is done with the =
family of runes.
Let's say you have some old subject p
. To 'pin' a value to the head means to modify the subject by repacing it with a cell of [new-value p]
. The head of the cell is the new value. So to pin 12
with the face a
the new subject would be: [a=12 p]
.
Of course there are many variations on ways to modify the subject, useful for different situations. Hence the whole family of =
runes.
=>
"tisgar"
Compose two expressions.
Syntax
Two arguments, fixed.
Form | Syntax |
---|---|
Tall |
|
Wide |
|
Irregular | None. |
AST
[%tsgr p=hoon q=hoon]
Produces
the product of q
, with the product of p
taken as the subject.
Examples
> =>([a=1 b=2 c=3] b)2> => 9 .9> =>((add 2 4) [. .])[6 6]> =>|%++ foo|= [a=@ b=@][b a]--(foo 42 27)[27 42]
=|
"tisbar"
Combine a named noun with the subject by "bunting" (producing the default value) of a given mold.
Syntax
Two arguments, fixed.
Form | Syntax |
---|---|
Tall |
|
Wide |
|
Irregular | None. |
AST
[%tsbr p=spec q=hoon]
Expands to
=+(*p q)
Discussion
The default (or 'bunt') value of p
is pinned to the head of the subject. Usually p
includes a name for ease of reference.
Speaking more loosely, =|
usually "declares a variable" which is "uninitialized," presumably because you'll set it in a loop or similar.
Examples
> =| a=@ud a0> =| a=[@t @t @t] a['' '' '']
=:
"tiscol"
Change multiple legs in the subject.
Syntax
Two arguments: the first a variable number of pairs, the second is fixed.
Form | Syntax |
---|---|
Tall |
|
Wide |
|
Irregular | None. |
AST
[%tscl p=(list (pair wing hoon)) q=hoon]
Expands to
=>(%_(. p) q)
Discussion
This rune is like =.
, but for modifying the values of multiple legs of the subject.
Examples
> =+ a=[b=1 c=2]=: c.a 4b.a 3==a[b=3 c=4]
=,
"tiscom"
Expose namespace.
Syntax
Two arguments, fixed.
Form | Syntax |
---|---|
Tall |
|
Wide |
|
Irregular | None. |
AST
[%tscm p=hoon q=hoon]
Produces
p
evaluates to a noun with some namespace. From within q
you may access p
's names without a wing path (i.e., you can use face b
rather than b.p
).
Discussion
This is especially useful for calling arms from an imported library core or for calling arms from a stdlib core repeatedly. For example, JSON reparsers like so:dejs:format
and of:dejs:format
can be called as so
and of
after doing:
=, dejs:format
Examples
With an imported core:
> (sum -7 --7)-find.sumdojo: hoon expression failed> (sum:si -7 --7)--0> =, si (sum -7 --7)--0
With a dojo-defined face:
> =/ fan [bab=2 baz=[3 qux=4]]=, fan[bab qux.baz][2 4]
=.
"tisdot"
Change one leg in the subject.
Syntax
Three arguments, fixed.
Form | Syntax |
---|---|
Tall |
|
Wide |
|
Irregular | None. |
AST
[%tsdt p=wing q=hoon r=hoon]
Expands to
=>(%_(. p q) r)
Discussion
Technically the =.
rune doesn't change the subject. It creates a new subject just like the old one except for a changed value at p
. Note that the mutation uses %_
("cencab"), so the type at p
doesn't change. Trying to change the value type results in a nest-fail
.
Examples
> =+ a=[b=1 c=2]=. b.a 3a[b=3 c=2]> =+ a=[b=1 c=2]=.(b.a 3 a)[b=3 c=2]> =+ a=[b=1 c=2]=.(b.a "hello" a)nest-fail
=-
"tishep"
Combine a new noun with the subject, inverted.
Syntax
Two arguments, fixed.
Form | Syntax |
---|---|
Tall |
|
Wide |
|
Irregular | None. |
AST
[%tshp p=hoon q=hoon]
Expands to
=>([q .] p)
Discussion
=-
is just like =+
but its subexpressions are reversed. =-
looks better than =+
when the expression you're pinning to the subject is much larger than the expression that uses it.
Examples
> =foo |= a=@=- (add a b):* %a-bunch%of-stuff%hereb=2%and-perhaps-more==> (foo 5)7
=^
"tisket"
Pin the head of a pair; change a leg with the tail.
Syntax
Four arguments, fixed.
Form | Syntax |
---|---|
Tall |
|
Wide |
|
Irregular | None. |
AST
[%tskt p=skin q=wing r=hoon s=hoon]
Expands to
=/(p -.r =.(q +.r s))
Discussion
p
is a new name (optionally with type) to pin to the subject.q
is the name of an existing wing of the subject.r
is an expression that produces[p-value new-q-value]
.s
is some more code to be evaluted against the modified subject.
This is a bit like doing =/
and =.
at the same time. It's useful for state machines, where you want to produce both effects and a new state. For example, many arms of a Gall agent produce [effects new-state]
in the form of a (quip card _this)
. In the ++on-poke
arm, you might have something like:
=^ cards state(handle-poke !<(action vase))[cards this]
This may also remind you of Haskell's State monad.
Note that =^
is subject to the same type nesting limitations as =.
; e.g., if you have ?~
checked a list for null, you can no longer nest a regular list in the result. (In this case, use ?:(=(~ ...))
instead to preserve the list
rather than produce a lest
.)
Examples
The og
core is a stateful pseudo-random number generator. We have to change the core state every time we generate a random number, so we use =^
:
~zod:dojo> =+ rng=~(. og 420)=^ r1 rng (rads:rng 100)=^ r2 rng (rads:rng 100)[r1 r2][99 46]
=<
"tisgal"
Compose two expressions, inverted.
Syntax
Two arguments, fixed
Form | Syntax |
---|---|
Tall |
|
Wide |
|
Irregular |
|
AST
[%tsgl p=hoon q=hoon]
Expands to
=>(q p)
Discussion
=<
is just =>
backwards.
Examples
> =<(b [a=1 b=2 c=3])2> =< b[a=1 b=2 c=3]2> b:[a=1 b=2 c=3]2> [. .]:(add 2 4)[6 6]
=+
"tislus"
Combine a new noun with the subject.
Syntax
Two arguments, fixed.
Form | Syntax |
---|---|
Tall |
|
Wide |
|
Irregular | None. |
AST
[%tsls p=hoon q=hoon]
Expands to
=>([p .] q)
Discussion
The subject of the =+
expression, call it a
, becomes the cell [p a]
for the evaluation of q
. That is, =+
'pins a value', p
, to the head of the subject.
Loosely speaking, =+
is the simplest way of "declaring a variable."
Examples
> =+ 42 -42> =+ x=42 x42> =+ [a='foo' b='bar'] a'foo'
=;
"tismic"
Combine a named noun with the subject, possibly with type annotation; inverted order.
Syntax
Three arguments, fixed.
Form | Syntax |
---|---|
Tall |
|
Wide |
|
Irregular | None. |
AST
[%tsmc p=skin q=hoon r=hoon]
Expands to
=/(p r q)
Discussion
=;
is exactly like =/
except that the order of its last two subexpressions is reversed.
Examples
> =foo |= a=@=/ b 1=; c=@:(add a b c)2> (foo 5)8
=/
"tisfas"
Combine a named noun with the subject, possibly with type annotation.
Syntax
Three arguments, fixed.
Form | Syntax |
---|---|
Tall |
|
Wide |
|
Irregular | None. |
AST
[%tsfs p=skin q=hoon r=hoon]
Expands to
if p
is a name, (e.g. a
):
=+(^=(p q) r)
if p
is a name with a type (e.g., a=@
):
=+(^-(p q) r)
Desugaring
?@ p=+ p=qr=+ ^-($=(p.p q.p) q)r
Discussion
p
can be either a name or a name=type
. If it's just a name, =/
("tisfas") "declares a type-inferred variable." If it has a type, =/
"declares a type-checked variable."
Examples
> =/ a=@t 'hello' a'hello'> =/ x [1 2 3] x[1 2 3]> =foo |= a=@=/ b 1=/ c=@ 2:(add a b c)> (foo 5)8
=~
"tissig"
Compose many expressions.
Syntax
Variable number of arguments.
Form | Syntax |
---|---|
Tall |
|
Wide |
|
Irregular | None. |
AST
[%tssg p=(list hoon)]
Produces
The product of the chain composition.
Examples
> =~ 10[20 .][30 .][40 .].==[40 30 20 10]> =~ [sub (mul 3 20) (add 10 20)](sub +)+(.)==31> =foo =| n=@=< =~ incrementincrementincrementn==|%++ increment..increment(n +(n))--> foo3
=*
"tistar"
Define a deferred expression.
Syntax
Three arguments, fixed.
Form | Syntax |
---|---|
Tall |
|
Wide |
|
Irregular | None. |
AST
[%tstr p=term q=hoon r=hoon]
Produces
r
, compiled with a subject in which p
is a deferred expression for q
.
Discussion
=*
assigns a name to an expression that will be evaluated in each place the name is dereferenced. This allows you to "write" through it to the original subject axis
. q
is recorded in the type information of p
, and q
is calculated every time you use p
.
This rune has some similarities with macros, and some similarities with aliases, but it is not really either.
This rune is commonly used to give a Gall agent's state the name state
like:
=* state -
This lets you reference the whole state
while also being able to reference its individual elements like foo
and bar
, without having to do foo.state
, bar.state
, etc.
Examples
> =+ a=1=* b a[a b][1 1]> =+ a=1=* b a=. a 2[a b][2 2]
=?
"tiswut"
Conditionally change one leg in the subject.
Syntax
Four arguments, fixed.
Form | Syntax |
---|---|
Tall |
|
Wide |
|
Irregular | None. |
AST
[%tswt p=wing q=hoon r=hoon s=hoon]
Expands to
=. p ?:(q r p)s
Discussion
Use =?
to replace the value of leg p
with r
on condition q
. As usual, we are not actually mutating the subject, just creating a new subject with a changed value. The change in value includes a type check against the old subject; the type of r
must nest under the type of p
.
Examples
> =a 12> =?(a =(1 1) 22 a)22> =?(a =(1 2) 22 a)12