From 98ac19574bd617e1e7dcf588554062ccc7fd01ff Mon Sep 17 00:00:00 2001 From: Florian Hammerschmidt Date: Wed, 3 Feb 2021 16:02:42 +0100 Subject: [PATCH 01/15] Add section about extensible variant types. --- data/sidebar_manual_latest.json | 3 + .../docs/manual/latest/extensible-variant.mdx | 62 +++++++++++++++++++ 2 files changed, 65 insertions(+) create mode 100644 pages/docs/manual/latest/extensible-variant.mdx diff --git a/data/sidebar_manual_latest.json b/data/sidebar_manual_latest.json index 3d42984c2..014109934 100644 --- a/data/sidebar_manual_latest.json +++ b/data/sidebar_manual_latest.json @@ -33,6 +33,9 @@ "unboxed", "reserved-keywords" ], + "Advanced Language Features": [ + "extensible-variant" + ], "JavaScript Interop": [ "embed-raw-javascript", "shared-data-types", diff --git a/pages/docs/manual/latest/extensible-variant.mdx b/pages/docs/manual/latest/extensible-variant.mdx new file mode 100644 index 000000000..8749ed6fa --- /dev/null +++ b/pages/docs/manual/latest/extensible-variant.mdx @@ -0,0 +1,62 @@ +--- +title: "Extensible Variant" +description: "Extensible Variants in ReScript" +canonical: "/docs/manual/latest/extensible-variant" +--- + +# Extensible Variant Types + +Variants can be made extensible by defining a type using `..` and adding new variant constructors using `+=`. + + + +```res example +type t = .. + +type t += Other + +type t += + | Point(float, float) + | Line(float, float, float, float) +``` +```js +var Caml_exceptions = require("./stdlib/caml_exceptions.js"); + +var Other = Caml_exceptions.create("Playground.Other"); + +var Point = Caml_exceptions.create("Playground.Point"); + +var Line = Caml_exceptions.create("Playground.Line"); +``` + + + +Pattern-matching is possible the same way as with normal variants but there is one caveat: +With extensible variants, the possibility to check for exhaustiveness vanishes, you always need a default case `_` here. + + + + + +```res example +let print = v => + switch v { + | Point(x, y) => Js.log2("Point", (x, y)) + | Line(ax, ay, bx, by) => Js.log2("Line", (ax, ay, bx, by)) + | Other + | _ => Js.log("Other") + } +``` +```js +function print(v) { + if (v.RE_EXN_ID === Point) { + console.log("Point", [v._1, v._2]); + } else if (v.RE_EXN_ID === Line) { + console.log("Line", [v._1, v._2, v._3, v._4]); + } else { + console.log("Other"); + } +} +``` + + \ No newline at end of file From 55f3cfdcd0c726728aa0d72bf91c6d38956ffa4c Mon Sep 17 00:00:00 2001 From: Patrick Ecker Date: Tue, 7 Sep 2021 10:28:52 +0200 Subject: [PATCH 02/15] Update pages/docs/manual/latest/extensible-variant.mdx --- pages/docs/manual/latest/extensible-variant.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/docs/manual/latest/extensible-variant.mdx b/pages/docs/manual/latest/extensible-variant.mdx index 8749ed6fa..ed6dd4bdb 100644 --- a/pages/docs/manual/latest/extensible-variant.mdx +++ b/pages/docs/manual/latest/extensible-variant.mdx @@ -4,7 +4,7 @@ description: "Extensible Variants in ReScript" canonical: "/docs/manual/latest/extensible-variant" --- -# Extensible Variant Types +# Extensible Variant Variants can be made extensible by defining a type using `..` and adding new variant constructors using `+=`. From 69d88ffc8fc7572e61bdf958da9f35b4eeb8a03e Mon Sep 17 00:00:00 2001 From: Patrick Ecker Date: Tue, 7 Sep 2021 10:29:12 +0200 Subject: [PATCH 03/15] Update pages/docs/manual/latest/extensible-variant.mdx --- pages/docs/manual/latest/extensible-variant.mdx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pages/docs/manual/latest/extensible-variant.mdx b/pages/docs/manual/latest/extensible-variant.mdx index ed6dd4bdb..72bbffb6c 100644 --- a/pages/docs/manual/latest/extensible-variant.mdx +++ b/pages/docs/manual/latest/extensible-variant.mdx @@ -6,7 +6,9 @@ canonical: "/docs/manual/latest/extensible-variant" # Extensible Variant -Variants can be made extensible by defining a type using `..` and adding new variant constructors using `+=`. +Variant types are usually constraint to a fixed set of constructors that are defined in its type declaration. There may be very rare cases where you still want to be able to add constructors to a variant type (e.g. in different places of your program). For this, we offer extensible variant types. + +## Definition and Usage From 41a900505c44fc12e11e02b52fc6bc7443d9f22d Mon Sep 17 00:00:00 2001 From: Patrick Ecker Date: Tue, 7 Sep 2021 10:29:45 +0200 Subject: [PATCH 04/15] Update pages/docs/manual/latest/extensible-variant.mdx --- pages/docs/manual/latest/extensible-variant.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pages/docs/manual/latest/extensible-variant.mdx b/pages/docs/manual/latest/extensible-variant.mdx index 72bbffb6c..096b85c6b 100644 --- a/pages/docs/manual/latest/extensible-variant.mdx +++ b/pages/docs/manual/latest/extensible-variant.mdx @@ -33,6 +33,8 @@ var Line = Caml_exceptions.create("Playground.Line"); +The `..` in the type declaration above defines an extensible variant `type t`. The `+=` operator is then used to add constructors to the given type. + Pattern-matching is possible the same way as with normal variants but there is one caveat: With extensible variants, the possibility to check for exhaustiveness vanishes, you always need a default case `_` here. From 2b06bcc2e3f2940139379aeabf00405f139eaee2 Mon Sep 17 00:00:00 2001 From: Patrick Ecker Date: Tue, 7 Sep 2021 10:30:19 +0200 Subject: [PATCH 05/15] Update pages/docs/manual/latest/extensible-variant.mdx --- pages/docs/manual/latest/extensible-variant.mdx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pages/docs/manual/latest/extensible-variant.mdx b/pages/docs/manual/latest/extensible-variant.mdx index 096b85c6b..937d1a5b4 100644 --- a/pages/docs/manual/latest/extensible-variant.mdx +++ b/pages/docs/manual/latest/extensible-variant.mdx @@ -35,7 +35,9 @@ var Line = Caml_exceptions.create("Playground.Line"); The `..` in the type declaration above defines an extensible variant `type t`. The `+=` operator is then used to add constructors to the given type. -Pattern-matching is possible the same way as with normal variants but there is one caveat: +## Pattern Matching Caveats + +Extensible variants are open-ended, so the compiler will not be able to exhaustively pattern match all available cases. You will always need to provide a default `_` case for every `switch` expression. With extensible variants, the possibility to check for exhaustiveness vanishes, you always need a default case `_` here. From b8291e23bb443564f460c55f769b334b7e204572 Mon Sep 17 00:00:00 2001 From: Patrick Ecker Date: Tue, 7 Sep 2021 10:30:24 +0200 Subject: [PATCH 06/15] Update pages/docs/manual/latest/extensible-variant.mdx --- pages/docs/manual/latest/extensible-variant.mdx | 1 - 1 file changed, 1 deletion(-) diff --git a/pages/docs/manual/latest/extensible-variant.mdx b/pages/docs/manual/latest/extensible-variant.mdx index 937d1a5b4..5b7adb334 100644 --- a/pages/docs/manual/latest/extensible-variant.mdx +++ b/pages/docs/manual/latest/extensible-variant.mdx @@ -38,7 +38,6 @@ The `..` in the type declaration above defines an extensible variant `type t`. T ## Pattern Matching Caveats Extensible variants are open-ended, so the compiler will not be able to exhaustively pattern match all available cases. You will always need to provide a default `_` case for every `switch` expression. -With extensible variants, the possibility to check for exhaustiveness vanishes, you always need a default case `_` here. From 8312fff0136ef8fde6104b9b2ea2490f61037a15 Mon Sep 17 00:00:00 2001 From: Patrick Ecker Date: Tue, 7 Sep 2021 10:30:32 +0200 Subject: [PATCH 07/15] Update pages/docs/manual/latest/extensible-variant.mdx --- pages/docs/manual/latest/extensible-variant.mdx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/pages/docs/manual/latest/extensible-variant.mdx b/pages/docs/manual/latest/extensible-variant.mdx index 5b7adb334..e721d1652 100644 --- a/pages/docs/manual/latest/extensible-variant.mdx +++ b/pages/docs/manual/latest/extensible-variant.mdx @@ -64,4 +64,8 @@ function print(v) { } ``` - \ No newline at end of file + + +## Tips & Tricks + +**Fun fact:** In ReScript, [exceptions](./exception) are actually implemented as Extensible Variants under the hood, so `exception UserError(string)` is equivalent to `type exn += UserError(string)`. It's probably one of the few use-cases were Extensible Variants make sense. We usually recommend sticking with common [Variants](./variant) as much as possible to reap the benefits of exhaustive pattern matching. \ No newline at end of file From edecfe9bbc4a50f9d6850f5fdf7467e9899cf3a8 Mon Sep 17 00:00:00 2001 From: Patrick Ecker Date: Tue, 7 Sep 2021 10:31:07 +0200 Subject: [PATCH 08/15] Update pages/docs/manual/latest/extensible-variant.mdx --- pages/docs/manual/latest/extensible-variant.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/docs/manual/latest/extensible-variant.mdx b/pages/docs/manual/latest/extensible-variant.mdx index e721d1652..fc755a1ff 100644 --- a/pages/docs/manual/latest/extensible-variant.mdx +++ b/pages/docs/manual/latest/extensible-variant.mdx @@ -68,4 +68,4 @@ function print(v) { ## Tips & Tricks -**Fun fact:** In ReScript, [exceptions](./exception) are actually implemented as Extensible Variants under the hood, so `exception UserError(string)` is equivalent to `type exn += UserError(string)`. It's probably one of the few use-cases were Extensible Variants make sense. We usually recommend sticking with common [Variants](./variant) as much as possible to reap the benefits of exhaustive pattern matching. \ No newline at end of file +**Fun fact:** In ReScript, [exceptions](./exception) are actually implemented as extensible variants under the hood, so `exception UserError(string)` is equivalent to `type exn += UserError(string)`. It's probably one of the few use-cases were Extensible Variants make sense. We usually recommend sticking with common [Variants](./variant) as much as possible to reap the benefits of exhaustive pattern matching. \ No newline at end of file From a923f1a3d605750eab81053811859512080fe5d5 Mon Sep 17 00:00:00 2001 From: Patrick Ecker Date: Tue, 7 Sep 2021 10:32:23 +0200 Subject: [PATCH 09/15] Update pages/docs/manual/latest/extensible-variant.mdx --- pages/docs/manual/latest/extensible-variant.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/docs/manual/latest/extensible-variant.mdx b/pages/docs/manual/latest/extensible-variant.mdx index fc755a1ff..e06cf9c8c 100644 --- a/pages/docs/manual/latest/extensible-variant.mdx +++ b/pages/docs/manual/latest/extensible-variant.mdx @@ -68,4 +68,4 @@ function print(v) { ## Tips & Tricks -**Fun fact:** In ReScript, [exceptions](./exception) are actually implemented as extensible variants under the hood, so `exception UserError(string)` is equivalent to `type exn += UserError(string)`. It's probably one of the few use-cases were Extensible Variants make sense. We usually recommend sticking with common [Variants](./variant) as much as possible to reap the benefits of exhaustive pattern matching. \ No newline at end of file +**Fun fact:** In ReScript, [exceptions](./exception) are actually implemented as extensible variants under the hood, so `exception UserError(string)` is equivalent to `type exn += UserError(string)`. It's probably one of the few use-cases were extensible variants make sense. We usually recommend sticking with common [variants](./variant) as much as possible to reap the benefits of exhaustive pattern matching. \ No newline at end of file From f2aa4f4031f210ae57f755990a495feb298fe240 Mon Sep 17 00:00:00 2001 From: Patrick Ecker Date: Tue, 7 Sep 2021 10:35:35 +0200 Subject: [PATCH 10/15] Update pages/docs/manual/latest/extensible-variant.mdx remove example notation due to missing constructor --- pages/docs/manual/latest/extensible-variant.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/docs/manual/latest/extensible-variant.mdx b/pages/docs/manual/latest/extensible-variant.mdx index e06cf9c8c..f1e005968 100644 --- a/pages/docs/manual/latest/extensible-variant.mdx +++ b/pages/docs/manual/latest/extensible-variant.mdx @@ -43,7 +43,7 @@ Extensible variants are open-ended, so the compiler will not be able to exhausti -```res example +```res let print = v => switch v { | Point(x, y) => Js.log2("Point", (x, y)) From 390ae1bd9c3304f66583037db1947841c1fb9f91 Mon Sep 17 00:00:00 2001 From: Patrick Ecker Date: Tue, 7 Sep 2021 15:00:09 +0200 Subject: [PATCH 11/15] Update pages/docs/manual/latest/extensible-variant.mdx --- pages/docs/manual/latest/extensible-variant.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/docs/manual/latest/extensible-variant.mdx b/pages/docs/manual/latest/extensible-variant.mdx index f1e005968..d66e5c0d3 100644 --- a/pages/docs/manual/latest/extensible-variant.mdx +++ b/pages/docs/manual/latest/extensible-variant.mdx @@ -6,7 +6,7 @@ canonical: "/docs/manual/latest/extensible-variant" # Extensible Variant -Variant types are usually constraint to a fixed set of constructors that are defined in its type declaration. There may be very rare cases where you still want to be able to add constructors to a variant type (e.g. in different places of your program). For this, we offer extensible variant types. +Variant types are usually constrained to a fixed set of constructors. There may be very rare cases where you still want to be able to add constructors to a variant type (even after its initial type declaration). For this, we offer extensible variant types. ## Definition and Usage From dc59d5ad08af1977ea2861eacdc4d7de1290f376 Mon Sep 17 00:00:00 2001 From: Patrick Ecker Date: Tue, 7 Sep 2021 17:15:24 +0200 Subject: [PATCH 12/15] Update pages/docs/manual/latest/extensible-variant.mdx --- pages/docs/manual/latest/extensible-variant.mdx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pages/docs/manual/latest/extensible-variant.mdx b/pages/docs/manual/latest/extensible-variant.mdx index d66e5c0d3..bb2422d2c 100644 --- a/pages/docs/manual/latest/extensible-variant.mdx +++ b/pages/docs/manual/latest/extensible-variant.mdx @@ -6,7 +6,7 @@ canonical: "/docs/manual/latest/extensible-variant" # Extensible Variant -Variant types are usually constrained to a fixed set of constructors. There may be very rare cases where you still want to be able to add constructors to a variant type (even after its initial type declaration). For this, we offer extensible variant types. +Variant types are usually constrained to a fixed set of constructors. There may be very rare cases where you still want to be able to add constructors to a variant type even after its initial type declaration. For this, we offer extensible variant types. ## Definition and Usage From e116ae0a905e3de1944dfd0dee8f6a0d8c6c7884 Mon Sep 17 00:00:00 2001 From: Patrick Ecker Date: Wed, 8 Sep 2021 09:58:03 +0200 Subject: [PATCH 13/15] Update pages/docs/manual/latest/extensible-variant.mdx --- pages/docs/manual/latest/extensible-variant.mdx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pages/docs/manual/latest/extensible-variant.mdx b/pages/docs/manual/latest/extensible-variant.mdx index bb2422d2c..20702fead 100644 --- a/pages/docs/manual/latest/extensible-variant.mdx +++ b/pages/docs/manual/latest/extensible-variant.mdx @@ -68,4 +68,6 @@ function print(v) { ## Tips & Tricks -**Fun fact:** In ReScript, [exceptions](./exception) are actually implemented as extensible variants under the hood, so `exception UserError(string)` is equivalent to `type exn += UserError(string)`. It's probably one of the few use-cases were extensible variants make sense. We usually recommend sticking with common [variants](./variant) as much as possible to reap the benefits of exhaustive pattern matching. \ No newline at end of file +**Fun fact:** In ReScript, [exceptions](./exception) are actually extensible variants under the hood, so `exception UserError(string)` is equivalent to `type exn += UserError(string)`. It's one of the very few use-case where extensible variants make sense. + +We usually recommend sticking with common [variants](./variant) as much as possible to reap the benefits of exhaustive pattern matching. \ No newline at end of file From 36d7ff06d3b8495a4a33da98d9eb1c0e7bfbcebf Mon Sep 17 00:00:00 2001 From: Patrick Ecker Date: Wed, 8 Sep 2021 10:01:13 +0200 Subject: [PATCH 14/15] Update data/sidebar_manual_latest.json --- data/sidebar_manual_latest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/data/sidebar_manual_latest.json b/data/sidebar_manual_latest.json index 014109934..9b516a776 100644 --- a/data/sidebar_manual_latest.json +++ b/data/sidebar_manual_latest.json @@ -33,7 +33,7 @@ "unboxed", "reserved-keywords" ], - "Advanced Language Features": [ + "Advanced Features": [ "extensible-variant" ], "JavaScript Interop": [ From 878e1051fb0de3adccb337d836397db3c604fdf8 Mon Sep 17 00:00:00 2001 From: Patrick Ecker Date: Wed, 8 Sep 2021 10:03:03 +0200 Subject: [PATCH 15/15] Update pages/docs/manual/latest/extensible-variant.mdx --- pages/docs/manual/latest/extensible-variant.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pages/docs/manual/latest/extensible-variant.mdx b/pages/docs/manual/latest/extensible-variant.mdx index 20702fead..0569bd6b0 100644 --- a/pages/docs/manual/latest/extensible-variant.mdx +++ b/pages/docs/manual/latest/extensible-variant.mdx @@ -35,6 +35,8 @@ var Line = Caml_exceptions.create("Playground.Line"); The `..` in the type declaration above defines an extensible variant `type t`. The `+=` operator is then used to add constructors to the given type. +**Note:** Don't forget the leading `type` keyword when using the `+=` operator! + ## Pattern Matching Caveats Extensible variants are open-ended, so the compiler will not be able to exhaustively pattern match all available cases. You will always need to provide a default `_` case for every `switch` expression.