8000 improve Array::makei by illusory0x0 · Pull Request #1753 · moonbitlang/core · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

improve Array::makei #1753

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 0 additions & 35 deletions array/array.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -54,41 +54,6 @@ pub fn push_iter[T](self : Array[T], iter : Iter[T]) -> Unit {
}
}

///|
/// Creates a new array of the specified length, where each element is
/// initialized using an index-based initialization function.
///
/// Parameters:
///
/// * `length` : The length of the new array. If `length` is less than or equal
/// to 0, returns an empty array.
/// * `initializer` : A function that takes an index (starting from 0) and
/// returns a value of type `T`. This function is called for each index to
/// initialize the corresponding element.
///
/// Returns a new array of type `Array[T]` with the specified length, where each
/// element is initialized using the provided function.
///
/// Example:
///
/// ```moonbit
/// test "Array::makei" {
/// let arr = Array::makei(3, fn(i) { i * 2 })
/// inspect!(arr, content="[0, 2, 4]")
/// }
/// ```
pub fn Array::makei[T](length : Int, value : (Int) -> T) -> Array[T] {
if length <= 0 {
[]
} else {
let array = Array::make(length, value(0))
Copy link
Contributor Author
@illusory0x0 illusory0x0 Mar 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I want to avoid redundent fill values Array::make(length, value(0))

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't see why it's redundent: when you have Array::make_uninit, it also has this fill operation, except it's filled with some other value.

The only thing that may change is the performance difference between set and unsafe_set.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Array::make has two fill operations.

Array::makei call Array::make has three fill operations,

pub fn Array::make[T](len : Int, elem : T) -> Array[T] {
  let arr = Array::make_uninit(len) // (1)
  for i in 0..<len {
    arr.unsafe_set(i, elem)  // (2)
  }
  arr
}

pub fn Array::makei[T](length : Int, value : (Int) -> T) -> Array[T] {
  if length <= 0 {
    []
  } else {
    let array = Array::make(length, value(0)) // (2)
    for i in 1..<length {
      array[i] = value(i) // (3)
    }
    array
  }
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Yu-zh Do we have intrinsics for these cases?

for i in 1..<length {
array[i] = value(i)
}
array
}
}

///|
/// Shuffle the array using Knuth shuffle
///
Expand Down
1 change: 0 additions & 1 deletion array/array.mbti
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ impl Array {
from_iter[T](Iter[T]) -> Self[T]
join(Self[String], String) -> String
last[A](Self[A]) -> A?
makei[T](Int, (Int) -> T) -> Self[T]
map_option[A, B](Self[A], (A) -> B?) -> Self[B] //deprecated
push_iter[T](Self[T], Iter[T]) -> Unit
shuffle[T](Self[T], rand~ : (Int) -> Int) -> Self[T]
Expand Down
2 changes: 1 addition & 1 deletion array/array_test.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -567,7 +567,7 @@ test "Array::makei with zero length" {
}

///|
test "Array::makei with negative length" {
test "panic/Array::makei with negative length" {
let arr = Array::makei(-1, fn(i) { i * 2 })
assert_eq!(arr, [])
}
Expand Down
31 changes: 31 additions & 0 deletions builtin/array.mbt
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,37 @@ pub fn Array::make[T](len : Int, elem : T) -> Array[T] {
arr
}

///|
/// Creates a new array of the specified length, where each element is
/// initialized using an index-based initialization function.
///
/// Parameters:
///
/// * `length` : The length of the new array. If `length` is less than or equal
/// to 0, returns an empty array.
/// * `initializer` : A function that takes an index (starting from 0) and
/// returns a value of type `T`. This function is called for each index to
/// initialize the corresponding element.
///
/// Returns a new array of type `Array[T]` with the specified length, where each
/// element is initialized using the provided function.
///
/// Example:
///
/// ```moonbit
/// test "Array::makei" {
/// let arr = Array::makei(3, fn(i) { i * 2 })
/// inspect!(arr, content="[0, 2, 4]")
/// }
/// ```
pub fn Array::makei[T](len : Int, value : (Int) -> T) -> Array[T] {
let arr = Array::make_uninit(len)
for i in 0..<len {
arr.unsafe_set(i, value(i))
}
arr
}

///|
/// Returns the total capacity of the array, which is the number of elements that
/// the array can hold without requiring reallocation of its internal buffer.
Expand Down
1 change: 1 addition & 0 deletions builtin/builtin.mbti
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ impl Array {
iter2[A](Self[A]) -> Iter2[Int, A]
length[T](Self[T]) -> Int
make[T](Int, T) -> Self[T]
makei[T](Int, (Int) -> T) -> Self[T]
map[T, U](Self[T], (T) -> U) -> Self[U]
map_inplace[T](Self[T], (T) -> T) -> Unit
mapi[T, U](Self[T], (Int, T) -> U) -> Self[U]
Expand Down
0