title | description | canonical |
---|---|---|
If-Else & Loops | If, else, ternary, for, and while | /docs/manual/v11.0.0/control-flow |
ReScript supports if
, else
, ternary expression (a ? b : c
), for
and while
.
ReScript also supports our famous pattern matching, which will be covered in its own section
Unlike its JavaScript counterpart, ReScript's if
is an expression; they evaluate to their body's content:
<CodeTab labels={["ReScript", "JS Output"]}>
letmessage=ifisMorning { "Good morning!" } else { "Hello!" }
varmessage=isMorning ? "Good morning!" : "Hello!";
Note: an if-else
expression without the final else
branch implicitly gives ()
(aka the unit
type). So this:
<CodeTab labels={["ReScript", "JS Output"]}>
ifshowMenu { displayMenu() }
if(showMenu){displayMenu();}
is basically the same as:
<CodeTab labels={["ReScript", "JS Output"]}>
ifshowMenu { displayMenu() } else { () }
if(showMenu){displayMenu()}
Here's another way to look at it. This is clearly wrong:
letresult=ifshowMenu { 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, but we encourage you to prefer if-else when possible.
<CodeTab labels={["ReScript", "JS Output"]}>
letmessage=isMorning ? "Good morning!" : "Hello!"
varmessage=isMorning ? "Good morning!" : "Hello!";
if-else
and ternary are much less used in ReScript than in other languages; Pattern-matching kills a whole category of code that previously required conditionals.
For loops iterate from a starting value up to (and including) the ending value.
<CodeTab labels={["ReScript", "JS Output"]}>
foriinstartValueInclusivetoendValueInclusive { Console.log(i) }
for(vari=startValueInclusive;i<=endValueInclusive;++i){console.log(i);}
<CodeTab labels={["ReScript", "JS Output"]}>
// prints: 1 2 3, one per lineforxin1to3 { Console.log(x) }
for(varx=1;x<=3;++x){console.log(x);}
You can make the for
loop count in the opposite direction by using downto
.
<CodeTab labels={["ReScript", "JS Output"]}>
foriinstartValueInclusivedowntoendValueInclusive { Console.log(i) }
for(vari=startValueInclusive;i>=endValueInclusive;--i){console.log(i);}
<CodeTab labels={["ReScript", "JS Output"]}>
// prints: 3 2 1, one per lineforxin3downto1 { Console.log(x) }
for(varx=3;x>=1;--x){console.log(x);}
While loops execute its body code block while its condition is true.
<CodeTab labels={["ReScript", "JS Output"]}>
whiletestCondition { // body here }
while(testCondition){// body here}
There's no loop-breaking break
keyword (nor early return
from functions, for that matter) in ReScript. However, we can break out of a while loop easily through using a mutable binding.
<CodeTab labels={["ReScript", "JS Output"]}>
letbreak=ref(false) while!break.contents { ifMath.random() > 0.3 { break:=true } else { Console.log("Still running") } }
var$$break={contents: false};while(!$$break.contents){if(Math.random()>0.3){$$break.contents=true;}else{console.log("Still running");}};