@@ -4,9 +4,10 @@ weight = 6
4template = "doc.html"
4template = "doc.html"
5aliases = ["docs/reference/hoon-expressions/rune/wut/"]
5aliases = ["docs/reference/hoon-expressions/rune/wut/"]
7−Hoon has the usual program control branches. It also has the usual logical
8+Hoon has the usual program control branches. It also has the usual logical
8−operators: AND `?&`, OR `?|`, and NOT `?!`. It also has a `?=` rune that tests
9+operators: AND `?&`, OR `?|`, and NOT `?!`. It also has a `?=` rune that tests
9−whether a value matches a given type. In the course of type inference, Hoon
10+whether a value matches a given type. In the course of type inference, Hoon
10learns from `?=` tests in the test condition of [`?:` ("wutcol")](#wutcol)
11learns from `?=` tests in the test condition of [`?:` ("wutcol")](#wutcol)
11expressions.
12expressions.
@@ -16,63 +17,57 @@ All `?` runes reduce to `?:` and/or `?=`.
17If the condition of an `?:` is a `?=`, **and** the `?=` is
18If the condition of an `?:` is a `?=`, **and** the `?=` is
18testing a leg of the subject, the compiler specializes the subject
19testing a leg of the subject, the compiler specializes the subject
19−type for the branches of the `?:`. Branch inference also works
20+type for the branches of the `?:`. Branch inference also works
20for expressions which expand to `?:`.
21for expressions which expand to `?:`.
22The test does not have to be a single `?=`; the compiler can
23The test does not have to be a single `?=`; the compiler can
23analyze arbitrary boolean logic ([`?&` ("wutpam")](#wutpam),
24analyze arbitrary boolean logic ([`?&` ("wutpam")](#wutpam),
24[`?|` ("wutbar")](#wutbar), [`?!` ("wutzap")](#wutzap)) with full
25[`?|` ("wutbar")](#wutbar), [`?!` ("wutzap")](#wutzap)) with full
25−short-circuiting. Equality tests ([`.=` ("dottis")](/docs/hoon/reference/rune/dot#dottis)) are **not**
26+short-circuiting. Equality tests ([`.=` ("dottis")](/docs/hoon/reference/rune/dot#dottis)) are **not**
28If the compiler detects that the branch is degenerate (only one
29If the compiler detects that the branch is degenerate (only one
29side is taken), it fails with an error.
30side is taken), it fails with an error.
35−`[%wtgr p=hoon q=hoon]`: positive assertion.
37−##### Expands to
34+## `?|` "wutbar"
43−##### Syntax
38+#### Syntax
45−Regular: **2-fixed**.
40+Variable number of arguments.
47−##### Discussion
42+Tall form:
49−`?>` is used to force a crash when some condition `p` doesn't yield 'yes', `%.y`.
51−It can be used for type inference, with the `?=` rune, to specify the type of a value.
59−> ?>(=(3 4) %foo)
52+Wide form:
64−> `@`a
58+Irregular form:
67−> ?>(?=(@ a) `@`a)
60+```hoon
71−### `?|` "wutbar"
64+#### AST
73−`[%wtbr p=(list hoon)]`: logical OR.
67+[%wtbr p=(list hoon)]
75−##### Expands to
70+#### Expands to
77**Pseudocode**: `a`, `b`, `c`, ... as elements of `p`:
72**Pseudocode**: `a`, `b`, `c`, ... as elements of `p`:
@@ -80,7 +75,7 @@ nest-fail
80?:(a & ?:(b & ?:(c & ?:(... ?:(z & |)))))
75?:(a & ?:(b & ?:(c & ?:(... ?:(z & |)))))
83−##### Desugaring
78+#### Desugaring
@@ -91,230 +86,368 @@ nest-fail
94−##### Syntax
89+#### Produces
98−Irregular: `|(foo bar baz)` is `?|(foo bar baz)`.
91+If any argument evaluates to true (`%.y`), true. If all arguments evaluate to
100−##### Examples
94+#### Examples
103−~zod:dojo> |(=(6 42) =(42 42))
97+> |(=(6 42) =(42 42))
106−~zod:dojo> |(=(6 42) =(42 43))
100+> |(=(6 42) =(42 43))
110−### `?:` "wutcol" {#wutcol}
104+---
112−`[%wtcl p=hoon q=hoon r=hoon]`: branch on a boolean test.
106+## `?-` "wuthep"
114−##### Produces
108+Switch against a union, with no default.
116−If `p` produces yes, `%.y`, then `q`. If `p` produces no, `%.n`, then `r`.
110+#### Syntax
117−If `p` is not a boolean, compiler yells at you.
111+
112+One fixed argument, then a variable number of pairs.
119−##### Type inference
114+Tall form:
121−The subject types of `q` and `r` are constrained to match any pattern-matching algebra in `p`. The analysis, which is conservative, understands any combination of [`?=`](#wuttis), [`?&`](#wutpam), [`?|`](#wutbar), and [`?!`](#wutzap), and infers the type of the subject appropriately when compiling.
116+```hoon
123−If test analysis reveals that either branch is never taken, or if `p` is not a boolean, compilation fails. An untaken branch is indicated with `mint-lost`.
124+Alternative tall form:
125−##### Syntax
126+```hoon
127−Regular: **3-fixed**.
137+Wide form:
129−##### Discussion
139+```hoon
140+?-(p q1a q1b, q2a q2b, qna qnb)
131−Short-circuiting in boolean tests works as you'd expect
143+Irregular form:
132−and includes the expected inference. For instance,
133−if you write `?&(a b)`, `b` is only executed if `a` is
134−positive, and compiled with that assumption.
136−Note also that all other branching expressions reduce to `?:`.
145+None.
138−##### Examples
147+#### AST
150+[%wthp p=wing q=(list (pair spec value))]
141−~zod:dojo> ?:((gth 1 0) 3 4)
144−~zod:dojo> ?: (gth 1 0)
153+#### Expands to
149−~zod:dojo> ?:((gth 1 2) 3 4)
155+**Pseudocode**: `a`, `b`, `c`, ... as elements of `q`:
152−~zod:dojo> ?: (gth 1 2)
157+```hoon
153− 3
158+?: ?=(p.a p) q.a
154− 4
159+?: ?=(p.b p) q.b
155−4
160+?: ?=(p.c p) q.c
178+The `?-` rune is for a conditional expression in which the type of `p`
179+determines which branch is taken. Usually the type of `p` is a union of other
180+types. There is no default branch.
182+The compiler makes sure that your code neither misses a case of the union, nor
183+includes a double case that isn't there. This is not special handling for `?-`,
184+just a consequence of the semantics of `?:`, which `?-` reduces to.
186+A missing case will throw the `mint-lost` error. An extra case will throw
192+> =cor |= vat=?(%a %b)
158−### `?.` "wutdot"
208+---
210+## `?:` "wutcol" {#wutcol}
212+Branch on a boolean test.
160−`[%wtdt p=hoon q=hoon r=hoon]`: branch on a boolean test, inverted.
214+#### Syntax
162−##### Expands to
216+Three arguments, fixed.
168−##### Syntax
226+Wide form:
170−Regular: **3-fixed**.
232+Irregular form:
172−##### Discussion
234+None.
174−`?.` is just like `?:`, but with its last two subexpressions reversed.
236+#### AST
176−As is usual with inverted forms, use `?.` when the yes-case expression is much taller and/or wider than the no-case expression.
238+```hoon
239+[%wtcl p=hoon q=hoon r=hoon]
244+If `p` produces true (`%.y`), then `q`. If `p` produces false (`%.n`), then `r`.
245+If `p` is not a boolean, compiler yells at you.
249+If test analysis reveals that either branch is never taken, or if `p` is not a
250+boolean, compilation fails. An untaken branch is indicated with `mint-lost`.
252+Note also that all other branching expressions reduce to `?:`.
178−##### Examples
254+#### Examples
181−~zod:dojo> ?.((gth 1 2) 3 4)
257+> ?:((gth 1 0) 3 4)
184−~zod:dojo> ?.(?=(%a 'a') %not-a %yup)
260+> ?: (gth 1 0)
187−~zod:dojo> ?. %.y
265+> ?:((gth 1 2) 3 4)
188− 'this false case is less heavy than the true case'
266+4
190− 'two not equal to 3'
268+> ?: (gth 1 2)
191− 'but see how \'r is much heavier than \'q?'
269+ 3
192−'but see how \'r is much heavier than \'q?'
270+ 4
195−### `?-` "wuthep"
274+---
197−`[%wthp p=wing q=(list (pair spec value))]`: switch against a union, with no default.
276+## `?.` "wutdot"
199−##### Expands to
278+Branch on a boolean test, inverted.
201−**Pseudocode**: `a`, `b`, `c`, ... as elements of `q`:
280+#### Syntax
282+Three arguments, fixed.
204−?: ?=(p.a p) q.a
287+?. p
205−?: ?=(p.b p) q.b
288+ q
206−?: ?=(p.c p) q.c
289+r
211−##### Desugaring
292+Wide form:
222−##### Syntax
298+Irregular form:
305+[%wtdt p=hoon q=hoon r=hoon]
224−Regular: **1-fixed**, then **jogging**.
308+#### Expands to
226−##### Discussion
310+```hoon
228−The `?-` rune is for a conditional expression in which the type of `p` determines which branch is taken. Usually the type of `p` is a union of other types. There is no default branch.
314+#### Discussion
230−The compiler makes sure that your code neither misses a case of
316+`?.` is just like `?:`, but with its last two subexpressions reversed.
231−the union, nor includes a double case that isn't there. This is
232−not special handling for `?-`, just a consequence of the
233−semantics of `?:`, which `?-` reduces to.
235−A missing case will throw the `mint-lost` error. An extra case
318+As is usual with inverted forms, use `?.` when the true-case expression is much
236−will throw `mint-vain`.
319+taller and/or wider than the false-case expression.
238−##### Examples
321+#### Examples
241−~zod:dojo> =cor |= vat=?(%a %b)
324+> ?.((gth 1 2) 3 4)
247−~zod:dojo> (cor %a)
327+> ?.(?=(%a 'a') %not-a %yup)
250−~zod:dojo> (cor %b)
330+> ?. %.y
251−42
331+ 'this false case is less heavy than the true case'
333+ 'two not equal to 3'
334+ 'but see how \'r is much heavier than \'q?'
335+'but see how \'r is much heavier than \'q?'
253−~zod:dojo> (cor %c)
338+---
342+Branch on whether a wing of the subject is a cell.
346+Three arguments, fixed.
257−### `?^` "wutket"
362+Irregular form:
259−`[%wtkt p=wing q=hoon r=hoon]`: branch on whether a wing
364+None.
260−of the subject is a cell.
262−##### Expands to
366+#### AST
265−?:(?=(^ p) q r)
369+[%wtkt p=wing q=hoon r=hoon]
268−##### Syntax
372+#### Expands to
270−Regular: **3-fixed**.
374+```hoon
272−##### Discussion
378+#### Discussion
380+The type of the wing, `p`, must not be known to be either an atom or a cell, or
274−The type of the wing, `p`, must not be known to be either an atom or a cell, or else you'll get a `mint-vain` error at compile time. `mint-vain` means that one of the `?^` branches, `q` or `r`, is never taken.
381+else you'll get a `mint-vain` error at compile time. `mint-vain` means that one
382+of the `?^` branches, `q` or `r`, is never taken.
276−##### Examples
384+#### Examples
279−~zod:dojo> ?^(0 1 2)
387+> ?^(0 1 2)
280! mint-vain
388! mint-vain
283−~zod:dojo> ?^(`*`0 1 2)
391+> ?^(`*`0 1 2)
286−~zod:dojo> ?^(`*`[1 2] 3 4)
394+> ?^(`*`[1 2] 3 4)
290−### `?<` "wutgal"
400+## `?<` "wutgal"
292−`[%wtgl p=hoon q=hoon]`: negative assertion.
402+Negative assertion.
294−##### Expands to
404+#### Syntax
406+Two arguments, fixed.
297−?:(p !! q)
418+?<(p q)
300−##### Syntax
421+Irregular form:
302−Regular: **2-fixed**.
427+```hoon
428+[%wtgl p=hoon q=hoon]
304−##### Discussion
433+```hoon
306−`?<` is used to force a crash when some condition `p` doesn't yield 'no', `%.n`.
437+#### Discussion
439+`?<` is used to force a crash when some condition `p` doesn't yield false
308−It can be used for type inference with the `?=` rune, much like the `?>` rune.
440+(`%.n`). It can be used for type inference with the `?=` rune, much like the
310−##### Examples
443+#### Examples
313> ?<(=(3 4) %foo)
446> ?<(=(3 4) %foo)
316> ?<(=(3 3) %foo)
449> ?<(=(3 3) %foo)
317−ford: build failed
450+dojo: hoon expression failed
319> =a `*`[12 14]
452> =a `*`[12 14]
@@ -325,12 +458,86 @@ nest-fail
328−### `?+` "wutlus"
461+---
330−`[%wtls p=wing q=hoon r=(list (pair spec hoon))]`: switch against
467+#### Syntax
331−a union, with a default.
469+Two arguments, fixed.
491+[%wtgr p=hoon q=hoon]
502+`?>` is used to force a crash when some condition `p` doesn't yield true
503+(`%.y`). It can be used for type inference, with the `?=` rune, to specify the
513+dojo: hoon expression failed
528+Switch against a union, with a default.
532+Regular: **2-fixed**, then **jogging**.
537+[%wtls p=wing q=hoon r=(list (pair spec hoon))]
333−##### Expands to
540+#### Expands to
335**Pseudocode**: `a`, `b`, `c`, ... as elements of `r`:
542**Pseudocode**: `a`, `b`, `c`, ... as elements of `r`:
@@ -342,7 +549,7 @@ a union, with a default.
345−##### Desugaring
552+#### Desugaring
@@ -353,40 +560,72 @@ q
358−Regular: **2-fixed**, then **jogging**.
360−##### Discussion
563+#### Discussion
565+The `?+` rune is for a conditional expression in which the type of `p`
362−The `?+` rune is for a conditional expression in which the type of `p` determines which branch is taken. Usually the type of `p` is a union of other types. If `p`'s type doesn't match the case for any given branch, the default expression, `q`, is evaluated.
566+determines which branch is taken. Usually the type of `p` is a union of other
567+types. If `p`'s type doesn't match the case for any given branch, the default
568+expression, `q`, is evaluated.
364If there is a case that is never taken you'll get a `mint-vain` error.
570If there is a case that is never taken you'll get a `mint-vain` error.
366−##### Examples
572+#### Examples
369−~zod:dojo> =cor |= vat=@tas
575+> =cor |= vat=@tas
370− ?+ vat 240
576+ ?+ vat 240
375−~zod:dojo> (cor %a)
581+> (cor %a)
378−~zod:dojo> (cor %b)
584+> (cor %b)
381−~zod:dojo> (cor %c)
587+> (cor %c)
385−### `?&` "wutpam"
593+## `?&` "wutpam"
387−`[%wtpm p=(list hoon)]`: logical AND.
625+[%wtpm p=(list hoon)]
389−##### Expands to
628+#### Expands to
391**Pseudocode**: `a`, `b`, `c`, ... as elements of `p`:
630**Pseudocode**: `a`, `b`, `c`, ... as elements of `p`:
@@ -394,7 +633,7 @@ If there is a case that is never taken you'll get a `mint-vain` error.
394?.(a | ?.(b | ?.(c | ?.(... ?.(z | &)))))
633?.(a | ?.(b | ?.(c | ?.(... ?.(z | &)))))
397−##### Desugaring
636+#### Desugaring
@@ -405,136 +644,248 @@ If there is a case that is never taken you'll get a `mint-vain` error.
408−##### Syntax
647+#### Produces
410−Regular: **running**.
412−Irregular: `&(foo bar baz)` is `?&(foo bar baz)`.
649+If ALL arguments evaluate to true (`%.y`), true (`%.y`). If one or more evalute
650+to false (`%.n`), false (`%.n`).
414−##### Examples
652+#### Examples
417−~zod:dojo> &(=(6 6) =(42 42))
655+> &(=(6 6) =(42 42))
420−~zod:dojo> &(=(6 7) =(42 43))
658+> &(=(6 7) =(42 42))
424−### `?~` "wutsig"
662+---
666+Branch on whether a wing of the subject is an atom.
670+Three arguments, fixed.
693+[%wtpt p=wing q=hoon r=hoon]
704+If `p` is an atom, `q`. If `p` is a cell, `r`.
708+The type of the wing, `p`, must not be known to be either an atom or a cell, or
709+else you'll get a `mint-vain` error at compile time. `mint-vain` means that one
710+of the `?@` branches, `q` or `r`, is never taken.
426−`[%wtsg p=wing q=hoon r=hoon]`: branch on whether a wing of the subject is null.
730+Branch on whether a wing of the subject is null.
734+Three arguments, fixed.
757+[%wtsg p=wing q=hoon r=hoon]
428−##### Expands to
760+#### Expands to
431?:(?=($~ p) q r)
763?:(?=($~ p) q r)
434−##### Syntax
766+#### Produces
436−Regular: **3-fixed**.
768+If `p` is null (`~`), `q`. If `p` is non-null, `r`.
438−##### Discussion
770+#### Discussion
440−It's bad style to use `?~` to test for any zero atom. Use it only for a true null, `~`.
772+It's bad style to use `?~` to test for any zero atom. Use it only for a true
442−##### Examples
775+#### Examples
445−~zod:dojo> =foo ""
778+> =foo ""
447−~zod:dojo> ?~(foo 1 2)
780+> ?~(foo 1 2)
451−### `?=` "wuttis"
786+## `?=` "wuttis"
792+Two arguments, fixed.
453−`[%wtts p=spec q=wing]`: test pattern match.
809+None.
455−##### Produces
811+#### AST
457−`%.y` (yes) if the noun at `q` is in the type of `p`; `%.n` (no) otherwise.
813+```hoon
814+[%wtts p=spec q=wing]
459−##### Syntax
817+#### Produces
461−Regular: **2-fixed**.
819+`%.y` (true) if the noun at `q` is in the type of `p`; `%.n` (false) otherwise.
463−##### Discussion
821+#### Discussion
465−`?=` is not as powerful as it might seem. For instance, it
823+`?=` is not as powerful as it might seem. For instance, it
466can't generate a loop -- you cannot (and should not) use it to
824can't generate a loop -- you cannot (and should not) use it to
467−test whether a `*` is a `(list @)`. Nor can it validate atomic
825+test whether a `*` is a `(list @)`. Nor can it validate atomic
470−Patterns should be as weak as possible. Unpack one layer of
828+Patterns should be as weak as possible. Unpack one layer of
471−union at a time. Don't confirm things the type system knows.
829+union at a time. Don't confirm things the type system knows.
473−For example, when matching from a tagged union for the type `[%foo p=@
831+For example, when matching from a tagged union for the type `[%foo p=@ q=[@ @]]`, the appropriate pattern is `[%foo *]`. You have one
474−q=[@ @]]`, the appropriate pattern is `[%foo *]`. You have one
475question, which is whether the head of the noun is `%foo`.
832question, which is whether the head of the noun is `%foo`.
477A common error is `find.$`, meaning `p` is not a type.
834A common error is `find.$`, meaning `p` is not a type.
479−##### Examples
836+#### Examples
482−~zod:dojo> =bar [%foo %bar %baz]
839+> =bar [%foo %bar %baz]
483−~zod:dojo> ?=([%foo *] bar)
840+> ?=([%foo *] bar)
487−### `?@` "wutpat"
844+---
489−`[%wtpt p=wing q=hoon r=hoon]`: branch on whether a wing of the subject is an atom.
491−##### Expands to
846+## `?!` "wutzap"
493−```hoon
848+Logical NOT.
497−##### Syntax
850+#### Syntax
499−Regular: **3-fixed**.
852+One argument, fixed.
501−##### Discussion
854+Tall form:
503−The type of the wing, `p`, must not be known to be either an atom or a cell, or else you'll get a `mint-vain` error at compile time. `mint-vain` means that one of the `?@` branches, `q` or `r`, is never taken.
856+```hoon
505−##### Examples
860+Wide form:
512−~zod:dojo> ?@(`*`0 1 2)
866+Irregular form:
515−~zod:dojo> ?@(`*`[1 2] 3 4)
868+```hoon
519−### `?!` "wutzap"
872+#### AST
521−`[%wtzp p=hoon]`: logical NOT.
875+[%wtzp p=hoon]
523−##### Expands to
878+#### Expands to
529−Produces the logical NOT of `p`.
884+#### Produces
533−Regular: **1-fixed**.
535−Irregular: `!foo` is `?!(foo)`.
886+The logical NOT of `p`, which must evaluate to either `%.y` or `%.n`.
537−##### Examples
888+#### Examples
540~zod:dojo> ?!(.=(1 2))
891~zod:dojo> ?!(.=(1 2))