Skip to main content

Syntax Reference

caution

Fino's syntax is in a volatile state at the moment and this page is not updated frequently; it may be outdated. If it is, consider clicking Edit this page at the bottom and opening an issue or pull request.

The programming language's current syntax and grammar is informally specified here. Arbitrary spaces are allowed between lexemes, excluding newlines. Newlines are only allowed where explicitly stated. Indentation may be required. An indentation is any whitespace 4 characters or more longer than the previous indentation.

Declarations

Data Declarations

For now, must all be on a single line.

data Maybe a = Nothing | Just a

data Either a b = Left a | Right b

data Nat = Zero | Succ Nat

Type Alias Declarations

For now, must all be on a single line.

type Failable a = Either Error a

type Person = {name : str, age : i32}

Fn Declarations

Fn declarations are desugared to let declarations with lambdas and match expressions in the parser.

Type annotation is optional. If type annotation is given, a newline must be present after the type annotation.

If a newline is present after the fn <id> [: <type>], then all cases must be indented and on a new line.

fn main : unit -> unit
() = println "Hello, World!"

fn factorial
1 = 1
n = n * factorial (n - 1)

fn id x = x

Let Declarations

Type annotation is optional.

For now, no newlines allowed before =.

let x = y

let a: Type = expr

Trait Declarations

Impl Declarations

Expressions

Operators

Operators are desugared to regular function applications in the parser.

1 + 2
~x
92!

Variables

abc123
Qwe_'4

some.qualified.var

Literals

123
123.456
true
false
'a'
'\n'
"hello\t\n"
()

Function application

print "hello"
add 1 2
map (add 1) listOfIntegers
input ()

Lambdas (anonymous functions)

Lambdas with arity greater than one are desugared to multiple lambdas with arity one in the parser.

\x -> y
\n m -> n + m
\a b c -> a (b c)

Annotated Expressions

expression : Type
(3 + 4) : f32

Let Bindings

Newlines allowed before and after in.

let x = y in z

let var = 1 + 2
in (+) 1 var

let a = expr in
body

If Expression

Newlines allowed after if.

Newlines allowed before and after then and else.

if c then a else b

if c
then a
else b

if
c
then
a
else
b

if
c
then
a
else
b

Match Expressions

Indentation required after match <expr>.

Each branch must be indented and on a new line.

match expr
Just m => m
12 => a
true => b
false => c
() => d
x => e
_ => f

Do Notation

Newline must be present after do.

Each statement in the do block must be indented and on a new line.

fn main : unit -> unit
() = do
println "What is your name?"
let name = input ()
println ("Hello " + name + "!")

The above is equivalent to:

fn main : unit -> unit
() = let _ = println "What is your name?" in
let name = input () in
println ("Hello " + name + "!")

Mdo Notation

Similar to do notation, a newline must be present after mdo.

Each statement in the mdo block must be indented and on a new line.

fn failableOperation : a -> Either Error (Pair a b)
a = mdo
someFunc a
res <- someOtherFunc a
pure (Pair a res)

Patterns

Type constructor patterns, variable patterns, wildcard patterns, and literal patterns.

Maybe::Just a
Maybe::Just false
Either::Right ()
Maybe::Nothing

x
someVar

_

123
()
true
'c'

Miscellaneous

Imports

import a
import some.module
import control.monad.state

Exports

All exported identifiers must be on the same line, separated by a ,.

Exported modules must have their name prefixed by the module keyword.

import m
import abc.xyz

export someDef, fnAbc, module m, Maybe, module abc.xyz

Extern Declarations

extern builtin_add_i32 : i32 -> i32 -> i32