Make ; ('mic')

    Miscellaneous useful macros.

    Runes

    ;: "miccol"

    [%mccl p=hoon q=(list hoon)]: call a binary function as an n-ary function.

    Expands to

    Pseudocode: a, b, c, ... as elements of q:

    Regular form:

    %-(p a %-(p b %-(p c ...)))
    

    Irregular form:

    (p a (p b (p c ...)))
    
    Desugaring
    |-
    ?~  q  !!
    ?~  t.q  !!
    ?~  t.t.q
      (p i.q i.t.q)
    (p i.q $(q t.q))
    
    Syntax

    Regular: 1-fixed, then running.

    Irregular: :(add a b c) is ;:(add a b c).

    Examples
    ~zod:dojo> (add 3 (add 4 5))
    12
    
    ~zod:dojo> ;:(add 3 4 5)
    12
    
    ~zod:dojo> :(add 3 4 5)
    12
    

    ;+ "miclus"

    make a single XML node (Sail)

    Produces

    A marl, i.e., a list of manx. A manx is a noun that represents a single XML node.

    Syntax

    1-fixed

    ;+  p=hoon
    

    p is a Hoon expression that produces a manx.

    Discussion

    tl;dr -- ;+ converts a manx to a marl.

    ;+ is a Sail rune. Sail is a part of Hoon used for creating and operating on nouns that represent XML nodes. With the appropriate rendering pipeline, a Sail document can be used to generate a static website. See the Sail tutorial.

    In Sail a single XML node is represented by a manx. A single <p> node manx can be produced in the following way:

    > ;p: This will be rendered as an XML node.
    [[%p ~] [[%$ [%$ "This will be rendered as an XML node."] ~] ~] ~]
    

    Sometimes what is needed is a marl, i.e., a list of manx. To convert a single manx to a marl, use the ;+ rune.

    One interesting thing about Sail is that it allows you to use complex Hoon expressions to choose from among several nodes to render. The ;+ rune can take such a complex expression.

    Examples
    > ^-  marl
      ;+  ?:  (gth 3 2)
            ;p: This is the node for 'yes'.
          ;p: This is the node for 'no'.
    ~[
      [ g=[n=%p a=~]
        c=[i=[g=[n=%$ a=~[[n=%$ v="This is the node for 'yes'."]]] c=~] t=~]
      ]
    ]
    
    > ^-  marl
      ;+  ?:  (gth 2 3)
            ;p: This is the node for 'yes'.
          ;p: This is the node for 'no'.
    ~[
      [ g=[n=%p a=~]
        c=[i=[g=[n=%$ a=~[[n=%$ v="This is the node for 'no'."]]] c=~] t=~]
      ]
    ]
    

    ;; "micmic"

    [%mcmc p=spec q=hoon]: normalize with a mold, asserting fixpoint.

    Expands to
    =+  a=(p q)
    ?>  =(`*`a `*`q)
    a
    

    Note: the expansion implementation is hygienic -- it doesn't actually add the a face to the subject.

    Syntax

    Regular: 2-fixed.

    Examples

    Fails because of auras:

    ~zod:dojo> ^-(tape ~[97 98 99])
    ! nest-fail
    ! exit
    

    Succeeds because molds don't care about auras:

    ~zod:dojo> ;;(tape ~[97 98 99])
    "abc"
    

    Fails because not a fixpoint:

    ~zod:dojo> ;;(tape [50 51 52])
    ! exit
    

    ;/ "micfas"

    [%mcnt p=hoon]: tape as XML element.

    Expands to
    ~[%$ ~[%$ 'p']]
    
    Examples
    ~zod/try=> :/"foo"
    [[%~. [%~. "foo] ~] ~]
    

    ;~ "micsig"

    [%mcsg p=hoon q=(list hoon)]: glue a pipeline together with a product-sample adapter.

    Produces

    The gates in q are composed together using the gate p as an intermediate function, which transforms a q product and a q gate into a q sample.

    Expands to

    Note: these are structurally correct, but elide some type-system complexity.

    ;~(a b) reduces to b.

    ;~(a b c) expands to

    |=  arg=*
    (a (b arg) c(+6 arg))
    

    ;~(a b c d) expands to

    |=  arg=*
    %+  a (b arg)
    =+  arg=arg
    |.  (a (c arg) d(+6 arg))
    
    Desugaring
    ?~  q  !!
    |-
    ?~  t.q  i.q
    =/  a  $(q t.q)
    =/  b  i.q
    =/  c  ,.+6.b
    |.  (p (b c) a(,.+6 c))
    
    Discussion

    Apparently ;~ is a "Kleisli arrow." It's also a close cousin of the infamous "monad." Don't let that bother you. Hoon doesn't know anything about category theory, so you don't need to either.

    ;~ is often used in parsers, but is not only for parsers.

    This can be thought of as user-defined function composition; instead of simply nesting the gates in q, each is passed individually to p with the product of the previous gate, allowing arbitrary filtering, transformation, or conditional application.

    Syntax

    Regular: 1-fixed, then running.

    Examples

    A simple "parser." trip converts a cord (atomic string) to a tape (linked string).

    ~zod:dojo> =cmp |=([a=tape b=$-(char tape)] `tape`?~(a ~ (weld (b i.a) t.a)))
    ~zod:dojo> ;~(cmp trip)
    <1.zje {a/@ <409.yxa 110.lxv 1.ztu $151>}>
    ~zod:dojo> (;~(cmp trip) 'a')
    "a"
    

    With just one gate in the pipeline q, the glue p is unused:

    ~zod:dojo> (;~(cmp trip |=(a=@ ~[a a])) 'a')
    "aa"
    ~zod:dojo> (;~(cmp trip |=(a=@ ~[a a])) '')
    ""
    

    But for multiple gates, we need it to connect the pipeline:

    ~zod:dojo> (;~(cmp trip ;~(cmp |=(a=@ ~[a a]) |=(a=@ <(dec a)>))) 'b')
    "97b"
    ~zod:dojo> (;~(cmp trip |=(a=@ ~[a a]) |=(a=@ <(dec a)>)) 'b')
    "97b"
    ~zod:dojo> (;~(cmp trip |=(a=@ ~[a a]) |=(a=@ <(dec a)>)) '')
    ""
    ~zod:dojo> (;~(cmp trip |=(a=@ ~[a a]) |=(a=@ <(dec a)>)) 'a')
    "96a"
    ~zod:dojo> (;~(cmp trip |=(a=@ ~[a a]) |=(a=@ <(dec a)>)) 'acd')
    "96acd"
    

    ;* "mictar"

    make a list of XML nodes from complex Hoon expression (Sail)

    Produces

    A marl, i.e., a list of manx. A manx is a noun that represents a single XML node.

    Syntax

    1-fixed

    ;*  p=hoon
    

    p is a Hoon expression that produces a marl.

    Discussion

    ;* is a Sail rune. Sail is a part of Hoon used for creating and operating on nouns that represent XML nodes. With the appropriate rendering pipeline, a Sail document can be used to generate a static website. See the Sail tutorial.

    If you need a complex Hoon expression to produce a marl, use the ;* rune. Often this rune is used with an expression, p, that includes one or more ;= subexpressions.

    (See also ;=.)

    Examples
    > ;*  ?:  (gth 3 2)
            ;=  ;p: This is node 1 of 'yes'.
                ;p: This is node 2 of 'yes'.
            ==
          ;=  ;p: This is node 1 of 'no'.
              ;p: This is node 2 of 'no'.
          ==
    [ [[%p ~] [[%$ [%$ "This is node 1 of 'yes'."] ~] ~] ~]
      [[[%p ~] [[%$ [%$ "This is node 2 of 'yes'."] ~] ~] ~] ~]
    ]
    
    > ;*  ?:  (gth 2 3)
              ;=  ;p: This is node 1 of 'yes'.
                  ;p: This is node 2 of 'yes'.
              ==
            ;=  ;p: This is node 1 of 'no'.
                ;p: This is node 2 of 'no'.
            ==
    [ [[%p ~] [[%$ [%$ "This is node 1 of 'no'."] ~] ~] ~]
      [[[%p ~] [[%$ [%$ "This is node 2 of 'no'."] ~] ~] ~] ~]
    ]
    

    ;= "mictis"

    make a list of XML nodes (Sail)

    Produces

    A marl, i.e., a list of manx. A manx is a noun that represents a single XML node.

    Syntax

    running

    ;=  p=hoon  q=hoon  ...  z=hoon  ==
    

    p-z are Hoon expressions, each of which poduces a manx.

    Discussion

    ;= is a Sail rune. Sail is a part of Hoon used for creating and operating on nouns that represent XML nodes. With the appropriate rendering pipeline, a Sail document can be used to generate a static website. See the Sail tutorial.

    In Sail a single XML node is represented by a manx. A single <p> node manx can be produced in the following way:

    > ;p: This will be rendered as an XML node.
    [[%p ~] [[%$ [%$ "This will be rendered as an XML node."] ~] ~] ~]
    

    Sometimes what is needed is a marl, i.e., a list of manx. To convert a series of manx nodes to a marl, use the ;= rune.

    (See also ;*.)

    Examples
    > ;=  ;p: This is the first node.
          ;p: This is the second.
          ;p: Here is the last one.
      ==
    [ [[%p ~] [[%$ [%$ "This is the first node."] ~] ~] ~]
      [[%p ~] [[%$ [%$ "This is the second."] ~] ~] ~]
      [[%p ~] [[%$ [%$ "Here is the last one."] ~] ~] ~]
      ~
    ]