@dzakh/rescript-stdlib v1.1.0
@dzakh/rescript-stdlib
This is vendored stdlib for personal usage
Learn more about vendoring a standard library at rescript-stdlib-vendorer. Feel free to fork and use it for your own projects. The main idea is that you can always adjust to yourself.
Acknowledgements
- Gabriel (@zth) from whom I copied the initial stdlib project. The repo is private now, but you can still find some traces on npm.
- @bloodyowl + contributors to
rescript-js
are 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.
$ npm i @dzakh/rescript-stdlib
Then add rescript-stdlib
to your bsconfig.json
's bs-dependencies
:
{
"bs-dependencies": [
+ "@dzakh/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)
Differences to rescript-js
This standard library is based on rescript-js
, but with a few tweaks and modifications:
Array
reduce
/reduceReverse
and friends (withIndex versions) are taken fromBelt
and replace the bindings to the JavaScript equivalents (reduce
andreduceRight
). Thereduce
versions fromBelt
works fully with type inference because of the argument order being reversed (init
value 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
/unshiftMany
are 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 beunit
gets rid of needing to dolet _ =
(or->ignore
), which can be confusing for beginners.findIndexOpt
/lastIndexOf
/indexOfOpt
are added, returningNone
instead of-1
if the item searched for does not exist. These are in addition tofindIndex
/lastIndexOf
, which still returns-1
when the item you're looking for does not exist.getUnsafe
added (copied fromBelt
).setUnsafe
added (copied fromBelt
).reverse
added (copied fromBelt
), in addition to existingreverseInPlace
.reverseInPlace
is zero cost but does not produce a new array.reverse
does produce a new array.keepMap
andkeepMapU
is added fromBelt
, but renamed tofilterMap
. Rationale:filterMap
is closer to the JS convention of naming. It's also available in other languages like Rust.keep
et al can confuse beginners, who're bound to be looking forfilter
style names since that's what JS has.shuffle
andshuffleInPlace
are added (copied fromBelt
).flatMap
added (copied fromBelt
, but using nativemap
andconcat
functions).
Float
fromString
is copied fromBelt
. Main difference is thatfromString
now returns anoption
that'sNone
if the parsed float isNaN
. If you want the raw JS behavior of potentially parsing a float toNaN
you can useFloat.parseFloat(string)
.parseInt
andparseIntWithRadix
are removed. They were present inFloat
as a way of dealing withparseInt
potentially returningNaN
, which is a float.parseFloat
takes astring
and not any type'a
.
String
searchOpt
/indexOfOpt
/lastIndexOfOpt
added. Convenience methods for returning anoption
instead of returning-1
for not found.- Added bindings for
localeCompare
.
Promise
The Promise
module is inlined from https://github.com/ryyppy/rescript-promise, with these additions:
- Jaap's
ignorePromise
PR is merged.
Option, List, Result
- The above stated modules are brought in from
Belt
, since they're widely used in the ecosystem. - In
Option
andList
, the same naming convention is applied as inArray
forkeep*
functions. As inkeep
becomesfilter
,keepMap
becomesfilterMap
, etc.
window, document
window
anddocument
are typed asDom.window
/Dom.document
rather than open objects ({..}
).
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.