Table of contents
Please support this book: buy it (PDF, EPUB, MOBI) or donate
(Ad, please don’t block.)

A first look at ReasonML’s syntax

In this chapter, I want to give you a first impression of what ReasonML code looks like. Therefore: Don’t try to understand (yet) – proper explanations will be provided step by step in the following chapters.

This is ReasonML code:

/* A comment (no single-line comments, yet) */
/* You can /* nest */ comments */

/* Variable binding */
let myInt = 123;

/* Functions */
let id = x => x;
let add = (x, y) => x + y;

/* Defining a variant type */
type color = Red | Green | Blue;

/* A function that switches over a variant type */
let stringOfColor = (c: color) =>
  switch (c) {
  | Red => "Red"
  | Green => "Green"
  | Blue => "Blue"

/* Calling stringOfColor() */
stringOfColor(Red); /* "Red" */

Again: There is no need to understand what I’ve just shown you. But if you want to dig deeper right now, you can:

Most things are expressions

For example, you can use if-then-else almost anywhere:

let myBool = true;
id(if (myBool) "yes" else "no");

And you can use blocks almost anywhere, too:

let abcabc = {
  let abc = "abc";
  abc ++ abc; /* "abcabc" */

In fact, the following two expressions are equivalent:

if (myBool) "yes" else "no";
if (myBool) {
} else {

Semicolons matter

You may have noticed that there are many semicolons in the code in this chapter. Most of these are mandatory. Extra semicolons are allowed and ignored. Especially the interactive command line rtop will only evaluate expressions terminated with semicolons.

At first, it is a bit strange to even see semicolons after code blocks, but it makes sense, given that a code block is also an expression. With that knowledge, take another look at the two if expressions:

if (myBool) "yes" else "no";
if (myBool) {
} else {

The semicolon at the end of the first line looks logical. But then the semicolon at the very end is logical, too, because we have only replaced the expression "no" with a block.

Everything is camel-cased in ReasonML

ReasonML is based on OCaml, which uses snake-casing for lowercase names (create_resource) and camel-casing for uppercase names (StringUtilities). That’s why you’ll occasionally see snake-cased names.

But all new ReasonML code is camel-cased (StringUtilities, createResource).

Special prefixes and suffixes for variable names

A prefixed underscore means: don’t warn me about this variable not being used.

let f = (x, _y) => x;
  /* No warning about _y */

Suffixed apostrophes are legal (in math, x' means a modified version of x):

let x = 23;
let x' = x + 1;

Prefixed apostrophes are reserved for type variables (think generic types in C-style languages):

let len(arr: array('a)) = Array.length(arr);

Type variables are explained in the chapter on variant types. They are similar to generic types in C-style languages.