@gabnor/rescript-stdlib v1.0.9
rescript-standard-library
This is not officially published yet, and is in private testing.
The new ReScript standard library. Intended to be familiar for JavaScript developers, easy to use, and be rich enough that you don't need to reach for anything else for typical ReScript development.
It ships as a separate package initially, so you can start migrating to it at your convenience. Eventually it'll make its way into the compiler (likely in ReScript v11). And, long term it will replace the current Js namespace.
Ultimately, this + Belt is what'll be available for ReScript developers out of the box. Read more about the plan in this forum post.
Acknowledgements
- @bloodyowl + contributors to
rescript-jsare the people who've done the heavy lifting here, since this stdlib is based fully onrescript-js. - Also a shout out to the authors of
Belt, as a few key things have been incorporated directly fromBelt. - Patrick (@ryyppy) for his work on
rescript-promise, which is fully inlined into the stdlib.
Installation
ReScript >=10.1 is required.
$ yarn add @gabnor/rescript-stdlibThe
@gabnorscope is for "private" testing before the package is officially published. When officially published, it'll be under the appropriate@rescriptscope.
Then add rescript-stdlib to your bsconfig.json's bs-dependencies:
{
"bs-dependencies": [
+ "@gabnor/rescript-stdlib"
]
}Open the standard library so it's available in the global scope. This is important because this is the way it'll ship in the compiler eventually, automatically available in the global scope.
{
"bsc-flags": [
+ "-open RescriptStdlib",
]
}What it looks like
Console.log("Hello world!")
let timeout = setTimeout(() => {
Console.log("Hello!")
}, 100)
clearTimeout(timeout)
let array = [1, 2, 3]
let sum = array
->Array.map(x => x * 2)
->Array.reduce((acc, item) => acc + item, 0)
let maybeValidFloats = ["1", "1.5", "some random string"]
let validFloats = maybeValidFloats
->Array.filterMap(v => v->Float.fromString)Documentation
Documentation will be added successively to this repository, and will be fully available as the standard library is officially merged into the compiler.
OCaml compat
During the transition phase to this standard library you might find yourself needing to access the current global Array/List etc modules that originate from OCaml. These will be removed eventually, but in the transition phase you'll be able to access them by adding this open at the top of any file:
open OCamlCompatDifferences to rescript-js
This standard library is based on rescript-js, but with a few tweaks and modifications:
Array
reduce/reduceReverseand friends (withIndex versions) are taken fromBeltand replace the bindings to the JavaScript equivalents (reduceandreduceRight). Thereduceversions fromBeltworks fully with type inference because of the argument order being reversed (initvalue comes first), whereas the JavaScript versions don't work well with inference. The runtime added for this is minor (and very fast still), and we want users to have to annotate as little as possible for the standard functions they'll be using.push/pushMany/unshift/unshiftManyare changed to returnunit, for convenience. In JS, these return the new length of the array. That's however extremely rare to actually use, and you can just doArray.length(array)after pushing to get the new length. Changing the return type to beunitgets rid of needing to dolet _ =(or->ignore), which can be confusing for beginners.findIndexOpt/lastIndexOf/indexOfOptare added, returningNoneinstead of-1if the item searched for does not exist. These are in addition tofindIndex/lastIndexOf, which still returns-1when the item you're looking for does not exist.getUnsafeadded (copied fromBelt).setUnsafeadded (copied fromBelt).reverseadded (copied fromBelt), in addition to existingreverseInPlace.reverseInPlaceis zero cost but does not produce a new array.reversedoes produce a new array.keepMapandkeepMapUis added fromBelt, but renamed tofilterMap. Rationale:filterMapis closer to the JS convention of naming. It's also available in other languages like Rust.keepet al can confuse beginners, who're bound to be looking forfilterstyle names since that's what JS has.shuffleandshuffleInPlaceare added (copied fromBelt).flatMapadded (copied fromBelt, but using nativemapandconcatfunctions).
Float
fromStringis copied fromBelt. Main difference is thatfromStringnow returns anoptionthat'sNoneif the parsed float isNaN. If you want the raw JS behavior of potentially parsing a float toNaNyou can useFloat.parseFloat(string).parseIntandparseIntWithRadixare removed. They were present inFloatas a way of dealing withparseIntpotentially returningNaN, which is a float.parseFloattakes astringand not any type'a.
String
searchOpt/indexOfOpt/lastIndexOfOptadded. Convenience methods for returning anoptioninstead of returning-1for not found.- Added bindings for
localeCompare.
Promise
The Promise module is inlined from https://github.com/ryyppy/rescript-promise, with these additions:
- Jaap's
ignorePromisePR is merged. thenandcatchis replaced with Cristiano's "safe promises" (where nested promises do not cause runtime breakages).
Option, List, Result
- The above stated modules are brought in from
Belt, since they're widely used in the ecosystem. - In
OptionandList, the same naming convention is applied as inArrayforkeep*functions. As inkeepbecomesfilter,keepMapbecomesfilterMap, etc.
window, document
windowanddocumentare typed asDom.window/Dom.documentrather than open objects ({..}).
Migration
Things are added to this section on migration gradually.
Migrating to the new standard library should be easy to do gradually. In this section we'll gather information that's intended to help migrating as painlessly as possible.
Name clashes
Since the standard library is designed to live in the global scope, you might have your own modules whose names might collide with the modules from the standard library. The easiest way to solve this is to just rename your own module to something else.