Meet the Toplevel
Before we draw a single pixel, meet the tool you'll use every day of this quest: a live conversation with the OCaml compiler — running right here in this page.
You will be able to…
- Evaluate OCaml expressions and read the compiler's answers
- Tell apart the four starter types:
int,float,string,bool - Name values with
let - Print text with
print_endline
Your first spell
The box below is a real OCaml 5.5 engine, compiled to JavaScript so it runs inside your browser. Nothing to install. Press Run (or Ctrl+Enter) and watch what comes back.
The engine answers something like:
Read it right to left: the value is 2, and its
type is int (a whole number). The - just
means "you didn't give this a name". In OCaml, everything you type is
an expression, and every expression evaluates to a value
with a type. That sentence is half of this whole course.
The four starter types
Games juggle numbers, text and yes/no facts all day: scores, speeds,
player names, "is the door open?". Here's how OCaml spells them — this is
a transcript of a toplevel session (the # is the prompt,
like the $ in a shell):
int— whole numbers. Operators:+ - * /andmod.float— decimal numbers. Operators end with a dot:+. -. *. /.string— text in double quotes. Glue two together with^.bool—trueorfalse. Comparisons like=,<,>=make them.
Yes, + and +. are different operators, and
OCaml refuses to mix them. Let's break it on purpose — run this
and read the error like a detective:
The compiler says the 2.5 has type float but
was expected to have type int, because
+ only works on ints. This strictness feels fussy today; by
Phase 2 it will be catching your game bugs before they exist. To fix it
you'd write 1.0 +. 2.5 — or convert:
float_of_int 1 +. 2.5.
Naming things with let
Answers marked - vanish into the sand. To keep a value,
bind it to a name:
Now the answers read val lives : int = 3 — a named value.
Time for your first real exercise. From here on, the Check button
compiles your code in a fresh environment and runs hidden tests against
it. Green means XP.
Define a value named answer equal to six times seven.
Use the multiplication operator, not the number 42 itself — let the
machine do the maths.
let name = expression.* : try let answer = 6 * 7.A health potion holds 2.5 litres. Your hero drinks
three of them, plus a 0.25-litre espresso of courage.
Define litres, a float with the total amount
drunk. Remember: float operators wear a dot.
*. and add with +. — both need the dot for floats.2.5 *. 3.0 +. 0.25 — note 3.0, not 3: no mixing ints into float maths.Strings: the ^ glue
Text joins with the caret operator. Run this, then make it your own:
Keep the given hero binding. Build
battle_cry so it reads exactly
For Camelot and Maks! — using ^ and the
hero value, not by typing the name again.
"For Camelot and ", the hero, and "!"."For Camelot and " ^ hero ^ "!" — mind the space after and.Saying it out loud: print_endline
The - : type = value answers are the toplevel being
helpful. To make your program actually print — like a game
printing "LEVEL UP!" — call print_endline, which outputs a
string plus a newline:
That let () = looks odd for now — read it as "do this,
keep nothing". print_endline returns the boring value
() (type unit, OCaml's "nothing to report"), and
we bind it to the pattern () to say we expected that.
Print exactly these two lines, using two
print_endline calls:
The tournament begins! Player one: ready
let () = print_endline "…" lines, in order.Deeper: can I change a let later?
No — and that's a feature. A let binding is not a
variable-in-a-box like in Python or JavaScript; it's a name for a
value, forever. You can shadow it (bind the same name to a
new value), but the old value never mutates behind your back. Phase 2
builds entire game worlds on this idea: instead of changing the world,
you compute a new world every tick. Determinism, replays and
fearless refactoring all fall out of it.
Checkpoint quiz
Loot collected
- The toplevel evaluates expressions into values with types — and tells you both.
int,float,string,bool; float operators wear a dot; strings glue with^.letnames values; names don't mutate.print_endlineprints; it returns():unit.
Next: teach the machine new tricks — functions, the verbs of your game.