= tis · Subject

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.

FormSyntax
Tall
=> p
q
Wide
=>(p q)
IrregularNone.

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.

FormSyntax
Tall
=| p
q
Wide
=|(p q)
IrregularNone.

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 a
0
> =| 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.

FormSyntax
Tall
=: p1a p1b
p2a p2b
p3a p3b
==
q
Wide
=:(p1a p1b, p2a p2b, p3a p3b q)
IrregularNone.

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 4
b.a 3
==
a
[b=3 c=4]

=, "tiscom"

Expose namespace.

Syntax

Two arguments, fixed.

FormSyntax
Tall
=, p
q
Wide
=,(p q)
IrregularNone.

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.sum
dojo: 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.

FormSyntax
Tall
=. p q
r
Wide
=.(p q r)
IrregularNone.

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 3
a
[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.

FormSyntax
Tall
=- p
q
Wide
=-(p q)
IrregularNone.

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
%here
b=2
%and-perhaps-more
==
> (foo 5)
7

=^ "tisket"

Pin the head of a pair; change a leg with the tail.

Syntax

Four arguments, fixed.

FormSyntax
Tall
=^ p q
r
s
Wide
=^(p q r s)
IrregularNone.

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

FormSyntax
Tall
=< p
q
Wide
=<(p q)
Irregular
p:q

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.

FormSyntax
Tall
=+ p
q
Wide
=+(p q)
IrregularNone.

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 x
42
> =+ [a='foo' b='bar'] a
'foo'

=; "tismic"

Combine a named noun with the subject, possibly with type annotation; inverted order.

Syntax

Three arguments, fixed.

FormSyntax
Tall
=; p
q
r
Wide
=;(p q r)
IrregularNone.

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.

FormSyntax
Tall
=/ p
q
r
Wide
=/(p q r)
IrregularNone.

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=q
r
=+ ^-($=(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.

FormSyntax
Tall
=~ p1
p2
p3
pn
==
Wide
=~(p1 p2 p3 pn)
IrregularNone.

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=@
=< =~ increment
increment
increment
n
==
|%
++ increment
..increment(n +(n))
--
> foo
3

=* "tistar"

Define a deferred expression.

Syntax

Three arguments, fixed.

FormSyntax
Tall
=* p
q
r
Wide
=*(p q r)
IrregularNone.

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.

FormSyntax
Tall
=? p q
r
s
Wide
=?(p q r s)
IrregularNone.

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