MinCaml is a subset of ML. Except for some details such as priority and parentheses, it has the following syntax.

e ::= | expressions |

c | constants |

op(e_{1}, ..., e_{n}) |
primitive operations |

if e_{1} then e_{2} else e_{3} |
conditional branches |

let x = e_{1} in e_{2} |
variable definitions |

x | variables |

let rec x y_{1} ... y_{n} = e_{1} in e_{2} |
function definitions (mutually recursive) |

e e_{1} ... e_{n} |
function applications |

(e_{1}, ..., e_{n}) |
tuple creations |

let (x_{1}, ..., x_{n}) = e_{1} in e_{2} |
read from tuples |

Array.create e_{1} e_{2} |
array creations |

e_{1}.(e_{2}) |
read from arrays |

e_{1}.(e_{2}) <- e_{3} |
write to arrays |

It is expressed as ML data type `Syntax.t` in module `syntax.ml`. Expressions (such as `let` and `let rec`) defining new variables also include their types, which are not shown above. Those types are expressed by `Type.t`, defined in `type.ml`.

T ::= | types |

π | primitive types |

T_{1} -> ... -> T_{n} -> T |
function types |

T_{1} * ... * T_{n} |
tuple types |

T array |
array types |

α | type variables |

The last "type variables" will be used in type inference.

By the way, the MinCaml compiler does not automatically support so-called partial application of curried functions. That is, every function application needs all arguments at once. If you want partial application, you need to define the intermediate function by hand, like `let rec f_123 x = f 123 x in f_123`. (If you know the Scheme language, it is similar in this respect.)

Also, there are no "reference cells," which are necessary for imperative programming, but they can be substituted by arrays with only one element. Specifically, `ref e` can be substituted with `Array.create 1 e`, `!e` with `e.(0)`, and `e _{1} := e_{2}` with