Reason ifs are expressions; they're evaluated to their body's content:

let message = if (isMorning) { "Good morning!" } else { "Hello!" };

Note: an if-else expression without the final else branch implicitly gives (). So this:

if (showMenu) { displayMenu() };

is basically the same as:

if (showMenu) { displayMenu() } else { () };

Which is usually what you'd expect; displayMenu() should return unit too.

Here's another way to look at it. This is clearly wrong:

let result = if (showMenu) { 1 + 2 };

It'll give a type error, saying basically that the implicit else branch has the type unit while the if branch has type int. Intuitively, this makes sense: what would result's value be, if showMenu was false?

We also have ternary sugar.

let message = isMorning ? "Good morning!" : "Hello!";


if-else and ternary are much less used in Reason than in other languages; Pattern-matching kills a whole category of code that previously required conditionals. Prefer if-else if you only have, say, 2 branches.

Design Decisions

Reason ternary is just a sugar for the bool variant and a switch:

switch (isMorning) { | true => "Good morning!" | false => "Hello!" }

If you pass that through refmt, you'd get:

isMorning ? "Good morning!" : "Hello!";

Interested? Here's a blog post about the spirit of our refmt.