Sign in

    #Builtin Package Documentation

    This package provides the core built-in types, functions, and utilities that are fundamental to MoonBit programming. It includes basic data structures, iterators, assertions, and core language features.

    #Core Types and Functions

    #Assertions and Testing

    MoonBit provides built-in assertion functions for testing:

    ///|
    test "assertions" {
    // Basic equality assertion
    @test.assert_eq(1 + 1, 2)
    @test.assert_eq("hello", "hello")

    // Boolean assertions
    assert_true(5 > 3)
    assert_false(2 > 5)

    // Inequality assertion
    @test.assert_not_eq(1, 2)
    @test.assert_not_eq("foo", "bar")
    }

    #Inspect Function

    The inspect function is used for testing and debugging:

    ///|
    test "inspect usage" {
    let value = 42
    inspect(value, content="42")
    let list = [1, 2, 3]
    debug_inspect(list, content="[1, 2, 3]")
    let result : Result[Int, String] = Ok(100)
    debug_inspect(result, content="Ok(100)")
    }

    #Result Type

    The Result[T, E] type represents operations that can succeed or fail:

    ///|
    test "result type" {
    fn divide(a : Int, b : Int) -> Result[Int, String] {
    if b == 0 {
    Err("Division by zero")
    } else {
    Ok(a / b)
    }
    }

    // Success case
    let result1 = divide(10, 2)
    debug_inspect(result1, content="Ok(5)")

    // Error case
    let result2 = divide(10, 0)
    debug_inspect(result2, content="Err(\"Division by zero\")")

    // Pattern matching on Result
    match result1 {
    Ok(value) => inspect(value, content="5")
    Err(_) => inspect(false, content="true")
    }
    }

    #Option Type

    The Option[T] type represents values that may or may not exist:

    ///|
    test "option type" {
    fn find_first_even(numbers : Array[Int]) -> Int? {
    for num in numbers {
    if num % 2 == 0 {
    return Some(num)
    }
    }
    None
    }

    // Found case
    let result1 = find_first_even([1, 3, 4, 5])
    debug_inspect(result1, content="Some(4)")

    // Not found case
    let result2 = find_first_even([1, 3, 5])
    debug_inspect(result2, content="None")

    // Pattern matching on Option
    match result1 {
    Some(value) => inspect(value, content="4")
    None => inspect(false, content="true")
    }
    }

    #Iterator Type

    The Iter[T] type provides lazy iteration over sequences:

    ///|
    test "iterators" {
    // Create iterator from array
    let numbers = [1, 2, 3, 4, 5]
    let iter = numbers.iter()

    // Collect back to array
    let collected = iter.collect()
    debug_inspect(collected, content="[1, 2, 3, 4, 5]")

    // Map transformation
    let doubled = numbers.iter().map(fn(x) { x * 2 }).collect()
    debug_inspect(doubled, content="[2, 4, 6, 8, 10]")

    // Filter elements
    let evens = numbers.iter().filter(fn(x) { x % 2 == 0 }).collect()
    debug_inspect(evens, content="[2, 4]")

    // Fold (reduce) operation
    let sum = numbers.iter().fold(init=0, fn(acc, x) { acc + x })
    inspect(sum, content="15")
    }

    #Array and FixedArray

    Built-in array types for storing collections:

    ///|
    test "arrays" {
    // Dynamic arrays
    let arr1 = Array()
    arr1.push(1)
    arr1.push(2)
    arr1.push(3)
    debug_inspect(arr1, content="[1, 2, 3]")

    // Array from literal
    let arr2 = [10, 20, 30]
    debug_inspect(arr2, content="[10, 20, 30]")

    // Array operations
    let length = arr2.length()
    inspect(length, content="3")
    let first = arr2[0]
    inspect(first, content="10")
    }

    Fixed-size array for storing collections of constant size:

    ///|
    test "fixed arrays" {
    // FixedArray from literal
    let fixed_arr : FixedArray[Int] = [10, 20, 30]
    debug_inspect(
    fixed_arr,
    content=(
    #|<FixedArray: [10, 20, 30]>
    ),
    )

    // FixedArray operations
    let length = fixed_arr.length()
    inspect(length, content="3")
    let first = fixed_arr[0]
    inspect(first, content="10")
    }

    #Views (Zero-Copy Slices)

    Each owning container has a matching view type created with the a[start:end] slice syntax. A view is a small record holding a reference to the shared storage plus its window bounds, so slicing never copies the elements:

    direction: right owners: "Owning containers" { arr: "Array[T] / FixedArray[T] / ReadOnlyArray[T]" bytes: "Bytes" str: "String" } views: "Zero-copy views (shared storage + window bounds)" { arrview: "ArrayView[T]" bytesview: "BytesView" strview: "StringView" } owners.arr -> views.arrview: "a[start:end]" owners.bytes -> views.bytesview: "b[start:end]" owners.str -> views.strview: "s[start:end]"

    Views are ideal for rest patterns ([first, .. rest]) and for passing sub-sequences without allocation; functions taking a view also accept the owning container through implicit conversion. Note that the s[start:end] slice syntax on String panics when a boundary would split a UTF-16 surrogate pair:

    ///|
    test "views are zero copy" {
    let arr = [1, 2, 3, 4, 5]
    let view = arr[1:4]
    @test.assert_eq(view.length(), 3)
    @test.assert_eq(view[0], 2)
    view is [first, .. rest]
    @test.assert_eq(first, 2)
    @test.assert_eq(rest.length(), 2)
    }

    #String Operations

    Basic string functionality:

    ///|
    test "strings" {
    let text = "Hello, World!"

    // String length
    let len = text.length()
    inspect(len, content="13")

    // String concatenation
    let greeting = "Hello" + ", " + "World!"
    inspect(greeting, content="Hello, World!")

    // String comparison
    let equal = "test" == "test"
    inspect(equal, content="true")
    }

    #StringBuilder

    Efficient string building:

    ///|
    test "string builder" {
    let builder = StringBuilder()
    builder.write_string("Hello")
    builder.write_string(", ")
    builder.write_string("World!")
    let result = builder.to_string()
    inspect(result, content="Hello, World!")
    }

    #JSON Support

    Basic JSON operations:

    ///|
    test "json" {
    // JSON values
    let json_null = null
    @debug.debug_inspect(json_null, content="Null")
    let json_bool = true.to_json()
    @debug.debug_inspect(json_bool, content="True")
    let json_number = (42 : Int).to_json()
    @debug.debug_inspect(json_number, content="Number(42)")
    let json_string = "hello".to_json()
    @debug.debug_inspect(
    json_string,
    content=(
    #|String("hello")
    ),
    )
    }

    #Comparison Operations

    Built-in comparison operators:

    ///|
    test "comparisons" {
    // Equality
    inspect(5 == 5, content="true")
    inspect(5 != 3, content="true")

    // Ordering
    inspect(3 < 5, content="true")
    inspect(5 > 3, content="true")
    inspect(5 >= 5, content="true")
    inspect(3 <= 5, content="true")

    // String comparison
    inspect("apple" < "banana", content="true")
    inspect("hello" == "hello", content="true")
    }

    #Utility Functions

    Helpful utility functions:

    ///|
    test "utilities" {
    // Identity and ignore
    let value = 42
    ignore(value) // Discards the value

    // Boolean negation
    let result = !false
    inspect(result, content="true")

    // Physical equality (reference equality)
    let arr1 = [1, 2, 3]
    let arr2 = [1, 2, 3]
    let same_ref = arr1
    inspect(physical_equal(arr1, arr2), content="false") // Different objects
    inspect(physical_equal(arr1, same_ref), content="true") // Same reference
    }

    #Error Handling

    Basic error handling with panic and abort:

    ///|
    test "error handling" {
    // This would panic in a real scenario, but we demonstrate the concept
    fn safe_divide(a : Int, b : Int) -> Int {
    if b == 0 {
    // In real code: panic()
    // For testing, we return a default value
    0
    } else {
    a / b
    }
    }

    let result = safe_divide(10, 2)
    inspect(result, content="5")
    let safe_result = safe_divide(10, 0)
    inspect(safe_result, content="0")
    }

    #Best Practices

    1. Use assertions liberally in tests: They help catch bugs early and document expected behavior
    2. Prefer Result over exceptions: For recoverable errors, use Result[T, E] instead of panicking
    3. Use Option for nullable values: Instead of null pointers, use Option[T]
    4. Leverage iterators for data processing: They provide composable and efficient data transformations
    5. Use StringBuilder for string concatenation: More efficient than repeated string concatenation
    6. Pattern match on Result and Option: Handle both success and failure cases explicitly

    #Performance Notes

    • Arrays have O(1) access and O(1) amortized append
    • Iterators are lazy and don't allocate intermediate collections
    • StringBuilder is more efficient than string concatenation for building large strings
    • Physical equality is faster than structural equality but should be used carefully

    Add

    pub(open) trait Add {
    fn add(Self, Self) -> Self
    }

    types implementing this trait can use the + operator
    impl Add for Byte
    impl Add for Int
    impl Add for Int64
    impl Add for UInt
    impl Add for UInt16
    impl Add for UInt64
    impl Add for Double
    impl Add for String
    impl Add for FixedArray[T]
    impl Add for Bytes
    impl Add for StringView

    BitAnd

    pub(open) trait BitAnd {
    fn land(Self, Self) -> Self
    }

    types implementing this trait can use the & operator
    impl BitAnd for Byte
    impl BitAnd for Int
    impl BitAnd for Int64
    impl BitAnd for UInt
    impl BitAnd for UInt16
    impl BitAnd for UInt64

    BitOr

    pub(open) trait BitOr {
    fn lor(Self, Self) -> Self
    }

    types implementing this trait can use the | operator
    impl BitOr for Byte
    impl BitOr for Int
    impl BitOr for Int64
    impl BitOr for UInt
    impl BitOr for UInt16
    impl BitOr for UInt64

    BitXOr

    pub(open) trait BitXOr {
    fn lxor(Self, Self) -> Self
    }

    types implementing this trait can use the ^ operator
    impl BitXOr for Byte
    impl BitXOr for Int
    impl BitXOr for Int64
    impl BitXOr for UInt
    impl BitXOr for UInt16
    impl BitXOr for UInt64

    Compare

    pub(open) trait Compare : Eq {
    fn compare(Self, Self) -> Int
    fn op_lt(Self, Self) -> Bool = _
    fn op_gt(Self, Self) -> Bool = _
    fn op_le(Self, Self) -> Bool = _
    fn op_ge(Self, Self) -> Bool = _
    }

    Trait for types whose elements are ordered

    The return value of [compare] is:
    • zero, if the two arguments are equal
    • negative, if the first argument is smaller
    • positive, if the first argument is greater
    impl Compare for Unit
    impl Compare for Bool
    impl Compare for Byte
    impl Compare for Char
    impl Compare for Int
    impl Compare for Int64
    impl Compare for UInt
    impl Compare for UInt16
    impl Compare for UInt64
    impl Compare for Double
    impl Compare for String
    impl Compare for Option[X]
    impl Compare for Result[T, E]
    impl Compare for FixedArray[T]
    impl Compare for Bytes
    impl Compare for Tuple2[T0, T1]
    impl Compare for Tuple3[T0, T1, T2]
    impl Compare for Tuple4[T0, T1, T2, T3]
    impl Compare for Tuple5[T0, T1, T2, T3, T4]
    impl Compare for Tuple6[T0, T1, T2, T3, T4, T5]
    impl Compare for Tuple7[T0, T1, T2, T3, T4, T5, T6]
    impl Compare for Tuple8[T0, T1, T2, T3, T4, T5, T6, T7]
    impl Compare for Tuple9[T0, T1, T2, T3, T4, T5, T6, T7, T8]
    impl Compare for Tuple10[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9]
    impl Compare for Tuple11[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]
    impl Compare for Tuple12[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]
    impl Compare for Tuple13[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]
    impl Compare for Tuple14[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]
    impl Compare for Tuple15[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]
    impl Compare for Tuple16[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]

    Default

    pub(open) trait Default {
    fn default() -> Self
    }

    Trait for types with a default value
    impl Default for Unit
    impl Default for Bool
    impl Default for Byte
    impl Default for Char
    impl Default for Int
    impl Default for Int64
    impl Default for UInt16
    impl Default for UInt64
    impl Default for Double
    impl Default for String
    impl Default for Option[X]
    impl Default for FixedArray[X]
    impl Default for Bytes

    Div

    pub(open) trait Div {
    fn div(Self, Self) -> Self
    }

    types implementing this trait can use the / operator
    impl Div for Byte
    impl Div for Int
    impl Div for Int64
    impl Div for UInt
    impl Div for UInt16
    impl Div for UInt64
    impl Div for Double
    pub(open) trait Eq {
    fn equal(Self, Self) -> Bool
    fn not_equal(Self, Self) -> Bool = _
    }

    Trait for types whose elements can test for equality
    impl Eq for Unit
    impl Eq for Bool
    impl Eq for Byte
    impl Eq for Char
    impl Eq for Int
    impl Eq for Int64
    impl Eq for UInt
    impl Eq for UInt16
    impl Eq for UInt64
    impl Eq for Double
    impl Eq for String
    impl Eq for Option[X]
    impl Eq for Result[T, E]
    impl Eq for FixedArray[T]
    impl Eq for ReadOnlyArray[T]
    impl Eq for Bytes
    impl Eq for Tuple2[T0, T1]
    impl Eq for Tuple3[T0, T1, T2]
    impl Eq for Tuple4[T0, T1, T2, T3]
    impl Eq for Tuple5[T0, T1, T2, T3, T4]
    impl Eq for Tuple6[T0, T1, T2, T3, T4, T5]
    impl Eq for Tuple7[T0, T1, T2, T3, T4, T5, T6]
    impl Eq for Tuple8[T0, T1, T2, T3, T4, T5, T6, T7]
    impl Eq for Tuple9[T0, T1, T2, T3, T4, T5, T6, T7, T8]
    impl Eq for Tuple10[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9]
    impl Eq for Tuple11[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]
    impl Eq for Tuple12[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]
    impl Eq for Tuple13[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]
    impl Eq for Tuple14[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]
    impl Eq for Tuple15[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]
    impl Eq for Tuple16[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]
    impl Eq for BytesView
    impl Eq for StringView

    Hash

    pub(open) trait Hash {
    fn hash_combine(Self, Hasher) -> Unit
    fn hash(Self) -> Int = _
    }

    Trait for types that can be hashed

    The hash method should return a hash value for the type, which is used in hash tables and other data structures. The hash_combine method is used to combine the hash of the current value with another hash value, typically used to hash composite types.

    When two values are equal according to the Eq trait, they should produce the same hash value.

    The hash method does not need to be implemented if hash_combine is implemented, When implemented separately, hash does not need to produce a hash value that is consistent with hash_combine.
    impl Hash for Unit
    impl Hash for Bool
    impl Hash for Byte
    impl Hash for Char
    impl Hash for Int
    impl Hash for Int64
    impl Hash for UInt
    impl Hash for UInt16
    impl Hash for UInt64
    impl Hash for Double
    impl Hash for String
    impl Hash for Option[X]
    impl Hash for Result[T, E]
    impl Hash for FixedArray[T]
    impl Hash for ReadOnlyArray[T]
    impl Hash for Bytes
    impl Hash for Tuple2[A, B]
    impl Hash for Tuple3[A, B, C]
    impl Hash for Tuple4[A, B, C, D]
    impl Hash for Tuple5[A, B, C, D, E]
    impl Hash for Tuple6[A, B, C, D, E, F]
    impl Hash for Tuple7[A, B, C, D, E, F, G]
    impl Hash for BytesView
    impl Hash for StringView

    Logger

    pub(open) trait Logger {
    fn write_string(Self, String) -> Unit = _
    #deprecated("use `write_view` instead")
    fn write_substring(Self, String, Int, Int) -> Unit = _
    fn write_view(Self, StringView) -> Unit = _
    fn write_char(Self, Char) -> Unit = _
    fn write_string_interpolation(Self, &Show) -> Unit = _
    fn write(Self, &Show) -> Unit = _
    }

    Trait for append-only text sinks used by Show implementations.

    A logger receives formatted output without requiring callers to allocate a complete String first.

    Mod

    pub(open) trait Mod {
    fn mod(Self, Self) -> Self
    }

    types implementing this trait can use the % operator
    impl Mod for Byte
    impl Mod for Int
    impl Mod for Int64
    impl Mod for UInt
    impl Mod for UInt16
    impl Mod for UInt64
    impl Mod for Double

    Mul

    pub(open) trait Mul {
    fn mul(Self, Self) -> Self
    }

    types implementing this trait can use the * operator
    impl Mul for Byte
    impl Mul for Int
    impl Mul for Int64
    impl Mul for UInt
    impl Mul for UInt16
    impl Mul for UInt64
    impl Mul for Double

    Neg

    pub(open) trait Neg {
    fn neg(Self) -> Self
    }

    types implementing this trait can use the unary - operator
    impl Neg for Int
    impl Neg for Int64
    impl Neg for Double

    Shl

    pub(open) trait Shl {
    fn shl(Self, Int) -> Self
    }

    types implementing this trait can use the << operator
    impl Shl for Byte
    impl Shl for Int
    impl Shl for Int64
    impl Shl for UInt
    impl Shl for UInt16
    impl Shl for UInt64

    Show

    #must_implement_one(output, to_string)
    pub(open) trait Show {
    fn output(Self, &Logger) -> Unit = _
    fn to_string(Self) -> String = _
    }

    Trait for types that can be converted to String
    impl Show for Unit
    impl Show for Bool
    impl Show for Byte
    impl Show for Char
    impl Show for Int
    impl Show for Int64
    impl Show for UInt
    impl Show for UInt16
    impl Show for UInt64
    impl Show for Double
    impl Show for String
    impl Show for Option[X]
    impl Show for Result[T, E]
    impl Show for FixedArray[X]
    impl Show for ReadOnlyArray[T]
    impl Show for Bytes
    impl Show for Tuple2[A, B]
    impl Show for Tuple3[A, B, C]
    impl Show for Tuple4[A, B, C, D]
    impl Show for Tuple5[A, B, C, D, E]
    impl Show for Tuple6[A, B, C, D, E, F]
    impl Show for Tuple7[A, B, C, D, E, F, G]
    impl Show for Tuple8[T0, T1, T2, T3, T4, T5, T6, T7]
    impl Show for Tuple9[T0, T1, T2, T3, T4, T5, T6, T7, T8]
    impl Show for Tuple10[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9]
    impl Show for Tuple11[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10]
    impl Show for Tuple12[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11]
    impl Show for Tuple13[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12]
    impl Show for Tuple14[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13]
    impl Show for Tuple15[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14]
    impl Show for Tuple16[T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15]
    impl Show for BytesView
    impl Show for StringView

    Shr

    pub(open) trait Shr {
    fn shr(Self, Int) -> Self
    }

    types implementing this trait can use the >> operator
    impl Shr for Byte
    impl Shr for Int
    impl Shr for Int64
    impl Shr for UInt
    impl Shr for UInt16
    impl Shr for UInt64

    Sub

    pub(open) trait Sub {
    fn sub(Self, Self) -> Self
    }

    types implementing this trait can use the - operator
    impl Sub for Byte
    impl Sub for Int
    impl Sub for Int64
    impl Sub for UInt
    impl Sub for UInt16
    impl Sub for UInt64
    impl Sub for Double

    ToJson

    pub(open) trait ToJson {
    fn to_json(Self) -> Json
    }

    Trait for types that can be converted to Json
    impl ToJson for Unit
    impl ToJson for Bool
    impl ToJson for Byte
    impl ToJson for Char
    impl ToJson for Int
    impl ToJson for Int64
    impl ToJson for UInt
    impl ToJson for UInt16
    impl ToJson for UInt64
    impl ToJson for Double
    impl ToJson for String
    impl ToJson for Option[T]
    impl ToJson for Result[Ok, Err]
    impl ToJson for FixedArray[X]
    impl ToJson for ReadOnlyArray[T]
    impl ToJson for Bytes
    impl ToJson for Tuple2[A, B]
    impl ToJson for Tuple3[A, B, C]
    impl ToJson for Tuple4[A, B, C, D]
    impl ToJson for Tuple5[A, B, C, D, E]
    impl ToJson for Tuple6[A, B, C, D, E, F]
    impl ToJson for Tuple7[A, B, C, D, E, F, G]
    impl ToJson for Tuple8[A, B, C, D, E, F, G, H]
    impl ToJson for Tuple9[A, B, C, D, E, F, G, H, I]
    impl ToJson for Tuple10[A, B, C, D, E, F, G, H, I, J]
    impl ToJson for Tuple11[A, B, C, D, E, F, G, H, I, J, K]
    impl ToJson for Tuple12[A, B, C, D, E, F, G, H, I, J, K, L]
    impl ToJson for Tuple13[A, B, C, D, E, F, G, H, I, J, K, L, M]
    impl ToJson for Tuple14[A, B, C, D, E, F, G, H, I, J, K, L, M, N]
    impl ToJson for Tuple15[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O]
    impl ToJson for Tuple16[A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P]
    impl ToJson for BytesView

    ToStringView

    pub trait ToStringView {
    fn to_string_view(Self) -> StringView
    }

    Trait for values that can be viewed as StringView.

    Types implementing this trait provide zero-copy access to string-like data.

    BenchError

    #deprecated("This type is deprecated.")
    pub(all) suberror BenchError {
    BenchError(String)
    }

    Failure

    pub(all) suberror Failure {
    Failure(String)
    } derive(Show, ToJson)

    Represents a generic test failure type used primarily in test assertions and validations.

    Since this is a type definition using suberror syntax, it creates an error type Failure that wraps a String value containing the failure message.

    Parameters:

    • message : A string describing the nature of the failure.

    Example:

    test {
    let err : Failure = Failure("Test assertion failed")
    match err {
    Failure(msg) => inspect(msg, content="Test assertion failed")
    }
    @json.json_inspect(err, content=["Failure", "Test assertion failed"])
    }

    Failure::to_json

    fn Failure::to_json(Failure) -> Json

    Failure::to_string

    fn Failure::to_string(self : Failure) -> String

    InspectError

    pub(all) suberror InspectError {
    InspectError(String)
    }

    Represents an error type used by the inspect function to indicate failures in value inspection. Contains a string message describing the nature of the inspection failure.

    Returns a type constructor that creates an error type from a string message.

    Example:

    test {
    let x : Int = 42
    inspect(x, content="42") // A mismatch would raise InspectError with a detailed message
    }

    SnapshotError

    pub(all) suberror SnapshotError {
    SnapshotError(String)
    }

    Represents an error that occurs during snapshot testing. Contains a string message describing the error.

    Used internally by the test driver to handle snapshot-related errors. Not intended for direct use by end users.

    Example:

    test {
    let err : SnapshotError = SnapshotError("failed to load snapshot")
    match err {
    SnapshotError(msg) => @test.assert_eq(msg, "failed to load snapshot")
    }
    }

    ArgsLoc

    pub(all) struct ArgsLoc(Array[SourceLoc?])

    Represents a type for storing argument locations in source code. It is an array of optional source locations, where each element corresponds to an argument's location in the source code. Used internally by the compiler for error reporting and debugging purposes.
    impl Show for ArgsLoc

    ArgsLoc::to_json

    fn ArgsLoc::to_json(self : ArgsLoc) -> String

    Converts an array of optional source locations to its JSON string representation. Each location in the array is either represented as a JSON object with filename, start_line, start_column, end_line and end_column fields if present, or "null" if absent.

    Parameters:

    • self : The array of optional source locations to be converted.

    Returns a JSON array string where each element is either a JSON object describing a source location or "null".

    ArgsLoc::to_string

    fn ArgsLoc::to_string(self : ArgsLoc) -> String

    Array

    type Array[T]

    An Array is a collection of values that supports random access and can grow in size.
    impl Add for Array[T]
    impl Compare for Array[T]
    impl Default for Array[T]
    impl Eq for Array[T]
    impl Hash for Array[T]
    impl Show for Array[X]
    impl ToJson for Array[X]

    Array::Array

    fn[T] Array::Array(capacity? : Int) -> Array[T]

    Creates a new empty array with an optional initial capacity.

    Parameters:

    • capacity : The initial capacity of the array. If 0 (default), creates an array with minimum capacity. Must be non-negative.

    Returns a new empty array of type Array[T] with the specified initial capacity.

    Example:

    test {
    let arr : Array[Int] = Array(capacity=10)
    inspect(arr.length(), content="0")
    inspect(arr.capacity(), content="10")
    let arr : Array[Int] = Array()
    inspect(arr.length(), content="0")
    }

    Array::add

    fn[T] Array::add(self : Array[T], other : Array[T]) -> Array[T]

    Array::all

    #alias(every)
    fn[T] Array::all(self : Array[T], f : (T) -> Bool raise?) -> Bool raise?

    Checks whether all elements satisfy the predicate.

    Example

    test {
    let arr = [1, 2, 3, 4, 5]
    assert_true(arr.all(x => x < 6))
    assert_false(arr.all(x => x < 5))
    }

    Array::any

    #alias(exists)
    fn[T] Array::any(self : Array[T], f : (T) -> Bool raise?) -> Bool raise?

    Checks whether any element satisfies the predicate.

    Example

    test {
    let arr = [1, 2, 3, 4, 5]
    assert_true(arr.any(x => x < 6))
    assert_false(arr.any(x => x < 1))
    }

    Array::append

    fn[T] Array::append(self : Array[T], other : ArrayView[T]) -> Unit

    Appends all elements from one array to the end of another array. The elements are added in-place, modifying the original array.

    Parameters:

    • self : The array to append to.
    • other : The array whose elements will be appended.

    Example:

    test {
    let v1 = [1, 2, 3]
    let v2 : ReadOnlyArray[Int] = [4, 5, 6]
    v1.append(v2)
    debug_inspect(v1, content="[1, 2, 3, 4, 5, 6]")
    let v1 = [1, 2, 3]
    let v2 : ReadOnlyArray[Int] = []
    v1.append(v2)
    debug_inspect(v1, content="[1, 2, 3]")
    }

    Array::at

    #alias("_[_]")
    fn[T] Array::at(self : Array[T], index : Int) -> T

    Retrieves an element from the array at the specified index.

    Parameters:

    • array : The array to get the element from.
    • index : The position in the array from which to retrieve the element.

    Returns the element at the specified index.

    Throws a panic if the index is negative or greater than or equal to the length of the array.

    Example:

    test {
    let arr : Array[Int] = [1, 2, 3]
    inspect(arr[1], content="2")
    }

    fn[T : Compare + Eq] Array::binary_search(self : Array[T], value : T) -> Result[Int, Int]

    Performs a binary search on a sorted array to find the index of a given element.

    Example

    test {
    let v = [3, 4, 5]
    let result = v.binary_search(3)
    @test.assert_eq(result, Ok(0)) // The element 3 is found at index 0
    }

    Arguments

    • self: The array in which to perform the search.
    • value: The element to search for in the array.

    Returns

    • Result[Int, Int]: If the element is found, an Ok variant is returned, containing the index of the matching element in the array. If there are multiple matches, the leftmost match will be returned. If the element is not found, an Err variant is returned, containing the index where the element could be inserted to maintain the sorted order.

    Notes

    • Ensure that the array is sorted in increasing order before calling this function.
    • If the array is not sorted, the returned result is undefined and should not be relied on.

    Array::binary_search_by

    fn[T] Array::binary_search_by(self : Array[T], cmp : (T) -> Int raise?) -> Result[Int, Int] raise?

    Performs a binary search on a sorted array using a custom comparison function. Returns the position of the matching element if found, or the position where the element could be inserted while maintaining the sorted order.

    Parameters:

    • array : The sorted array to search in.
    • comparator : A function that compares each element with the target value, returning:
    • A negative integer if the element is less than the target
    • Zero if the element equals the target
    • A positive integer if the element is greater than the target

    Returns a Result containing either:

    • Ok(index) if a matching element is found at position index
    • Err(index) if no match is found, where index is the position where the element could be inserted

    Example:

    test {
    let arr = [1, 3, 5, 7, 9]
    let find_3 = arr.binary_search_by(x => x.compare(3))
    debug_inspect(find_3, content="Ok(1)")
    let find_4 = arr.binary_search_by(x => x.compare(4))
    debug_inspect(find_4, content="Err(2)")
    }

    Notes:

    • Assumes the array is sorted according to the ordering implied by the comparison function
    • For multiple matches, returns the leftmost matching position
    • Returns an insertion point that maintains the sort order when no match is found

    Array::blit_to

    fn[A] Array::blit_to(self : Array[A], dst : Array[A], len? : Int, src_offset? : Int, dst_offset? : Int) -> Unit

    Copies elements from one array to another array, with support for growing the destination array if needed. The arrays may overlap, in which case the copy is performed in a way that preserves the data.

    Parameters:

    • self : The array to copy elements from.
    • dst : The array to copy elements to. Will be automatically grown if needed to accommodate the copied elements.
    • len : The number of elements to copy.
    • src_offset : Starting index in the source array. Defaults to 0.
    • dst_offset : Starting index in the destination array. Defaults to

    Example:

    test {
    let src = [1, 2, 3, 4, 5]
    let dst = [0, 0]
    src[:3].blit_to(dst, dst_offset=1)
    @debug.debug_inspect(dst, content="[0, 1, 2, 3]")
    }

    Panics if:

    • len is negative
    • src_offset is negative
    • dst_offset is negative
    • dst_offset exceeds the length of destination array
    • src_offset + len exceeds the length of source array

    Array::capacity

    fn[T] Array::capacity(self : Array[T]) -> Int

    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.

    Parameters:

    • array : The array whose capacity is to be determined.

    Returns the current capacity of the array as an integer.

    NOTE: The capacity of an array may not be consistent across different backends and/or different versions of the MoonBit compiler/core.

    Array::chunk_by

    fn[T] Array::chunk_by(self : Array[T], pred : (T, T) -> Bool raise?) -> Array[ArrayView[T]] raise?

    Groups consecutive elements of the array into chunks where adjacent elements satisfy the given predicate function.

    Parameters:

    • array : The array to be chunked.
    • predicate : A function that takes two adjacent elements and returns true if they should be in the same chunk, false otherwise.

    Returns an array of views, where each view is a chunk of consecutive elements that satisfy the predicate with their adjacent elements.

    Example:

    test {
    let v = [1, 1, 2, 3, 2, 3, 2, 3, 4]
    let chunks = v.chunk_by((x, y) => x <= y)
    debug_inspect(
    chunks,
    content=(
    #|[
    #| <ArrayView: [1, 1, 2, 3]>,
    #| <ArrayView: [2, 3]>,
    #| <ArrayView: [2, 3, 4]>,
    #|]
    ),
    )
    let v : Array[Int] = []
    debug_inspect(v.chunk_by((x, y) => x <= y), content="[]")
    }

    Array::chunks

    fn[T] Array::chunks(self : Array[T], size : Int) -> Array[ArrayView[T]]

    Divides an array into chunks (views) of the specified size.

    Parameters:

    • array : The array to be divided into chunks.
    • size : The size of each chunk. Must be a positive integer, otherwise it will panic.

    Returns an array of views, where each view is a chunk containing consecutive elements of the original array. If the length of the original array is not divisible by the chunk size, the last chunk will contain fewer elements.

    Example:

    test {
    let arr = [1, 2, 3, 4, 5]
    let chunks = arr.chunks(2)
    debug_inspect(
    chunks,
    content=(
    #|[<ArrayView: [1, 2]>, <ArrayView: [3, 4]>, <ArrayView: [5]>]
    ),
    )
    let arr : Array[Int] = []
    debug_inspect(arr.chunks(3), content="[]")
    }

    Array::clear

    fn[T] Array::clear(self : Array[T]) -> Unit

    Clears the array, removing all values.

    This method has no effect on the allocated capacity of the array, only setting the length to 0.

    Emptying an array is a removal like any other: the buffer keeps referring to the elements that were in it, and they are released once later pushes reuse those slots, the buffer grows, or the array is dropped. Call Array::release_unused to overwrite them at once, or Array::shrink_to_fit to hand the buffer back entirely. On the JavaScript backend the removed elements are released right away and Array::release_unused is a no-op.

    Example

    test {
    let v = [3, 4, 5]
    v.clear()
    @test.assert_eq(v.length(), 0)
    }

    Array::compare

    fn[T : Compare + Eq] Array::compare(self : Array[T], other : Array[T]) -> Int

    Array::contains

    fn[T : Eq] Array::contains(self : Array[T], value : T) -> Bool

    Checks whether the array contains an element equal to the given value.

    Parameters:

    • array : The array to search in.
    • value : The value to search for.

    Returns true if the array contains an element equal to the given value, false otherwise.

    Example:

    test {
    let arr = [1, 2, 3, 4, 5]
    inspect(arr.contains(3), content="true")
    inspect(arr.contains(6), content="false")
    let arr : Array[Int] = []
    inspect(arr.contains(1), content="false")
    }

    Array::copy

    #alias(clone, deprecated="`clone` is deprecated, use `copy` instead")
    fn[T] Array::copy(self : Array[T]) -> Array[T]

    Creates and returns a new array with a copy of all elements from the input array.

    Parameters:

    • array : The array to be copied.

    Returns a new array containing all elements from the original array.

    Example:

    test {
    let original = [1, 2, 3]
    let copied = original.copy()
    @debug.debug_inspect(copied, content="[1, 2, 3]")
    inspect(physical_equal(original, copied), content="false")
    }

    Array::count

    fn[T : Eq] Array::count(self : Array[T], value : T) -> Int

    Counts how many elements in the array are equal to value.

    Example

    test {
    let arr = [1, 2, 1, 3, 1]
    inspect(arr.count(1), content="3")
    inspect(arr.count(4), content="0")
    }

    Array::count_if

    fn[T] Array::count_if(self : Array[T], f : (T) -> Bool raise?) -> Int raise?

    Counts how many elements in the array satisfy the predicate.

    Example

    test {
    let arr = [1, 2, 3, 4, 5]
    inspect(arr.count_if(x => x % 2 == 0), content="2")
    }

    Array::dedup

    fn[T : Eq] Array::dedup(self : Array[T]) -> Unit

    Removes consecutive duplicate elements from an array in-place, using equality comparison. The first occurrence of each element is retained while subsequent equal elements are removed.

    Parameters:

    • array : The array to remove duplicates from. Must contain elements that implement the Eq trait for equality comparison.

    Example:

    test {
    let arr = [1, 2, 2, 3, 3, 3, 2]
    arr.dedup()
    debug_inspect(arr, content="[1, 2, 3, 2]")
    let arr = [1, 2, 2, 2, 3, 3]
    arr.dedup()
    debug_inspect(arr, content="[1, 2, 3]")
    let arr : Array[Int] = []
    arr.dedup()
    debug_inspect(arr, content="[]")
    }

    Note: For best results when removing all duplicates regardless of position, sort the array before calling this function. When used on an unsorted array, this function only removes consecutive duplicates.

    Array::drain

    fn[T] Array::drain(self : Array[T], begin : Int, end : Int) -> Array[T]

    Removes the specified range from the array and returns it.

    This functions returns an array range from begin to end [begin, end)

    This function will panic if the index is out of bounds.

    Example

    test {
    let v = [3, 4, 5]
    let vv = v.drain(1, 2) // vv = [4], v = [3, 5]
    @test.assert_eq(vv, [4])
    @test.assert_eq(v, [3, 5])
    }

    The end - begin slots vacated at the end of the array are not cleared: each keeps whatever it held before the survivors were shifted down, so a drained element or a duplicate reference to a survivor stays reachable there until the slot is reused, the buffer grows, or the array is dropped. Call Array::release_unused to overwrite them at once, or Array::shrink_to_fit to move the survivors into an exact-size buffer.

    Array::each

    fn[T] Array::each(self : Array[T], f : (T) -> Unit raise?) -> Unit raise?

    Iterates through each element of the array in order, applying the given function to each element.

    Parameters:

    • array : The array to iterate over.
    • function : A function that takes a single element of type T as input and returns Unit. This function is applied to each element of the array in order.

    Example:

    test {
    let arr = [1, 2, 3]
    let mut sum = 0
    arr.each(x => sum x)
    inspect(sum, content="6")
    }
    This method uses the array iterator. Structural mutations during traversal are unsupported: appended elements are not visited, and shrinking the array with operations such as remove, truncate, clear, or drain may cause later iterator steps to fail.

    Array::eachi

    fn[T] Array::eachi(self : Array[T], f : (Int, T) -> Unit raise?) -> Unit raise?

    Iterates over the elements of the array with index.

    Example

    test {
    let v = [3, 4, 5]
    let mut sum = 0
    v.eachi((i, x) => sum x + i)
    inspect(sum, content="15")
    }

    Array::ends_with

    fn[T : Eq] Array::ends_with(self : Array[T], suffix : ArrayView[T]) -> Bool

    Tests if an array ends with the given suffix.

    Parameters:

    • self : The array to check.
    • suffix : The array to test against.

    Returns true if the array ends with the given suffix, false otherwise.

    Example:

    test {
    let arr = [1, 2, 3, 4, 5]
    inspect(arr.ends_with([4, 5]), content="true")
    inspect(arr.ends_with([3, 4]), content="false")
    inspect(arr.ends_with([]), content="true")
    let arr : Array[Int] = []
    inspect(arr.ends_with([]), content="true")
    inspect(arr.ends_with([1]), content="false")
    }

    Array::equal

    fn[T : Eq] Array::equal(self : Array[T], other : Array[T]) -> Bool

    Array::extract_if

    fn[T] Array::extract_if(self : Array[T], f : (T) -> Bool raise?) -> Array[T] raise?

    Extracts elements from an array that satisfy a given predicate function. The extracted elements are removed from the original array and returned as a new array. The relative order of the extracted elements is preserved.

    Parameters:

    • array : The array to extract elements from.
    • predicate : A function that takes an element and returns true if the element should be extracted, false otherwise.

    Returns a new array containing all elements that satisfy the predicate function, in the order they appeared in the original array.

    Example:

    test {
    let arr = [1, 2, 3, 4, 5]
    let extracted = arr.extract_if(x => x % 2 == 0)
    debug_inspect(extracted, content="[2, 4]")
    debug_inspect(arr, content="[1, 3, 5]")
    }

    Array::fill

    fn[A] Array::fill(self : Array[A], value : A, start? : Int, end? : Int) -> Unit

    Fills an Array with a specified value.

    This method fills all or part of an Array with the given value.

    Parameters

    • value: The value to fill the array with
    • start: The starting index (inclusive, default: 0)
    • end: The ending index (exclusive, optional)

    If end is not provided, fills from start to the end of the array. If start equals end, no elements are modified.

    Panics

    • Panics if start is negative or greater than or equal to the array length
    • Panics if end is provided and is less than start or greater than array length
    • Does nothing if the array is empty

    Example

    test {
    // Fill entire array
    let arr = [1, 2, 3, 4, 5]
    arr.fill(0)
    @debug.debug_inspect(arr, content="[0, 0, 0, 0, 0]")

    // Fill from index 1 to 3 (exclusive)
    let arr2 = [1, 2, 3, 4, 5]
    arr2.fill(99, start=1, end=3)
    @debug.debug_inspect(arr2, content="[1, 99, 99, 4, 5]")

    // Fill from index 2 to end
    let arr3 = ["a", "b", "c", "d"]
    arr3.fill("x", start=2)
    @debug.debug_inspect(
    arr3,
    content=(
    #|["a", "b", "x", "x"]
    ),
    )
    }

    Array::filter

    fn[T] Array::filter(self : Array[T], f : (T) -> Bool raise?) -> Array[T] raise?

    Creates a new array containing all elements from the input array that satisfy the given predicate function.

    Parameters:

    • array : The array to filter.
    • predicate : A function that takes an element and returns a boolean indicating whether the element should be included in the result.

    Returns a new array containing only the elements for which the predicate function returns true. The relative order of the elements is preserved.

    Example:

    test {
    let arr = [1, 2, 3, 4, 5]
    let evens = arr.filter(x => x % 2 == 0)
    debug_inspect(evens, content="[2, 4]")
    }

    Array::filter_map

    fn[A, B] Array::filter_map(self : Array[A], f : (A) -> B? raise?) -> Array[B] raise?

    Applies a function to each element of the array and collects the results that are Some, discarding the elements for which the function returns None.

    Arguments

    • self - The array to filter and map.
    • f - The function applied to each element, returning Some(value) to keep the mapped value, or None to drop the element.

    Returns

    A new array containing the unwrapped Some results, in the order the corresponding elements appeared in the original array.

    Array::flatten

    fn[T] Array::flatten(self : Array[Array[T]]) -> Array[T]

    Flattens an array of arrays into an array.

    Example:

    test {
    let v = [[3, 4], [5, 6]].flatten()
    @test.assert_eq(v, [3, 4, 5, 6])
    }

    Array::fold

    #alias(fold_left, deprecated="`fold_left` is deprecated, use `fold` instead")
    fn[A, B] Array::fold(self : Array[A], init~ : B, f : (B, A) -> B raise?) -> B raise?

    Fold out values from an array according to certain rules. This method traverses the array through self.iter(), so the traversal bounds are fixed when folding starts.

    Structural mutations to self inside f are unsupported. Appended elements are not visited, and shrinking the array with operations such as remove, truncate, clear, or drain may cause later fold steps to fail.

    Example:

    test {
    let sum = [1, 2, 3, 4, 5].fold(init=0, (sum, elem) => sum + elem)
    @test.assert_eq(sum, 15)
    }

    Array::foldi

    #alias(fold_lefti, deprecated="`fold_lefti` is deprecated, use `foldi` instead")
    fn[A, B] Array::foldi(self : Array[A], init~ : B, f : (Int, B, A) -> B raise?) -> B raise?

    Fold out values from an array according to certain rules with index.

    Example:

    test {
    let sum = [1, 2, 3, 4, 5].foldi(init=0, (index, sum, _elem) => sum + index)
    @test.assert_eq(sum, 10)
    }

    Array::from_fixed_array

    fn[T] Array::from_fixed_array(arr : FixedArray[T]) -> Array[T]

    Creates a new dynamic array from a fixed-size array.

    Parameters:

    • arr : The fixed-size array to convert. The elements of this array will be copied to the new array.

    Returns a new dynamic array containing all elements from the input fixed-size array.

    Example:

    test {
    let fixed = FixedArray::make(3, 42)
    let dynamic = Array::from_fixed_array(fixed)
    debug_inspect(dynamic, content="[42, 42, 42]")
    }

    Array::from_iter

    #alias(from_iterator, deprecated="`from_iterator` is deprecated, use `from_iter` instead")
    fn[T] Array::from_iter(iter : Iter[T]) -> Array[T]

    Creates a new array containing all elements from an iterator.

    Parameters:

    • iterator : An iterator containing elements of type T.

    Returns a new array containing all elements from the iterator in the same order.

    Example:

    test {
    let iter = 42
    let arr = Array::from_iter(iter)
    debug_inspect(arr, content="[42]")
    }

    Array::get

    fn[T] Array::get(self : Array[T], index : Int) -> T?

    Retrieves the element at the specified index from the array.

    Parameters:

    • self : The array to get the element from.
    • index : The position in the array from which to retrieve the element.

    Returns Some(element) if the index is within bounds, or None if the index is out of bounds.

    Example:

    test {
    let arr = [1, 2, 3]
    debug_inspect(arr.get(-1), content="None")
    debug_inspect(arr.get(0), content="Some(1)")
    debug_inspect(arr.get(3), content="None")
    }

    Array::get_view

    fn[T] Array::get_view(self : Array[T], start? : Int, end? : Int) -> ArrayView[T]?

    Creates a view of a portion of the array, returning None when indices are invalid.

    Parameters:

    • array : The array to create a view from.
    • start : The starting index of the view (inclusive). Defaults to 0.
    • end : The ending index of the view (exclusive). If not provided, defaults to the length of the array.

    Returns Some(ArrayView) that provides a window into the specified portion of the array, or None when the indices are invalid.

    Example:

    test {
    let arr = [1, 2, 3, 4, 5]
    let start = 1
    let end = 4
    debug_inspect(
    arr.get_view(start~, end~),
    content=(
    #|Some(<ArrayView: [2, 3, 4]>)
    ),
    )
    let start = 3
    let end = 10
    debug_inspect(arr.get_view(start~, end~), content="None")
    }

    Array::hash

    fn[T : Hash] Array::hash(self : Array[T]) -> Int

    Array::insert

    fn[T] Array::insert(self : Array[T], index : Int, value : T) -> Unit

    Inserts an element at a given index within the array. This function will panic if the index is out of bounds.

    Example

    test {
    let a = [1, 2, 3]
    a.insert(1, 4)
    @debug.debug_inspect(a, content="[1, 4, 2, 3]")
    let b = [1, 2, 3]
    b.insert(0, 5)
    @debug.debug_inspect(b, content="[5, 1, 2, 3]")
    let c = [1, 2, 3]
    c.insert(3, 6)
    @debug.debug_inspect(c, content="[1, 2, 3, 6]")
    }

    Array::is_empty

    fn[T] Array::is_empty(self : Array[T]) -> Bool

    Tests whether the array contains no elements.

    Parameters:

    • array : The array to check.

    Returns true if the array has no elements, false otherwise.

    Example:

    test {
    let empty : Array[Int] = []
    inspect(empty.is_empty(), content="true")
    let non_empty = [1, 2, 3]
    inspect(non_empty.is_empty(), content="false")
    }

    Array::is_sorted

    fn[T : Compare + Eq] Array::is_sorted(self : Array[T]) -> Bool

    Tests whether the array is sorted in ascending order.

    Parameters:

    • self : The array to be tested.
    • T : The type of elements in the array. Must implement the Compare trait.

    Returns a boolean value indicating whether the array is sorted in ascending order:

    • true if the array is empty, contains only one element, or all elements are in ascending order.
    • false if any element is greater than the element that follows it.

    Example:

    test {
    let ascending = [1, 2, 3, 4, 5]
    let descending = [5, 4, 3, 2, 1]
    let unsorted = [1, 3, 2, 4, 5]
    inspect(ascending.is_sorted(), content="true")
    inspect(descending.is_sorted(), content="false")
    inspect(unsorted.is_sorted(), content="false")
    }

    Array::iter

    #alias(iterator, deprecated="`iterator` is deprecated, use `iter` instead")
    fn[T] Array::iter(self : Array[T]) -> Iter[T]

    Creates an iterator over the elements of the array.

    Parameters:

    • array : The array to create an iterator from.

    Returns an iterator that yields each element of the array in order. This iterator is created from self[:], so the traversal bounds are fixed when iteration starts.

    Structural mutations after the iterator is created are unsupported. Appended elements are not visited, and shrinking the array with operations such as remove, truncate, clear, or drain may cause later iterator steps to fail. The same caveat applies to rev_iter(), iter2(), and helpers built on top of them such as each(), eachi(), and fold().

    Example:

    test {
    let arr = [1, 2, 3]
    let mut sum = 0
    arr.iter().each(x => sum x)
    inspect(sum, content="6")
    }

    Array::iter2

    #alias(iterator2, deprecated="`iterator2` is deprecated, use `iter2` instead")
    fn[A] Array::iter2(self : Array[A]) -> Iter2[Int, A]

    Returns an iterator that provides both indices and values of the array in order.

    Parameters:

    • self : The array to iterate over.

    Returns an iterator that yields tuples of index and value pairs, where indices start from 0.

    Example:

    test {
    let arr = [10, 20, 30]
    let mut sum = 0
    arr.iter2().each((i, x) => sum i + x)
    inspect(sum, content="63") // (0 + 10) + (1 + 20) + (2 + 30) = 63
    }

    Array::join

    fn[A : ToStringView] Array::join(self : Array[A], separator : StringView) -> String

    Join an array of strings using the provided separator.

    Parameters:
    • separator : The string inserted between each element.

    Returns a single concatenated String.

    Example:

    test {
    let s = "hello world"
    inspect(s.split(" ").to_array().join(":"), content="hello:world")
    }

    Array::last

    fn[A] Array::last(self : Array[A]) -> A?

    Returns the last element of the array, or None if the array is empty.

    Parameters:

    • array : The array to get the last element from.

    Returns an optional value containing the last element of the array. The result is None if the array is empty, or Some(x) where x is the last element of the array.

    Example:

    test {
    let arr = [1, 2, 3]
    debug_inspect(arr.last(), content="Some(3)")
    let empty : Array[Int] = []
    debug_inspect(empty.last(), content="None")
    }

    Array::length

    fn[T] Array::length(self : Array[T]) -> Int

    Returns the number of elements in the array.

    Parameters:

    • array : The array whose length is to be determined.

    Returns the number of elements in the array as an integer.

    Example:

    test {
    let arr : Array[Int] = [1, 2, 3]
    inspect(arr.length(), content="3")
    let empty : Array[Int] = []
    inspect(empty.length(), content="0")
    }

    Array::lexical_compare

    fn[T : Compare + Eq] Array::lexical_compare(self : Array[T], other : Array[T]) -> Int

    Performs a lexicographical comparison of two arrays.

    This method compares the arrays element by element until a difference is found or one array is exhausted. Unlike the Compare trait implementation which uses shortlex order (shorter arrays come first), this method compares based purely on element values until a difference is found.

    Returns

    • A negative integer if self is lexicographically less than other
    • Zero if self is lexicographically equal to other
    • A positive integer if self is lexicographically greater than other

    Example

    test {
    inspect([1, 2].lexical_compare([1, 2, 3]), content="-1")
    inspect([1, 2, 3].lexical_compare([1, 2]), content="1")
    inspect([1, 2, 3].lexical_compare([1, 2, 3]), content="0")
    inspect([1, 2, 3].lexical_compare([1, 2, 4]), content="-1")
    }

    Array::make

    fn[T] Array::make(len : Int, elem : T) -> Array[T]

    Creates a new array with a specified length and initializes all elements with the given value.

    Parameters:

    • length : The length of the array to create. Must be a non-negative integer.
    • initial_value : The value used to initialize all elements in the array.

    Returns a new array of type Array[T] with length elements, where each element is initialized to initial_value.

    Throws an error if length is negative.

    Example:

    test {
    let arr = Array::make(3, 42)
    debug_inspect(arr, content="[42, 42, 42]")
    }

    WARNING: A common pitfall is creating with the same initial value, for example:
    test {
    let two_dimension_array = Array::make(10, Array::make(10, 0))
    two_dimension_array[0][5] = 10
    @test.assert_eq(two_dimension_array[5][5], 10)
    }
    This is because all the cells reference to the same object (the Array[Int] in this case). One should use makei() instead which creates an object for each index.

    Array::makei

    fn[T] Array::makei(length : Int, f : (Int) -> T raise?) -> Array[T] raise?

    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:

    test {
    let arr = Array::makei(3, i => i * 2)
    debug_inspect(arr, content="[0, 2, 4]")
    }

    Array::map

    fn[T, U] Array::map(self : Array[T], f : (T) -> U raise?) -> Array[U] raise?

    Maps a function over the elements of the array.

    Example

    test {
    let v = [3, 4, 5]
    let v2 = v.map(x => x + 1)
    @test.assert_eq(v2, [4, 5, 6])
    }

    Array::map_in_place

    #alias(map_inplace, deprecated="`map_inplace` is deprecated, use `map_in_place` instead")
    fn[T] Array::map_in_place(self : Array[T], f : (T) -> T raise?) -> Unit raise?

    Maps a function over the elements of the array in place.

    Example

    test {
    let v = [3, 4, 5]
    v.map_in_place(x => x + 1)
    @test.assert_eq(v, [4, 5, 6])
    }

    Array::mapi

    fn[T, U] Array::mapi(self : Array[T], f : (Int, T) -> U raise?) -> Array[U] raise?

    Maps a function over the elements of the array with index.

    Example

    test {
    let v = [3, 4, 5]
    let v2 = v.mapi((i, x) => x + i)
    @test.assert_eq(v2, [3, 5, 7])
    }

    Array::mapi_in_place

    #alias(mapi_inplace, deprecated="`mapi_inplace` is deprecated, use `mapi_in_place` instead")
    fn[T] Array::mapi_in_place(self : Array[T], f : (Int, T) -> T raise?) -> Unit raise?

    Maps a function over the elements of the array with index in place.

    Example

    test {
    let v = [3, 4, 5]
    v.mapi_in_place((i, x) => x + i)
    @test.assert_eq(v, [3, 5, 7])
    }

    Array::mut_view

    fn[T] Array::mut_view(self : Array[T], start? : Int, end? : Int) -> MutArrayView[T]

    Creates a mutable view of a portion of the array. The view provides read-write access to the underlying array without copying the elements.

    Parameters:

    • array : The array to create a view from.
    • start : The starting index of the view (inclusive). Defaults to 0.
    • end : The ending index of the view (exclusive). If not provided, defaults to the length of the array.

    Returns a MutArrayView that provides a window into the specified portion of the array.

    Throws a panic if the indices are invalid (i.e., start is negative, end is greater than the array length, or start is greater than end).

    Example:

    test {
    let arr = [1, 2, 3, 4, 5]
    let view = arr.mut_view(start=1, end=4) // Create a view of elements at indices 1, 2, and 3
    inspect(view[0], content="2") // First element of view is arr[1]
    inspect(view.length(), content="3") // View contains 3 elements
    }

    Array::new

    #deprecated("Use `Array(capacity=...)` instead")
    fn[T] Array::new(capacity? : Int) -> Array[T]

    Creates a new empty array with an optional initial capacity.

    Deprecated: use Array(capacity=...) instead.

    Array::pop

    fn[T] Array::pop(self : Array[T]) -> T?

    Removes the last element from an array and returns it, or None if it is empty.

    The vacated slot goes on referring to the returned element, so an ArrayView created beforehand keeps observing that element, and it is released only once a later push reuses the slot, the buffer grows, or the buffer is dropped. Call Array::release_unused to release it at once.

    Example

    test {
    let v = [1, 2, 3]
    @test.assert_eq(v.pop(), Some(3))
    @test.assert_eq(v, [1, 2])
    }

    Array::push

    fn[T] Array::push(self : Array[T], value : T) -> Unit

    Adds an element to the end of the array.

    If the array is at capacity, it will be reallocated.

    Example

    test {
    let v = []
    v.push(3)
    }

    Array::push_iter

    fn[T] Array::push_iter(self : Array[T], iter : Iter[T]) -> Unit

    Adds all elements from an iterator to the end of the array.

    This function iterates over each element in the provided iterator and adds them to the array using the push method.

    Example

    test {
    let u = [1, 2, 3]
    let v = [4, 5, 6]
    u.push_iter(v.iter())
    @test.assert_eq(u, [1, 2, 3, 4, 5, 6])
    }

    Array::release_unused

    fn[T] Array::release_unused(self : Array[T], placeholder~ : T) -> Unit

    Overwrites the array's unused capacity -- every slot from length() up to capacity() -- with placeholder, releasing whatever those slots held.

    Shrinking an array never clears the slots it vacates, so whatever they held -- a removed element, or a duplicate reference to a survivor that was shifted over it -- stays reachable from the buffer and unreleased until later pushes reuse those slots, the buffer grows, or the array is dropped. This releases them on demand without reallocating, which is what Array::pop, Array::remove, Array::retain and the other operations that take no placeholder leave outstanding. Array::shrink_to_fit releases them too, but by allocating an exact-size buffer and copying every survivor into it; this costs one pass over the unused region and no allocation.

    An ArrayView created before the call observes placeholder in that region afterwards, in place of whatever it held.

    This only matters for element types holding references -- for types such as Int there is nothing to release and the call merely costs a pass over the buffer.

    Example:

    test {
    let arr = ["a", "b", "c"]
    let _ = arr.pop()
    arr.release_unused(placeholder="")
    debug_inspect(arr, content="[\"a\", \"b\"]")
    }

    Array::remove

    fn[T] Array::remove(self : Array[T], index : Int) -> T

    Removes and returns the element at position index within the array, shifting all elements after it to the left.

    This function will panic if the index is out of bounds.

    Example

    test {
    let v = [3, 4, 5]
    @test.assert_eq(v.remove(1), 4)
    @test.assert_eq(v, [3, 5])
    }

    Array::repeat

    fn[T] Array::repeat(self : Array[T], times : Int) -> Array[T]

    Create an array by repeating self times times.

    Aborts if times is negative. When times is 0, returns an empty array.

    Example:

    test {
    let v = [3, 4].repeat(2)
    @test.assert_eq(v, [3, 4, 3, 4])
    }

    Array::reserve_capacity

    fn[T] Array::reserve_capacity(self : Array[T], capacity : Int) -> Unit

    Reserves capacity to ensure that it can hold at least the number of elements specified by the capacity argument.

    Example

    test {
    let v = [1]
    v.reserve_capacity(10)
    @test.assert_eq(v.capacity(), 10)
    }

    Array::resize

    fn[T] Array::resize(self : Array[T], new_len : Int, f : T) -> Unit

    Resizes an array to a specified length, either by truncating if the new length is smaller, or by appending copies of a default value if the new length is larger.

    Parameters:

    • array : The array to be resized.
    • new_length : The desired length of the array after resizing.
    • default_value : The value to append when extending the array.

    Throws a panic if new_length is negative.

    Examples:

    test {
    let arr = [1, 2, 3, 4, 5]
    arr.resize(3, 0)
    debug_inspect(arr, content="[1, 2, 3]")
    let arr = [1, 2, 3]
    arr.resize(5, 0)
    debug_inspect(arr, content="[1, 2, 3, 0, 0]")
    }

    Array::retain

    fn[T] Array::retain(self : Array[T], f : (T) -> Bool raise?) -> Unit raise?

    Removes all elements from the array that do not satisfy the predicate function, modifying the array in place. The order of remaining elements is preserved.

    Parameters:

    • array : The array to be filtered.
    • predicate : A function that takes an element and returns true if the element should be kept, false if it should be removed.

    Example:

    test {
    let arr = [1, 2, 3, 4, 5]
    arr.retain(x => x % 2 == 0)
    debug_inspect(arr, content="[2, 4]")
    let arr = [1, 2, 3]
    arr.retain(x => x > 10)
    debug_inspect(arr, content="[]")
    let arr = [1, 2, 3]
    arr.retain(_ => true)
    debug_inspect(arr, content="[1, 2, 3]")
    }

    Array::retain_map

    fn[A] Array::retain_map(self : Array[A], f : (A) -> A? raise?) -> Unit raise?

    In-place filter and map for Array

    Example

    test {
    let arr = [1, 2, 3, 4, 5]
    arr.retain_map(fn(x) { if x % 2 == 0 { Some(x * 2) } else { None } })
    debug_inspect(arr, content="[4, 8]")
    }

    Array::rev

    fn[T] Array::rev(self : Array[T]) -> Array[T]

    Creates a new array with elements in reversed order.

    Parameters:

    • self : The array to be reversed.

    Returns a new array containing the same elements as the input array but in reverse order. The original array remains unchanged.

    Example:

    test {
    let arr = [1, 2, 3, 4, 5]
    debug_inspect(arr.rev(), content="[5, 4, 3, 2, 1]")
    debug_inspect(arr, content="[1, 2, 3, 4, 5]") // original array unchanged
    }

    Array::rev_each

    fn[T] Array::rev_each(self : Array[T], f : (T) -> Unit raise?) -> Unit raise?

    Iterates over the elements of the array in reverse order, applying the given function to each element.

    Parameters:

    • array : The array to iterate over.
    • f : A function that takes an element of type T and returns Unit. This function is applied to each element of the array in reverse order.

    Example:

    test {
    let v = [3, 4, 5]
    let mut sum = 0
    v.rev_each(x => sum = sum - x)
    @json.json_inspect(sum, content=-12)
    }

    Array::rev_eachi

    fn[T] Array::rev_eachi(self : Array[T], f : (Int, T) -> Unit raise?) -> Unit raise?

    Iterates over the elements of the array with index in reversed order.

    Example

    test {
    let v = [3, 4, 5]
    let mut sum = 0
    v.rev_eachi((i, x) => sum x + i)
    @test.assert_eq(sum, 15)
    }

    Array::rev_fold

    #alias(fold_right, deprecated="`fold_right` is deprecated, use `rev_fold` instead")
    fn[A, B] Array::rev_fold(self : Array[A], init~ : B, f : (B, A) -> B raise?) -> B raise?

    Fold out values from an array according to certain rules in reversed turn.

    Example:

    test {
    let sum = [1, 2, 3, 4, 5].rev_fold(init=0, (sum, elem) => sum + elem)
    @test.assert_eq(sum, 15)
    }

    Array::rev_foldi

    #alias(fold_righti, deprecated="`fold_righti` is deprecated, use `rev_foldi` instead")
    fn[A, B] Array::rev_foldi(self : Array[A], init~ : B, f : (Int, B, A) -> B raise?) -> B raise?

    Fold out values from an array according to certain rules in reversed turn with index.

    Example:

    test {
    let sum = [1, 2, 3, 4, 5].rev_foldi(init=0, (index, sum, _elem) => sum + index)
    @test.assert_eq(sum, 10)
    }

    Array::rev_in_place

    #alias(rev_inplace, deprecated="`rev_inplace` is deprecated, use `rev_in_place` instead")
    fn[T] Array::rev_in_place(self : Array[T]) -> Unit

    Reverses the order of elements in an array in place, modifying the original array.

    Parameters:

    • self : The array to be reversed.

    Example:

    test {
    let arr = [1, 2, 3, 4, 5]
    arr.rev_in_place()
    debug_inspect(arr, content="[5, 4, 3, 2, 1]")
    let arr : Array[Int] = []
    arr.rev_in_place()
    debug_inspect(arr, content="[]")
    }

    Array::rev_iter

    #alias(rev_iterator, deprecated="`rev_iterator` is deprecated, use `rev_iter` instead")
    fn[T] Array::rev_iter(self : Array[T]) -> Iter[T]

    Returns an iterator that yields elements from the array in reverse order, from the last element to the first.

    Parameters:

    • array : The array to iterate over in reverse order.

    Returns an iterator that yields each element of the array, starting from the last element and moving towards the first.

    Example:

    test {
    let arr = [1, 2, 3]
    let result = []
    arr.rev_iter().each(x => result.push(x))
    debug_inspect(result, content="[3, 2, 1]")
    }

    Array::search

    fn[T : Eq] Array::search(self : Array[T], value : T) -> Int?

    Searches for the first occurrence of a value in the array and returns its index.

    Parameters:

    • self : The array to search in.
    • value : The value to search for.

    Returns an Option containing the index of the first occurrence of value if found, or None if the value is not present in the array.

    Example:

    test {
    let arr = [1, 2, 3, 2, 4]
    debug_inspect(arr.search(2), content="Some(1)") // first occurrence
    debug_inspect(arr.search(5), content="None") // not found
    }

    Array::search_by

    #alias(find_index, deprecated="`find_index` is deprecated, use `search_by` instead")
    fn[T] Array::search_by(self : Array[T], f : (T) -> Bool raise?) -> Int? raise?

    Search the index of the first element that satisfies the predicate.

    Example

    test {
    let v = [1, 2, 3, 4, 5]
    match v.search_by(x => x == 3) {
    Some(index) => @test.assert_eq(index, 2) // 2
    None => println("Not found")
    }
    }

    Array::set

    #alias("_[_]=_")
    fn[T] Array::set(self : Array[T], index : Int, value : T) -> Unit

    Sets the element at the specified index in the array to a new value. The original value at that index is overwritten.

    Parameters:

    • array : The array to modify.
    • index : The position in the array where the value will be set.
    • value : The new value to assign at the specified index.

    Throws an error if index is negative or greater than or equal to the length of the array.

    Example:

    test {
    let arr = [1, 2, 3]
    arr[1] = 42
    debug_inspect(arr, content="[1, 42, 3]")
    }

    Array::shrink_to_fit

    fn[T] Array::shrink_to_fit(self : Array[T]) -> Unit

    Shrinks the capacity of the array as much as possible.

    Example

    test {
    let v = Array(capacity=10)
    v.push(1)
    v.push(2)
    v.push(3)
    v.shrink_to_fit()
    @test.assert_eq(v.capacity(), 3)
    }

    The survivors are copied into the new buffer and the old one is released with them, so this also releases whatever earlier removals left in the unused capacity. It pays an allocation plus a copy of every survivor to do so; Array::release_unused releases the same elements in one pass over the unused region and no allocation, at the cost of leaving the capacity alone.

    Array::shuffle

    fn[T] Array::shuffle(self : Array[T], rand~ : (Int) -> Int) -> Array[T]

    Shuffle the array using Knuth shuffle

    To use this function, you need to provide a rand function, which takes an integer as it upper bound and returns an integer. rand n is expected to returns a uniformly distribution integer between 0 and n - 1

    Example

    let arr = [1, 2, 3, 4, 5]

    fn rand(upper : Int) -> Int {
    let rng = @random.Rand::new()
    rng.int(limit=upper)
    }

    let _shuffled = Array::shuffle(arr, rand~)

    Array::shuffle_in_place

    fn[T] Array::shuffle_in_place(self : Array[T], rand~ : (Int) -> Int) -> Unit

    Shuffle the array using Knuth shuffle

    To use this function, you need to provide a rand function, which takes an integer as it upper bound and returns an integer. rand n is expected to returns a uniformly distribution integer between 0 and n - 1

    Example

    test {
    let arr = [1, 2, 3, 4, 5]
    fn rand(upper : Int) -> Int {
    let rng = @random.Rand::new()
    rng.int(limit=upper)
    }

    Array::shuffle_in_place(arr, rand~)
    }

    Array::sort

    fn[T : Compare + Eq] Array::sort(self : Array[T]) -> Unit

    Sorts the array in place.

    It's an in-place, unstable sort(it will reorder equal elements). The time complexity is O(n log n) in the worst case.

    Example

    test {
    let arr = [5, 4, 3, 2, 1]
    arr.sort()
    @test.assert_eq(arr, [1, 2, 3, 4, 5])
    }

    Array::sort_by

    fn[T] Array::sort_by(self : Array[T], cmp : (T, T) -> Int) -> Unit

    Sorts the array with a custom comparison function.

    It's an in-place, unstable sort(it will reorder equal elements). The time complexity is O(n log n) in the worst case.

    Example

    test {
    let arr = [5, 3, 2, 4, 1]
    arr.sort_by((a, b) => a - b)
    @test.assert_eq(arr, [1, 2, 3, 4, 5])
    }

    Array::sort_by_key

    fn[T, K : Compare + Eq] Array::sort_by_key(self : Array[T], map : (T) -> K) -> Unit

    Sorts the array with a key extraction function.

    It's an in-place, unstable sort(it will reorder equal elements). The time complexity is O(n log n) in the worst case.

    Example

    test {
    let arr = [5, 3, 2, 4, 1]
    arr.sort_by_key(x => -x)
    @test.assert_eq(arr, [5, 4, 3, 2, 1])
    }

    Array::split

    fn[T] Array::split(self : Array[T], pred : (T) -> Bool raise?) -> Array[Array[T]] raise?

    Splits an array into chunks using a predicate function. Creates chunks by grouping consecutive elements that do not satisfy the predicate function. Elements that satisfy the predicate function are excluded from the resulting chunks and act as delimiters.

    Parameters:

    • array : The array to be split into chunks.
    • predicate : A function that takes an element and returns true if the element should be used as a delimiter.

    Returns an array of arrays, where each inner array is a chunk of consecutive elements that do not satisfy the predicate.

    Example:

    test {
    let arr = [1, 0, 2, 0, 3, 0, 4]
    debug_inspect(arr.split(x => x == 0), content="[[1], [2], [3], [4]]")
    let arr = [0, 1, 0, 0, 2, 0]
    debug_inspect(arr.split(x => x == 0), content="[[], [1], [], [2]]")
    }

    Array::starts_with

    fn[T : Eq] Array::starts_with(self : Array[T], prefix : ArrayView[T]) -> Bool

    Checks if the array begins with all elements of the provided prefix array in order.

    Parameters:

    • self : The array to check against.
    • prefix : The array containing the sequence of elements to look for at the beginning.

    Returns true if the array starts with all elements in prefix in the same order, false otherwise. An empty prefix array always returns true, and a prefix longer than the array always returns false.

    Example:

    test {
    let arr = [1, 2, 3, 4, 5]
    inspect(arr.starts_with([1, 2]), content="true")
    inspect(arr.starts_with([2, 3]), content="false")
    inspect(arr.starts_with([]), content="true")
    inspect(arr.starts_with([1, 2, 3, 4, 5, 6]), content="false")
    }

    Array::strip_prefix

    fn[T : Eq] Array::strip_prefix(self : Array[T], prefix : ArrayView[T]) -> ArrayView[T]?

    Strip a prefix from the array.

    If the array starts with the prefix, return a view of the array after the prefix, otherwise return None. The returned view shares the original backing array — no allocation.

    Example

    test {
    let v = [1, 2, 3, 4, 5]
    let v2 = v.strip_prefix([1, 2])
    debug_inspect(
    v2,
    content=(
    #|Some(<ArrayView: [3, 4, 5]>)
    ),
    )
    }

    Array::strip_suffix

    fn[T : Eq] Array::strip_suffix(self : Array[T], suffix : ArrayView[T]) -> ArrayView[T]?

    Strip a suffix from the array.

    If the array ends with the suffix, return a view of the array before the suffix, otherwise return None. The returned view shares the original backing array — no allocation.

    Example

    test {
    let v = [3, 4, 5]
    let v2 = v.strip_suffix([5])
    debug_inspect(
    v2,
    content=(
    #|Some(<ArrayView: [3, 4]>)
    ),
    )
    }

    Array::suffixes

    fn[T] Array::suffixes(self : Array[T], include_empty? : Bool) -> Iter[ArrayView[T]]

    Return an iterator over all suffix views of this array.

    Suffixes are yielded from longest to shortest. Set include_empty=true to include the final empty suffix.

    Example:

    test {
    let xs = [1, 2]
    debug_inspect(
    xs.suffixes().collect(),
    content=(
    #|[<ArrayView: [1, 2]>, <ArrayView: [2]>]
    ),
    )
    debug_inspect(
    xs.suffixes(include_empty=true).collect(),
    content=(
    #|[<ArrayView: [1, 2]>, <ArrayView: [2]>, <ArrayView: []>]
    ),
    )
    }

    Array::swap

    fn[T] Array::swap(self : Array[T], i : Int, j : Int) -> Unit

    Swaps the values at two positions in the array.

    Parameters:

    • array : The array in which to swap elements.
    • index1 : The index of the first element to be swapped.
    • index2 : The index of the second element to be swapped.

    This function will panic if either index is negative or greater than or equal to the length of the array.

    Example:

    test {
    let arr = [1, 2, 3]
    arr.swap(0, 2)
    debug_inspect(arr, content="[3, 2, 1]")
    }

    Array::to_json

    fn[X : ToJson] Array::to_json(self : Array[X]) -> Json

    Array::truncate

    fn[A] Array::truncate(self : Array[A], len : Int) -> Unit

    Truncates the array in-place to the specified length.

    If len is greater than or equal to the current array length, the function does nothing. If len is 0, the array is cleared. Otherwise, removes elements from the end until the array reaches the given length.

    Parameters:

    • self : The target array (modified in-place).
    • len : The new desired length (must be non-negative).

    Important:
    • If len is negative, the function does nothing.
    • If len exceeds current length, the array remains unchanged.

    Elements beyond len are removed from the array, but the backing buffer keeps referring to them: they are released once those slots are reused by later pushes, once the buffer grows, or once the array is dropped. Call Array::release_unused to overwrite them at once, or Array::shrink_to_fit to move the survivors into an exact-size buffer. On the JavaScript backend the removed elements are released right away and Array::release_unused is a no-op.

    Example:

    test {
    let arr = [1, 2, 3, 4, 5]
    arr.truncate(3)
    debug_inspect(arr, content="[1, 2, 3]")
    }

    Array::unsafe_blit_fixed

    fn[A] Array::unsafe_blit_fixed(dst : Array[A], dst_offset : Int, src : FixedArray[A], src_offset : Int, len : Int) -> Unit

    Copies elements from a fixed-size array to a dynamic array. The arrays may overlap, in which case the copy is performed in a way that preserves the data.

    Parameters:

    • dst : The destination dynamic array where elements will be copied to.
    • dst_offset : The starting index in the destination array where copying begins.
    • src : The source fixed-size array from which elements will be copied.
    • src_offset : The starting index in the source array from which copying begins.
    • len : The number of elements to copy.

    Example:

    test {
    let src = FixedArray::make(5, 0)
    let dst = Array::make(5, 0)
    for i in 0..<5 {
    src[i] = i + 1
    }
    Array::unsafe_blit_fixed(dst, 1, src, 0, 2)
    @debug.debug_inspect(dst, content="[0, 1, 2, 0, 0]")
    }

    Array::unsafe_get

    fn[T] Array::unsafe_get(self : Array[T], idx : Int) -> T

    Retrieves the element at the specified index from an array without bounds checking.

    Parameters:

    • array : The array from which to retrieve the element.
    • index : The position in the array from which to retrieve the element.

    Returns the element at the specified index.

    Example:

    test {
    let arr : Array[Int] = [1, 2, 3]
    inspect(arr.unsafe_get(1), content="2")
    }

    Array::unsafe_set

    fn[T] Array::unsafe_set(self : Array[T], idx : Int, val : T) -> Unit

    Write val to idx without bounds checking.

    This is unsafe: caller must ensure 0 <= idx < self.length().

    Example:

    test {
    let arr = [1, 2, 3]
    arr.unsafe_set(1, 99)
    debug_inspect(arr, content="[1, 99, 3]")
    }

    Array::unzip

    fn[T1, T2] Array::unzip(self : Array[(T1, T2)]) -> (Array[T1], Array[T2])

    Splits an array of pairs into two arrays, separating the first and second elements.

    Example

    test {
    let arr = [(1, "a"), (2, "b"), (3, "c")]
    let (nums, strs) = arr.unzip()
    debug_inspect(nums, content="[1, 2, 3]")
    debug_inspect(strs, content="[\"a\", \"b\", \"c\"]")
    }

    Array::view

    #alias(sub, deprecated="Use _[_:_] instead")
    #alias("_[_:_]")
    fn[T] Array::view(self : Array[T], start? : Int, end? : Int) -> ArrayView[T]

    Creates a view of a portion of the array. The view provides read-only access to the underlying array without copying the elements.

    Parameters:

    • array : The array to create a view from.
    • start : The starting index of the view (inclusive). Defaults to 0.
    • end : The ending index of the view (exclusive). If not provided, defaults to the length of the array.

    Returns an ArrayView that provides a window into the specified portion of the array.

    Throws a panic if the indices are invalid (i.e., start is negative, end is greater than the array length, or start is greater than end).

    Example:

    test {
    let arr = [1, 2, 3, 4, 5]
    let view = arr[1:4] // Create a view of elements at indices 1, 2, and 3
    inspect(view[0], content="2") // First element of view is arr[1]
    inspect(view.length(), content="3") // View contains 3 elements
    }

    Array::windows

    fn[T] Array::windows(self : Array[T], size : Int) -> Array[ArrayView[T]]

    Generates overlapping subslices (sliding windows) of the specified size.

    Parameters:

    • array : The array to be processed with sliding windows.
    • size : The window length. Must be a positive integer, otherwise it will panic.

    Returns an array of slices, where each inner slice is a contiguous subslice of the original array. Windows are produced with a step size of 1. If the original array's length is less than the specified window size, the result will be an empty array.

    Example:

    test {
    let arr = [1, 2, 3, 4, 5]
    let windows = arr.windows(2)
    debug_inspect(
    windows,
    content=(
    #|[
    #| <ArrayView: [1, 2]>,
    #| <ArrayView: [2, 3]>,
    #| <ArrayView: [3, 4]>,
    #| <ArrayView: [4, 5]>,
    #|]
    ),
    )
    let arr = [1, 2]
    debug_inspect(arr.windows(3), content="[]")
    }

    Array::zip

    fn[A, B] Array::zip(self : Array[A], other : Array[B]) -> Array[(A, B)]

    Zips two arrays into a single array of tuples.

    Parameters:

    • self : The first array.
    • other : The second array.

    Returns an array of tuples, where each tuple contains corresponding elements from the two input arrays.

    Example:

    test {
    let arr1 = [1, 2, 3]
    let arr2 = ['a', 'b', 'c']
    debug_inspect(arr1.zip(arr2), content="[(1, 'a'), (2, 'b'), (3, 'c')]")
    }

    Array::zip_to_iter2

    fn[A, B] Array::zip_to_iter2(self : Array[A], other : Array[B]) -> Iter2[A, B]

    Zips two arrays into an iterator that yields corresponding elements.

    Parameters:

    • self : The first array.
    • other : The second array.

    Returns an Iter2 iterator that produces corresponding elements from both arrays. The iteration continues until the shorter array is exhausted.

    Example:

    test {
    let arr1 = [1, 2, 3]
    let arr2 = ['a', 'b', 'c']
    debug_inspect(
    arr1.zip_to_iter2(arr2).to_array(),
    content="[(1, 'a'), (2, 'b'), (3, 'c')]",
    )
    }

    ArrayView

    type ArrayView[T]

    An ArrayView represents a view into a section of an array without copying the data. It stores its own start offset and length when it is created, so iteration over a view keeps using those bounds even if the underlying array is later structurally modified.

    Mutating an array while a view of it is alive is a program error. Because a view keeps its original bounds and does not track the array, after such a mutation it may observe elements that have since been removed, a value handed to Array::release_unused, or the contents of a buffer the array has stopped using. What it yields is always a valid value of T -- never uninitialized memory -- but is otherwise unspecified.

    No removal writes to the slots it vacates, so the removed elements stay reachable, and so unreleased, until a later push reuses the slot, until the buffer grows, or until the buffer itself is dropped. That holds uniformly: clear empties an array the same way pop shortens it. Two operations release those elements on demand -- Array::release_unused overwrites the unused capacity in place, and Array::shrink_to_fit moves the survivors into an exact-size buffer and lets the old one go.

    On the JavaScript backend this guarantee does not yet hold: operations such as Array::pop shrink the underlying JavaScript array, so a view reaching past the array's current length observes undefined.

    Example

    test {
    let arr = [1, 2, 3, 4, 5]
    let view = arr[1:4] // Creates a view of elements at indices 1,2,3
    @test.assert_eq(view[0], 2)
    @test.assert_eq(view.length(), 3)
    }
    impl Add for ArrayView[T]
    impl Compare for ArrayView[T]
    impl Eq for ArrayView[T]
    impl Hash for ArrayView[A]
    impl Show for ArrayView[X]
    impl ToJson for ArrayView[X]

    ArrayView::add

    fn[T] ArrayView::add(self : ArrayView[T], other : ArrayView[T]) -> ArrayView[T]

    ArrayView::all

    #alias(every)
    fn[T] ArrayView::all(self : ArrayView[T], f : (T) -> Bool raise?) -> Bool raise?

    Checks if all elements in the array view match the condition.

    Example

    test {
    let v = [1, 4, 6, 8, 9]
    assert_false(v[:].all(elem => elem % 2 == 0))
    assert_true(v[1:4].all(elem => elem % 2 == 0))
    }

    ArrayView::any

    #alias(exists)
    fn[T] ArrayView::any(self : ArrayView[T], f : (T) -> Bool raise?) -> Bool raise?

    Check if any of the elements in the array view match the condition.

    Example

    test {
    let v = [1, 2, 3, 4, 5][:]
    assert_true(v.any(ele => ele < 6))
    assert_false(v.any(ele => ele < 1))
    }

    ArrayView::at

    #alias("_[_]")
    fn[T] ArrayView::at(self : ArrayView[T], index : Int) -> T

    Retrieves an element at the specified index from the array view.

    Parameters:

    • self : The array view to access.
    • index : The position in the array view from which to retrieve the element.

    Returns the element at the specified index.

    Throws a runtime error if the index is out of bounds (less than 0 or greater than or equal to the length of the array view).

    Example:

    test {
    let arr = [1, 2, 3, 4, 5]
    let view = arr[2:4]
    inspect(view[0], content="3")
    inspect(view[1], content="4")
    }
    fn[T : Compare + Eq] ArrayView::binary_search(self : ArrayView[T], value : T) -> Result[Int, Int]

    Performs a binary search on a sorted array view.

    Example

    test {
    let view = [1, 3, 5, 7, 9][:]
    debug_inspect(view.binary_search(5), content="Ok(2)")
    debug_inspect(view.binary_search(6), content="Err(3)")
    }

    ArrayView::binary_search_by

    fn[T] ArrayView::binary_search_by(self : ArrayView[T], cmp : (T) -> Int raise?) -> Result[Int, Int] raise?

    Performs a binary search using a custom comparison function.

    Example

    test {
    let view = [1, 3, 5, 7, 9][:]
    let result = view.binary_search_by(x => x.compare(5))
    debug_inspect(result, content="Ok(2)")
    }

    ArrayView::blit_to

    fn[A] ArrayView::blit_to(self : ArrayView[A], dst : Array[A], dst_offset? : Int) -> Unit

    Copies all elements from an array view to a destination array, with support for growing the destination array if needed.

    Parameters:

    • self : The array view to copy elements from.
    • dst : The array to copy elements to. Will be automatically grown if needed to accommodate the copied elements.
    • dst_offset : Starting index in the destination array. Defaults to 0.

    Example:

    test {
    let src = [1, 2, 3, 4, 5]
    let view = src[1:4] // view = [2, 3, 4]
    let dst = [0, 0]
    view.blit_to(dst, dst_offset=1)
    @debug.debug_inspect(dst, content="[0, 2, 3, 4]")
    }

    Panics if:

    • dst_offset is negative
    • dst_offset exceeds the length of destination array

    ArrayView::chunk_by

    fn[T] ArrayView::chunk_by(self : ArrayView[T], pred : (T, T) -> Bool raise?) -> Array[ArrayView[T]] raise?

    Groups consecutive elements of the view into chunks where adjacent elements satisfy the given predicate. Each returned sub-view shares the original backing array.

    Example:

    test {
    let v = [1, 1, 2, 2, 2, 3, 1][:]
    debug_inspect(
    v.chunk_by((a, b) => a == b),
    content=(
    #|[
    #| <ArrayView: [1, 1]>,
    #| <ArrayView: [2, 2, 2]>,
    #| <ArrayView: [3]>,
    #| <ArrayView: [1]>,
    #|]
    ),
    )
    }

    ArrayView::chunks

    fn[T] ArrayView::chunks(self : ArrayView[T], size : Int) -> Array[ArrayView[T]]

    Split the array view into contiguous sub-views of length size. The last sub-view may be shorter if the view length is not a multiple of size. The returned sub-views share the original backing array — no elements are copied.

    Panics if size <= 0.

    Example:

    test {
    let v = [1, 2, 3, 4, 5, 6, 7][:]
    debug_inspect(
    v.chunks(3),
    content=(
    #|[<ArrayView: [1, 2, 3]>, <ArrayView: [4, 5, 6]>, <ArrayView: [7]>]
    ),
    )
    }

    ArrayView::compare

    fn[T : Compare + Eq] ArrayView::compare(self : ArrayView[T], other : ArrayView[T]) -> Int

    ArrayView::contains

    fn[T : Eq] ArrayView::contains(self : ArrayView[T], value : T) -> Bool

    Checks whether the array view contains a specific element by comparing each element with the target value using the equality operator.

    Parameters:

    • view : The array view to search in.
    • target : The value to search for in the array view.

    Returns a boolean value indicating whether the target value exists in the array view.

    Example:

    test {
    let arr = [1, 2, 3, 4, 5][:]
    inspect(arr.contains(3), content="true")
    inspect(arr.contains(6), content="false")
    }

    ArrayView::count

    fn[T : Eq] ArrayView::count(self : ArrayView[T], value : T) -> Int

    Counts how many elements in the array view are equal to value.

    Example

    test {
    let view = [1, 2, 1, 3, 1][:]
    inspect(view.count(1), content="3")
    inspect(view.count(4), content="0")
    }

    ArrayView::count_if

    fn[T] ArrayView::count_if(self : ArrayView[T], f : (T) -> Bool raise?) -> Int raise?

    Counts how many elements in the array view satisfy the predicate.

    Example

    test {
    let view = [1, 2, 3, 4, 5][:]
    inspect(view.count_if(x => x % 2 == 0), content="2")
    }

    ArrayView::each

    fn[T] ArrayView::each(self : ArrayView[T], f : (T) -> Unit raise?) -> Unit raise?

    Iterates over each element in the array view and applies a function to it.

    Parameters:

    • self : The array view to iterate over.
    • function : A function that takes an element of type T and returns nothing. This function will be applied to each element in the array view.

    Example:

    test {
    let arr = [1, 2, 3][:]
    let mut sum = 0
    arr.each(x => sum x)
    inspect(sum, content="6")
    }

    ArrayView::eachi

    fn[T] ArrayView::eachi(self : ArrayView[T], f : (Int, T) -> Unit raise?) -> Unit raise?

    Iterates over the elements of the array view with index.

    Example

    test {
    let v = [3, 4, 5][:]
    let mut sum = 0
    v.eachi((i, x) => sum x + i)
    inspect(sum, content="15")
    }

    ArrayView::ends_with

    fn[T : Eq] ArrayView::ends_with(self : ArrayView[T], suffix : ArrayView[T]) -> Bool

    Checks if the array view ends with the given suffix.

    Example

    test {
    let view = [1, 2, 3, 4, 5][:]
    inspect(view.ends_with([4, 5]), content="true")
    inspect(view.ends_with([3, 4]), content="false")
    }

    ArrayView::equal

    fn[T : Eq] ArrayView::equal(self : ArrayView[T], other : ArrayView[T]) -> Bool

    ArrayView::filter

    fn[T] ArrayView::filter(self : ArrayView[T], f : (T) -> Bool raise?) -> Array[T] raise?

    Filters the array view with a predicate function.

    Example

    test {
    let arr = [1, 2, 3, 4, 5, 6]
    let v = arr[2:].filter(x => x % 2 == 0)
    @test.assert_eq(v, [4, 6])
    }

    ArrayView::filter_map

    fn[A, B] ArrayView::filter_map(self : ArrayView[A], f : (A) -> B? raise?) -> Array[B] raise?

    Apply a function to each element of the view, keeping only the Some results. Returns a freshly allocated Array.

    Example:

    test {
    let v = [1, 2, 3, 4, 5][1:4]
    debug_inspect(
    v.filter_map(x => if x % 2 == 0 { Some(x * 10) } else { None }),
    content="[20, 40]",
    )
    }

    ArrayView::fold

    fn[A, B] ArrayView::fold(self : ArrayView[A], init~ : B, f : (B, A) -> B raise?) -> B raise?

    Fold out values from an ArrayView according to certain rules.

    Example

    test {
    let sum = [1, 2, 3, 4, 5][:].fold(init=0, (sum, elem) => sum + elem)
    inspect(sum, content="15")
    }

    ArrayView::foldi

    fn[A, B] ArrayView::foldi(self : ArrayView[A], init~ : B, f : (Int, B, A) -> B raise?) -> B raise?

    Fold out values from an ArrayView according to certain rules with index.

    Example

    test {
    let sum = [1, 2, 3, 4, 5][:].foldi(init=0, (index, sum, _elem) => sum + index)
    inspect(sum, content="10")
    }

    ArrayView::get

    fn[T] ArrayView::get(self : ArrayView[T], index : Int) -> T?

    Retrieves an element from the array view at the specified index.

    Parameters:

    • self : The array view to retrieve the element from.
    • index : The position in the array view from which to retrieve the element.

    Returns Some(element) if the index is within bounds, or None if the index is out of bounds.

    Example:

    test {
    let arr = [1, 2, 3, 4, 5]
    let view = arr[1:4]
    debug_inspect(view.get(0), content="Some(2)")
    debug_inspect(view.get(1), content="Some(3)")
    debug_inspect(view.get(2), content="Some(4)")
    debug_inspect(view.get(5), content="None")
    }

    ArrayView::get_view

    fn[T] ArrayView::get_view(self : ArrayView[T], start? : Int, end? : Int) -> ArrayView[T]?

    Creates a new view into a portion of the array view, returning None when indices are invalid.

    Parameters:

    • self : The array view to create a new view from.
    • start : The starting index in the current view (inclusive). Defaults to
    • end : The ending index in the current view (exclusive). Defaults to the length of the current view.

    Returns Some(ArrayView) that provides a window into the specified portion of the original array view, or None when the indices are invalid.

    Example:

    test {
    let arr = [1, 2, 3, 4, 5]
    let view = arr[1:4] // view = [2, 3, 4]
    let start = 1
    let end = 2
    debug_inspect(
    view.get_view(start~, end~),
    content=(
    #|Some(<ArrayView: [3]>)
    ),
    )
    let start = 4
    let end = 5
    debug_inspect(view.get_view(start~, end~), content="None")
    }

    ArrayView::hash

    fn[A : Hash] ArrayView::hash(self : ArrayView[A]) -> Int

    ArrayView::is_empty

    fn[T] ArrayView::is_empty(self : ArrayView[T]) -> Bool

    Returns whether the array view is empty.

    Example:

    test {
    let view = [1, 2, 3][:]
    inspect(view.is_empty(), content="false")
    let empty = [1, 2][0:0]
    inspect(empty.is_empty(), content="true")
    }

    ArrayView::is_sorted

    fn[T : Compare + Eq] ArrayView::is_sorted(self : ArrayView[T]) -> Bool

    Tests whether the array view is sorted in ascending order.

    Parameters:

    • self : The array view to be tested.
    • T : The type of elements in the array view. Must implement the Compare trait.

    Returns a boolean value indicating whether the array view is sorted in ascending order:

    • true if the array view is empty, contains only one element, or all elements are in ascending order.
    • false if any element is greater than the element that follows it.

    Example:

    test {
    let arr = [1, 2, 3, 4, 5]
    let view = arr[1:4]
    inspect(view.is_sorted(), content="true")
    let descending : ReadOnlyArray[Int] = [5, 4, 3, 2, 1]
    inspect(descending[:].is_sorted(), content="false")
    }

    ArrayView::iter

    #alias(iterator, deprecated="`iterator` is deprecated, use `iter` instead")
    fn[X] ArrayView::iter(self : ArrayView[X]) -> Iter[X]

    Returns an iterator that yields each element of the array view in sequence from start to end.

    Parameters:

    • array_view : The array view to iterate over.

    Returns an iterator that yields elements of type A from the array view. The iterator uses the view's stored length, so structural mutations to the underlying array after the view is created do not change how many steps the iterator attempts to take.

    Structural shrinking of the underlying array is unsupported and may cause later iterator steps to fail. The same caveat applies to rev_iter() and iter2().

    Example:

    test {
    let arr = [1, 2, 3]
    let view = arr[1:]
    let mut sum = 0
    view.iter().each(x => sum x)
    inspect(sum, content="5")
    }

    ArrayView::iter2

    #alias(iterator2, deprecated="`iterator2` is deprecated, use `iter2` instead")
    fn[X] ArrayView::iter2(self : ArrayView[X]) -> Iter2[Int, X]

    Returns an iterator that yields tuples of index and value indices start from 0.

    Example:
    test {
    let arr = [1, 2, 3]
    let view = arr[1:]
    let mut sum = 0
    let mut sum_keys = 0
    view
    .iter2()
    .each((i, x) => {
    sum x
    sum_keys i
    })
    inspect(sum, content="5")
    inspect(sum_keys, content="1")
    }

    ArrayView::join

    fn[A : ToStringView] ArrayView::join(self : ArrayView[A], separator : StringView) -> String

    Concatenate strings within an array into a single complete string.

    Example:

    test {
    let a : Array[String] = ["1", "2", "3"]
    let array_view = a[:]
    inspect(array_view.join(","), content="1,2,3")
    }

    ArrayView::last

    fn[T] ArrayView::last(self : ArrayView[T]) -> T?

    Returns the last element of the array view, if any.

    Example:

    test {
    let view = [1, 2, 3][:]
    debug_inspect(view.last(), content="Some(3)")
    let empty = [1, 2][0:0]
    debug_inspect(empty.last(), content="None")
    }

    ArrayView::length

    fn[T] ArrayView::length(self : ArrayView[T]) -> Int

    Returns the length (number of elements) of an array view.

    Parameters:

    • array_view : The array view whose length is to be determined.

    Returns an integer representing the number of elements in the array view.

    Example:

    test {
    let arr = [1, 2, 3, 4, 5]
    let view = arr[2:4]
    inspect(view.length(), content="2")
    }

    ArrayView::lexical_compare

    fn[T : Compare + Eq] ArrayView::lexical_compare(self : ArrayView[T], other : ArrayView[T]) -> Int

    Performs a lexicographical comparison of two array views.

    This method compares the array views element by element until a difference is found or one view is exhausted. Unlike the Compare trait implementation which uses shortlex order (shorter views come first), this method compares based purely on element values until a difference is found.

    Returns

    • A negative integer if self is lexicographically less than other
    • Zero if self is lexicographically equal to other
    • A positive integer if self is lexicographically greater than other

    Example

    test {
    inspect([1, 2][:].lexical_compare([1, 2, 3]), content="-1")
    inspect([1, 2, 3][:].lexical_compare([1, 2]), content="1")
    inspect([1, 2, 3][:].lexical_compare([1, 2, 3]), content="0")
    inspect([1, 2, 3][:].lexical_compare([1, 2, 4]), content="-1")
    }

    ArrayView::map

    fn[T, U] ArrayView::map(self : ArrayView[T], f : (T) -> U raise?) -> Array[U] raise?

    Maps a function over the elements of the array view.

    Example

    test {
    let v = [3, 4, 5]
    let v2 = v[1:].map(x => x + 1)
    @test.assert_eq(v2, [5, 6])
    }

    ArrayView::mapi

    fn[T, U] ArrayView::mapi(self : ArrayView[T], f : (Int, T) -> U raise?) -> Array[U] raise?

    Maps a function over the elements of the array view with index.

    Example

    test {
    let v = [3, 4, 5]
    let v2 = v[1:].mapi((i, x) => x + i)
    @test.assert_eq(v2, [4, 6])
    }

    ArrayView::rev

    fn[T] ArrayView::rev(self : ArrayView[T]) -> Array[T]

    Reverses the elements of the array view, returning a freshly allocated array containing the elements in reverse order. The original view is not modified.

    Example:

    test {
    let v = [1, 2, 3, 4, 5][1:4]
    debug_inspect(v.rev(), content="[4, 3, 2]")
    // The view itself is unchanged.
    debug_inspect(
    v,
    content=(
    #|<ArrayView: [2, 3, 4]>
    ),
    )
    }

    ArrayView::rev_each

    fn[T] ArrayView::rev_each(self : ArrayView[T], f : (T) -> Unit raise?) -> Unit raise?

    Iterates over the elements of the array view in reverse order (last to first).

    Example:

    test {
    let v = [1, 2, 3, 4, 5][1:4]
    let out = []
    v.rev_each(x => out.push(x))
    debug_inspect(out, content="[4, 3, 2]")
    }

    ArrayView::rev_eachi

    fn[T] ArrayView::rev_eachi(self : ArrayView[T], f : (Int, T) -> Unit raise?) -> Unit raise?

    Iterates over the elements of the array view in reverse order, passing the view-relative index of each element (0 for the first element yielded, the last position of the view).

    Example:

    test {
    let v = [10, 20, 30][:]
    let out = []
    v.rev_eachi((i, x) => out.push((i, x)))
    debug_inspect(out, content="[(0, 30), (1, 20), (2, 10)]")
    }

    ArrayView::rev_fold

    fn[A, B] ArrayView::rev_fold(self : ArrayView[A], init~ : B, f : (B, A) -> B raise?) -> B raise?

    Fold out values from an ArrayView according to certain rules in reversed turn.

    Example

    test {
    let sum = [1, 2, 3, 4, 5][:].rev_fold(init=0, (sum, elem) => sum + elem)
    inspect(sum, content="15")
    }

    ArrayView::rev_foldi

    fn[A, B] ArrayView::rev_foldi(self : ArrayView[A], init~ : B, f : (Int, B, A) -> B raise?) -> B raise?

    Fold out values from an ArrayView according to certain rules in reversed turn with index.

    Example

    test {
    let sum = [1, 2, 3, 4, 5][:].rev_foldi(init=0, (index, sum, _elem) => {
    sum + index
    })
    inspect(sum, content="10")
    }

    ArrayView::rev_iter

    #alias(rev_iterator, deprecated="`rev_iterator` is deprecated, use `rev_iter` instead")
    fn[X] ArrayView::rev_iter(self : ArrayView[X]) -> Iter[X]

    Return a reverse iterator over elements of this view.

    rev_iterator is a deprecated alias for this function.

    Example:

    test {
    let values = [1, 2, 3][:].rev_iter().collect()
    debug_inspect(values, content="[3, 2, 1]")
    }

    ArrayView::search

    fn[T : Eq] ArrayView::search(self : ArrayView[T], value : T) -> Int?

    Searches for the first occurrence of a value in the array view.

    Example

    test {
    let view = [1, 2, 3, 2, 4][:]
    debug_inspect(view.search(2), content="Some(1)")
    debug_inspect(view.search(5), content="None")
    }

    ArrayView::search_by

    fn[T] ArrayView::search_by(self : ArrayView[T], f : (T) -> Bool raise?) -> Int? raise?

    Searches for the first element in the view that satisfies the predicate f and returns its (view-relative) index, or None if no element matches.

    Example:

    test {
    let view = [1, 2, 3, 4, 5][1:]
    debug_inspect(view.search_by(x => x > 3), content="Some(2)")
    debug_inspect(view.search_by(x => x > 99), content="None")
    }

    ArrayView::start_offset

    fn[T] ArrayView::start_offset(self : ArrayView[T]) -> Int

    Return the starting index of this view in the underlying array.

    Example:

    test {
    let arr = [10, 20, 30]
    let v = arr[1:]
    inspect(v.start_offset(), content="1")
    }

    ArrayView::starts_with

    fn[T : Eq] ArrayView::starts_with(self : ArrayView[T], prefix : ArrayView[T]) -> Bool

    Checks if the array view starts with the given prefix.

    Example

    test {
    let view = [1, 2, 3, 4, 5][:]
    inspect(view.starts_with([1, 2]), content="true")
    inspect(view.starts_with([2, 3]), content="false")
    }

    ArrayView::strip_prefix

    fn[T : Eq] ArrayView::strip_prefix(self : ArrayView[T], prefix : ArrayView[T]) -> ArrayView[T]?

    Returns a sub-view with prefix removed from the start, or None if the view does not start with prefix. The returned view shares the original backing array — no allocation.

    Example:

    test {
    let v = [1, 2, 3, 4, 5][:]
    debug_inspect(
    v.strip_prefix([1, 2]),
    content=(
    #|Some(<ArrayView: [3, 4, 5]>)
    ),
    )
    debug_inspect(v.strip_prefix([2, 3]), content="None")
    }

    ArrayView::strip_suffix

    fn[T : Eq] ArrayView::strip_suffix(self : ArrayView[T], suffix : ArrayView[T]) -> ArrayView[T]?

    Returns a sub-view with suffix removed from the end, or None if the view does not end with suffix. The returned view shares the original backing array — no allocation.

    Example:

    test {
    let v = [1, 2, 3, 4, 5][:]
    debug_inspect(
    v.strip_suffix([4, 5]),
    content=(
    #|Some(<ArrayView: [1, 2, 3]>)
    ),
    )
    debug_inspect(v.strip_suffix([3, 4]), content="None")
    }

    ArrayView::suffixes

    fn[T] ArrayView::suffixes(self : ArrayView[T], include_empty? : Bool) -> Iter[ArrayView[T]]

    Return an iterator over suffix views of this array view.

    Set include_empty=true to include the empty suffix at the end.

    Example:

    test {
    let v = [1, 2][:]
    debug_inspect(
    v.suffixes().collect(),
    content=(
    #|[<ArrayView: [1, 2]>, <ArrayView: [2]>]
    ),
    )
    debug_inspect(
    v.suffixes(include_empty=true).collect(),
    content=(
    #|[<ArrayView: [1, 2]>, <ArrayView: [2]>, <ArrayView: []>]
    ),
    )
    }

    ArrayView::to_json

    fn[X : ToJson] ArrayView::to_json(self : ArrayView[X]) -> Json

    ArrayView::to_owned

    #alias(to_array, deprecated="`to_array` is deprecated, use `to_owned` instead")
    fn[T] ArrayView::to_owned(self : ArrayView[T]) -> Array[T]

    Copy the view elements into a newly allocated Array.

    Example

    test {
    let view = [1, 2, 3, 4, 5, 6][2:4]
    let arr = view.to_owned()
    @test.assert_eq(arr, [3, 4])
    }

    ArrayView::view

    #alias(sub, deprecated="Use _[_:_] instead")
    #alias("_[_:_]")
    fn[T] ArrayView::view(self : ArrayView[T], start? : Int, end? : Int) -> ArrayView[T]

    Creates a new view into a portion of the array view.

    Parameters:

    • self : The array view to create a new view from.
    • start : The starting index in the current view (inclusive). Defaults to
    • end : The ending index in the current view (exclusive). Defaults to the length of the current view.

    Returns a new ArrayView that provides a window into the specified portion of the original array view. The indices are relative to the start of the current view.

    Throws a panic if:

    • start is negative
    • end is greater than the length of the current view
    • start is greater than end

    Example:

    test {
    let arr = [1, 2, 3, 4, 5]
    let view = arr[1:4] // view = [2, 3, 4]
    let subview = view[1:2] // subview = [3]
    inspect(subview[0], content="3")
    }

    ArrayView::windows

    fn[T] ArrayView::windows(self : ArrayView[T], size : Int) -> Array[ArrayView[T]]

    Return all contiguous sub-views of the given size, stepping by one element. Returns an empty array if size exceeds the view length. Each returned sub-view shares the original backing array.

    Panics if size <= 0.

    Example:

    test {
    let v = [1, 2, 3, 4, 5][:]
    debug_inspect(
    v.windows(3),
    content=(
    #|[
    #| <ArrayView: [1, 2, 3]>,
    #| <ArrayView: [2, 3, 4]>,
    #| <ArrayView: [3, 4, 5]>,
    #|]
    ),
    )
    }

    Hasher

    type Hasher

    Represents a hasher that implements the xxHash32 algorithm. The hasher maintains a mutable accumulator that is updated with each value added to the hash computation.

    This struct provides methods for combining different types of values into a single hash value, making it suitable for implementing hash functions for custom types.

    Example:

    test {
    let hasher = Hasher(seed=0)
    hasher.combine_int(42)
    hasher.combine_string("hello")
    inspect(hasher.finalize(), content="860601284")
    }

    Hasher::Hasher

    #alias(new, deprecated="Use `Hasher()` instead")
    fn Hasher::Hasher(seed? : Int) -> Hasher

    Creates a new hasher with an optional seed value. Enables the constructor call syntax Hasher() and Hasher(seed=...).

    Parameters:

    • seed : An integer value used to initialize the hasher's internal state. When omitted, a randomly chosen process-wide seed is used on native, LLVM, and JavaScript targets. Wasm targets default to 0. Pass 0 explicitly when deterministic output is required.

    Returns a new Hasher instance initialized with the given seed value.

    Example:

    test {
    let h1 = Hasher(seed=0) // Create a hasher with default seed
    let h2 = Hasher(seed=42) // Create a hasher with custom seed
    let x = 123
    h1.combine(x)
    h2.combine(x)
    inspect(h1.finalize() != h2.finalize(), content="true") // Different seeds produce different hashes
    }

    Hasher::new remains available as a deprecated alias.

    Hasher::combine

    fn[T : Hash] Hasher::combine(self : Hasher, value : T) -> Unit

    Combines a hashable value with the current state of the hasher. This is typically used to incrementally build a hash value from multiple components.

    Parameters:

    • self : The hasher instance to update.
    • value : The value to be combined with the current hash state. Must implement the Hash trait.

    Example:

    test {
    let hasher = Hasher(seed=0)
    hasher.combine(42)
    hasher.combine("hello")
    inspect(hasher.finalize(), content="860601284")
    }

    Hasher::combine_bool

    fn Hasher::combine_bool(self : Hasher, value : Bool) -> Unit

    Combines a boolean value into the current hash state. The boolean value is converted to an integer (1 for true, 0 for false) before being combined with the hash.

    Parameters:

    • self : The hasher instance to update.
    • value : The boolean value to be combined into the hash state.

    Example:

    test {
    let hasher = Hasher(seed=0)
    hasher.combine_bool(true)
    inspect(hasher.finalize(), content="-205818221")
    }

    Hasher::combine_byte

    fn Hasher::combine_byte(self : Hasher, value : Byte) -> Unit

    Combines a byte value into the hash state.

    Parameters:

    • hasher : The hasher object to update with the byte value.
    • byte : The byte value to be combined into the hash.

    Example:

    test {
    let hasher = Hasher(seed=0)
    hasher.combine_byte(b'\xFF')
    inspect(hasher.finalize(), content="1955036104")
    }

    Hasher::combine_bytes

    fn Hasher::combine_bytes(self : Hasher, value : Bytes) -> Unit

    Combines a byte sequence into the hasher's internal state using xxHash32 algorithm. Processes the input bytes in chunks of 4 bytes for efficiency, with remaining bytes processed individually.

    Parameters:

    • hasher : The hasher object to update with the byte sequence.
    • bytes : The byte sequence to be combined into the hash.

    Example:

    test {
    let hasher = Hasher(seed=0)
    hasher.combine_bytes(b"\xFF\x00\xFF\x00")
    inspect(hasher.finalize(), content="-686861102")
    }

    Hasher::combine_char

    fn Hasher::combine_char(self : Hasher, value : Char) -> Unit

    Combines a character value into the hasher's internal state. The character is first converted to its Unicode code point (as an integer) before being combined.

    Parameters:

    • self : The hasher instance to update.
    • value : The character value to be combined into the hash state.

    Example:

    test {
    let hasher = Hasher(seed=0)
    hasher.combine_char('A')
    inspect(hasher.finalize(), content="-1625495534")
    }

    Hasher::combine_double

    fn Hasher::combine_double(self : Hasher, value : Double) -> Unit

    Combines a double-precision floating-point number into the hasher's internal state by reinterpreting its bits as a 64-bit integer. Maintains consistent hashing behavior regardless of the floating-point value's representation.

    Parameters:

    • hasher : The hasher to combine the value into.
    • value : The double-precision floating-point number to be combined into the hash.

    Example:

    test {
    let hasher = Hasher(seed=0)
    hasher.combine_double(3.14)
    inspect(hasher.finalize(), content="-428265677")
    }

    Hasher::combine_float

    #deprecated("This function is deprecated.")
    fn Hasher::combine_float(self : Hasher, value : Float) -> Unit

    Combines a 32-bit floating-point value into the hasher by reinterpreting its bit pattern as a 32-bit integer. The operation maintains the same hash result regardless of the floating-point value's representation.

    Parameters:

    • hasher : The hasher object that maintains the internal state of the hashing operation.
    • value : The 32-bit floating-point value to be combined into the hash.

    Example:

    test {
    let hasher = Hasher(seed=0)
    hasher.combine(3.14F)
    inspect(hasher.finalize(), content="635116317") // Hash of the bits of 3.14
    }

    Hasher::combine_int

    fn Hasher::combine_int(self : Hasher, value : Int) -> Unit

    Combines a 32-bit integer value into the hasher's internal state. The value is processed as a 4-byte sequence, and the internal accumulator is updated accordingly.

    Parameters:

    • self : The hasher instance to update.
    • value : A 32-bit integer value to be incorporated into the hash.

    Example:

    test {
    let hasher = Hasher(seed=0)
    hasher.combine_int(42)
    inspect(hasher.finalize(), content="1161967057")
    }

    Hasher::combine_int64

    fn Hasher::combine_int64(self : Hasher, value : Int64) -> Unit

    Combines a 64-bit integer value into the hash state by splitting it into two 32-bit parts and processing them separately. This method is used internally by the hash implementation to incorporate 64-bit integers into the hash computation.

    Parameters:

    • hasher : The hasher object whose internal state will be updated.
    • value : The 64-bit integer value to be incorporated into the hash state.

    Example:

    test {
    let hasher = Hasher(seed=0)
    hasher.combine_int64(42L)
    inspect(hasher.finalize(), content="-1962516083")
    }

    Hasher::combine_string

    fn Hasher::combine_string(self : Hasher, value : String) -> Unit

    Combines a string value into the current hash state by processing each character in the string sequentially.

    Parameters:

    • self : The hasher object whose state will be updated.
    • value : The string value to be combined into the hash state.

    Example:

    test {
    let hasher = Hasher(seed=0)
    hasher.combine_string("hello")
    inspect(hasher.finalize(), content="-655549713")
    }

    Hasher::combine_uint

    fn Hasher::combine_uint(self : Hasher, value : UInt) -> Unit

    Combines an unsigned 32-bit integer into the hasher's internal state by reinterpreting it as a signed integer and incorporating it into the hash computation.

    Parameters:

    • hasher : The hasher object to update.
    • value : The unsigned 32-bit integer value to be combined into the hash.

    Example:

    test {
    let hasher = Hasher(seed=0)
    hasher.combine_uint(42U)
    inspect(hasher.finalize(), content="1161967057")
    }

    Hasher::combine_uint64

    fn Hasher::combine_uint64(self : Hasher, value : UInt64) -> Unit

    Combines a 64-bit unsigned integer into the hasher's internal state. Useful for hashing UInt64 values as part of a larger composite structure.

    Parameters:

    • self : The hasher instance to update.
    • value : The 64-bit unsigned integer value to be incorporated into the hash.

    Example:

    test {
    let hasher = Hasher(seed=0)
    hasher.combine_uint64(42UL)
    inspect(hasher.finalize(), content="-1962516083")
    }

    Hasher::combine_unit

    fn Hasher::combine_unit(self : Hasher) -> Unit

    Combines the unit value (i.e., ()) into the hasher's internal state by hashing it as an integer value of 0.

    Parameters:

    • hasher : The hasher object to combine the unit value into.

    Example:

    test {
    let hasher = Hasher(seed=0)
    hasher.combine_unit()
    inspect(hasher.finalize(), content="148298089")
    }

    Hasher::finalize

    fn Hasher::finalize(self : Hasher) -> Int

    Finalizes the hashing process and returns the computed hash value. Applies an avalanche function to improve the distribution of the hash value.

    Parameters:

    • hasher : The hasher object containing the accumulated hash state.

    Returns a 32-bit integer representing the final hash value.

    Example:

    test {
    let hasher = Hasher(seed=0)
    hasher.combine_byte(b'\xFF')
    inspect(hasher.finalize(), content="1955036104")
    }

    Iter

    #alias(Iterator, deprecated="The name `Iterator` is deprecated, use `Iter` instead. Note that if you have defined `iterator()` method to support `for .. in` loop, you should also rename `iterator()` to `iter()`. See https://github.com/moonbitlang/core/pull/3127 for more details.")
    type Iter[X]

    External iterator type. Iterator[X] is a mutable type: iterators internally maintain mutable state to advance iteration. All read operations on Iterator will advance the iterator, and would give different result when called multiple times.
    impl Add for Iter[T]
    impl Show for Iter[X]
    impl ToJson for Iter[X]

    Iter::add

    fn[T] Iter::add(self : Iter[T], other : Iter[T]) -> Iter[T]

    Iter::all

    fn[X] Iter::all(self : Iter[X], f : (X) -> Bool) -> Bool

    Return true if all elements satisfy predicate f. Function all.

    Iter::any

    fn[X] Iter::any(self : Iter[X], f : (X) -> Bool) -> Bool

    Return true if any element satisfies predicate f. Function any.

    Iter::concat

    fn[X] Iter::concat(self : Iter[X], other : Iter[X]) -> Iter[X]

    Combines two iterators into one by appending the elements of the second iterator to the first.

    Type Parameters

    • X: The type of the elements in the iterators.

    Arguments

    • self - The first input iterator.
    • other - The second input iterator to be appended to the first.

    Returns

    Returns a new iterator that contains the elements of self followed by the elements of other.

    Note

    The old iterators self and other must not be used again after calling concat.

    Iter::contains

    fn[X : Eq] Iter::contains(self : Iter[X], value : X) -> Bool

    Checks if the iterator contains an element equal to the given value.

    Parameters:

    • self : The iterator to search in.
    • value : The value to search for.

    Returns true if the iterator contains an element equal to the given value, false otherwise.

    Example:

    test {
    let iter = 1, 2, 3, 4, 5
    inspect(iter.contains(3), content="true")
    inspect(iter.contains(6), content="false")
    let iter =
    inspect(iter.contains(1), content="false")
    }

    Note

    The old iterator self will advance past the searched element.

    Iter::count

    #alias(length)
    fn[X] Iter::count(self : Iter[X]) -> Int

    Counts the number of elements in the iterator.

    Type Parameters

    • X: The type of the elements in the iterator.

    Arguments

    • self: The iterator to consume.

    Returns

    Returns the number of elements in the iterator.

    Iter::count_if

    fn[X] Iter::count_if(self : Iter[X], f : (X) -> Bool) -> Int

    Counts the number of elements in the iterator that satisfy the predicate.

    Type Parameters

    • X: The type of the elements in the iterator.

    Arguments

    • self: The iterator to consume.
    • f: A predicate function applied to each element.

    Returns

    Returns the number of elements for which f returns true.

    Iter::drop

    fn[X] Iter::drop(self : Iter[X], n : Int) -> Iter[X]

    Skips the first n elements from the iterator.

    Type Parameters

    • X: The type of the elements in the iterator.

    Arguments

    • self - The input iterator.
    • n - The number of elements to skip.

    Returns

    A new iterator that starts after skipping the first n elements.

    Note

    The old iterator self must not be used again after calling drop.

    Iter::drop_while

    fn[X] Iter::drop_while(self : Iter[X], f : (X) -> Bool) -> Iter[X]

    Skips elements from the iterator as long as the predicate function returns true.

    Type Parameters

    • X: The type of the elements in the iterator.

    Arguments

    • self - The input iterator.
    • f - The predicate function that determines whether an element should be skipped.

    Returns

    A new iterator that starts after skipping the elements as long as the predicate function returns true.

    Note

    The old iterator self must not be used again after calling drop_while.

    Iter::each

    fn[X] Iter::each(self : Iter[X], f : (X) -> Unit raise?) -> Unit raise?

    Iterates over each element in the iterator, applying the function f to each element.

    Type Parameters

    • X: The type of the elements in the iterator.

    Arguments

    • self: The iterator to consume.
    • f: A function that takes an element of type X and returns Unit. This function is applied to each element of the iterator.

    Iter::eachi

    fn[X] Iter::eachi(self : Iter[X], f : (Int, X) -> Unit raise?) -> Unit raise?

    Iterates over each element in the iterator, applying the function f to each element with index.

    Type Parameters

    • X: The type of the elements in the iterator.

    Arguments

    • self: The iterator to consume.
    • f: A function that takes an index of type Int and an element of type X and returns Unit. This function is applied to each element of the iterator.

    Iter::empty

    fn[X] Iter::empty() -> Iter[X]

    Creates an empty iterator.

    Prefer the iterator literal [||], which is equivalent and shorter.

    Type Parameters

    • X: The type of the elements in the iterator.

    Returns

    Returns an empty iterator of type Iter[X].

    Iter::filter

    fn[X] Iter::filter(self : Iter[X], f : (X) -> Bool) -> Iter[X]

    Filters the elements of the iterator based on a predicate function.

    Type Parameters

    • X: The type of the elements in the iterator.

    Arguments

    • self - The input iterator.
    • f - The predicate function that determines whether an element should be included in the filtered iterator.

    Returns

    A new iterator that only contains the elements for which the predicate function returns true.

    Note

    The old iterator self must not be used again after calling filter.

    Iter::filter_map

    fn[X, Y] Iter::filter_map(self : Iter[X], f : (X) -> Y?) -> Iter[Y]

    Transforms the elements of the iterator using a mapping function that returns an Option. The elements for which the function returns None are filtered out.

    The old iterator self must not be used again after calling filter_map.

    Iter::find_first

    fn[X] Iter::find_first(self : Iter[X], f : (X) -> Bool) -> X?

    Finds the first element in the iterator that satisfies the predicate function.

    Type Parameters

    • X: The type of the elements in the iterator.

    Arguments

    • self - The input iterator.
    • f - The predicate function that determines whether an element is the first element to be found.

    Returns

    An Option that contains the first element that satisfies the predicate function, or None if no such element is found.

    Note

    The iterator self will advance past the returned element.

    Iter::flat_map

    fn[X, Y] Iter::flat_map(self : Iter[X], f : (X) -> Iter[Y]) -> Iter[Y]

    Transforms each element of the iterator into an iterator and flattens the resulting iterators into a single iterator.

    Type Parameters

    • X: The type of the elements in the iterator.
    • Y: The type of the transformed elements.

    Arguments

    • self - The input iterator.
    • f - The function that transforms each element of the iterator into an iterator.

    Returns

    A new iterator that contains the flattened elements.

    Note

    The old iterator self and the iterators returned by f must not be used again after calling flat_map.

    Iter::flatten

    fn[X] Iter::flatten(self : Iter[Iter[X]]) -> Iter[X]

    iter.map(f).flatten() == iter.flat_map(f)

    Iter::fold

    fn[X, R] Iter::fold(self : Iter[X], init~ : R, f : (R, X) -> R raise?) -> R raise?

    Folds the elements of the iterator using the given function, starting with the given initial value.

    Type Parameters

    • X: The type of the elements in the iterator.
    • R: The type of the accumulator (result) value.

    Arguments

    • self: The iterator to consume.
    • f: A function that takes an accumulator of type R and an element of type X, and returns a new accumulator value.
    • init: The initial value for the fold operation.

    Returns

    Returns the final accumulator value after folding all elements of the iterator.

    Iter::intersperse

    fn[X] Iter::intersperse(self : Iter[X], sep : X) -> Iter[X]

    Inserts a separator element sep between each element of the iterator.

    Parameters

    • self : The iterator to intersperse the separator into.
    • sep : The separator element to insert between each element of the iterator.

    Examples

    test {
    let arr = []
    1, 2, 3.intersperse(0).each(i => arr.push(i))
    @test.assert_eq(arr, [1, 0, 2, 0, 3])
    }

    Note

    The old iterator self must not be used again after calling intersperse.

    Iter::iter

    #alias(iterator)
    fn[X] Iter::iter(self : Iter[X]) -> Iter[X]

    Return this iterator itself. Return an iterator via iter.

    Iter::iter2

    #alias(iterator2)
    fn[X] Iter::iter2(self : Iter[X]) -> Iter2[Int, X]

    Return an indexed view of this iterator. Return an iterator via iter2.

    Iter::join

    fn[A : ToStringView] Iter::join(self : Iter[A], sep : StringView) -> String

    Collects the string-renderable elements of the iterator into a single string, separated by sep. The old iterator self must not be used again after calling join.

    Iter::last

    fn[X] Iter::last(self : Iter[X]) -> X?

    Returns the last element of the iterator, or None if the iterator is empty. The old iterator self must not be used again after calling last.

    Iter::map

    fn[X, Y] Iter::map(self : Iter[X], f : (X) -> Y) -> Iter[Y]

    Transforms the elements of the iterator using a mapping function.

    Type Parameters

    • X: The type of the elements in the iterator.
    • Y: The type of the transformed elements.

    Arguments

    • self - The input iterator.
    • f - The mapping function that transforms each element of the iterator.

    Returns

    A new iterator that contains the transformed elements.

    Note

    The old iterator self must not be used again after calling map.

    Iter::map_while

    fn[X, Y] Iter::map_while(self : Iter[X], f : (X) -> Y?) -> Iter[Y]

    Transforms the elements of the iterator using a mapping function upto the function returns None. The old iterator self must not be used again after calling map_while.

    Iter::mapi

    fn[X, Y] Iter::mapi(self : Iter[X], f : (Int, X) -> Y) -> Iter[Y]

    Transforms the elements of the iterator using a mapping function.

    Type Parameters

    • X: The type of the elements in the iterator.
    • Y: The type of the transformed elements.

    Arguments

    • self - The input iterator.
    • f - The mapping function that transforms each element of the iterator with index.

    Returns

    A new iterator that contains the transformed elements.

    Note

    The old iterator self must not be used again after calling mapi.

    Iter::maximum

    fn[X : Compare + Eq] Iter::maximum(self : Iter[X]) -> X?

    Return the maximum element, or None if empty.

    Iter::minimum

    fn[X : Compare + Eq] Iter::minimum(self : Iter[X]) -> X?

    Return the minimum element, or None if empty.

    Iter::new

    fn[X] Iter::new(f : () -> X?, size_hint? : Int) -> Iter[X]

    Create a new iterator by supplying a next function directly. The supplied function should output the next element being iterated everytime it is called. If the number of remaining elements is known, pass it as size_hint.

    This function is intended for use by data structure authors, and should not be called by end users in general.

    Iter::next

    #alias(head)
    #alias(peek, deprecated="`peek` is deprecated, use `next` instead")
    fn[X] Iter::next(self : Iter[X]) -> X?

    Get the next element from an iterator, or return None if no more element exists. The returned element will be consumed from the iterator. Calling next repeatedly will iterate through all elements in the iterator.

    Iter::nth

    fn[X] Iter::nth(self : Iter[X], n : Int) -> X?

    Returns the n-th element of the iterator, counting from zero, or None if n is negative or the iterator has fewer than n + 1 elements. The iterator self will advance past the returned element.

    Iter::repeat

    fn[X] Iter::repeat(x : X) -> Iter[X]

    Creates an iterator that repeats the given element indefinitely.

    Type Parameters

    • X: The type of the elements in the iterator.

    Arguments

    • x: The element to be repeated.

    Returns

    Returns an iterator of type Iter[X] that repeats the element x indefinitely.

    Iter::singleton

    fn[X] Iter::singleton(elem : X) -> Iter[X]

    Creates an iterator that contains a single element.

    Prefer the iterator literal [|elem|], which is equivalent and shorter.

    Type Parameters

    • X: The type of the element in the iterator.

    Arguments

    • elem: The single element to be contained in the iterator.

    Returns

    Returns an iterator of type Iter[X] that contains the single element elem.

    Iter::size_hint

    fn[X] Iter::size_hint(self : Iter[X]) -> Int?

    Returns the hinted number of remaining elements if it is known.

    The hint is intended to be exact for iterators produced by trusted collection APIs and adapters, but it must not be used for correctness.

    Iter::take

    fn[X] Iter::take(self : Iter[X], n : Int) -> Iter[X]

    Takes the first n elements from the iterator.

    Type Parameters

    • X: The type of the elements in the iterator.

    Arguments

    • self - The input iterator.
    • n - The number of elements to take.

    Returns

    A new iterator that contains the first n elements.

    Note

    The old iterator self must not be used again after calling take.

    Iter::take_while

    fn[X] Iter::take_while(self : Iter[X], f : (X) -> Bool) -> Iter[X]

    Takes elements from the iterator as long as the predicate function returns true.

    Type Parameters

    • X: The type of the elements in the iterator.

    Arguments

    • self - The input iterator.
    • f - The predicate function that determines whether an element should be taken.

    Returns

    A new iterator that contains the elements as long as the predicate function returns true.

    Note

    The old iterator self must not be used again after calling take_while.

    Iter::tap

    fn[X] Iter::tap(self : Iter[X], f : (X) -> Unit) -> Iter[X]

    Applies a function to each element of the iterator without modifying the iterator.

    Type Parameters

    • X: The type of the elements in the iterator.

    Arguments

    • self - The input iterator.
    • f - The function to apply to each element of the iterator.

    Returns

    The same iterator.

    Note

    The old iterator self must not be used again after calling tap.

    Iter::to_array

    #alias(collect)
    fn[X] Iter::to_array(self : Iter[X]) -> Array[X]

    Collects the elements of the iterator into an array. The old iterator self must not be used again.

    Iter::to_json

    fn[X : ToJson] Iter::to_json(self : Iter[X]) -> Json

    Iter::view

    #alias(sub, deprecated="Use _[_:_] instead")
    #alias("_[_:_]")
    fn[X] Iter::view(self : Iter[X], start? : Int, end? : Int) -> Iter[X]

    Return a sliced iterator view in range [start, end). Function view.

    Iter::zip

    #alias(combine)
    fn[X, Y] Iter::zip(self : Iter[X], other : Iter[Y]) -> Iter[(X, Y)]

    Combines two iterators element-wise into an iterator of pairs.

    The resulting iterator stops as soon as either input iterator is exhausted.

    Type Parameters

    • X: The element type of self.
    • Y: The element type of other.

    Arguments

    • self - The first input iterator.
    • other - The second input iterator.

    Returns

    Returns a new iterator yielding tuples (x, y) where x comes from self and y comes from other.

    Example

    test {
    let numbers = (1).until(5)
    let letters = "a", "b", "c"
    debug_inspect(
    numbers.zip(letters).collect(),
    content="[(1, \"a\"), (2, \"b\"), (3, \"c\")]",
    )
    }

    Note

    The old iterators self and other must not be used again after calling zip.

    Iter2

    #alias(Iterator2, deprecated="The name `Iterator2` is deprecated, use `Iter2` instead. Note that if you have defined `iterator2()` method to support `for .. in` loop, you should also rename `iterator2()` to `iter2()`. See https://github.com/moonbitlang/core/pull/3127 for more details.")
    pub(all) struct Iter2[X, Y](Iter[(X, Y)])

    This type is used for for _, _ in .. loop (for .. in loop with two loop variables), and should not be used directly in general.

    Iter2::concat

    fn[X, Y] Iter2::concat(self : Iter2[X, Y], other : Iter2[X, Y]) -> Iter2[X, Y]

    Concatenate two Iter2 streams.

    Iter2::each

    fn[X, Y] Iter2::each(self : Iter2[X, Y], f : (X, Y) -> Unit) -> Unit

    Apply callback to each pair.

    Iter2::iter

    #alias(iterator)
    fn[X, Y] Iter2::iter(self : Iter2[X, Y]) -> Iter[(X, Y)]

    Convert to plain iterator of pairs. Return an iterator via iter.

    Iter2::iter2

    #alias(iterator2)
    fn[X, Y] Iter2::iter2(self : Iter2[X, Y]) -> Iter2[X, Y]

    Return this two-variable iterator itself. Return an iterator via iter2.

    Iter2::new

    fn[X, Y] Iter2::new(f : () -> (X, Y)?, size_hint? : Int) -> Iter2[X, Y]

    Construct an Iter2 from a pair-producing function. If the number of remaining pairs is known, pass it as size_hint.

    Iter2::next

    fn[X, Y] Iter2::next(self : Iter2[X, Y]) -> (X, Y)?

    Get the next pair from the iterator.

    Iter2::to_array

    fn[X, Y] Iter2::to_array(self : Iter2[X, Y]) -> Array[(X, Y)]

    Collect all pairs into an array.

    Json

    pub enum Json {
    Null
    True
    False
    Number(Double, repr~ : String?)
    String(String)
    Array(Array[Json])
    Object(Map[String, Json])
    }

    JSON value type used by core serialization APIs.

    Example:

    test {
    let value : Json = Json::array([Json::number(1.0), Json::null()])
    inspect(value.stringify(), content="[1,null]")
    }
    impl Default for Json
    impl Eq for Json

    Json::Json

    fn[T : ToJson] Json::Json(value : T) -> Json

    Converts any value implementing ToJson into a Json.

    This is the constructor of Json, so it is written Json(value), and it is re-exported by the prelude — no import is needed. Prefer it over calling ToJson::to_json directly.

    Parameters:

    • value : The value to convert.

    Returns the Json representation of value.

    Example:

    test {
    @debug.debug_inspect(Json(42), content="Number(42)")
    @debug.debug_inspect(Json("hello"), content="String(\"hello\")")
    @debug.debug_inspect(Json([1, 2]), content="Array([Number(1), Number(2)])")
    }

    Json::array

    fn Json::array(array : Array[Json]) -> Json

    Creates a JSON array value from a MoonBit array.

    Parameters:

    • values : An array of JSON values to be converted to a JSON array value.

    Returns a JSON value representing the given array.

    Example:

    test {
    let values : Array[Json] = [1.0, "hello"]
    @debug.debug_inspect(
    Json::array(values),
    content="Array([Number(1), String(\"hello\")])",
    )
    }

    Json::boolean

    fn Json::boolean(boolean : Bool) -> Json

    Creates a JSON boolean value from a MoonBit boolean.

    Parameters:

    • boolean : A MoonBit boolean to be converted to a JSON boolean value.

    Returns a JSON value representing the given boolean.

    Example:

    test {
    @debug.debug_inspect(Json::boolean(true), content="True")
    @debug.debug_inspect(Json::boolean(false), content="False")
    }

    Json::empty_object

    fn Json::empty_object() -> Json

    JSON {} constant.

    Json::equal

    fn Json::equal(a : Json, b : Json) -> Bool

    Json::null

    fn Json::null() -> Json

    Creates a JSON null value.

    Returns a JSON value representing null.

    Json::number

    fn Json::number(number : Double, repr? : String) -> Json

    Creates a JSON number value from a double-precision floating-point number.

    Parameters:

    • value : A double-precision floating-point number to be converted to a JSON number.

    Returns a JSON value representing the given number.

    Example:

    test {
    @debug.debug_inspect(Json::number(3.14), content="Number(3.14)")
    inspect(
    Json::number(@double.infinity, repr="1e9999999999999999999999999999999").stringify(),
    content="1e9999999999999999999999999999999",
    )
    }

    Json::object

    fn Json::object(object : Map[String, Json]) -> Json

    Creates a JSON object value from a MoonBit map.

    Parameters:

    • map : A map from strings to JSON values to be converted to a JSON object value.

    Returns a JSON value representing the given map.

    Example:

    test {
    let map : Map[String, Json] = { "name": "John", "age": 42.0 }
    @debug.debug_inspect(
    Json::object(map),
    content="Object({ \"name\": String(\"John\"), \"age\": Number(42) })",
    )
    }

    Json::string

    fn Json::string(string : String) -> Json

    Creates a JSON string value from a MoonBit string.

    Parameters:

    • string : A MoonBit string to be converted to a JSON string value.

    Returns a JSON value representing the given string.

    Example:

    test {
    @debug.debug_inspect(Json::string("hello"), content="String(\"hello\")")
    }

    Map

    type Map[K, V]

    Mutable linked hash map that maintains the order of insertion, not thread safe.

    Example

    test {
    let map = { 3: "three", 8: "eight", 1: "one" }
    @test.assert_eq(map.get(2), None)
    @test.assert_eq(map.get(3), Some("three"))
    map.set(3, "updated")
    @test.assert_eq(map.get(3), Some("updated"))
    }
    impl Default for Map[K, V]
    impl Eq for Map[K, V]
    impl Show for Map[K, V]
    impl ToJson for Map[K, V]

    Map::Map

    #alias(from_array)
    fn[K : Hash + Eq, V] Map::Map(arr : ArrayView[(K, V)], capacity? : Int) -> Map[K, V]

    Create a hash map from an array. The optional capacity is treated as a minimum initial capacity and will be rounded up to the smallest power of 2 that can hold the requested capacity.

    Map::at

    #alias("_[_]")
    fn[K : Hash + Eq, V] Map::at(self : Map[K, V], key : K) -> V

    Get value with at access semantics.

    Map::capacity

    fn[K, V] Map::capacity(self : Map[K, V]) -> Int

    Get the capacity of the map.

    Map::clear

    fn[K, V] Map::clear(self : Map[K, V]) -> Unit

    Clears the map, removing all key-value pairs. Keeps the allocated space.

    Map::contains

    fn[K : Hash + Eq, V] Map::contains(self : Map[K, V], key : K) -> Bool

    Check if the hash map contains a key.

    Map::contains_kv

    fn[K : Hash + Eq, V : Eq] Map::contains_kv(self : Map[K, V], key : K, value : V) -> Bool

    Checks if a map contains a specific key-value pair.

    Parameters:

    • map : A map of type Map[K, V] to search in.
    • key : The key to look up in the map.
    • value : The value to be compared with the value associated with the key.

    Returns true if the map contains the specified key and its associated value equals the given value, false otherwise.

    Example:

    test {
    let map = { "a": 1, "b": 2 }
    inspect(map.contains_kv("a", 1), content="true")
    inspect(map.contains_kv("a", 2), content="false")
    inspect(map.contains_kv("c", 3), content="false")
    }

    Map::copy

    #alias(clone, deprecated="`clone` is deprecated, use `copy` instead")
    fn[K, V] Map::copy(self : Map[K, V]) -> Map[K, V]

    Copy the map, creating a new map with the same key-value pairs and order of insertion.

    Map::each

    fn[K, V] Map::each(self : Map[K, V], f : (K, V) -> Unit raise?) -> Unit raise?

    Iterate over all key-value pairs of the map in the order of insertion.

    Map::eachi

    fn[K, V] Map::eachi(self : Map[K, V], f : (Int, K, V) -> Unit raise?) -> Unit raise?

    Iterate over all key-value pairs of the map in the order of insertion, with index.

    Map::equal

    fn[K : Hash + Eq, V : Eq] Map::equal(self : Map[K, V], that : Map[K, V]) -> Bool

    Map::from_iter

    #alias(from_iterator, deprecated="`from_iterator` is deprecated, use `from_iter` instead")
    fn[K : Hash + Eq, V] Map::from_iter(iter : Iter[(K, V)]) -> Map[K, V]

    Create from iter.

    Map::get

    fn[K : Hash + Eq, V] Map::get(self : Map[K, V], key : K) -> V?

    Retrieves the value associated with a given key in the hash map.

    Parameters:

    • self : The hash map to search in.
    • key : The key to look up in the map.

    Returns Some(value) if the key exists in the map, None otherwise.

    Example:

    test {
    let map = { "key": 42 }
    debug_inspect(map.get("key"), content="Some(42)")
    debug_inspect(map.get("nonexistent"), content="None")
    }

    Map::get_from_bytes

    fn[V] Map::get_from_bytes(map : Map[Bytes, V], key : BytesView) -> V?

    Retrieves the value associated with a BytesView key in a map with Bytes keys.

    This function allows efficient lookups using BytesView without creating a new Bytes object. It's particularly useful when working with byte slices or subranges of existing byte arrays.

    Parameters:

    • map : The hash map with Bytes keys to search in.
    • key : A BytesView representing the key to look up.

    Returns Some(value) if a matching key exists in the map, None otherwise.

    Example:

    test {
    let map = { b"hello": 1, b"world": 2 }
    let bytes = b"prefix_hello_suffix"
    let view = bytes[7:12] // view of "hello"
    debug_inspect(map.get_from_bytes(view), content="Some(1)")
    }

    Map::get_from_string

    fn[V] Map::get_from_string(map : Map[String, V], key : StringView) -> V?

    Retrieves the value associated with a StringView key in a map with String keys.

    This function allows efficient lookups using StringView without creating a new String object. It's particularly useful when working with substrings or string slices.

    Parameters:

    • map : The hash map with String keys to search in.
    • key : A StringView representing the key to look up.

    Returns Some(value) if a matching key exists in the map, None otherwise.

    Example:

    test {
    let map = { "hello": 1, "world": 2 }
    let str = "say hello to everyone"
    let view = str.view(start_offset=4, end_offset=9) // view of "hello"
    debug_inspect(map.get_from_string(view), content="Some(1)")
    }

    Map::get_or_default

    fn[K : Hash + Eq, V] Map::get_or_default(self : Map[K, V], key : K, default : V) -> V

    Returns the value associated with the key in the map, or computes and returns a default value if the key does not exist.

    Parameters:

    • map : The map to search in.
    • key : The key to look up in the map.
    • default : A function that returns a default value when the key is not found.

    Returns either the value associated with the key if it exists, or the result of calling the default function.

    Example:

    test {
    let map = { "a": 1, "b": 2 }
    inspect(map.get_or_default("a", 0), content="1")
    inspect(map.get_or_default("c", 42), content="42")
    }

    Map::get_or_init

    fn[K : Hash + Eq, V] Map::get_or_init(self : Map[K, V], key : K, default : () -> V) -> V

    Returns the value for the given key, or sets and returns a default value if the key does not exist.

    Map::is_empty

    fn[K, V] Map::is_empty(self : Map[K, V]) -> Bool

    Check if the hash map is empty.

    Map::iter

    #alias(iterator, deprecated="`iterator` is deprecated, use `iter` instead")
    fn[K, V] Map::iter(self : Map[K, V]) -> Iter[(K, V)]

    Returns the iterator of the hash map, provide elements in the order of insertion.

    Map::iter2

    #alias(iterator2, deprecated="`iterator2` is deprecated, use `iter2` instead")
    fn[K, V] Map::iter2(self : Map[K, V]) -> Iter2[K, V]

    Return an iterator via iter2.

    Map::keys

    fn[K, V] Map::keys(self : Map[K, V]) -> Iter[K]

    Return an iterator of keys.

    Map::length

    #alias(size, deprecated="`size` is deprecated, use `length` instead")
    fn[K, V] Map::length(self : Map[K, V]) -> Int

    Get the number of key-value pairs in the map.

    Map::map

    fn[K, V, V2] Map::map(self :