From 8f9de57dfb87662d71fe371a64c560da9e0e591d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20Tsnobiladz=C3=A9?= Date: Tue, 5 Dec 2023 11:37:31 +0100 Subject: [PATCH 1/4] remove unboxed doc, point it to untagged variant --- misc_docs/syntax/decorator_unboxed.mdx | 10 +- .../docs/manual/latest/interop-cheatsheet.mdx | 2 +- pages/docs/manual/latest/unboxed.mdx | 157 ------------------ 3 files changed, 7 insertions(+), 162 deletions(-) delete mode 100644 pages/docs/manual/latest/unboxed.mdx diff --git a/misc_docs/syntax/decorator_unboxed.mdx b/misc_docs/syntax/decorator_unboxed.mdx index 4eb9c7c89..0be8cfe0a 100644 --- a/misc_docs/syntax/decorator_unboxed.mdx +++ b/misc_docs/syntax/decorator_unboxed.mdx @@ -7,7 +7,7 @@ category: "decorators" --- The `@unboxed` decorator provides a way to unwrap **variant** constructors -that have a *single* argument, or **record** objects that have a *single* field. +that have no overlap in their runtime representation, or **record** objects that have a *single* field. ### Example @@ -15,7 +15,8 @@ that have a *single* argument, or **record** objects that have a *single* field. ```res @unboxed -type name = Name(string) +type listItemValue = String(string) | Boolean(bool) | Number(float) +let myArray = [String("Hello"), Boolean(true), Boolean(false), Number(13.37)] let studentName = Name("Joe") @unboxed @@ -24,7 +25,7 @@ let hi = {message: "hello!"} ``` ```js -var studentName = "Joe"; +var myArray = ["hello", true, false, 13.37]; var hi = "hello!"; ``` @@ -32,4 +33,5 @@ var hi = "hello!"; ### References -* [Unboxed](/docs/manual/latest/unboxed) \ No newline at end of file +* [Untagged variants](variant#untagged-variants) +* [Unboxed record](/docs/manual/v10.0.0/unboxed) \ No newline at end of file diff --git a/pages/docs/manual/latest/interop-cheatsheet.mdx b/pages/docs/manual/latest/interop-cheatsheet.mdx index 4e189cb45..e2b366408 100644 --- a/pages/docs/manual/latest/interop-cheatsheet.mdx +++ b/pages/docs/manual/latest/interop-cheatsheet.mdx @@ -45,7 +45,7 @@ This is a glossary with examples. All the features are described by later pages. - [`@JSX`](jsx) - `@react.component`: [here](/docs/react/latest/introduction) and [here](https://github.com/reasonml/reason-react) - [`@warning`](attribute#usage) -- [`@unboxed`](unboxed) +- [`@unboxed`](variant#untagged-variants) ### Extension Points diff --git a/pages/docs/manual/latest/unboxed.mdx b/pages/docs/manual/latest/unboxed.mdx deleted file mode 100644 index 6ebe3c4b3..000000000 --- a/pages/docs/manual/latest/unboxed.mdx +++ /dev/null @@ -1,157 +0,0 @@ ---- -title: "Unboxed" -description: "Unbox a wrapper" -canonical: "/docs/manual/latest/unboxed" ---- - -# Unboxed - -Consider a ReScript variant with a single payload, and a record with a single field: - - - -```res -type name = Name(string) -let studentName = Name("Joe") - -type greeting = {message: string} -let hi = {message: "hello!"} -``` -```js -var studentName = /* Name */{ - _0: "Joe" -}; - -var hi = { - message: "hello!" -}; -``` - - - -If you check the JavaScript output, you'll see the `studentName` and `hi` JS object, as expected (see the [variant JS output](variant#javascript-output) and [record JS output](record#javascript-output) sections for details). - -For performance and certain JavaScript interop situations, ReScript offers a way to unwrap (aka unbox) the JS object wrappers from the output for records with a single field and variants with a single constructor and single payload. Annotate their type declaration with the attribute `@unboxed`: - - - -```res -@unboxed -type name = Name(string) -let studentName = Name("Joe") - -@unboxed -type greeting = {message: string} -let hi = {message: "hello!"} -``` -```js -var studentName = "Joe"; - -var hi = "hello!"; -``` - - - -Check the new output! Clean. - -## Usage - -Why would you ever want a variant or a record with a single payload? Why not just... pass the payload? Here's one use-case for variant. - -Suppose you have a game with a local/global coordinate system: - - - -```res example -type coordinates = {x: float, y: float} - -let renderDot = (coordinates) => { - Js.log3("Pretend to draw at:", coordinates.x, coordinates.y) -} - -let toWorldCoordinates = (localCoordinates) => { - { - x: localCoordinates.x +. 10., - y: localCoordinates.x +. 20., - } -} - -let playerLocalCoordinates = {x: 20.5, y: 30.5} - -renderDot(playerLocalCoordinates) -``` -```js -function renderDot(coordinates) { - console.log("Pretend to draw at:", coordinates.x, coordinates.y); -} - -function toWorldCoordinates(localCoordinates) { - return { - x: localCoordinates.x + 10, - y: localCoordinates.x + 20 - }; -} - -var playerLocalCoordinates = { - x: 20.5, - y: 30.5 -}; - -renderDot(playerLocalCoordinates); -``` - - - -Oops, that's wrong! `renderDot` should have taken global coordinates, not local ones... Let's prevent passing the wrong kind of coordinates: - - - -```res example -type coordinates = {x: float, y: float} -@unboxed type localCoordinates = Local(coordinates) -@unboxed type worldCoordinates = World(coordinates) - -let renderDot = (World(coordinates)) => { - Js.log3("Pretend to draw at:", coordinates.x, coordinates.y) -} - -let toWorldCoordinates = (Local(coordinates)) => { - World({ - x: coordinates.x +. 10., - y: coordinates.x +. 20., - }) -} - -let playerLocalCoordinates = Local({x: 20.5, y: 30.5}) - -// This now errors! -// renderDot(playerLocalCoordinates) -// We're forced to do this instead: -renderDot(playerLocalCoordinates->toWorldCoordinates) -``` -```js -function renderDot(coordinates) { - console.log("Pretend to draw at:", coordinates.x, coordinates.y); -} - -function toWorldCoordinates(coordinates) { - return { - x: coordinates.x + 10, - y: coordinates.x + 20 - }; -} - -var playerLocalCoordinates = { - x: 20.5, - y: 30.5 -}; - -renderDot(toWorldCoordinates(playerLocalCoordinates)); -``` - - - -Now `renderDot` only takes `worldCoordinates`. Through a nice combination of using distinct variant types + argument destructuring, we've achieved better safety **without compromising on performance**: the `unboxed` attribute compiled to clean, variant-wrapper-less JS code! Check the output. - -As for a record with a single field, the use-cases are a bit more edgy. We won't mention them here. - From 65e08a3d0bbbed99d3b7e0411ae4825890c5ab0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20Tsnobiladz=C3=A9?= Date: Tue, 5 Dec 2023 12:01:57 +0100 Subject: [PATCH 2/4] add available since v11 for untagged variants --- misc_docs/syntax/decorator_unboxed.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/misc_docs/syntax/decorator_unboxed.mdx b/misc_docs/syntax/decorator_unboxed.mdx index 0be8cfe0a..14741768a 100644 --- a/misc_docs/syntax/decorator_unboxed.mdx +++ b/misc_docs/syntax/decorator_unboxed.mdx @@ -31,6 +31,8 @@ var hi = "hello!"; +_`@unboxed` for variants with multiple constructors is available since ReScript `11.0.0`._ + ### References * [Untagged variants](variant#untagged-variants) From 0c7557fd3ce172ae267b30737d063f7d7e332573 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20Tsnobiladz=C3=A9?= Date: Tue, 5 Dec 2023 12:02:12 +0100 Subject: [PATCH 3/4] add link to blog post about untagged variants --- misc_docs/syntax/decorator_unboxed.mdx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/misc_docs/syntax/decorator_unboxed.mdx b/misc_docs/syntax/decorator_unboxed.mdx index 14741768a..22adf9742 100644 --- a/misc_docs/syntax/decorator_unboxed.mdx +++ b/misc_docs/syntax/decorator_unboxed.mdx @@ -35,5 +35,6 @@ _`@unboxed` for variants with multiple constructors is available since ReScript ### References -* [Untagged variants](variant#untagged-variants) +* [Untagged variants doc](variant#untagged-variants) +* [Blog post introducing untagged variants](blog/improving-interop) * [Unboxed record](/docs/manual/v10.0.0/unboxed) \ No newline at end of file From 1fabe8dfc8d3ba2126540e591ba45c4fd49276e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Paul=20Tsnobiladz=C3=A9?= Date: Tue, 5 Dec 2023 12:19:36 +0100 Subject: [PATCH 4/4] fix links --- misc_docs/syntax/decorator_unboxed.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/misc_docs/syntax/decorator_unboxed.mdx b/misc_docs/syntax/decorator_unboxed.mdx index 22adf9742..05fd81337 100644 --- a/misc_docs/syntax/decorator_unboxed.mdx +++ b/misc_docs/syntax/decorator_unboxed.mdx @@ -35,6 +35,6 @@ _`@unboxed` for variants with multiple constructors is available since ReScript ### References -* [Untagged variants doc](variant#untagged-variants) -* [Blog post introducing untagged variants](blog/improving-interop) +* [Untagged variants doc](/docs/manual/latest/variant#untagged-variants) +* [Blog post introducing untagged variants](/blog/improving-interop) * [Unboxed record](/docs/manual/v10.0.0/unboxed) \ No newline at end of file