Reference
Surface Language
Look up syntax, contracts, layouts, algorithms, and exact behavior.
An OJaml program is a sequence of top-level let declarations, module type declarations, module declarations, top-level open declarations, record type declarations, and algebraic data type declarations with optional type parameters. A let declaration may be recursive, may bind parameters, may annotate those parameters, may carry a value annotation, and may be separated by optional double semicolons. Module declarations contain value bindings, nested modules, record types, and algebraic data types; module members are reached through qualified names such as Scores.total, Scores.Offsets.make, Geometry.point, or Geometry.Named, and open Geometry exposes immediate values, types, and constructors by short name when no local, top-level, or competing opened namespace owns that name. Module type declarations contain abstract type entries, concrete record or variant type manifests, and val signatures. Module ascription checks that an implementation exports every promised type and value at the declared type, and concrete manifests must match the implementation's field or constructor structure. Expressions include primitives, tuples, tuple projection, records, field access, variables, unary and binary operations, sequencing, forward pipelines, conditionals, local lets, local function bindings, local recursive function bindings, function application, anonymous functions, constructor application, and match expressions.
let main =
println "Hello, OJaml!"The surface syntax borrows the OCaml forms that support this compiler's goals without committing to the whole language. Function application is whitespace-based. Parentheses group expressions and represent unit when empty. Sequencing uses expr; expr, requires the left expression to return unit, and returns the right expression's type. Forward pipelines use value |> f and typecheck as f value, so the target must be a one-argument function after any ordinary application on the right has run. Structural records use { field = value; other = value } syntax, record type declarations use type person = { name: string; year: int }, algebraic data type declarations use type status = Pending | Done of int and type 'a option = None | Some of 'a, value annotations use let ada : person = ... or let value : int option = ..., parameter annotations use let describe (person : person) = ..., higher-order annotations use forms such as let apply (f : int -> int) = ..., and field access uses value.field. Comments are block comments with nesting support. Module-style names such as Map.get or Scores.total are lexed as identifiers, and open List or open Scores exposes values by short name; user modules also expose immediate type names and constructors by short name.
open List
open String
let main =
let words = split (concat "hello" " OJaml") " " in
String.length (head words) + List.length wordslet rec fact n =
match n with
| 0 -> 1
| 1 -> 1
| _ -> n * fact (n - 1)
let main =
let x = fact 5 in
if x > 100 then x else 0Every construct in the grammar maps to a direct AST node. That correspondence is an engineering choice: it keeps diagnostics precise, lets hover spans point back to real tokens, and lets later compilation passes switch on explicit node kinds instead of recovering meaning from parser artifacts.
- Lexed token kinds include ints, floats, strings, identifiers, keywords, operators, parentheses, braces, pipes, arrows, equals, separators, and EOF.
- Supported primitive values are int, float, bool, string, and unit; tuple expressions group values by position, zero-based postfix projection reads tuple elements, record type declarations name record shapes, algebraic data type declarations name constructor sets and type parameters, structural records group values by label, and fst/snd remain pair-specific helpers.
- Supported binary operators include int and float arithmetic, right-associative power **, mixed numeric comparisons, equality/inequality, short-circuit boolean conjunction/disjunction, int-only mod, and forward pipeline |>.
- Patterns cover int, float, string, bool, unit, tuple structure, record structure, list structure, fixed-length array structure, set structure, map structure, constructor structure, wildcard, and variable catch-all patterns.