Docs / Language Manual / SyntaxCheatsheet

Syntax Cheatsheet

Variable

JavaScriptReason
const x = 5;let x = 5;
var x = y;No equivalent (thankfully)
let x = 5; x = x + 1;let x = ref(5); x := x^ + 1;

String & Character

JavaScriptReason
"Hello world!"Same
'Hello world!'Strings must use "
Characters are strings'a'
"hello " + "world""hello " ++ "world"

Boolean

JavaScriptReason
true, falseSame
!trueSame
||, &&, <=, >=, <, >Same
a === b, a !== bSame
No deep equality (recursive compare)a == b, a != b
a == bNo equality with implicit casting (thankfully)

Number

JavaScriptReason
3Same
3.1415Same
3 + 4Same
3.0 + 4.53.0 +. 4.5
5 % 35 mod 3

* JS has no distinction between integer and float.

Object/Record

JavaScriptReason
no static typestype point = {x: int, mutable y: int}
{x: 30, y: 20}Same *
point.xSame
point.y = 30;Same
{...point, x: 30}Same

Array

JavaScriptReason
[1, 2, 3][|1, 2, 3|]
myArray[1] = 10Same
[1, "Bob", true] *(1, "Bob", true)
No immutable list[1, 2, 3]

* We can simulate tuples in JavaScript with arrays, because JavaScript arrays can contain multiple types of elements.

Null

JavaScriptReason
null, undefinedNone *

* Again, only a spiritual equivalent; Reason doesn't have nulls, nor null bugs! But it does have an option type for when you actually need nullability.

Function

JavaScriptReason
arg => retVal(arg) => retVal
function named(arg) {...}let named = (arg) => ...
const f = function(arg) {...}let f = (arg) => ...
add(4, add(5, 6))Same

Blocks

JavaScriptReason
const myFun = (x, y) => {
  const doubleX = x + x;
  const doubleY = y + y;
  return doubleX + doubleY
};
let myFun = (x, y) => {
  let doubleX = x + x;
  let doubleY = y + y;
  doubleX + doubleY
};

Currying

JavaScriptReason
let add = a => b => a + blet add = (a, b) => a + b

Both JavaScript and Reason support currying, but Reason currying is built-in and optimized to avoid intermediate function allocation & calls, whenever possible.

If-else

JavaScriptReason
if (a) {b} else {c}Same *
a ? b : cSame
switchswitch but super-powered!

* Reason conditionals are always expressions!

Destructuring

JavaScriptReason
const {a, b} = datalet {a, b} = data
const [a, b] = datalet [|a, b|] = data *
const {a: aa, b: bb} = datalet {a: aa, b: bb} = data

* Gives good compiler warning that data might not be of length 2. Switch to pattern-matching instead.

Loop

JavaScriptReason
for (let i = 0; i <= 10; i++) {...}for (i in 0 to 10) {...}
for (let i = 10; i >= 0; i--) {...}for (i in 10 downto 0) {...}
while (true) {...}Same

JSX

JavaScriptReason
<Foo bar=1 baz="hi" onClick={bla} />Same
<Foo bar=bar /><Foo bar /> *
<input checked /><input checked=true />
No children spread<Foo>...children</Foo>

* Argument punning!

Exception

JavaScriptReason
throw new SomeError(...)raise(SomeError(...))
try {a} catch (Err) {...} finally {...}try (a) { | Err => ...} *

* No finally.

Blocks

In Reason, "sequence expressions" are created with {} and evaluate to their last statement. In JavaScript, this can be simulated via an immediately-invoked function expression (since function bodies have their own local scope).

JavaScriptReason
let res = (function() {
  const x = 23;
  const y = 34;
  return x + y;
})();
let res = {
  let x = 23;
  let y = 34;
  x + y
};

Comments

JavaScriptReason
/* Comment */Same
// Line commentSame