Change Subject = ('tis')

    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.

    Runes

    => "tisgar"

    [%tsgr p=hoon q=hoon]: compose two expressions.

    Produces

    the product of q, with the product of p taken as the subject.

    Syntax

    Regular: 2-fixed.

    Examples
    > =>([a=1 b=2 c=3] b)
    2
    
    > =>((add 2 4) [. .])
    [6 6]
    

    =| "tisbar"

    [%tsbr p=spec q=hoon]: combine a default type value with the subject.

    Expands to
    =+(*p q)
    
    Syntax

    Regular: 2-fixed.

    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
    ~zod:dojo> =foo  |=  a=@
                     =|  b=@
                     =-  :(add a b c)
                     c=2
    ~zod:dojo> (foo 5)
    7
    

    =: "tiscol"

    [%tscl p=(list (pair wing hoon)) q=hoon]: change multiple legs in the subject.

    Expands to
    =>(%_(. p) q)
    
    Syntax

    Regular: jogging, then 1-fixed.

    Discussion

    This rune is like =., but for modifying the values of multiple legs of the subject.

    Examples
    ~zod:dojo> =+  a=[b=1 c=2]
               =:  c.a  4
                   b.a  3
                 ==
               a
    [b=3 c=4]
    

    =, "tiscom"

    [%tscm p=hoon q=hoon]: expose namespace

    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). This is especially useful for calling arms from an imported library core or for calling arms from a stdlib core repeatedly.

    Syntax

    Regular: 2-fixed.

    Examples

    With an imported core:

    > (sum -7 --7)
    -find.sum
    [crash message]
    
    > (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"

    [%tsdt p=wing q=hoon r=hoon]: change one leg in the subject.

    Expands to
    =>(%_(. p q) r)
    
    Syntax

    Regular: 3-fixed.

    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"

    [%tshp p=hoon q=hoon]: combine a new noun with the subject, inverted.

    Expands to
    =>([q .] p)
    
    Syntax

    Regular: 2-fixed.

    Discussion

    =- is just like =+ but its subexpressions are reversed. =- looks better than =+ when the expression you're pinning to the subject is much smaller than the expression that uses it.

    Examples
    ~zod:dojo> =foo  |=  a=@
                     =+  b=1
                     =-  (add a b c)
                     c=2
    ~zod:dojo> (foo 5)
    8
    

    =^ "tisket"

    [%tskt p=skin q=wing r=hoon s=hoon]: pin the head of a pair; change a leg with the tail.

    Expands to
    =/(p -.r =.(q +.r s))
    
    Syntax

    Regular: 4-fixed.

    Discussion

    p is a new name (possibly with type annotation, e.g., a=@) of a value to be pinned to the subject. The value of p is the head of the product of r. q is given the value of the tail of r's product. Then s is evaluated against this new subject.

    We generally use =^ when we have a state machine with a function, r, that produces a cell, whose head is a result and whose tail is a new state. The head value is given a new name p, and the tail is stuffed back into wherever we stored the old state, q.

    This may also remind you of Haskell's State monad.

    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"

    [%tsgl p=hoon q=hoon]: compose two expressions, inverted.

    Expands to
    =>(q p)
    
    Syntax

    Regular: 2-fixed.

    Irregular: foo:baz is =<(foo baz).

    Discussion

    =< is just => backwards.

    Examples
    ~zod:dojo> =<(b [a=1 b=2 c=3])
    2
    
    ~zod:dojo> =<  b
               [a=1 b=2 c=3]
    2
    
    ~zod:dojo> b:[a=1 b=2 c=3]
    2
    
    ~zod:dojo> [. .]:(add 2 4)
    [6 6]
    

    =+ "tislus"

    [%tsls p=hoon q=hoon]: combine a new noun with the subject.

    Expands to
    =>([p .] q)
    
    Syntax

    Regular: 2-fixed.

    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

    =; "tismic"

    [%tsmc p=skin q=hoon r=hoon]: combine a named noun with the subject, possibly with type annotation; inverted order.

    Expands to
    =/(p r q)
    
    Syntax

    Regular: 3-fixed.

    Discussion

    =; is exactly like =/ except that the order of its last two subexpressions is reversed.

    Examples
    ~zod:dojo> =foo  |=  a=@
                     =/   b  1
                     =;   c=@  :(add a b c)
                     2
    ~zod:dojo> (foo 5)
    8
    

    =/ "tisfas"

    [%tsfs p=skin q=hoon r=hoon]: combine a named noun with the subject, possibly with type annotation.

    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
    
    Syntax

    Regular: 3-fixed.

    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
    ~zod:dojo> =foo  |=  a=@
                     =/  b  1
                     =/  c=@  2
                     :(add a b c)
    ~zod:dojo> (foo 5)
    8
    

    =~ "tissig"

    [%tssg p=(list hoon)]: compose many expressions.

    Produces

    The product of the chain composition.

    Syntax

    Regular: running.

    Examples
    ~zod:dojo> =~  [sub (mul 3 20) (add 10 20)]
          (sub +)
          +(.)
      ==
    31
    
    ~zod:dojo> =foo =|  n=@
                    =<  =~  increment
                            increment
                            increment
                            n
                        ==
                    |%
                    ++  increment
                      ..increment(n +(n))
                    --
    ~zod:dojo> foo
    3
    

    =* "tistar"

    [%tstr p=term q=hoon r=hoon]: define an alias.

    Produces

    r, compiled with a subject in which p is aliased to q.

    Syntax

    Regular: 3-fixed.

    Discussion

    The difference between aliasing and pinning is that pinning changes the subject, but for aliasing the subject noun stays the same. The aliased expression, q, is recorded in the type information of p. q is calculated every time you use the p alias.

    Examples
    ~zod:dojo>
        =+  a=1
        =*  b  a
        [a b]
    [1 1]
    
    ~zod:dojo>
        =+  a=1
        =*  b  a
        =.  a  2
        [a b]
    [2 2]
    

    =? "tiswut"

    [$tswt p=wing q=hoon r=hoon s=hoon]: conditionally change one leg in the subject.

    Expands to
    =.  p  ?:(q r p)
    s
    
    Syntax

    Regular: 4-fixed.

    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