Expressions
This section provides an overview of the Cryptol’s expression syntax.
Calling Functions
f 2             // call `f` with parameter `2`
g x y           // call `g` with two parameters: `x` and `y`
h (x,y)         // call `h` with one parameter,  the pair `(x,y)`
Prefix Operators
-2              // call unary `-` with parameter `2`
- 2             // call unary `-` with parameter `2`
f (-2)          // call `f` with one argument: `-2`,  parens are important
-f 2            // call unary `-` with parameter `f 2`
- f 2           // call unary `-` with parameter `f 2`
Infix Functions
2 + 3           // call `+` with two parameters: `2` and `3`
2 + 3 * 5       // call `+` with two parameters: `2` and `3 * 5`
(+) 2 3         // call `+` with two parameters: `2` and `3`
f 2 + g 3       // call `+` with two parameters: `f 2` and `g 3`
- 2 + - 3       // call `+` with two parameters: `-2` and `-3`
- f 2 + - g 3
Type Annotations
Explicit type annotations may be added on expressions, patterns, and in argument definitions.
x : Bit         // specify that `x` has type `Bit`
f x : Bit       // specify that `f x` has type `Bit`
- f x : [8]     // specify that `- f x` has type `[8]`
2 + 3 : [8]     // specify that `2 + 3` has type `[8]`
\x -> x : [8]   // type annotation is on `x`, not the function
if x
  then y
  else z : Bit  // the type annotation is on `z`, not the whole `if`
[1..9 : [8]]    // specify that elements in `[1..9]` have type `[8]`
f (x : [8]) = x + 1   // type annotation on patterns
Todo
Patterns with type variables
Explicit Type Instantiation
If f is a polymorphic value with type:
f : { tyParam } tyParam
f = zero
you can evaluate f, passing it a type parameter:
f `{ tyParam = 13 }
Local Declarations
Local declarations have the weakest precedence of all expressions.
2 + x : [T]
  where
  type T = 8
  x      = 2          // `T` and `x` are in scope of `2 + x : `[T]`
if x then 1 else 2
  where x = 2         // `x` is in scope in the whole `if`
\y -> x + y
  where x = 2         // `y` is not in scope in the defintion of `x`
Block Arguments
When used as the last argument to a function call,
if and lambda expressions do not need parens:
f \x -> x       // call `f` with one argument `x -> x`
2 + if x
      then y
      else z    // call `+` with two arguments: `2` and `if ...`
Conditionals
The if ... then ... else construct can be used with
multiple branches. For example:
x = if y % 2 == 0 then 22 else 33
x = if y % 2 == 0 then 1
     | y % 3 == 0 then 2
     | y % 5 == 0 then 3
     else 7
Demoting Numeric Types to Values
The value corresponding to a numeric type may be accessed using the following notation:
`t
Here t should be a finite type expression with numeric kind. The resulting expression will be of a numeric base type, which is sufficiently large to accommodate the value of the type:
`t : {a} (Literal t a) => a
This backtick notation is syntax sugar for an application of the number primtive, so the above may be written as:
number`{t} : {a} (Literal t a) => a
If a type cannot be inferred from context, a suitable type will be automatically chosen if possible, usually Integer.