From dbe8c1605a51d78e961166b13398175fadbf3305 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Sat, 21 Jan 2023 21:10:08 -0700 Subject: [PATCH 1/9] feat(compiler)!: Remove Exclusive/Inclusive Ranges, provide as record via compiler --- compiler/src/typed/builtin_types.re | 36 +++++++++++- compiler/test/stdlib/immutablearray.test.gr | 13 ++--- compiler/test/stdlib/range.test.gr | 46 +-------------- stdlib/range.gr | 64 ++++++--------------- 4 files changed, 58 insertions(+), 101 deletions(-) diff --git a/compiler/src/typed/builtin_types.re b/compiler/src/typed/builtin_types.re index 3a2a01af0c..b7317796e5 100644 --- a/compiler/src/typed/builtin_types.re +++ b/compiler/src/typed/builtin_types.re @@ -36,7 +36,10 @@ let ident_number = ident_create("Number") and ident_exception = ident_create("Exception") and ident_option = ident_create("Option") and ident_result = ident_create("Result") -and ident_list = ident_create("List") +and ident_list = ident_create("List"); +let ident_range = ident_create("Range") +and ident_range_start = ident_create("range_start") +and ident_range_end = ident_create("range_end") and ident_int32 = ident_create("Int32") and ident_int64 = ident_create("Int64") and ident_uint32 = ident_create("Uint32") @@ -67,6 +70,7 @@ and path_exception = PIdent(ident_exception) and path_option = PIdent(ident_option) and path_result = PIdent(ident_result) and path_list = PIdent(ident_list) +and path_range = PIdent(ident_range) and path_int32 = PIdent(ident_int32) and path_int64 = PIdent(ident_int64) and path_uint32 = PIdent(ident_uint32) @@ -95,6 +99,8 @@ and type_option = var => and type_result = (ok, err) => newgenty(TTyConstr(path_result, [ok, err], ref(TMemNil))) and type_list = var => newgenty(TTyConstr(path_list, [var], ref(TMemNil))) +and type_range = var => + newgenty(TTyRecord([("range_start", var), ("range_end", var)])) and type_int32 = newgenty(TTyConstr(path_int32, [], ref(TMemNil))) and type_int64 = newgenty(TTyConstr(path_int64, [], ref(TMemNil))) and type_uint32 = newgenty(TTyConstr(path_uint32, [], ref(TMemNil))) @@ -150,7 +156,9 @@ and ident_none_cstr = ident_create("None") and ident_ok_cstr = ident_create("Ok") and ident_err_cstr = ident_create("Err") and ident_cons_cstr = ident_create("[...]") -and ident_empty_cstr = ident_create("[]"); +and ident_empty_cstr = ident_create("[]") +and ident_inclusive_cstr = ident_create("Inclusive") +and ident_exclusive_cstr = ident_create("Exclusive"); let decl_exception = {...decl_abstr(path_exception), type_kind: TDataOpen}; let decl_bool = { @@ -201,6 +209,29 @@ and decl_list = { ]), }; } +and decl_range = { + let tvar = newgenvar(); + { + ...decl_abstr(path_range), + type_params: [tvar], + type_arity: 1, + type_kind: + TDataRecord([ + { + rf_name: ident_range_start, + rf_type: tvar, + rf_mutable: false, + rf_loc: Location.dummy_loc, + }, + { + rf_name: ident_range_end, + rf_type: tvar, + rf_mutable: false, + rf_loc: Location.dummy_loc, + }, + ]), + }; +} and decl_box = { let tvar = newgenvar(); {...decl_abstr(path_box), type_params: [tvar], type_arity: 1}; @@ -237,6 +268,7 @@ let initial_env = (add_type, add_extension, empty_env) => |> add_type(ident_option, decl_option) |> add_type(ident_result, decl_result) |> add_type(ident_list, decl_list) + |> add_type(ident_range, decl_range) |> add_type(ident_int32, decl_abstr(path_int32)) |> add_type(ident_int64, decl_abstr(path_int64)) |> add_type(ident_uint32, decl_abstr(path_uint32)) diff --git a/compiler/test/stdlib/immutablearray.test.gr b/compiler/test/stdlib/immutablearray.test.gr index 535b0e968a..3c5dcb7163 100644 --- a/compiler/test/stdlib/immutablearray.test.gr +++ b/compiler/test/stdlib/immutablearray.test.gr @@ -9,23 +9,20 @@ let fromList = ImmutableArray.fromList let arr = fromList([1, 2, 3]) // for testing the case where the tail is empty -let noTail = Range.map(identity, Range.Exclusive(0, 32)) +let noTail = Range.map(identity, { range_start: 0, range_end: 32 }) let noTailArr = fromList(noTail) // for testing the case where the tree branches and has a tail of max length let branchingLongTailLen = 32 * 33 + 31 let branchingLongTail = Range.map( identity, - Range.Exclusive(0, branchingLongTailLen) + { range_start: 0, range_end: branchingLongTailLen } ) let bltArr = fromList(branchingLongTail) // for testing the case where the tree is about to branch let almostBranchingLen = 32 * 32 + 31 -let almostBranching = Range.map( - identity, - Range.Exclusive(0, almostBranchingLen) -) +let almostBranching = Range.map(identity, { range_start: 0, range_end: almostBranchingLen }) let abArr = fromList(almostBranching) assert ImmutableArray.empty == fromList([]) @@ -92,10 +89,10 @@ assert ImmutableArray.append(bltArr, fromList([val, val + 1, val + 2])) == fromList(List.append(branchingLongTail, [val, val + 1, val + 2])) assert ImmutableArray.append(fromList([-3, -2, -1]), bltArr) == fromList([-3, -2, -1, ...branchingLongTail]) -let vals = Range.map(x => x + 32, Range.Exclusive(0, 128)) +let vals = Range.map(x => x + 32, { range_start: 0, range_end: 128 }) assert ImmutableArray.append(noTailArr, fromList(vals)) == fromList(List.append(noTail, vals)) -let vals = Range.map(x => x + 32, Range.Exclusive(0, 128 + 31)) +let vals = Range.map(x => x + 32, { range_start: 0, range_end: 128 + 31 }) assert ImmutableArray.append(noTailArr, fromList(vals)) == fromList(List.append(noTail, vals)) assert ImmutableArray.append(noTailArr, noTailArr) == diff --git a/compiler/test/stdlib/range.test.gr b/compiler/test/stdlib/range.test.gr index 2775e1480d..20250c0331 100644 --- a/compiler/test/stdlib/range.test.gr +++ b/compiler/test/stdlib/range.test.gr @@ -2,29 +2,11 @@ module RangeTest include "range" -let inclusiveAscendingRange = Range.Inclusive(1, 5) -let inclusiveDescendingRange = Range.Inclusive(5, 1) -let inclusiveSameRange = Range.Inclusive(1, 1) -let exclusiveAscendingRange = Range.Exclusive(1, 5) -let exclusiveDescendingRange = Range.Exclusive(5, 1) -let exclusiveSameRange = Range.Exclusive(1, 1) +let exclusiveAscendingRange = { range_start: 1, range_end: 5 } +let exclusiveDescendingRange = { range_start: 5, range_end: 1 } +let exclusiveSameRange = { range_start: 1, range_end: 1 } // Range.inRange -assert Range.inRange(1, inclusiveAscendingRange) -assert Range.inRange(3, inclusiveAscendingRange) -assert Range.inRange(5, inclusiveAscendingRange) -assert !Range.inRange(10, inclusiveAscendingRange) -assert !Range.inRange(-1, inclusiveAscendingRange) - -assert Range.inRange(1, inclusiveDescendingRange) -assert Range.inRange(3, inclusiveDescendingRange) -assert Range.inRange(5, inclusiveDescendingRange) -assert !Range.inRange(10, inclusiveDescendingRange) -assert !Range.inRange(-1, inclusiveDescendingRange) - -assert Range.inRange(1, inclusiveSameRange) -assert !Range.inRange(3, inclusiveSameRange) - assert Range.inRange(1, exclusiveAscendingRange) assert Range.inRange(3, exclusiveAscendingRange) assert !Range.inRange(5, exclusiveAscendingRange) @@ -44,24 +26,6 @@ assert !Range.inRange(3, exclusiveSameRange) // Note: the lists in these tests are reverse the iteration // order because we use `...results` to append the lists -let mut results = [] -Range.forEach(idx => { - results = [idx, ...results] -}, inclusiveAscendingRange) -assert results == [5, 4, 3, 2, 1] - -let mut results = [] -Range.forEach(idx => { - results = [idx, ...results] -}, inclusiveDescendingRange) -assert results == [1, 2, 3, 4, 5] - -let mut results = [] -Range.forEach(idx => { - results = [idx, ...results] -}, inclusiveSameRange) -assert results == [1] - let mut results = [] Range.forEach(idx => { results = [idx, ...results] @@ -78,10 +42,6 @@ Range.forEach(idx => { fail "Shouldn't be called" }, exclusiveSameRange) -assert Range.map(toString, inclusiveAscendingRange) == ["1", "2", "3", "4", "5"] -assert Range.map(toString, inclusiveDescendingRange) == - ["5", "4", "3", "2", "1"] -assert Range.map(toString, inclusiveSameRange) == ["1"] assert Range.map(toString, exclusiveAscendingRange) == ["1", "2", "3", "4"] assert Range.map(toString, exclusiveDescendingRange) == ["5", "4", "3", "2"] assert Range.map(toString, exclusiveSameRange) == [] diff --git a/stdlib/range.gr b/stdlib/range.gr index 0da489cdc9..b49a41c9b5 100644 --- a/stdlib/range.gr +++ b/stdlib/range.gr @@ -8,14 +8,6 @@ module Range -/** - * Ranges can be inclusive or exclusive. When `Inclusive`, the end value will be included in operations. When `Exclusive`, the end value will be excluded from operations. - */ -provide enum Range { - Inclusive(Number, Number), - Exclusive(Number, Number), -} - /** * Checks if the given number is within the range. * @@ -23,17 +15,21 @@ provide enum Range { * @param range: The range to check within * @returns Whether or not the value is within range * - * @example Range.inRange(1, Range.Inclusive(0, 2)) == true - * @example Range.inRange(10, Range.Inclusive(0, 2)) == false + * @example Range.inRange(1, Inclusive(0, 2)) == true + * @example Range.inRange(10, Inclusive(0, 2)) == false * * @since v0.3.0 */ provide let inRange = (value, range) => { match (range) { - Inclusive(lower, upper) when value >= lower && value <= upper => true, - Inclusive(upper, lower) when value >= lower && value <= upper => true, - Exclusive(lower, upper) when value >= lower && value < upper => true, - Exclusive(upper, lower) when value >= lower && value < upper => true, + { range_start: lower, range_end: upper } when ( + value >= lower && value < upper + ) => + true, + { range_start: upper, range_end: lower } when ( + value >= lower && value < upper + ) => + true, _ => false, } } @@ -44,34 +40,20 @@ provide let inRange = (value, range) => { * @param fn: The function to be executed on each number in the range * @param range: The range to iterate * - * @example Range.forEach(val => print(val), Range.Exclusive(0, 2)) + * @example Range.forEach(val => print(val), Exclusive(0, 2)) * * @since v0.3.0 */ provide let forEach = (fn: Number -> Void, range) => { match (range) { - Inclusive(lower, upper) when lower <= upper => { - let mut idx = lower - while (idx <= upper) { - fn(idx) - idx += 1 - } - }, - Inclusive(upper, lower) => { - let mut idx = upper - while (idx >= lower) { - fn(idx) - idx -= 1 - } - }, - Exclusive(lower, upper) when lower <= upper => { + { range_start: lower, range_end: upper } when lower <= upper => { let mut idx = lower while (idx < upper) { fn(idx) idx += 1 } }, - Exclusive(upper, lower) => { + { range_start: upper, range_end: lower } => { let mut idx = upper while (idx > lower) { fn(idx) @@ -88,35 +70,21 @@ provide let forEach = (fn: Number -> Void, range) => { * @param range: The range to iterate * @returns A list containing all values returned from the `fn` * - * @example Range.map(val => val * 2, Range.Inclusive(0, 2)) == [0, 2, 4] + * @example Range.map(val => val * 2, Inclusive(0, 2)) == [0, 2, 4] * * @since v0.3.2 */ provide let map = (fn, range) => { let mut result = [] match (range) { - Inclusive(lower, upper) when lower <= upper => { - let mut idx = upper - while (idx >= lower) { - result = [fn(idx), ...result] - idx -= 1 - } - }, - Inclusive(upper, lower) => { - let mut idx = lower - while (idx <= upper) { - result = [fn(idx), ...result] - idx += 1 - } - }, - Exclusive(lower, upper) when lower <= upper => { + { range_start: lower, range_end: upper } when lower <= upper => { let mut idx = upper - 1 while (idx >= lower) { result = [fn(idx), ...result] idx -= 1 } }, - Exclusive(upper, lower) => { + { range_start: upper, range_end: lower } => { let mut idx = lower + 1 while (idx <= upper) { result = [fn(idx), ...result] From d8b5268652e6bffa4534800f3edf2c9ac3a8bfb3 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Tue, 21 Feb 2023 20:38:56 -0700 Subject: [PATCH 2/9] update snapshots --- compiler/test/__snapshots__/arrays.0f9e7d37.0.snapshot | 6 +++--- compiler/test/__snapshots__/arrays.1deb7b51.0.snapshot | 6 +++--- compiler/test/__snapshots__/arrays.28fcc534.0.snapshot | 6 +++--- compiler/test/__snapshots__/arrays.4c8c9f91.0.snapshot | 6 +++--- compiler/test/__snapshots__/arrays.6eac4e1f.0.snapshot | 6 +++--- compiler/test/__snapshots__/arrays.74d79181.0.snapshot | 6 +++--- .../__snapshots__/basic_functionality.2bcc447b.0.snapshot | 4 ++-- 7 files changed, 20 insertions(+), 20 deletions(-) diff --git a/compiler/test/__snapshots__/arrays.0f9e7d37.0.snapshot b/compiler/test/__snapshots__/arrays.0f9e7d37.0.snapshot index aa1e7b9465..cf412d6468 100644 --- a/compiler/test/__snapshots__/arrays.0f9e7d37.0.snapshot +++ b/compiler/test/__snapshots__/arrays.0f9e7d37.0.snapshot @@ -149,7 +149,7 @@ arrays › array_access ) (i32.store offset=12 (local.get $0) - (i32.const 55) + (i32.const 61) ) (i32.store offset=16 (local.get $0) @@ -183,7 +183,7 @@ arrays › array_access ) (i32.store offset=12 (local.get $0) - (i32.const 57) + (i32.const 63) ) (i32.store offset=16 (local.get $0) @@ -249,7 +249,7 @@ arrays › array_access ) (i32.store offset=12 (local.get $0) - (i32.const 55) + (i32.const 61) ) (i32.store offset=16 (local.get $0) diff --git a/compiler/test/__snapshots__/arrays.1deb7b51.0.snapshot b/compiler/test/__snapshots__/arrays.1deb7b51.0.snapshot index b38c2e9646..d8906d8a92 100644 --- a/compiler/test/__snapshots__/arrays.1deb7b51.0.snapshot +++ b/compiler/test/__snapshots__/arrays.1deb7b51.0.snapshot @@ -149,7 +149,7 @@ arrays › array_access5 ) (i32.store offset=12 (local.get $0) - (i32.const 55) + (i32.const 61) ) (i32.store offset=16 (local.get $0) @@ -183,7 +183,7 @@ arrays › array_access5 ) (i32.store offset=12 (local.get $0) - (i32.const 57) + (i32.const 63) ) (i32.store offset=16 (local.get $0) @@ -249,7 +249,7 @@ arrays › array_access5 ) (i32.store offset=12 (local.get $0) - (i32.const 55) + (i32.const 61) ) (i32.store offset=16 (local.get $0) diff --git a/compiler/test/__snapshots__/arrays.28fcc534.0.snapshot b/compiler/test/__snapshots__/arrays.28fcc534.0.snapshot index 39c64ad3ea..4cb20b0630 100644 --- a/compiler/test/__snapshots__/arrays.28fcc534.0.snapshot +++ b/compiler/test/__snapshots__/arrays.28fcc534.0.snapshot @@ -149,7 +149,7 @@ arrays › array_access4 ) (i32.store offset=12 (local.get $0) - (i32.const 55) + (i32.const 61) ) (i32.store offset=16 (local.get $0) @@ -183,7 +183,7 @@ arrays › array_access4 ) (i32.store offset=12 (local.get $0) - (i32.const 57) + (i32.const 63) ) (i32.store offset=16 (local.get $0) @@ -249,7 +249,7 @@ arrays › array_access4 ) (i32.store offset=12 (local.get $0) - (i32.const 55) + (i32.const 61) ) (i32.store offset=16 (local.get $0) diff --git a/compiler/test/__snapshots__/arrays.4c8c9f91.0.snapshot b/compiler/test/__snapshots__/arrays.4c8c9f91.0.snapshot index 6acf427fcd..82cbb15dbe 100644 --- a/compiler/test/__snapshots__/arrays.4c8c9f91.0.snapshot +++ b/compiler/test/__snapshots__/arrays.4c8c9f91.0.snapshot @@ -149,7 +149,7 @@ arrays › array_access2 ) (i32.store offset=12 (local.get $0) - (i32.const 55) + (i32.const 61) ) (i32.store offset=16 (local.get $0) @@ -183,7 +183,7 @@ arrays › array_access2 ) (i32.store offset=12 (local.get $0) - (i32.const 57) + (i32.const 63) ) (i32.store offset=16 (local.get $0) @@ -249,7 +249,7 @@ arrays › array_access2 ) (i32.store offset=12 (local.get $0) - (i32.const 55) + (i32.const 61) ) (i32.store offset=16 (local.get $0) diff --git a/compiler/test/__snapshots__/arrays.6eac4e1f.0.snapshot b/compiler/test/__snapshots__/arrays.6eac4e1f.0.snapshot index 58b78834f5..ae207d668b 100644 --- a/compiler/test/__snapshots__/arrays.6eac4e1f.0.snapshot +++ b/compiler/test/__snapshots__/arrays.6eac4e1f.0.snapshot @@ -149,7 +149,7 @@ arrays › array_access3 ) (i32.store offset=12 (local.get $0) - (i32.const 55) + (i32.const 61) ) (i32.store offset=16 (local.get $0) @@ -183,7 +183,7 @@ arrays › array_access3 ) (i32.store offset=12 (local.get $0) - (i32.const 57) + (i32.const 63) ) (i32.store offset=16 (local.get $0) @@ -249,7 +249,7 @@ arrays › array_access3 ) (i32.store offset=12 (local.get $0) - (i32.const 55) + (i32.const 61) ) (i32.store offset=16 (local.get $0) diff --git a/compiler/test/__snapshots__/arrays.74d79181.0.snapshot b/compiler/test/__snapshots__/arrays.74d79181.0.snapshot index 6ed0893595..938435999e 100644 --- a/compiler/test/__snapshots__/arrays.74d79181.0.snapshot +++ b/compiler/test/__snapshots__/arrays.74d79181.0.snapshot @@ -149,7 +149,7 @@ arrays › array_access5 ) (i32.store offset=12 (local.get $0) - (i32.const 55) + (i32.const 61) ) (i32.store offset=16 (local.get $0) @@ -183,7 +183,7 @@ arrays › array_access5 ) (i32.store offset=12 (local.get $0) - (i32.const 57) + (i32.const 63) ) (i32.store offset=16 (local.get $0) @@ -249,7 +249,7 @@ arrays › array_access5 ) (i32.store offset=12 (local.get $0) - (i32.const 55) + (i32.const 61) ) (i32.store offset=16 (local.get $0) diff --git a/compiler/test/__snapshots__/basic_functionality.2bcc447b.0.snapshot b/compiler/test/__snapshots__/basic_functionality.2bcc447b.0.snapshot index 42fc6ea86c..17cadabdd8 100644 --- a/compiler/test/__snapshots__/basic_functionality.2bcc447b.0.snapshot +++ b/compiler/test/__snapshots__/basic_functionality.2bcc447b.0.snapshot @@ -180,11 +180,11 @@ basic functionality › assert2 ) (i32.store offset=8 (local.get $0) - (i32.const 45) + (i32.const 51) ) (i32.store offset=12 (local.get $0) - (i32.const 53) + (i32.const 59) ) (i32.store offset=16 (local.get $0) From e2b0528cc7d02fe3f903786a74552b7f91e813e7 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Tue, 21 Feb 2023 21:00:26 -0700 Subject: [PATCH 3/9] update docs --- stdlib/range.gr | 27 +++++++++++++++----- stdlib/range.md | 68 ++++++++++++++++++++++++++----------------------- 2 files changed, 56 insertions(+), 39 deletions(-) diff --git a/stdlib/range.gr b/stdlib/range.gr index b49a41c9b5..fd960b7faf 100644 --- a/stdlib/range.gr +++ b/stdlib/range.gr @@ -1,9 +1,14 @@ /** - * Utilities for working with ranges. A range represents an interval—a set of values with a beginning and an end. + * Utilities for working with ranges. + * + * A range represents an interval—a set of values with a beginning and an end. + * + * All functions in this module treat ranges as exclusive. * * @example include "range" * * @since v0.3.0 + * @history v0.6.0: Treats all ranges as exclusive */ module Range @@ -15,8 +20,8 @@ module Range * @param range: The range to check within * @returns Whether or not the value is within range * - * @example Range.inRange(1, Inclusive(0, 2)) == true - * @example Range.inRange(10, Inclusive(0, 2)) == false + * @example Range.inRange(1, { range_start: 0, range_end: 2 }) == true + * @example Range.inRange(10, { range_start: 0, range_end: 2 }) == false * * @since v0.3.0 */ @@ -35,12 +40,16 @@ provide let inRange = (value, range) => { } /** - * Calls the given function with each number in the range. For increasing ranges, the value is increased by `1` in each iteration, and for decreasing ranges, the value is decreased by `1`. The value is always changed by `1`, even if non-integer values were provided in the range. + * Calls the given function with each number in the range. + * + * For increasing ranges, the value is increased by `1` in each iteration, + * and for decreasing ranges, the value is decreased by `1`. The value is + * always changed by `1`, even if non-integer values were provided in the range. * * @param fn: The function to be executed on each number in the range * @param range: The range to iterate * - * @example Range.forEach(val => print(val), Exclusive(0, 2)) + * @example Range.forEach(val => print(val), { range_start: 0, range_end: 2 }) * * @since v0.3.0 */ @@ -64,13 +73,17 @@ provide let forEach = (fn: Number -> Void, range) => { } /** - * Produces a list by calling the given function on each number included in the range. For increasing ranges, the value is increased by `1` in each iteration, and for decreasing ranges, the value is decreased by `1`. The value is always changed by `1`, even if non-integer values were provided in the range. + * Produces a list by calling the given function on each number included in the range. + * + * For increasing ranges, the value is increased by `1` in each iteration, + * and for decreasing ranges, the value is decreased by `1`. The value is + * always changed by `1`, even if non-integer values were provided in the range. * * @param fn: The function called on each number in the range that returns the value for the output list * @param range: The range to iterate * @returns A list containing all values returned from the `fn` * - * @example Range.map(val => val * 2, Inclusive(0, 2)) == [0, 2, 4] + * @example Range.map(val => val * 2, { range_start: 0, range_end: 3 }) == [0, 2, 4] * * @since v0.3.2 */ diff --git a/stdlib/range.md b/stdlib/range.md index 17ae5e44bd..c2d816ae82 100644 --- a/stdlib/range.md +++ b/stdlib/range.md @@ -2,32 +2,28 @@ title: Range --- -Utilities for working with ranges. A range represents an interval—a set of values with a beginning and an end. - -
-Added in 0.3.0 -No other changes yet. +Utilities for working with ranges. + +A range represents an interval—a set of values with a beginning and an end. + +All functions in this module treat ranges as exclusive. + +
+Added in 0.3.0 + + + + + + + +
versionchanges
nextTreats all ranges as exclusive
```grain include "range" ``` -## Types - -Type declarations included in the Range module. - -### Range.**Range** - -```grain -enum Range { - Inclusive(Number, Number), - Exclusive(Number, Number), -} -``` - -Ranges can be inclusive or exclusive. When `Inclusive`, the end value will be included in operations. When `Exclusive`, the end value will be excluded from operations. - ## Values Functions and constants included in the Range module. @@ -40,7 +36,7 @@ No other changes yet.
```grain -inRange : (Number, Range) -> Bool +inRange : (Number, Range) -> Bool ``` Checks if the given number is within the range. @@ -50,7 +46,7 @@ Parameters: |param|type|description| |-----|----|-----------| |`value`|`Number`|The number being checked| -|`range`|`Range`|The range to check within| +|`range`|`Range`|The range to check within| Returns: @@ -61,11 +57,11 @@ Returns: Examples: ```grain -Range.inRange(1, Range.Inclusive(0, 2)) == true +Range.inRange(1, { range_start: 0, range_end: 2 }) == true ``` ```grain -Range.inRange(10, Range.Inclusive(0, 2)) == false +Range.inRange(10, { range_start: 0, range_end: 2 }) == false ``` ### Range.**forEach** @@ -76,22 +72,26 @@ No other changes yet. ```grain -forEach : ((Number -> Void), Range) -> Void +forEach : ((Number -> Void), Range) -> Void ``` -Calls the given function with each number in the range. For increasing ranges, the value is increased by `1` in each iteration, and for decreasing ranges, the value is decreased by `1`. The value is always changed by `1`, even if non-integer values were provided in the range. +Calls the given function with each number in the range. + +For increasing ranges, the value is increased by `1` in each iteration, +and for decreasing ranges, the value is decreased by `1`. The value is +always changed by `1`, even if non-integer values were provided in the range. Parameters: |param|type|description| |-----|----|-----------| |`fn`|`Number -> Void`|The function to be executed on each number in the range| -|`range`|`Range`|The range to iterate| +|`range`|`Range`|The range to iterate| Examples: ```grain -Range.forEach(val => print(val), Range.Exclusive(0, 2)) +Range.forEach(val => print(val), { range_start: 0, range_end: 2 }) ``` ### Range.**map** @@ -102,17 +102,21 @@ No other changes yet. ```grain -map : ((Number -> a), Range) -> List +map : ((Number -> a), Range) -> List ``` -Produces a list by calling the given function on each number included in the range. For increasing ranges, the value is increased by `1` in each iteration, and for decreasing ranges, the value is decreased by `1`. The value is always changed by `1`, even if non-integer values were provided in the range. +Produces a list by calling the given function on each number included in the range. + +For increasing ranges, the value is increased by `1` in each iteration, +and for decreasing ranges, the value is decreased by `1`. The value is +always changed by `1`, even if non-integer values were provided in the range. Parameters: |param|type|description| |-----|----|-----------| |`fn`|`Number -> a`|The function called on each number in the range that returns the value for the output list| -|`range`|`Range`|The range to iterate| +|`range`|`Range`|The range to iterate| Returns: @@ -123,6 +127,6 @@ Returns: Examples: ```grain -Range.map(val => val * 2, Range.Inclusive(0, 2)) == [0, 2, 4] +Range.map(val => val * 2, { range_start: 0, range_end: 3 }) == [0, 2, 4] ``` From 575559bb6b660c0521c205b3bd5963bd2074d3f1 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Tue, 21 Feb 2023 21:32:28 -0700 Subject: [PATCH 4/9] formatting --- compiler/test/stdlib/immutablearray.test.gr | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/test/stdlib/immutablearray.test.gr b/compiler/test/stdlib/immutablearray.test.gr index 3c5dcb7163..0c4805ed27 100644 --- a/compiler/test/stdlib/immutablearray.test.gr +++ b/compiler/test/stdlib/immutablearray.test.gr @@ -22,7 +22,10 @@ let bltArr = fromList(branchingLongTail) // for testing the case where the tree is about to branch let almostBranchingLen = 32 * 32 + 31 -let almostBranching = Range.map(identity, { range_start: 0, range_end: almostBranchingLen }) +let almostBranching = Range.map( + identity, + { range_start: 0, range_end: almostBranchingLen } +) let abArr = fromList(almostBranching) assert ImmutableArray.empty == fromList([]) From 71a23fa909aa0a48f44889be391ca697a5bf89c8 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Tue, 21 Feb 2023 22:10:15 -0700 Subject: [PATCH 5/9] rename range_start and range_end --- compiler/src/typed/builtin_types.re | 6 +++--- compiler/test/stdlib/immutablearray.test.gr | 10 +++++----- compiler/test/stdlib/range.test.gr | 6 +++--- stdlib/range.gr | 20 ++++++++++---------- stdlib/range.md | 8 ++++---- 5 files changed, 25 insertions(+), 25 deletions(-) diff --git a/compiler/src/typed/builtin_types.re b/compiler/src/typed/builtin_types.re index b7317796e5..2274b47b2b 100644 --- a/compiler/src/typed/builtin_types.re +++ b/compiler/src/typed/builtin_types.re @@ -38,8 +38,8 @@ and ident_option = ident_create("Option") and ident_result = ident_create("Result") and ident_list = ident_create("List"); let ident_range = ident_create("Range") -and ident_range_start = ident_create("range_start") -and ident_range_end = ident_create("range_end") +and ident_range_start = ident_create("rangeStart") +and ident_range_end = ident_create("rangeEnd") and ident_int32 = ident_create("Int32") and ident_int64 = ident_create("Int64") and ident_uint32 = ident_create("Uint32") @@ -100,7 +100,7 @@ and type_result = (ok, err) => newgenty(TTyConstr(path_result, [ok, err], ref(TMemNil))) and type_list = var => newgenty(TTyConstr(path_list, [var], ref(TMemNil))) and type_range = var => - newgenty(TTyRecord([("range_start", var), ("range_end", var)])) + newgenty(TTyRecord([("rangeStart", var), ("rangeEnd", var)])) and type_int32 = newgenty(TTyConstr(path_int32, [], ref(TMemNil))) and type_int64 = newgenty(TTyConstr(path_int64, [], ref(TMemNil))) and type_uint32 = newgenty(TTyConstr(path_uint32, [], ref(TMemNil))) diff --git a/compiler/test/stdlib/immutablearray.test.gr b/compiler/test/stdlib/immutablearray.test.gr index 0c4805ed27..67bf1410c2 100644 --- a/compiler/test/stdlib/immutablearray.test.gr +++ b/compiler/test/stdlib/immutablearray.test.gr @@ -9,14 +9,14 @@ let fromList = ImmutableArray.fromList let arr = fromList([1, 2, 3]) // for testing the case where the tail is empty -let noTail = Range.map(identity, { range_start: 0, range_end: 32 }) +let noTail = Range.map(identity, { rangeStart: 0, rangeEnd: 32 }) let noTailArr = fromList(noTail) // for testing the case where the tree branches and has a tail of max length let branchingLongTailLen = 32 * 33 + 31 let branchingLongTail = Range.map( identity, - { range_start: 0, range_end: branchingLongTailLen } + { rangeStart: 0, rangeEnd: branchingLongTailLen } ) let bltArr = fromList(branchingLongTail) @@ -24,7 +24,7 @@ let bltArr = fromList(branchingLongTail) let almostBranchingLen = 32 * 32 + 31 let almostBranching = Range.map( identity, - { range_start: 0, range_end: almostBranchingLen } + { rangeStart: 0, rangeEnd: almostBranchingLen } ) let abArr = fromList(almostBranching) @@ -92,10 +92,10 @@ assert ImmutableArray.append(bltArr, fromList([val, val + 1, val + 2])) == fromList(List.append(branchingLongTail, [val, val + 1, val + 2])) assert ImmutableArray.append(fromList([-3, -2, -1]), bltArr) == fromList([-3, -2, -1, ...branchingLongTail]) -let vals = Range.map(x => x + 32, { range_start: 0, range_end: 128 }) +let vals = Range.map(x => x + 32, { rangeStart: 0, rangeEnd: 128 }) assert ImmutableArray.append(noTailArr, fromList(vals)) == fromList(List.append(noTail, vals)) -let vals = Range.map(x => x + 32, { range_start: 0, range_end: 128 + 31 }) +let vals = Range.map(x => x + 32, { rangeStart: 0, rangeEnd: 128 + 31 }) assert ImmutableArray.append(noTailArr, fromList(vals)) == fromList(List.append(noTail, vals)) assert ImmutableArray.append(noTailArr, noTailArr) == diff --git a/compiler/test/stdlib/range.test.gr b/compiler/test/stdlib/range.test.gr index 20250c0331..53a37fad9c 100644 --- a/compiler/test/stdlib/range.test.gr +++ b/compiler/test/stdlib/range.test.gr @@ -2,9 +2,9 @@ module RangeTest include "range" -let exclusiveAscendingRange = { range_start: 1, range_end: 5 } -let exclusiveDescendingRange = { range_start: 5, range_end: 1 } -let exclusiveSameRange = { range_start: 1, range_end: 1 } +let exclusiveAscendingRange = { rangeStart: 1, rangeEnd: 5 } +let exclusiveDescendingRange = { rangeStart: 5, rangeEnd: 1 } +let exclusiveSameRange = { rangeStart: 1, rangeEnd: 1 } // Range.inRange assert Range.inRange(1, exclusiveAscendingRange) diff --git a/stdlib/range.gr b/stdlib/range.gr index fd960b7faf..82a31f3b4b 100644 --- a/stdlib/range.gr +++ b/stdlib/range.gr @@ -20,18 +20,18 @@ module Range * @param range: The range to check within * @returns Whether or not the value is within range * - * @example Range.inRange(1, { range_start: 0, range_end: 2 }) == true - * @example Range.inRange(10, { range_start: 0, range_end: 2 }) == false + * @example Range.inRange(1, { rangeStart: 0, rangeEnd: 2 }) == true + * @example Range.inRange(10, { rangeStart: 0, rangeEnd: 2 }) == false * * @since v0.3.0 */ provide let inRange = (value, range) => { match (range) { - { range_start: lower, range_end: upper } when ( + { rangeStart: lower, rangeEnd: upper } when ( value >= lower && value < upper ) => true, - { range_start: upper, range_end: lower } when ( + { rangeStart: upper, rangeEnd: lower } when ( value >= lower && value < upper ) => true, @@ -49,20 +49,20 @@ provide let inRange = (value, range) => { * @param fn: The function to be executed on each number in the range * @param range: The range to iterate * - * @example Range.forEach(val => print(val), { range_start: 0, range_end: 2 }) + * @example Range.forEach(val => print(val), { rangeStart: 0, rangeEnd: 2 }) * * @since v0.3.0 */ provide let forEach = (fn: Number -> Void, range) => { match (range) { - { range_start: lower, range_end: upper } when lower <= upper => { + { rangeStart: lower, rangeEnd: upper } when lower <= upper => { let mut idx = lower while (idx < upper) { fn(idx) idx += 1 } }, - { range_start: upper, range_end: lower } => { + { rangeStart: upper, rangeEnd: lower } => { let mut idx = upper while (idx > lower) { fn(idx) @@ -83,21 +83,21 @@ provide let forEach = (fn: Number -> Void, range) => { * @param range: The range to iterate * @returns A list containing all values returned from the `fn` * - * @example Range.map(val => val * 2, { range_start: 0, range_end: 3 }) == [0, 2, 4] + * @example Range.map(val => val * 2, { rangeStart: 0, rangeEnd: 3 }) == [0, 2, 4] * * @since v0.3.2 */ provide let map = (fn, range) => { let mut result = [] match (range) { - { range_start: lower, range_end: upper } when lower <= upper => { + { rangeStart: lower, rangeEnd: upper } when lower <= upper => { let mut idx = upper - 1 while (idx >= lower) { result = [fn(idx), ...result] idx -= 1 } }, - { range_start: upper, range_end: lower } => { + { rangeStart: upper, rangeEnd: lower } => { let mut idx = lower + 1 while (idx <= upper) { result = [fn(idx), ...result] diff --git a/stdlib/range.md b/stdlib/range.md index c2d816ae82..55628d411d 100644 --- a/stdlib/range.md +++ b/stdlib/range.md @@ -57,11 +57,11 @@ Returns: Examples: ```grain -Range.inRange(1, { range_start: 0, range_end: 2 }) == true +Range.inRange(1, { rangeStart: 0, rangeEnd: 2 }) == true ``` ```grain -Range.inRange(10, { range_start: 0, range_end: 2 }) == false +Range.inRange(10, { rangeStart: 0, rangeEnd: 2 }) == false ``` ### Range.**forEach** @@ -91,7 +91,7 @@ Parameters: Examples: ```grain -Range.forEach(val => print(val), { range_start: 0, range_end: 2 }) +Range.forEach(val => print(val), { rangeStart: 0, rangeEnd: 2 }) ``` ### Range.**map** @@ -127,6 +127,6 @@ Returns: Examples: ```grain -Range.map(val => val * 2, { range_start: 0, range_end: 3 }) == [0, 2, 4] +Range.map(val => val * 2, { rangeStart: 0, rangeEnd: 3 }) == [0, 2, 4] ``` From 2a7d7f0aa3fc72f96ce46d53d8f042178f231836 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Tue, 21 Feb 2023 22:11:03 -0700 Subject: [PATCH 6/9] remove old idents --- compiler/src/typed/builtin_types.re | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/compiler/src/typed/builtin_types.re b/compiler/src/typed/builtin_types.re index 2274b47b2b..a25a76ba31 100644 --- a/compiler/src/typed/builtin_types.re +++ b/compiler/src/typed/builtin_types.re @@ -156,9 +156,7 @@ and ident_none_cstr = ident_create("None") and ident_ok_cstr = ident_create("Ok") and ident_err_cstr = ident_create("Err") and ident_cons_cstr = ident_create("[...]") -and ident_empty_cstr = ident_create("[]") -and ident_inclusive_cstr = ident_create("Inclusive") -and ident_exclusive_cstr = ident_create("Exclusive"); +and ident_empty_cstr = ident_create("[]"); let decl_exception = {...decl_abstr(path_exception), type_kind: TDataOpen}; let decl_bool = { From db8c585baa4882f96a7dd187c37a53308b52ed95 Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Tue, 21 Feb 2023 22:27:06 -0700 Subject: [PATCH 7/9] feat(stdlib): Add Inclusive submodule to Range module --- compiler/test/stdlib/range.test.gr | 48 ++++++++ stdlib/range.gr | 109 +++++++++++++++++- stdlib/range.md | 171 +++++++++++++++++++++++++++-- 3 files changed, 317 insertions(+), 11 deletions(-) diff --git a/compiler/test/stdlib/range.test.gr b/compiler/test/stdlib/range.test.gr index 53a37fad9c..d71c1c3f47 100644 --- a/compiler/test/stdlib/range.test.gr +++ b/compiler/test/stdlib/range.test.gr @@ -45,3 +45,51 @@ Range.forEach(idx => { assert Range.map(toString, exclusiveAscendingRange) == ["1", "2", "3", "4"] assert Range.map(toString, exclusiveDescendingRange) == ["5", "4", "3", "2"] assert Range.map(toString, exclusiveSameRange) == [] + +module Inclusive { + from Range use { Inclusive as Range } + + let inclusiveAscendingRange = { rangeStart: 1, rangeEnd: 5 } + let inclusiveDescendingRange = { rangeStart: 5, rangeEnd: 1 } + let inclusiveSameRange = { rangeStart: 1, rangeEnd: 1 } + + // Range.inRange + assert Range.inRange(1, inclusiveAscendingRange) + assert Range.inRange(3, inclusiveAscendingRange) + assert Range.inRange(5, inclusiveAscendingRange) + assert !Range.inRange(10, inclusiveAscendingRange) + assert !Range.inRange(-1, inclusiveAscendingRange) + + assert Range.inRange(1, inclusiveDescendingRange) + assert Range.inRange(3, inclusiveDescendingRange) + assert Range.inRange(5, inclusiveDescendingRange) + assert !Range.inRange(10, inclusiveDescendingRange) + assert !Range.inRange(-1, inclusiveDescendingRange) + + assert Range.inRange(1, inclusiveSameRange) + assert !Range.inRange(3, inclusiveSameRange) + + let mut results = [] + Range.forEach(idx => { + results = [idx, ...results] + }, inclusiveAscendingRange) + assert results == [5, 4, 3, 2, 1] + + let mut results = [] + Range.forEach(idx => { + results = [idx, ...results] + }, inclusiveDescendingRange) + assert results == [1, 2, 3, 4, 5] + + let mut results = [] + Range.forEach(idx => { + results = [idx, ...results] + }, inclusiveSameRange) + assert results == [1] + + assert Range.map(toString, inclusiveAscendingRange) == + ["1", "2", "3", "4", "5"] + assert Range.map(toString, inclusiveDescendingRange) == + ["5", "4", "3", "2", "1"] + assert Range.map(toString, inclusiveSameRange) == ["1"] +} diff --git a/stdlib/range.gr b/stdlib/range.gr index 82a31f3b4b..31438fba9a 100644 --- a/stdlib/range.gr +++ b/stdlib/range.gr @@ -3,7 +3,8 @@ * * A range represents an interval—a set of values with a beginning and an end. * - * All functions in this module treat ranges as exclusive. + * All functions in this module treat ranges as exclusive, but inclusive versions + * of all APIs are available in the `Inclusive` submodule. * * @example include "range" * @@ -24,6 +25,7 @@ module Range * @example Range.inRange(10, { rangeStart: 0, rangeEnd: 2 }) == false * * @since v0.3.0 + * @history v0.6.0: Treats all ranges as exclusive */ provide let inRange = (value, range) => { match (range) { @@ -52,6 +54,7 @@ provide let inRange = (value, range) => { * @example Range.forEach(val => print(val), { rangeStart: 0, rangeEnd: 2 }) * * @since v0.3.0 + * @history v0.6.0: Treats all ranges as exclusive */ provide let forEach = (fn: Number -> Void, range) => { match (range) { @@ -86,6 +89,7 @@ provide let forEach = (fn: Number -> Void, range) => { * @example Range.map(val => val * 2, { rangeStart: 0, rangeEnd: 3 }) == [0, 2, 4] * * @since v0.3.2 + * @history v0.6.0: Treats all ranges as exclusive */ provide let map = (fn, range) => { let mut result = [] @@ -107,3 +111,106 @@ provide let map = (fn, range) => { } result } + +provide module Inclusive { + /** + * Checks if the given number is within the range. + * + * @param value: The number being checked + * @param range: The range to check within + * @returns Whether or not the value is within range + * + * @example Range.Inclusive.inRange(1, { rangeStart: 0, rangeEnd: 1 }) == true + * @example Range.Inclusive.inRange(10, { rangeStart: 0, rangeEnd: 2 }) == false + * + * @since v0.6.0 + * @history v0.3.0: Root APIs originally handled Inclusive & Exclusive variants + */ + + provide let inRange = (value, range) => { + match (range) { + { rangeStart: lower, rangeEnd: upper } when ( + value >= lower && value <= upper + ) => + true, + { rangeStart: upper, rangeEnd: lower } when ( + value >= lower && value <= upper + ) => + true, + _ => false, + } + } + + /** + * Calls the given function with each number in the range. + * + * For increasing ranges, the value is increased by `1` in each iteration, + * and for decreasing ranges, the value is decreased by `1`. The value is + * always changed by `1`, even if non-integer values were provided in the range. + * + * @param fn: The function to be executed on each number in the range + * @param range: The range to iterate + * + * @example Range.Inclusive.forEach(val => print(val), { rangeStart: 0, rangeEnd: 2 }) + * + * @since v0.3.0 + * @history v0.3.0: Root APIs originally handled Inclusive & Exclusive variants + */ + + provide let forEach = (fn: Number -> Void, range) => { + match (range) { + { rangeStart: lower, rangeEnd: upper } when lower <= upper => { + let mut idx = lower + while (idx <= upper) { + fn(idx) + idx += 1 + } + }, + { rangeStart: upper, rangeEnd: lower } => { + let mut idx = upper + while (idx >= lower) { + fn(idx) + idx -= 1 + } + }, + } + } + + /** + * Produces a list by calling the given function on each number included in the range. + * + * For increasing ranges, the value is increased by `1` in each iteration, + * and for decreasing ranges, the value is decreased by `1`. The value is + * always changed by `1`, even if non-integer values were provided in the range. + * + * @param fn: The function called on each number in the range that returns the value for the output list + * @param range: The range to iterate + * @returns A list containing all values returned from the `fn` + * + * @example Range.Inclusive.map(val => val * 2, { rangeStart: 0, rangeEnd: 2 }) == [0, 2, 4] + * + * @since v0.3.2 + * @history v0.3.0: Root APIs originally handled Inclusive & Exclusive variants + */ + + provide let map = (fn, range) => { + let mut result = [] + match (range) { + { rangeStart: lower, rangeEnd: upper } when lower <= upper => { + let mut idx = upper + while (idx >= lower) { + result = [fn(idx), ...result] + idx -= 1 + } + }, + { rangeStart: upper, rangeEnd: lower } => { + let mut idx = lower + while (idx <= upper) { + result = [fn(idx), ...result] + idx += 1 + } + }, + } + result + } +} diff --git a/stdlib/range.md b/stdlib/range.md index 55628d411d..7930508eab 100644 --- a/stdlib/range.md +++ b/stdlib/range.md @@ -6,7 +6,8 @@ Utilities for working with ranges. A range represents an interval—a set of values with a beginning and an end. -All functions in this module treat ranges as exclusive. +All functions in this module treat ranges as exclusive, but inclusive versions +of all APIs are available in the `Inclusive` submodule.
Added in 0.3.0 @@ -30,9 +31,16 @@ Functions and constants included in the Range module. ### Range.**inRange** -
-Added in 0.3.0 -No other changes yet. +
+Added in 0.3.0 + + + + + + + +
versionchanges
nextTreats all ranges as exclusive
```grain @@ -66,9 +74,16 @@ Range.inRange(10, { rangeStart: 0, rangeEnd: 2 }) == false ### Range.**forEach** -
-Added in 0.3.0 -No other changes yet. +
+Added in 0.3.0 + + + + + + + +
versionchanges
nextTreats all ranges as exclusive
```grain @@ -96,9 +111,16 @@ Range.forEach(val => print(val), { rangeStart: 0, rangeEnd: 2 }) ### Range.**map** -
-Added in 0.3.2 -No other changes yet. +
+Added in 0.3.2 + + + + + + + +
versionchanges
nextTreats all ranges as exclusive
```grain @@ -130,3 +152,132 @@ Examples: Range.map(val => val * 2, { rangeStart: 0, rangeEnd: 3 }) == [0, 2, 4] ``` +## Range.Inclusive + +### Values + +Functions and constants included in the Range.Inclusive module. + +#### Range.Inclusive.**inRange** + +
+Added in next + + + + + + + +
versionchanges
0.3.0Root APIs originally handled Inclusive & Exclusive variants
+
+ +```grain +inRange : (Number, Range) -> Bool +``` + +Checks if the given number is within the range. + +Parameters: + +|param|type|description| +|-----|----|-----------| +|`value`|`Number`|The number being checked| +|`range`|`Range`|The range to check within| + +Returns: + +|type|description| +|----|-----------| +|`Bool`|Whether or not the value is within range| + +Examples: + +```grain +Range.Inclusive.inRange(1, { rangeStart: 0, rangeEnd: 1 }) == true +``` + +```grain +Range.Inclusive.inRange(10, { rangeStart: 0, rangeEnd: 2 }) == false +``` + +#### Range.Inclusive.**forEach** + +
+Added in 0.3.0 + + + + + + + +
versionchanges
0.3.0Root APIs originally handled Inclusive & Exclusive variants
+
+ +```grain +forEach : ((Number -> Void), Range) -> Void +``` + +Calls the given function with each number in the range. + +For increasing ranges, the value is increased by `1` in each iteration, +and for decreasing ranges, the value is decreased by `1`. The value is +always changed by `1`, even if non-integer values were provided in the range. + +Parameters: + +|param|type|description| +|-----|----|-----------| +|`fn`|`Number -> Void`|The function to be executed on each number in the range| +|`range`|`Range`|The range to iterate| + +Examples: + +```grain +Range.Inclusive.forEach(val => print(val), { rangeStart: 0, rangeEnd: 2 }) +``` + +#### Range.Inclusive.**map** + +
+Added in 0.3.2 + + + + + + + +
versionchanges
0.3.0Root APIs originally handled Inclusive & Exclusive variants
+
+ +```grain +map : ((Number -> a), Range) -> List
+``` + +Produces a list by calling the given function on each number included in the range. + +For increasing ranges, the value is increased by `1` in each iteration, +and for decreasing ranges, the value is decreased by `1`. The value is +always changed by `1`, even if non-integer values were provided in the range. + +Parameters: + +|param|type|description| +|-----|----|-----------| +|`fn`|`Number -> a`|The function called on each number in the range that returns the value for the output list| +|`range`|`Range`|The range to iterate| + +Returns: + +|type|description| +|----|-----------| +|`List`|A list containing all values returned from the `fn`| + +Examples: + +```grain +Range.Inclusive.map(val => val * 2, { rangeStart: 0, rangeEnd: 2 }) == [0, 2, 4] +``` + From cd6d60818c04072347dfe402fe5d43423b9462ef Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Tue, 21 Feb 2023 22:43:44 -0700 Subject: [PATCH 8/9] Update compiler/src/typed/builtin_types.re Co-authored-by: Oscar Spencer --- compiler/src/typed/builtin_types.re | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/src/typed/builtin_types.re b/compiler/src/typed/builtin_types.re index a25a76ba31..cd520af7b4 100644 --- a/compiler/src/typed/builtin_types.re +++ b/compiler/src/typed/builtin_types.re @@ -100,7 +100,7 @@ and type_result = (ok, err) => newgenty(TTyConstr(path_result, [ok, err], ref(TMemNil))) and type_list = var => newgenty(TTyConstr(path_list, [var], ref(TMemNil))) and type_range = var => - newgenty(TTyRecord([("rangeStart", var), ("rangeEnd", var)])) + newgenty(TTyRecord([(Ident.name(ident_range_start), var), (Ident.name(ident_range_end), var)])) and type_int32 = newgenty(TTyConstr(path_int32, [], ref(TMemNil))) and type_int64 = newgenty(TTyConstr(path_int64, [], ref(TMemNil))) and type_uint32 = newgenty(TTyConstr(path_uint32, [], ref(TMemNil))) From e63e107f1642cc52b32a755619785355fd802c2a Mon Sep 17 00:00:00 2001 From: Blaine Bublitz Date: Wed, 22 Feb 2023 07:20:33 -0700 Subject: [PATCH 9/9] formatting --- compiler/src/typed/builtin_types.re | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/compiler/src/typed/builtin_types.re b/compiler/src/typed/builtin_types.re index cd520af7b4..b67c16948e 100644 --- a/compiler/src/typed/builtin_types.re +++ b/compiler/src/typed/builtin_types.re @@ -100,7 +100,12 @@ and type_result = (ok, err) => newgenty(TTyConstr(path_result, [ok, err], ref(TMemNil))) and type_list = var => newgenty(TTyConstr(path_list, [var], ref(TMemNil))) and type_range = var => - newgenty(TTyRecord([(Ident.name(ident_range_start), var), (Ident.name(ident_range_end), var)])) + newgenty( + TTyRecord([ + (Ident.name(ident_range_start), var), + (Ident.name(ident_range_end), var), + ]), + ) and type_int32 = newgenty(TTyConstr(path_int32, [], ref(TMemNil))) and type_int64 = newgenty(TTyConstr(path_int64, [], ref(TMemNil))) and type_uint32 = newgenty(TTyConstr(path_uint32, [], ref(TMemNil)))