MoonBit Update
-
We added support for
+=
operators, including:+=
,=
,=
and/=
. You can use them to mutate the value of a mutable variable.fn init { let array = [1,2,3,4] array[2] *= 10 println(array) // [1, 2, 30, 4] } fn init { let mut a = 1 a += 20 println(a) // 21 }
struct Foo { data : Array[Int] } derive(Debug) fn op_set(self : Foo, index : Int, value : Int) { self.data[index] = value } fn op_get(self : Foo, index : Int) -> Int { self.data[index] } fn init { let foo : Foo = { data: [0,0,0,0] } foo[2] -= 10 debug(foo) // {data: [0, 0, -10, 0]} }
-
Toplevel declarations that are not left-aligned will be an error now.
-
New language feature: Super Trait. A super trait can be specified using
:
, e.g.trait A { // ... } trait B : A { // A is a super trait of B, B is a sub trait of A // ... }
You can specify that a trait has multiple super traits, which means this trait requires those super traits to be implemented:
// ... trait B: A + Compare + Debug { // ^~~ B is a sub-trait of A *and* Compare *and* Debug // ... }
Wherever a trait is required, a sub-trait of that trait can also be used, but not the other way around. For built-in traits, we make
Compare
a sub-trait ofEq
. This means if you have a value of typeA : Compare
, you can put it into a place whereEq
trait is required. For example,trait Eq { op_equal(Self, Self) -> Bool } trait Compare: Eq { compare(Self, Self) -> Int } fn eq[X: Compare](this: X, that: X) -> Bool { this == that // Ok. } fn compare[X: Eq](this: X, that: X) -> Int { this.compare(that) // !! Error // ^~~~~~~ Type X has no method compare. }
-
We added
T::[x, y, ...]
as a short-hand notation forT::from_array([x, y, ...])
, to provide a more handy way to initialize array-like structures, for example, a list.enum List[X] { Nil Cons(X, List[X]) } derive(Show, Debug) fn List::from_array[X](array: Array[X]) -> List[X] { let mut list = List::Nil for i = array.length() - 1; i >= 0; i = i - 1 { list = Cons(array[i], list) } list } fn main { println(List::[1, 2, 3]) // outputs Cons(1, Cons(2, Cons(3, Nil))) }
-
fn hello() = "xx"
has been deprecated. Instead, we suggest you write it as follows:extern "wasm" fn hello () = #| ...
For now inline stubs like these only support wasmgc, not wasm1.
-
The logic of derived
Show
implementation is modified. It now usesDebug
as implementation. So to deriveShow
for a type, users now need to implement or deriveDebug
for that type first.Debug
’s output is valid MoonBit syntax for creating values, whileShow
can be used to produce better-looking output. This solves the problems of derivedShow
implementation withString
fields:struct T { x: String } derive(Show, Debug) fn init { println({ x: "1, y: 2" }) // before: {x: 1, y: 2} // now: {x: "1, y: 2"} }
-
Dropping non-unit values is now an error. Use
ignore
to explicitly discard them.fn f() -> Int { ignore(3) // Ok. 3 |> ignore // Ok. 3 // Err: Expr Type Mismatch: has type Int, wanted Unit 3 // Ok, as this value is returned, not dropped }
-
test
is now a keyword, and cannot be used as an identifier anymore.
IDE Update
- Better support for Markdown in online IDE.
- MoonBit Code inside markdown will be highlighted.
- We open-sourced a simple tools to check the syntax correctness of MoonBit code blocks in a markdown documentation at GitHub - moonbitlang/moonbit-markdown: markdown linter for MoonBit . Refer to its README for usage.
Build System Update
- We support the
main
function now. However, there are some caveats you might want to know- It can only be in the
main
package (whereis_main: true
). - The
main
package should have exactly onemain
function. - It will be executed after all
init
functions - We disallow any
test
to co-exists with themain
function inside the same package.
- It can only be in the
- You can use
moon upgrade
to upgrade your MoonBit toolchain to the latest version. However, before using it, you must run the installation script one more time - The
moon check|build|run
command now defaults to linking with the standard librarymoonbitlang/core
.