The Js module mostly contains Reason bindings to standard JavaScript APIs like console.log, or the JavaScript String, Date, and Promise classes.
Belt is the standard lib, and right now it mostly implements something that cannot be done with Js: Option, Result and some collections. They do plan to implement Belt.Script, but maybe most of the Js will still remain, because those are zero-cost bindings, while the Belt modules are not.
As for Array vs Array2, those have different argument order. Array2, being data-first, is more future-friendly, but I doubt the name stays
The Js.Array2 module was supposed to be hidden but unfortunately our documentation tool exposed it and people started using it. But yes, it’s the recommended version over Js.Array and Pervasives.Array.
Belt.Array has a bigger runtime and isn’t idiomatic JS. Slightly different use-cases. This should be cleaned up. Sorry about that…
Adding another one in here - the Array. methods. So I think there are 4 ways…
let aaa = [1, 2, 3]->Array.map(i => i * 2, _)
let bbb = [1, 2, 3]->Js.Array2.map(i => i * 2)
let ccc = [1, 2, 3]->Js.Array.map(i => i * 2, _)
let ddd = [1, 2, 3]->Belt.Array.map(i => i * 2)
I’m confused how the first one - Array.map - even works. What “module” is that coming from? How does that relate to the others? I have a similar question about when I use the words Some and None - seems like these should be in Js.Option or Belt.Option but I don’t see them there.
Ok. Note this somewhat contradicts information on API | ReScript API (rescript-lang.org) which steers people to Js.Array2. I just wrote some unit tests that demonstrate one danger of Js.Array2. In functional programming you get used to comparing objects by their contents not by reference. Js.Array2.includes does the usual javascript thing - reference comparison - which is unexpected in a functional environment. I notice Belt.Array does not have an includes function probably for this reason.
type person = {first: string, last: string}
describe("arrays", () => {
test("Js.Array2.includes uses structural equality", () => {
let a = {first: "justin", last: "smith"}
let b = {first: "justin", last: "smith"}
[a]->Js.Array2.includes(b)->expect->toEqual(true) // fails
})
test("Belt.Array.includes uses structural equality", () => {
let a = {first: "justin", last: "smith"}
let b = {first: "justin", last: "smith"}
[a]->Belt.Array.some(i => i == b)->expect->toEqual(true)
})
})