diff --git a/markdown-pages/blog/release-9-0.mdx b/markdown-pages/blog/release-9-0.mdx index b13d54359..70c5a8ba6 100644 --- a/markdown-pages/blog/release-9-0.mdx +++ b/markdown-pages/blog/release-9-0.mdx @@ -34,7 +34,7 @@ Our compiler comes with a set of stdlib modules (such as `Belt`, `Pervasives`, e In previous versions, users couldn't ship their compiled JS code without defining a `package.json` dependency on `bs-platform`. Whenever a ReScript developer wanted to publish a package just for pure JS consumption / lean container deployment, they were required to use a bundler to bundle up their library / stdlib code, which made things way more complex and harder to understand. -To fix this problem, we introduced an `external-stdlib` configuration that allows specifying a pre-compiled stdlib npm package (`@rescript/std`). More details on how to use that feature can be found in our [External Stdlib](../docs/manual/build-external-stdlib.mdx) documentation. +To fix this problem, we introduced an `external-stdlib` configuration that allows specifying a pre-compiled stdlib npm package (`@rescript/std`). ### Less Bundle Bloat when Adding ReScript diff --git a/markdown-pages/docs/manual/array-and-list.mdx b/markdown-pages/docs/manual/array-and-list.mdx index 6cf825e9c..71eb9dab4 100644 --- a/markdown-pages/docs/manual/array-and-list.mdx +++ b/markdown-pages/docs/manual/array-and-list.mdx @@ -10,7 +10,7 @@ order: 12 ## Array -Arrays are our main ordered data structure. They work the same way as JavaScript arrays: they can be randomly accessed, dynamically resized, updated, etc. +Arrays are the main ordered data structure in ReScript. They can be randomly accessed, dynamically resized, and updated. @@ -82,9 +82,7 @@ myArray[0] = "bye"; ### Array spreads -**Since 11.1** - -You can spread arrays of the the same type into new arrays, just like in JavaScript: +You can spread arrays of the same type into new arrays: @@ -96,21 +94,17 @@ let x3 = [...y] ``` ```javascript -var Belt_Array = require("rescript/lib/js/belt_Array.js"); - var y = [1, 2]; -var x = Belt_Array.concatMany([[4, 5], y]); +var x = [4, 5, ...y]; -var x2 = Belt_Array.concatMany([[4, 5], y, [7], y]); +var x2 = [4, 5, ...y, 7, ...y]; -var x3 = Belt_Array.concatMany([y]); +var x3 = [...y]; ``` -> Note that array spreads compiles to `Belt.Array.concatMany` right now. This is likely to change to native array spreads in the future. - ## List ReScript provides a singly linked list too. Lists are: diff --git a/markdown-pages/docs/manual/async-await.mdx b/markdown-pages/docs/manual/async-await.mdx index e46b2a4bf..e36346e1b 100644 --- a/markdown-pages/docs/manual/async-await.mdx +++ b/markdown-pages/docs/manual/async-await.mdx @@ -67,7 +67,7 @@ You will probably notice that this looks very similar to `async` / `await` in JS - `await` may only be called on a `promise` value - `await` calls are expressions, therefore they can be used in pattern matching (`switch`) - A function returning a `promise<'a>` is equivalent to an `async` function returning a value `'a` (important for writing signature files and bindings) -- `promise` values and types returned from an `async` function don't auto-collapse into a "flat promise" like in JS (more on this later) +- `promise` values and types returned from an `async` function don't auto-collapse into a flat promise. See the details below. ## Types and `async` functions diff --git a/markdown-pages/docs/manual/browser-support-polyfills.mdx b/markdown-pages/docs/manual/browser-support-polyfills.mdx deleted file mode 100644 index 1adf06d02..000000000 --- a/markdown-pages/docs/manual/browser-support-polyfills.mdx +++ /dev/null @@ -1,20 +0,0 @@ ---- -title: "Browser Support & Polyfills" -description: "Note on browser support in ReScript" -canonical: "/docs/manual/browser-support-polyfills" -section: "JavaScript Interop" -order: 13 ---- - -# Browser Support & Polyfills - -ReScript compiles to JavaScript **ES5**, with the exception of optionally allowing to compile to ES6's module import & export. - -For [old browsers](https://caniuse.com/#search=typed%20array), you also need to polyfill TypedArray. The following standard library functions require it: - -- `Int64.float_of_bits` -- `Int64.bits_of_float` -- `Int32.float_of_bits` -- `Int32.bits_of_float` - -If you don't use these functions, you're fine. Otherwise, it'll be a runtime failure. diff --git a/markdown-pages/docs/manual/build-configuration.mdx b/markdown-pages/docs/manual/build-configuration.mdx index 4a37d0f32..f9d0151e8 100644 --- a/markdown-pages/docs/manual/build-configuration.mdx +++ b/markdown-pages/docs/manual/build-configuration.mdx @@ -81,17 +81,13 @@ Here, the file `src/MyMainModule.res` is exposed to outside consumers, while all } ``` -## bs-dependencies, bs-dev-dependencies +## dependencies, dev-dependencies List of ReScript dependencies. Just like `package.json`'s dependencies, they'll be searched in `node_modules`. -Note that only sources marked with `"type":"dev"` will be able to resolve modules from `bs-dev-dependencies`. +Note that only sources marked with `"type":"dev"` will be able to resolve modules from `dev-dependencies`. -## external-stdlib - -**Since 9.0**: This setting allows depending on an externally built stdlib package (instead of a locally built stdlib runtime). Useful for shipping packages that are only consumed in JS or TS without any dependencies to the ReScript development toolchain. - -More details can be found on our [external stdlib](./build-external-stdlib.mdx) page. +> The legacy keys `bs-dependencies` and `bs-dev-dependencies` are still accepted but deprecated. ## js-post-build @@ -155,7 +151,7 @@ This configuration only applies to you, when you develop the project. When the p ## suffix -**Since 11.0**: The suffix can now be freely chosen. However, we still suggest you stick to the convention and use +The suffix can be freely chosen. However, we still suggest you stick to the convention and use one of the following: - `".js` @@ -190,12 +186,14 @@ Turn off warning `44` and `102` (polymorphic comparison). Turn warning `5` (part The warning numbers are shown in the build output when they're triggered. See [Warning Numbers](./warning-numbers.mdx) for the complete list. -## bsc-flags +## compiler-flags Extra flags to pass to the compiler. For advanced usages. - `-open ABC` opens the module `ABC` for each file in the project. `ABC` can either be a dependency, namespaced project or local module of the current project. +> The legacy key `bsc-flags` is still accepted but deprecated. + ## gentypeconfig To enable genType, set `"gentypeconfig"` at top level in the project's `rescript.json`. diff --git a/markdown-pages/docs/manual/build-external-stdlib.mdx b/markdown-pages/docs/manual/build-external-stdlib.mdx deleted file mode 100644 index e789a0b7e..000000000 --- a/markdown-pages/docs/manual/build-external-stdlib.mdx +++ /dev/null @@ -1,62 +0,0 @@ ---- -title: "External Stdlib" -metaTitle: "External Stdlib" -description: "Configuring an external ReScript stdlib package" -canonical: "/docs/manual/build-external-stdlib" -section: "Build System" -order: 4 ---- - -# External Stdlib - -**Since 9.0** - -Your ReScript project depends on the `rescript` package as a [`devDependency`](https://docs.npmjs.com/specifying-dependencies-and-devdependencies-in-a-package-json-file), which includes our compiler, build system and runtime like `Belt`. However, you had to move it to `dependency` in `package.json` if you publish your code: - -- To Docker or other low-storage deployment devices. -- For pure JS/TS consumers who probably won't install `rescript` in their own project. - -In these cases, the size or mere presence of `rescript` can be troublesome, since it includes not just our necessary runtime like `Belt`, but also our compiler and build system. - -To solve that, we now publish our runtime as a standalone package at [`@rescript/std`](https://www.npmjs.com/package/@rescript/std), whose versions mirror `rescript`'s. Now you can keep `rescript` as a `devDependency` and have only `@rescript/std` as your runtime `dependency`. - -**This is an advanced feature**. Please only use it in the aforementioned scenarios. If you already use a JS bundler with dead code elimination, you might not need this feature. - -## Configuration - -Say you want to publish a JS-only ReScript 9.0 library. Install the packages like this: - -```sh -npm install rescript@11.0.1 --save-dev -npm install @rescript/std@11.0.1 -``` - -Then add this to `rescript.json`: - -```json -{ - // ... - "external-stdlib": "@rescript/std" -} -``` - -Now the compiled JS code will import using the path defined by `external-stdlib`. Check the JS output tab: - - - -```res -Array.forEach([1, 2, 3], num => Console.log(num)) -``` - -```js -// Note the require path starting with "@rescript/std". -var Belt_Array = require("@rescript/std/lib/js/belt_Array.js"); - -Belt_Array.forEach([1, 2, 3], function (num) { - console.log(num); -}); -``` - - - -**Make sure the version number of `rescript` and `@rescript/std` match in your `package.json`** to avoid running into runtime issues due to mismatching stdlib assumptions. diff --git a/markdown-pages/docs/manual/build-monorepo-setup.mdx b/markdown-pages/docs/manual/build-monorepo-setup.mdx index 64344e5ec..39f0336f3 100644 --- a/markdown-pages/docs/manual/build-monorepo-setup.mdx +++ b/markdown-pages/docs/manual/build-monorepo-setup.mdx @@ -58,7 +58,7 @@ The root `rescript.json` manages the monorepo by listing its packages. "in-source": true }, "suffix": ".res.mjs", - "bsc-flags": [] + "compiler-flags": [] } ``` diff --git a/markdown-pages/docs/manual/build-performance.mdx b/markdown-pages/docs/manual/build-performance.mdx index 3f743a400..7af0ea73a 100644 --- a/markdown-pages/docs/manual/build-performance.mdx +++ b/markdown-pages/docs/manual/build-performance.mdx @@ -68,9 +68,7 @@ The watcher is also just a thin file watcher that calls `rescript.exe`. We don't ReScript doesn't take whole seconds to run every time. The bulk of the build performance comes from incremental build, aka re-building a previously built project when a few files changed. -In short, thanks to our compiler and the build system's architecture, we're able to **only build what's needed**. E.g. if `MyFile.res` isn't changed, then it's not recompiled. You can roughly emulate such incrementalism in languages like JavaScript, but the degree of correctness is unfortunately low. For example, if you rename or move a JS file, then the watcher might get confused and not pick up the "new" file or fail to clean things up correctly, resulting in you needing to clean your build and restart anew, which defeats the purpose. - -Say goodbye to stale build from your JavaScript ecosystem! +In short, thanks to our compiler and the build system's architecture, we're able to **only build what's needed**. If `MyFile.res` isn't changed, it isn't recompiled. Renaming or moving files is handled automatically, with no stale builds. ## Speed Up Incremental Build diff --git a/markdown-pages/docs/manual/control-flow.mdx b/markdown-pages/docs/manual/control-flow.mdx index 517a0a33f..510d24f52 100644 --- a/markdown-pages/docs/manual/control-flow.mdx +++ b/markdown-pages/docs/manual/control-flow.mdx @@ -10,11 +10,11 @@ order: 14 ReScript supports `if`, `else`, ternary expression (`a ? b : c`), `for` and `while`. -The `switch` pattern has a default case too, just like many other functional languages. Read more about [pattern-matching & destructuring](./pattern-matching-destructuring.mdx). there. +The `switch` pattern supports a default case. Read more about [pattern-matching & destructuring](./pattern-matching-destructuring.mdx). ## If-Else & Ternary -Unlike its JavaScript counterpart, ReScript's `if` is an expression; they evaluate to their body's content: +ReScript's `if` is an expression; it evaluates to its body's content: @@ -94,7 +94,7 @@ var message = isMorning ? "Good morning!" : "Hello!"; -**`if-else` and ternary are much less used** in ReScript than in other languages; [Pattern-matching](./pattern-matching-destructuring.mdx) kills a whole category of code that previously required conditionals. +`if-else` and ternary are often replaced by [pattern matching](./pattern-matching-destructuring.mdx), which handles a wide range of conditional logic more expressively. ## For Loops diff --git a/markdown-pages/docs/manual/converting-from-js.mdx b/markdown-pages/docs/manual/converting-from-js.mdx index 697d34315..75fd1ae82 100644 --- a/markdown-pages/docs/manual/converting-from-js.mdx +++ b/markdown-pages/docs/manual/converting-from-js.mdx @@ -12,7 +12,7 @@ ReScript offers a unique project conversion methodology which: - Ensures minimal disruption to your teammates (very important!). - Remove the typical friction of verifying conversion's correctness and performance guarantees. -- Doesn't force you to search for pre-made binding libraries made by others. **ReScript doesn't need the equivalent of TypeScript's `DefinitelyTyped`**. +- Doesn't require pre-made binding libraries. You can write bindings directly for any JavaScript API. ## Step 1: Install ReScript diff --git a/markdown-pages/docs/manual/editor-plugins.mdx b/markdown-pages/docs/manual/editor-plugins.mdx index 97c5bb884..e2a93abcf 100644 --- a/markdown-pages/docs/manual/editor-plugins.mdx +++ b/markdown-pages/docs/manual/editor-plugins.mdx @@ -40,14 +40,14 @@ The code analysis provides extra checks for your ReScript project, such as detec ### Configuration Add a `reanalyze` section to your `rescript.json` to control what the analyzer checks or ignores. You'll get autocomplete for config options in the editor. -More details: [reanalyze config docs](https://github.com/rescript-association/reanalyze#configuration-via-bsconfigjson) +More details: [reanalyze configuration docs](https://github.com/rescript-association/reanalyze#configuration-via-bsconfigjson) ### Exception analysis The exception analysis is designed to keep track statically of the exceptions that might be thrown at runtime. It works by issuing warnings and recognizing annotations. Warnings are issued whenever an exception is thrown and not immediately caught. Annotations are used to push warnings from he local point where the exception is thrown, to the outside context: callers of the current function. Nested functions need to be annotated separately. -Instructions on how to run the exception analysis using the `-exception` and `-exception-cmt` command-line arguments, or how to add `"analysis": ["exception"]` in `rescript.json` are contained in the [reanalyze config docs](https://github.com/rescript-association/reanalyze#configuration-via-bsconfigjson). +Instructions on how to run the exception analysis using the `-exception` and `-exception-cmt` command-line arguments, or how to add `"analysis": ["exception"]` in `rescript.json` are contained in the [reanalyze configuration docs](https://github.com/rescript-association/reanalyze#configuration-via-bsconfigjson). Here's an example, where the analysis reports a warning any time an exception is thrown, and not caught: @@ -142,12 +142,11 @@ There is a way to enhance this behavior via configuration, described further dow ### Dot completion enhancements -In ReScript, using a dot (`.`) normally means "access record field". But, because using `.` to trigger completions is so pervasive in for example JavaScript, we extend `.` to trigger completions in more scenarios than just for record field access. +In ReScript, using a dot (`.`) normally means "access record field". The editor extends dot (`.`) to trigger completions in more scenarios beyond record field access. This behavior has the following important implications: - Improves discoverability (E.g. using a `.` will reveal important pipe completions) -- Enables a more natural completion flow for people used to JavaScript, where dots power more completions naturally Below is a list of all the scenarios where using dots trigger completion in addition to the normal record field completion. diff --git a/markdown-pages/docs/manual/embed-raw-javascript.mdx b/markdown-pages/docs/manual/embed-raw-javascript.mdx index ec69f950b..a0d252de8 100644 --- a/markdown-pages/docs/manual/embed-raw-javascript.mdx +++ b/markdown-pages/docs/manual/embed-raw-javascript.mdx @@ -36,7 +36,7 @@ function greet(m) { The `%%raw` special ReScript call takes your code string and pastes it as-is into the output. **You've now technically written your first ReScript file!** -(The back tick syntax is a multiline string, similar to JavaScript's. Except for us, no escaping is needed inside the string. More on string in a later section.) +(The backtick syntax is a multiline string. No escaping is needed inside the string.) While `%%raw` lets you embed top-level raw JS code, `%raw` lets you embed expression-level JS code: @@ -70,7 +70,7 @@ The above code: - with the raw JavaScript value of a function declaration, - then called that function in ReScript. -If your boss is ever worried that your teammates can't adopt ReScript, just let them keep writing JavaScript inside ReScript files =). +Existing JavaScript code can live inside ReScript files during migration. ## Debugger @@ -113,4 +113,4 @@ Embedding raw JS snippets isn't the best way to experience ReScript, though it's At the end, we get a fully safe, converted ReScript file whose JS output is clean enough that we can confidently assert that no new bug has been introduced during the conversion process. -We have a small guide on this iteration [here](./converting-from-js.mdx). Feel free to peruse it later. +See the [Converting from JS](./converting-from-js.mdx) guide for a detailed walkthrough. diff --git a/markdown-pages/docs/manual/exception.mdx b/markdown-pages/docs/manual/exception.mdx index 085c77dc7..617b01d0c 100644 --- a/markdown-pages/docs/manual/exception.mdx +++ b/markdown-pages/docs/manual/exception.mdx @@ -452,7 +452,7 @@ try { ## Catch ReScript Exceptions from JS -The previous section is less useful than you think; to let your JS code work with your exception-throwing ReScript code, the latter doesn't actually need to throw a JS exception. ReScript exceptions can be used by JS code! +To let JavaScript code work with exception-throwing ReScript code, you don't need to throw a JS exception. ReScript exceptions can be used directly from JavaScript. diff --git a/markdown-pages/docs/manual/external.mdx b/markdown-pages/docs/manual/external.mdx index 5319594fc..314e6e355 100644 --- a/markdown-pages/docs/manual/external.mdx +++ b/markdown-pages/docs/manual/external.mdx @@ -77,9 +77,9 @@ document.location.href = "rescript-lang.org"; -We've specified `document`'s type as `'a`, aka a placeholder type that's polymorphic. Any value can be passed there, so you're not getting much type safety (except the inferences at various call sites). However, this is excellent for quickly getting started using a JavaScript library in ReScript **without needing the equivalent of a repository of typed bindings** like TypeScript's `DefinitelyTyped` repo. +We've specified `document`'s type as `'a`, a placeholder type that's polymorphic. Any value can be passed there, so you're not getting much type safety (except the inferences at various call sites). This is useful for quickly getting started with a JavaScript library in ReScript since you can write bindings directly for any API you need. -However, if you want to more rigidly bind to the JavaScript library you want, keep reading the next few interop pages. +For more rigidly typed bindings, see the other interop pages in this section. ## Performance & Output Readability diff --git a/markdown-pages/docs/manual/function.mdx b/markdown-pages/docs/manual/function.mdx index 5abe76f96..e40cc7958 100644 --- a/markdown-pages/docs/manual/function.mdx +++ b/markdown-pages/docs/manual/function.mdx @@ -10,7 +10,7 @@ order: 13 _Cheat sheet for the full function syntax at the end_. -ReScript functions are declared with an arrow and return an expression, just like JS functions. They compile to clean JS functions too. +ReScript functions are declared with an arrow and return an expression. They compile to clean JavaScript functions. @@ -639,6 +639,6 @@ To annotate a function from the implementation file (`.res`) in your interface f let add: (int, int) => int ``` -The type annotation part is the same as the previous section on With Type Annotation. +The type annotation syntax is the same as described in [With Type Annotation](#with-type-annotation) above. **Don't** confuse `let add: myType` with `type add = myType`. When used in `.resi` interface files, the former exports the binding `add` while annotating it as type `myType`. The latter exports the type `add`, whose value is the type `myType`. diff --git a/markdown-pages/docs/manual/generalized-algebraic-data-types.mdx b/markdown-pages/docs/manual/generalized-algebraic-data-types.mdx index af384d92c..3f942822d 100644 --- a/markdown-pages/docs/manual/generalized-algebraic-data-types.mdx +++ b/markdown-pages/docs/manual/generalized-algebraic-data-types.mdx @@ -125,9 +125,7 @@ GADTs give us is that the compiler less able to help us with type inference. ## Varying return type -Sometimes, a function should have a different return type based on what you give it, and GADTs are how we can do this in a type-safe way. We can implement a generic `add` function[^1] that works on both `int` or `float`: - -[^1]: In ReScript v12, the built-in operators are already generic, but we use them in this example for simplicity. +Sometimes, a function should have a different return type based on what you give it, and GADTs are how we can do this in a type-safe way. We can implement a generic `add` function that works on both `int` or `float`: {/* this example purposefully has an error so it is not marked as an example */} @@ -137,7 +135,7 @@ type rec number<_> = Int(int): number | Float(float): number let add = (type a, x: number, y: number): a => switch (x, y) { | (Int(x), Int(y)) => x + y - | (Float(x), Float(y)) => x +. y + | (Float(x), Float(y)) => x + y } let foo = add(Int(1), Int(2)) @@ -199,7 +197,7 @@ and num = Num(numTy<'a>, 'a): num and num_array = Narray(numTy<'a>, array<'a>): num_array let addInt = (x, y) => x + y -let addFloat = (x, y) => x +. y +let addFloat = (x: float, y: float) => x + y let sum = (Narray(witness, array)) => { switch witness { diff --git a/markdown-pages/docs/manual/generate-converters-accessors.mdx b/markdown-pages/docs/manual/generate-converters-accessors.mdx index 39d016f11..5ca3ce4d2 100644 --- a/markdown-pages/docs/manual/generate-converters-accessors.mdx +++ b/markdown-pages/docs/manual/generate-converters-accessors.mdx @@ -111,7 +111,7 @@ var pets = [ }, ]; -console.log(Belt_Array.map(pets, name).join("&")); +console.log(pets.map(name).join("&")); ``` diff --git a/markdown-pages/docs/manual/import-from-export-to-js.mdx b/markdown-pages/docs/manual/import-from-export-to-js.mdx index 60cb7dee9..f4305ecdc 100644 --- a/markdown-pages/docs/manual/import-from-export-to-js.mdx +++ b/markdown-pages/docs/manual/import-from-export-to-js.mdx @@ -12,7 +12,7 @@ You've seen how ReScript's idiomatic [Import & Export](./import-export.mdx) work If you're looking for react-specific interop guidance, check out the [React JS Interop guide](../react/import-export-reactjs.mdx). -**Note**: due to JS ecosystem's module compatibility issues, our advice of keeping your ReScript file's compiled JS output open in a tab applies here **more than ever**, as you don't want to subtly output the wrong JS module import/export code, on top of having to deal with Babel/Webpack/Jest/Node's CommonJS \<-> JavaScript module compatibility shims. +**Tip**: keep your compiled JS output open in a tab to verify the generated import/export code. In short: **make sure your bindings below output what you'd have manually written in JS**. diff --git a/markdown-pages/docs/manual/interop-cheatsheet.mdx b/markdown-pages/docs/manual/interop-cheatsheet.mdx index 23cbe4459..a8a216ca8 100644 --- a/markdown-pages/docs/manual/interop-cheatsheet.mdx +++ b/markdown-pages/docs/manual/interop-cheatsheet.mdx @@ -271,7 +271,7 @@ Final escape hatch converter. Do not abuse. ```res example external convertToFloat: int => float = "%identity" let age = 10 -let gpa = 2.1 +. convertToFloat(age) +let gpa = 2.1 + convertToFloat(age) ``` ```js diff --git a/markdown-pages/docs/manual/interop-with-js-build-systems.mdx b/markdown-pages/docs/manual/interop-with-js-build-systems.mdx index 7884bbc38..704281986 100644 --- a/markdown-pages/docs/manual/interop-with-js-build-systems.mdx +++ b/markdown-pages/docs/manual/interop-with-js-build-systems.mdx @@ -14,7 +14,7 @@ If you come from JS, chances are that you already have a build system in your ex ## Popular JS Build Systems -The JS ecosystem uses a few build systems: [vite](https://vite.dev/), [browserify](http://browserify.org/), [rollup](https://github.com/rollup/rollup), [webpack](https://webpack.js.org/), etc. The first one is probably the most popular of the four (as of 2025 =P). These build systems do both the compilation and the linking (aka, bundling many files into one or few files). +The JS ecosystem uses a few build systems: [vite](https://vite.dev/), [browserify](http://browserify.org/), [rollup](https://github.com/rollup/rollup), [webpack](https://webpack.js.org/), etc. The first one is probably the most popular of the four (as of 2025). These build systems do both the compilation and the linking (aka, bundling many files into one or few files). `rescript` only takes care of the compilation step; it maps one `.res`/`.resi` file into one JS output file. As such, in theory, no build system integration is needed from our side. From e.g. the webpack watcher's perspective, the JS files ReScript generates are almost equivalent to your hand-written JS files. We also recommend **that you initially check in those ReScript-generated JS files**, as this workflow means: diff --git a/markdown-pages/docs/manual/introduction.mdx b/markdown-pages/docs/manual/introduction.mdx index 2b2093ba4..3a46b8873 100644 --- a/markdown-pages/docs/manual/introduction.mdx +++ b/markdown-pages/docs/manual/introduction.mdx @@ -10,19 +10,19 @@ order: 1 ReScript is a robustly typed language that compiles to efficient and human-readable JavaScript. It comes with a lightning fast compiler toolchain that scales to any codebase size. -## Part of the JavaScript ecosystem +## JavaScript Interop -ReScript looks like JS, acts like JS, and compiles to the highest quality of clean, readable and performant JS, directly runnable in browsers and Node. This means you can pick up ReScript and access the vast JavaScript ecosystem and tooling as if you've known ReScript for a long time! +ReScript compiles to clean, readable, and performant JavaScript, directly runnable in browsers and Node. Your existing package managers, bundlers, frameworks, and test runners all work with ReScript. -You don't need to learn new package managers, bundlers, frameworks, or testing libraries. All of the knowledge you have about doing web development with JavaScript can be applied to building applications with Rescript. +Your existing knowledge of web development transfers to ReScript projects. ReScript code can be [imported into JavaScript code](./import-from-export-to-js.mdx#export-to-javascript), can [generate types for TypeScript](./typescript-integration.mdx), and ReScript can [import code written in JavaScript or TypeScript](./import-from-export-to-js.mdx#import-from-javascript). ## Type System - Is deliberately curated to be a simple subset most folks will have an easier time to use. -- Has **no** pitfalls, aka the type system is "sound" (the types will always be correct). E.g. If a type isn't marked as nullable, its value will never lie and let through some `undefined` value silently. **ReScript code has no null/undefined errors**. -- Is the same for everyone. No knobs, no bikeshedding opportunity. +- Sound type system. If a type isn't marked as nullable, the value will never be `undefined`. **ReScript code has no null/undefined errors**. +- No configuration needed. The type system behaves the same way in every project. - Runs extremely fast precisely thanks to its simplicity and curation. It's one of the fastest compiler & build system toolchains for JavaScript development. - **Doesn't need type annotations**. Annotate as much or as little as you'd like. The types are inferred by the language (and, again, are guaranteed correct). @@ -30,9 +30,7 @@ ReScript code can be [imported into JavaScript code](./import-from-export-to-js. ### Compiles to Optimized JavaScript -JavaScript's been aggressively optimized by talented engineers over a long span. Unfortunately, even for seasoned JS devs, it can be hard to know how to properly leverage JS's performance. ReScript's type system and compiler naturally guides you toward writing code that's very often performant by default, with good leverage of various Just-In-Time optimizations (hidden classes, inline caching, avoiding deopts, etc). - -A widespread adage to write fast JavaScript code is to write as if there's a type system (in order to trigger JS engines' good optimization heuristics); ReScript gives you a real one and generates code that's friendly to optimizations by default. +ReScript's type system and compiler generate JavaScript that is performant by default, taking advantage of Just-In-Time optimizations (hidden classes, inline caching, avoiding deopts, etc). ### Tiny JS Output diff --git a/markdown-pages/docs/manual/jsx.mdx b/markdown-pages/docs/manual/jsx.mdx index 374b11c08..32fd20265 100644 --- a/markdown-pages/docs/manual/jsx.mdx +++ b/markdown-pages/docs/manual/jsx.mdx @@ -211,7 +211,7 @@ JsxRuntime.jsx(Playground$MyComponent, { **Since 10.1** -JSX props spread is supported now, but in a stricter way than in JS. +JSX props spread is supported with type safety. diff --git a/markdown-pages/docs/manual/libraries.mdx b/markdown-pages/docs/manual/libraries.mdx index 9c2ee2277..e6ac74d79 100644 --- a/markdown-pages/docs/manual/libraries.mdx +++ b/markdown-pages/docs/manual/libraries.mdx @@ -16,8 +16,6 @@ ReScript libraries are just like JavaScript libraries: published & hosted on [NP We recommend you to check in your compiled JavaScript output, for its [various benefits](./interop-with-js-build-systems.mdx#popular-js-build-systems). If not, then at least consider publishing the JavaScript output by un-ignoring them in your [npmignore](https://docs.npmjs.com/cli/v7/using-npm/developers#keeping-files-out-of-your-package). This way, your published ReScript package comes with plain JavaScript files that JS users can consume. If your project's good, JS users might not even realize that they've installed a library written in ReScript! -In case your library is only consumed by JS users, you may want to check out our [external stdlib](./build-external-stdlib.mdx) configuration as well. - ### Find Libraries Search `rescript`-related packages on NPM, or use our [Package Index](/packages). diff --git a/markdown-pages/docs/manual/module.mdx b/markdown-pages/docs/manual/module.mdx index b1f0ed208..a6379737d 100644 --- a/markdown-pages/docs/manual/module.mdx +++ b/markdown-pages/docs/manual/module.mdx @@ -276,7 +276,7 @@ inside a signature definition's `{}` block. ```res example -/* Picking up previous section's example */ +/* Using the types defined above */ module type EstablishmentType = { type profession let getProfession: profession => string @@ -305,7 +305,7 @@ To illustrate the various kinds of type entries, consider the above signature **Note**: Modules of the type `EstablishmentType` can contain more fields than the -signature declares, just like the module `School` in the previous section (if we +signature declares, just like the module `School` defined above (if we choose to assign it the type `EstablishmentType`. Otherwise, `School` exposes every field). This effectively makes the `person1` field an enforced implementation detail! Outsiders can't access it, since it's not present in the diff --git a/markdown-pages/docs/manual/overview.mdx b/markdown-pages/docs/manual/overview.mdx index 7c008770b..94dafc278 100644 --- a/markdown-pages/docs/manual/overview.mdx +++ b/markdown-pages/docs/manual/overview.mdx @@ -1,221 +1,154 @@ --- title: "Overview" metaTitle: "Language Features Overview" -description: "A quick overview on ReScript's syntax" +description: "A quick overview of ReScript's syntax and language features" canonical: "/docs/manual/overview" section: "Language Features" order: 1 --- -# Overview +# Language Overview -## Comparison to JS +A concise reference of ReScript's syntax and core language features. -### Semicolon +## Semicolons -| JavaScript | ReScript | -| ---------------------------------- | -------------------- | -| Rules enforced by linter/formatter | No semicolon needed! | +ReScript does not require semicolons. Line breaks are sufficient to separate statements. -### Comments +## Comments -| JavaScript | ReScript | -| -------------------- | -------------------------------- | -| `// Line comment` | Same | -| `/* Comment */` | Same | -| `/** Doc Comment */` | `/** Before Types/Values */` | -| | `/*** Standalone Doc Comment */` | +| Syntax | Purpose | +| -------------------------------- | ---------------------- | +| `// Line comment` | Single-line comment | +| `/* Block comment */` | Multi-line comment | +| `/** Doc comment */` | Documentation comment | +| `/*** Standalone doc comment */` | Standalone doc comment | -### Variable +## Variables -| JavaScript | ReScript | -| ----------------------- | ------------------------------------- | -| `const x = 5;` | `let x = 5` | -| `var x = y;` | No equivalent (thankfully) | -| `let x = 5; x = x + 1;` | `let x = ref(5); x := x.contents + 1` | +| Syntax | Description | +| ------------------------------------- | ----------------------- | +| `let x = 5` | Immutable binding | +| `let x = ref(5); x := x.contents + 1` | Mutable value via `ref` | -### String & Character +## Strings -| JavaScript | ReScript | -| ---------------------------- | --------------------- | -| `"Hello world!"` | Same | -| `'Hello world!'` | Strings must use `"` | -| `"hello " + "world"` | `"hello " ++ "world"` | -| `` `hello ${message}` `` | Same | -| `` sql`select ${fnName};` `` | Same | +| Syntax | Description | +| ------------------------- | -------------------- | +| `"Hello world!"` | String literal | +| `"hello " ++ "world"` | String concatenation | +| `` `hello ${message}` `` | String interpolation | +| `` sql`select ${col};` `` | Tagged template | -### Boolean +Strings must use double quotes (`"`). -| JavaScript | ReScript | -| ------------------------------------ | ---------------------------------------------- | -| `true`, `false` | Same | -| `!true` | Same | -| `\|\|`, `&&`, `<=`, `>=`, `<`, `>` | Same | -| `a === b`, `a !== b` | Same | -| No deep equality (recursive compare) | `a == b`, `a != b` | -| `a == b` | No equality with implicit casting (thankfully) | +## Booleans -### Number +| Syntax | Description | +| -------------------- | ------------------------------ | +| `true`, `false` | Boolean literals | +| `!` | Logical NOT | +| `\|\|`, `&&` | Logical OR, AND | +| `<=`, `>=`, `<`, `>` | Comparison operators | +| `===`, `!==` | Referential (shallow) equality | +| `==`, `!=` | Structural (deep) equality | -| JavaScript | ReScript | -| ----------- | -------- | -| `3` | Same \* | -| `3.1415` | Same | -| `3 + 4` | Same | -| `3.0 + 4.5` | Same | -| `5 % 3` | Same | +There is no equality with implicit type casting. -\* JS has no distinction between integer and float. +## Numbers -### Object/Record +| Syntax | Description | +| ------------ | ---------------------------------- | +| `3` | Integer literal | +| `3.1415` | Float literal | +| `3 + 4` | Addition (works for int and float) | +| `2 / 3 * 4` | Division and multiplication | +| `2.0 ** 3.0` | Exponentiation | +| `5 % 3` | Modulo | -| JavaScript | ReScript | -| ------------------- | --------------------------------------- | -| no types | `type point = {x: int, mutable y: int}` | -| `{x: 30, y: 20}` | Same | -| `point.x` | Same | -| `point.y = 30;` | Same | -| `{...point, x: 30}` | Same | +Arithmetic operators (`+`, `-`, `*`, `/`, `%`, `**`) work for both `int` and `float`. -### Array +## Records -| JavaScript | ReScript | -| ------------------ | --------------------- | -| `[1, 2, 3]` | Same | -| `myArray[1] = 10` | Same | -| `[1, "Bob", true]` | `(1, "Bob", true)` \* | +Records are typed, immutable-by-default data structures with named fields. -\* ReScript does not have heterogenous arrays. Use tuples or [Untagged Variants](./variant.mdx#untagged-variants) instead. +| Syntax | Description | +| --------------------------------------- | -------------------- | +| `type point = {x: int, mutable y: int}` | Type declaration | +| `{x: 30, y: 20}` | Record creation | +| `point.x` | Field access | +| `point.y = 30` | Mutable field update | +| `{...point, x: 30}` | Immutable update | -### Null +## Arrays -| JavaScript | ReScript | -| ------------------- | --------- | -| `null`, `undefined` | `None` \* | +| Syntax | Description | +| ----------------- | ---------------------- | +| `[1, 2, 3]` | Array literal | +| `myArray[1] = 10` | Mutable element update | -\* Again, only a spiritual equivalent; we don't have nulls, nor null bugs! But we do have an `option` type for when you actually need nullability. +Arrays are homogeneous. For mixed types, use tuples or [Untagged Variants](./variant.mdx#untagged-variants). -### Function +## Tuples -| JavaScript | ReScript | -| ------------------------------- | ---------------------------- | -| `arg => retVal` | Same | -| `function named(arg) {...}` | `let named = (arg) => {...}` | -| `const f = function(arg) {...}` | `let f = (arg) => {...}` | -| `add(4, add(5, 6))` | Same | +| Syntax | Description | +| ------------------- | ------------------- | +| `(1, "Bob", true)` | Tuple literal | +| `let (a, b, c) = t` | Tuple destructuring | -### Async Function / Await +Tuples are fixed-length, heterogeneous, and immutable. -| JavaScript | ReScript | -| --------------------------------------- | ----------------------------------------------------- | -| `async (arg) => {...}` | Same | -| `async function named(arg) {...}` | `let named = async (arg) => {...}` | -| `await somePromise` | Same | -| `async (arg): Promise => {...}` | `async (arg): string => {...}` (note the return type) | +## Null & Option -### Blocks +ReScript has no `null` or `undefined`. The `option` type represents the possible absence of a value: - - - - - - - - - - - - - -
JavaScriptReScript
- ``` - const myFun = (x, y) => { - const doubleX = x + x; - const doubleY = y + y; - return doubleX + doubleY; - }; - ``` - - ``` - let myFun = (x, y) => { - let doubleX = x + x - let doubleY = y + y - doubleX + doubleY - } - ``` -
- -### If-else - -| JavaScript | ReScript | -| --------------------- | ------------------------------------------------------------------------------------ | -| `if (a) {b} else {c}` | `if a {b} else {c}` \* | -| `a ? b : c` | Same | -| `switch` | `switch` but [super-powered pattern matching!](./pattern-matching-destructuring.mdx) | - -\* Our conditionals are always expressions! You can write `let result = if a {"hello"} else {"bye"}` - -### Destructuring - -| JavaScript | ReScript | -| ----------------------------- | --------------------------- | -| `const {a, b} = data` | `let {a, b} = data` | -| `const [a, b] = data` | `let [a, b] = data` \* | -| `const {a: aa, b: bb} = data` | `let {a: aa, b: bb} = data` | - -\* Gives good compiler warning that `data` might not be of length 2. - -### Loop +| Syntax | Description | +| ------------ | --------------- | +| `None` | No value | +| `Some("hi")` | A present value | -| JavaScript | ReScript | -| ------------------------------------- | ---------------------------- | -| `for (let i = 0; i <= 10; i++) {...}` | `for i in 0 to 10 {...}` | -| `for (let i = 10; i >= 0; i--) {...}` | `for i in 10 downto 0 {...}` | -| `while (true) {...}` | `while true {...}` | +## Functions -### JSX +| Syntax | Description | +| ----------------------------- | -------------------- | +| `arg => retVal` | Anonymous function | +| `let named = (arg) => retVal` | Named function | +| `add(4, add(5, 6))` | Function application | -| JavaScript | ReScript | -| ----------------------------------------- | -------------------------- | -| `` | Same | -| `` | `` \* | -| `` | `` | -| No children spread | `...children` | +## Async / Await -\* Argument punning! +| Syntax | Description | +| ---------------------------------- | ------------------------------ | +| `async (arg) => {...}` | Async anonymous function | +| `let named = async (arg) => {...}` | Async named function | +| `await somePromise` | Await a promise | +| `async (arg): string => {...}` | Typed async (return type only) | -### Exception +## Blocks -| JavaScript | ReScript | -| ----------------------------------------- | ------------------------------------------------ | -| `throw new SomeError(...)` | `throw(SomeException(...))` | -| `try {a} catch (err) {...} finally {...}` | `try a catch { \| SomeException(err) => ...}` \* | - -\* No finally. - -### Blocks - -The last expression of a block delimited by `{}` implicitly returns (including function body). In JavaScript, this can only be simulated via an immediately-invoked function expression (since function bodies have their own local scope). +The last expression in a `{}` block is implicitly returned, including in function bodies. - - + + + + + +
JavaScriptReScriptExampleDescription
``` - let result = (function() { - const x = 23; - const y = 34; - return x + y; - })(); + let myFun = (x, y) => { + let doubleX = x + x + let doubleY = y + y + doubleX + doubleY + } ``` Function body with implicit return
``` let result = { @@ -225,33 +158,82 @@ The last expression of a block delimited by `{}` implicitly returns (including f } ``` Block expression bound to a variable
-## Common Features' JS Output - -| Feature | Example | JavaScript Output | -| ------------------------------- | ------------------------------------ | ------------------------------------------ | -| String | `"Hello"` | `"Hello"` | -| String Interpolation | `` `Hello ${message}` `` | `"Hello " + message` | -| Character (discouraged) | `'x'` | `120` (char code) | -| Integer | `23`, `-23` | `23`, `-23` | -| Float | `23.0`, `-23.0` | `23.0`, `-23.0` | -| Integer Addition | `23 + 1` | `23 + 1` | -| Float Addition | `23.0 +. 1.0` | `23.0 + 1.0` | -| Integer Division/Multiplication | `2 / 23 * 1` | `2 / 23 * 1` | -| Float Division/Multiplication | `2.0 /. 23.0 *. 1.0` | `2.0 / 23.0 * 1.0` | -| Float Exponentiation | `2.0 ** 3.0` | `Math.pow(2.0, 3.0)` | -| String Concatenation | `"Hello " ++ "World"` | `"Hello " + "World"` | -| Comparison | `>`, `<`, `>=`, `<=` | `>`, `<`, `>=`, `<=` | -| Boolean operation | `!`, `&&`, `\|\|` | `!`, `&&`, `\|\|` | -| Shallow and deep Equality | `===`, `==` | `===`, `==` | -| List (discouraged) | `list{1, 2, 3}` | `{hd: 1, tl: {hd: 2, tl: {hd: 3, tl: 0}}}` | -| List Prepend | `list{a1, a2, ...oldList}` | `{hd: a1, tl: {hd: a2, tl: theRest}}` | -| Array | `[1, 2, 3]` | `[1, 2, 3]` | -| Record | `type t = {b: int}; let a = {b: 10}` | `var a = {b: 10}` | -| Multiline Comment | `/* Comment here */` | Not in output | -| Single line Comment | `// Comment here` | Not in output | - -_Note that this is a cleaned-up comparison table; a few examples' JavaScript output are slightly different in reality._ +## If-Else + +| Syntax | Description | +| ------------------- | ------------------------------------------------------------------------ | +| `if a {b} else {c}` | Conditional expression | +| `a ? b : c` | Ternary expression | +| `switch` | Pattern matching — [see full docs](./pattern-matching-destructuring.mdx) | + +Conditionals are expressions: `let result = if a {"hello"} else {"bye"}` + +## Destructuring + +| Syntax | Description | +| --------------------------- | ------------------------- | +| `let {a, b} = data` | Record destructuring | +| `let [a, b] = data` | Array destructuring \* | +| `let {a: aa, b: bb} = data` | Destructuring with rename | + +\* The compiler warns if `data` might not be of length 2. + +## Loops + +| Syntax | Description | +| ---------------------------- | --------------- | +| `for i in 0 to 10 {...}` | Ascending loop | +| `for i in 10 downto 0 {...}` | Descending loop | +| `while true {...}` | While loop | + +## JSX + +| Syntax | Description | +| ----------------------------------------- | ---------------------- | +| `` | Props | +| `` | Argument punning | +| `` | Explicit boolean props | +| `...children` | Children spread | + +## Exceptions + +| Syntax | Description | +| --------------------------------------------- | --------------------- | +| `throw(SomeException(...))` | Raise an exception | +| `try a catch { \| SomeException(err) => ...}` | Catch an exception \* | + +\* There is no `finally` clause. + +## Compilation Output Reference + +A reference showing how common ReScript features compile to JavaScript. + +| Feature | ReScript | JavaScript Output | +| ------------------------- | ------------------------------------ | ------------------------------------------ | +| String | `"Hello"` | `"Hello"` | +| String Interpolation | `` `Hello ${message}` `` | `"Hello " + message` | +| Character (discouraged) | `'x'` | `120` (char code) | +| Integer | `23`, `-23` | `23`, `-23` | +| Float | `23.0`, `-23.0` | `23.0`, `-23.0` | +| Addition | `23 + 1` | `23 + 1` | +| Float Addition | `23.0 + 1.0` | `23.0 + 1.0` | +| Division/Multiply | `2 / 23 * 1` | `2 / 23 * 1` | +| Float Division/Multiply | `2.0 / 23.0 * 1.0` | `2.0 / 23.0 * 1.0` | +| Float Exponentiation | `2.0 ** 3.0` | `2.0 ** 3.0` | +| String Concatenation | `"Hello " ++ "World"` | `"Hello " + "World"` | +| Comparison | `>`, `<`, `>=`, `<=` | `>`, `<`, `>=`, `<=` | +| Boolean operation | `!`, `&&`, `\|\|` | `!`, `&&`, `\|\|` | +| Shallow and deep Equality | `===`, `==` | `===`, `==` | +| List (discouraged) | `list{1, 2, 3}` | `{hd: 1, tl: {hd: 2, tl: {hd: 3, tl: 0}}}` | +| List Prepend | `list{a1, a2, ...oldList}` | `{hd: a1, tl: {hd: a2, tl: theRest}}` | +| Array | `[1, 2, 3]` | `[1, 2, 3]` | +| Record | `type t = {b: int}; let a = {b: 10}` | `var a = {b: 10}` | +| Multiline Comment | `/* Comment here */` | Not in output | +| Single line Comment | `// Comment here` | Not in output | + +_Note that this is a cleaned-up reference table; some examples' JavaScript output may differ slightly in practice._ diff --git a/markdown-pages/docs/manual/primitive-types.mdx b/markdown-pages/docs/manual/primitive-types.mdx index 0ce777644..dbe5c7239 100644 --- a/markdown-pages/docs/manual/primitive-types.mdx +++ b/markdown-pages/docs/manual/primitive-types.mdx @@ -89,7 +89,7 @@ See the familiar `String` API in the [API docs](/docs/manual/api/stdlib/string). - an enum: `if (audio.canPlayType() === 'probably') {...}` [(ಠ_ಠ)](https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/canPlayType#Return_value) - other crazy patterns you'll soon find horrible, after getting used to ReScript's alternatives. -The more you overload the poor string type, the less the type system (or a teammate) can help you! ReScript provides concise, fast and maintainable types & data structures alternatives to the use-cases above (e.g. variants, in a later section). +The more you overload the poor string type, the less the type system (or a teammate) can help you! ReScript provides concise, fast and maintainable types & data structures alternatives to the use-cases above (e.g. [variants](./variant.mdx)). ## Char @@ -160,9 +160,7 @@ To improve readability, you may place underscores in the middle of numeric liter ## Floats -Float requires other operators: `+.`, `-.`, `*.`, `/.`, etc. Like `0.5 +. 0.6`. See [Float](/docs/manual/api/stdlib/float) for helper functions. - -Float also supports `**` (exponentiation) and `%` (remainder semantics). +Arithmetic operators (`+`, `-`, `*`, `/`, `%`, `**`) work for both `int` and `float`. Like `0.5 + 0.6`. See [Float](/docs/manual/api/stdlib/float) for helper functions. As with integers, you may use underscores within literals to improve readability. @@ -173,7 +171,7 @@ As with integers, you may use underscores within literals to improve readability ```res example -let result = (1 :> float) +. 2. +let result = (1 :> float) + 2. ``` ```js diff --git a/markdown-pages/docs/manual/record.mdx b/markdown-pages/docs/manual/record.mdx index f12a4d3cd..eebbb545f 100644 --- a/markdown-pages/docs/manual/record.mdx +++ b/markdown-pages/docs/manual/record.mdx @@ -657,7 +657,7 @@ Optional record fields, introduced in [`v10`](../../blog/release-10-0-0.mdx#expe ## Design Decisions -After reading the constraints in the previous sections, and if you're coming from a dynamic language background, you might be wondering why one would bother with record in the first place instead of straight using object, since the former needs explicit typing and doesn't allow different records with the same field name to be passed to the same function, etc. +Why use records instead of objects? 1. The truth is that most of the times in your app, your data's shape is actually fixed, and if it's not, it can potentially be better represented as a combination of variant (introduced next) + record instead. diff --git a/markdown-pages/docs/manual/shared-data-types.mdx b/markdown-pages/docs/manual/shared-data-types.mdx index 9c1f9d8cf..bc00c31c3 100644 --- a/markdown-pages/docs/manual/shared-data-types.mdx +++ b/markdown-pages/docs/manual/shared-data-types.mdx @@ -10,30 +10,30 @@ order: 2 ReScript's built-in values of type `string`, `float`, `array` and a few others have a rather interesting property: they compile to the exact same value in JavaScript! -This means that if you're passing e.g. a ReScript string to the JavaScript side, the JS side can directly use it as a native JS string. It also means that you can import a JS string and pretend it's a native ReScript string. +This means that if you're passing e.g. a ReScript string to the JavaScript side, the JavaScript side can directly use it as a native string. It also means that you can import a JavaScript string and use it as a native ReScript string. -Unlike most compiled-to-js languages, in ReScript, **you don't need to write data converters back and forth for most of our values**! +ReScript values compile to their JavaScript equivalents directly, so **no data converters are needed for most types**. **Shared, bidirectionally usable types**: - String. ReScript strings are JavaScript strings, vice-versa. (Caveat: only our backtick string `` `hello 👋 ${personName}` `` supports unicode and interpolation). -- Float. ReScript floats are JS numbers, vice-versa. -- Array. In addition to the [Array API](/docs/manual/api/stdlib/array), we provide our own [Belt.Array](/docs/manual/api/belt/array#set) API too. -- Tuple. Compiles to a JS array. You can treat a fixed-sized, heterogenous JS array as ReScript tuple too. +- Float. ReScript floats are JavaScript numbers, vice-versa. +- Array. Use the [Array API](/docs/manual/api/stdlib/array) for array operations. +- Tuple. Compiles to an array at runtime. You can treat a fixed-sized, heterogenous JavaScript array as a ReScript tuple too. - Boolean. -- Record. Record compiles to JS object. Therefore you can also treat JS objects as records. If they're too dynamic, consider modeling them on the ReScript side as a hashmap/dictionary [`Dict`](/docs/manual/api/stdlib/dict) or a ReScript object. +- Record. Record compiles to a JavaScript object. Therefore you can also treat JavaScript objects as records. If they're too dynamic, consider modeling them on the ReScript side as a hashmap/dictionary [`Dict`](/docs/manual/api/stdlib/dict) or a ReScript object. - Object. ReScript objects are JavaScript objects, vice-versa. -- Function. They compile to clean JS functions. -- Module. ReScript files are considered top-level modules, and are compiled to JS files 1 to 1. Nested modules are compiled to JavaScript objects. +- Function. They compile to clean JavaScript functions. +- Module. ReScript files are considered top-level modules, and are compiled to JavaScript files 1 to 1. Nested modules are compiled to JavaScript objects. - Polymorphic variants. -- Unit. The `unit` type, which has a single value `()`, compiles to `undefined` too. Likewise, you can treat an incoming JS `undefined` as `()` if that's the only value it'll ever be. +- Unit. The `unit` type, which has a single value `()`, compiles to `undefined` too. Likewise, you can treat an incoming `undefined` as `()` if that's the only value it'll ever be. -**Types that are slightly different than JS, but that you can still use from JS**: +**Types that are slightly different, but that you can still use from JavaScript**: -- Int. **Ints are 32-bits**! Be careful, you can potentially treat them as JS numbers and vice-versa, but if the number's large, then you better treat JS numbers as floats. For example, we bind to `Date` using `float`s. -- Option. The `option` type's `None` value compiles into JS `undefined`. The `Some` value, e.g. `Some(5)`, compiles to `5`. Likewise, you can treat an incoming JS `undefined` as `None`. **JS `null` isn't handled here**. If your JS value can be `null`, use [Nullable](/docs/manual/api/stdlib/nullable) helpers. +- Int. **Ints are 32-bits**! Be careful, you can potentially treat them as JavaScript numbers and vice-versa, but if the number's large, then you better treat JavaScript numbers as floats. For example, we bind to `Date` using `float`s. +- Option. The `option` type's `None` value compiles into `undefined`. The `Some` value, e.g. `Some(5)`, compiles to `5`. Likewise, you can treat an incoming `undefined` as `None`. **`null` isn't handled here**. If your JavaScript value can be `null`, use [Nullable](/docs/manual/api/stdlib/nullable) helpers. - Exception. -- Variant. Check the compiled JavaScript output of variant to see its shape. We don't recommend exporting a ReScript variant for pure JS usage, since they're harder to read as plain JS code, but you can do it. +- Variant. Check the compiled JavaScript output of variant to see its shape. We don't recommend exporting a ReScript variant for pure JavaScript usage, since they're harder to read as plain JavaScript code, but you can do it. - List, which is just a regular variant. **Non-shared types (aka internal types)**: @@ -45,4 +45,4 @@ Unlike most compiled-to-js languages, in ReScript, **you don't need to write dat Many of these are stable, which means that you can still serialize/deserialize them as-is without manual conversions. But we discourage actively peeking into their structure otherwise. -These types require manual conversions if you want to export them for JS consumption. For a seamless JS/TypeScript integration experience, you might want to use [genType](https://github.com/cristianoc/gentype) instead of doing conversions by hand. +These types require manual conversions if you want to export them for JavaScript consumption. For a seamless JavaScript/TypeScript integration experience, check out the [TypeScript Integration](./typescript-integration.mdx) page instead of doing conversions by hand. diff --git a/markdown-pages/docs/manual/type.mdx b/markdown-pages/docs/manual/type.mdx index d32da7b26..747c77f5f 100644 --- a/markdown-pages/docs/manual/type.mdx +++ b/markdown-pages/docs/manual/type.mdx @@ -277,7 +277,7 @@ This declaration converts a `myType1` of your choice to `myType2` of your choice ```res example external convertToFloat : int => float = "%identity" let age = 10 -let gpa = 2.1 +. convertToFloat(age) +let gpa = 2.1 + convertToFloat(age) ``` ```js diff --git a/markdown-pages/syntax-lookup/extension_identity.mdx b/markdown-pages/syntax-lookup/extension_identity.mdx index 776f9ccee..846891c99 100644 --- a/markdown-pages/syntax-lookup/extension_identity.mdx +++ b/markdown-pages/syntax-lookup/extension_identity.mdx @@ -13,7 +13,7 @@ category: "extensionpoints" ```res external convertToFloat: int => float = "%identity" let age = 10 -let gpa = 2.1 +. convertToFloat(age) +let gpa = 2.1 + convertToFloat(age) ``` ```js diff --git a/markdown-pages/syntax-lookup/language_labeled_argument.mdx b/markdown-pages/syntax-lookup/language_labeled_argument.mdx index 8b3ae0bea..23d655222 100644 --- a/markdown-pages/syntax-lookup/language_labeled_argument.mdx +++ b/markdown-pages/syntax-lookup/language_labeled_argument.mdx @@ -14,7 +14,7 @@ When declaring a function, arguments can be prefixed with `~` which means that t ```res prelude let calculateDistance = (~x1, ~y1, ~x2, ~y2) => { - Math.sqrt((x1 -. x2) ** 2. +. (y1 -. y2) ** 2.) + Math.sqrt((x1 - x2) ** 2. + (y1 - y2) ** 2.) } calculateDistance(~x1=6., ~y1=8., ~x2=3., ~y2=4.) diff --git a/markdown-pages/syntax-lookup/language_open.mdx b/markdown-pages/syntax-lookup/language_open.mdx index 63dee0be4..f95b3e317 100644 --- a/markdown-pages/syntax-lookup/language_open.mdx +++ b/markdown-pages/syntax-lookup/language_open.mdx @@ -17,8 +17,8 @@ In some cases, `open` will cause a "shadow warning" due to existing identifiers ```res open Math -// Use _PI and pow_float from the Math module -let area = radius => Constants.pi *. pow(radius, ~exp=2.0) +// Use PI and pow from the Math module +let area = radius => Constants.pi * pow(radius, ~exp=2.0) ``` ```js diff --git a/src/Path.res b/src/Path.res index 7f85f27ea..b71508fe4 100644 --- a/src/Path.res +++ b/src/Path.res @@ -300,10 +300,8 @@ type t = [ | #"/docs/manual/build-performance" | #"/docs/manual/build-overview" | #"/docs/manual/build-monorepo-setup" - | #"/docs/manual/build-external-stdlib" | #"/docs/manual/build-configuration" | #"/docs/manual/build-configuration-schema" - | #"/docs/manual/browser-support-polyfills" | #"/docs/manual/bind-to-js-object" | #"/docs/manual/bind-to-js-function" | #"/docs/manual/bind-to-global-js-values"