______ @ @
| | _ ___ _
| /\/\ | | | | _ | | |
|/ \| |_| |/ \| |_|
Mini is a WIP functional (ML-style) programming language that has Scheme-like aspects. Currently, it features:
- GADTs
- HM-style type inference
- compilation to C via CPS conversion
- a module system
And some planned features are:
- first-class modules
- record types
- modular implicits
Mini syntax is fairly spartan, being a toy compiler; the only constructs it offers are fix
, let
, ind
(datatype declaration), match
, type annotation, lam
, and function application.
(fix (fn1 args def) (fn2 args def) expr)
defines the (recursive) functionsfn1
andfn2
with arguments (like(a b c)
) inexpr
.(let (name1 def) (name2 def) expr)
evaluates bothdef
s, then evaluatesexpr
withname1
andname2
referring to the output of the relevantdef
. You can omitname
in favour of_
ifname
is unused inexpr
.(match x (case1 -> branch1) (case2 -> branch2))
matchesx
with one of the cases of thematch
, and performs the correspondingbranch
- you can omit the outermost brackets on cases.(lam (x y) expr)
denotes a lambda with (curried) argumentsx
andy
, which evaluatesexpr
with those arguments when called.(a :: t)
declares to the compiler that the (bracketed) expressiona
is of typet
.
(ind Name (case1 :: type1) (case2 :: type2))
declares a GADT with (capitalised) nameName
which has constructorscase1
of typetype1
, andcase2
of typetype2
.(fix (fn1 args def) (fn2 args def))
is like the expression-levelfix
, except the resultant expression is ommitted.(let (name1 def) (name2 def))
is like the expression-levellet
, except the resultant expression is ommitted.(fn1 args def)
is shorthand for(fix (fn1 args def))
(fix ((f :: a -> b -> a) (a b) a) exp)
annotates the created lambdas whenf
is elaborated.(let ((a :: b) b) exp)
is equivalent to(let (a (b :: b)) exp)
.
Here is the factorial function in Mini:
(fac x match (eq x 0)
(true -> 1)
(false -> * x (fac (- x 1))))
(let
(_ putint (fac 6)))
i.e. fac
is a function that takes one argument, x
, and checks if x
equals 0
:
- if it does,
fac
returns1
- if it doesn't,
fac
returns x times the factorial ofx
's predecessor
The program then calculates fac 6
, and outputs it.
This demonstrates some of Mini's key features;
- tail-call optimisation (a Mini program will never* stack overflow)
- pattern matching
- top-level expressions are executed when the module is called
The (let (_ putint (fac 6)))
top-level expression shows how anonymized - hence the _
- let-expressions can be used to perform side-effecting operations without having to use sequencing operators like (seq (a b) b)
.
* - provided my garbage collector works!