# Class

A class is a collection of objects, similar to **proper classes** in Set theory.

Any object satisfying the constraints of a class belongs to it. Therefore, an object does not have a single type.

A class is defined structurally from a type expression, and can optionally have constraint expressions to verify if the object satisfy the desired properties.

### Syntax

class_definition

## Show source

```
class_definition
= "class" "[" type_expression "]"
("{" pattern_matching_clause ("," pattern_matching_clause)* ","? "}")?
```

type_expression

## Show source

```
type_expression
= (type_expression "&" type_expression)
/ (type_expression "|" type_expression)
/ ("!" type_expression)
/ ("(" type_expression ")")
/ type_term
```

type_term

## Show source

```
type_term
= type_ref
/ type_literal
/ type_tuple
/ type_namedtuple
```

type_ref

## Show source

```
type_ref
= symbol_path ("<" type_expression ("," type_expression)* ","? ">")?
```

type_literal

## Show source

```
type_literal
= atom / bool / number / string
```

type_tuple

## Show source

```
type_tuple
= ( "(" ")" )
/ ( "(" type_expression "," ")" )
/ ( "(" type_expression ("," type_expression)+ ","? ")" )
```

type_namedtuple

## Show source

```
type_namedtuple
= ( "{" "}" )
/ ( "{" type_namedtuple_pair ("," type_namedtuple_pair)* ","? "}" )
```

type_namedtuple_pair

## Show source

```
type_namedtuple_pair
= identifier ":" type_expression
```

### Examples

```
let even: class[int] {
(n) -> n % 2 = 0,
};
let odd: class[int & !even];
```

```
let ok<t>: class[(@ok, t)];
let err<e>: class[(@error, e)];
let result<t, e>: class[ok<t> | err<e>];
```

### Semantics

Each clause of a class MUST evaluate to a boolean (`true`

or `false`

).

If an exception is thrown in the body of a clause, it SHOULD be ignored and be
equivalent to returning `false`

.