# Examples
```
fn returnsFortyTwo(a in 'int, b in 'int) returns 'int
42
```
```
fn returnsFortyTwo(a: 'int, b: 'int) returns 'int[crashable]
if a == 42 then crash else 42
```
```
fn printsHello() returns 'nothing[stdout]
println "hello"
```
```
fn printsManyThings(a: is Iterable(is Showable)) returns 'nothing[complexity precise a]
foreach a println
```
```
fn sometimesPrintsThings(a: 'list['int]) returns 'nothing[worstcase a, bestcase 0, stdout]
any a printIfNot42
fn printIfNot42(a: 'int) returns bool[stdout]
if a == 42 then return true else [print "hello"]
```
```
type bool = true | false
type int = 0..
type non_empty_list 'T = first_value 'T, rest: list 'T
```
```
{- TODO: this syntax is kind of rough. How is this an expr?
Do we need generator funcs?
-}
constraint prime a: 'int = forall (x in 'int < a) (a / x is 'int holds)
```
# Expressions
## If
```bnf
<if> ::= "if" <expr> "then" <expr> <else>
<else> ::= "else" <expr>
| ε
```
## Function Call
```
<call> ::= ident <args>
<args> ::= <expr> <args>
| ε
```
## let..in
```
<let_in> ::= "let" <assignment>+
"in" <expr>
<assignment> ::= ident <type_annotation>? "=" <expr>
<type_annotation> ::= "in" <ident><effects>?
<effects> ::= "[" <effect>+ "]"
<effect> ::= ident <effect_params>
```
# Declarations
## Type
```
<data_type> ::= "data" "type" ident "=" <named_field>*
<named_field> ::= ident "in" ident <effects>?
<sum_type> ::= "sum" "type" ident "=" <named_variant>*
<named_variant> ::= ident <contained_ty>?
<contained_ty> ::= ident <effects>?
```
## Function
```
<fn_decl> ::= <fn_signature> <expr>
<fn_signature> ::= "fn" ident <params> "returns" ident <effects>?
```
## Constraint
```
<constraint_decl> ::= "constraint" ident <constraint_param>* = <constraint_body>
<constraint_param> ::= ident ident? <effects>?
<constraint_body> ::= "intrinsic"
| <expr>
```
## Typeclass
```
<typeclass> ::= "typeclass" ident <fn_signature>*
```
```
<instance_of> ::= ident "is" "instance" "of" <typeclass> <fn_decl>*
```
## Sugar
### field access lambda
```
_.field_name
// is the same as
\x -> x.field_name
```