Reason
  • Docs
  • Try
  • API
  • Community
  • Blog
  • Languages iconEnglish
    • 日本語
    • Deutsch
    • Español
    • Français
    • 한국어
    • Português (Brasil)
    • Русский
    • Українська
    • 中文
    • 繁體中文
    • Help Translate
  • GitHub

›Language Basics

Intro

  • What & Why
  • Getting started

Setup

  • Installation
  • Editor Plugins
  • Format (refmt)

Language Basics

  • Overview
  • Let Bindings
  • Primitives
  • Basic Structures
  • Types
  • Records
  • Variants
  • Options and nullability
  • Functions
  • Recursion
  • Destructuring
  • Pattern Matching
  • Mutable Bindings
  • Loops
  • Modules

Advanced Features

  • JSX
  • External
  • Exception
  • Object

JavaScript

  • Melange
  • Interop
  • Syntax Cheatsheet
  • Pipe First
  • Promise
  • Libraries
  • Converting from JS

Extra

  • Frequently Asked Questions
  • Extra Goodies
  • REPL (rtop)
Edit

Overview

This is an overview of most language features in Reason. It does not explain them in detail, but should serve as a quick reference. Please see the guides on the left for additional details about each feature.

Let Bindings

Details: Let Bindings

FeatureExample
String valuelet hi = "Hello World";
Int valuelet count = 42;
Type annotation on bindinglet count: int = 42;
  • Note: Let bindings are immutable and cannot change once created.

Built In Types

Details: Primitives

FeatureExample
Intlet x: int = 10;
Floatlet x: float = 10.0;
Booleanlet x: bool = false;
Stringlet x: string = "ten";
Charlet x: char = 'c';
Unitlet x: unit = ();
Optionlet x: option(int) = Some(10);
Tuplelet x: (int, string) = (10, "ten");
Listlet x: list(int) = [1, 2, 3];
Arraylet x: array(int) = [|1, 2, 3|];
Functionslet x: (int, int) => int = (a, b) => a + b;

Strings

Details: Strings

FeatureExample
String"Hello"
String concatenation"Hello " ++ "World"
Character'x'
Character at indexlet x = "Hello"; x.[2];
  • String Functions: module String

Numbers

  • Details: Integer
  • Details: Float
FeatureExample
Integer23, -23
Integer operations23 + 1 - 7 * 2 / 5
Integer modulo13 mod 2
Float23.0, -23.0
Float operations23.0 +. 1.0 -. 7.0 *. 2.0 /. 5.0
Float exponentiation2.0 ** 3.0

Booleans and Logical Operators

Details: Boolean

FeatureExample
Boolean Valuestrue, false
Comparison>, <, >=, <=
Boolean operations!, &&, ||
Reference equality===, !==
Structural equality==, !=

If-Else Expressions

FeatureExample
If-Else expressionsif (condition) { a; } else { b; }
Ternary expressionscondition ? a : b;
  • Note: These are expressions and can be assigned to a variable: let x = if (condition) { a; } else { b; };

Functions

Details: Functions

FeatureExample
Function definitionlet divide = (a, b) => a / b;
Function callsdivide(6, 2); // 3
Named argumentslet divide = (~a, ~b) => a / b;
Calling named argumentsdivide(~a=6, ~b=2); // 3
Named argument punningdivide(~a, ~b);
Recursive functionslet rec infinite = () => infinite();

Advanced Functions

FeatureExample
Partial applicationlet divideTen = divide(10); divideTen(5); // 2
Partially applying out of orderlet half = divide(_, 2); half(10); // 5
Optional argumentslet print = (~prefix=?, text) => {...};
Optional arguments with defaultlet divide = (~a=100, ~b) => a / b;
Function chaining (pipe)32 |> half |> half; // 8

Function Types

FeatureExample
Inline typinglet divide = (a: int, b: int): int => a / b;
Standalone typetype intFn = (int, int) => int;
Using standalone typelet divide: intFn = (a, b) => a / b;
Typing optional argumentslet print = (~prefix: option(string)=?, text) => {...};

Implicit Return

There is no return keyword in Reason. The last expression in a block or function definition is the returned value.

let twentyThree = () => {
  let x = 10;
  let x = x + 10;
  /* x + 3 is the implicit return of the function. */
  x + 3;
};

Basic Structures

Details: Basic Structures

FeatureExample
List (Immutable)[1, 2, 3]
List add to front[a1, a2, ...theRest]
List concat[a1, a2] @ theRest
Array (Mutable)[|1, 2, 3|]
Array accesslet arr = [|1, 2, 3|]; arr[1];
Tuples(1, "hello")
  • List Functions: module List
  • Array Functions: module Array

Maps and Sets

There are several different ways to interact with Maps and Sets depending on the specific environment being used. In standard Reason code there are Map and Set modules:

  • module Map.Make
  • module Set.Make

When using BuckleScript belt exposes these modules:

  • module Belt.Map
  • module Belt.Set

There are also other libraries that will provide their own implementation of these data structures. Check the style guide of the project you are working in to determine which module to use.

Type Annotations

Any expression or argument may include a "type annotation". In most cases, type annotations are not necessary and the compiler will infer the types automatically. You may include type annotations to verify your own understanding against what the compiler infers.

FeatureExample
Expression type annotationlet x = (expression: int)
Annotation on let bindinglet x: int = expression;
Argument/return value annotationlet addOne = (a: int): int => a + 1;

Type Parameters

Types can be made generic with type parameters.

FeatureExample
Type parameterstype pair('a, 'b) = ('a, 'b);
Annotation with parameterslet x: pair(int, string) = (10, "ten");
String listlet x: list(string) = ["Hello", "World"];

Records

Details: Records

FeatureExample
Record definitiontype t = {foo: int, bar: string};
Record creationlet x = {foo: 10, bar: "hello"};
Record accessx.foo;
Record spreadlet y = {...x, bar: "world"};
Destructuringlet {foo, bar} = x;
Mutable record fieldstype t = {mutable baz: int}; let z = {baz: 10};
Mutable record updatesz.baz = 23;
With type parameterstype t('a) = {foo: 'a, bar: string};
  • Note: Record types are nominal. This means that two different record definitions (type x = {...};) with the exact same fields are not compatible. They cannot be used interchangeably and cannot be spread into each other.

Variants

Details: Variants

Variant types model values that may assume one of many known variations. This feature is similar to "enums" in other languages, but each variant form may optionally specify data that is carried along with it.

FeatureExample
Variant definitiontype t = | Foo | Bar;
Variants with argstype t = | Foo(string) | Bar(int);
With type parameterstype t('a) = | One('a) | Two('a, 'a);
Using a variantlet x = Two("Hello", "World");

Options

Details: Options

Options are a built-in variant that represent the presence or absence of a value. It is similar to the concept of "nullable" values in other languages. Options are used often.

FeatureExample
Definition (already defined)type option('a) = | None | Some('a);
Value that is presentlet x = Some("Hello World");
Value that is absentlet y = None;

Pattern Matching

Pattern matching is a very powerful feature in Reason. It matches against variants and ensures all cases are covered. Start matching using the switch keyword:

switch (foo) {
| Some(value) => doSomething(value)
| None => error()
}
FeatureExample
Basic case| Some(value) => doSomething(value)
When conditions| Some(value) when value > 10 => doSomething(value)
Catch-all case| _ => doSomething()
Matching lists| [a, b, ...rest] => doSomething(rest)
Matching records| {foo: value} => doSomething(value)
Matching literals| "Hello" => handleHello()

Unit

The special "unit" value (written ()) represents something that never has any meaningful value (this is distinct from options which may have a value). Functions usually indicate that they perform a side effect by returning a unit value.

FeatureExample
Creating a unitlet x = ();
Passing to a functionfn(a, b, ());
Unit as only argumentlet fn = () => 1; fn();

Refs

Details: Mutable Bindings

Refs allow mutable "variables" in your program. They are a thin wrapper around a record with a mutable field called contents.

FeatureExample
Type (already defined)type ref('a) = {mutable contents: 'a};
Ref creationlet x = ref(10); or let x = {contents: 10};
Ref accessx^; or x.contents;
Ref updatex := 20; or x.contents = 20;

Loops

Details: Loops

Loops are discouraged in most cases. Instead functional programming patterns like map, filter, or reduce can usually be used in their place.

FeatureExample
Whilewhile (condition) {...}
For (incrementing)for (i in 0 to 9) {...} (inclusive)
For (decrementing)for (i in 9 downto 0) {...} (inclusive)
  • Note: There is no break or early returns in Reason. Use a ref containing a bool for break-like behavior: let break = ref(false); while (!break^ && condition) {...};

Modules

Details: Modules

Modules are a way to group types and values. Each Reason file implicitly creates a module of the same name. Each type definition and let binding in a module automatically becomes a "member" of that module which can be accessed by other modules. Modules can also be nested using the module keyword.

FeatureExample
Module creationmodule Foo = { let bar = 10; };
Module member accessFoo.bar;
Module typesmodule type Foo = { let bar: int; };

Functors

Functors are like functions that create modules. This is an advanced topic that can be very powerful. Here is a basic example:

module type Stringable = {
  type t;
  let toString: (t) => string;
};

module Printer = (Item: Stringable) => {
  let print = (t: Item.t) => {
    print_endline(Item.toString(t));
  };

  let printList = (list: list(Item.t)) => {
    list
    |> List.map(Item.toString)
    |> String.concat(", ")
    |> print_endline;
  };
};

module IntPrinter = Printer({
  type t = int;
  let toString = string_of_int;
});

IntPrinter.print(10); // 10
IntPrinter.printList([1, 2, 3]); // 1, 2, 3

Comments

FeatureExample
Multiline Comment/* Comment here */
Single line Comment// Comment here
← Format (refmt)Let Bindings →
  • Let Bindings
  • Built In Types
  • Strings
  • Numbers
  • Booleans and Logical Operators
  • If-Else Expressions
  • Functions
    • Advanced Functions
    • Function Types
  • Implicit Return
  • Basic Structures
  • Maps and Sets
  • Type Annotations
  • Type Parameters
  • Records
  • Variants
  • Options
  • Pattern Matching
  • Unit
  • Refs
  • Loops
  • Modules
  • Functors
  • Comments