The MoonBit Update——0708

Language Update

  • [Breaking change] Modified array slice syntax from arr[start..end] to arr[start:end] similar to Python. This change is made to avoid syntax conflicts with the upcoming cascade method call x..f(). The old syntax will be deprecated soon.

  • [Breaking change on wasm backend] Code in fn init is now compiled into the start section.

    Previous versions compiled code from both fn init and fn main into a special function exported as “_start”, therefore, host environments needed to call “_start” for initialization and execution of the main function.

    The new version uses the wasm standard’s start section to execute fn init during module loading, eliminating the need to call “_start” for fn init. “_start” is only necessary when executing main.

  • [Breaking change] test block no longer returns Result type results.

    Error handling mechanisms are now used within test blocks to handle test failures. The standard library’s inspect function and helpers like @test.eq from the @test package are encouraged for writing tests, for example:


test "unwrap should return value on Some" {

let some : Int? = Some(42)

inspect(some, content="Some(42)")!

@test.eq(some.unwrap(), 42)!

}

  • Supports using @pkg.C to access constructors across packages. For example, if @pkgA contains the following declaration:

// pkgA

pub enum E1 { C1 }

Now, in another package, E1’s constructor C1 can be directly used, for instance:


// pkgB

fn main {

debug(@pkgA.C1)

}

In the same package, encountering duplicate public constructors will result in an error, for example:


pub enum E1 {

C1

}

pub enum E2 {

C1

^^ ------ There can be at most one public constructor with name C1.

}

Core Update

  • Migrated to a new error handling mechanism.

  • Migrated to unsigned integers, removed old compare_u, div_u, mod_u functions for Int and Int64 types; API adjustments include:

  • Int32.trunc_double_u, Int64.trunc_double_u

    changed to UInt.trunc_double, UInt64.trunc_double.

  • Int64::extend_i32_u changed to UInt64::extend_uint.

  • Double::convert_i32_u, Double::convert_i64_u

    changed to Double::convert_uint, Double::convert_uint64.

Build System Update

  • moon version --all displays moonrun’s version information:

$ moon version --all

moon 0.1.20240705 (0e8c10e 2024-07-05) ~/.moon/bin/moon

moonc v0.1.20240705+7fdd4a042 ~/.moon/bin/moonc

moonrun 0.1.20240703 (52ecf2a 2024-07-03) ~/.moon/bin/moonrun

  • Modified moon new project creation to default the license field to empty.

  • Diagnostics information rendering is now enabled by default.

Toolchain Update

  • VSCode plugin defaulted to installing the corresponding plugin version’s toolchain, changed from always installing the latest version.
1 Like

I’m trying to use the new arr[start:end] syntax with moon 0.1.20240715 (0188781 2024-07-15) but am getting this:

[4014] Error: Expr Type Mismatch
        has type : ArrayView[_/0]
        wanted   : Array[_/1]
    ╭─[/.../parse-data.mbt:53:9]
    │
 53 │         fields[0:fields.length() - 1],
    │         ──────────────┬──────────────
    │                       ╰──────────────── Expr Type Mismatch
        has type : ArrayView[_/0]
        wanted   : Array[_/1]
────╯
error: failed when testing

The generic function that is using this is:

fn eachi_exn[T, Err](arr : Array[T], func : (Int, T) -> Unit!Err) -> Unit!Err {
  for i = 0; i < arr.length(); i = i + 1 {
    func(i, arr[i])!
  }
}

If I change the generic function to this:

fn eachi_exn[T, Err](arr : ArrayView[T], func : (Int, T) -> Unit!Err) -> Unit!Err {
  for i = 0; i < arr.length(); i = i + 1 {
    func(i, arr[i])!
  }
}

then that line passes, but elsewhere in the code where I’m using Array[String] this change causes the corresponding error message in the other direction:

[4014] Error: Expr Type Mismatch
        has type : Array[String]
        wanted   : ArrayView[_/0]
    ╭─[/.../parse-data.mbt:39:5]
    │
 39 │     lines,
    │     ──┬──
    │       ╰──── Expr Type Mismatch
        has type : Array[String]
        wanted   : ArrayView[_/0]
────╯
error: failed when testing

It seems like the MoonBit compiler should implicitly treat an ArrayView[T] as a perfectly valid Array[T], right?

Or is there something else I need to do when writing this generic function in order to handle both cases?

Thank you, and keep up the great work!

Currently, to keep the type system simple, MoonBit cannot implicitly convert between Array[T] and ArrayView[T]. But you can create an array view from an array arr : Array[T] by arr[:]. This is a very cheap zero-copy operation.

In terms of API design, since ArrayView is more general (it can handle both full array and a part of a big array), I think you should use ArrayView[T] for the parameter of eachi_exn. At call site, if you want to call eachi_exn on an Array[T], you can write xs[:].eachi_exn(..)

1 Like

This may specific to your use case, but maybe you could use Iter[T] for passing the data? We encourage using Iter or Array to pass the data between structures.

In yesterday’s post: The MoonBit Update——0715 - Announcement - Moonbitlang, we are now supporting spread operator for anything that is kind of iterable. Since ArrayView is iterable, you can always pass convert ArrayView to Array with [..x].

1 Like