@@ -4,9 +4,10 @@ weight = 6
44template = "doc.html"
55aliases = ["docs/reference/hoon-expressions/rune/wut/"]
66+++
7−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−whether a value matches a given type. In the course of type inference, Hoon
7+
8+Hoon has the usual program control branches. It also has the usual logical
9+operators: AND `?&`, OR `?|`, and NOT `?!`. It also has a `?=` rune that tests
10+whether a value matches a given type. In the course of type inference, Hoon
1011learns from `?=` tests in the test condition of [`?:` ("wutcol")](#wutcol)
1112expressions.
1213
@@ -16,63 +17,57 @@ All `?` runes reduce to `?:` and/or `?=`.
1617
1718If the condition of an `?:` is a `?=`, **and** the `?=` is
1819testing 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
2021for expressions which expand to `?:`.
2122
2223The test does not have to be a single `?=`; the compiler can
2324analyze arbitrary boolean logic ([`?&` ("wutpam")](#wutpam),
2425[`?|` ("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**
2627analyzed.
2728
2829If the compiler detects that the branch is degenerate (only one
2930side is taken), it fails with an error.
3031
31−## Runes
32−
33−### `?>` "wutgar"
34−
35−`[%wtgr p=hoon q=hoon]`: positive assertion.
32+---
3633
37−##### Expands to
34+## `?|` "wutbar"
3835
39−```hoon
40−?.(p !! q)
41−```
36+Logical OR.
4237
43−##### Syntax
38+#### Syntax
4439
45−Regular: **2-fixed**.
40+Variable number of arguments.
4641
47−##### Discussion
48−
49−`?>` is used to force a crash when some condition `p` doesn't yield 'yes', `%.y`.
50−
51−It can be used for type inference, with the `?=` rune, to specify the type of a value.
52−
53−##### Examples
42+Tall form:
5443
44+```hoon
45+?| p1
46+ p2
47+ p3
48+ pn
49+==
5550```
56−> ?>(=(3 3) %foo)
57−%foo
5851
59−> ?>(=(3 4) %foo)
60−ford: build failed
52+Wide form:
6153
62−> =a `*`123
54+```hoon
55+?|(p1 p2 p3 pn)
56+```
6357
64−> `@`a
65−nest-fail
58+Irregular form:
6659
67−> ?>(?=(@ a) `@`a)
68−123
60+```hoon
61+|(p1 p2 p3 pn)
6962```
7063
71−### `?|` "wutbar"
64+#### AST
7265
73−`[%wtbr p=(list hoon)]`: logical OR.
66+```hoon
67+[%wtbr p=(list hoon)]
68+```
7469
75−##### Expands to
70+#### Expands to
7671
7772**Pseudocode**: `a`, `b`, `c`, ... as elements of `p`:
7873
@@ -80,7 +75,7 @@ nest-fail
8075?:(a & ?:(b & ?:(c & ?:(... ?:(z & |)))))
8176```
8277
83−##### Desugaring
78+#### Desugaring
8479
8580```hoon
8681|-
@@ -91,230 +86,368 @@ nest-fail
9186$(p t.p)
9287```
9388
94−##### Syntax
95−
96−Regular: **running**.
89+#### Produces
9790
98−Irregular: `|(foo bar baz)` is `?|(foo bar baz)`.
91+If any argument evaluates to true (`%.y`), true. If all arguments evaluate to
92+false (`%.n`), false.
9993
100−##### Examples
94+#### Examples
10195
10296```
103−~zod:dojo> |(=(6 42) =(42 42))
97+> |(=(6 42) =(42 42))
10498%.y
10599
106−~zod:dojo> |(=(6 42) =(42 43))
100+> |(=(6 42) =(42 43))
107101%.n
108102```
109103
110−### `?:` "wutcol" {#wutcol}
104+---
111105
112−`[%wtcl p=hoon q=hoon r=hoon]`: branch on a boolean test.
106+## `?-` "wuthep"
113107
114−##### Produces
108+Switch against a union, with no default.
115109
116−If `p` produces yes, `%.y`, then `q`. If `p` produces no, `%.n`, then `r`.
117−If `p` is not a boolean, compiler yells at you.
110+#### Syntax
111+
112+One fixed argument, then a variable number of pairs.
118113
119−##### Type inference
114+Tall form:
120115
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
117+?- p
118+ q1a q1b
119+ q2a q2b
120+ qna qnb
121+==
122+```
122123
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:
124125
125−##### Syntax
126+```hoon
127+?- p
128+ q1a
129+ q1b
130+ q2a
131+ q2b
132+ qna
133+ qnb
134+==
135+```
126136
127−Regular: **3-fixed**.
137+Wide form:
128138
129−##### Discussion
139+```hoon
140+?-(p q1a q1b, q2a q2b, qna qnb)
141+```
130142
131−Short-circuiting in boolean tests works as you'd expect
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.
143+Irregular form:
135144
136−Note also that all other branching expressions reduce to `?:`.
145+None.
137146
138−##### Examples
147+#### AST
139148
149+```hoon
150+[%wthp p=wing q=(list (pair spec value))]
140151```
141−~zod:dojo> ?:((gth 1 0) 3 4)
142−3
143152
144−~zod:dojo> ?: (gth 1 0)
145− 3
146− 4
147−3
153+#### Expands to
148154
149−~zod:dojo> ?:((gth 1 2) 3 4)
150−4
155+**Pseudocode**: `a`, `b`, `c`, ... as elements of `q`:
151156
152−~zod:dojo> ?: (gth 1 2)
153− 3
154− 4
155−4
157+```hoon
158+?: ?=(p.a p) q.a
159+?: ?=(p.b p) q.b
160+?: ?=(p.c p) q.c
161+...
162+~|(%mint-lost !!)
163+```
164+
165+#### Desugaring
166+
167+```hoon
168+|-
169+?. q
170+ ~|(%mint-lost !!)
171+?: ?=(p.i.q p)
172+ q.i.q
173+$(q t.q)
174+```
175+
176+#### Discussion
177+
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.
181+
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.
185+
186+A missing case will throw the `mint-lost` error. An extra case will throw
187+`mint-vain`.
188+
189+#### Examples
190+
191+```
192+> =cor |= vat=?(%a %b)
193+ ?- vat
194+ %a 20
195+ %b 42
196+ ==
197+
198+> (cor %a)
199+20
200+
201+> (cor %b)
202+42
203+
204+> (cor %c)
205+! nest-fail
156206```
157207
158−### `?.` "wutdot"
208+---
209+
210+## `?:` "wutcol" {#wutcol}
211+
212+Branch on a boolean test.
159213
160−`[%wtdt p=hoon q=hoon r=hoon]`: branch on a boolean test, inverted.
214+#### Syntax
161215
162−##### Expands to
216+Three arguments, fixed.
217+
218+Tall form:
163219
164220```hoon
165−?:(p r q)
221+?: p
222+ q
223+r
166224```
167225
168−##### Syntax
226+Wide form:
227+
228+```hoon
229+?:(p q r)
230+```
169231
170−Regular: **3-fixed**.
232+Irregular form:
171233
172−##### Discussion
234+None.
173235
174−`?.` is just like `?:`, but with its last two subexpressions reversed.
236+#### AST
175237
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]
240+```
177241
178−##### Examples
242+#### Produces
243+
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.
246+
247+#### Discussion
248+
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`.
251+
252+Note also that all other branching expressions reduce to `?:`.
253+
254+#### Examples
179255
180256```
181−~zod:dojo> ?.((gth 1 2) 3 4)
257+> ?:((gth 1 0) 3 4)
1822583
183259
184−~zod:dojo> ?.(?=(%a 'a') %not-a %yup)
185−%yup
260+> ?: (gth 1 0)
261+ 3
262+ 4
263+3
186264
187−~zod:dojo> ?. %.y
188− 'this false case is less heavy than the true case'
189− ?: =(2 3)
190− 'two not equal to 3'
191− 'but see how \'r is much heavier than \'q?'
192−'but see how \'r is much heavier than \'q?'
265+> ?:((gth 1 2) 3 4)
266+4
267+
268+> ?: (gth 1 2)
269+ 3
270+ 4
271+4
193272```
194273
195−### `?-` "wuthep"
274+---
196275
197−`[%wthp p=wing q=(list (pair spec value))]`: switch against a union, with no default.
276+## `?.` "wutdot"
198277
199−##### Expands to
278+Branch on a boolean test, inverted.
200279
201−**Pseudocode**: `a`, `b`, `c`, ... as elements of `q`:
280+#### Syntax
281+
282+Three arguments, fixed.
283+
284+Tall form:
202285
203286```hoon
204−?: ?=(p.a p) q.a
205−?: ?=(p.b p) q.b
206−?: ?=(p.c p) q.c
207−...
208−~|(%mint-lost !!)
287+?. p
288+ q
289+r
209290```
210291
211−##### Desugaring
292+Wide form:
212293
213294```hoon
214−|-
215−?. q
216− ~|(%mint-lost !!)
217−?: ?=(p.i.q p)
218− q.i.q
219−$(q t.q)
295+?.(p q r)
220296```
221297
222−##### Syntax
298+Irregular form:
299+
300+None.
301+
302+#### AST
303+
304+```hoon
305+[%wtdt p=hoon q=hoon r=hoon]
306+```
223307
224−Regular: **1-fixed**, then **jogging**.
308+#### Expands to
225309
226−##### Discussion
310+```hoon
311+?:(p r q)
312+```
227313
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
229315
230−The compiler makes sure that your code neither misses a case of
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.
316+`?.` is just like `?:`, but with its last two subexpressions reversed.
234317
235−A missing case will throw the `mint-lost` error. An extra case
236−will throw `mint-vain`.
318+As is usual with inverted forms, use `?.` when the true-case expression is much
319+taller and/or wider than the false-case expression.
237320
238−##### Examples
321+#### Examples
239322
240323```
241−~zod:dojo> =cor |= vat=?(%a %b)
242− ?- vat
243− %a 20
244− %b 42
245− ==
324+> ?.((gth 1 2) 3 4)
325+3
246326
247−~zod:dojo> (cor %a)
248−20
327+> ?.(?=(%a 'a') %not-a %yup)
328+%yup
249329
250−~zod:dojo> (cor %b)
251−42
330+> ?. %.y
331+ 'this false case is less heavy than the true case'
332+ ?: =(2 3)
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?'
336+```
252337
253−~zod:dojo> (cor %c)
254−! nest-fail
338+---
339+
340+## `?^` "wutket"
341+
342+Branch on whether a wing of the subject is a cell.
343+
344+#### Syntax
345+
346+Three arguments, fixed.
347+
348+Tall form:
349+
350+```hoon
351+?^ p
352+ q
353+r
354+```
355+
356+Wide form:
357+
358+```hoon
359+?^(p q r)
255360```
256361
257−### `?^` "wutket"
362+Irregular form:
258363
259−`[%wtkt p=wing q=hoon r=hoon]`: branch on whether a wing
260−of the subject is a cell.
364+None.
261365
262−##### Expands to
366+#### AST
263367
264368```hoon
265−?:(?=(^ p) q r)
369+[%wtkt p=wing q=hoon r=hoon]
266370```
267371
268−##### Syntax
372+#### Expands to
269373
270−Regular: **3-fixed**.
374+```hoon
375+?:(?=(^ p) q r)
376+```
271377
272−##### Discussion
378+#### Discussion
273379
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.
380+The type of the wing, `p`, must not be known to be either an atom or a cell, or
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.
275383
276−##### Examples
384+#### Examples
277385
278386```
279−~zod:dojo> ?^(0 1 2)
387+> ?^(0 1 2)
280388! mint-vain
281389! exit
282390
283−~zod:dojo> ?^(`*`0 1 2)
391+> ?^(`*`0 1 2)
2843922
285393
286−~zod:dojo> ?^(`*`[1 2] 3 4)
394+> ?^(`*`[1 2] 3 4)
2873953
288396```
289397
290−### `?<` "wutgal"
398+---
399+
400+## `?<` "wutgal"
291401
292−`[%wtgl p=hoon q=hoon]`: negative assertion.
402+Negative assertion.
293403
294−##### Expands to
404+#### Syntax
405+
406+Two arguments, fixed.
407+
408+Tall form:
295409
296410```hoon
297−?:(p !! q)
411+?< p
412+q
413+```
414+
415+Wide form:
416+
417+```hoon
418+?<(p q)
298419```
299420
300−##### Syntax
421+Irregular form:
422+
423+None.
424+
425+#### AST
301426
302−Regular: **2-fixed**.
427+```hoon
428+[%wtgl p=hoon q=hoon]
429+```
430+
431+#### Expands to
303432
304−##### Discussion
433+```hoon
434+?:(p !! q)
435+```
305436
306−`?<` is used to force a crash when some condition `p` doesn't yield 'no', `%.n`.
437+#### Discussion
307438
308−It can be used for type inference with the `?=` rune, much like the `?>` rune.
439+`?<` is used to force a crash when some condition `p` doesn't yield false
440+(`%.n`). It can be used for type inference with the `?=` rune, much like the
441+`?>` rune.
309442
310−##### Examples
443+#### Examples
311444
312445```
313446> ?<(=(3 4) %foo)
314447%foo
315448
316449> ?<(=(3 3) %foo)
317−ford: build failed
450+dojo: hoon expression failed
318451
319452> =a `*`[12 14]
320453
@@ -325,12 +458,86 @@ nest-fail
325458[12 14]
326459```
327460
328−### `?+` "wutlus"
461+---
462+
463+## `?>` "wutgar"
464+
465+Positive assertion.
329466
330−`[%wtls p=wing q=hoon r=(list (pair spec hoon))]`: switch against
331−a union, with a default.
467+#### Syntax
332468
333−##### Expands to
469+Two arguments, fixed.
470+
471+Tall form:
472+
473+```hoon
474+?> p
475+q
476+```
477+
478+Wide form:
479+
480+```hoon
481+?>(p q)
482+```
483+
484+Irregular form:
485+
486+None.
487+
488+#### AST
489+
490+```hoon
491+[%wtgr p=hoon q=hoon]
492+```
493+
494+#### Expands to
495+
496+```hoon
497+?.(p !! q)
498+```
499+
500+#### Discussion
501+
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
504+type of a value.
505+
506+#### Examples
507+
508+```
509+> ?>(=(3 3) %foo)
510+%foo
511+
512+> ?>(=(3 4) %foo)
513+dojo: hoon expression failed
514+
515+> =a `*`123
516+
517+> `@`a
518+nest-fail
519+
520+> ?>(?=(@ a) `@`a)
521+123
522+```
523+
524+---
525+
526+## `?+` "wutlus"
527+
528+Switch against a union, with a default.
529+
530+#### Syntax
531+
532+Regular: **2-fixed**, then **jogging**.
533+
534+#### AST
535+
536+```hoon
537+[%wtls p=wing q=hoon r=(list (pair spec hoon))]
538+```
539+
540+#### Expands to
334541
335542**Pseudocode**: `a`, `b`, `c`, ... as elements of `r`:
336543
@@ -342,7 +549,7 @@ a union, with a default.
342549q
343550```
344551
345−##### Desugaring
552+#### Desugaring
346553
347554```hoon
348555|-
@@ -353,40 +560,72 @@ q
353560$(r t.r)
354561```
355562
356−##### Syntax
357−
358−Regular: **2-fixed**, then **jogging**.
359−
360−##### Discussion
563+#### Discussion
361564
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.
565+The `?+` rune is for a conditional expression in which the type of `p`
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.
363569
364570If there is a case that is never taken you'll get a `mint-vain` error.
365571
366−##### Examples
572+#### Examples
367573
368574```
369−~zod:dojo> =cor |= vat=@tas
370− ?+ vat 240
371− %a 20
372− %b 42
373− ==
575+> =cor |= vat=@tas
576+ ?+ vat 240
577+ %a 20
578+ %b 42
579+ ==
374580
375−~zod:dojo> (cor %a)
581+> (cor %a)
37658220
377583
378−~zod:dojo> (cor %b)
584+> (cor %b)
37958542
380586
381−~zod:dojo> (cor %c)
587+> (cor %c)
382588240
383589```
384590
385−### `?&` "wutpam"
591+---
592+
593+## `?&` "wutpam"
594+
595+Logical AND.
596+
597+#### Syntax
598+
599+Variable arguments.
600+
601+Tall form:
602+
603+```hoon
604+?& p1
605+ p2
606+ pn
607+==
608+```
609+
610+Wide form:
611+
612+```hoon
613+?&(p1 p2 pn)
614+```
615+
616+Irregular form:
617+
618+```hoon
619+&(p1 p2 pn)
620+```
621+
622+#### AST
386623
387−`[%wtpm p=(list hoon)]`: logical AND.
624+```hoon
625+[%wtpm p=(list hoon)]
626+```
388627
389−##### Expands to
628+#### Expands to
390629
391630**Pseudocode**: `a`, `b`, `c`, ... as elements of `p`:
392631
@@ -394,7 +633,7 @@ If there is a case that is never taken you'll get a `mint-vain` error.
394633?.(a | ?.(b | ?.(c | ?.(... ?.(z | &)))))
395634```
396635
397−##### Desugaring
636+#### Desugaring
398637
399638```hoon
400639|-
@@ -405,136 +644,248 @@ If there is a case that is never taken you'll get a `mint-vain` error.
405644$(p t.p)
406645```
407646
408−##### Syntax
409−
410−Regular: **running**.
647+#### Produces
411648
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`).
413651
414−##### Examples
652+#### Examples
415653
416654```
417−~zod:dojo> &(=(6 6) =(42 42))
655+> &(=(6 6) =(42 42))
418656%.y
419657
420−~zod:dojo> &(=(6 7) =(42 43))
658+> &(=(6 7) =(42 42))
421659%.n
422660```
423661
424−### `?~` "wutsig"
662+---
663+
664+## `?@` "wutpat"
665+
666+Branch on whether a wing of the subject is an atom.
667+
668+#### Syntax
669+
670+Three arguments, fixed.
671+
672+Tall form:
673+
674+```hoon
675+?@ p
676+ q
677+r
678+```
679+
680+Wide form:
425681
426−`[%wtsg p=wing q=hoon r=hoon]`: branch on whether a wing of the subject is null.
682+```hoon
683+?@(p q r)
684+```
685+
686+Irregular form:
687+
688+None.
689+
690+#### AST
691+
692+```hoon
693+[%wtpt p=wing q=hoon r=hoon]
694+```
695+
696+#### Expands to
697+
698+```hoon
699+?:(?=(@ p) q r)
700+```
701+
702+#### Produces
703+
704+If `p` is an atom, `q`. If `p` is a cell, `r`.
705+
706+#### Discussion
707+
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.
711+
712+#### Examples
713+
714+```
715+> ?@(0 1 2)
716+! mint-vain
717+! exit
718+
719+> ?@(`*`0 1 2)
720+1
721+
722+> ?@(`*`[1 2] 3 4)
723+4
724+```
725+
726+---
727+
728+## `?~` "wutsig"
729+
730+Branch on whether a wing of the subject is null.
731+
732+#### Syntax
733+
734+Three arguments, fixed.
735+
736+Tall form:
737+
738+```hoon
739+?~ p
740+ q
741+r
742+```
743+
744+Wide form:
745+
746+```hoon
747+?~(p q r)
748+```
749+
750+Irregular form:
751+
752+None.
753+
754+#### AST
427755
428−##### Expands to
756+```hoon
757+[%wtsg p=wing q=hoon r=hoon]
758+```
759+
760+#### Expands to
429761
430762```hoon
431763?:(?=($~ p) q r)
432764```
433765
434−##### Syntax
766+#### Produces
435767
436−Regular: **3-fixed**.
768+If `p` is null (`~`), `q`. If `p` is non-null, `r`.
437769
438−##### Discussion
770+#### Discussion
439771
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
773+null, `~`.
441774
442−##### Examples
775+#### Examples
443776
444777```
445−~zod:dojo> =foo ""
778+> =foo ""
446779
447−~zod:dojo> ?~(foo 1 2)
780+> ?~(foo 1 2)
4487811
449782```
450783
451−### `?=` "wuttis"
784+---
785+
786+## `?=` "wuttis"
787+
788+Test pattern match.
789+
790+#### Syntax
791+
792+Two arguments, fixed.
793+
794+Tall form:
795+
796+```hoon
797+?= p
798+q
799+```
800+
801+Wide form:
802+
803+```hoon
804+?=(p q)
805+```
806+
807+Irregular form:
452808
453−`[%wtts p=spec q=wing]`: test pattern match.
809+None.
454810
455−##### Produces
811+#### AST
456812
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]
815+```
458816
459−##### Syntax
817+#### Produces
460818
461−Regular: **2-fixed**.
819+`%.y` (true) if the noun at `q` is in the type of `p`; `%.n` (false) otherwise.
462820
463−##### Discussion
821+#### Discussion
464822
465−`?=` is not as powerful as it might seem. For instance, it
823+`?=` is not as powerful as it might seem. For instance, it
466824can'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
468826auras.
469827
470−Patterns should be as weak as possible. Unpack one layer of
471−union at a time. Don't confirm things the type system knows.
828+Patterns should be as weak as possible. Unpack one layer of
829+union at a time. Don't confirm things the type system knows.
472830
473−For example, when matching from a tagged union for the type `[%foo p=@
474−q=[@ @]]`, the appropriate pattern is `[%foo *]`. You have one
831+For example, when matching from a tagged union for the type `[%foo p=@ q=[@ @]]`, the appropriate pattern is `[%foo *]`. You have one
475832question, which is whether the head of the noun is `%foo`.
476833
477834A common error is `find.$`, meaning `p` is not a type.
478835
479−##### Examples
836+#### Examples
480837
481838```
482−~zod:dojo> =bar [%foo %bar %baz]
483−~zod:dojo> ?=([%foo *] bar)
839+> =bar [%foo %bar %baz]
840+> ?=([%foo *] bar)
484841%.y
485842```
486843
487−### `?@` "wutpat"
488−
489−`[%wtpt p=wing q=hoon r=hoon]`: branch on whether a wing of the subject is an atom.
844+---
490845
491−##### Expands to
846+## `?!` "wutzap"
492847
493−```hoon
494−?:(?=(@ p) q r)
495−```
848+Logical NOT.
496849
497−##### Syntax
850+#### Syntax
498851
499−Regular: **3-fixed**.
852+One argument, fixed.
500853
501−##### Discussion
854+Tall form:
502855
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
857+?! p
858+```
504859
505−##### Examples
860+Wide form:
506861
862+```hoon
863+?!(p)
507864```
508−~zod:dojo> ?@(0 1 2)
509−! mint-vain
510−! exit
511865
512−~zod:dojo> ?@(`*`0 1 2)
513−1
866+Irregular form:
514867
515−~zod:dojo> ?@(`*`[1 2] 3 4)
516−4
868+```hoon
869+!p
517870```
518871
519−### `?!` "wutzap"
872+#### AST
520873
521−`[%wtzp p=hoon]`: logical NOT.
874+```hoon
875+[%wtzp p=hoon]
876+```
522877
523−##### Expands to
878+#### Expands to
524879
525880```hoon
526881.=(| p)
527882```
528883
529−Produces the logical NOT of `p`.
530−
531−##### Syntax
532−
533−Regular: **1-fixed**.
884+#### Produces
534885
535−Irregular: `!foo` is `?!(foo)`.
886+The logical NOT of `p`, which must evaluate to either `%.y` or `%.n`.
536887
537−##### Examples
888+#### Examples
538889
539890```
540891~zod:dojo> ?!(.=(1 2))