From 00d730da3c164027f11bb439f455397774864f2f Mon Sep 17 00:00:00 2001 From: Dmitry Zakharov Date: Mon, 16 Jun 2025 19:22:50 +0400 Subject: [PATCH 1/5] Rename Stdlib functions from Exn to OrThrow --- runtime/Stdlib_List.res | 12 ++++++-- runtime/Stdlib_List.resi | 56 ++++++++++++++++++++++++++++++++++++ runtime/Stdlib_Null.res | 6 ++-- runtime/Stdlib_Null.resi | 26 ++++++++++++++++- runtime/Stdlib_Nullable.res | 6 ++-- runtime/Stdlib_Nullable.resi | 27 +++++++++++++++++ runtime/Stdlib_Option.res | 6 ++-- runtime/Stdlib_Option.resi | 24 ++++++++++++++++ 8 files changed, 153 insertions(+), 10 deletions(-) diff --git a/runtime/Stdlib_List.res b/runtime/Stdlib_List.res index c6269c30fd..3478ded2b5 100644 --- a/runtime/Stdlib_List.res +++ b/runtime/Stdlib_List.res @@ -106,24 +106,28 @@ let head = x => | list{x, ..._} => Some(x) } -let headExn = x => +let headOrThrow = x => switch x { | list{} => throw(Not_found) | list{x, ..._} => x } +let headExn = headOrThrow + let tail = x => switch x { | list{} => None | list{_, ...xs} => Some(xs) } -let tailExn = x => +let tailOrThrow = x => switch x { | list{} => throw(Not_found) | list{_, ...t} => t } +let tailExn = tailOrThrow + let add = (xs, x) => list{x, ...xs} /* Assume `n >=0` */ @@ -156,13 +160,15 @@ let get = (x, n) => nthAux(x, n) } -let getExn = (x, n) => +let getOrThrow = (x, n) => if n < 0 { throw(Not_found) } else { nthAuxAssert(x, n) } +let getExn = getOrThrow + let rec partitionAux = (p, cell, precX, precY) => switch cell { | list{} => () diff --git a/runtime/Stdlib_List.resi b/runtime/Stdlib_List.resi index b76e679319..aa838c43e8 100644 --- a/runtime/Stdlib_List.resi +++ b/runtime/Stdlib_List.resi @@ -90,8 +90,29 @@ switch List.headExn(list{}) { - Raises an Error if list is empty. */ +@deprecated("Use `headOrThrow` instead") let headExn: list<'a> => 'a +/** +`headOrThrow(list)` same as [`head`](#head). + +## Examples + +```rescript +List.headOrThrow(list{1, 2, 3})->assertEqual(1) + +switch List.headOrThrow(list{}) { +| exception Not_found => assert(true) +| _ => assert(false) +} +``` + +## Exceptions + +- Raises an Error if list is empty. +*/ +let headOrThrow: list<'a> => 'a + /** `tail(list)` returns `None` if `list` is empty, otherwise it returns `Some(tail)` where `tail` is everything except the first element of `list`. @@ -124,8 +145,25 @@ switch List.tailExn(list{}) { - Raises an Error if list is empty. */ +@deprecated("Use `tailOrThrow` instead") let tailExn: list<'a> => list<'a> +/** + `tailOrThrow(list)` same as [`tail`](#tail). + Raises an Error if list is empty. + + ## Examples + ```res + List.tailOrThrow(list{1, 2, 3})->assertEqual(list{2, 3}) + + switch List.tailOrThrow(list{}) { + | _ => Console.log("never happens") + | exception _ => Console.log("error") + } + ``` +*/ +let tailOrThrow: list<'a> => list<'a> + /** `add(list, value)` adds a `value` to the beginning of list `list`. @@ -177,8 +215,26 @@ switch abc->List.getExn(4) { - Raises an Error if `index` is larger than the length of list. */ +@deprecated("Use `getOrThrow` instead") let getExn: (list<'a>, int) => 'a +/** + `getOrThrow(list, index)` same as [`get`](#get). + Raises an Error if `index` is larger than the length of list. + + ## Examples + ```res + let abc = list{"A", "B", "C"} + abc->List.getOrThrow(1)->assertEqual("B") + + switch abc->List.getOrThrow(4) { + | _ => Console.log("never happens") + | exception _ => Console.log("error") + } + ``` +*/ +let getOrThrow: (list<'a>, int) => 'a + /** `make(length, value)` returns a list of length `length` with each element filled with `value`. Returns an empty list if `value` is negative. diff --git a/runtime/Stdlib_Null.res b/runtime/Stdlib_Null.res index 37aa6947fc..9ce0dc4467 100644 --- a/runtime/Stdlib_Null.res +++ b/runtime/Stdlib_Null.res @@ -29,12 +29,14 @@ let getOr = (value, default) => let getWithDefault = getOr -let getExn: t<'a> => 'a = value => +let getOrThrow: t<'a> => 'a = value => switch value->toOption { | Some(x) => x - | None => throw(Invalid_argument("Null.getExn: value is null")) + | None => throw(Invalid_argument("Null.getOrThrow: value is null")) } +let getExn = getOrThrow + external getUnsafe: t<'a> => 'a = "%identity" let forEach = (value, f) => diff --git a/runtime/Stdlib_Null.resi b/runtime/Stdlib_Null.resi index ebe95b03ac..e219ee709c 100644 --- a/runtime/Stdlib_Null.resi +++ b/runtime/Stdlib_Null.resi @@ -120,10 +120,34 @@ switch Null.getExn(%raw("null")) { ## Exceptions -- Raises `Invalid_argument` if `value` is `null`, +- Raises `Invalid_argument` if `value` is `null` */ +@deprecated("Use `getOrThrow` instead") let getExn: t<'a> => 'a +/** +`getOrThrow(value)` raises an exception if `null`, otherwise returns the value. + +```rescript +Null.getOrThrow(Null.make(3))->assertEqual(3) + +switch Null.getOrThrow(%raw("'ReScript'")) { +| exception Invalid_argument(_) => assert(false) +| value => assertEqual(value, "ReScript") +} + +switch Null.getOrThrow(%raw("null")) { +| exception Invalid_argument(_) => assert(true) +| _ => assert(false) +} +``` + +## Exceptions + +- Raises `Invalid_argument` if `value` is `null` +*/ +let getOrThrow: t<'a> => 'a + /** `getUnsafe(value)` returns `value`. diff --git a/runtime/Stdlib_Nullable.res b/runtime/Stdlib_Nullable.res index 25b854b93a..36eeac3b86 100644 --- a/runtime/Stdlib_Nullable.res +++ b/runtime/Stdlib_Nullable.res @@ -32,12 +32,14 @@ let getOr = (value, default) => let getWithDefault = getOr -let getExn: t<'a> => 'a = value => +let getOrThrow: t<'a> => 'a = value => switch value->toOption { | Some(x) => x - | None => throw(Invalid_argument("Nullable.getExn: value is null or undefined")) + | None => throw(Invalid_argument("Nullable.getOrThrow: value is null or undefined")) } +let getExn = getOrThrow + external getUnsafe: t<'a> => 'a = "%identity" let forEach = (value, f) => diff --git a/runtime/Stdlib_Nullable.resi b/runtime/Stdlib_Nullable.resi index 5e3dfbcae0..002f482e51 100644 --- a/runtime/Stdlib_Nullable.resi +++ b/runtime/Stdlib_Nullable.resi @@ -157,8 +157,35 @@ switch Nullable.getExn(%raw("undefined")) { - Raises `Invalid_argument` if `value` is `null` or `undefined` */ +@deprecated("Use `getOrThrow` instead") let getExn: t<'a> => 'a +/** +`getOrThrow(value)` raises an exception if `null` or `undefined`, otherwise returns the value. + +```rescript +switch Nullable.getOrThrow(%raw("'Hello'")) { +| exception Invalid_argument(_) => assert(false) +| value => assertEqual(value, "Hello") +} + +switch Nullable.getOrThrow(%raw("null")) { +| exception Invalid_argument(_) => assert(true) +| _ => assert(false) +} + +switch Nullable.getOrThrow(%raw("undefined")) { +| exception Invalid_argument(_) => assert(true) +| _ => assert(false) +} +``` + +## Exceptions + +- Raises `Invalid_argument` if `value` is `null` or `undefined` +*/ +let getOrThrow: t<'a> => 'a + /** `getUnsafe(value)` returns `value`. diff --git a/runtime/Stdlib_Option.res b/runtime/Stdlib_Option.res index 299a8d941d..f6a3800aba 100644 --- a/runtime/Stdlib_Option.res +++ b/runtime/Stdlib_Option.res @@ -35,18 +35,20 @@ let forEach = (opt, f) => | None => () } -let getExn = (x, ~message=?) => +let getOrThrow = (x, ~message=?) => switch x { | Some(x) => x | None => Stdlib_Error.panic( switch message { - | None => "Option.getExn called for None value" + | None => "Option.getOrThrow called for None value" | Some(message) => message }, ) } +let getExn = getOrThrow + external getUnsafe: option<'a> => 'a = "%identity" let mapOr = (opt, default, f) => diff --git a/runtime/Stdlib_Option.resi b/runtime/Stdlib_Option.resi index 2beae9d621..62ca90b2b5 100644 --- a/runtime/Stdlib_Option.resi +++ b/runtime/Stdlib_Option.resi @@ -91,8 +91,32 @@ switch Option.getExn(None, ~message="was None!") { - Raises an error if `opt` is `None` */ +@deprecated("Use `getOrThrow` instead") let getExn: (option<'a>, ~message: string=?) => 'a +/** +`getOrThrow(opt, ~message=?)` returns `value` if `opt` is `Some(value)`, otherwise raises an exception with the message provided, or a generic message if no message was provided. + +```rescript +Option.getOrThrow(Some(3))->assertEqual(3) + +switch Option.getOrThrow(None) { +| exception _ => assert(true) +| _ => assert(false) +} + +switch Option.getOrThrow(None, ~message="was None!") { +| exception _ => assert(true) // Raises an Error with the message "was None!" +| _ => assert(false) +} +``` + +## Exceptions + +- Raises an error if `opt` is `None` +*/ +let getOrThrow: (option<'a>, ~message: string=?) => 'a + /** `getUnsafe(opt)` returns `value` if `opt` is `Some(value)`, otherwise `undefined`. From 43e5c68af34a13b21e7a44cc56a7f94d822ffc5a Mon Sep 17 00:00:00 2001 From: Dmitry Zakharov Date: Mon, 16 Jun 2025 19:33:21 +0400 Subject: [PATCH 2/5] Fix tests and add changelog --- CHANGELOG.md | 8 +++ lib/es6/Stdlib_List.js | 15 ++++-- lib/es6/Stdlib_Null.js | 7 ++- lib/es6/Stdlib_Nullable.js | 7 ++- lib/es6/Stdlib_Option.js | 7 ++- lib/js/Stdlib_List.js | 15 ++++-- lib/js/Stdlib_Null.js | 7 ++- lib/js/Stdlib_Nullable.js | 7 ++- lib/js/Stdlib_Option.js | 7 ++- runtime/Stdlib_List.resi | 53 +++++++++++-------- .../tests/src/expected/Completion.res.txt | 12 ----- tests/docstring_tests/DocTest.res | 8 +-- tests/docstring_tests/DocTest.res.js | 4 +- 13 files changed, 101 insertions(+), 56 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a16a527114..9d3bb93975 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -20,7 +20,15 @@ - `JSON.parseExn` → `JSON.parseOrThrow` - Changed `BigInt.fromFloat` to return an option rather than throwing an error. - Added `BigInt.fromFloatOrThrow` + - `Option.getExn` → `Option.getOrThrow` + - `Null.getExn` → `Null.getOrThrow` + - `Nullable.getExn` → `Nullable.getOrThrow` + - `Result.getExn` → `Result.getOrThrow` + - `List.getExn` → `List.getOrThrow` + - `List.tailExn` → `List.tailOrThrow` + - `List.headExn` → `List.headOrThrow` - Old functions remain available but are marked as deprecated with guidance to use the new `OrThrow` variants. + - https://github.com/rescript-lang/rescript/pull/7518, https://github.com/rescript-lang/rescript/pull/7554 #### :rocket: New Feature diff --git a/lib/es6/Stdlib_List.js b/lib/es6/Stdlib_List.js index 0f2e7e7843..7870e1adc4 100644 --- a/lib/es6/Stdlib_List.js +++ b/lib/es6/Stdlib_List.js @@ -11,7 +11,7 @@ function head(x) { } -function headExn(x) { +function headOrThrow(x) { if (x !== 0) { return x.hd; } @@ -28,7 +28,7 @@ function tail(x) { } -function tailExn(x) { +function tailOrThrow(x) { if (x !== 0) { return x.tl; } @@ -67,7 +67,7 @@ function get(x, n) { } } -function getExn(x, n) { +function getOrThrow(x, n) { if (n < 0) { throw { RE_EXN_ID: "Not_found", @@ -1298,6 +1298,12 @@ function zip(l1, l2) { let size = length; +let headExn = headOrThrow; + +let tailExn = tailOrThrow; + +let getExn = getOrThrow; + let toShuffled = shuffle; export { @@ -1305,11 +1311,14 @@ export { size, head, headExn, + headOrThrow, tail, tailExn, + tailOrThrow, add, get, getExn, + getOrThrow, make, fromInitializer, shuffle, diff --git a/lib/es6/Stdlib_Null.js b/lib/es6/Stdlib_Null.js index a9227bd384..9a61308435 100644 --- a/lib/es6/Stdlib_Null.js +++ b/lib/es6/Stdlib_Null.js @@ -27,13 +27,13 @@ function getOr(value, $$default) { } } -function getExn(value) { +function getOrThrow(value) { if (value !== null) { return value; } throw { RE_EXN_ID: "Invalid_argument", - _1: "Null.getExn: value is null", + _1: "Null.getOrThrow: value is null", Error: new Error() }; } @@ -71,6 +71,8 @@ function flatMap(value, f) { let getWithDefault = getOr; +let getExn = getOrThrow; + let mapWithDefault = mapOr; export { @@ -80,6 +82,7 @@ export { getOr, getWithDefault, getExn, + getOrThrow, forEach, map, mapOr, diff --git a/lib/es6/Stdlib_Nullable.js b/lib/es6/Stdlib_Nullable.js index de9df692a1..6763f42b6f 100644 --- a/lib/es6/Stdlib_Nullable.js +++ b/lib/es6/Stdlib_Nullable.js @@ -26,13 +26,13 @@ function getOr(value, $$default) { } } -function getExn(value) { +function getOrThrow(value) { if (!(value == null)) { return value; } throw { RE_EXN_ID: "Invalid_argument", - _1: "Nullable.getExn: value is null or undefined", + _1: "Nullable.getOrThrow: value is null or undefined", Error: new Error() }; } @@ -70,6 +70,8 @@ function flatMap(value, f) { let getWithDefault = getOr; +let getExn = getOrThrow; + let mapWithDefault = mapOr; export { @@ -79,6 +81,7 @@ export { getOr, getWithDefault, getExn, + getOrThrow, forEach, map, mapOr, diff --git a/lib/es6/Stdlib_Option.js b/lib/es6/Stdlib_Option.js index 2bb1041776..24bbf4929c 100644 --- a/lib/es6/Stdlib_Option.js +++ b/lib/es6/Stdlib_Option.js @@ -17,11 +17,11 @@ function forEach(opt, f) { } -function getExn(x, message) { +function getOrThrow(x, message) { if (x !== undefined) { return Primitive_option.valFromOption(x); } else { - return Stdlib_Error.panic(message !== undefined ? message : "Option.getExn called for None value"); + return Stdlib_Error.panic(message !== undefined ? message : "Option.getOrThrow called for None value"); } } @@ -197,6 +197,8 @@ function all6(param) { } +let getExn = getOrThrow; + let mapWithDefault = mapOr; let getWithDefault = getOr; @@ -205,6 +207,7 @@ export { filter, forEach, getExn, + getOrThrow, mapOr, mapWithDefault, map, diff --git a/lib/js/Stdlib_List.js b/lib/js/Stdlib_List.js index 47c32dd1d0..4dc975dffc 100644 --- a/lib/js/Stdlib_List.js +++ b/lib/js/Stdlib_List.js @@ -11,7 +11,7 @@ function head(x) { } -function headExn(x) { +function headOrThrow(x) { if (x !== 0) { return x.hd; } @@ -28,7 +28,7 @@ function tail(x) { } -function tailExn(x) { +function tailOrThrow(x) { if (x !== 0) { return x.tl; } @@ -67,7 +67,7 @@ function get(x, n) { } } -function getExn(x, n) { +function getOrThrow(x, n) { if (n < 0) { throw { RE_EXN_ID: "Not_found", @@ -1298,17 +1298,26 @@ function zip(l1, l2) { let size = length; +let headExn = headOrThrow; + +let tailExn = tailOrThrow; + +let getExn = getOrThrow; + let toShuffled = shuffle; exports.length = length; exports.size = size; exports.head = head; exports.headExn = headExn; +exports.headOrThrow = headOrThrow; exports.tail = tail; exports.tailExn = tailExn; +exports.tailOrThrow = tailOrThrow; exports.add = add; exports.get = get; exports.getExn = getExn; +exports.getOrThrow = getOrThrow; exports.make = make; exports.fromInitializer = fromInitializer; exports.shuffle = shuffle; diff --git a/lib/js/Stdlib_Null.js b/lib/js/Stdlib_Null.js index 19f2353d5a..87a40b1b9f 100644 --- a/lib/js/Stdlib_Null.js +++ b/lib/js/Stdlib_Null.js @@ -27,13 +27,13 @@ function getOr(value, $$default) { } } -function getExn(value) { +function getOrThrow(value) { if (value !== null) { return value; } throw { RE_EXN_ID: "Invalid_argument", - _1: "Null.getExn: value is null", + _1: "Null.getOrThrow: value is null", Error: new Error() }; } @@ -71,6 +71,8 @@ function flatMap(value, f) { let getWithDefault = getOr; +let getExn = getOrThrow; + let mapWithDefault = mapOr; exports.equal = equal; @@ -79,6 +81,7 @@ exports.fromOption = fromOption; exports.getOr = getOr; exports.getWithDefault = getWithDefault; exports.getExn = getExn; +exports.getOrThrow = getOrThrow; exports.forEach = forEach; exports.map = map; exports.mapOr = mapOr; diff --git a/lib/js/Stdlib_Nullable.js b/lib/js/Stdlib_Nullable.js index bae5ec43c6..abd1601065 100644 --- a/lib/js/Stdlib_Nullable.js +++ b/lib/js/Stdlib_Nullable.js @@ -26,13 +26,13 @@ function getOr(value, $$default) { } } -function getExn(value) { +function getOrThrow(value) { if (!(value == null)) { return value; } throw { RE_EXN_ID: "Invalid_argument", - _1: "Nullable.getExn: value is null or undefined", + _1: "Nullable.getOrThrow: value is null or undefined", Error: new Error() }; } @@ -70,6 +70,8 @@ function flatMap(value, f) { let getWithDefault = getOr; +let getExn = getOrThrow; + let mapWithDefault = mapOr; exports.equal = equal; @@ -78,6 +80,7 @@ exports.fromOption = fromOption; exports.getOr = getOr; exports.getWithDefault = getWithDefault; exports.getExn = getExn; +exports.getOrThrow = getOrThrow; exports.forEach = forEach; exports.map = map; exports.mapOr = mapOr; diff --git a/lib/js/Stdlib_Option.js b/lib/js/Stdlib_Option.js index ae2a98a30c..6e5ed229c2 100644 --- a/lib/js/Stdlib_Option.js +++ b/lib/js/Stdlib_Option.js @@ -17,11 +17,11 @@ function forEach(opt, f) { } -function getExn(x, message) { +function getOrThrow(x, message) { if (x !== undefined) { return Primitive_option.valFromOption(x); } else { - return Stdlib_Error.panic(message !== undefined ? message : "Option.getExn called for None value"); + return Stdlib_Error.panic(message !== undefined ? message : "Option.getOrThrow called for None value"); } } @@ -197,6 +197,8 @@ function all6(param) { } +let getExn = getOrThrow; + let mapWithDefault = mapOr; let getWithDefault = getOr; @@ -204,6 +206,7 @@ let getWithDefault = getOr; exports.filter = filter; exports.forEach = forEach; exports.getExn = getExn; +exports.getOrThrow = getOrThrow; exports.mapOr = mapOr; exports.mapWithDefault = mapWithDefault; exports.map = map; diff --git a/runtime/Stdlib_List.resi b/runtime/Stdlib_List.resi index aa838c43e8..e1385bbe51 100644 --- a/runtime/Stdlib_List.resi +++ b/runtime/Stdlib_List.resi @@ -149,18 +149,22 @@ switch List.tailExn(list{}) { let tailExn: list<'a> => list<'a> /** - `tailOrThrow(list)` same as [`tail`](#tail). - Raises an Error if list is empty. +`tailOrThrow(list)` same as [`tail`](#tail). - ## Examples - ```res - List.tailOrThrow(list{1, 2, 3})->assertEqual(list{2, 3}) +## Examples + +```rescript +List.tailOrThrow(list{1, 2, 3})->assertEqual(list{2, 3}) - switch List.tailOrThrow(list{}) { - | _ => Console.log("never happens") - | exception _ => Console.log("error") - } - ``` +switch List.tailOrThrow(list{}) { +| exception Not_found => assert(true) +| _ => assert(false) +} +``` + +## Exceptions + +- Raises an Error if list is empty. */ let tailOrThrow: list<'a> => list<'a> @@ -219,19 +223,26 @@ switch abc->List.getExn(4) { let getExn: (list<'a>, int) => 'a /** - `getOrThrow(list, index)` same as [`get`](#get). - Raises an Error if `index` is larger than the length of list. +`getOrThrow(list, index)` same as [`get`](#get). + +## Examples - ## Examples - ```res - let abc = list{"A", "B", "C"} - abc->List.getOrThrow(1)->assertEqual("B") +```rescript +let abc = list{"A", "B", "C"} - switch abc->List.getOrThrow(4) { - | _ => Console.log("never happens") - | exception _ => Console.log("error") - } - ``` +abc +->List.getOrThrow(1) +->assertEqual("B") + +switch abc->List.getOrThrow(4) { +| exception Not_found => assert(true) +| _ => assert(false) +} +``` + +## Exceptions + +- Raises an Error if `index` is larger than the length of list. */ let getOrThrow: (list<'a>, int) => 'a diff --git a/tests/analysis_tests/tests/src/expected/Completion.res.txt b/tests/analysis_tests/tests/src/expected/Completion.res.txt index ca1a714121..f56854cd77 100644 --- a/tests/analysis_tests/tests/src/expected/Completion.res.txt +++ b/tests/analysis_tests/tests/src/expected/Completion.res.txt @@ -328,12 +328,6 @@ Path Array. "tags": [], "detail": "(array<'a>, int) => 'a", "documentation": {"kind": "markdown", "value": "\n`getUnsafe(array, index)` returns the element at `index` of `array`.\n\nThis is _unsafe_, meaning it will return `undefined` value if `index` does not exist in `array`.\n\nUse `Array.getUnsafe` only when you are sure the `index` exists (i.e. when using for-loop).\n\n## Examples\n```rescript\nlet array = [1, 2, 3]\nfor index in 0 to array->Array.length - 1 {\n let value = array->Array.getUnsafe(index)\n Console.log(value)\n}\n```\n"} - }, { - "label": "entries", - "kind": 12, - "tags": [], - "detail": "array<'a> => Iterator.t<(int, 'a)>", - "documentation": {"kind": "markdown", "value": "\n`entries(array)` returns a new array iterator object that contains the key/value pairs for each index in the array.\n\nSee [Array.prototype.entries](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/entries) on MDN.\n\n## Examples\n\n```rescript\nlet array = [5, 6, 7]\nlet iterator : Iterator.t<(int, int)> = array->Array.entries\niterator->Iterator.next->assertEqual({done: false, value: Some((0, 5))})\niterator->Iterator.next->assertEqual({done: false, value: Some((1, 6))})\n```\n"} }, { "label": "unshiftMany", "kind": 12, @@ -382,12 +376,6 @@ Path Array. "tags": [], "detail": "'a => bool", "documentation": null - }, { - "label": "values", - "kind": 12, - "tags": [], - "detail": "array<'a> => Iterator.t<'a>", - "documentation": {"kind": "markdown", "value": "\n`values(array)` returns a new array iterator object that contains the values for each index in the array.\n\nSee [Array.prototype.values](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/values) on MDN.\n\n## Examples\n\n```rescript\nlet array = [5, 6, 7]\nlet iterator : Iterator.t = array->Array.values\niterator->Iterator.next->assertEqual({done: false, value: Some(5)})\niterator->Iterator.next->assertEqual({done: false, value: Some(6)})\n```\n "} }, { "label": "indexOfOpt", "kind": 12, diff --git a/tests/docstring_tests/DocTest.res b/tests/docstring_tests/DocTest.res index b38b8ecb04..54ea5c88fc 100644 --- a/tests/docstring_tests/DocTest.res +++ b/tests/docstring_tests/DocTest.res @@ -15,9 +15,9 @@ let nodeVersion = ->String.replace("v", "") ->String.split(".") ->Array.get(0) - ->Option.getExn(~message="Failed to find major version of Node") + ->Option.getOrThrow(~message="Failed to find major version of Node") ->Int.fromString - ->Option.getExn(~message="Failed to convert node version to Int") + ->Option.getOrThrow(~message="Failed to convert node version to Int") let ignoreRuntimeTests = [ ( @@ -186,7 +186,9 @@ let getCodeBlocks = example => { left, lines ->Array.get(idx + 1) - ->Option.getExn(~message="Expected to have an expected expression on the next line"), + ->Option.getOrThrow( + ~message="Expected to have an expected expression on the next line", + ), )) | _ => parts } diff --git a/tests/docstring_tests/DocTest.res.js b/tests/docstring_tests/DocTest.res.js index 68be8d88fb..d18c54da14 100644 --- a/tests/docstring_tests/DocTest.res.js +++ b/tests/docstring_tests/DocTest.res.js @@ -21,7 +21,7 @@ import * as Promises from "node:fs/promises"; import * as Primitive_exceptions from "rescript/lib/es6/Primitive_exceptions.js"; import * as RescriptTools_Docgen from "rescript/lib/es6/RescriptTools_Docgen.js"; -let nodeVersion = Stdlib_Option.getExn(Stdlib_Int.fromString(Stdlib_Option.getExn(process.version.replace("v", "").split(".")[0], "Failed to find major version of Node"), undefined), "Failed to convert node version to Int"); +let nodeVersion = Stdlib_Option.getOrThrow(Stdlib_Int.fromString(Stdlib_Option.getOrThrow(process.version.replace("v", "").split(".")[0], "Failed to find major version of Node"), undefined), "Failed to convert node version to Int"); let ignoreRuntimeTests = [ [ @@ -224,7 +224,7 @@ function getCodeBlocks(example) { let parts = searchFrom(line, 0); let parts$1 = parts !== undefined && parts[1].trim().length === 0 ? [ parts[0], - Stdlib_Option.getExn(lines[idx + 1 | 0], "Expected to have an expected expression on the next line") + Stdlib_Option.getOrThrow(lines[idx + 1 | 0], "Expected to have an expected expression on the next line") ] : parts; if (parts$1 === undefined) { return line; From cc569a3df91d7b137c1e3eae1e5af17dd3527f81 Mon Sep 17 00:00:00 2001 From: Christoph Knittel Date: Tue, 17 Jun 2025 09:14:29 +0200 Subject: [PATCH 3/5] Undo change to Completion.res.txt --- .../tests/src/expected/Completion.res.txt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/analysis_tests/tests/src/expected/Completion.res.txt b/tests/analysis_tests/tests/src/expected/Completion.res.txt index f56854cd77..ca1a714121 100644 --- a/tests/analysis_tests/tests/src/expected/Completion.res.txt +++ b/tests/analysis_tests/tests/src/expected/Completion.res.txt @@ -328,6 +328,12 @@ Path Array. "tags": [], "detail": "(array<'a>, int) => 'a", "documentation": {"kind": "markdown", "value": "\n`getUnsafe(array, index)` returns the element at `index` of `array`.\n\nThis is _unsafe_, meaning it will return `undefined` value if `index` does not exist in `array`.\n\nUse `Array.getUnsafe` only when you are sure the `index` exists (i.e. when using for-loop).\n\n## Examples\n```rescript\nlet array = [1, 2, 3]\nfor index in 0 to array->Array.length - 1 {\n let value = array->Array.getUnsafe(index)\n Console.log(value)\n}\n```\n"} + }, { + "label": "entries", + "kind": 12, + "tags": [], + "detail": "array<'a> => Iterator.t<(int, 'a)>", + "documentation": {"kind": "markdown", "value": "\n`entries(array)` returns a new array iterator object that contains the key/value pairs for each index in the array.\n\nSee [Array.prototype.entries](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/entries) on MDN.\n\n## Examples\n\n```rescript\nlet array = [5, 6, 7]\nlet iterator : Iterator.t<(int, int)> = array->Array.entries\niterator->Iterator.next->assertEqual({done: false, value: Some((0, 5))})\niterator->Iterator.next->assertEqual({done: false, value: Some((1, 6))})\n```\n"} }, { "label": "unshiftMany", "kind": 12, @@ -376,6 +382,12 @@ Path Array. "tags": [], "detail": "'a => bool", "documentation": null + }, { + "label": "values", + "kind": 12, + "tags": [], + "detail": "array<'a> => Iterator.t<'a>", + "documentation": {"kind": "markdown", "value": "\n`values(array)` returns a new array iterator object that contains the values for each index in the array.\n\nSee [Array.prototype.values](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/values) on MDN.\n\n## Examples\n\n```rescript\nlet array = [5, 6, 7]\nlet iterator : Iterator.t = array->Array.values\niterator->Iterator.next->assertEqual({done: false, value: Some(5)})\niterator->Iterator.next->assertEqual({done: false, value: Some(6)})\n```\n "} }, { "label": "indexOfOpt", "kind": 12, From 0153b9895fd6db7ee7f9c3f8965f28623d43d279 Mon Sep 17 00:00:00 2001 From: Dmitry Zakharov Date: Tue, 17 Jun 2025 11:42:53 +0400 Subject: [PATCH 4/5] Rename Result.getExn --- lib/es6/Stdlib_Result.js | 5 ++++- lib/js/Stdlib_Result.js | 5 ++++- runtime/Stdlib_Result.res | 4 +++- runtime/Stdlib_Result.resi | 15 +++++++++++++++ 4 files changed, 26 insertions(+), 3 deletions(-) diff --git a/lib/es6/Stdlib_Result.js b/lib/es6/Stdlib_Result.js index 65aebf9e8e..f896fc897d 100644 --- a/lib/es6/Stdlib_Result.js +++ b/lib/es6/Stdlib_Result.js @@ -1,7 +1,7 @@ -function getExn(x) { +function getOrThrow(x) { if (x.TAG === "Ok") { return x._0; } @@ -342,12 +342,15 @@ function all6(param) { } } +let getExn = getOrThrow; + let mapWithDefault = mapOr; let getWithDefault = getOr; export { getExn, + getOrThrow, mapOr, mapWithDefault, map, diff --git a/lib/js/Stdlib_Result.js b/lib/js/Stdlib_Result.js index 24b8c0cb29..dcd2561cd5 100644 --- a/lib/js/Stdlib_Result.js +++ b/lib/js/Stdlib_Result.js @@ -1,7 +1,7 @@ 'use strict'; -function getExn(x) { +function getOrThrow(x) { if (x.TAG === "Ok") { return x._0; } @@ -342,11 +342,14 @@ function all6(param) { } } +let getExn = getOrThrow; + let mapWithDefault = mapOr; let getWithDefault = getOr; exports.getExn = getExn; +exports.getOrThrow = getOrThrow; exports.mapOr = mapOr; exports.mapWithDefault = mapWithDefault; exports.map = map; diff --git a/runtime/Stdlib_Result.res b/runtime/Stdlib_Result.res index b2b7f10219..8db2c6b985 100644 --- a/runtime/Stdlib_Result.res +++ b/runtime/Stdlib_Result.res @@ -23,12 +23,14 @@ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ type t<'res, 'err> = result<'res, 'err> = Ok('res) | Error('err) -let getExn = x => +let getOrThrow = x => switch x { | Ok(x) => x | Error(_) => throw(Not_found) } +let getExn = getOrThrow + let mapOr = (opt, default, f) => switch opt { | Ok(x) => f(x) diff --git a/runtime/Stdlib_Result.resi b/runtime/Stdlib_Result.resi index 6b98634de7..6a6a0c2ecc 100644 --- a/runtime/Stdlib_Result.resi +++ b/runtime/Stdlib_Result.resi @@ -59,8 +59,23 @@ type t<'res, 'err> = result<'res, 'err> = Ok('res) | Error('err) } ``` */ +@deprecated("Use 'getOrThrow' instead") let getExn: result<'a, 'b> => 'a +/** + `getOrThrow(res)`: when `res` is `Ok(n)`, returns `n` when `res` is `Error(m)`, raise an exception + + ```res example + Result.getOrThrow(Result.Ok(42)) == 42 + + switch Result.getOrThrow(Error("Invalid data")) { + | exception Not_found => assert(true) + | _ => assert(false) + } + ``` +*/ +let getOrThrow: result<'a, 'b> => 'a + /** `mapOr(res, default, f)`: When res is `Ok(n)`, returns `f(n)`, otherwise `default`. From 522a704cf5d850b5afa8658354011518506b5088 Mon Sep 17 00:00:00 2001 From: Dmitry Zakharov Date: Tue, 17 Jun 2025 11:50:11 +0400 Subject: [PATCH 5/5] Fix tests --- .../analysis_tests/tests/src/expected/Completion.res.txt | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tests/analysis_tests/tests/src/expected/Completion.res.txt b/tests/analysis_tests/tests/src/expected/Completion.res.txt index ca1a714121..65c64d5b94 100644 --- a/tests/analysis_tests/tests/src/expected/Completion.res.txt +++ b/tests/analysis_tests/tests/src/expected/Completion.res.txt @@ -2586,9 +2586,15 @@ Path g [{ "label": "Result.getExn", "kind": 12, + "tags": [1], + "detail": "result<'a, 'b> => 'a", + "documentation": {"kind": "markdown", "value": "Deprecated: Use 'getOrThrow' instead\n\n\n `getExn(res)`: when `res` is `Ok(n)`, returns `n` when `res` is `Error(m)`, raise an exception\n\n ```res example\n Result.getExn(Result.Ok(42)) == 42\n\n switch Result.getExn(Error(\"Invalid data\")) {\n | exception Not_found => assert(true)\n | _ => assert(false)\n }\n ```\n"} + }, { + "label": "Result.getOrThrow", + "kind": 12, "tags": [], "detail": "result<'a, 'b> => 'a", - "documentation": {"kind": "markdown", "value": "\n `getExn(res)`: when `res` is `Ok(n)`, returns `n` when `res` is `Error(m)`, raise an exception\n\n ```res example\n Result.getExn(Result.Ok(42)) == 42\n\n switch Result.getExn(Error(\"Invalid data\")) {\n | exception Not_found => assert(true)\n | _ => assert(false)\n }\n ```\n"} + "documentation": {"kind": "markdown", "value": "\n `getOrThrow(res)`: when `res` is `Ok(n)`, returns `n` when `res` is `Error(m)`, raise an exception\n\n ```res example\n Result.getOrThrow(Result.Ok(42)) == 42\n\n switch Result.getOrThrow(Error(\"Invalid data\")) {\n | exception Not_found => assert(true)\n | _ => assert(false)\n }\n ```\n"} }, { "label": "Result.getOr", "kind": 12,