From 32ca780f43fc0f601ed2ebef78e2e0eb3d38c083 Mon Sep 17 00:00:00 2001 From: Josh Vlk Date: Mon, 22 Jan 2024 14:39:15 -0500 Subject: [PATCH 1/3] docs: add docs for equality and comparison --- data/sidebar_manual_latest.json | 5 +- .../manual/latest/equality-comparison.mdx | 125 ++++++++++++++++++ 2 files changed, 128 insertions(+), 2 deletions(-) create mode 100644 pages/docs/manual/latest/equality-comparison.mdx diff --git a/data/sidebar_manual_latest.json b/data/sidebar_manual_latest.json index 43a78c47a..097c77518 100644 --- a/data/sidebar_manual_latest.json +++ b/data/sidebar_manual_latest.json @@ -31,7 +31,8 @@ "module", "import-export", "attribute", - "reserved-keywords" + "reserved-keywords", + "equality-comparison" ], "Advanced Features": [ "extensible-variant", @@ -72,4 +73,4 @@ "project-structure", "faq" ] -} +} \ No newline at end of file diff --git a/pages/docs/manual/latest/equality-comparison.mdx b/pages/docs/manual/latest/equality-comparison.mdx new file mode 100644 index 000000000..62c4da3b3 --- /dev/null +++ b/pages/docs/manual/latest/equality-comparison.mdx @@ -0,0 +1,125 @@ +--- +title: "Equality and Comparison" +description: "compare" +canonical: "/docs/manual/latest/equality-comparison" +--- + +# Equality and Comparison + +ReScript has shallow equality `===`, deep equality `==`, and comparison operators `>`, `>=`, `<`, and `<=`. + +## Shallow equality +The shallow equality operator `===` compares two values and either compiles to `===` or a `bool` if the equality is known to the compiler. +It behaves the same as the strict equality operator `===` in JavaScript. + +Using `===` will never add a runtime cost. + + + +```res +let t1 = 1 === 1 // true +let t2 = "foo" === "foo" // true +let t3 = { "foo": "bar" } === { "foo": "bar"} // false + +let doStringsMatch = (s1: string, s2: string) => s1 === s2 +``` +```js +var t1 = true; +var t2 = "foo" === "foo"; +var t3 = ({ foo: "bar" }) === ({ foo: "bar" }); + +function doStringsMatch(s1, s2) { + return s1 === s2; +} +``` + + + +## Deep equality +ReScript has the deep equality operator `==` to check deep equality of two items, which is very different from the loose equality operator like `==` in JavaScript. + +When using `==` in ReScript it will never compile to `==` in JavaScript, +it will either compile to `===`, a runtime call to an internal function that deeply compares the equality, or a `bool` if the equality is known to the compiler. + + + +```res +let t1 = 1 == 1 // true +let t2 = "foo" == "foo" // true +let t3 = { "foo": "bar" } == { "foo": "bar"} // true + +let doStringsMatch = (s1: string, s2: string) => s1 == s2 +``` +```js +import * as Caml_obj from "./stdlib/caml_obj.js"; + +var t1 = true; +var t2 = true; +var t3 = Caml_obj.equal({ foo: "bar" }, { foo: "bar" }); + +function doStringsMatch(s1, s2) { + return s1 === s2; +} +``` + + +`==` will compile to `===` (or a `bool` if the compiler can determine equality) when: + +- Comparing `string`, `char`, `int`, `float`, `bool`, or `unit` +- Comparing variants or polymorphic variants that do not have constructor values + +`==` will compile to a runtime check for deep equality when: +- Comparing `array`, `tuple`, `list`, `object`, `record`, or regular expression `Re.t` +- Comparing variants or polymorphic variants that have constructor values + +> When using `==` pay close attention to the JavaScript output if you're not sure what `==` will compile to. + +## Comparison +ReScript has operators for comparing values that compile to the the same operator in JS, a runtime check using an internal function, or a `bool` if the equality is known to the compiler, + +| operator | comparison | +| --- | ----------- | +| `>` | greater than | +| `>=` | greater than or equal | +| `<` | less than | +| `<=` | less than or equal | + +Comparison can be done on any type. + +An operator will compile to the same operator (or a `bool` if the compiler can determine equality) when: +- Comparing `int`, `float`, `string`, `char`, `bool` + +An operator will compile to a runtime check for deep equality when: +- Comparing `array`, `tuple`, `list`, `object`, `record`, or regular expression (`Re.t`) +- Comparing variants or polymorphic variants + + + +```res +let compareInt = (a: int, b: int) => a > b +let t1 = 1 > 10 +let compareArray = (a: array, b: array) => a > b +let compareOptions = (a: option, b: option) => a < b +``` +```js +import * as Caml_obj from "./stdlib/caml_obj.js"; + +function compareInt(a, b) { + return a > b; +} + +var t1 = false; + +var compareArray = Caml_obj.greaterthan; + +var compareOptions = Caml_obj.lessthan; +``` + + +## Performance of runtime equality checks +The runtime equality check ReScript uses is quite fast and should be adequate for almost all use cases. +It's 2x-4x times faster than alternative deep compare functions such as [`_.isEqual`](https://lodash.com/docs/4.17.15#isEqual) or [`deep-equal`](https://www.npmjs.com/package/deep-equal). + +Instead of using `==` you could manually use a slightly faster alternative as [fast-deep-compare](https://www.npmjs.com/package/fast-deep-equal). + +[This repo](https://github.com/jderochervlk/rescript-perf) has benchmarks comparing results of different libraries compared to ReScrip's built in equality function. \ No newline at end of file From 4759eeaf3b5244a0ec38cc639bfcfb3b5d41791a Mon Sep 17 00:00:00 2001 From: Josh Vlk Date: Tue, 23 Jan 2024 14:32:11 -0500 Subject: [PATCH 2/3] fix typo --- pages/docs/manual/latest/equality-comparison.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pages/docs/manual/latest/equality-comparison.mdx b/pages/docs/manual/latest/equality-comparison.mdx index 62c4da3b3..07a270a6a 100644 --- a/pages/docs/manual/latest/equality-comparison.mdx +++ b/pages/docs/manual/latest/equality-comparison.mdx @@ -1,6 +1,6 @@ --- title: "Equality and Comparison" -description: "compare" +description: "Handling equality and comparison checks" canonical: "/docs/manual/latest/equality-comparison" --- @@ -122,4 +122,4 @@ It's 2x-4x times faster than alternative deep compare functions such as [`_.isEq Instead of using `==` you could manually use a slightly faster alternative as [fast-deep-compare](https://www.npmjs.com/package/fast-deep-equal). -[This repo](https://github.com/jderochervlk/rescript-perf) has benchmarks comparing results of different libraries compared to ReScrip's built in equality function. \ No newline at end of file +[This repo](https://github.com/jderochervlk/rescript-perf) has benchmarks comparing results of different libraries compared to ReScript's built in equality function. \ No newline at end of file From 842c29cb8a7399bc2fe47d95ceeac55c02f86a91 Mon Sep 17 00:00:00 2001 From: Josh Vlk Date: Sat, 27 Jan 2024 09:59:49 -0500 Subject: [PATCH 3/3] adjust working about performance --- pages/docs/manual/latest/equality-comparison.mdx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pages/docs/manual/latest/equality-comparison.mdx b/pages/docs/manual/latest/equality-comparison.mdx index 07a270a6a..7f7031d80 100644 --- a/pages/docs/manual/latest/equality-comparison.mdx +++ b/pages/docs/manual/latest/equality-comparison.mdx @@ -118,8 +118,8 @@ var compareOptions = Caml_obj.lessthan; ## Performance of runtime equality checks The runtime equality check ReScript uses is quite fast and should be adequate for almost all use cases. -It's 2x-4x times faster than alternative deep compare functions such as [`_.isEqual`](https://lodash.com/docs/4.17.15#isEqual) or [`deep-equal`](https://www.npmjs.com/package/deep-equal). +For small objects it can be 2x times faster than alternative deep compare functions such as Lodash's [`_.isEqual`](https://lodash.com/docs/4.17.15#isEqual). -Instead of using `==` you could manually use a slightly faster alternative as [fast-deep-compare](https://www.npmjs.com/package/fast-deep-equal). +For larger objects instead of using `==` you could manually use a faster alternative such as [fast-deep-compare](https://www.npmjs.com/package/fast-deep-equal), or write a custom comparator function. [This repo](https://github.com/jderochervlk/rescript-perf) has benchmarks comparing results of different libraries compared to ReScript's built in equality function. \ No newline at end of file