On this page:
Boolean
False
True
||
||
||
||
any
any
&&
&&
&&
&&
all
all
!
!
!
8.18

7.1 Booleans🔗ℹ

annotation

Boolean

Matches #true or #false.

annotation

False

 

annotation

True

Matches only #false and values other than #false, respectively.

> #false is_a False

#true

> #false is_a True

#false

> 42 is_a True

#true

Produces the value of left_expr if it is non-#false, otherwise produces the value(s) of right_expr. The right_expr is evaluated in tail position with respect to the || form, if evaluated at all.

The static information of a || expression is the statinfo_meta.or of static information from left_expr and right_expr. Since a #false result from left_expr is never returned, if left_expr has static information from maybe(annot), the static information of annot is used, instead.

The || operator can also form a repetition.

binding operator

left_bind || right_bind

 

~order: logical_disjunction

Matches if either left_bind or right_bind matches. No identifiers are bound after a successful match, however. In other words, left_bind and right_bind are used only in matching mode, and implied conversions might be skipped.

> fun check_shape(v):

    match v

    | [x] || [x, y, z]: #true

    | ~else: #false

> check_shape([1])

#true

> check_shape([1, 2, 3])

#true

> check_shape([1, 2])

#false

Creates an annotation that accepts a value satisfying either left_annot or right_annot. The static information implied by the annotation is the statinfo_meta.or of information for left_annot and right_annot, which means that information for a key must appear in both for the key to be part of the implied annotation (except that None is treated specially).

The annotations are checked in other. Either or both of left_annot and right_annot can be a converter annotation, in which case the conversion result of the first satisfied annotation is used.

> 1 is_a (String || Int)

#true

> 1 is_a (Boolean || Int)

#true

reducer

any

 

expression

any(expr_or_splice, ...)

 

expr_or_splice

 = 

expr

 | 

repet , ellipses

The any form as a reducer is like ||: it stops an iteration as soon as a non-#false value is produced for an element and it returns that value, otherwise it returns #false.

> for any (i in 0..10):

    i == 5 && to_string(i)

"5"

> for any (i in 0..10):

    i == 10

#false

The any expression form is like ||, but any supports repetition arguments, and it stops iterating through a repetition as soon as a non-#false result is found. When the last expr_or_splice is an expr, it is in tail position. When no expr_or_splice is provided, the result is #false. The static information of an any expression is derived as in ||, but generalized to multiple arguments.

> def [x, ...] = [1, 2, 3, 4]

> any(x > 2 && x, ...)

3

Produces #false if the value of left_expr is #false, otherwise produces the value(s) of right_expr. The right_expr is evaluated in tail position with respect to the && form, if evaluated at all.

The static information of a && expression is like that of maybe(annot) if the static information of right_expr is like that of annot.

The && operator can also form a repetition.

binding operator

left_bind && right_bind

 

~order: logical_conjunction

Matches when both left_bind and right_bind match. All identifiers from bindings are available after the match, and static information from left_bind is propagated to right_bind (but not the other way around).

See where for a different kind of “and” binding that allows the right-hand side to refer to bindings from the left-hand side.

> class Posn(x, y)

> fun three_xs(v):

    match v

    | [_, _, _] && [Posn(x, _), ...]: [x, ...]

    | ~else: #false

> three_xs([Posn(1, 2), Posn(3, 4), Posn(5, 6)])

[1, 3, 5]

> three_xs([Posn(1, 2), Posn(3, 4)])

#false

> three_xs([Posn(1, 2), Posn(3, 4), "no"])

#false

Creates an annotation that accepts a value satisfying both left_annot and right_annot.

When left_annot and right_annot are predicate annotations, the static information implied by the annotation is the statinfo_meta.and of information for left_annot and right_annot, where information from right_annot takes precedence in cases where both supply values for the same static-information key.

If left_annot or right_annot is a converter annotation, the left_annot conversion is applied first, and its result is the input to right_annot, and the result of right_annot is the result for the for the overall annotation created by &&. When the overall annotation is used only for matching, the conversion part of right_annot is skipped, but the conversion part of left_annot must be performed.

> 1 is_a (String && Int)

#false

> Pair(1, "hello") is_a (Pair.of(Int, Any) && Pair.of(Any, String))

#true

> 1 :: (converting(fun (n): n+1) && converting(fun (n): -n))

-2

reducer

all

 

expression

all(expr_or_splice, ...)

The all form as a reducer is like &&: it stops an iteration as soon as #false is produced for an element and it returns #false, otherwise it returns the result of the last iteration or #true if no iteration is done.

> for all (i in 0..10):

    i == 5

#false

> for all (i in 0..10):

    i < 10 && to_string(i)

"9"

The all expression form is like &&, but all supports repetition arguments, and it stops iterating through a repetition as soon as a #false result is found. When the last expr_or_splice is a expr, it is in tail position. When no expr_or_splice is provided, the result is #true. The static information of an all expression is derived as in &&, but generalized to multiple arguments.

> def [x, ...] = [1, 2, 3, 4]

> all(x < 2, ...)

#false

operator

operator (! (v :: Any)) :: Boolean

 

~order: logical_negation

 

expression

expr !in expr

 

repetition

repet !in repet

 

expression

expr !is_now expr

 

repetition

repet !is_now repet

 

expression

expr !is_a annot

 

repetition

repet !is_a annot

 

expression

expr !matches bind

 

repetition

repet !matches bind

 

~order: equivalence

The prefix ! operator produces #true if v is #false, #false otherwise.

As an infix operator, ! modifies in, is_now, is_a, or matches. Any other infix use of ! is an error.

> !#false

#true

> !#true

#false

> !"false"

#false

> 1 !in [0, 2, 4]

#true

binding operator

! bind

 

~order: logical_negation

Matches if bind does not match. Because bind does not match, no identifiers are bound.

> fun

  | is_two_list(![x, y]): #false

  | is_two_list(_): #true

> is_two_list([1])

#false

> is_two_list([1, 2])

#true

> is_two_list([1, 2, 3])

#false

annotation

! annot

 

~order: logical_negation

Creates an annotation that accepts a value not satisfying annot. Because annot is not satisfied, no conversion is performed.

> [1, 2, 3] is_a !List

#false

> PairList[1, 2, 3] is_a !List

#true