Overview

Comparison to JS

Semicolon

JavaScriptReScript
Rules enforced by linter/formatterNo semicolon needed!

Comments

JavaScriptReScript
// Line commentSame
/* Comment */Same
/** Doc Comment *//** Before Types/Values */
/*** Standalone Doc Comment */

Variable

JavaScriptReScript
const x = 5;let x = 5
var x = y;No equivalent (thankfully)
let x = 5; x = x + 1;let x = ref(5); x := x.contents + 1

String & Character

JavaScriptReScript
"Hello world!"Same
'Hello world!'Strings must use "
"hello " + "world""hello " ++ "world"
`hello ${message}`Same
sql`select ${fnName};`Same

Boolean

JavaScriptReScript
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

JavaScriptReScript
3Same *
3.1415Same
3 + 4Same
3.0 + 4.53.0 +. 4.5
5 % 3mod(5, 3)

* JS has no distinction between integer and float.

Object/Record

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

Array

JavaScriptReScript
[1, 2, 3]Same
myArray[1] = 10Same
[1, "Bob", true](1, "Bob", true) *

* ReScript does not have heterogenous arrays. Use tuples or Untagged Variants instead.

Null

JavaScriptReScript
null, undefinedNone *

* Again, only a spiritual equivalent; we don't have nulls, nor null bugs! But we do have an option type for when you actually need nullability.

Function

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

Async Function / Await

JavaScriptReScript
async (arg) => {...}Same
async function named(arg) {...}let named = async (arg) => {...}
await somePromiseSame
async (arg): Promise<string> => {...}async (arg): string => {...} (note the return type)

Blocks

JavaScriptReScript
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 }

If-else

JavaScriptReScript
if (a) {b} else {c}if a {b} else {c} *
a ? b : cSame
switchswitch but super-powered pattern matching!

* Our conditionals are always expressions! You can write let result = if a {"hello"} else {"bye"}

Destructuring

JavaScriptReScript
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.

Loop

JavaScriptReScript
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) {...}while true {...}

JSX

JavaScriptReScript
<Comp message="hi" onClick={handler} />Same
<Comp message={message} /><Comp message /> *
<input checked /><input checked=true />
No children spread<Comp>...children</Comp>

* Argument punning!

Exception

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

* No finally.

Blocks

The last expression of a block delimited by {} implicitly returns (including function body). In JavaScript, this can only be simulated via an immediately-invoked function expression (since function bodies have their own local scope).

JavaScriptReScript
let result = (function() { const x = 23; const y = 34; return x + y; })();
let result = { let x = 23 let y = 34 x + y }

Common Features' JS Output

FeatureExampleJavaScript Output
String"Hello""Hello"
String Interpolation`Hello ${message}`"Hello " + message
Character (disrecommended)'x'120 (char code)
Integer23, -2323, -23
Float23.0, -23.023.0, -23.0
Integer Addition23 + 123 + 1
Float Addition23.0 +. 1.023.0 + 1.0
Integer Division/Multiplication2 / 23 * 12 / 23 * 1
Float Division/Multiplication2.0 /. 23.0 *. 1.02.0 / 23.0 * 1.0
Float Exponentiation2.0 ** 3.0Math.pow(2.0, 3.0)
String Concatenation"Hello " ++ "World""Hello " + "World"
Comparison>, <, >=, <=>, <, >=, <=
Boolean operation!, &&, ||!, &&, ||
Shallow and deep Equality===, =====, ==
List (disrecommended)list{1, 2, 3}{hd: 1, tl: {hd: 2, tl: {hd: 3, tl: 0}}}
List Prependlist{a1, a2, ...oldList}{hd: a1, tl: {hd: a2, tl: theRest}}
Array[1, 2, 3][1, 2, 3]
Recordtype t = {b: int}; let a = {b: 10}var a = {b: 10}
Multiline Comment/* Comment here */Not in output
Single line Comment// Comment hereNot in output

Note that this is a cleaned-up comparison table; a few examples' JavaScript output are slightly different in reality.