Module Belt

module Belt: sig .. end
A stdlib shipped with BuckleScript

This stdlib is still in beta status, but we encourage you to try it out and provide feedback.

Motivation

The motivation of creating such library is to provide BuckleScript users a better end-to-end user experience, since the original OCaml stdlib was not written with JS platform in mind, below are a list of areas this lib aims to improve:

  1. 1. Consistency in name convention: camlCase, and arguments order
  2. 2. Exception thrown functions are all suffixed with Exn, e.g, getExn
  3. 3. Better performance and smaller code size running on JS platform

Name Convention

For higher order functions, it will be suffixed U if it takes uncurried callback.

      val forEach  : 'a t -> ('a -> unit) -> unit
      val forEachU : 'a t -> ('a -> unit [@bs]) -> unit
    

In general, uncurried version will be faster, but it may be less familiar to people who have a background in functional programming.

A special encoding for collection safety

When we create a collection library for a custom data type, take Set for example, suppose its element type is a pair of ints, it needs a custom compare function. However, the Set could not just be typed as Set.t (int * int) , its customized compare function needs to be manifested in the signature, otherwise, if the user create another customized compare function, and the two collection would mix which would result in runtime error.

The original OCaml stdlib solved the problem using functor which is a big closure in runtime; it makes dead code elimination much harder. We introduced a phantom type to solve the problem

      module Comparable1 = Belt.Id.MakeComparable(struct
        type t = int * int
        let cmp (a0, a1) (b0, b1) =
          match Pervasives.compare a0 b0 with
          | 0 -> Pervasives.compare a1 b1
          | c -> c
      end)

    let mySet1 = Belt.Set.make ~id:(module Comparable1)

    module Comparable2 = Belt.Id.MakeComparable(struct
      type t = int * int
      let cmp (a0, a1) (b0, b1) =
        match Pervasives.compare a0 b0 with
        | 0 -> Pervasives.compare a1 b1
        | c -> c
    end)

    let mySet2 = Belt.Set.make ~id:(module Comparable2)
    

Here, the compiler would infer mySet1 and mySet2 having different type, so e.g. a `merge` operation that tries to merge these two sets will correctly fail.

      val mySet1 : ((int * int), Comparable1.identity) t
      val mySet2 : ((int * int), Comparable2.identity) t
    

Comparable1.identity and Comparable2.identity are not the same using our encoding scheme.

Collection Hierarchy

In general, we provide a generic collection module, but also create specialized modules for commonly used data type, take Belt.Set for example

      Belt.Set
      Belt.Set.Int
      Belt.Set.String
    

The specialized module Belt.Set.Int, Belt.Set.String is in general more efficient.

Currently, both Belt_Set and Belt.Set are accessible to users for some technical reasons, we strongly recommend users stick to qualified import, Belt.Sort, we may hide the internal, i.e, Belt_Set in the future


module Id: Belt_Id
Belt.Id

Provide utilities to create identified comparators or hashes for data structures used below.

It create a unique identifier per module of functions so that different data structures with slightly different comparison functions won't mix

module Array: Belt_Array
Belt.Array

mutable array: Utilities functions

module SortArray: Belt_SortArray
Belt.SortArray

The top level provides some generic sort related utilities.

It also has two specialized inner modules Belt.SortArray.Int and Belt.SortArray.String

module MutableQueue: Belt_MutableQueue
Belt.MutableQueue

An FIFO(first in first out) queue data structure

module MutableStack: Belt_MutableStack
Belt.MutableStack

An FILO(first in last out) stack data structure

module List: Belt_List
Belt.List

Utilities for List data type

module Range: Belt_Range
Belt.Range

Utilities for a closed range (from, start)

module Set: Belt_Set
Belt.Set

The top level provides generic immutable set operations.

It also has three specialized inner modules Belt.Set.Int, Belt.Set.String and

Belt.Set.Dict: This module separates data from function which is more verbose but slightly more efficient

module Map: Belt_Map
Belt.Map,

The top level provides generic immutable map operations.

It also has three specialized inner modules Belt.Map.Int, Belt.Map.String and

Belt.Map.Dict: This module separates data from function which is more verbose but slightly more efficient

module MutableSet: Belt_MutableSet
Belt.MutableSet

The top level provides generic mutable set operations.

It also has two specialized inner modules Belt.MutableSet.Int and Belt.MutableSet.String

module MutableMap: Belt_MutableMap
Belt.MutableMap

The top level provides generic mutable map operations.

It also has two specialized inner modules Belt.MutableMap.Int and Belt.MutableMap.String

module HashSet: Belt_HashSet
Belt.HashSet

The top level provides generic mutable hash set operations.

It also has two specialized inner modules Belt.HashSet.Int and Belt.HashSet.String

module HashMap: Belt_HashMap
Belt.HashMap

The top level provides generic mutable hash map operations.

It also has two specialized inner modules Belt.HashMap.Int and Belt.HashMap.String

module Option: Belt_Option
Belt.Option

Utilities for option data type.

module Result: Belt_Result
module Debug: Belt_Debug
Belt.Debug

Utilities for set up debugging