From eed255df57b340fc63418ca65622e9fefd33eab4 Mon Sep 17 00:00:00 2001 From: zihang Date: Mon, 22 Sep 2025 17:16:50 +0800 Subject: [PATCH 1/2] refactor: make arrayview immutable --- array/deprecated.mbt | 44 ------------------------------------ builtin/arrayview.mbt | 52 ------------------------------------------- 2 files changed, 96 deletions(-) delete mode 100644 array/deprecated.mbt diff --git a/array/deprecated.mbt b/array/deprecated.mbt deleted file mode 100644 index d3ac1f95c..000000000 --- a/array/deprecated.mbt +++ /dev/null @@ -1,44 +0,0 @@ -// Copyright 2025 International Digital Economy Academy -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -///| -#deprecated("ArrayView will be immutable, use array if you need mutation") -pub fn[T] View::rev_inplace(self : View[T]) -> Unit { - let mid_len = self.length() / 2 - for i in 0.. T raise?) -> Unit raise? { - for i, v in self { - self[i] = f(v) - } -} - -///| -#deprecated("ArrayView will be immutable, use array if you need mutation") -pub fn[T] View::mapi_inplace( - self : View[T], - f : (Int, T) -> T raise?, -) -> Unit raise? { - for i, v in self { - self[i] = f(i, v) - } -} diff --git a/builtin/arrayview.mbt b/builtin/arrayview.mbt index 2524a4269..003d1739a 100644 --- a/builtin/arrayview.mbt +++ b/builtin/arrayview.mbt @@ -120,43 +120,6 @@ pub fn[T] ArrayView::unsafe_get(self : ArrayView[T], index : Int) -> T { self.buf()[self.start() + index] } -///| -/// Sets the value at the specified index in the array view. -/// -/// Parameters: -/// -/// * `array_view` : The array view to modify. -/// * `index` : The position in the array view where the value will be set. -/// * `value` : The value to be assigned at the specified index. -/// -/// Throws a panic if `index` is negative or greater than or equal to the length -/// of the array view. -/// -/// -#deprecated("ArrayView will be immutable, use array if you need mutation") -#alias("_[_]=_") -pub fn[T] ArrayView::set(self : ArrayView[T], index : Int, value : T) -> Unit { - guard index >= 0 && index < self.len() else { - abort( - "index out of bounds: the len is from 0 to \{self.len()} but the index is \{index}", - ) - } - self.buf()[self.start() + index] = value -} - -///| -#deprecated("ArrayView will be immutable, use array if you need mutation") -pub fn[T] ArrayView::swap(self : ArrayView[T], i : Int, j : Int) -> Unit { - guard i >= 0 && i < self.len() && j >= 0 && j < self.len() else { - abort( - "index out of bounds: the len is from 0 to \{self.len()} but the index is (\{i}, \{j})", - ) - } - let temp = self.buf()[self.start() + i] - self.buf()[self.start() + i] = self.buf()[self.start() + j] - self.buf()[self.start() + j] = temp -} - ///| /// Creates a view of a portion of the array. The view provides read-write access /// to the underlying array without copying the elements. @@ -299,18 +262,3 @@ pub fn[T] FixedArray::sub( end - start, ) } - -///| -#deprecated("ArrayView will be immutable, use array if you need mutation") -pub fn[T] ArrayView::blit_to(self : ArrayView[T], dst : ArrayView[T]) -> Unit { - let src_len = self.length() - let dst_len = dst.length() - guard dst_len >= src_len - UninitializedArray::unsafe_blit( - dst.buf(), - dst.start(), - self.buf(), - self.start(), - src_len, - ) -} From 489bfa1d26a39390c5912ec9c13789d521752bba Mon Sep 17 00:00:00 2001 From: zihang Date: Mon, 22 Sep 2025 14:31:50 +0800 Subject: [PATCH 2/2] fix: migrate sort implementation --- array/fixedarray_sort.mbt | 2 +- array/pkg.generated.mbti | 6 ---- array/slice.mbt | 55 ++++++++++++++++++++++++++++++ array/sort.mbt | 68 +++++++++++++++++++++----------------- array/sort_by.mbt | 41 +++++++++++++++-------- builtin/array.mbt | 2 +- builtin/pkg.generated.mbti | 8 +---- 7 files changed, 123 insertions(+), 59 deletions(-) diff --git a/array/fixedarray_sort.mbt b/array/fixedarray_sort.mbt index 16a16a4bc..5ad9d2984 100644 --- a/array/fixedarray_sort.mbt +++ b/array/fixedarray_sort.mbt @@ -98,7 +98,7 @@ fn[T : Compare] merge(arr : FixedArraySlice[T], mid : Int) -> Unit { for i in 0..= 0 && p2 >= 0; { diff --git a/array/pkg.generated.mbti b/array/pkg.generated.mbti index 0b3639c93..f13258043 100644 --- a/array/pkg.generated.mbti +++ b/array/pkg.generated.mbti @@ -84,15 +84,9 @@ fn[A] ArrayView::iter(Self[A]) -> Iter[A] fn[A] ArrayView::iter2(Self[A]) -> Iter2[Int, A] fn[A : @string.ToStringView] ArrayView::join(Self[A], StringView) -> String fn[T, U] ArrayView::map(Self[T], (T) -> U raise?) -> Array[U] raise? -#deprecated -fn[T] ArrayView::map_inplace(Self[T], (T) -> T raise?) -> Unit raise? fn[T, U] ArrayView::mapi(Self[T], (Int, T) -> U raise?) -> Array[U] raise? -#deprecated -fn[T] ArrayView::mapi_inplace(Self[T], (Int, T) -> T raise?) -> Unit raise? fn[A, B] ArrayView::rev_fold(Self[A], init~ : B, (B, A) -> B raise?) -> B raise? fn[A, B] ArrayView::rev_foldi(Self[A], init~ : B, (Int, B, A) -> B raise?) -> B raise? -#deprecated -fn[T] ArrayView::rev_inplace(Self[T]) -> Unit fn[T] ArrayView::to_array(Self[T]) -> Array[T] fn ArrayView::unsafe_extract_bit(Self[Byte], Int, Int) -> UInt fn ArrayView::unsafe_extract_byte(Self[Byte], Int, Int) -> UInt diff --git a/array/slice.mbt b/array/slice.mbt index 505f9cfe1..0a4a83e2b 100644 --- a/array/slice.mbt +++ b/array/slice.mbt @@ -67,3 +67,58 @@ fn[T] FixedArraySlice::slice( ) -> FixedArraySlice[T] { { array: self.array, start: self.start + start, end: self.start + end } } + +///| +/// TODO: use specific type for non-js backend +/// Notice: may need to move to builtin +priv struct ArraySlice[T] { + array : Array[T] + start : Int + end : Int +} + +///| +fn[T] ArraySlice::length(self : ArraySlice[T]) -> Int { + self.end - self.start +} + +///| +#alias("_[_]") +fn[T] ArraySlice::at(self : ArraySlice[T], index : Int) -> T { + self.array[self.start + index] +} + +///| +fn[T] ArraySlice::swap(self : ArraySlice[T], a : Int, b : Int) -> Unit { + let i = a + self.start + let j = b + self.start + if i >= self.end || j >= self.end || i < self.start || j < self.start { + let len = self.length() + abort( + "index out of bounds: the len is from 0 to \{len} but the index is (\{a}, \{b})", + ) + } + let temp = self.array.unsafe_get(i) + self.array.unsafe_set(i, self.array.unsafe_get(j)) + self.array.unsafe_set(j, temp) +} + +///| +fn[T] ArraySlice::rev_inplace(self : ArraySlice[T]) -> Unit { + let len = self.length() + let mid_len = len / 2 + for i in 0.. ArraySlice[T] { + { array: self.array, start: self.start + start, end: self.start + end } +} diff --git a/array/sort.mbt b/array/sort.mbt index db3df9b75..c6cddeb28 100644 --- a/array/sort.mbt +++ b/array/sort.mbt @@ -26,11 +26,11 @@ /// ``` pub fn[T : Compare] sort(self : Array[T]) -> Unit { let len = self.length() - quick_sort(self[:len], None, get_limit(len)) + quick_sort({ array: self, start: 0, end: len }, None, get_limit(len)) } ///| -fn[T : Compare] quick_sort(arr : ArrayView[T], pred : T?, limit : Int) -> Unit { +fn[T : Compare] quick_sort(arr : ArraySlice[T], pred : T?, limit : Int) -> Unit { let mut limit = limit let mut arr = arr let mut pred = pred @@ -41,7 +41,7 @@ fn[T : Compare] quick_sort(arr : ArrayView[T], pred : T?, limit : Int) -> Unit { let len = arr.length() if len <= insertion_sort_len { if len >= 2 { - ArrayView::insertion_sort(arr) + insertion_sort(arr) } return } @@ -60,7 +60,10 @@ fn[T : Compare] quick_sort(arr : ArrayView[T], pred : T?, limit : Int) -> Unit { } let (pivot, partitioned) = partition(arr, pivot_index) was_partitioned = partitioned - balanced = minimum(pivot, len - pivot) >= len / 8 + balanced = { + let diff = len - pivot + (if pivot < diff { pivot } else { diff }) >= len / 8 + } if !balanced { limit -= 1 } @@ -107,7 +110,7 @@ fn get_limit(len : Int) -> Int { /// It will only tolerate at most 8 unsorted elements. The time complexity is O(n). /// /// Returns whether the array is sorted. -fn[T : Compare] try_bubble_sort(arr : ArrayView[T]) -> Bool { +fn[T : Compare] try_bubble_sort(arr : ArraySlice[T]) -> Bool { let max_tries = 8 let mut tries = 0 for i in 1.. Bool { ///| /// Used when the array is small enough (<=16) to avoid recursion overhead. -fn[T : Compare] ArrayView::insertion_sort(arr : ArrayView[T]) -> Unit { +fn[T : Compare] insertion_sort(arr : ArraySlice[T]) -> Unit { for i in 1.. 0 && arr[j - 1] > arr[j]; j = j - 1 { arr.swap(j, j - 1) @@ -137,7 +140,10 @@ fn[T : Compare] ArrayView::insertion_sort(arr : ArrayView[T]) -> Unit { } ///| -fn[T : Compare] partition(arr : ArrayView[T], pivot_index : Int) -> (Int, Bool) { +fn[T : Compare] partition( + arr : ArraySlice[T], + pivot_index : Int, +) -> (Int, Bool) { arr.swap(pivot_index, arr.length() - 1) let pivot = arr[arr.length() - 1] let mut i = 0 @@ -161,7 +167,7 @@ fn[T : Compare] partition(arr : ArrayView[T], pivot_index : Int) -> (Int, Bool) /// It avoids worst case performance by choosing a pivot that is likely to be close to the median. /// /// Returns the pivot index and whether the array is likely sorted. -fn[T : Compare] choose_pivot(arr : ArrayView[T]) -> (Int, Bool) { +fn[T : Compare] choose_pivot(arr : ArraySlice[T]) -> (Int, Bool) { let len = arr.length() let use_median_of_medians = 50 let max_swaps = 4 * 3 @@ -195,7 +201,7 @@ fn[T : Compare] choose_pivot(arr : ArrayView[T]) -> (Int, Bool) { } ///| -fn[T : Compare] heap_sort(arr : ArrayView[T]) -> Unit { +fn[T : Compare] heap_sort(arr : ArraySlice[T]) -> Unit { let len = arr.length() for i = len / 2 - 1; i >= 0; i = i - 1 { sift_down(arr, i) @@ -207,7 +213,7 @@ fn[T : Compare] heap_sort(arr : ArrayView[T]) -> Unit { } ///| -fn[T : Compare] sift_down(arr : ArrayView[T], index : Int) -> Unit { +fn[T : Compare] sift_down(arr : ArraySlice[T], index : Int) -> Unit { let mut index = index let len = arr.length() let mut child = index * 2 + 1 @@ -253,19 +259,19 @@ fn test_sort(f : (Array[Int]) -> Unit) -> Unit raise { ///| test "try_bubble_sort" { let arr = [8, 7, 6, 5, 4, 3, 2, 1] - let sorted = try_bubble_sort(arr[0:8]) + let sorted = try_bubble_sort({ array: arr, start: 0, end: 8 }) inspect(sorted, content="true") assert_eq(arr, [1, 2, 3, 4, 5, 6, 7, 8]) } ///| test "heap_sort" { - test_sort(arr => heap_sort(arr[:])) + test_sort(arr => heap_sort({ array: arr, start: 0, end: arr.length() })) } ///| test "insertion_sort" { - test_sort(arr => ArrayView::insertion_sort(arr[:])) + test_sort(arr => insertion_sort({ array: arr, start: 0, end: arr.length() })) } ///| @@ -287,29 +293,29 @@ test "sort with same pivot optimization" { ///| test "heap_sort coverage" { let arr = [5, 4, 3, 2, 1] - heap_sort(arr[:]) + heap_sort({ array: arr, start: 0, end: arr.length() }) assert_eq(arr, [1, 2, 3, 4, 5]) let arr2 = [1, 2, 3, 4, 5] - heap_sort(arr2[:]) + heap_sort({ array: arr2, start: 0, end: arr2.length() }) assert_eq(arr2, [1, 2, 3, 4, 5]) let arr2 = [1, 2, 3, 4, 5] - heap_sort(arr2[:]) + heap_sort({ array: arr2, start: 0, end: arr2.length() }) assert_eq(arr2, [1, 2, 3, 4, 5]) let arr3 = [5, 5, 5, 5, 1] - heap_sort(arr3[:]) + heap_sort({ array: arr3, start: 0, end: arr3.length() }) assert_eq(arr3, [1, 5, 5, 5, 5]) } ///| test "quick_sort limit check" { let arr = [5, 4, 3, 2, 1] - quick_sort(arr[:], None, 0) + quick_sort({ array: arr, start: 0, end: arr.length() }, None, 0) assert_eq(arr, [1, 2, 3, 4, 5]) let arr2 = [1, 2, 3, 4, 5] - quick_sort(arr2[:], None, 0) + quick_sort({ array: arr2, start: 0, end: arr2.length() }, None, 0) assert_eq(arr2, [1, 2, 3, 4, 5]) let arr3 = [5, 5, 5, 5, 1] - quick_sort(arr3[:], None, 0) + quick_sort({ array: arr3, start: 0, end: arr3.length() }, None, 0) assert_eq(arr3, [1, 5, 5, 5, 5]) } @@ -319,16 +325,16 @@ test "quick_sort with pred check" { for i = 16; i >= 0; i = i - 1 { arr.push(i) } - quick_sort(arr[:], Some(8), 0) + quick_sort({ array: arr, start: 0, end: arr.length() }, Some(8), 0) assert_eq(arr, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]) let arr = [5, 4, 3, 2, 1] - quick_sort(arr[:], Some(3), 0) + quick_sort({ array: arr, start: 0, end: arr.length() }, Some(3), 0) assert_eq(arr, [1, 2, 3, 4, 5]) let arr2 = [1, 2, 3, 4, 5] - quick_sort(arr2[:], Some(3), 0) + quick_sort({ array: arr2, start: 0, end: arr2.length() }, Some(3), 0) assert_eq(arr2, [1, 2, 3, 4, 5]) let arr3 = [5, 5, 5, 5, 1] - quick_sort(arr3[:], Some(3), 0) + quick_sort({ array: arr3, start: 0, end: arr3.length() }, Some(3), 0) assert_eq(arr3, [1, 5, 5, 5, 5]) } @@ -338,36 +344,36 @@ test "quick_sort with unbalanced partitions" { for i = 16; i >= 0; i = i - 1 { arr.push(if i >= 8 { i } else { 8 }) } - quick_sort(arr[:], Some(8), 42) + quick_sort({ array: arr, start: 0, end: arr.length() }, Some(8), 42) assert_eq(arr, [8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 10, 11, 12, 13, 14, 15, 16]) let arr = [5, 4, 3, 2, 1] - quick_sort(arr[:], None, 1) + quick_sort({ array: arr, start: 0, end: arr.length() }, None, 1) assert_eq(arr, [1, 2, 3, 4, 5]) let arr2 = [1, 2, 3, 4, 5] - quick_sort(arr2[:], None, 1) + quick_sort({ array: arr2, start: 0, end: arr2.length() }, None, 1) assert_eq(arr2, [1, 2, 3, 4, 5]) let arr3 = [5, 5, 5, 5, 1] - quick_sort(arr3[:], None, 1) + quick_sort({ array: arr3, start: 0, end: arr3.length() }, None, 1) assert_eq(arr3, [1, 5, 5, 5, 5]) } ///| test "quick_sort with pivot equal to pred" { let arr = [5, 4, 3, 2, 1] - quick_sort(arr[:], Some(3), 0) + quick_sort({ array: arr, start: 0, end: arr.length() }, Some(3), 0) assert_eq(arr, [1, 2, 3, 4, 5]) } ///| test "quick_sort with pred less than all elements" { let arr = [5, 4, 3, 2, 1] - quick_sort(arr[:], Some(0), 0) + quick_sort({ array: arr, start: 0, end: arr.length() }, Some(0), 0) assert_eq(arr, [1, 2, 3, 4, 5]) } ///| test "quick_sort with pred greater than all elements" { let arr = [5, 4, 3, 2, 1] - quick_sort(arr[:], Some(6), 0) + quick_sort({ array: arr, start: 0, end: arr.length() }, Some(6), 0) assert_eq(arr, [1, 2, 3, 4, 5]) } diff --git a/array/sort_by.mbt b/array/sort_by.mbt index 61eff9cb6..7e5e7251e 100644 --- a/array/sort_by.mbt +++ b/array/sort_by.mbt @@ -26,7 +26,7 @@ /// ``` pub fn[T, K : Compare] sort_by_key(self : Array[T], map : (T) -> K) -> Unit { quick_sort_by( - self[:], + { array: self, start: 0, end: self.length() }, (a, b) => map(a).compare(map(b)), None, get_limit(self.length()), @@ -46,12 +46,17 @@ pub fn[T, K : Compare] sort_by_key(self : Array[T], map : (T) -> K) -> Unit { /// assert_eq(arr, [1, 2, 3, 4, 5]) /// ``` pub fn[T] sort_by(self : Array[T], cmp : (T, T) -> Int) -> Unit { - quick_sort_by(self[:], cmp, None, get_limit(self.length())) + quick_sort_by( + { array: self, start: 0, end: self.length() }, + cmp, + None, + get_limit(self.length()), + ) } ///| fn[T] quick_sort_by( - arr : ArrayView[T], + arr : ArraySlice[T], cmp : (T, T) -> Int, pred : T?, limit : Int, @@ -85,7 +90,10 @@ fn[T] quick_sort_by( } let (pivot, partitioned) = partition_by(arr, cmp, pivot_index) was_partitioned = partitioned - balanced = minimum(pivot, len - pivot) >= len / 8 + balanced = { + let diff = len - pivot + (if pivot < diff { pivot } else { diff }) >= len / 8 + } if !balanced { limit -= 1 } @@ -121,7 +129,7 @@ fn[T] quick_sort_by( /// It will only tolerate at most 8 unsorted elements. The time complexity is O(n). /// /// Returns whether the array is sorted. -fn[T] try_bubble_sort_by(arr : ArrayView[T], cmp : (T, T) -> Int) -> Bool { +fn[T] try_bubble_sort_by(arr : ArraySlice[T], cmp : (T, T) -> Int) -> Bool { let max_tries = 8 let mut tries = 0 for i in 1.. Int) -> Bool { /// It will only tolerate at most 8 unsorted elements. The time complexity is O(n). /// /// Returns whether the array is sorted. -fn[T] bubble_sort_by(arr : ArrayView[T], cmp : (T, T) -> Int) -> Unit { +fn[T] bubble_sort_by(arr : ArraySlice[T], cmp : (T, T) -> Int) -> Unit { for i in 1.. 0 && cmp(arr[j - 1], arr[j]) > 0; j = j - 1 { arr.swap(j, j - 1) @@ -156,7 +164,7 @@ fn[T] bubble_sort_by(arr : ArrayView[T], cmp : (T, T) -> Int) -> Unit { ///| fn[T] partition_by( - arr : ArrayView[T], + arr : ArraySlice[T], cmp : (T, T) -> Int, pivot_index : Int, ) -> (Int, Bool) { @@ -183,7 +191,7 @@ fn[T] partition_by( /// It avoids worst case performance by choosing a pivot that is likely to be close to the median. /// /// Returns the pivot index and whether the array is likely sorted. -fn[T] choose_pivot_by(arr : ArrayView[T], cmp : (T, T) -> Int) -> (Int, Bool) { +fn[T] choose_pivot_by(arr : ArraySlice[T], cmp : (T, T) -> Int) -> (Int, Bool) { let len = arr.length() let use_median_of_medians = 50 let max_swaps = 4 * 3 @@ -217,7 +225,7 @@ fn[T] choose_pivot_by(arr : ArrayView[T], cmp : (T, T) -> Int) -> (Int, Bool) { } ///| -fn[T] heap_sort_by(arr : ArrayView[T], cmp : (T, T) -> Int) -> Unit { +fn[T] heap_sort_by(arr : ArraySlice[T], cmp : (T, T) -> Int) -> Unit { let len = arr.length() for i = len / 2 - 1; i >= 0; i = i - 1 { sift_down_by(arr, i, cmp) @@ -230,7 +238,7 @@ fn[T] heap_sort_by(arr : ArrayView[T], cmp : (T, T) -> Int) -> Unit { ///| fn[T] sift_down_by( - arr : ArrayView[T], + arr : ArraySlice[T], index : Int, cmp : (T, T) -> Int, ) -> Unit { @@ -253,19 +261,26 @@ fn[T] sift_down_by( ///| test "try_bubble_sort" { let arr = [8, 7, 6, 5, 4, 3, 2, 1] - let sorted = try_bubble_sort_by(arr[0:8], (a, b) => a - b) + let sorted = try_bubble_sort_by({ array: arr, start: 0, end: 8 }, (a, b) => a - + b) inspect(sorted, content="true") assert_eq(arr, [1, 2, 3, 4, 5, 6, 7, 8]) } ///| test "heap_sort" { - test_sort(arr => heap_sort_by(arr[:], (a, b) => a - b)) + test_sort(arr => heap_sort_by({ array: arr, start: 0, end: arr.length() }, ( + a, + b, + ) => a - b)) } ///| test "bubble_sort" { - test_sort(arr => bubble_sort_by(arr[:], (a, b) => a - b)) + test_sort(arr => bubble_sort_by({ array: arr, start: 0, end: arr.length() }, ( + a, + b, + ) => a - b)) } ///| diff --git a/builtin/array.mbt b/builtin/array.mbt index eece2c625..2a23d8a1e 100644 --- a/builtin/array.mbt +++ b/builtin/array.mbt @@ -206,7 +206,7 @@ pub fn[T] Array::get(self : Array[T], index : Int) -> T? { ///| #intrinsic("%array.unsafe_set") -fn[T] Array::unsafe_set(self : Array[T], idx : Int, val : T) -> Unit { +pub fn[T] Array::unsafe_set(self : Array[T], idx : Int, val : T) -> Unit { self.buffer()[idx] = val } diff --git a/builtin/pkg.generated.mbti b/builtin/pkg.generated.mbti index c22ab52cf..43bf2b831 100644 --- a/builtin/pkg.generated.mbti +++ b/builtin/pkg.generated.mbti @@ -146,6 +146,7 @@ fn[T] Array::unsafe_get(Self[T], Int) -> T #alias(pop_exn, deprecated) fn[T] Array::unsafe_pop(Self[T]) -> T fn[A] Array::unsafe_pop_back(Self[A]) -> Unit +fn[T] Array::unsafe_set(Self[T], Int, T) -> Unit fn[T] Array::windows(Self[T], Int) -> Self[ArrayView[T]] impl[T] Add for Array[T] impl[T : Compare] Compare for Array[T] @@ -158,16 +159,9 @@ impl[X : ToJson] ToJson for Array[X] type ArrayView[T] #alias("_[_]") fn[T] ArrayView::at(Self[T], Int) -> T -#deprecated -fn[T] ArrayView::blit_to(Self[T], Self[T]) -> Unit fn[T] ArrayView::length(Self[T]) -> Int -#alias("_[_]=_") -#deprecated -fn[T] ArrayView::set(Self[T], Int, T) -> Unit #alias("_[_:_]") fn[T] ArrayView::sub(Self[T], start? : Int, end? : Int) -> Self[T] -#deprecated -fn[T] ArrayView::swap(Self[T], Int, Int) -> Unit fn[T] ArrayView::unsafe_get(Self[T], Int) -> T impl[X : ToJson] ToJson for ArrayView[X]