2025-06-16
Language Updatesβ
- Error Function Syntax Updated to
raise
-
The
!
syntax for representing errors has been replaced with the keywordraise
. The specific mappings are as follows:-
(..) -> T ! SomeErr
=>(..) -> T raise SomeErr
-
(..) -> T !
=>(..) -> T raise
-
(..) -> T ? Error
=>(..) -> T raise?
(This is a recently added error polymorphism syntax; it can be ignored if unfamiliar.) -
fn f!(..) { .. }
=>fn f(..) raise { .. }
-
fn!( ..) { .. }
=>fn (..) raise { .. }
The above changes can be auto-migrated using code formatting.
-
- Error Type Declaration Syntax Changed
- The syntax for defining error types,
type! T ..
, has been changed tosuberror T ..
. This change can also be automatically migrated using code formatting.
- Deprecation of
f!(..)
andf?(..)
- The
f!(..)
andf?(..)
syntaxes have been deprecated. Continued use of them will trigger compiler warnings. Code formatting can automatically remove!
for migration, butf?(..)
requires manual migration totry?
. This is because for cases likef?(g!(..))
, a simple change totry? f(g(..))
would alter the semantics, causing errors ing
to also be caught. Special attention is needed during manual migration off?(..)
.
- Function Type Parameter Syntax Aligned with
impl
- Several weeks ago, the position of type parameters in function definitions was moved from
fn f[..](..)
tofn[..] f(..)
to align withimpl
. Now, the old syntax is deprecated and will trigger compiler warnings. This change can be automatically migrated using code formatting.
- Simplified Syntax for
typealias
andtraitalias
-
Use
typealias B as A
andtraitalias B as A
instead oftypealias A = B
andtraitalias A = B.
Example:Old:
typealias Matrix[X] = Array[Array[X]]
New:
typealias Array[Array[X]] as Matrix[X]
This change can be auto-migrated.
- Multi-parameter
loop
syntax deprecated
- The multi-parameter
loop
syntax has been deprecated and should be replaced with aloop
that takes a tuple as its parameter. This change alignsloop
withmatch
more consistently. The MoonBit compiler can optimize away the overhead of tuples inloop
in release mode, so there is no need to worry about performance impacts.
- Trait Method Implementation Now Explicit
- For traits where "every method has a default implementation," previously all types would automatically implement them. Now, even if all methods of a trait have default implementations, explicit implementation is still required. If no custom implementation is needed,
impl Trait for Type
can be used to indicate "implement Trait for Type using all default methods."impl Trait for Type
can also serve as documentation or a TODO. MoonBit will automatically check whetherType
implementsTrait
and report an error if it does not.
- Cannot Use Dot Syntax Call Implementation Method for External Types
-
Previously,
impl
for external types could be called within the current package using.
. However, this feature was not refactoring-safe: upstream additions of methods could alter the behavior of downstream code. Therefore, this behavior has been deprecated. As an alternative, MoonBit now supports locally defining new methods for external types, with syntax identical to regular method definitions. Methods defined for external types have the following characteristics:-
They cannot be
pub
. This ensures no conflicts arise during cross-package collaboration. -
If the upstream package (where the type is defined) already has a method with the same name, the compiler will issue a warning.
-
Local methods have the highest priority during method resolution.
After this change, the resolution rules for x.f(..) are as follows (in order of priority):
- Local methods
- Methods from the package where
x
's type is defined impl
from the package wherex
's type is defined
-
- Auto Insertion of
to_json
for JSON Literals
- Within JSON literals, the compiler now automatically inserts
ToJson::to_json
calls for non-literal expressions, making JSON literals more convenient to write:
let x = 42
// Previously
let _ : Json = { "x": x.to_json() }
// Now
let _ : Json = { "x": x }
- Virtual Package Support for Abstract Types
- The virtual package feature now supports abstract types. Abstract types can be declared in
.mbti
interfaces, and different implementations can use different concrete types to fulfill the interface's abstract types.
- Simplified Syntax for Error Handling
- For handling errors in simple expressions,
try
can be omitted, andf(..) catch { .. }
can be written directly.
- Reserved Words Warning Mechanism
- A new set of reserved words has been added. These are not currently keywords but may become keywords in the future. Using these names in code will trigger compiler warnings.
Upcoming Changes to Be Released Before the MoonBit Beta on June 18β
-
New Arrow Function Syntax
(..) => expr
This syntax simplifies defining single-parameter inline functions. Example:
test {
let arr = [ 1, 2, 3 ]
arr
.map(x => x + 1) // Parentheses can be omitted for single parameters
.iter2()
.each((i, x) => println("\{i}: \{x}"))
}
-
Matrix Function Syntax Simplified
Matrix functions have been deprecated to simplify the syntax. Matrix functions of the form
fn { .. => expr }
can be replaced with arrow functions, while other matrix functions should be replaced with explicitfn
andmatch
. -
Deprecation of
xx._
Syntax innew type
DefinitionsPreviously, the
xx._
syntax could be used to convert a newtype into its underlying representation. However, this syntax was visually ambiguous with partial application syntax (_.f(..)
). Therefore, thexx._
syntax has been deprecated. Instead, the compiler will automatically generate an.inner()
method for each newtype to replace._
. This change can be automatically migrated using code formatting. -
Warnings on Ambiguous Precedence
For ambiguous or less widely known operator precedence combinations, such as
<<
and+
, MoonBit will now issue warnings. Adding parentheses manually or via code formatting will resolve the warnings. -
Introduction of
letrec
andand
for Local Mutual RecursionThe
letrec
andand
keywords have been introduced for declaring locally mutually recursive functions, e.g.:
fn main {
letrec even = fn (x: Int) { ... } // Anonymous function
and odd = x => ... // Arrow function
}
- The right-hand side of the equals sign must be a function-like value, such as an anonymous function or arrow function. The previous implicit mutual recursion syntax using fn will be deprecated, though self-recursive functions can still be declared with fn.*
-
fnalias
Cannot Be Used to Define Non-Function valuesThe
fnalias
keyword is now restricted to function definitions only. Uselet
to define other types of values.
Standard Library Updatesβ
- Leveraging the new error polymorphism feature, many higher-order functions in the standard library, such as
Array::each
, can now accept callback functions that may raise errors.
Toolchain Updatesβ
- Tests can now be written in the
main
package.moon test
will run tests in themain
package, whilemoon run
will execute themain
function. - The IDE's codelens now supports running tests in documentation.
moon test
andmoon check
now include tests in documentation by default.
MoonBit Beta Launch on June 18 β Developer Updates Transition to Monthly Reportsβ
After extensive refinement and continuous improvement based on community feedback, the MoonBit Beta version will be officially released on June 18, marking the transition to a more stable stage of the language.
Starting from this milestone, the MoonBit biweekly report will shift to a monthly cadence. Please stay tuned to this column for future updates.
We also welcome community feedback and discussion β feel free to share your thoughts and suggestions with us!