Skip to content

Commit d3b9d6d

Browse files
committed
init
0 parents  commit d3b9d6d

File tree

126 files changed

+9442
-0
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

126 files changed

+9442
-0
lines changed

.gitignore

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
*.exe
2+
*.obj
3+
*.out
4+
*.compile
5+
*.native
6+
*.byte
7+
*.cmo
8+
*.annot
9+
*.cmi
10+
*.cmx
11+
*.cmt
12+
*.cmti
13+
*.cma
14+
*.a
15+
*.cmxa
16+
*.obj
17+
*~
18+
*.annot
19+
*.cmj
20+
*.bak
21+
lib/bs
22+
*.mlast
23+
*.mliast
24+
.vscode
25+
.merlin
26+
.bsb.lock
27+
/node_modules/
28+
.DS_Store

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2022 ReScript
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+160
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
# @rescript/core
2+
3+
A drop-in standard library for ReScript. Intended to be familiar for JavaScript developers, easy to use, and be rich enough (without being bloated) so that you don't need to reach for anything else for typical ReScript development.
4+
5+
## Background
6+
7+
We're proposing a new, experimental drop-in standard library intended to solve a number of problems we see in ReScript development today. This proposed standard library has the following purposes:
8+
9+
1. Adding a rich (enough) standard library that's familiar to JavaScript developers
10+
2. Clearing up the current confusing situation with regards to t-first vs t-last, OCaml pervasives, `Js.Array2` etc
11+
3. Prepare for "uncurried by default" by only shipping compatible APIs
12+
13+
In practice, the proposed standard library is a fusion of `rescript-js`, `rescript-promise`, and `Belt` - all battle tested and well liked, with a few minor additions sprinkled in. So while we're calling this a new standard library, the parts it's made up of isn't new.
14+
15+
It ships as a separate package, so you can try it out and start migrating to it if you want at your convenience. Eventually, if the community likes it and it stands the test of time, it'll might its way into the compiler. And, at that point it would replace the current `Js` namespace.
16+
17+
We don't anticipate nor plan for larger changes to any of the API:s, but please beware _changes may still happen_ as this project stabilizes. We're of course also interested in the community's feedback on the APIs.
18+
19+
## Guiding principles
20+
21+
We've been following a few guiding principles as we developed this:
22+
23+
- Familiarity for JavaScript developers. Let APIs follow their JS equivalents as much as possible, and where there's new APIs that don't exist in the JS standard library, follow a naming and layout that we think will feel familiar to a JS developer. Example: `Belt.Array.keepMap` is included in the `Array` module, but here renamed to `Array.filterMap` to be more familiar to JS developers.
24+
- Focus on zero cost APIs, but prioritize quality. Sometimes a small bit of runtime is required for the API to be as good as it can be.
25+
- Effortless inference is important here. Choose APIs where inference just works. Example: `Belt.Array.reduce` is included instead of `Js.Array2.reduce`, because the `Belt` version's inference is better than the `Js.Array2` version.
26+
27+
## Acknowledgements
28+
29+
- @bloodyowl + contributors to `rescript-js` are the people who've done the heavy lifting here, since this stdlib is based heavily on `rescript-js`.
30+
- Also a shout out to the authors of `Belt`, as a few key things have been incorporated directly from `Belt`.
31+
- Patrick (@ryyppy) for his work on `rescript-promise`, which is fully inlined into the stdlib.
32+
33+
## Installation
34+
35+
ReScript `>=10.1` is required.
36+
37+
```console
38+
$ npm install @rescript/core
39+
```
40+
41+
Then add `@rescript/core` to your `bsconfig.json`'s `bs-dependencies`:
42+
43+
```diff
44+
{
45+
"bs-dependencies": [
46+
+ "@rescript/core"
47+
]
48+
}
49+
```
50+
51+
Open it so it's available in the global scope.
52+
53+
```diff
54+
{
55+
"bsc-flags": [
56+
+ "-open RescriptCore",
57+
]
58+
}
59+
```
60+
61+
## What it looks like
62+
63+
All relevant standard library modules are designed to be available directly in
64+
the global scope, just like you expect them to.
65+
66+
```rescript
67+
Console.log("Hello world!")
68+
69+
let timeout = setTimeout(() => {
70+
Console.log("Hello!")
71+
}, 100)
72+
73+
clearTimeout(timeout)
74+
75+
let array = [1, 2, 3]
76+
77+
let sum = array
78+
->Array.map(x => x * 2)
79+
->Array.reduce(0, (acc, item) => acc + item)
80+
81+
let maybeValidFloats = ["1", "1.5", "some random string"]
82+
83+
let validFloats = maybeValidFloats
84+
->Array.filterMap(v => v->Float.fromString)
85+
```
86+
87+
## Documentation
88+
89+
Documentation will be added successively to this repository. We're looking for help in producing good, high quality docstrings for all APIs. More information coming on how you can help out with this.
90+
91+
## OCaml compat
92+
93+
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:
94+
95+
```rescript
96+
open OCamlCompat
97+
```
98+
99+
## Differences to `rescript-js`
100+
101+
This standard library is based on `rescript-js`, but with the tweaks and modifications listed below. There are also no uncurried versions of anything in the standard library. This is because this will ship at the same time (or if anything, later) as _uncurried by default_, which will remove the need for explicit uncurried functions.
102+
103+
### Array
104+
105+
- `reduce`/`reduceReverse` and friends (withIndex versions) are taken from `Belt` and replace the bindings to the JavaScript equivalents (`reduce` and `reduceRight`). The `reduce` versions from `Belt` 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.
106+
- `push`/`pushMany`/`unshift`/`unshiftMany` are changed to return `unit`, for convenience. In JS, these return the new length of the array. That's however extremely rare to actually use, and you can just do `Array.length(array)` after pushing to get the new length. Changing the return type to be `unit` gets rid of needing to do `let _ = ` (or `->ignore`), which can be confusing for beginners.
107+
- `findIndexOpt`/`lastIndexOf`/`indexOfOpt` are added, returning `None` instead of `-1` if the item searched for does not exist. These are in addition to `findIndex`/`lastIndexOf`, which still returns `-1` when the item you're looking for does not exist.
108+
- `getUnsafe` added (copied from `Belt`).
109+
- `setUnsafe` added (copied from `Belt`).
110+
- `reverse` added (copied from `Belt`), in addition to existing `reverseInPlace`. `reverseInPlace` is zero cost but does not produce a new array. `reverse` does produce a new array.
111+
- `keepMap` is added from `Belt`, but **renamed to `filterMap`**. 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 for `filter` style names since that's what JS has.
112+
- `shuffle` and `shuffleInPlace` are added (copied from `Belt`).
113+
- `flatMap` added (copied from `Belt`, but using native `map` and `concat` functions).
114+
115+
### Float
116+
117+
- `fromString` is copied from `Belt`. Main difference is that `fromString` now returns an `option` that's `None` if the parsed float is `NaN`. If you want the raw JS behavior of potentially parsing a float to `NaN` you can use `Float.parseFloat(string)`.
118+
119+
### String
120+
121+
- `searchOpt`/`indexOfOpt`/`lastIndexOfOpt` added. Convenience methods for returning an `option` instead of returning `-1` for not found.
122+
- Added bindings for `localeCompare`.
123+
124+
### Promise
125+
126+
The `Promise` module is inlined from https://github.com/ryyppy/rescript-promise, with these additions:
127+
128+
- Jaap's `ignorePromise` PR is merged.
129+
130+
### Option, List, Result
131+
132+
- The above stated modules are brought in from `Belt`, since they're widely used in the ecosystem.
133+
- In `Option` and `List`, the same naming convention is applied as in `Array` for `keep*` functions. As in `keep` becomes `filter`, `keepMap` becomes `filterMap`, etc.
134+
135+
### window, document
136+
137+
- `window` and `document` are typed as `Dom.window`/`Dom.document` rather than open objects (`{..}`).
138+
139+
## Migration
140+
141+
_Things are added to this section on migration gradually._
142+
143+
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.
144+
145+
### Semi-automated migration
146+
147+
We've prepared a script you can run with [comby.dev](https://comby.dev) that will do parts of the migration for you automatically. The migration script is located in [`migration.toml`](migration/migration.toml). Here's an example of how you can run it:
148+
149+
```bash
150+
# Run in your project root. Assumes `migration.toml` has been copied in place to your project root.
151+
comby -config migration.toml -f .res -matcher .re -exclude-dir node_modules,__generated__ -i
152+
```
153+
154+
The migration script is a set of instructions that Comby runs in sequence. You're encouraged to take `migration.toml` and tweak it so it fits your needs. [Comby](https://comby.dev) is powerful. It can do interactive rewriting and numerous other useful stuff. Check it out, but please note it's _not_ intended to cover all of the migration necessary. You'll still likely need to do a few manual fixes after running the migration scripts.
155+
156+
### Name clashes
157+
158+
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.
159+
160+
This is a side effect of shipping the standard library as its own package, meaning it won't be a problem if the standard library is adopted and ships with the compiler. At that point you'll be able to have your own modules shadowing builtin modules.

bsconfig.json

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
{
2+
"name": "@rescript/core",
3+
"version": "0.1.0",
4+
"sources": [
5+
{
6+
"dir": "src",
7+
"subdirs": true
8+
},
9+
{
10+
"dir": "test",
11+
"subdirs": true,
12+
"type": "dev"
13+
}
14+
],
15+
"suffix": ".mjs",
16+
"package-specs": {
17+
"module": "es6",
18+
"in-source": true
19+
},
20+
"warnings": {
21+
"error": "+101"
22+
}
23+
}

0 commit comments

Comments
 (0)