# ? wut · Conditionals

Hoon has the usual program control branches. It also has the usual logical operators: AND `?&`, OR `?|`, and NOT `?!`. It also has a `?=` rune that tests whether a value matches a given type. In the course of type inference, Hoon learns from `?=` tests in the test condition of [`?:` ("wutcol")](#-wutcol) expressions.

## Overview <a href="#overview" id="overview"></a>

All `?` runes reduce to `?:` and/or `?=`.

If the condition of an `?:` is a `?=`, **and** the `?=` is testing a leg of the subject, the compiler specializes the subject type for the branches of the `?:`. Branch inference also works for expressions which expand to `?:`.

The test does not have to be a single `?=`; the compiler can analyze arbitrary boolean logic ([`?&` ("wutpam")](#-wutpam), [`?|` ("wutbar")](#-wutbar), [`?!` ("wutzap")](#-wutzap)) with full short-circuiting. Equality tests ([`.=` ("dottis")](/hoon/rune/dot.md#dottis)) are **not** analyzed.

If the compiler detects that the branch is degenerate (only one side is taken), it fails with an error.

***

## ?| "wutbar" <a href="#wutbar" id="wutbar"></a>

Logical OR.

#### Syntax

Variable number of arguments.

{% tabs %}
{% tab title="Tall form" %}

```hoon
?|  p1
    p2
    p3
    pn
==
```

{% endtab %}

{% tab title="Wide form" %}

```hoon
?|(p1 p2 p3 pn)
```

{% endtab %}

{% tab title="Irregular form" %}

```hoon
|(p1 p2 p3 pn)
```

{% endtab %}
{% endtabs %}

#### AST

```hoon
[%wtbr p=(list hoon)]
```

#### Expands to

**Pseudocode**: *a*, *b*, *c*, ... as elements of `.p`:

```hoon
?:(a & ?:(b & ?:(c & ?:(... ?:(z & |)))))
```

#### Desugaring

```hoon
|-
?~  p
  |
?:  i.p
  &
$(p t.p)
```

#### Produces

If any argument evaluates to true (`%.y`), true. If all arguments evaluate to false (`%.n`), false.

#### Examples

```
> |(=(6 42) =(42 42))
%.y

> |(=(6 42) =(42 43))
%.n
```

***

## ?- "wuthep" <a href="#wuthep" id="wuthep"></a>

Switch against a union, with no default.

#### Syntax

One fixed argument, then a variable number of pairs.

{% tabs %}
{% tab title="Tall style #1" %}

```hoon
?-  p
  q1a  q1b
  q2a  q2b
  qna  qnb
==
```

{% endtab %}

{% tab title="Tall style #2" %}

```hoon
?-    p
    q1a
  q1b
::
    q2a
  q2b
::
    qna
  qnb
==
```

{% endtab %}

{% tab title="Wide form" %}

```hoon
?-(p q1a q1b, q2a q2b, qna qnb)
```

{% endtab %}

{% tab title="Irregular form" %}
None
{% endtab %}
{% endtabs %}

#### AST

```hoon
[%wthp p=wing q=(list (pair spec value))]
```

#### Expands to

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

```hoon
?:  ?=(p.a p)  q.a
?:  ?=(p.b p)  q.b
?:  ?=(p.c p)  q.c
...
~|(%mint-lost !!)
```

#### Desugaring

```hoon
|-
?.  q
  ~|(%mint-lost !!)
?:  ?=(p.i.q p)
  q.i.q
$(q t.q)
```

#### Discussion

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.

The compiler makes sure that your code neither misses a case of the union, nor includes a double case that isn't there. This is not special handling for `?-`, just a consequence of the semantics of `?:`, which `?-` reduces to.

A missing case will throw the `mint-lost` error. An extra case will throw `mint-vain`.

#### Examples

```
> =cor |=  vat=?(%a %b)
       ?-  vat
         %a  20
         %b  42
       ==

> (cor %a)
20

> (cor %b)
42

> (cor %c)
! nest-fail
```

***

## ?: "wutcol" <a href="#wutcol" id="wutcol"></a>

Branch on a boolean test.

#### Syntax

Three arguments, fixed.

{% tabs %}
{% tab title="Tall form" %}

```hoon
?:  p
  q
r
```

{% endtab %}

{% tab title="Wide form" %}

```hoon
?:(p q r)
```

{% endtab %}

{% tab title="Irregular form" %}
None
{% endtab %}
{% endtabs %}

#### AST

```hoon
[%wtcl p=hoon q=hoon r=hoon]
```

#### Produces

If `.p` produces true (`%.y`), then `.q`. If `.p` produces false (`%.n`), then `.r`. If `.p` is not a boolean, compiler yells at you.

#### Discussion

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`.

Note also that all other branching expressions reduce to `?:`.

#### Examples

```
> ?:((gth 1 0) 3 4)
3

> ?:  (gth 1 0)
    3
  4
3

> ?:((gth 1 2) 3 4)
4

> ?:  (gth 1 2)
    3
  4
4
```

***

## ?. "wutdot" <a href="#wutdot" id="wutdot"></a>

Branch on a boolean test, inverted.

#### Syntax

Three arguments, fixed.

{% tabs %}
{% tab title="Tall form" %}

```hoon
?.  p
  q
r
```

{% endtab %}

{% tab title="Wide form" %}

```hoon
?.(p q r)
```

{% endtab %}

{% tab title="Irregular form" %}
None
{% endtab %}
{% endtabs %}

#### AST

```hoon
[%wtdt p=hoon q=hoon r=hoon]
```

#### Expands to

```hoon
?:(p r q)
```

#### Discussion

`?.` is just like `?:`, but with its last two subexpressions reversed.

As is usual with inverted forms, use `?.` when the true-case expression is much taller and/or wider than the false-case expression.

#### Examples

```
> ?.((gth 1 2) 3 4)
3

> ?.(?=(%a 'a') %not-a %yup)
%yup

> ?.  %.y
    'this false case is less heavy than the true case'
  ?:  =(2 3)
    'two not equal to 3'
  'but see how \'r is much heavier than \'q?'
'but see how \'r is much heavier than \'q?'
```

***

## ?^ "wutket" <a href="#wutket" id="wutket"></a>

Branch on whether a wing of the subject is a cell.

#### Syntax

Three arguments, fixed.

{% tabs %}
{% tab title="Tall form" %}

```hoon
?^  p
  q
r
```

{% endtab %}

{% tab title="Wide form" %}

```hoon
?^(p q r)
```

{% endtab %}

{% tab title="Irregular form" %}
None
{% endtab %}
{% endtabs %}

#### AST

```hoon
[%wtkt p=wing q=hoon r=hoon]
```

#### Expands to

```hoon
?:(?=(^ p) q r)
```

#### Discussion

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.

#### Examples

```
> ?^(0 1 2)
! mint-vain
! exit

> ?^(`*`0 1 2)
2

> ?^(`*`[1 2] 3 4)
3
```

***

## ?< "wutgal" <a href="#wutgal" id="wutgal"></a>

Negative assertion.

#### Syntax

Two arguments, fixed.

{% tabs %}
{% tab title="Tall form" %}

```hoon
?<  p
q
```

{% endtab %}

{% tab title="Wide form" %}

```hoon
?<(p q)
```

{% endtab %}

{% tab title="Irregular form" %}
None
{% endtab %}
{% endtabs %}

#### AST

```hoon
[%wtgl p=hoon q=hoon]
```

#### Expands to

```hoon
?:(p !! q)
```

#### Discussion

`?<` is used to force a crash when some condition `.p` doesn't yield false (`%.n`). It can be used for type inference with the `?=` rune, much like the `?>` rune.

#### Examples

```
> ?<(=(3 4) %foo)
%foo

> ?<(=(3 3) %foo)
dojo: hoon expression failed

> =a `*`[12 14]

> `^`a
nest-fail

> ?<(?=(@ a) `^`a)
[12 14]
```

***

## ?> "wutgar" <a href="#wutgar" id="wutgar"></a>

Positive assertion.

#### Syntax

Two arguments, fixed.

{% tabs %}
{% tab title="Tall form" %}

```hoon
?>  p
q
```

{% endtab %}

{% tab title="Wide form" %}

```hoon
?>(p q)
```

{% endtab %}

{% tab title="Irregular form" %}
None
{% endtab %}
{% endtabs %}

#### AST

```hoon
[%wtgr p=hoon q=hoon]
```

#### Expands to

```hoon
?.(p !! q)
```

#### Discussion

`?>` is used to force a crash when some condition `.p` doesn't yield true (`%.y`). It can be used for type inference, with the `?=` rune, to specify the type of a value.

#### Examples

```
> ?>(=(3 3) %foo)
%foo

> ?>(=(3 4) %foo)
dojo: hoon expression failed

> =a `*`123

> `@`a
nest-fail

> ?>(?=(@ a) `@`a)
123
```

***

## ?+ "wutlus" <a href="#wutlus" id="wutlus"></a>

Switch against a union, with a default.

#### Syntax

Two fixed arguments, then a variable number of pairs.

{% tabs %}
{% tab title="Tall style #1" %}

```hoon
?+  p  q
  r1a  r1b
  r2a  r2b
  rna  rnb
==
```

{% endtab %}

{% tab title="Tall style #2" %}

```hoon
?+    p  q
    r1a
  r1b
::
    r2a
  r2b
::
    rna
  rnb
==
```

{% endtab %}

{% tab title="Wide form" %}

```hoon
?+(p q r1a r1b, r2a r2b, rna rnb)
```

{% endtab %}

{% tab title="Irregular form" %}
None
{% endtab %}
{% endtabs %}

#### AST

```hoon
[%wtls p=wing q=hoon r=(list (pair spec hoon))]
```

#### Expands to

**Pseudocode**: *a*, *b*, *c*, ... as elements of `.r`:

```hoon
?:  ?=(p.a p)  q.a
?:  ?=(p.b p)  q.b
?:  ?=(p.c p)  q.c
...
q
```

#### Desugaring

```hoon
|-
?.  r
  q
?:  ?=(p.i.r p)
  q.i.r
$(r t.r)
```

#### Discussion

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.

If there is a case that is never taken you'll get a `mint-vain` error.

#### Examples

```
> =cor |=  vat=@tas
       ?+  vat  240
         %a  20
         %b  42
       ==

> (cor %a)
20

> (cor %b)
42

> (cor %c)
240
```

***

## ?& "wutpam" <a href="#wutpam" id="wutpam"></a>

Logical AND.

#### Syntax

Variable arguments.

{% tabs %}
{% tab title="Tall form" %}

```hoon
?&  p1
    p2
    pn
==
```

{% endtab %}

{% tab title="Wide form" %}

```hoon
?&(p1 p2 pn)
```

{% endtab %}

{% tab title="Irregular form" %}

```
  &(p1 p2 pn)
```

{% endtab %}
{% endtabs %}

#### AST

```hoon
[%wtpm p=(list hoon)]
```

#### Expands to

**Pseudocode**: *a*, *b*, *c*, ... as elements of `.p`:

```hoon
?.(a | ?.(b | ?.(c | ?.(... ?.(z | &)))))
```

#### Desugaring

```hoon
|-
?~  p
  &
?.  i.p
  |
$(p t.p)
```

#### Produces

If ALL arguments evaluate to true (`%.y`), true (`%.y`). If one or more evalute to false (`%.n`), false (`%.n`).

#### Examples

```
> &(=(6 6) =(42 42))
%.y

> &(=(6 7) =(42 42))
%.n
```

***

## ?@ "wutpat" <a href="#wutpat" id="wutpat"></a>

Branch on whether a wing of the subject is an atom.

#### Syntax

Three arguments, fixed.

{% tabs %}
{% tab title="Tall form" %}

```hoon
?@  p
  q
r
```

{% endtab %}

{% tab title="Wide form" %}

```hoon
?@(p q r)
```

{% endtab %}

{% tab title="Irregular form" %}
None
{% endtab %}
{% endtabs %}

#### AST

```hoon
[%wtpt p=wing q=hoon r=hoon]
```

#### Expands to

```hoon
?:(?=(@ p) q r)
```

#### Produces

If `.p` is an atom, `.q`. If `.p` is a cell, `.r`.

#### Discussion

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.

#### Examples

```
> ?@(0 1 2)
! mint-vain
! exit

> ?@(`*`0 1 2)
1

> ?@(`*`[1 2] 3 4)
4
```

***

## ?\~ "wutsig" <a href="#wutsig" id="wutsig"></a>

Branch on whether a wing of the subject is null.

#### Syntax

Three arguments, fixed.

{% tabs %}
{% tab title="Tall form" %}

```hoon
?~  p
  q
r
```

{% endtab %}

{% tab title="Wide form" %}

```hoon
?~(p q r)
```

{% endtab %}

{% tab title="Irregular form" %}
None
{% endtab %}
{% endtabs %}

#### AST

```hoon
[%wtsg p=wing q=hoon r=hoon]
```

#### Expands to

```hoon
?:(?=($~ p) q r)
```

#### Produces

If `.p` is null (`~`), `.q`. If `.p` is non-null, `.r`.

#### Discussion

It's bad style to use `?~` to test for any zero atom. Use it only for a true null, `~`.

#### Examples

```
> =foo ""

> ?~(foo 1 2)
1
```

***

## ?= "wuttis" <a href="#wuttis" id="wuttis"></a>

Test pattern match.

#### Syntax

Two arguments, fixed.

{% tabs %}
{% tab title="Tall form" %}

```hoon
?=  p
q
```

{% endtab %}

{% tab title="Wide form" %}

```hoon
?=(p q)
```

{% endtab %}

{% tab title="Irregular form" %}

{% endtab %}
{% endtabs %}

#### AST

```hoon
[%wtts p=spec q=wing]
```

#### Produces

`%.y` (true) if the noun at `.q` is in the type of `.p`; `%.n` (false) otherwise.

#### Discussion

`?=` is not as powerful as it might seem. For instance, it can't generate a loop -- you cannot (and should not) use it to test whether a `*` is a `(list @)`. Nor can it validate atomic auras.

Patterns should be as weak as possible. Unpack one layer of union at a time. Don't confirm things the type system knows.

For example, when matching from a tagged union for the type `[%foo p=@ q=[@ @]]`, the appropriate pattern is `[%foo *]`. You have one question, which is whether the head of the noun is `%foo`.

A common error is `find.$`, meaning `.p` is not a type.

#### Examples

```
> =bar [%foo %bar %baz]
> ?=([%foo *] bar)
%.y
```

***

## ?! "wutzap" <a href="#wutzap" id="wutzap"></a>

Logical NOT.

#### Syntax

One argument, fixed.

| Tall form | Wide form | Irregular form |
| --------- | --------- | -------------- |
| `?! p`    | `?!(p)`   | `!p`           |

#### AST

```hoon
[%wtzp p=hoon]
```

#### Expands to

```hoon
.=(| p)
```

#### Produces

The logical NOT of `.p`, which must evaluate to either `%.y` or `%.n`.

#### Examples

```
~zod:dojo> ?!(.=(1 2))
%.y

~zod:dojo> !&
%.n

~zod:dojo> !|
%.y

~zod:dojo> !(gth 5 6)
%.y
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.urbit.org/hoon/rune/wut.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
