This article was originally written with ReasonML. I updated it in May 2021 to use ReScript.
In ReScript, these two uses are completely separate structures and cannot overlap. ReScript is designed around managing both cases. For static objects there are records, and for “map” objects ReScript provides the
And now, let’s jump into what the containers actually are:
For simplicity, let’s first look at one of its inner modules:
Map object). Conceptually, it’s a series of key-value pairs. The keys are strings, and the values can be any type you want as long as they’re all the same type.
If you want to use a map in your code, you may think the first step is to create an empty one. Surprisingly, there is no
make function for
Belt.Map.String. Instead, you simply use the
Belt.Map.String.empty value (it’s not a function!). Because maps are immutable, you can reuse that value every time you need a “new” empty map.
If you’re not familiar with immutability, keep in mind that when you assign a value with a function like
Belt.Map.String.set, it returns a new map that has the new value. The original map will be unchanged. (Due to the way maps work behind the scenes, this is actually very efficient.)
Belt.Map.String will probably be most familiar at first. But you can also use
(You may wonder, why would I want to use an int map instead of an array? Immutability may be one benefit. Also, with a map, you can use negative integers as keys. You can also assign a value to
0 and then a value to
99, and you’ll get a map with just those values. In an array, if you do the same, you’ll get an array with 100 entries and 98 of them are
On the surface,
Belt.HashMap.Int) works similarly to
Belt.Map.Int). One key difference is that hashmaps are mutable. When you assign a value with the function
Belt.HashMap.String.set, it modifies the hashmap in-place.
In functional programming land, immutability is preferred, but structures like hashmaps are useful too. In some cases, a hashmap is more performant than a regular map. Both come with benefits and trade-offs, and both serve different purposes.
You’ll notice that there is a
Belt.HashMap.Int.make). They take one argument:
hintSize. That’s just your best guess as to how many keys the hashmap will have. The closer it is to the actual size of your data, the more performant your code will run. You don’t have to stress about it being exactly right.
Set object. They store a series of values that have to be unique. If you try to add a duplicate value, then the set will be unchanged. Like a Belt
Map, sets are immutable, so you usually don’t “make” them, just use
Belt.Set.Int.empty) instead. Updates will return a new set without modifying the original.
You probably noticed that I skipped the
Belt.Set modules and only explained their respective
Int inner-modules. The outer-modules let you use your own custom data types as your keys. (The
Int inner-modules largely exist for convenience because using strings and integers as keys is so common.)
Setting up your container with custom keys is a bit more complex and utilizes some advanced ReScript features. That will require a blog post for another time. Stay tuned!