<!-- path: index.md -->
# MoonBit Documentation

MoonBit is an end-to-end programming language toolchain for cloud and edge computing using WebAssembly.

The IDE environment is available at [https://try.moonbitlang.com](https://try.moonbitlang.com) without any installation; it does not rely on any server either.

## Get started

- [**Tutorials**](tutorial/index.md): Follow tutorials to start your journey
- [**Language**](language/index.md): Introduction to detailed language specifications
- [**Standard library**](https://mooncakes.io/docs/moonbitlang/core/): documentation of the standard library `moonbitlang/core`
- [**Toolchains**](toolchain/index.md): Introduction to all the toolchains making developing MoonBit a unique experience.
- [**MoonPilot**](pilot/index.md): Introduction to MoonBit's code agent.

## Useful Sources

- [Homepage](https://www.moonbitlang.com): The official site of MoonBit, including:
  - [Download](https://www.moonbitlang.com/download/): How to install MoonBit toolchain
  - [Blogs](https://www.moonbitlang.com/blog/): Big news and updates from the team
  - [Updates](https://www.moonbitlang.com/weekly-updates/): Changelogs to language features
- [Document (this site)](https://docs.moonbitlang.com/en/): The complete and up to date document for MoonBit, including the sections mentioned before
- [Tour](https://tour.moonbitlang.com): Interactive language playground
- [mooncakes.io](https://mooncakes.io): Package registry along with API documents, including:
  - [Experimental library API](https://mooncakes.io/docs/moonbitlang/x/)

<!-- path: tutorial/index.md -->
## Tutorial

Here are some tutorials that may help you learn the programming language:

- [An interactive tour with language basics](https://tour.moonbitlang.com)
- [Tour for Beginners](tour.md)

<!-- path: tutorial/tour.md -->
### A Tour of MoonBit for Beginners

This guide is intended for newcomers, and it's not meant to be a 5-minute quick
tour. This article tries to be a succinct yet easy to understand guide for those
who haven't programmed in a way that MoonBit enables them to, that is, in a more
modern, functional way.

See [the General Introduction](../language/index.md) if you want to straight
delve into the language.

#### Installation

**The extension**

Currently, MoonBit development support is through the VS Code extension.
Navigate to
[VS Code Marketplace](https://marketplace.visualstudio.com/items?itemName=moonbit.moonbit-lang)
to download MoonBit language support.

**The toolchain**

> (Recommended) If you've installed the extension above, the runtime can be
> directly installed by running 'Install moonbit toolchain' in the action menu
> and you may skip this part:
> ![runtime-installation](imgs/runtime-installation.png)

We also provide an installation script: Linux & macOS users can install via

```bash
curl -fsSL https://cli.moonbitlang.com/install/unix.sh | bash
```

For Windows users, PowerShell is used:

```powershell
Set-ExecutionPolicy RemoteSigned -Scope CurrentUser; irm https://cli.moonbitlang.com/install/powershell.ps1 | iex
```

This automatically installs MoonBit in `$HOME/.moon` and adds it to your `PATH`.

If you encounter `moon` not found after installation, try restarting your
terminal or VS Code to let the environment variable take effect.

Do notice that MoonBit is not production-ready at the moment, it's under active
development. To update MoonBit, just run the commands above again.

Running `moon help` gives us a bunch of subcommands. But right now the only
commands we need are `build`, `run`, and `new`.

To create a project (or module, more formally), run `moon new <path>`, where path
is the place you would like to place the project. For example, if you execute
`moon new examine`, you will get:

```default
examine
├── Agents.md
├── cmd
│   └── main
│       ├── main.mbt
│       └── moon.pkg.json
├── LICENSE
├── moon.mod.json
├── moon.pkg.json
├── my_project_test.mbt
├── my_project.mbt
├── README.mbt.md
└── README.md -> README.mbt.md
```

which contains a `cmd/main` lib containing a `fn main` that serves as the entrance
of the program. Try running `cd my_project && moon run cmd/main`.

In this tutorial, we assume the project name is `examine`,
and the current working directory is also `examine`.

#### Example: Finding those who passed

In this example, we will try to find out, given the scores of some students, how
many of them have passed the test?

To do so, we will start with defining our data types, identify our functions,
and write our tests. Then we will implement our functions.

Unless specified, the following will be defined under the file `top.mbt`.

##### Data types

The [basic data types](../language/fundamentals.md#built-in-data-structures) in MoonBit includes the following:

- `Unit`
- `Bool`
- `Int`, `UInt`, `Int64`, `UInt64`, `Byte`, ...
- `Float`, `Double`
- `Char`, `String`, ...
- `Array[T]`, ...
- Tuples, and still others

To represent a struct containing a student ID and a score using a primitive
type, we can use a 2-tuple containing a student ID (of type `String`) and a
score (of type `Double`) as `(String, Double)`. However this is not very
intuitive as we can't identify with other possible data types, such as a struct
containing a student ID and the height of the student.

So we choose to declare our own data type using [struct](../language/fundamentals.md#struct):

```moonbit
struct Student {
  id : String
  score : Double
}
```

One can either pass or fail an exam, so the judgement result can be defined
using [enum](../language/fundamentals.md#enum):

```moonbit
enum ExamResult {
  Pass
  Fail
}
```

##### Functions

[Function](../language/fundamentals.md#functions) is a piece of code that takes some inputs and produces a result.

In our example, we need to judge whether a student have passed an exam:

```moonbit
fn is_qualified(student : Student, criteria: Double) -> ExamResult {
  ...
}
```

This function takes an input `student` of type `Student` that we've just defined, an input `criteria` of type `Double` as the criteria may be different for each course or different in each country, and returns an `ExamResult`.

The `...` syntax allows us to leave functions unimplemented for now.

We also need to find out how many students have passed an exam:

```moonbit
fn count_qualified_students(
  students : Array[Student],
  is_qualified : (Student) -> ExamResult
) -> Int {
  ...
}
```

In MoonBit, functions are first-classed, meaning that we can bind a function to a variable, pass a function as parameter or receiving a function as a result.
This function takes an array of students' structs and another function that will judge whether a student have passed an exam.

##### Writing tests

We can define inline tests to define the expected behavior of the functions. This is also helpful to make sure that there'll be no regressions when we refactor the program.

```moonbit
test "is qualified" {
  assert_eq(is_qualified(Student::{ id : "0", score : 50.0 }, 60.0), Fail)
  assert_eq(is_qualified(Student::{ id : "1", score : 60.0 }, 60.0), Pass)
  assert_eq(is_qualified(Student::{ id : "2", score : 13.0 }, 7.0), Pass)
}
```

We will get an error message, reminding us that `Show` and `Eq` are not implemented for `ExamResult`.

`Show` and `Eq` are **traits**. A trait in MoonBit defines some common operations that a type should be able to perform.

For example, `Eq` defines that there should be a way to compare two values of the same type with a function called `op_equal`:

```moonbit
trait Eq {
  op_equal(Self, Self) -> Bool
}
```

and `Show` defines that there should be a way to either convert a value of a type into `String` or write it using a `Logger`:

```moonbit
trait Show {
  output(Self, &Logger) -> Unit
  to_string(Self) -> String
}
```

And the `assert_eq` uses them to constraint the passed parameters so that it can compare the two values and print them when they are not equal:

```moonbit
fn assert_eq![A : Eq + Show](value : A, other : A) -> Unit {
  ...
}
```

We need to implement `Eq` and `Show` for our `ExamResult`. There are two ways to do so.

1. By defining an explicit implementation:
   ```moonbit
   impl Eq for ExamResult with op_equal(self, other) {
     match (self, other) {
       (Pass, Pass) | (Fail, Fail) => true
       _ => false
     }
   }
   ```

   Here we use [pattern matching](../language/fundamentals.md#pattern-matching) to check the cases of the `ExamResult`.
2. Other is by [deriving](../language/derive.md) since `Eq` and `Show` are [builtin traits](../language/methods.md#builtin-traits) and the output for `ExamResult` is quite straightforward:
   ```moonbit
   enum ExamResult {
     Pass
     Fail
   } derive(Show)
   ```

Now that we've implemented the traits, we can continue with our test implementations:

```moonbit
test "count qualified students" {
  let students = [
    { id: "0", score: 10.0 },
    { id: "1", score: 50.0 },
    { id: "2", score: 61.0 },
  ]
  let criteria1 = fn(student) { is_qualified(student, 10) }
  let criteria2 = fn(student) { is_qualified(student, 50) }
  assert_eq(count_qualified_students(students, criteria1), 3)
  assert_eq(count_qualified_students(students, criteria2), 2)
}
```

Here we use [lambda expressions](../language/fundamentals.md#local-functions) to reuse the previously defined `is_qualified` to create different criteria.

We can run `moon test` to see whether the tests succeed or not.

##### Implementing the functions

For the `is_qualified` function, it is as easy as a simple comparison:

```moonbit
fn is_qualified(student : Student, criteria : Double) -> ExamResult {
  if student.score >= criteria {
    Pass
  } else {
    Fail
  }
}
```

In MoonBit, the result of the last expression is the return value of the function, and the result of each branch is the value of the `if` expression.

For the `count_qualified_students` function, we need to iterate through the array to check if each student has passed or not.

A naive version is by using a mutable value and a [`for` loop](../language/fundamentals.md#for-loop):

```moonbit
fn count_qualified_students(
  students : Array[Student],
  is_qualified : (Student) -> ExamResult
) -> Int {
  let mut count = 0
  for i = 0; i < students.length(); i = i + 1 {
    if is_qualified(students[i]) == Pass {
      count += 1
    }
  }
  count
}
```

However, this is neither efficient (due to the border check) nor intuitive, so we can replace the `for` loop with a [`for .. in` loop](../language/fundamentals.md#for-in-loop):

```moonbit
fn count_qualified_students(
  students : Array[Student],
  is_qualified : (Student) -> ExamResult
) -> Int {
  let mut count = 0
  for student in students {
    if is_qualified(student) == Pass { count += 1}
  }
  count
}
```

Still another way is use the functions defined for [iterator](../language/fundamentals.md#iterator):

```moonbit
fn count_qualified_students(
  students : Array[Student],
  is_qualified : (Student) -> ExamResult
) -> Int {
  students.iter().filter(fn(student) { is_qualified(student) == Pass }).count()
}
```

Now the tests defined before should pass.

#### Making the library available

Congratulation on your first MoonBit library!

You can now share it with other developers so that they don't need to repeat what you have done.

But before that, you have some other things to do.

##### Adjusting the visibility

To see how other people may use our program, MoonBit provides a mechanism called ["black box test"](../language/tests.md#blackbox-tests-and-whitebox-tests).

Let's move the `test` block we defined above into a new file `top_test.mbt`.

Oops! Now there are errors complaining that:

- `is_qualified` and `count_qualified_students` are unbound
- `Fail` and `Pass` are undefined
- `Student` is not a struct type and the field `id` is not found, etc.

All these come from the problem of visibility. By default, a function defined is not visible for other part of the program outside the current package (bound by the current folder).
And by default, a type is viewed as an abstract type, i.e. we know only that there exists a type `Student` and a type `ExamResult`. By using the black box test, you can make sure that
everything you'd like others to have is indeed decorated with the intended visibility.

In order for others to use the functions, we need to add `pub` before the `fn` to make the function public.

In order for others to construct the types and read the content, we need to add `pub(all)` before the `struct` and `enum` to make the types public.

We also need to slightly modify the test of `count qualified students` to add type annotation:

```moonbit
test "count qualified students" {
  let students: Array[@examine.Student] = [
    { id: "0", score: 10.0 },
    { id: "1", score: 50.0 },
    { id: "2", score: 61.0 },
  ]
  let criteria1 = fn(student) { @examine.is_qualified(student, 10) }
  let criteria2 = fn(student) { @examine.is_qualified(student, 50) }
  assert_eq(@examine.count_qualified_students(students, criteria1), 3)
  assert_eq(@examine.count_qualified_students(students, criteria2), 2)
}
```

Note that we access the type and the functions with `@examine`, the name of your package. This is how others use your package, but you can omit them in the black box tests.

And now, the compilation should work and the tests should pass again.

##### Publishing the library

Now that you've ready, you can publish this project to [mooncakes.io](https://mooncakes.io),
the module registry of MoonBit. You can find other interesting projects there
too.

1. Execute `moon login` and follow the instruction to create your account with
   an existing GitHub account.
2. Modify the project name in `moon.mod.json` to
   `<your github account name>/<project name>`. Run `moon check` to see if
   there's any other affected places in `moon.pkg.json`.
3. Execute `moon publish` and your done. Your project will be available for
   others to use.

By default, the project will be shared under [Apache 2.0](https://www.apache.org/licenses/LICENSE-2.0.html),
which is a permissive license allowing everyone to use. You can also use other licenses, such as the [MulanPSL 2.0](https://spdx.org/licenses/MulanPSL-2.0.html),
by changing the field `license` in `moon.mod.json` and the content of `LICENSE`.

##### Closing

At this point, we've learned about the very basic and most not-so-trivial
features of MoonBit, yet MoonBit is a feature-rich, multi-paradigm programming
language. Visit [language tours](https://tour.moonbitlang.com) for more information in grammar and basic types,
and other documents to get a better hold of MoonBit.

<!-- path: tutorial/for-go-programmers/index.md -->
### MoonBit for Go Programmers

MoonBit is a modern programming language designed for cloud and edge computing.
If you're coming from Go, you'll find some familiar concepts alongside powerful
new features that make MoonBit a simple yet expressive and performant language.

#### Key Similarities

Both Go and MoonBit are:

- **Statically typed** with type inference
- **Compiled languages** with fast compilation
- **Memory safe**, though through slightly different mechanisms
- **Designed for modern computing** with excellent tooling

#### Major Differences at a Glance

| Aspect                | Go                                          | MoonBit                                                  |
|-----------------------|---------------------------------------------|----------------------------------------------------------|
| **Paradigm**          | Imperative with certain functional features | Both functional and imperative                           |
| **Memory Management** | Garbage collected                           | Reference counting/GC (backend dependent)                |
| **Error Handling**    | Multiple return values                      | Checked error-throwing functions                         |
| **Generics**          | Interfaces and type parameters              | Full generic system with traits (similar to Rust)        |
| **Pattern Matching**  | Limited (`switch` statements)               | Comprehensive pattern matching                           |
| **Target Platforms**  | Native binaries                             | WebAssembly, JavaScript, native binaries (via C or LLVM) |

#### Identifiers and Naming Conventions

In Go, identifiers are case-sensitive and must start with a Unicode letter
or an underscore, followed by any number of Unicode letters, Unicode digits,
or underscores.

Since the first letter of a Go identifier dictates its visibility
(uppercase for public, lowercase for private), the convention is to use
camelCase for private items, and PascalCase for public ones:

```go
type privateType int
var PublicVariable PublicType = PublicFunction()
privateVariable := privateFunction()
```

In MoonBit, identifiers are also case-sensitive and follow a very similar
set of rules as Go, but the casing of the initial letter has no effect on
visibility. Instead, lowercase initial letters should be used for
variables and functions, while uppercase ones are reserved for types,
traits, enumeration variants, etc.

As a result, the MoonBit convention is to use snake_case for the former
category, and CamelCase for the latter:

```moonbit
Enumeration::Variant(random_variable).do_something()
impl[T : Trait] for Structure[T] with some_method(self, other) { ... }
```

#### Variable Bindings

In Go, new bindings are created using `var` or `:=`.
Type inference is activated by the `:=` syntax or the omission of type
annotation when using `var`.
There is no way to mark a variable as immutable.

```go
var name string = "MoonBit"
var count = 25 // Or `count := 25`
// There are no immutable variables in Go
```

In MoonBit, new bindings are created with the `let` keyword.
They are immutable by default, and you can use `let mut` to create mutable ones.
Types can be optionally specified with `:` after the variable name, and type
inference is used in the absent case.

```moonbit
let mut name : String = "MoonBit"
let mut count = 25
let pi = 3.14159 // Omit `mut` to create an immutable binding
```

Note `mut` is only allowed in local bindings, and not allowed in global bindings.

#### Newtypes

Newtypes are used to create type-safe wrappers around existing types,
so that you can define domain-specific types with the same underlying
representation as the original type, but with a different set of
available operations.

In Go, newtypes can be created using the `type` keyword.
A round trip from the underlying value to the newtype-wrapped one is
possible via the `T()` conversion syntax:

```go
type Age int

age := Age(25)
ageInt := int(age)
```

Newtypes are defined as tuple struct in MoonBit:

```moonbit
struct Age(Int)

let age = Age(25)
let age_int = age.0
```

#### Type Aliases

Type aliases can be created using the `type ... = ...` syntax in Go:

```go
type Description = string
```

In MoonBit, the `typealias` keyword is used instead:

```moonbit
typealias String as Description
```

#### Structures

In Go, named structures are newtypes of anonymous structures `struct { ... }`,
hence the common `type ... struct { ... }` idiom:

```go
type Person struct {
    Name string
    Age  int
}
```

The `Person` structure can be created using literals like so:

```go
john := Person{
    Name: "John Doe",
    Age:  30,
}

// Field names can be omitted if the field order is respected:
alice := Person{"Alice Smith", 25}
```

In MoonBit, all structures must be named, and they are defined
using the `struct` keyword:

```moonbit
struct Person {
  name : String
  age : Int
}
```

The `Person` structure can be created using literals like so:

```moonbit
let john = Person::{ name: "John Doe", age: 30 }

// Type name can be omitted if the type can be inferred:
let alice : Person = { name: "Alice Smith", age: 25 }
```

#### Enumerations

Enumerations allow you to define a type with a fixed set of values.

In Go, enumeration is not a language feature, but rather an idiom
of using `iota` to create a sequence of constants:

```go
type Ordering int
const (
    Less Ordering = iota
    Equal
    Greater
)
```

On the other hand, MoonBit has a built-in `enum` keyword for defining
enumerations:

```moonbit
enum Ordering {
  Less
  Equal
  Greater
}
```

In addition, MoonBit's enumerations can also have payloads:

```moonbit
enum IntList {
  /// `Nil` represents an empty list and has no payload.
  Nil
  /// `Cons` represents a non-empty list and has two payloads:
  /// 1. The first element of the list;
  /// 2. The remaining parts of the list.
  Cons(Int, IntList)
}
```

#### Control Flow

One of MoonBit's key differences from Go is that lots of control structures have
actual return values instead of simply being statements that execute code.
This expression-centered approach allows for more concise and functional programming
patterns compared to Go's statement-based control flow.

##### `if` Expressions

In Go, `if` statements don't return values. As a result, you often need to write:

```go
var result string
if condition {
    result = "true case"
} else {
    result = "false case"
}
```

In MoonBit, `if` is an expression that returns a value:

```moonbit
let result = if condition {
  "true case"
} else {
  "false case"
}
```

##### `match` Expressions

In Go, `switch` statements can be used to match against values, but they don't
return values directly:

```go
var description string
switch err {
case nil:
    description = fmt.Sprintf("Success: %v", value)
default:
    description = fmt.Sprintf("Error: %s", err)
}
```

On the other hand, `match` expressions in MoonBit can actually return values:

```moonbit
let description = match status {
  Ok(value) => "Success: \{value}"
  Err(error) => "Error: \{error}"
}
```

For more details on `match` expressions, please refer to [Pattern Matching]().

##### `loop` Expressions

MoonBit's loops can return values as well.

Functional loops using the `loop` keyword are particularly powerful.
The loop body is similar to that of a `match` expression, where each arm tries to
match the loop variables and act on them accordingly.
You may use the `continue` keyword to start the next iteration of the loop with the given
loop values, or use the `break` keyword to exit the loop with some given output value.
At the trailing expression of each arm, the `break`ing is implicit and thus not required.

```moonbit
// Calculates the sum of all elements in an `xs : IntList`.
let sum = loop (xs, 0) {
  (Nil, acc) => acc
  (Cons(x, rest), acc) => continue (rest, x + acc)
}
```

##### `for` and `while` Expressions

MoonBit's `for` and `while` loops are also expressions that return values.

The `for` loop is similar to Go's `for` loop, with a variable initialization, condition, and update
clause respectively:

```moonbit
// Iterates from 1 to 6, summing even numbers.
let sum = for i = 1, acc = 0; i <= 6; i = i + 1 {
  if i % 2 == 0 {
    continue i + 1, acc + i
  }
} else {
  acc
}
```

There are a few distinct features of the `for` loop in MoonBit, however:

- The update clause is not in-place, but rather are used to assign new values to the loop variables.
- `continue` can (optionally) be used to start the next iteration with new input values.
  In that case, the update clause is skipped.
- The `else` clause is used to return the final value of the loop when it normally exits. If the loop
  is exited early with the `break` keyword, the value from the `break` clause is returned instead.

The `while` loop is equivalent to the `for` loop with a condition clause only, and it can also return
a value:

```moonbit
let result = while condition {
  // loop body
  if should_break {
    break "early exit value"
  }
} else {
  "normal completion value"
}
```

#### Generic Types

In Go, you can define a generic named structure using type parameters delimited
by square brackets `[]`:

```go
type ListNode[T any] struct {
    val  T
    next *ListNode[T]
}
```

In MoonBit, you would define a generic structure very similarly:

```moonbit
struct ListNode[T] {
  val : T
  next : ListNode[T]?
}
```

In addition, you can also define a generic MoonBit enumeration.
Below are two common generic enumerations available in MoonBit's standard library:

```moonbit
enum Option[T] {
  None
  Some(T)
}

enum Result[T, E] {
  Ok(T)
  Err(E)
}
```

#### Functions

In Go, functions are defined using the `func` keyword followed by
the function name, parameters, and return type.

```go
func add(a int, b int) int {
    return a + b
}
```

In MoonBit, function definitions use the `fn` keyword and a
slightly different syntax:

```moonbit
fn add(a : Int, b : Int) -> Int {
  a + b
}
```

Note the use of the `:` token to specify types, and the `->` token
to indicate the return type.
Also, the function body is an expression that returns a value, so the
`return` keyword is not required unless early exits are needed.

##### Value and Reference Semantics

Understanding how data is passed and stored is crucial when moving between programming languages.
Go and MoonBit, in particular, have different approaches to value and reference semantics.

In Go, **the value semantics is the default**.
That is, values are copied when passed to functions or assigned to variables:

```go
type Point struct {
    X int
    Y int
}

func modifyPointVal(p Point) {
    p.X = 100  // This modifies a copy, not the original
}

func main() {
    point := Point{X: 10, Y: 20}
    modifyPointVal(point)
    fmt.Println(point.X) // Still prints 10, not 100
}
```

To achieve **reference semantics** in Go, you often need to explicitly
create and dereference pointers:

```go
func modifyPointRef(p *Point) {
    p.X = 100  // This modifies the original through the pointer
}

func main() {
    point := Point{X: 10, Y: 20}
    modifyPointRef(&point)  // Create a pointer with the `&` operator
    fmt.Println(point.X)    // Now prints 100
}
```

Some other built-in types like slices and maps behave similarly to pointers in Go,
but all these types are still technically passed by value (the value being a reference):

```go
func incrementSlice(nums []int) {
    for i := range nums {
        nums[i]++  // Modifies original slice
    }
}

func modifyMap(m map[string]int) {
    m["key"] = 42  // Modifies original map
}
```

MoonBit is semantically *always passed by reference*.
But for immutable types and primitive types, they may be passed by value since
this is semantically the same, this is purely an optimization.

<!-- MoonBit does not have pointer types, and which semantic is used when passing a value
depends on its type: a value of an \*\*immutable type\*\* is passed by value, while that
of a \*\*mutable type\*\* is passed by reference. -->

Notable **primitive types** in MoonBit include
[`Unit`](../../language/fundamentals.md#unit)
, [`Boolean`](../../language/fundamentals.md#boolean)
, integers ([`Int`](../../language/fundamentals.md#number), [`Int64`](../../language/fundamentals.md#number), [`UInt`](../../language/fundamentals.md#number), etc.)
, floating-point numbers ([`Double`](../../language/fundamentals.md#number), [`Float`](../../language/fundamentals.md#number), etc.)
, [`String`](../../language/fundamentals.md#string)
, [`Char`](../../language/fundamentals.md#char)
, [`Byte`](../../language/fundamentals.md#byte-s).

Notable **immutable collection types** in MoonBit include
[tuples](../../language/fundamentals.md#tuple),
immutable collections such as `@immut/hashset.T[A]`,
and custom types with no `mut` fields.

On the other hand, notable **mutable collection types** include
mutable collections such as [`Array[T]`](../../language/fundamentals.md#array)
, [`FixedArray[T]`](../../language/fundamentals.md#array)
, and [`Map[K, V]`](../../language/fundamentals.md#map),
as well as custom types with at least one `mut` field.

For example, we can rewrite some of the above Go examples in MoonBit:

```moonbit
struct Point {
  mut x : Int
  mut y : Int
}

fn modify_point_ref(p : Point) -> Unit {
  p.x = 100 // Modifies the original struct
}

fn main {
  let point = Point::{ x: 10, y: 20 }
  modify_point_ref(point) // Passes the original struct by reference
  println("\{point.x}")   // Prints 100
}

fn increment_array(nums : Array[Int]) -> Unit {
  for i = 0; i < nums.length(); i = i + 1 {
    nums[i] += 1 // Modifies the original array
  }
}

fn modify_map(m : Map[String, Int]) -> Unit {
  m["key"] = 42 // Modifies the original map
}
```

###### The [`Ref[T]`](../../language/fundamentals.md#ref) Helper Type

When you need explicit mutable references to value types,
MoonBit provides the [`Ref[T]`](../../language/fundamentals.md#ref) type
which is roughly defined as follows:

```moonbit
struct Ref[T] {
  mut val : T
}
```

With the help of `Ref[T]`, you can create mutable references to a value
just like you would with pointers in Go:

```moonbit
fn increment_counter(counter : Ref[Int]) -> Unit {
  counter.val = counter.val + 1
}

fn main {
  let counter = Ref::new(0)
  increment_counter(counter)
  println(counter.val) // Prints 1
}
```

##### Generic Functions

In Go, you can define a generic function using type parameters:

```go
// `T` is a type parameter that must implement the `fmt.Stringer` interface.
func DoubleString[T fmt.Stringer](t T) string {
    s := t.String()
    return s + s
}
```

The same is true for MoonBit:

```moonbit
// `T` is a type parameter that must implement the `Show` trait.
fn[T : Show] double_string(t : T) -> String {
  let s = t.to_string()
  s + s
}
```

##### Named Parameters

MoonBit functions also support named arguments with an optional
default value using the `label? : Type` syntax:

```moonbit
fn named_args(named~ : Int, optional? : Int = 42) -> Int {
  named + optional
}

// This can be called like so:
named_args(named=10)               // optional defaults to 42
named_args(named=10, optional=20)  // optional is set to 20
named_args(optional=20, named=10)  // order doesn't matter
let named = 10
named_args(named~)                 // `label~` is a shorthand for `label=label`
```

##### Optional Return Values

For functions that may or may not logically return a value of type `T`,
Go encourages the use of multiple return values:

In particular, `(res T, ok bool)` is used to indicate an optional return value:

```go
func maybeDivide(a int, b int) (quotient int, ok bool) {
    if b == 0 {
        return 0, false
    }
    return a / b, true
}
```

In MoonBit, to return an optional value, you will simply need to return `T?`
(shorthand for `Option[T]`):

```moonbit
fn maybe_divide(a : Int, b : Int) -> Int? {
  if b == 0 {
    None
  } else {
    Some(a / b)
  }
}
```

##### Fallible Functions

For functions that may return an error, Go uses `(res T, err error)` at the return position:

```go
func divide(a int, b int) (quotient int, err error) {
    if b == 0 {
        return 0, errors.New("division by zero")
    }
    return a / b, nil
}
```

You can then use the above `divide` function with the common `if err != nil` idiom:

```go
func useDivide() error {
    q, err := divide(10, 2)
    if err != nil {
        return err
    }
    fmt.Println(q) // Use the quotient
    return nil
}
```

In MoonBit, fallible functions are declared a bit differently. To indicate that
the function might throw an error, write `T raise E` at the return type
position, where `E` is an error type declared with `suberror`:

```moonbit
suberror ValueError { ValueError(String) }

fn divide(a : Int, b : Int) -> Int raise ValueError {
  if b == 0 {
    raise ValueError("division by zero")
  }
  a / b
}
```

There are different ways to handle the error when calling such a throwing function:

```moonbit
// Option 1: Propagate the error directly.
fn use_divide_propagate() -> Unit raise ValueError {
  let q = divide(10, 2) // Rethrow the error if it occurs
  println(q) // Use the quotient
}

// Option 2: Use `try?` to convert the error to a `Result[T, E]` type.
fn use_divide_try() -> Unit raise ValueError {
  // The type annotation is optional
  let mq : Result[
    Int,
    ValueError,
  ] = try? divide(10, 2)
  match mq { // Refer to the section on pattern matching for more details
    Err(e) => raise e
    Ok(q) => println(q) // Use the quotient
  }
}

// Option 3: Use the `try { .. } catch { .. }` syntax to handle the error.
fn use_divide_try_catch() -> Unit raise ValueError {
  try {
    let q = divide(10, 2)
    println(q) // Use the quotient
  } catch {
    e => raise e
  }
}
```

#### Pattern Matching

Go has no builtin support for pattern matching.
In certain cases, you can use the `switch` statement to achieve similar functionality:

```go
func fibonacci(n int) int {
    switch n {
    case 0:
        return 0
    case 1, 2:
        return 1
    default:
        return fibonacci(n-1) + fibonacci(n-2)
    }
}
```

MoonBit, on the other hand, offers comprehensive pattern matching with the `match` keyword.

You can match against literal values such as booleans, integers, strings, etc.:

```moonbit
fn fibonacci(n : Int) -> Int {
  match n {
    0 => 0
    // `|` combines multiple patterns
    1 | 2 => 1
    // `_` is a wildcard pattern that matches anything
    _ => fibonacci(n - 1) + fibonacci(n - 2)
  }
}
```

In addition, it is possible to perform destructuring of structures and tuples:

```moonbit
struct Point3D {
  x : Int
  y : Int
  z : Int
}

fn use_point3d(p : Point3D) -> Unit {
  match p {
    { x: 0, .. } => println("x == 0")
    // The `if` guard allows you to add additional conditions
    // for this arm to match.
    { y, z, .. } if y == z => println("x != 0, y == z")
    _ => println("uncategorized")
  }
}
```

Finally, array patterns allow you to easily destructure arrays, bytes, strings, and views:

```moonbit
fn categorize_array(array : Array[Int]) -> String {
  match array {
    [] => "empty"
    [x] => "only=\{x}"
    [first, .. middle, last] =>
      "first=\{first} and last=\{last} with middle=\{middle}"
  }
}

fn is_palindrome(s : @string.View) -> Bool {
  match s {
    [] | [_] => true
    // `a` and `b` capture the first and last characters of the view, and
    // `.. rest` captures the middle part of the view as a new view.
    [a, .. rest, b] if a == b => is_palindrome(rest)
    _ => false
  }
}
```

#### Methods and Traits

Although both languages support methods and behavior sharing via traits/interfaces,
MoonBit's approach to methods and traits/interfaces differs significantly from Go's.

As we will see below, MoonBit allows for more flexibility and expressiveness in terms of
trait methods than go, since in MoonBit:

- A trait must be explicitly implemented for each type;
- A type's method is not necessarily object-safe (i.e. can be used in trait objects),
  in fact, they don't even need to have `self` as the first parameter at all.

##### Methods

In Go, methods are defined on types using the receiver syntax:

```go
type Rectangle struct {
    width, height float64
}

func (r *Rectangle) Area() float64 {
    return r.width * r.height
}

func (r *Rectangle) Scale(factor float64) {
    r.width *= factor
    r.height *= factor
}
```

Methods can be called using the `.method()` syntax:

```go
rect := Rectangle{width: 10.0, height: 5.0}
areaValue := rect.Area()
rect.Scale(2.0) // NOTE: `.Scale()` modifies the rectangle in place.
```

In MoonBit, however, a type `T`'s methods are simply functions defined with the
`T::` prefix.

This is how you would recreate the above `Rectangle` example in MoonBit:

```moonbit
struct Rectangle {
  // `mut` allows these fields to be modified in-place.
  mut width : Double
  mut height : Double
}

fn Rectangle::area(self : Rectangle) -> Double {
  self.width * self.height
}

fn Rectangle::scale(self : Rectangle, factor : Double) -> Unit {
  // NOTE: `self` have reference semantics here, since `Rectangle` is mutable.
  self.width *= factor
  self.height *= factor
}
```

... and you can call methods like this:

```moonbit
let rect = Rectangle::{ width: 10.0, height: 5.0 }
let area_value = rect.area()
rect.scale(2.0) // NOTE: `.scale()` modifies the rectangle in place.
```

##### Traits

Go uses interfaces for polymorphism:

```go
type Shape interface {
    Area() float64
    Perimeter() float64
}

// Implicitly implements the `Shape` interface for `Rectangle`
// `func (r *Rectangle) Area() float64` already exists
func (r *Rectangle) Perimeter() float64 {
    return 2 * (r.width + r.height)
}

// Static dispatch is possible using generic functions with type bounds
func PrintShapeInfo[T Shape](s T) {
    fmt.Printf("Area: %f, Perimeter: %f\n", s.Area(), s.Perimeter())
}

// Dynamic dispatch is possible using the interface type
func PrintShapeInfoDyn(s Shape) {
    PrintShapeInfo(s)
}

func TestRectangle(t *testing.T) {
    rect := &Rectangle{10, 5}
    PrintShapeInfo(rect)
    PrintShapeInfoDyn(rect)
}
```

MoonBit has traits, which are similar to Go interfaces:

```moonbit
trait Shape {
  area(Self) -> Double
  perimeter(Self) -> Double
}

// Explicitly implement the `Shape` trait for `Rectangle`
impl Shape for Rectangle with area(self) {
  // NOTE: This is a method call to the previously-defined `Rectangle::area()`,
  // thus no recursion is involved.
  self.area()
}

impl Shape for Rectangle with perimeter(self) {
  2.0 * (self.width + self.height)
}

// Static dispatch is possible using generic functions with type bounds
fn[T : Shape] print_shape_info(shape : T) -> Unit {
  println("Area: \{shape.area()}, Perimeter: \{shape.perimeter()}")
}

// Dynamic dispatch is possible using the `&Shape` trait object type
fn print_shape_info_dyn(shape : &Shape) -> Unit {
  print_shape_info(shape)
}

test {
  let rect = Rectangle::{ width: 10.0, height: 5.0 }
  print_shape_info(rect)
  print_shape_info_dyn(rect)
}
```

##### Object Safety

MoonBit traits can also include certain kinds of methods not available in Go interfaces,
such as the ones with no `self` parameter, as shown in the example below:

```moonbit
trait Name {
  name() -> String
}

impl Name for Rectangle with name() {
  "Rectangle"
}

// `T : Shape + Name` is a bound that requires the type `T` to
// implement both `Shape` and `Name`.
fn[T : Shape + Name] print_shape_name_and_info(shape : T) -> Unit {
  println(
    "\{T::name()}, Area: \{shape.area()}, Perimeter: \{shape.perimeter()}",
  )
}

test {
  print_shape_name_and_info(Rectangle::{ width: 10.0, height: 5.0 })
}
```

However, for a trait to be usable in a trait object, it must only contain object-safe methods.

There are a few requirements for a method of type `T` to be object-safe:

- `self : T` should be the first parameter of the method;
- Any other parameter of the method should not have the type `T`.

For example, in the above `Name` trait, the `name()` method is not object-safe because it does not
have a `self` parameter, and thus `Name` cannot be used in the hypothetical `&Name` trait object.

##### Trait Extensions

MoonBit traits can explicitly extend other traits, allowing you to build on existing functionality:

```moonbit
pub(open) trait Position {
  pos(Self) -> (Int, Int)
}

pub(open) trait Draw {
  draw(Self, Int, Int) -> Unit
}

pub(open) trait Object: Position + Draw {
  // You can add more required methods here...
}
```

Since the `Object` trait extends two traits `Position` and `Draw`, the latter two are called the
former's **supertrait**s.

##### Default Implementations

Unlike Go interfaces, MoonBit trait functions can have default implementations:

```moonbit
trait Printable {
  print(Self) -> Unit
  // `= _` marks the method as having a default implementation
  print_twice(Self) -> Unit = _
}

// The default implementation of `print_twice()` is provided individually:
impl Printable with print_twice(self) {
  self.print()
  self.print()
}
```

##### Operator Overloading

MoonBit supports operator overloading through built-in traits, which has no Go equivalent:

```moonbit
impl Add for Rectangle with add(self, other) {
  { width: self.width + other.width, height: self.height + other.height }
}

// Now you can use + with rectangles
let combined = rect1 + rect2
```

#### Imports and Package Management

Package management and imports work differently between Go and MoonBit.

##### Creating a Project

In Go, the first thing to do when creating a new project is running:

```console
$ go mod init example.com/my-project
```

This will initialize a `go.mod` file that tracks your project's dependencies.

Then you can create a `main.go` file with the `package main` declaration and
start writing your code:

```go
package main

import "fmt"

func main() { fmt.Println("Hello, 世界") }
```

In MoonBit, creating a new project is much easier. Simply run the `moon new`
command to set up your project:

```console
$ moon new my-project
```

##### Project Structure

The Go toolchain has few requirements for the project structure, apart
from the `go.mod` file being in the root directory of the project.
To scale up from a single `main.go` file to a larger project, you would
typically add more files and directories, resulting in a flat or nested
structure, depending on the style you choose.

While organizing the source files, the key point is that Go's tooling
doesn't distinguish between source files under a common directory, so you
can freely create multiple `.go` files in the same package directory, knowing
that they will be treated as a whole by the toolchain.
For definitions within source files of another directory, however,
you would need to import them before they can be used.

In MoonBit, on the other hand, the default project structure provided by
`moon new` is more organized, as shown below:

```txt
my-project
├── LICENSE
├── README.md
├── moon.mod.json
└── src
    ├── lib
    │   ├── hello.mbt
    │   ├── hello_test.mbt
    │   └── moon.pkg.json
    └── main
        ├── main.mbt
        └── moon.pkg.json
```

This demonstrates a typical "binary-and-library" project structure in MoonBit,
located in the `src` directory. This is declared in `moon.mod.json` like so
(with irrelevant parts omitted):

```json
{
  "source": "src"
}
```

This is the module configuration file that also registers the project's
basic information such as its name, version, and dependencies.

Each directory under the source directory (`src` in this example) is a package
with its own `moon.pkg.json` file containing package-specific metadata,
such as its imports, and whether it should be regarded as a main binary package.
For example, `src/lib/moon.pkg.json` is minimally defined as follows:

```json
{}
```

... and `src/main/moon.pkg.json` as follows:

```json
{
  "is_main": true,
  "import": ["username/hello/lib"]
}
```

Similarly to Go, MoonBit treats all `.mbt` files under a same package directory
as a whole. When creating a new directory for more source files, however,
a corresponding `moon.pkg.json` file is required under that directory.

##### Running the Project

To run the aforementioned Go project, you would typically use:

```console
$ go run main.go
```

Running the previous MoonBit project with `moon run` is very similar:

```console
$ moon run src/main/main.mbt
```

##### Adding Imports

In Go, you can add imports with the `import` clause followed by their module path:

```go
package main

import (
    "github.com/user/repo/sys"
)
```

MoonBit uses a different approach with `moon.mod.json` for module configuration and
`moon.pkg.json` for package configuration.

First, declare dependencies in the `"deps"` section of your `moon.mod.json`.
This is usually done with the `moon add <package>` command.

For example, to use `moonbitlang/x`, you would run:

```console
$ moon add moonbitlang/x
```

... which would result in a `moon.mod.json` file like so (with irrelevant parts omitted):

```json
{
  "deps": {
    "moonbitlang/x": "*"
  }
}
```

Then, in your package's `moon.pkg.json`, specify which packages to import
in the `"import"` section:

```json
{
  "import": ["moonbitlang/x/sys"]
}
```

Now you should be ready to use the `sys` package in this MoonBit package.

##### Using Imported Packages

In Go, the above import allows you to access the `sys` package's APIs
using the `<package-name>.` prefix (the actual API is hypothetical):

```go
func main() {
    sys.SetEnvVar("MOONBIT", "Hello")
}
```

In MoonBit, you access imported APIs using the `@<package-name>.` prefix:

```moonbit
fn main {
  @sys.set_env_var("MOONBIT", "Hello")
}
```

##### Package Aliases

In Go, you can create aliases for imported packages using the `import` statement:

```go
import (
    system "github.com/user/repo/sys"
)
```

In MoonBit, you can create aliases for imported packages in `moon.pkg.json` using the `alias` field:

```json
{
  "import": [
    {
      "path": "moonbitlang/x/sys"
      "alias": "system"
    }
  ]
}
```

Then you may use the alias like so:

```moonbit
fn main {
  @system.set_env_var("MOONBIT", "Hello")
}
```

##### Access Control

In Go, visibility is determined by the case of the first letter of an identifier
(uppercase for public, lowercase for private).

MoonBit has more granular access control than Go, providing the following visibility levels:

- `priv`: Completely private (like Go's lowercase identifiers)
- Default (abstract): Only the type name is visible, implementation is hidden
- `pub`: Read-only access from outside the package
- `pub(all)`: Full public access (like Go's uppercase identifiers)

This gives you fine-grained control over what parts of your API are exposed and how they can be used.

#### Runtime Support

The same MoonBit code can target multiple runtimes with different code generation
backends, allowing you to choose the best fit for your particular application:

- WebAssembly (for web and edge computing)
- JavaScript (for Node.js integration)
- C (for native performance)
- LLVM (experimental)

##### Memory Management

Go uses a garbage collector, while MoonBit uses different strategies depending on the
code generation backend being used:

- **Wasm/C backends**: Reference counting without cycle detection
- **Wasm GC/JavaScript backends**: Leverages the runtime's garbage collector

#### Getting Started

1. Visit [the online playground](https://try.moonbitlang.com).
2. Check out our [installation guide](../tour.md#installation).
3. Create your first MoonBit project:
   ```console
   $ moon new hello-world
   $ cd hello-world
   $ moon run
   ```

#### When to Choose MoonBit

MoonBit offers a fresh take on systems programming with functional programming benefits and WebAssembly-first design.
While different from Go's philosophy, it provides powerful tools for building efficient, safe, and maintainable applications.
Thus, MoonBit will be an interesting option for your project if you embrace:

- **WebAssembly targets** with minimal size and maximum performance
- **Functional programming** features like pattern matching and algebraic data types
- **Mathematical/algorithmic code** that benefits from immutability by default
- **Strong type safety** with comprehensive error handling

#### Next Steps

- Explore the [Language Fundamentals](../../language/fundamentals.md)
- Learn about [Error Handling](../../language/error-handling.md)
- Understand [Methods and Traits](../../language/methods.md)
- Check out [FFI capabilities](../../language/ffi.md) for interop

<!-- path: language/index.md -->
## MoonBit Language

MoonBit is an AI native programming language toolchain for cloud and edge computing. It compiles to WebAssembly, JavaScript, and C.

The IDE environment is available at [https://try.moonbitlang.com](https://try.moonbitlang.com) without any installation; it does not rely on any server either.

**Status and aimed timeline**

MoonBit is currently in beta-preview. We expect to reach 1.0 in 2025.

When MoonBit reaches beta, it means any backwards-incompatible changes will be seriously evaluated and MoonBit *can* be used in production(very rare compiler bugs). MoonBit is developed by a talented full time team who had extensive experience in building language toolchains, so we will grow much faster than the typical language ecosystem, you won't wait long to use MoonBit in your production.

**Main advantages**

- Generate significantly smaller WASM output than any existing solutions.
- Much faster runtime performance.
- State of the art compile-time performance.
- Simple but practical, data-oriented language design.

<!-- path: language/introduction.md -->
### Introduction

A MoonBit program consists of top-level definitions including:

- type definitions
- function definitions
- constant definitions and variable bindings
- `init` functions, `main` function and/or `test` blocks.

#### Expressions and Statements

MoonBit distinguishes between statements and expressions. In a function body, only the last clause should be an expression, which serves as a return value. For example:

```moonbit
fn foo() -> Int {
  let x = 1
  x + 1
}

fn bar() -> Int {
  let x = 1
  //! x + 1
  x + 2
}
```

Expressions include:

- Value literals (e.g. Boolean values, numbers, characters, strings, arrays, tuples, structs)
- Arithmetical, logical, or comparison operations
- Accesses to array elements (e.g. `a[0]`), struct fields (e.g `r.x`), tuple components (e.g. `t.0`), etc.
- Variables and (capitalized) enum constructors
- Anonymous local function definitions
- `match`, `if`, `loop` expressions, etc.

Statements include:

- Named local function definitions
- Local variable bindings
- Assignments
- `return` statements
- Any expression whose return type is `Unit`, (e.g. `ignore`)

A code block can contain multiple statements and one expression, and the value of the expression is the value of the code block.

#### Variable Binding

A variable can be declared as mutable or immutable using `let mut` or `let`, respectively. A mutable variable can be reassigned to a new value, while an immutable one cannot.

A constant can only be declared at top level and cannot be changed.

```moonbit
let zero = 0

const ZERO = 0

fn main {
  //! const ZERO = 0 
  let mut i = 10
  i = 20
  println(i + zero + ZERO)
}
```

###### NOTE
A top level variable binding

- requires **explicit** type annotation (unless defined using literals such as string, byte or numbers)
- can't be mutable (use `Ref` instead)

#### Naming conventions

Variables, functions should start with lowercase letters `a-z` and can contain letters, numbers, underscore, and other non-ascii unicode chars.
It is recommended to name them with snake_case.

Constants, types should start with uppercase letters `A-Z` and can contain letters, numbers, underscore, and other non-ascii unicode chars.
It is recommended to name them with PascalCase or SCREAMING_SNAKE_CASE.

##### Keywords

The following are the keywords and should not be used:

```json
[
  "as", "else", "extern", "fn", "fnalias", "if", "let", "const", "match", "using",
  "mut", "type", "typealias", "struct", "enum", "trait", "traitalias", "derive",
  "while", "break", "continue", "import", "return", "throw", "raise", "try", "catch",
  "pub", "priv", "readonly", "true", "false", "_", "test", "loop", "for", "in", "impl",
  "with", "guard", "async", "is", "suberror", "and", "letrec", "enumview", "noraise",
  "defer",
]
```

##### Reserved Keywords

The following are the reserved keywords. Using them would introduce a warning.
They might be turned into keywords in the future.

```json
[
  "module", "move", "ref", "static", "super", "unsafe", "use", "where", "await",
  "dyn", "abstract", "do", "final", "macro", "override", "typeof", "virtual", "yield",
  "local", "method", "alias", "assert", "package", "recur", "using", "enumview",
  "isnot", "define", "downcast", "inherit", "member", "namespace", "static", "upcast",
  "use", "void", "lazy", "include", "mixin", "protected", "sealed", "constructor",
  "atomic", "volatile", "anyframe", "anytype", "asm", "await", "comptime", "errdefer",
  "export", "opaque", "orelse", "resume", "threadlocal", "unreachable", "dynclass",
  "dynobj", "dynrec", "var", "finally", "noasync",
]
```

#### Program entrance

##### `init` and `main`

There is a specialized function called `init` function. The `init` function is special:

1. It has no parameter list nor return type.
2. There can be multiple `init` functions in the same package.
3. An `init` function can't be explicitly called or referred to by other functions.
   Instead, all `init` functions will be implicitly called when initializing a package. Therefore, `init` functions should only consist of statements.

```moonbit
fn init {
  let x = 1
  println(x)
}
```

There is another specialized function called `main` function. The `main` function is the main entrance of the program, and it will be executed after the initialization stage.

Same as the `init` function, it has no parameter list nor return type.

```moonbit
fn main {
  let x = 2
  println(x)
}
```

The previous two code snippets will print the following at runtime:

```bash
1
2
```

Only packages that are `main` packages can define such `main` function. Check out [build system tutorial](../toolchain/moon/tutorial.md) for detail.

```json
{
  "is-main": true
}
```

##### `test`

There's also a top-level structure called `test` block. A `test` block defines inline tests, such as:

```moonbit
test "test_name" {
  assert_eq(1 + 1, 2)
  assert_eq(2 + 2, 4)
  inspect([1, 2, 3], content="[1, 2, 3]")
}
```

The following contents will use `test` block and `main` function to demonstrate the execution result,
and we assume that all the `test` blocks pass unless stated otherwise.

<!-- path: language/fundamentals.md -->
### Fundamentals

#### Built-in Data Structures

##### Unit

`Unit` is a built-in type in MoonBit that represents the absence of a meaningful value. It has only one value, written as `()`. `Unit` is similar to `void` in languages like C/C++/Java, but unlike `void`, it is a real type and can be used anywhere a type is expected.

The `Unit` type is commonly used as the return type for functions that perform some action but do not produce a meaningful result:

```moonbit
fn print_hello() -> Unit {
  println("Hello, world!")
}
```

Unlike some other languages, MoonBit treats `Unit` as a first-class type, allowing it to be used in generics, stored in data structures, and passed as function arguments.

##### Boolean

MoonBit has a built-in boolean type, which has two values: `true` and `false`. The boolean type is used in conditional expressions and control structures. Use `!` to negate a boolean value; `not(x)` is equivalent.

```moonbit
let a = true
let b = false
let c = a && b
let d = a || b
let e = !a
let f = not(a)
```

##### Number

MoonBit have integer type and floating point type:

| type     | description                                       | example                    |
|----------|---------------------------------------------------|----------------------------|
| `Int16`  | 16-bit signed integer                             | `(42 : Int16)`             |
| `Int`    | 32-bit signed integer                             | `42`                       |
| `Int64`  | 64-bit signed integer                             | `1000L`                    |
| `UInt16` | 16-bit unsigned integer                           | `(14 : UInt16)`            |
| `UInt`   | 32-bit unsigned integer                           | `14U`                      |
| `UInt64` | 64-bit unsigned integer                           | `14UL`                     |
| `Double` | 64-bit floating point, defined by IEEE754         | `3.14`                     |
| `Float`  | 32-bit floating point                             | `(3.14 : Float)`           |
| `BigInt` | represents numeric values larger than other types | `10000000000000000000000N` |

MoonBit also supports numeric literals, including decimal, binary, octal, and hexadecimal numbers.

To improve readability, you may place underscores in the middle of numeric literals such as `1_000_000`. Note that underscores can be placed anywhere within a number, not just every three digits.

- Decimal numbers can have underscore between the numbers.

  By default, an int literal is signed 32-bit number. For unsigned numbers, a postfix `U` is needed; for 64-bit numbers, a postfix `L` is needed.
  ```moonbit
  let a = 1234
  let b : Int = 1_000_000 + a
  let unsigned_num       : UInt   = 4_294_967_295U
  let large_num          : Int64  = 9_223_372_036_854_775_807L
  let unsigned_large_num : UInt64 = 18_446_744_073_709_551_615UL
  ```
- A binary number has a leading zero followed by a letter "B", i.e. `0b`/`0B`.
  Note that the digits after `0b`/`0B` must be `0` or `1`.
  ```moonbit
  let bin = 0b110010
  let another_bin = 0B110010
  ```
- An octal number has a leading zero followed by a letter "O", i.e. `0o`/`0O`.
  Note that the digits after `0o`/`0O` must be in the range from `0` through `7`:
  ```moonbit
  let octal = 0o1234
  let another_octal = 0O1234
  ```
- A hexadecimal number has a leading zero followed by a letter "X", i.e. `0x`/`0X`.
  Note that the digits after the `0x`/`0X` must be in the range `0123456789ABCDEF`.
  ```moonbit
  let hex = 0XA
  let another_hex = 0xA_B_C
  ```
- A floating-point number literal is 64-bit floating-point number. To define a float, type annotation is needed.
  ```moonbit
  let double = 3.14 // Double
  let float : Float = 3.14
  let float2 = (3.14 : Float)
  ```

  A 64-bit floating-point number can also be defined using hexadecimal format:
  ```moonbit
  let hex_double = 0x1.2P3 // (1.0 + 2 / 16) * 2^(+3) == 9
  ```

When the expected type is known, MoonBit can automatically overload literal, and there is no need to specify the type of number via letter postfix:

```moonbit
let int : Int = 42
let uint : UInt = 42
let int64 : Int64 = 42
let double : Double = 42
let float : Float = 42
let bigint : BigInt = 42
```

###### SEE ALSO
[Overloaded Literals]()

##### String

`String` holds a sequence of UTF-16 code units. You can use double quotes to create a string, or use `#|` to write a multi-line string.

```moonbit
let a = "兔rabbit"
println(a.code_unit_at(0).to_char())
println(a.code_unit_at(1).to_char())
let b =
  #| Hello
  #| MoonBit\n
  #|
println(b)
```

```default
Some('兔')
Some('r')
 Hello
 MoonBit\n

```

In double quotes string, a backslash followed by certain special characters forms an escape sequence:

| escape sequences       | description                                          |
|------------------------|------------------------------------------------------|
| `\n`, `\r`, `\t`, `\b` | New line, Carriage return, Horizontal tab, Backspace |
| `\\`                   | Backslash                                            |
| `\u5154` , `\u{1F600}` | Unicode escape sequence                              |

MoonBit supports string interpolation. It enables you to substitute variables within interpolated strings. This feature simplifies the process of constructing dynamic strings by directly embedding variable values into the text. Variables used for string interpolation must implement the [`Show` trait](methods.md#builtin-traits).

```moonbit
let x = 42
println("The answer is \{x}")
```

###### NOTE
The interpolated expression can not contain newline, `{}` or `"`.

Multi-line strings can be defined using the leading `#|` or `$|`, where the former will keep the raw string and the latter will perform the escape and interpolation:

```moonbit
let lang = "MoonBit"
let raw =
  #| Hello
  #| ---
  #| \{lang}
  #| ---
let interp =
  $| Hello
  $| ---
  $| \{lang}
  $| ---
println(raw)
println(interp)
```

```default
 Hello
 ---
 \{lang}
 ---
 Hello
 ---
 MoonBit
 ---
```

Avoid mixing `$|` and `#|` within the same multi-line string; pick one style for the whole block.

The [VSCode extension](../toolchain/vscode/index.md#actions) includes an action that can turn pasted documents into a plain multi-line string and switch between plain text and MoonBit multi-line strings.

When the expected type is `String` , the array literal syntax is overloaded to
construct the `String` by specifying each character in the string.

```moonbit
test {
  let c : Char = '中'
  let s : String = [c, '文']
  inspect(s, content="中文")
}
```

###### SEE ALSO
API: [https://mooncakes.io/docs/moonbitlang/core/string](https://mooncakes.io/docs/moonbitlang/core/string)

[Overloaded Literals]()

##### Char

`Char` represents a Unicode code point.

```moonbit
let a : Char = 'A'
let b = '兔'
let zero = '\u{30}'
let zero = '\u0030'
```

Char literals can be overloaded to type `Int` or `UInt16` when it is the expected type:

```moonbit
test {
  let s : String = "hello"
  let b : UInt16 = s.code_unit_at(0) // 'h'
  assert_eq(b, 'h') // 'h' is overloaded to UInt16
  let c : Int = '兔'
  // Not ok : exceed range
  // let d : UInt16 = '𠮷'
}
```

###### SEE ALSO
API: [https://mooncakes.io/docs/moonbitlang/core/char](https://mooncakes.io/docs/moonbitlang/core/char)

[Overloaded Literals]()

##### Byte(s)

A byte literal in MoonBit is either a single ASCII character or a single escape, have the form of `b'...'`. Byte literals are of type `Byte`. For example:

```moonbit
fn main {
  let b1 : Byte = b'a'
  println(b1.to_int())
  let b2 = b'\xff'
  println(b2.to_int())
}
```

```default
97
255
```

A `Bytes` is an immutable sequence of bytes. Similar to byte, bytes literals have the form of `b"..."`. For example:

```moonbit
test {
  let b1 : Bytes = b"abcd"
  let b2 = b"\x61\x62\x63\x64"
  assert_eq(b1, b2)
}
```

The byte literal and bytes literal also support escape sequences, but different from those in string literals. The following table lists the supported escape sequences for byte and bytes literals:

| escape sequences       | description                                          |
|------------------------|------------------------------------------------------|
| `\n`, `\r`, `\t`, `\b` | New line, Carriage return, Horizontal tab, Backspace |
| `\\`                   | Backslash                                            |
| `\x41`                 | Hexadecimal escape sequence                          |
| `\o102`                | Octal escape sequence                                |

###### NOTE
You can use `@buffer.T` to construct bytes by writing various types of data. For example:

```moonbit
test "buffer 1" {
  let buf : @buffer.Buffer = @buffer.new()
  buf.write_bytes(b"Hello")
  buf.write_byte(b'!')
  assert_eq(buf.contents(), b"Hello!")
}
```

When the expected type is `Bytes`, the `b` prefix can be omitted. Array literals can also be overloaded to construct a `Bytes` sequence by specifying each byte in the sequence.

```moonbit
test {
  let b : Byte = '\xFF'
  let bs : Bytes = [b, '\x01']
  inspect(
    bs,
    content=(
      #|b"\xff\x01"
    ),
  )
}
```

###### SEE ALSO
API for `Byte`: [https://mooncakes.io/docs/moonbitlang/core/byte](https://mooncakes.io/docs/moonbitlang/core/byte)<br />
\\\\
API for `Bytes`: [https://mooncakes.io/docs/moonbitlang/core/bytes](https://mooncakes.io/docs/moonbitlang/core/bytes)<br />
\\\\
API for `@buffer.T`: [https://mooncakes.io/docs/moonbitlang/core/buffer](https://mooncakes.io/docs/moonbitlang/core/buffer)

[Overloaded Literals]()

##### Tuple

A tuple is a collection of finite values constructed using round brackets `()` with the elements separated by commas `,`. The order of elements matters; for example, `(1,true)` and `(true,1)` have different types. Here's an example:

```moonbit
fn main {
  fn pack(
    a : Bool,
    b : Int,
    c : String,
    d : Double
  ) -> (Bool, Int, String, Double) {
    (a, b, c, d)
  }

  let quad = pack(false, 100, "text", 3.14)
  let (bool_val, int_val, str, float_val) = quad
  println("\{bool_val} \{int_val} \{str} \{float_val}")
}
```

```default
false 100 text 3.14
```

Tuples can be accessed via pattern matching or index:

```moonbit
test {
  let t = (1, 2)
  let (x1, y1) = t
  let x2 = t.0
  let y2 = t.1
  assert_eq(x1, x2)
  assert_eq(y1, y2)
}
```

##### Ref

A `Ref[T]` is a mutable reference containing a value `val` of type `T`.

It can be constructed using `{ val : x }`, and can be accessed using `ref.val`. See [struct]() for detailed explanation.

```moonbit
let a : Ref[Int] = { val: 100 }

test {
  a.val = 200
  assert_eq(a.val, 200)
  a.val += 1
  assert_eq(a.val, 201)
}
```

###### SEE ALSO
API: [https://mooncakes.io/docs/moonbitlang/core/ref](https://mooncakes.io/docs/moonbitlang/core/ref)

##### Option and Result

`Option` and `Result` are the most common types to represent a possible error or failure in MoonBit.

- `Option[T]` represents a possibly missing value of type `T`. It can be abbreviated as `T?`.
- `Result[T, E]` represents either a value of type `T` or an error of type `E`.

See [enum]() for detailed explanation.

```moonbit
test {
  let a : Int? = None
  let b : Option[Int] = Some(42)
  let c : Result[Int, String] = Ok(42)
  let d : Result[Int, String] = Err("error")
  match a {
    Some(_) => assert_true(false)
    None => assert_true(true)
  }
  match d {
    Ok(_) => assert_true(false)
    Err(_) => assert_true(true)
  }
}
```

###### SEE ALSO
API for `Option`: [https://mooncakes.io/docs/moonbitlang/core/option](https://mooncakes.io/docs/moonbitlang/core/option)<br />
\\\\
API for `Result`: [https://mooncakes.io/docs/moonbitlang/core/result](https://mooncakes.io/docs/moonbitlang/core/result)

##### Array

An array is a finite sequence of values constructed using square brackets `[]`, with elements separated by commas `,`. For example:

```moonbit
let numbers = [1, 2, 3, 4]
```

You can use `numbers[x]` to refer to the xth element. The index starts from zero.

```moonbit
test {
  let numbers = [1, 2, 3, 4]
  let a = numbers[2]
  numbers[3] = 5
  let b = a + numbers[3]
  assert_eq(b, 8)
}
```

There are `Array[T]` and `FixedArray[T]`. Views are provided by `ArrayView[T]`
and `MutArrayView[T]` (see below).

`Array[T]` can grow in size, while `FixedArray[T]` has a fixed size, thus it needs to be created with initial value.

###### WARNING
A common pitfall is creating `FixedArray` with the same initial value:

```moonbit
test {
  let two_dimension_array = FixedArray::make(10, FixedArray::make(10, 0))
  two_dimension_array[0][5] = 10
  assert_eq(two_dimension_array[5][5], 10)
}
```

This is because all the cells reference to the same object (the `FixedArray[Int]` in this case). One should use `FixedArray::makei()` instead which creates an object for each index.

```moonbit
test {
  let two_dimension_array = FixedArray::makei(10, fn(_i) {
    FixedArray::make(10, 0)
  })
  two_dimension_array[0][5] = 10
  assert_eq(two_dimension_array[5][5], 0)
}
```

When the expected type is known, MoonBit can automatically overload array, otherwise
`Array[T]` is created:

```moonbit
let fixed_array_1 : FixedArray[Int] = [1, 2, 3]

let fixed_array_2 = ([1, 2, 3] : FixedArray[Int])

let array_3 : Array[Int] = [1, 2, 3] // Array[Int]
```

###### SEE ALSO
API: [https://mooncakes.io/docs/moonbitlang/core/array](https://mooncakes.io/docs/moonbitlang/core/array)

[Overloaded Literals]()

###### ArrayView

Analogous to `slice` in other languages, the view is a reference to a
specific segment of collections. You can use `data[start:end]` to create a
view of array `data`, referencing elements from `start` to `end` (exclusive).
Both `start` and `end` indices can be omitted.

###### NOTE
`ArrayView` is an immutable data structure on its own, but the underlying
`Array` or `FixedArray` could be modified. For a mutable view, use
`MutArrayView[T]` via `data.mut_view(...)`.

```moonbit
test {
  let xs = [0, 1, 2, 3, 4, 5]
  let s1 : ArrayView[Int] = xs[2:]
  inspect(s1, content="[2, 3, 4, 5]")
  inspect(xs[:4], content="[0, 1, 2, 3]")
  inspect(xs[2:5], content="[2, 3, 4]")
  inspect(xs[:], content="[0, 1, 2, 3, 4, 5]")
  let mv : MutArrayView[Int] = xs.mut_view(start=1, end=3)
  mv[0] = 99
  inspect(xs[1], content="99")
}
```

###### SEE ALSO
API: [https://mooncakes.io/docs/moonbitlang/core/array](https://mooncakes.io/docs/moonbitlang/core/array)

##### Map

MoonBit provides a hash map data structure that preserves insertion order called `Map` in its standard library.
`Map`s can be created via a convenient literal syntax:

```moonbit
let map : Map[String, Int] = { "x": 1, "y": 2, "z": 3 }
```

Currently keys in map literal syntax must be constant. `Map`s can also be destructed elegantly with pattern matching, see [Map Pattern]().

###### SEE ALSO
API: [https://mooncakes.io/docs/moonbitlang/core/builtin#Map](https://mooncakes.io/docs/moonbitlang/core/builtin#Map)

[Overloaded Literals]()

##### Json

MoonBit supports convenient json handling by overloading literals.
When the expected type of an expression is `Json`, number, string, array and map literals can be directly used to create json data:

```moonbit
let moon_pkg_json_example : Json = {
  "import": ["moonbitlang/core/builtin", "moonbitlang/core/coverage"],
  "test-import": ["moonbitlang/core/random"],
}
```

Json values can be pattern matched too, see [Json Pattern]().

###### SEE ALSO
API: [https://mooncakes.io/docs/moonbitlang/core/json](https://mooncakes.io/docs/moonbitlang/core/json)

[Overloaded Literals]()

#### Overloaded Literals

Overloaded literals allow you to use the same syntax to represent different types of values.
For example, you can use `1` to represent `UInt` or `Double` depending on the expected type. If the expected type is not known, the literal will be interpreted as `Int` by default.

```moonbit
fn expect_double(x : Double) -> Unit {

}

test {
  let x = 1 // type of x is Int
  let y : Double = 1
  expect_double(1)
}
```

The overloaded literals can be composed. If array literal can be overloaded to `Bytes` , and number literal can be overloaded to `Byte` , then you can overload `[1,2,3]` to `Bytes` as well. Here is a table of overloaded literals in MoonBit:

| Overloaded literal                                          | Default type   | Can be overloaded to                                                              |
|-------------------------------------------------------------|----------------|-----------------------------------------------------------------------------------|
| `10`, `0xFF`, `0o377`, `10_000`                             | `Int`          | `UInt`, `Int64`, `UInt64`, `Int16`, `UInt16`, `Byte`, `Double`, `Float`, `BigInt` |
| `"str"`                                                     | `String`       | `Bytes`                                                                           |
| `'c'`                                                       | `Char`         | `Int` , `Byte`                                                                    |
| `3.14`                                                      | `Double`       | `Float`                                                                           |
| `[a, b, c]` (where the types of literals a, b, and c are E) | `Array[E]`     | `FixedArray[E]`, `String`  (if E is of type Char), `Bytes` (if E is of type Byte) |

There are also some similar overloading rules in pattern. For more details, see [Pattern Matching]().

###### NOTE
Literal overloading is not the same as value conversion. To convert a variable to a different type, you can use methods prefixed with `to_`, such as `to_int()`, `to_double()`, etc.

##### Escape Sequences in Overloaded Literals

Escape sequences can be used in overloaded `"..."` literals and `'...'` literals. The interpretation of escape sequences depends on the types they are overloaded to:

- Simple escape sequences

  Including `\n`, `\r`, `\t`, `\\`, and `\b`. These escape sequences are supported in any `"..."` or `'...'` literals. They are interpreted as their respective `Char` or `Byte` in `String` or `Bytes`.
- Byte escape sequences

  The `\x41` and `\o102` escape sequences represent a Byte. These are supported in literals overloaded to `Bytes` and `Byte`.
- Unicode escape sequences

  The `\u5154` and `\u{1F600}` escape sequences represent a `Char`. These are supported in literals of type `String` and `Char`.

#### Functions

Functions take arguments and produce a result. In MoonBit, functions are first-class, which means that functions can be arguments or return values of other functions. MoonBit's naming convention requires that function names should not begin with uppercase letters (A-Z). Compare for constructors in the `enum` section below.

##### Top-Level Functions

Functions can be defined as top-level or local. We can use the `fn` keyword to define a top-level function that sums three integers and returns the result, as follows:

```moonbit
fn add3(x : Int, y : Int, z : Int) -> Int {
  x + y + z
}
```

Note that the arguments and return value of top-level functions require **explicit** type annotations.

##### Local Functions

Local functions can be named or anonymous. Type annotations can be omitted for local function definitions: they can be automatically inferred in most cases. For example:

```moonbit
fn local_1() -> Int {
  fn inc(x) { // named as `inc`
    x + 1
  }
  // anonymous, instantly applied to integer literal 6
  (fn(x) { x + inc(2) })(6)
}

test {
  assert_eq(local_1(), 9)
}
```

For simple anonymous function, MoonBit provides a very concise syntax called arrow function:

```moonbit
  [1, 2, 3].eachi((i, x) => println("\{i} => \{x}"))
  // parenthesis can be omitted when there is only one parameter
  [1, 2, 3].each(x => println(x * x))
```

Functions, whether named or anonymous, are *lexical closures*: any identifiers without a local binding must refer to bindings from a surrounding lexical scope. For example:

```moonbit
let global_y = 3

fn local_2(x : Int) -> (Int, Int) {
  fn inc() {
    x + 1
  }

  fn four() {
    global_y + 1
  }

  (inc(), four())
}

test {
  assert_eq(local_2(3), (4, 4))
}
```

A local function can only refer to itself and other previously defined local functions.
To define  mutually recursive local functions, use the syntax `letrec f = .. and g = ..` instead:

```moonbit
  fn f(x) {
    // `f` can refer to itself here, but cannot use `g`
    if x > 0 {
      f(x - 1)
    }
  }

  fn g(x) {
    // `g` can refer to `f` and `g` itself
    if x < 0 {
      f(-x)
    } else {
      f(x)
    }
  }
  // mutually recursive local functions
  letrec even = x => x == 0 || odd(x - 1)
  and odd = x => x != 0 && even(x - 1)
```

##### Function Applications

A function can be applied to a list of arguments in parentheses:

```moonbit
add3(1, 2, 7)
```

This works whether `add3` is a function defined with a name (as in the previous example), or a variable bound to a function value, as shown below:

```moonbit
test {
  let add3 = fn(x, y, z) { x + y + z }
  assert_eq(add3(1, 2, 7), 10)
}
```

The expression `add3(1, 2, 7)` returns `10`. Any expression that evaluates to a function value is applicable:

```moonbit
test {
  let f = fn(x) { x + 1 }
  let g = fn(x) { x + 2 }
  let w = (if true { f } else { g })(3)
  assert_eq(w, 4)
}
```

##### Partial Applications

Partial application is a technique of applying a function to some of its arguments, resulting in a new function that takes the remaining arguments. In MoonBit, partial application is achieved by using the `_` operator in function application:

```moonbit
fn add(x : Int, y : Int) -> Int {
  x + y
}

test {
  let add10 : (Int) -> Int = add(10, _)
  println(add10(5)) // prints 15
  println(add10(10)) // prints 20
}
```

The `_` operator represents the missing argument in parentheses. The partial application allows multiple `_` in the same parentheses.
For example, `Array::fold(_, _, init=5)` is equivalent to `fn(x, y) { Array::fold(x, y, init=5) }`.

The `_` operator can also be used in enum creation, dot style function calls and in the pipelines.

##### Labelled arguments

**Top-level** functions can declare labelled argument with the syntax `label~ : Type`. `label` will also serve as parameter name inside function body:

```moonbit
fn labelled_1(arg1~ : Int, arg2~ : Int) -> Int {
  arg1 + arg2
}
```

Labelled arguments can be supplied via the syntax `label=arg`. `label=label` can be abbreviated as `label~`:

```moonbit
test {
  let arg1 = 1
  assert_eq(labelled_1(arg2=2, arg1~), 3)
}
```

Labelled function can be supplied in any order. The evaluation order of arguments is the same as the order of parameters in function declaration.

##### Optional arguments

An argument can be made optional by supplying a default expression with the syntax `label?: Type = default_expr`, where the `default_expr` may be omitted. If this argument is not supplied at call site, the default expression will be used:

```moonbit
fn optional(opt? : Int = 42) -> Int {
  opt
}

test {
  assert_eq(optional(), 42)
  assert_eq(optional(opt=0), 0)
}
```

The default expression will be evaluated every time it is used. And the side effect in the default expression, if any, will also be triggered. For example:

```moonbit
fn incr(counter? : Ref[Int] = { val: 0 }) -> Ref[Int] {
  counter.val = counter.val + 1
  counter
}

test {
  inspect(incr(), content="{val: 1}")
  inspect(incr(), content="{val: 1}")
  let counter : Ref[Int] = { val: 0 }
  inspect(incr(counter~), content="{val: 1}")
  inspect(incr(counter~), content="{val: 2}")
}
```

Optional argument values are regular expressions at the call site. You can pass
expressions that may raise errors or call async functions when in a `raise` or
`async` context:

```moonbit
fn may_fail(x : Int) -> Int raise Failure {
  if x < 0 {
    fail("negative")
  }
  x
}

fn add_with_optional(base : Int, extra? : Int = 1) -> Int {
  base + extra
}

test {
  inspect(add_with_optional(1, extra=may_fail(2)), content="3")
}
```

For async functions, optional argument expressions can call async functions as
usual:

```moonbit
async fn fetch_default() -> Int raise { ... }

async fn build(x? : Int = fetch_default()) -> Int raise { ... }

async fn use_value() -> Int raise {
  build(x=fetch_default())
}
```

If you want to share the result of default expression between different function calls, you can lift the default expression to a toplevel `let` declaration:

```moonbit
let default_counter : Ref[Int] = { val: 0 }

fn incr_2(counter? : Ref[Int] = default_counter) -> Int {
  counter.val = counter.val + 1
  counter.val
}

test {
  assert_eq(incr_2(), 1)
  assert_eq(incr_2(), 2)
}
```

The default expression can depend on previous arguments, such as:

```moonbit
fn create_rectangle(a : Int, b? : Int = a) -> (Int, Int) {
  (a, b)
}

test {
  inspect(create_rectangle(10), content="(10, 10)")
}
```

###### Optional arguments without default values

It is quite common to have different semantics when a user does not provide a value.
Optional arguments without default values have type `T?` and `None` as the default value.
When supplying this kind of optional argument directly, MoonBit will automatically wrap the value with `Some`:

```moonbit
fn new_image(width? : Int, height? : Int) -> Image {
  if width is Some(w) {
    ...
  }
  ...
}

let img2 : Image = new_image(width=1920, height=1080)
```

Sometimes, it is also useful to pass a value of type `T?` directly,
for example when forwarding optional argument.
MoonBit provides a syntax `label?=value` for this, with `label?` being an abbreviation of `label?=label`:

```moonbit
fn image(width? : Int, height? : Int) -> Image {
  ...
}

fn fixed_width_image(height? : Int) -> Image {
  image(width=1920, height?)
}
```

##### Autofill arguments

MoonBit supports filling specific types of arguments automatically at different call site, such as the source location of a function call.
To declare an autofill argument, simply declare a labelled argument, and add a function attribute `#callsite(autofill(param_a, param_b))`.
Now if the argument is not explicitly supplied, MoonBit will automatically fill it at the call site.

Currently MoonBit supports two types of autofill arguments, `SourceLoc`, which is the source location of the whole function call,
and `ArgsLoc`, which is an array containing the source location of each argument, if any:

```moonbit
###callsite(autofill(loc, args_loc))
fn f(_x : Int, loc~ : SourceLoc, args_loc~ : ArgsLoc) -> String {
  (
    $|loc of whole function call: \{loc}
    $|loc of arguments: \{args_loc}
  )
  // loc of whole function call: <filename>:7:3-7:10
  // loc of arguments: [Some(<filename>:7:5-7:6), Some(<filename>:7:8-7:9), None, None]
}
```

Autofill arguments are very useful for writing debugging and testing utilities.

##### Function alias

MoonBit allows calling functions with alternative names via function alias. Function alias can be declared as follows:

```moonbit
###alias(g)
###alias(h, visibility="pub")
fn k() -> Bool {
  true
}
```

You can also create function alias that has different visibility with the field `visibility`.

#### Control Structures

##### Conditional Expressions

A conditional expression consists of a condition, a consequent, and an optional `else` clause or `else if` clause.

```moonbit
if x == y {
  expr1
} else if x == z {
  expr2
} else {
  expr3
}
```

The curly brackets around the consequent are required.

Note that a conditional expression always returns a value in MoonBit, and the return values of the consequent and the else clause must be of the same type. Here is an example:

```moonbit
let initial = if size < 1 { 1 } else { size }
```

The `else` clause can only be omitted if the return value has type `Unit`.

##### Match Expression

The `match` expression is similar to conditional expression, but it uses [pattern matching]() to decide which consequent to evaluate and extracting variables at the same time.

```moonbit
fn decide_sport(weather : String, humidity : Int) -> String {
  match weather {
    "sunny" => "tennis"
    "rainy" => if humidity > 80 { "swimming" } else { "football" }
    _ => "unknown"
  }
}

test {
  assert_eq(decide_sport("sunny", 0), "tennis")
}
```

If a possible condition is omitted, the compiler will issue a warning, and the program will terminate if that case were reached.

##### Guard Statement

The `guard` statement is used to check a specified invariant.
If the condition of the invariant is satisfied, the program continues executing
the subsequent statements and returns. If the condition is not satisfied (i.e., false),
the code in the `else` block is executed and its evaluation result is returned (the subsequent statements are skipped).

```moonbit
fn guarded_get(array : Array[Int], index : Int) -> Int? {
  guard index >= 0 && index < array.length() else { None }
  Some(array[index])
}

test {
  inspect(guarded_get([1, 2, 3], -1), content="None")
}
```

###### Guard statement and is expression

The `let` statement can be used with [pattern matching](). However, `let` statement can only handle one case. And using [is expression]() with `guard` statement can solve this issue.

In the following example, `getProcessedText` assumes that the input `path` points to resources that are all plain text,
and it uses the `guard` statement to ensure this invariant while extracting the plain text resource.
Compared to using a `match` statement, the subsequent processing of `text` can have one less level of indentation.

```moonbit
enum Resource {
  Folder(Array[String])
  PlainText(String)
  JsonConfig(Json)
}

fn getProcessedText(
  resources : Map[String, Resource],
  path : String,
) -> String raise Error {
  guard resources.get(path) is Some(resource) else { fail("\{path} not found") }
  guard resource is PlainText(text) else { fail("\{path} is not plain text") }
  process(text)
}
```

When the `else` part is omitted, the program terminates if the condition specified
in the `guard` statement is not true or cannot be matched.

```moonbit
guard condition  // <=> guard condition else { panic() }
guard expr is Some(x)
// <=> guard expr is Some(x) else { _ => panic() }
```

##### While loop

In MoonBit, `while` loop can be used to execute a block of code repeatedly as long as a condition is true. The condition is evaluated before executing the block of code. The `while` loop is defined using the `while` keyword, followed by a condition and the loop body. The loop body is a sequence of statements. The loop body is executed as long as the condition is true.

```moonbit
fn main {
  let mut i = 5
  while i > 0 {
    println(i)
    i = i - 1
  }
}
```

```default
5
4
3
2
1
```

The loop body supports `break` and `continue`. Using `break` allows you to exit the current loop, while using `continue` skips the remaining part of the current iteration and proceeds to the next iteration.

```moonbit
fn main {
  let mut i = 5
  while i > 0 {
    i = i - 1
    if i == 4 {
      continue
    }
    if i == 1 {
      break
    }
    println(i)
  }
}
```

```default
3
2
```

The `while` loop also supports an optional `else` clause. When the loop condition becomes false, the `else` clause will be executed, and then the loop will end.

```moonbit
fn main {
  let mut i = 2
  while i > 0 {
    println(i)
    i = i - 1
  } else {
    println(i)
  }
}
```

```default
2
1
0
```

When there is an `else` clause, the `while` loop can also return a value. The return value is the evaluation result of the `else` clause. In this case, if you use `break` to exit the loop, you need to provide a return value after `break`, which should be of the same type as the return value of the `else` clause.

```moonbit
fn main {
  let mut i = 10
  let r = while i > 0 {
    i = i - 1
    if i % 2 == 0 {
      break 5
    }
  } else {
    7
  }
  println(r)
}
```

```default
5
```

```moonbit
fn main {
  let mut i = 10
  let r = while i > 0 {
    i = i - 1
  } else {
    7
  }
  println(r)
}
```

```default
7
```

##### For Loop

MoonBit also supports C-style For loops. The keyword `for` is followed by variable initialization clauses, loop conditions, and update clauses separated by semicolons. They do not need to be enclosed in parentheses.
For example, the code below creates a new variable binding `i`, which has a scope throughout the entire loop and is immutable. This makes it easier to write clear code and reason about it:

```moonbit
fn main {
  for i = 0; i < 5; i = i + 1 {
    println(i)
  }
}
```

```default
0
1
2
3
4
```

The variable initialization clause can create multiple bindings:

```moonbit
for i = 0, j = 0; i + j < 100; i = i + 1, j = j + 1 {
  println(i)
}
```

It should be noted that in the update clause, when there are multiple binding variables, the semantics are to update them simultaneously. In other words, in the example above, the update clause does not execute `i = i + 1`, `j = j + 1` sequentially, but rather increments `i` and `j` at the same time. Therefore, when reading the values of the binding variables in the update clause, you will always get the values updated in the previous iteration.

Variable initialization clauses, loop conditions, and update clauses are all optional. For example, the following two are infinite loops:

```moonbit
for i = 1; ; i = i + 1 {
  println(i)
}
for {
  println("loop forever")
}
```

The `for` loop also supports `continue`, `break`, and `else` clauses. Like the `while` loop, the `for` loop can also return a value using the `break` and `else` clauses.

The `continue` statement skips the remaining part of the current iteration of the `for` loop (including the update clause) and proceeds to the next iteration. The `continue` statement can also update the binding variables of the `for` loop, as long as it is followed by expressions that match the number of binding variables, separated by commas.

For example, the following program calculates the sum of even numbers from 1 to 6:

```moonbit
fn main {
  let sum = for i = 1, acc = 0; i <= 6; i = i + 1 {
    if i % 2 == 0 {
      println("even: \{i}")
      continue i + 1, acc + i
    }
  } else {
    acc
  }
  println(sum)
}
```

```default
even: 2
even: 4
even: 6
12
```

##### `for .. in` loop

MoonBit supports traversing elements of different data structures and sequences via the `for .. in` loop syntax:

```moonbit
for x in [1, 2, 3] {
  println(x)
}
```

`for .. in` loop is translated to the use of `Iter` in MoonBit's standard library. Any type with a method `.iter() : Iter[T]` can be traversed using `for .. in`.
For more information of the `Iter` type, see [Iterator]() below.

`for .. in` loop also supports iterating through a sequence of integers, such as:

```moonbit
test {
  let mut i = 0
  for j in 0..<10 {
    i += j
  }
  assert_eq(i, 45)
  let mut k = 0
  for l in 0..=10 {
    k += l
  }
  assert_eq(k, 55)
}
```

In addition to sequences of a single value, MoonBit also supports traversing sequences of two values, such as `Map`, via the `Iter2` type in MoonBit's standard library.
Any type with method `.iter2() : Iter2[A, B]` can be traversed using `for .. in` with two loop variables:

```moonbit
for k, v in { "x": 1, "y": 2, "z": 3 } {
  println(k)
  println(v)
}
```

Another example of `for .. in` with two loop variables is traversing an array while keeping track of array index:

```moonbit
fn main {
  for index, elem in [4, 5, 6] {
    let i = index + 1
    println("The \{i}-th element of the array is \{elem}")
  }
}
```

```default
The 1-th element of the array is 4
The 2-th element of the array is 5
The 3-th element of the array is 6
```

Control flow operations such as `return`, `break` and error handling are supported in the body of `for .. in` loop:

```moonbit
fn main {
  let map = { "x": 1, "y": 2, "z": 3, "w": 4 }
  for k, v in map {
    if k == "y" {
      continue
    }
    println("\{k}, \{v}")
    if k == "z" {
      break
    }
  }
}
```

```default
x, 1
z, 3
```

If a loop variable is unused, it can be ignored with `_`.

##### Functional loop

Functional loop is a powerful feature in MoonBit that enables you to write loops in a functional style.

A functional loop consumes an argument and returns a value. It is defined using the `loop` keyword, followed by its argument and the loop body. The loop body is a sequence of clauses, each of which consists of a pattern and an expression. The clause whose pattern matches the input will be executed, and the loop will return the value of the expression. If no pattern matches, the loop will panic. Use the `continue` keyword with arguments to start the next iteration of the loop. Use the `break` keyword with an argument to return a value from the loop. The `break` keyword can be omitted if the value is the last expression in the loop body.

```moonbit
test {
  fn sum(xs : @list.List[Int]) -> Int {
    loop (xs, 0) {
      (Empty, acc) => break acc // <=> Nil, acc => acc
      (More(x, tail=rest), acc) => continue (rest, x + acc)
    }
  }

  assert_eq(sum(@list.from_array([1, 2, 3])), 6)
}
```

##### Labelled Continue/Break

When a loop is labelled, it can be referenced from a `break` or `continue` from
within a nested loop. For example:

```moonbit
test "break label" {
  let mut count = 0
  let xs = [1, 2, 3]
  let ys = [4, 5, 6]
  let res = outer~: for i in xs {
    for j in ys {
      count = count + i
      break outer~ j
    }
  } else {
    -1
  }
  assert_eq(res, 4)
  assert_eq(count, 1)
}

test "continue label" {
  let mut count = 0
  let init = 10
  let res = outer~: loop init {
    0 => 42
    i =>
      for {
        count = count + 1
        continue outer~ i - 1
      }
  }
  assert_eq(res, 42)
  assert_eq(count, 10)
}
```

##### `defer` expression

`defer` expression can be used to perform reliable resource cleanup.
The syntax for `defer` is as follows:

```moonbit
defer <expr>
<body>
```

Whenever the program leaves `body`, `expr` will be executed.
For example, the following program:

```moonbit
  defer println("perform resource cleanup")
  println("do things with the resource")
```

will first print `do things with the resource`, and then `perform resource cleanup`.
`defer` expression will always get executed no matter how its body exits.
It can handle [error](error-handling.md),
as well as control flow constructs including `return`, `break` and `continue`.

Consecutive `defer` will be executed in reverse order, for example, the following:

```moonbit
  defer println("first defer")
  defer println("second defer")
  println("do things")
```

will output first `do things`, then `second defer`, and finally `first defer`.

`return`, `break` and `continue` are disallowed in the right hand side of `defer`.
Currently, raising error or calling `async` function is also disallowed in the right hand side of `defer`.

#### Iterator

An iterator is an object that traverse through a sequence while providing access
to its elements. Traditional OO languages like Java's `Iterator<T>` use `next()`
`hasNext()` to step through the iteration process, whereas functional languages
(JavaScript's `forEach`, Lisp's `mapcar`) provides a high-order function which
takes an operation and a sequence then consumes the sequence with that operation
being applied to the sequence. The former is called *external iterator* (visible
to user) and the latter is called *internal iterator* (invisible to user).

The built-in type `Iter[T]` is MoonBit's external iterator implementation. It
exposes `next()` to pull the next value: it returns `Some(value)` and advances
the iterator, or `None` when the iteration is finished.
Almost all built-in sequential data structures have implemented `Iter`:

```moonbit
///|
fn filter_even(l : Array[Int]) -> Array[Int] {
  let l_iter : Iter[Int] = l.iter()
  l_iter.filter(x => (x & 1) == 0).collect()
}

///|
fn fact(n : Int) -> Int {
  let start = 1
  let range : Iter[Int] = start.until(n)
  range.fold(Int::mul, init=start)
}
```

Commonly used methods include:

- `each`: Iterates over each element in the iterator, applying some function to each element.
- `fold`: Folds the elements of the iterator using the given function, starting with the given initial value.
- `collect`: Collects the elements of the iterator into an array.
- `filter`: *lazy* Filters the elements of the iterator based on a predicate function.
- `map`: *lazy* Transforms the elements of the iterator using a mapping function.
- `concat`: *lazy* Combines two iterators into one by appending the elements of the second iterator to the first.

Methods like `filter` and `map` are very common on a sequence object e.g. Array.
But what makes `Iter` special is that any method that constructs a new `Iter` is
*lazy* (i.e. iteration doesn't start on call because it's wrapped inside a
function), as a result of no allocation for intermediate value. That's what
makes `Iter` superior for traversing through sequence: no extra cost. MoonBit
encourages user to pass an `Iter` across functions instead of the sequence
object itself.

Pre-defined sequence structures like `Array` and its iterators should be
enough to use. But to take advantages of these methods when used with a custom
sequence with elements of type `S`, we will need to implement `Iter`, namely, a function that returns
an `Iter[S]`. Take `Bytes` as an example:

```moonbit
///|
fn iter(data : Bytes) -> Iter[Byte] {
  let mut index = 0
  Iter::new(fn() -> Byte? {
    if index < data.length() {
      let byte = data[index]
      index += 1
      Some(byte)
    } else {
      None
    }
  })
}
```

Iterators are single-pass: once you call `next()` or consume them with methods
like `each`, `fold`, or `collect`, their internal state advances and cannot be
reset. If you need to traverse the sequence again, request a new `Iter` from
the source.

#### Custom Data Types

There are two ways to create new data types: `struct` and `enum`.

##### Struct

In MoonBit, structs are similar to tuples, but their fields are indexed by field names. A struct can be constructed using a struct literal, which is composed of a set of labeled values and delimited with curly brackets. The type of a struct literal can be automatically inferred if its fields exactly match the type definition. A field can be accessed using the dot syntax `s.f`. If a field is marked as mutable using the keyword `mut`, it can be assigned a new value.

```moonbit
struct User {
  id : Int
  name : String
  mut email : String
}
```

```moonbit
fn main {
  let u = User::{ id: 0, name: "John Doe", email: "john@doe.com" }
  u.email = "john@doe.name"
  //! u.id = 10
  println(u.id)
  println(u.name)
  println(u.email)
}
```

```default
0
John Doe
john@doe.name
```

###### Constructing Struct with Shorthand

If you already have some variable like `name` and `email`, it's redundant to repeat those names when constructing a struct. You can use shorthand instead, it behaves exactly the same:

```moonbit
let name = "john"
let email = "john@doe.com"
let u = User::{ id: 0, name, email }
```

If there's no other struct that has the same fields, it's redundant to add the struct's name when constructing it:

```moonbit
let u2 = { id: 0, name, email }
```

###### Struct Update Syntax

It's useful to create a new struct based on an existing one, but with some fields updated.

```moonbit
fn main {
  let user = { id: 0, name: "John Doe", email: "john@doe.com" }
  let updated_user = { ..user, email: "john@doe.name" }
  println(
    (
      $|{ id: \{user.id}, name: \{user.name}, email: \{user.email} }
      $|{ id: \{updated_user.id}, name: \{updated_user.name}, email: \{updated_user.email} }
    ),
  )
}
```

```default
{ id: 0, name: John Doe, email: john@doe.com }
{ id: 0, name: John Doe, email: john@doe.name }
```

##### Enum

Enum types are similar to algebraic data types in functional languages. Users familiar with C/C++ may prefer calling it tagged union.

An enum can have a set of cases (constructors). Constructor names must start with capitalized letter. You can use these names to construct corresponding cases of an enum, or checking which branch an enum value belongs to in pattern matching:

```moonbit
/// An enum type that represents the ordering relation between two values,
/// with three cases "Smaller", "Greater" and "Equal"
enum Relation {
  Smaller
  Greater
  Equal
}
```

```moonbit
/// compare the ordering relation between two integers
fn compare_int(x : Int, y : Int) -> Relation {
  if x < y {
    // when creating an enum, if the target type is known, 
    // you can write the constructor name directly
    Smaller
  } else if x > y {
    // but when the target type is not known,
    // you can always use `TypeName::Constructor` to create an enum unambiguously
    Relation::Greater
  } else {
    Equal
  }
}

/// output a value of type `Relation`
fn print_relation(r : Relation) -> Unit {
  // use pattern matching to decide which case `r` belongs to
  match r {
    // during pattern matching, if the type is known, 
    // writing the name of constructor is sufficient
    Smaller => println("smaller!")
    // but you can use the `TypeName::Constructor` syntax 
    // for pattern matching as well
    Relation::Greater => println("greater!")
    Equal => println("equal!")
  }
}
```

```moonbit
fn main {
  print_relation(compare_int(0, 1))
  print_relation(compare_int(1, 1))
  print_relation(compare_int(2, 1))
}
```

```default
smaller!
equal!
greater!
```

Enum cases can also carry payload data. Here's an example of defining an integer list type using enum:

```moonbit
enum Lst {
  Nil
  // constructor `Cons` carries additional payload: the first element of the list,
  // and the remaining parts of the list
  Cons(Int, Lst)
}
```

```moonbit
// In addition to binding payload to variables,
// you can also continue matching payload data inside constructors.
// Here's a function that decides if a list contains only one element
fn is_singleton(l : Lst) -> Bool {
  match l {
    // This branch only matches values of shape `Cons(_, Nil)`, 
    // i.e. lists of length 1
    Cons(_, Nil) => true
    // Use `_` to match everything else
    _ => false
  }
}

fn print_list(l : Lst) -> Unit {
  // when pattern-matching an enum with payload,
  // in additional to deciding which case a value belongs to
  // you can extract the payload data inside that case
  match l {
    Nil => println("nil")
    // Here `x` and `xs` are defining new variables 
    // instead of referring to existing variables,
    // if `l` is a `Cons`, then the payload of `Cons` 
    // (the first element and the rest of the list)
    // will be bind to `x` and `xs
    Cons(x, xs) => {
      println("\{x},")
      print_list(xs)
    }
  }
}
```

```moonbit
fn main {
  // when creating values using `Cons`, the payload of by `Cons` must be provided
  let l : Lst = Cons(1, Cons(2, Nil))
  println(is_singleton(l))
  print_list(l)
}
```

```default
false
1,
2,
nil
```

###### Constructor with labelled arguments

Enum constructors can have labelled argument:

```moonbit
enum E {
  // `x` and `y` are labelled argument
  C(x~ : Int, y~ : Int)
}
```

```moonbit
// pattern matching constructor with labelled arguments
fn f(e : E) -> Unit {
  match e {
    // `label=pattern`
    C(x=0, y=0) => println("0!")
    // `x~` is an abbreviation for `x=x`
    // Unmatched labelled arguments can be omitted via `..`
    C(x~, ..) => println(x)
  }
}
```

```moonbit
fn main {
  f(C(x=0, y=0))
  let x = 0
  f(C(x~, y=1)) // <=> C(x=x, y=1)
}
```

```default
0!
0
```

It is also possible to access labelled arguments of constructors like accessing struct fields in pattern matching:

```moonbit
enum Object {
  Point(x~ : Double, y~ : Double)
  Circle(x~ : Double, y~ : Double, radius~ : Double)
}

suberror NotImplementedError derive(Show)

fn Object::distance_with(
  self : Object,
  other : Object,
) -> Double raise NotImplementedError {
  match (self, other) {
    // For variables defined via `Point(..) as p`,
    // the compiler knows it must be of constructor `Point`,
    // so you can access fields of `Point` directly via `p.x`, `p.y` etc.
    (Point(_) as p1, Point(_) as p2) => {
      let dx = p2.x - p1.x
      let dy = p2.y - p1.y
      (dx * dx + dy * dy).sqrt()
    }
    (Point(_), Circle(_)) | (Circle(_), Point(_)) | (Circle(_), Circle(_)) =>
      raise NotImplementedError
  }
}
```

```moonbit
fn main {
  let p1 : Object = Point(x=0, y=0)
  let p2 : Object = Point(x=3, y=4)
  let c1 : Object = Circle(x=0, y=0, radius=2)
  try {
    println(p1.distance_with(p2))
    println(p1.distance_with(c1))
  } catch {
    e => println(e)
  }
}
```

```default
5
NotImplementedError
```

###### Constructor with mutable fields

It is also possible to define mutable fields for constructor. This is especially useful for defining imperative data structures:

```moonbit
// A set implemented using mutable binary search tree.
struct Set[X] {
  mut root : Tree[X]
}

fn[X : Compare] Set::insert(self : Set[X], x : X) -> Unit {
  self.root = self.root.insert(x, parent=Nil)
}

// A mutable binary search tree with parent pointer
enum Tree[X] {
  Nil
  // only labelled arguments can be mutable
  Node(
    mut value~ : X,
    mut left~ : Tree[X],
    mut right~ : Tree[X],
    mut parent~ : Tree[X]
  )
}

// In-place insert a new element to a binary search tree.
// Return the new tree root
fn[X : Compare] Tree::insert(
  self : Tree[X],
  x : X,
  parent~ : Tree[X],
) -> Tree[X] {
  match self {
    Nil => Node(value=x, left=Nil, right=Nil, parent~)
    Node(_) as node => {
      let order = x.compare(node.value)
      if order == 0 {
        // mutate the field of a constructor
        node.value = x
      } else if order < 0 {
        // cycle between `node` and `node.left` created here
        node.left = node.left.insert(x, parent=node)
      } else {
        node.right = node.right.insert(x, parent=node)
      }
      // The tree is non-empty, so the new root is just the original tree
      node
    }
  }
}
```

##### Tuple Struct

MoonBit supports a special kind of struct called tuple struct:

```moonbit
struct UserId(Int)

struct UserInfo(UserId, String)
```

Tuple structs are similar to enum with only one constructor (with the same name as the tuple struct itself). So, you can use the constructor to create values, or use pattern matching to extract the underlying representation:

```moonbit
fn main {
  let id : UserId = UserId(1)
  let name : UserInfo = UserInfo(id, "John Doe")
  let UserId(uid) = id // uid : Int
  let UserInfo(_, uname) = name // uname: String
  println(uid)
  println(uname)
}
```

```default
1
John Doe
```

Besides pattern matching, you can also use index to access the elements similar to tuple:

```moonbit
fn main {
  let id : UserId = UserId(1)
  let info : UserInfo = UserInfo(id, "John Doe")
  let uid : Int = id.0
  let uname : String = info.1
  println(uid)
  println(uname)
}
```

```default
1
John Doe
```

##### Type alias

MoonBit supports type alias via the syntax `type NewType = OldType`:

###### WARNING
The old syntax `typealias OldType as NewType` may be removed in the future.

```moonbit
pub type Index = Int
pub type MyIndex = Int
pub type MyMap = Map[Int, String]
```

Unlike all other kinds of type declaration above, type alias does not define a new type,
it is merely a type macro that behaves exactly the same as its definition.
So for example one cannot define new methods or implement traits for a type alias.

##### Local types

MoonBit supports declaring structs/enums at the top of a toplevel
function, which are only visible within the current toplevel function. These
local types can use the generic parameters of the toplevel function but cannot
introduce additional generic parameters themselves. Local types can derive
methods using derive, but no additional methods can be defined manually. For
example:

```moonbit
fn[T : Show] toplevel(x : T) -> Unit {
  enum LocalEnum {
    A(T)
    B(Int)
  } derive(Show)
  struct LocalStruct {
    a : (String, T)
  } derive(Show)
  struct LocalStructTuple(T) derive(Show)
  ...
}
```

Currently, local types do not support being declared as error types.

#### Pattern Matching

Pattern matching allows us to match on specific pattern and bind data from data structures.

##### Simple Patterns

We can pattern match expressions against

- literals, such as boolean values, numbers, chars, strings, etc
- constants
- structs
- enums
- arrays
- maps
- JSONs

and so on. We can define identifiers to bind the matched values so that they can be used later.

```moonbit
const ONE = 1

fn match_int(x : Int) -> Unit {
  match x {
    0 => println("zero")
    ONE => println("one")
    value => println(value)
  }
}
```

We can use `_` as wildcards for the values we don't care about, and use `..` to ignore remaining fields of struct or enum, or array (see [array pattern]()).

```moonbit
struct Point3D {
  x : Int
  y : Int
  z : Int
}

fn match_point3D(p : Point3D) -> Unit {
  match p {
    { x: 0, .. } => println("on yz-plane")
    _ => println("not on yz-plane")
  }
}

enum Point[T] {
  Point2D(Int, Int, name~ : String, payload~ : T)
}

fn[T] match_point(p : Point[T]) -> Unit {
  match p {
    //! Point2D(0, 0) => println("2D origin")
    Point2D(0, 0, ..) => println("2D origin")
    Point2D(_) => println("2D point")
    _ => panic()
  }
}
```

We can use `as` to give a name to some pattern, and we can use `|` to match several cases at once. A variable name can only be bound once in a single pattern, and the same set of variables should be bound on both sides of `|` patterns.

```moonbit
match expr {
  //! Add(e1, e2) | Lit(e1) => ...
  Lit(n) as a => ...
  Add(e1, e2) | Mul(e1, e2) => ...
  ...
}
```

##### Array Pattern

Array patterns can be used to match on the following types to obtain their
corresponding elements or views:

| Type                                  | Element   | View         |
|---------------------------------------|-----------|--------------|
| Array[T], ArrayView[T], FixedArray[T] | T         | ArrayView[T] |
| Bytes, BytesView                      | Byte      | BytesView    |
| String, StringView                    | Char      | StringView   |

Array patterns have the following forms:

- `[]` : matching for empty array
- `[pa, pb, pc]` : matching for array of length three, and bind `pa`, `pb`, `pc`
  to the three elements
- `[pa, ..rest, pb]` : matching for array with at least two elements, and bind
  `pa` to the first element, `pb` to the last element, and `rest` to the
  remaining elements. the binder `rest` can be omitted if the rest of the
  elements are not needed. Arbitrary number of elements are allowed preceding
  and following the `..` part. Because `..` can match uncertain number of
  elements, it can appear at most once in an array pattern.

```moonbit
test {
  let ary = [1, 2, 3, 4]
  if ary is [a, b, .. rest] && a == 1 && b == 2 && rest.length() == 2 {
    inspect("a = \{a}, b = \{b}", content="a = 1, b = 2")
  } else {
    fail("")
  }
  guard ary is [.., a, b] else { fail("") }
  inspect("a = \{a}, b = \{b}", content="a = 3, b = 4")
}
```

Array patterns provide a unicode-safe way to manipulate strings, meaning that it
respects the code unit boundaries. For example, we can check if a string is a
palindrome:

```moonbit
test {
  fn palindrome(s : String) -> Bool {
    loop s.view() {
      [] | [_] => true
      [a, .. rest, b] => if a == b { continue rest } else { false }
    }
  }

  inspect(palindrome("abba"), content="true")
  inspect(palindrome("中b中"), content="true")
  inspect(palindrome("文bb中"), content="false")
}
```

When there are consecutive char or byte constants in an array pattern, the
pattern spread `..` operator can be used to combine them to make the code look
cleaner. Note that in this case the `..` followed by string or bytes constant
matches exact number of elements so its usage is not limited to once.

```moonbit
const NO : Bytes = "no"

test {
  fn match_string(s : String) -> Bool {
    match s {
      [.. "yes", ..] => true // equivalent to ['y', 'e', 's', ..]
    }
  }

  fn match_bytes(b : Bytes) -> Bool {
    match b {
      [.. NO, ..] => false // equivalent to ['n', 'o', ..]
    }
  }
}
```

##### Range Pattern

For builtin integer types and `Char`, MoonBit allows matching whether the value falls in a specific range.

Range patterns have the form `a..<b` or `a..=b`, where `..<` means the upper bound is exclusive, and `..=` means inclusive upper bound.
`a` and `b` can be one of:

- literal
- named constant declared with `const`
- `_`, meaning the pattern has no restriction on this side

Here are some examples:

```moonbit
const Zero = 0

fn sign(x : Int) -> Int {
  match x {
    _..<Zero => -1
    Zero => 0
    1..<_ => 1
  }
}

fn classify_char(c : Char) -> String {
  match c {
    'a'..='z' => "lowercase"
    'A'..='Z' => "uppercase"
    '0'..='9' => "digit"
    _ => "other"
  }
}
```

##### Map Pattern

MoonBit allows convenient matching on map-like data structures.
Inside a map pattern, the `key : value` syntax will match if `key` exists in the map, and match the value of `key` with pattern `value`.
The `key? : value` syntax will match no matter `key` exists or not, and `value` will be matched against `map[key]` (an optional).

```moonbit
match map {
  // matches if any only if "b" exists in `map`
  { "b": _, .. } => ...
  // matches if and only if "b" does not exist in `map` and "a" exists in `map`.
  // When matches, bind the value of "a" in `map` to `x`
  { "b"? : None, "a": x, .. } => ...
  // compiler reports missing case: { "b"? : None, "a"? : None }
}
```

- To match a data type `T` using map pattern, `T` must have a method `op_get(Self, K) -> Option[V]` for some type `K` and `V` (see [method and trait](methods.md)).
- Currently, the key part of map pattern must be a literal or constant
- Map patterns are always open: the unmatched keys are silently ignored, and `..` needs to be added to identify this nature
- Map pattern will be compiled to efficient code: every key will be fetched at most once

##### Json Pattern

When the matched value has type `Json`, literal patterns can be used directly, together with constructors:

```moonbit
match json {
  { "version": "1.0.0", "import": [..] as imports, .. } => ...
  { "version": Number(i, ..), "import": Array(imports), .. } => ...
  ...
}
```

##### Guard condition

Each case in a pattern matching expression can have a guard condition. A guard
condition is a boolean expression that must be true for the case to be matched.
If the guard condition is false, the case is skipped and the next case is tried.
For example:

```moonbit
fn guard_cond(x : Int?) -> Int {
  fn f(x : Int) -> Array[Int] {
    [x, x + 42]
  }

  match x {
    Some(a) if f(a) is [0, b] => a + b
    Some(b) => b
    None => -1
  }
}

test {
  assert_eq(guard_cond(None), -1)
  assert_eq(guard_cond(Some(0)), 42)
  assert_eq(guard_cond(Some(1)), 1)
}
```

Note that the guard conditions will not be considered when checking if all
patterns are covered by the match expression. So you will see a warning of
partial match for the following case:

```moonbit
fn guard_check(x : Int?) -> Unit {
  match x {
    Some(a) if a >= 0 => ()
    Some(a) if a < 0 => ()
    None => ()
  }
}
```

###### WARNING
It is not encouraged to call a function that mutates a part of the value being
matched inside a guard condition. When such case happens, the part being mutated
will not be re-evaluated in the subsequent patterns. Use it with caution.

#### Generics

Generics are supported in top-level function and data type definitions. Type parameters can be introduced within square brackets. We can rewrite the aforementioned data type `List` to add a type parameter `T` to obtain a generic version of lists. We can then define generic functions over lists like `map` and `reduce`.

```moonbit
///|
enum List[T] {
  Nil
  Cons(T, List[T])
}

///|
fn[S, T] List::map(self : List[S], f : (S) -> T) -> List[T] {
  match self {
    Nil => Nil
    Cons(x, xs) => Cons(f(x), xs.map(f))
  }
}

///|
fn[S, T] List::reduce(self : List[S], op : (T, S) -> T, init : T) -> T {
  match self {
    Nil => init
    Cons(x, xs) => xs.reduce(op, op(init, x))
  }
}
```

#### Special Syntax

##### Pipelines

MoonBit provides a convenient pipe syntax `x |> f(y)`, which can be used to chain regular function calls:

```moonbit
5 |> ignore // <=> ignore(5)
[] |> Array::push(5) // <=> Array::push([], 5)
1
|> add(5) // <=> add(1, 5)
|> x => { x + 1 }
|> ignore // <=> ignore(add(1, 5))
```

The MoonBit code follows the *data-first* style, meaning the function places its "subject" as the first argument.
Thus, the pipe operator inserts the left-hand side value into the first argument of the right-hand side function call by default.
For example, `x |> f(y)` is equivalent to `f(x, y)`.

You can use the `_` operator to insert `x` into any argument of the function `f`, such as `x |> f(y, _)`, which is equivalent to `f(y, x)`. Labeled arguments are also supported.

The pipe operator can also connect to an arrow function. When piping into an arrow function, the function body must be wrapped in curly braces, for example `value |> x => { x + 1 }`.

##### Cascade Operator

The cascade operator `..` is used to perform a series of mutable operations on
the same value consecutively. The syntax is as follows:

```moonbit
[]..append([1])
```

- `x..f()..g()` is equivalent to `{ x.f(); x.g(); }`.
- `x..f().g()` is equivalent to `{ x.f(); x.g(); }`.

Consider the following scenario: for a `StringBuilder` type that has methods
like `write_string`, `write_char`, `write_object`, etc., we often need to perform
a series of operations on the same `StringBuilder` value:

```moonbit
let builder = StringBuilder::new()
builder.write_char('a')
builder.write_char('a')
builder.write_object(1001)
builder.write_string("abcdef")
let result = builder.to_string()
```

To avoid repetitive typing of `builder`, its methods are often designed to
return `self` itself, allowing operations to be chained using the `.` operator.
To distinguish between immutable and mutable operations, in MoonBit,
for all methods that return `Unit`, cascade operator can be used for
consecutive operations without the need to modify the return type of the methods.

```moonbit
let result = StringBuilder::new()
  ..write_char('a')
  ..write_char('a')
  ..write_object(1001)
  ..write_string("abcdef")
  .to_string()
```

##### is Expression

The `is` expression tests whether a value conforms to a specific pattern. It
returns a `Bool` value and can be used anywhere a boolean value is expected,
for example:

```moonbit
fn[T] is_none(x : T?) -> Bool {
  x is None
}

fn start_with_lower_letter(s : String) -> Bool {
  s is ['a'..='z', ..]
}
```

Pattern binders introduced by `is` expressions can be used in the following
contexts:

1. In boolean AND expressions (`&&`):
   binders introduced in the left-hand expression can be used in the right-hand
   expression
   ```moonbit
   fn f(x : Int?) -> Bool {
     x is Some(v) && v >= 0
   }
   ```
2. In the first branch of `if` expression: if the condition is a sequence of
   boolean expressions `e1 && e2 && ...`, the binders introduced by the `is`
   expression can be used in the branch where the condition evaluates to `true`.
   ```moonbit
   fn g(x : Array[Int?]) -> Unit {
     if x is [v, .. rest] && v is Some(i) && i is (0..=10) {
       println(v)
       println(i)
       println(rest)
     }
   }
   ```
3. In the following statements of a `guard` condition:
   ```moonbit
   fn h(x : Int?) -> Unit {
     guard x is Some(v)
     println(v)
   }
   ```
4. In the body of a `while` loop:
   ```moonbit
   fn i(x : Int?) -> Unit {
     let mut m = x
     while m is Some(v) {
       println(v)
       m = None
     }
   }
   ```

Note that `is` expression can only take a simple pattern. If you need to use
`as` to bind the pattern to a variable, you have to add parentheses. For
example:

```moonbit
fn j(x : Int) -> Int? {
  Some(x)
}

fn init {
  guard j(42) is (Some(a) as b)
  println(a)
  println(b)
}
```

##### Lexmatch

`lexmatch` matches a `String` against a regex pattern and lets you bind the
pieces of a match. The search-mode pattern is `(before, regex pieces, after)`,
where `before` and `after` are optional bindings for the unmatched prefix and
suffix, separated by commas. The regex pieces in the middle are separated by
whitespace only. The regex itself is written as a sequence of string literals,
so you can split it across lines or insert comments between parts. You can
also bind a matched sub-pattern using `as`, such as `("b*" as b)`.

`lexmatch?` is a boolean check similar to `is`, and it can introduce binders
for use in the same contexts as `is` expressions.

`lexmatch` also supports a lexer-style mode: `lexmatch <expr> with longest`,
which picks the longest match among alternatives (for example, `if|[a-z]*`
matches `iff` as `iff` in longest mode, while search mode matches `if` first).

Regex literals do not support `\\b`, `\\s`, or `\\w`. Use POSIX character
classes like `[:digit:]` inside ranges (for example, `[[:digit:]]`).

```moonbit
test {
  let text = "xxabbbcyy"
  lexmatch text {
    (before, "a" ("b*" as b) "c", after) => {
      inspect(before, content="xx")
      inspect(b, content="bbb")
      inspect(after, content="yy")
    }
    _ => fail("")
  }

  if text lexmatch? ("a" ("b*" as b) "c") && b.length() > 0 {
    inspect(b, content="bbb")
  }

  let keyword = "iff"
  lexmatch keyword with longest {
    ("if|[a-z]*" as ident) => inspect(ident, content="iff")
    _ => fail("")
  }
}
```

##### Spread Operator

MoonBit provides a spread operator to expand a sequence of elements when
constructing `Array`, `String`, and `Bytes` using the array literal syntax. To
expand such a sequence, it needs to be prefixed with `..`, and it must have
`iter()` method that yields the corresponding type of element.

For example, we can use the spread operator to construct an array:

```moonbit
test {
  let a1 : Array[Int] = [1, 2, 3]
  let a2 : FixedArray[Int] = [4, 5, 6]
  let a3 : @list.List[Int] = @list.from_array([7, 8, 9])
  let a : Array[Int] = [..a1, ..a2, ..a3, 10]
  inspect(a, content="[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]")
}
```

Similarly, we can use the spread operator to construct a string:

```moonbit
test {
  let s1 : String = "Hello"
  let s2 : StringView = "World".view()
  let s3 : Array[Char] = [..s1, ' ', ..s2, '!']
  let s : String = [..s1, ' ', ..s2, '!', ..s3]
  inspect(s, content="Hello World!Hello World!")
}
```

The last example shows how the spread operator can be used to construct a bytes
sequence.

```moonbit
test {
  let b1 : Bytes = "hello"
  let b2 : BytesView = b1[1:4]
  let b : Bytes = [..b1, ..b2, 10]
  inspect(
    b,
    content=(
      #|b"helloell\x0a"
    ),
  )
}
```

##### TODO syntax

The `todo` syntax (`...`) is a special construct used to mark sections of code that are not yet implemented or are placeholders for future functionality. For example:

```moonbit
fn todo_in_func() -> Int {
  ...
}
```

<!-- path: language/methods.md -->
### Method and Trait

#### Method system

MoonBit supports methods in a different way from traditional object-oriented languages. A method in MoonBit is just a toplevel function associated with a type constructor.
To define a method, prepend `SelfTypeName::` in front of the function name, such as `fn SelfTypeName::method_name(...)`, and the method belongs to `SelfTypeName`.
Within the signature of the method declaration, you can use `Self` to refer to `SelfTypeName`.

###### WARNING
Currently, there is a shorthand syntax for defining methods.
When the name of the first parameter is `self`, a function declaration will be considered a method for the type of `self`.
This syntax may be deprecated in the future, and we do not recommend using it in new code.

```moonbit
fn method_name(self : SelfType) -> Unit { ... }
```

```moonbit
enum List[X] {
  Nil
  Cons(X, List[X])
}

///|
fn[X] List::length(xs : List[X]) -> Int {
  ...
}
```

To call a method, you can either invoke using qualified syntax `T::method_name(..)`, or using dot syntax where the first argument is the type of `T`:

```moonbit
let l : List[Int] = Nil
println(l.length())
println(List::length(l))
```

When the first parameter of a method is also the type it belongs to, methods can be called using dot syntax `x.method(...)`. MoonBit automatically finds the correct method based on the type of `x`, there is no need to write the type name and even the package name of the method:

```moonbit
pub(all) enum List[X] {
  Nil
  Cons(X, List[X])
}

pub fn[X] List::concat(list : List[List[X]]) -> List[X] {
  ...
}
```

```moonbit
// assume `xs` is a list of lists, all the following two lines are equivalent
let _ = xs.concat()
let _ = @list.List::concat(xs)
```

Unlike regular functions, methods defined using the `TypeName::method_name` syntax support overloading:
different types can define methods of the same name, because each method lives in a different name space:

```moonbit
struct T1 {
  x1 : Int
}

fn T1::default() -> T1 {
  { x1: 0 }
}

struct T2 {
  x2 : Int
}

fn T2::default() -> T2 {
  { x2: 0 }
}

test {
  let t1 = T1::default()
  let t2 = T2::default()

}
```

##### Local method

To ensure single source of truth in method resolution and avoid ambiguity,
[methods can only be defined in the same package as its type](packages.md#trait-implementations).
However, there is one exception to this rule: MoonBit allows defining *private* methods for foreign types locally.
These local methods can override methods from the type's own package (MoonBit will emit a warning in this case),
and provide extension/complementary to upstream API:

```moonbit
fn Int::my_int_method(self : Int) -> Int {
  self * self + self
}

test {
  assert_eq((6).my_int_method(), 42)
}
```

##### Alias methods as functions

MoonBit allows calling methods with alternative names via alias.

The method alias will create a method with the corresponding name.
You can also choose to create a function with the corresponding name.
The visibility can also be controlled.

```moonbit
###alias(m)
###alias(n, visibility="priv")
###as_free_fn(m)
###as_free_fn(n, visibility="pub")
fn List::f() -> Bool {
  true
}
test {
  assert_eq(List::f(), List::m())
  assert_eq(List::m(), m())
}
```

#### Operator Overloading

MoonBit supports overloading infix operators of builtin operators via several builtin traits. For example:

```moonbit
struct T {
  x : Int
}

impl Add for T with add(self : T, other : T) -> T {
  { x: self.x + other.x }
}

test {
  let a = { x: 0 }
  let b = { x: 2 }
  assert_eq((a + b).x, 2)
}
```

Other operators are overloaded via methods with annotations, for example `_[_]` and `_[_]=_`:

```moonbit
struct Coord {
  mut x : Int
  mut y : Int
} derive(Show)

###alias("_[_]")
fn Coord::get(coord : Self, key : String) -> Int {
  match key {
    "x" => coord.x
    "y" => coord.y
  }
}

###alias("_[_]=_")
fn Coord::set(coord : Self, key : String, val : Int) -> Unit {
  match key {
    "x" => coord.x = val
    "y" => coord.y = val
  }
}
```

```moonbit
fn main {
  let c = { x: 1, y: 2 }
  println(c)
  println(c["y"])
  c["x"] = 23
  println(c)
  println(c["x"])
}
```

```default
{x: 1, y: 2}
2
{x: 23, y: 2}
23
```

Currently, the following operators can be overloaded:

| Operator Name         | overloading mechanism   |
|-----------------------|-------------------------|
| `+`                   | trait `Add`             |
| `-`                   | trait `Sub`             |
| `*`                   | trait `Mul`             |
| `/`                   | trait `Div`             |
| `%`                   | trait `Mod`             |
| `==`                  | trait `Eq`              |
| `<<`                  | trait `Shl`             |
| `>>`                  | trait `Shr`             |
| `-` (unary)           | trait `Neg`             |
| `_[_]` (get item)     | method + alias `_[_]`   |
| `_[_] = _` (set item) | method + alias `_[_]=_` |
| `_[_:_]` (view)       | method + alias `_[_:_]` |
| `&`                   | trait `BitAnd`          |
| `|`                   | trait `BitOr`           |
| `^`                   | trait `BitXOr`          |

When overloading `_[_]`/`_[_] = _`/`_[_:_]`, the method must have a correcnt signature:

- `_[_]` should have signature `(Self, Index) -> Result`, used as `let result = self[index]`
- `_[_]=_` should have signature `(Self, Index, Value) -> Unit`, used as `self[index] = value`
- `_[_:_]` should have signature `(Self, start? : Index, end? : Index) -> Result`, used as `let result = self[start:end]`

By implementing `_[_:_]` method, you can create a view for a user-defined type. Here is an example:

```moonbit
struct DataView(String)

struct Data {}

###alias("_[_:_]")
fn Data::as_view(_self : Data, start? : Int = 0, end? : Int) -> DataView {
  "[\{start}, \{end.unwrap_or(100)})"
}

test {
  let data = Data::{  }
  inspect(data[:].0, content="[0, 100)")
  inspect(data[2:].0, content="[2, 100)")
  inspect(data[:5].0, content="[0, 5)")
  inspect(data[2:5].0, content="[2, 5)")
}
```

#### Trait system

MoonBit provides a trait system for overloading/ad-hoc polymorphism. Traits declare a list of operations, which must be supplied when a type wants to implement the trait. Traits can be declared as follows:

```moonbit
pub(open) trait I {
  method_(Int) -> Int
  method_with_label(Int, label~ : Int) -> Int
  //! method_with_label(Int, label?: Int) -> Int
}
```

In the body of a trait definition, a special type `Self` is used to refer to the type that implements the trait.

##### Extending traits

A trait can depend on other traits, for example:

```moonbit
pub(open) trait Position {
  pos(Self) -> (Int, Int)
}

pub(open) trait Draw {
  draw(Self, Int, Int) -> Unit
}

pub(open) trait Object: Position + Draw {}
```

##### Implementing traits

To implement a trait, a type must explicitly provide all the methods required by the trait
using the syntax `impl Trait for Type with method_name(...) { ... }`. For example:

```moonbit
pub(open) trait MyShow {
  to_string(Self) -> String
}

struct MyType {}

pub impl MyShow for MyType with to_string(self) {
  ...
}

struct MyContainer[_] {}

// trait implementation with type parameters.
// `[X : Show]` means the type parameter `X` must implement `Show`,
// this will be covered later.
pub impl[X : MyShow] MyShow for MyContainer[X] with to_string(self) {
  ...
}
```

Type annotation can be omitted for trait `impl`: MoonBit will automatically infer the type based on the signature of `Trait::method` and the self type.

The author of the trait can also define **default implementations** for some methods in the trait, for example:

```moonbit
pub(open) trait J {
  f(Self) -> Unit
  f_twice(Self) -> Unit = _
}

impl J with f_twice(self) {
  self.f()
  self.f()
}
```

Note that in addition to the actual default implementation `impl J with f_twice`,
a mark `= _` is also required in the declaration of `f_twice` in `J`.
The `= _` mark is an indicator that this method has default implementation,
it enhances readability by allowing readers to know which methods have default implementation at first glance.

Implementers of trait `J` don't have to provide an implementation for `f_twice`: to implement `J`, only `f` is necessary.
They can always override the default implementation with an explicit `impl J for Type with f_twice`, if desired, though.

```moonbit
impl J for Int with f(self) {
  println(self)
}

impl J for String with f(self) {
  println(self)
}

impl J for String with f_twice(self) {
  println(self)
  println(self)
}

```

To implement the sub trait, one will have to implement the super traits,
and the methods defined in the sub trait. For example:

```moonbit
impl Position for Point with pos(self) {
  (self.x, self.y)
}

impl Draw for Point with draw(self, x, y) {
  ()
}

pub fn[O : Object] draw_object(obj : O) -> Unit {
  let (x, y) = obj.pos()
  obj.draw(x, y)
}

test {
  let p = Point::{ x: 1, y: 2 }
  draw_object(p)
}
```

For traits where all methods have default implementation,
it is still necessary to explicitly implement them,
in order to support features such as [abstract trait](packages.md#traits).
For this purpose, MoonBit provides the syntax `impl Trait for Type` (i.e. without the method part).
`impl Trait for Type` ensures that `Type` implements `Trait`,
MoonBit will automatically check if every method in `Trait` has corresponding implementation (custom or default).

In addition to handling traits where every methods has a default implementation,
the `impl Trait for Type` can also serve as documentation, or a TODO mark before filling actual implementation.

###### WARNING
Currently, an empty trait without any method is implemented automatically.

##### Using traits

When declaring a generic function, the type parameters can be annotated with the traits they should implement, allowing the definition of constrained generic functions. For example:

```moonbit
fn[X : Eq] contains(xs : Array[X], elem : X) -> Bool {
  for x in xs {
    if x == elem {
      return true
    }
  } else {
    false
  }
}
```

Without the `Eq` requirement, the expression `x == elem` in `contains` will result in a type error. Now, the function `contains` can be called with any type that implements `Eq`, for example:

```moonbit
struct Point {
  x : Int
  y : Int
}

impl Eq for Point with equal(p1, p2) {
  p1.x == p2.x && p1.y == p2.y
}

test {
  assert_false(contains([1, 2, 3], 4))
  assert_true(contains([1.5, 2.25, 3.375], 2.25))
  assert_false(contains([{ x: 2, y: 3 }], { x: 4, y: 9 }))
}
```

###### Invoke trait methods directly

Methods of a trait can be called directly via `Trait::method`. MoonBit will infer the type of `Self` and check if `Self` indeed implements `Trait`, for example:

```moonbit
test {
  assert_eq(Show::to_string(42), "42")
  assert_eq(Compare::compare(1.0, 2.5), -1)
}
```

Trait implementations can also be invoked via dot syntax, with the following restrictions:

1. if a regular method is present, the regular method is always favored when using dot syntax
2. only trait implementations that are located in the package of the self type can be invoked via dot syntax
   - if there are multiple trait methods (from different traits) with the same name available, an ambiguity error is reported

The above rules ensures that MoonBit's dot syntax enjoys good property while being flexible.
For example, adding a new dependency never break existing code with dot syntax due to ambiguity.
These rules also make name resolution of MoonBit extremely simple:
the method called via dot syntax must always come from current package or the package of the type!

Here's an example of calling trait `impl` with dot syntax:

```moonbit
struct MyCustomType {}

pub impl Show for MyCustomType with output(self, logger) {
  ...
}

fn f() -> Unit {
  let x = MyCustomType::{  }
  let _ = x.to_string()

}
```

#### Trait objects

MoonBit supports runtime polymorphism via trait objects.
If `t` is of type `T`, which implements trait `I`,
one can pack the methods of `T` that implements `I`, together with `t`,
into a runtime object via `t as &I`.
When the expected type of an expression is known to be a trait object type, `as &I` can be omitted.
Trait object erases the concrete type of a value,
so objects created from different concrete types can be put in the same data structure and handled uniformly:

```moonbit
pub(open) trait Animal {
  speak(Self) -> String
}

struct Duck(String)

fn Duck::make(name : String) -> Duck {
  Duck(name)
}

impl Animal for Duck with speak(self) {
  "\{self.0}: quack!"
}

struct Fox(String)

fn Fox::make(name : String) -> Fox {
  Fox(name)
}

impl Animal for Fox with speak(_self) {
  "What does the fox say?"
}

test {
  let duck1 = Duck::make("duck1")
  let duck2 = Duck::make("duck2")
  let fox1 = Fox::make("fox1")
  let animals : Array[&Animal] = [duck1, duck2, fox1]
  inspect(
    animals.map(fn(animal) { animal.speak() }),
    content=(
      #|["duck1: quack!", "duck2: quack!", "What does the fox say?"]
    ),
  )
}
```

Not all traits can be used to create objects.
"object-safe" traits' methods must satisfy the following conditions:

- `Self` must be the first parameter of a method
- There must be only one occurrence of `Self` in the type of the method (i.e. the first parameter)

Users can define new methods for trait objects, just like defining new methods for structs and enums:

```moonbit
pub(open) trait Logger {
  write_string(Self, String) -> Unit
}

pub(open) trait CanLog {
  log(Self, &Logger) -> Unit
}

fn[Obj : CanLog] &Logger::write_object(self : &Logger, obj : Obj) -> Unit {
  obj.log(self)
}

// use the new method to simplify code
pub impl[A : CanLog, B : CanLog] CanLog for (A, B) with log(self, logger) {
  let (a, b) = self
  logger
  ..write_string("(")
  ..write_object(a)
  ..write_string(", ")
  ..write_object(b)
  ..write_string(")")
}
```

#### Builtin traits

MoonBit provides the following useful builtin traits:

<!-- MANUAL CHECK https://github.com/moonbitlang/core/blob/80cf250d22a5d5eff4a2a1b9a6720026f2fe8e38/builtin/traits.mbt -->
```moonbit
trait Eq {
  op_equal(Self, Self) -> Bool
}

trait Compare : Eq {
  // `0` for equal, `-1` for smaller, `1` for greater
  compare(Self, Self) -> Int
}

trait Hash {
  hash_combine(Self, Hasher) -> Unit // to be implemented
  hash(Self) -> Int // has default implementation
}

trait Show {
  output(Self, Logger) -> Unit // to be implemented
  to_string(Self) -> String // has default implementation
}

trait Default {
  default() -> Self
}
```

##### Deriving builtin traits

MoonBit can automatically derive implementations for some builtin traits:

```moonbit
struct T {
  a : Int
  b : Int
} derive(Eq, Compare, Show, Default)

test {
  let t1 = T::default()
  let t2 = T::{ a: 1, b: 1 }
  inspect(t1, content="{a: 0, b: 0}")
  inspect(t2, content="{a: 1, b: 1}")
  assert_not_eq(t1, t2)
  assert_true(t1 < t2)
}
```

See [Deriving](derive.md) for more information about deriving traits.

<!-- path: language/derive.md -->
### Deriving traits

MoonBit supports deriving a number of builtin traits automatically from the type definition.

To derive a trait `T`, it is required that all fields used in the type implements `T`.
For example, deriving `Show` for a struct `struct A { x: T1; y: T2 }` requires both `T1: Show` and `T2: Show`

#### Show

`derive(Show)` will generate a pretty-printing method for the type.
The derived format is similar to how the type can be constructed in code.

```moonbit
struct MyStruct {
  x : Int
  y : Int
} derive(Show)

test "derive show struct" {
  let p = MyStruct::{ x: 1, y: 2 }
  assert_eq(Show::to_string(p), "{x: 1, y: 2}")
}
```

```moonbit
enum MyEnum {
  Case1(Int)
  Case2(label~ : String)
  Case3
} derive(Show)

test "derive show enum" {
  assert_eq(Show::to_string(MyEnum::Case1(42)), "Case1(42)")
  assert_eq(
    Show::to_string(MyEnum::Case2(label="hello")),
    "Case2(label=\"hello\")",
  )
  assert_eq(Show::to_string(MyEnum::Case3), "Case3")
}
```

#### Eq and Compare

`derive(Eq)` and `derive(Compare)` will generate the corresponding method for testing equality and comparison.
Fields are compared in the same order as their definitions.
For enums, the order between cases ascends in the order of definition.

```moonbit
struct DeriveEqCompare {
  x : Int
  y : Int
} derive(Eq, Compare)

test "derive eq_compare struct" {
  let p1 = DeriveEqCompare::{ x: 1, y: 2 }
  let p2 = DeriveEqCompare::{ x: 2, y: 1 }
  let p3 = DeriveEqCompare::{ x: 1, y: 2 }
  let p4 = DeriveEqCompare::{ x: 1, y: 3 }

  // Eq
  assert_eq(p1 == p2, false)
  assert_eq(p1 == p3, true)
  assert_eq(p1 == p4, false)
  assert_eq(p1 != p2, true)
  assert_eq(p1 != p3, false)
  assert_eq(p1 != p4, true)

  // Compare
  assert_eq(p1 < p2, true)
  assert_eq(p1 < p3, false)
  assert_eq(p1 < p4, true)
  assert_eq(p1 > p2, false)
  assert_eq(p1 > p3, false)
  assert_eq(p1 > p4, false)
  assert_eq(p1 <= p2, true)
  assert_eq(p1 >= p2, false)
}
```

```moonbit
enum DeriveEqCompareEnum {
  Case1(Int)
  Case2(label~ : String)
  Case3
} derive(Eq, Compare)

test "derive eq_compare enum" {
  let p1 = DeriveEqCompareEnum::Case1(42)
  let p2 = DeriveEqCompareEnum::Case1(43)
  let p3 = DeriveEqCompareEnum::Case1(42)
  let p4 = DeriveEqCompareEnum::Case2(label="hello")
  let p5 = DeriveEqCompareEnum::Case2(label="world")
  let p6 = DeriveEqCompareEnum::Case2(label="hello")
  let p7 = DeriveEqCompareEnum::Case3

  // Eq
  assert_eq(p1 == p2, false)
  assert_eq(p1 == p3, true)
  assert_eq(p1 == p4, false)
  assert_eq(p1 != p2, true)
  assert_eq(p1 != p3, false)
  assert_eq(p1 != p4, true)

  // Compare
  assert_eq(p1 < p2, true) // 42 < 43
  assert_eq(p1 < p3, false)
  assert_eq(p1 < p4, true) // Case1 < Case2
  assert_eq(p4 < p5, true)
  assert_eq(p4 < p6, false)
  assert_eq(p4 < p7, true) // Case2 < Case3
}
```

#### Default

`derive(Default)` will generate a method that returns the default value of the type.

For structs, the default value is the struct with all fields set as their default value.

```moonbit
struct DeriveDefault {
  x : Int
  y : String?
} derive(Default, Eq, Show)

test "derive default struct" {
  let p = DeriveDefault::default()
  assert_eq(p, DeriveDefault::{ x: 0, y: None })
}
```

For enums, the default value is the only case that has no parameters.

```moonbit
enum DeriveDefaultEnum {
  Case1(Int)
  Case2(label~ : String)
  Case3
} derive(Default, Eq, Show)

test "derive default enum" {
  assert_eq(DeriveDefaultEnum::default(), DeriveDefaultEnum::Case3)
}
```

Enums that has no cases or more than one cases without parameters cannot derive `Default`.

<!-- MANUAL CHECK  should not compile -->
```moonbit
enum CannotDerive1 {
    Case1(String)
    Case2(Int)
} derive(Default) // cannot find a constant constructor as default

enum CannotDerive2 {
    Case1
    Case2
} derive(Default) // Case1 and Case2 are both candidates as default constructor
```

#### Hash

`derive(Hash)` will generate a hash implementation for the type.
This will allow the type to be used in places that expects a `Hash` implementation,
for example `HashMap`s and `HashSet`s.

```moonbit
struct DeriveHash {
  x : Int
  y : String?
} derive(Hash, Eq, Show)

test "derive hash struct" {
  let hs = @hashset.new()
  hs.add(DeriveHash::{ x: 123, y: None })
  hs.add(DeriveHash::{ x: 123, y: None })
  assert_eq(hs.length(), 1)
  hs.add(DeriveHash::{ x: 123, y: Some("456") })
  assert_eq(hs.length(), 2)
}
```

#### Arbitrary

`derive(Arbitrary)` will generate random values of the given type.

#### FromJson and ToJson

`derive(FromJson)` and `derive(ToJson)` automatically derives round-trippable method implementations
used for serializing the type to and from JSON.
The implementation is mainly for debugging and storing the types in a human-readable format.

```moonbit
struct JsonTest1 {
  x : Int
  y : Int
} derive(FromJson, ToJson, Eq, Show)

enum JsonTest2 {
  A(x~ : Int)
  B(x~ : Int, y~ : Int)
} derive(FromJson(style="legacy"), ToJson(style="legacy"), Eq, Show)

test "json basic" {
  let input = JsonTest1::{ x: 123, y: 456 }
  let expected : Json = { "x": 123, "y": 456 }
  assert_eq(input.to_json(), expected)
  assert_eq(@json.from_json(expected), input)
  let input = JsonTest2::A(x=123)
  let expected : Json = { "$tag": "A", "x": 123 }
  assert_eq(input.to_json(), expected)
  assert_eq(@json.from_json(expected), input)
}
```

Both derive directives accept a number of arguments to configure the exact behavior of serialization and deserialization.

###### WARNING
The actual behavior of JSON serialization arguments is unstable.

###### WARNING
JSON derivation arguments are only for coarse-grained control of the derived format.
If you need to precisely control how the types are laid out,
consider **directly implementing the two traits instead**.

We have recently deprecated a large number of advanced layout tweaking arguments.
For such usage and future usage of them, please manually implement the traits.
The arguments include: `repr`, `case_repr`, `default`, `rename_all`, etc.

```moonbit
struct JsonTest3 {
  x : Int
  y : Int
} derive (
  FromJson(fields(x(rename="renamedX"))),
  ToJson(fields(x(rename="renamedX"))),
  Eq,
  Show,
)

enum JsonTest4 {
  A(x~ : Int)
  B(x~ : Int, y~ : Int)
} derive(FromJson, ToJson, Eq, Show)

test "json args" {
  let input = JsonTest3::{ x: 123, y: 456 }
  let expected : Json = { "renamedX": 123, "y": 456 }
  assert_eq(input.to_json(), expected)
  assert_eq(@json.from_json(expected), input)
  let input = JsonTest4::A(x=123)
  let expected : Json = ["A", { "x": 123 }]
  assert_eq(input.to_json(), expected)
  assert_eq(@json.from_json(expected), input)
}
```

##### Enum styles

There are currently two styles of enum serialization: `legacy` and `flat`,
which the user must select one using the `style` argument.
Considering the following enum definition:

```moonbit
enum E {
  One
  Uniform(Int)
  Axes(x~: Int, y~: Int)
}
```

With `derive(ToJson(style="legacy"))`, the enum is formatted into:

```default
E::One              => { "$tag": "One" }
E::Uniform(2)       => { "$tag": "Uniform", "0": 2 }
E::Axes(x=-1, y=1)  => { "$tag": "Axes", "x": -1, "y": 1 }
```

With `derive(ToJson(style="flat"))`, the enum is formatted into:

```default
E::One              => "One"
E::Uniform(2)       => [ "Uniform", 2 ]
E::Axes(x=-1, y=1)  => [ "Axes", -1, 1 ]
```

###### Deriving `Option`

A notable exception is the builtin type `Option[T]`.
Ideally, it would be interpreted as `T | undefined`, but the issue is that it would be
impossible to distinguish `Some(None)` and `None` for `Option[Option[T]]`.

As a result, it interpreted as `T | undefined` iff it is a direct field
of a struct, and `[T] | null` otherwise:

```moonbit
struct A {
  x : Int?
  y : Int??
  z : (Int?, Int??)
} derive(ToJson)

test {
  @json.inspect({ x: None, y: None, z: (None, None) }, content={
    "z": [null, null],
  })
  @json.inspect({ x: Some(1), y: Some(None), z: (Some(1), Some(None)) }, content={
    "x": 1,
    "y": null,
    "z": [[1], [null]],
  })
  @json.inspect({ x: Some(1), y: Some(Some(1)), z: (Some(1), Some(Some(1))) }, content={
    "x": 1,
    "y": [1],
    "z": [[1], [[1]]],
  })
}
```

##### Container arguments

- `rename_fields` and `rename_cases` (enum only)
  batch renames fields (for enums and structs) and enum cases to the given format.
  Available parameters are:
  - `lowercase`
  - `UPPERCASE`
  - `camelCase`
  - `PascalCase`
  - `snake_case`
  - `SCREAMING_SNAKE_CASE`
  - `kebab-case`
  - `SCREAMING-KEBAB-CASE`

  Example: `rename_fields = "PascalCase"`
  for a field named `my_long_field_name`
  results in `MyLongFieldName`.

  Renaming assumes the name of fields in `snake_case`
  and the name of structs/enum cases in `PascalCase`.
- `cases(...)` (enum only) controls the layout of enum cases.

  #### WARNING
  This might be replaced with case attributes in the future.

  For example, for an enum
  ```moonbit
  enum E {
    A(...)
    B(...)
  }
  ```

  you are able to control each case using `cases(A(...), B(...))`.

  See [Case arguments]() below for details.
- `fields(...)` (struct only) controls the layout of struct fields.

  #### WARNING
  This might be replaced with field attributes in the future.

  For example, for a struct
  ```moonbit
  struct S {
    x: Int
    y: Int
  }
  ```

  you are able to control each field using `fields(x(...), y(...))`

  See [Field arguments]() below for details.

##### Case arguments

- `rename = "..."` renames this specific case,
  overriding existing container-wide rename directive if any.
- `fields(...)` controls the layout of the payload of this case.
  Note that renaming positional fields are not possible currently.

  See [Field arguments]() below for details.

##### Field arguments

- `rename = "..."` renames this specific field,
  overriding existing container-wide rename directives if any.

<!-- path: language/error-handling.md -->
### Error handling

Error handling has always been at core of our language design. In the following
we'll be explaining how error handling is done in MoonBit. We assume you have
some prior knowledge of MoonBit, if not, please checkout
[A tour of MoonBit](../tutorial/tour.md).

#### Error Types

In MoonBit, all the error values can be represented by the `Error` type, a
generalized error type.

However, an `Error` cannot be constructed directly. A concrete error type must
be defined, in the following forms:

```moonbit
suberror E1 { E1(Int) } // error type E1 has one constructor E1 with an Int payload

suberror E2 // error type E2 has one constructor E2 with no payload

suberror E3 { // error type E3 has three constructors like a normal enum type
  A
  B(Int, x~ : String)
  C(mut x~ : String, Char, y~ : Bool)
}
```

###### WARNING
The older `suberror A B` syntax is deprecated. Use `suberror A { A(B) }` instead.

The error types can be promoted to the `Error` type automatically, and pattern
matched back:

```moonbit
suberror CustomError { CustomError(UInt) }

test {
  let e : Error = CustomError(42)
  guard e is CustomError(m)
  assert_eq(m, 42)
}
```

Since the type `Error` can include multiple error types, pattern matching on the
`Error` type must use the wildcard `_` to match all error types. For example,

```moonbit
fn f(e : Error) -> Unit {
  match e {
    E2 => println("E2")
    A => println("A")
    B(i, x~) => println("B(\{i}, \{x})")
    _ => println("unknown error")
  }
}
```

The `Error` is meant to be used where no concrete error type is needed, or a
catch-all for all kinds of sub-errors is needed.

##### Failure

A builtin error type is `Failure`.

There's a handly `fail` function, which is merely a constructor with a
pre-defined output template for showing both the error and the source location.
In practice, `fail` is always preferred over `Failure`.

<!-- MANUAL CHECK -->
```moonbit
###callsite(autofill(loc))
pub fn[T] fail(msg : String, loc~ : SourceLoc) -> T raise Failure {
  raise Failure("FAILED: \{loc} \{msg}")
}
```

#### Throwing Errors

The keyword `raise` is used to interrupt the function execution and return an
error.

The type declaration of a function can use `raise` with an Error type to
indicate that the function might raise an error during an execution. For
example, the following function `div` might return an error of type `DivError`:

```moonbit
suberror DivError { DivError(String) }

fn div(x : Int, y : Int) -> Int raise DivError {
  if y == 0 {
    raise DivError("division by zero")
  }
  x / y
}
```

The `Error` can be used when the concrete error type is not important. For
convenience, you can omit the error type after the `raise` to indicate that the
`Error` type is used. For example, the following function signatures are
equivalent:

```moonbit
fn f() -> Unit raise {
  ...
}

fn g() -> Unit raise Error {
  let h : () -> Unit raise = fn() raise { fail("fail") }
  ...
}
```

For functions that are generic in the error type, you can use the `Error` bound
to do that. For example,

```moonbit
// Result::unwrap_or_error
fn[T, E : Error] unwrap_or_error(result : Result[T, E]) -> T raise E {
  match result {
    Ok(x) => x
    Err(e) => raise e
  }
}
```

For functions that do not raise an error, you can add `noraise` in the
signature. For example:

```moonbit
fn add(a : Int, b : Int) -> Int noraise {
  a + b
}
```

##### Error Polymorphism

It happens when a higher order function accepts another function as parameter.
The function as parameter may or may not throw error, which in turn affects the
behavior of this function.

A notable example is `map` of `Array`:

```moonbit
fn[T] map(array : Array[T], f : (T) -> T raise) -> Array[T] raise {
  let mut res = []
  for x in array {
    res.push(f(x))
  }
  res
}
```

However, writing so would make the `map` function constantly having the
possibility of throwing errors, which is not the case.

Thus, the error polymorphism is introduced. You may use `raise?` to signify that
an error may or may not be throw.

```moonbit
fn[T] map_with_polymorphism(
  array : Array[T],
  f : (T) -> T raise?
) -> Array[T] raise? {
  let mut res = []
  for x in array {
    res.push(f(x))
  }
  res
}

fn[T] map_without_error(
  array : Array[T],
  f : (T) -> T noraise,
) -> Array[T] noraise {
  map_with_polymorphism(array, f)
}

fn[T] map_with_error(array : Array[T], f : (T) -> T raise) -> Array[T] raise {
  map_with_polymorphism(array, f)
}
```

The signature of the `map_with_polymorphism` will be determined by the actual
parameter.

#### Handling Errors

Applying the function normally will rethrow the error directly in case of an
error. For example:

```moonbit
fn div_reraise(x : Int, y : Int) -> Int raise DivError {
  div(x, y) // Rethrow the error if `div` raised an error
}
```

However, you may want to handle the errors.

##### Try ... Catch

You can use `try` and `catch` to catch and handle errors, for example:

```moonbit
fn main {
  try div(42, 0) catch {
    DivError(s) => println(s)
  } noraise {
    v => println(v)
  }
}
```

```default
division by zero
```

Here, `try` is used to call a function that might throw an error, and `catch` is
used to match and handle the caught error. If no error is caught, the catch
block will not be executed and the `noraise` block will be executed instead.

The `noraise` block can be omitted if no action is needed when no error is
caught. For example:

```moonbit
try { println(div(42, 0)) } catch {
  _ => println("Error")
}
```

When the body of `try` is a simple expression, the curly braces, and even the
`try` keyword can be omitted. For example:

```moonbit
let a = div(42, 0) catch { _ => 0 }
println(a)
```

##### Transforming to Result

You can also catch the potential error and transform into a first-class value of
the [`Result`](fundamentals.md#option-and-result) type, by using
`try?` before an expression that may throw error:

```moonbit
test {
  let res = try? (div(6, 0) * div(6, 3))
  inspect(
    res,
    content=(
      #|Err("division by zero")
    ),
  )
}
```

##### Panic on Errors

You can also panic directly when an unexpected error occurs:

```moonbit
fn remainder(a : Int, b : Int) -> Int raise DivError {
  if b == 0 {
    raise DivError("division by zero")
  }
  let div = try! div(a, b)
  a - b * div
}
```

##### Error Inference

Within a `try` block, several different kinds of errors can be raised. When that
happens, the compiler will use the type `Error` as the common error type.
Accordingly, the handler must use the wildcard `_` to make sure all errors are
caught, and `e => raise e` to reraise the other errors. For example,

```moonbit
fn f1() -> Unit raise E1 {
  ...
}

fn f2() -> Unit raise E2 {
  ...
}

try {
  f1()
  f2()
} catch {
  E1(_) => ...
  E2 => ...
  e => raise e
}
```

<!-- path: language/packages.md -->
### Managing Projects with Packages

When developing projects at large scale, the project usually needs to be divided into smaller modular unit that depends on each other.
More often, it involves using other people's work: most noticeably is the [core](https://github.com/moonbitlang/core), the standard library of MoonBit.

#### Packages and modules

In MoonBit, the most important unit for code organization is a package, which consists of a number of source code files and a single `moon.pkg.json` configuration file.
A package can either be a `main` package, consisting a `main` function, or a package that serves as a library, identified by the [`is-main`](../toolchain/moon/package.md#is-main) field.

A project, corresponding to a module, consists of multiple packages and a single `moon.mod.json` configuration file.

A module is identified by the [`name`](../toolchain/moon/module.md#name) field, which usually consists of two parts, separated by `/`: `user-name/project-name`.
A package is identified by the relative path to the source root defined by the [`source`](../toolchain/moon/module.md#source-directory) field. The full identifier would be `user-name/project-name/path-to-pkg`.

When using things from another package, the dependency between modules should first be declared inside the `moon.mod.json` by the [`deps`](../toolchain/moon/module.md#dependency-management) field.
The dependency between packages should then be declared in side the `moon.pkg.json` by the [`import`](../toolchain/moon/package.md#import) field.

<a id="default-alias"></a>

The **default alias** of a package is the last part of the identifier split by `/`.
One can use `@pkg_alias` to access the imported entities, where `pkg_alias` is either the full identifier or the default alias.
A custom alias may also be defined with the [`import`](../toolchain/moon/package.md#import) field.

```json
{
    "import": [
        "moonbit-community/language/packages/pkgA",
        {
            "path": "moonbit-community/language/packages/pkgC",
            "alias": "c"
        }
    ]
}
```

```moonbit
///|
pub fn add1(x : Int) -> Int {
  @moonbitlang/core/builtin.Add::add(0, @c.incr(@pkgA.incr(x)))
}
```

##### Internal Packages

You can define internal packages that are only available for certain packages.

Code in `a/b/c/internal/x/y/z` are only available to packages `a/b/c` and `a/b/c/**`.

##### Using

You can use `using` syntax to import symbols defined in another package.

```moonbit
///|
pub using @pkgA {incr, trait Trait, type Type}
```

By having `pub` modifier, it is considered as reexportation.

#### Access Control

MoonBit features a comprehensive access control system that governs which parts of your code are accessible from other packages.
This system helps maintain encapsulation, information hiding, and clear API boundaries.
The visibility modifiers apply to functions, variables, types, and traits, allowing fine-grained control over how your code can be used by others.

##### Functions

By default, all function definitions and variable bindings are *invisible* to other packages.
You can use the `pub` modifier before toplevel `let`/`fn` to make them public.

##### Aliases

By default, [function alias](fundamentals.md#function-alias) and
[method alias](methods.md#alias-methods-as-functions) follow the
visibility of the original definition, while
[type alias](fundamentals.md#type-alias), [using]() are *invisible* to other
packages.

You can add the `pub` modifier before the definition or fill in the `visibility`
field within the annotation.

##### Types

There are four different kinds of visibility for types in MoonBit:

- Private type: declared with `priv`, completely invisible to the outside world
- Abstract type: which is the default visibility for types.

  Only the name of an abstract type is visible outside, the internal representation of the
  type is hidden. Making abstract type by default is a design choice to encourage
  encapsulation and information hiding.
- Readonly types, declared with `pub`.

  The internal representation of readonly types are visible outside,
  but users can only read the values of these types from outside, construction and mutation are not allowed.
- Fully public types, declared with `pub(all)`.

  The outside world can freely construct, read values of these types and modify them if possible.

In addition to the visibility of the type itself, the fields of a public `struct` can be annotated with `priv`,
which will hide the field from the outside world completely.
Note that `struct`s with private fields cannot be constructed directly outside,
but you can update the public fields using the functional struct update syntax.

Readonly types is a very useful feature, inspired by [private types](https://ocaml.org/manual/5.3/privatetypes.html) in OCaml.
In short, values of `pub` types can be destructed by pattern matching and the dot syntax, but
cannot be constructed or mutated in other packages.

###### NOTE
There is no restriction within the same package where `pub` types are defined.

<!-- MANUAL CHECK -->
```moonbit
// Package A
pub struct RO {
  field: Int
}
test {
  let r = { field: 4 }       // OK
  let r = { ..r, field: 8 }  // OK
}

// Package B
fn println(r : RO) -> Unit {
  println("{ field: ")
  println(r.field)  // OK
  println(" }")
}
test {
  let r : RO = { field: 4 }  // ERROR: Cannot create values of the public read-only type RO!
  let r = { ..r, field: 8 }  // ERROR: Cannot mutate a public read-only field!
}
```

Access control in MoonBit adheres to the principle that a `pub` type, function, or variable cannot be defined in terms of a private type. This is because the private type may not be accessible everywhere that the `pub` entity is used. MoonBit incorporates sanity checks to prevent the occurrence of use cases that violate this principle.

<!-- MANUAL CHECK -->
```moonbit
pub(all) type T1
pub(all) type T2
priv type T3

pub(all) struct S {
  x: T1  // OK
  y: T2  // OK
  z: T3  // ERROR: public field has private type `T3`!
}

// ERROR: public function has private parameter type `T3`!
pub fn f1(_x: T3) -> T1 { ... }
// ERROR: public function has private return type `T3`!
pub fn f2(_x: T1) -> T3 { ... }
// OK
pub fn f3(_x: T1) -> T1 { ... }

pub let a: T3 = { ... } // ERROR: public variable has private type `T3`!
```

##### Traits

There are four visibility for traits, just like `struct` and `enum`: private, abstract, readonly and fully public.

- Private traits are declared with `priv trait`, and they are completely invisible from outside.
- Abstract trait is the default visibility. Only the name of the trait is visible from outside, and the methods in the trait are not exposed.
- Readonly traits are declared with `pub trait`, their methods can be invoked from outside, but only the current package can add new implementation for readonly traits.
- Fully public traits are declared with `pub(open) trait`, they are open to new implementations outside current package, and their methods can be freely used.

Abstract and readonly traits are sealed, because only the package defining the trait can implement them.
Implementing a sealed (abstract or readonly) trait outside its package result in compiler error.

###### Trait Implementations

Implementations have independent visibility, just like functions. The type will not be considered having fulfillled the trait outside current package unless the implementation is `pub`.

To make the trait system coherent (i.e. there is a globally unique implementation for every `Type: Trait` pair),
and prevent third-party packages from modifying behavior of existing programs by accident,
MoonBit employs the following restrictions on who can define methods/implement traits for types:

- *only the package that defines a type can define methods for it*. So one cannot define new methods or override old methods for builtin and foreign types.
  - there is an exception to this rule: [local methods](methods.md#local-method). Local methods are always private though, so they do not break coherence properties of MoonBit's type system
- *only the package of the type or the package of the trait can define an implementation*.
  For example, only `@pkg1` and `@pkg2` are allowed to write `impl @pkg1.Trait for @pkg2.Type`.

The second rule above allows one to add new functionality to a foreign type by defining a new trait and implementing it.
This makes MoonBit's trait & method system flexible while enjoying good coherence property.

###### WARNING
Currently, an empty trait is implemented automatically.

Here's an example of abstract trait:

<!-- MANUAL CHECK -->
```moonbit
trait Number {
 op_add(Self, Self) -> Self
 op_sub(Self, Self) -> Self
}

fn[N : Number] add(x : N, y: N) -> N {
  Number::op_add(x, y)
}

fn[N : Number] sub(x : N, y: N) -> N {
  Number::op_sub(x, y)
}

impl Number for Int with op_add(x, y) { x + y }
impl Number for Int with op_sub(x, y) { x - y }

impl Number for Double with op_add(x, y) { x + y }
impl Number for Double with op_sub(x, y) { x - y }
```

From outside this package, users can only see the following:

```moonbit
trait Number

fn[N : Number] op_add(x : N, y : N) -> N
fn[N : Number] op_sub(x : N, y : N) -> N

impl Number for Int
impl Number for Double
```

The author of `Number` can make use of the fact that only `Int` and `Double` can ever implement `Number`,
because new implementations are not allowed outside.

#### Virtual Packages

###### WARNING
Virtual package is an experimental feature. There may be bugs and undefined behaviors.

You can define virtual packages, which serves as an interface. They can be replaced by specific implementations at build time. Currently virtual packages can only contain plain functions.

Virtual packages can be useful when swapping different implementations while keeping the code untouched.

##### Defining a virtual package

You need to declare it to be a virtual package and define its interface in a MoonBit interface file.

Within `moon.pkg.json`, you will need to add field [`virtual`](../toolchain/moon/package.md#declarations) :

```json
{
  "virtual": {
    "has-default": true
  }
}
```

The `has-default` indicates whether the virtual package has a default implementation.

Within the package, you will need to add an interface file `pkg.mbti`:

```moonbit
package "moonbit-community/language/packages/virtual"

fn log(String) -> Unit
```

The first line of the interface file need to be `package "full-package-name"`. Then comes the declarations.
The `pub` keyword for [access control]() and the function parameter names should be omitted.

##### Implementing a virtual package

A virtual package can have a default implementation. By defining [`virtual.has-default`](../toolchain/moon/package.md#declarations) as `true`, you can implement the code as usual within the same package.

```moonbit
///|
pub fn log(s : String) -> Unit {
  println(s)
}
```

A virtual package can also be implemented by a third party. By defining [`implements`](../toolchain/moon/package.md#implementations) as the target package's full name, the compiler can warn you about the missing implementations or the mismatched implementations.

```json
{
  "implement": "moonbit-community/language/packages/virtual"
}
```

```moonbit
///|
pub fn log(string : String) -> Unit {
  ignore(string)
}
```

##### Using a virtual package

To use a virtual package, it's the same as other packages: define [`import`](../toolchain/moon/package.md#import) field in the package where you want to use it.

##### Overriding a virtual package

If a virtual package has a default implementation and that is your choice, there's no extra configurations.

Otherwise, you may define the [`overrides`](../toolchain/moon/package.md#overriding-implementations) field by providing an array of implementations that you would like to use.

```json
{
  "overrides": ["moonbit-community/language/packages/implement"],
  "import": [
    "moonbit-community/language/packages/virtual"
  ],
  "is-main": true
}
```

You should reference the virtual package when using the entities.

```moonbit
///|
fn main {
  @virtual.log("Hello")
}
```

<!-- path: language/tests.md -->
### Writing Tests

Tests are important for improving quality and maintainability of a program. They verify the behavior of a program and also serves as a specification to avoid regressions over time.

MoonBit comes with test support to make the writing easier and simpler.

#### Test Blocks

MoonBit provides the test code block for writing inline test cases. For example:

```moonbit
test "test_name" {
  assert_eq(1 + 1, 2)
  assert_eq(2 + 2, 4)
  inspect([1, 2, 3], content="[1, 2, 3]")
}
```

A test code block is essentially a function that returns a `Unit` but may throws an [`Error`](error-handling.md#error-types), or `Unit!Error` as one would see in its signature at the position of return type. It is called during the execution of `moon test` and outputs a test report through the build system. The `assert_eq` function is from the standard library; if the assertion fails, it prints an error message and terminates the test. The string `"test_name"` is used to identify the test case and is optional.

If a test name starts with `"panic"`, it indicates that the expected behavior of the test is to trigger a panic, and the test will only pass if the panic is triggered. For example:

```moonbit
test "panic_test" {
  let _ : Int = Option::None.unwrap()

}
```

#### Snapshot Tests

Writing tests can be tedious when specifying the expected values. Thus, MoonBit provides three kinds of snapshot tests.
All of which can be inserted or updated automatically using `moon test --update`.

##### Snapshotting `Show`

We can use `inspect(x, content="x")` to inspect anything that implements `Show` trait.
As we mentioned before, `Show` is a builtin trait that can be derived, providing `to_string` that will print the content of the data structures.
The labelled argument `content` can be omitted as `moon test --update` will insert it for you:

```moonbit
struct X {
  x : Int
} derive(Show)

test "show snapshot test" {
  inspect({ x: 10 }, content="{x: 10}")
}
```

##### Snapshotting `JSON`

The problem with the derived `Show` trait is that it does not perform pretty printing, resulting in extremely long output.

The solution is to use `@json.inspect(x, content=x)`. The benefit is that the resulting content is a JSON structure, which can be more readable after being formatted.

```moonbit
enum Rec {
  End
  Really_long_name_that_is_difficult_to_read(Rec)
} derive(Show, ToJson)

test "json snapshot test" {
  let r = Really_long_name_that_is_difficult_to_read(
    Really_long_name_that_is_difficult_to_read(
      Really_long_name_that_is_difficult_to_read(End),
    ),
  )
  inspect(
    r,
    content="Really_long_name_that_is_difficult_to_read(Really_long_name_that_is_difficult_to_read(Really_long_name_that_is_difficult_to_read(End)))",
  )
  @json.inspect(r, content=[
    "Really_long_name_that_is_difficult_to_read",
    [
      "Really_long_name_that_is_difficult_to_read",
      ["Really_long_name_that_is_difficult_to_read", "End"],
    ],
  ])
}
```

One can also implement a custom `ToJson` to keep only the essential information.

##### Snapshotting Anything

Still, sometimes we want to not only record one data structure but the output of a whole process.

A full snapshot test can be used to record anything using `@test.T::write` and `@test.T::writeln`:

```moonbit
test "record anything" (t : @test.Test) {
  t.write("Hello, world!")
  t.writeln(" And hello, MoonBit!")
  t.snapshot(filename="record_anything.txt")
}
```

This will create a file under `__snapshot__` of that package with the given filename:

```default
Hello, world! And hello, MoonBit!
```

This can also be used for applications to test the generated output, whether it were creating an image, a video or some custom data.

Please note that `@test.T::snapshot` should be used at the end of a test block, as it always raises exception.

#### BlackBox Tests and WhiteBox Tests

When developing libraries, it is important to verify if the user can use it correctly. For example, one may forget to make a type or a function public. That's why MoonBit provides BlackBox tests, allowing developers to have a grasp of how others are feeling.

- A test that has access to all the members in a package is called a WhiteBox tests as we can see everything. Such tests can be defined inline or defined in a file whose name ends with `_wbtest.mbt`.
- A test that has access only to the public members in a package is called a BlackBox tests. Such tests need to be defined in a file whose name ends with `_test.mbt`.

The WhiteBox test files (`_wbtest.mbt`) imports the packages defined in the `import` and `wbtest-import` sections of the package configuration (`moon.pkg.json`).

The BlackBox test files (`_test.mbt`) imports the current package and the packages defined in the `import` and `test-import` sections of the package configuration (`moon.pkg.json`).

<!-- path: language/benchmarks.md -->
### Writing Benchmarks

Benchmarks are a way to measure the performance of your code. They can be used to compare different implementations or to track performance changes over time.

#### Benchmarking with Test Blocks

The most simple way to benchmark a function is to use a test block with a
`@bench.T` argument. It has a method `@bench.T::bench` that takes a function of type
`() -> Unit` and run it with a suitable number of iterations.
The measurements and statistical analysis will be conducted and passed to `moon`,
where they will be displayed in the console output.

```moonbit
fn fib(n : Int) -> Int {
  if n < 2 {
    return n
  }
  return fib(n - 1) + fib(n - 2)
}

test (b : @bench.T) {
  b.bench(fn() { b.keep(fib(20)) })
}
```

The output is as follows:

```default
time (mean ± σ)         range (min … max) 
  21.67 µs ±   0.54 µs    21.28 µs …  23.14 µs  in 10 ×   4619 runs
```

The function is executed `10 × 4619` times.
The second number is automatically detected by benchmark utilities, which increase the number of iterations until the measurement time is long enough for accurate timing.
The first number can be adjusted by passing a named parameter `count` to the `@bench.T::bench` argument.

```moonbit
test (b : @bench.T) {
  b.bench(fn() { b.keep(fib(20)) }, count=20)
}
```

`@bench.T::keep` is an important auxiliary function that prevents your calculation from being optimized away and skipped entirely.
If you are benchmarking a pure function, make sure to use this function to avoid potential optimizations.
However, there is still a possibility that the compiler might pre-calculate and replace the calculation with a constant.

#### Batch Benchmarking

A common scenario of benchmarking is to compare two or more implementations of the same function.
In this case, you may want to bench them in a batch within a block for easy comparison.
The `name` parameter of the `@bench.T::bench` method can be used to identify the benchmark.

```moonbit
fn fast_fib(n : Int) -> Int {
  if n < 2 {
    return n
  } else {
    let mut a = 0
    let mut b = 1
    for i = 2; i <= n; i = i + 1 {
      let t = a + b
      a = b
      b = t
    }
    b
  }
}

test (b : @bench.T) {
  b.bench(name="naive_fib", fn() { b.keep(fib(20)) })
  b.bench(name="fast_fib", fn() { b.keep(fast_fib(20)) })
}
```

Now you can evaluate which one is faster by looking at the output:

```default
name      time (mean ± σ)         range (min … max) 
naive_fib   21.01 µs ±   0.21 µs    20.76 µs …  21.32 µs  in 10 ×   4632 runs
fast_fib     0.02 µs ±   0.00 µs     0.02 µs …   0.02 µs  in 10 × 100000 runs
```

#### Raw Benchmark Statistics

Sometimes users may want to obtain raw benchmark statistics for further analysis.
There is a function `@bench.single_bench` that returns an abstract `Summary` type, which can be serialized into JSON format. The stability of the `Summary` type is not guaranteed to be stable.

In this case, users must ensure that the calculation is not optimized away.
There is no `keep` function available as a standalone function; it is a method of `@bench.T`.

```moonbit
fn collect_bench() -> Unit {
  let mut saved = 0
  let summary : @bench.Summary = @bench.single_bench(name="fib", fn() {
    saved = fib(20)
  })
  println(saved)
  println(summary.to_json().stringify(escape_slash=true, indent=4))
}
```

The output may look like this:

```json
6765
{
    "name": "fib",
    "sum": 217.22039973878972,
    "min": 21.62009230518067,
    "max": 21.87286402916848,
    "mean": 21.72203997387897,
    "median": 21.70412048323901,
    "var": 0.007197724461032505,
    "std_dev": 0.08483940394081341,
    "std_dev_pct": 0.39056830777787843,
    "median_abs_dev": 0.08189815918589166,
    "median_abs_dev_pct": 0.3773392211360855,
    "quartiles": [
        21.669052078798433,
        21.70412048323901,
        21.76141434479756
    ],
    "iqr": 0.09236226599912811,
    "batch_size": 4594,
    "runs": 10
}
```

Time units are in microseconds.

<!-- path: language/docs.md -->
### Documentation

#### Doc Comments

Doc comments are comments prefix with `///` in each line in the leading of toplevel structure like `fn`, `let`, `enum`, `struct` or `type`. The doc comments are written in markdown.

```moonbit
/// Return a new array with reversed elements.
fn[T] reverse(xs : Array[T]) -> Array[T] {
  ...
}
```

Markdown code blocks inside docstrings marked with `mbt check` are treated as
document tests. `moon check` and `moon test` will automatically check and run
these tests, so that examples in docstring are always up-to-date.
Wrap the snippet in `test { .. }` when you want a test block:

```moonbit
/// Increment an integer by one,
///
/// Example:
/// ```mbt check
/// test {
///   inspect(incr(41), content="42")
/// }
/// ```
pub fn incr(x : Int) -> Int {
  x + 1
}
```

Doc tests also apply to literate `.mbt.md` files. For a standalone file, run
`moon check README.mbt.md` and `moon test README.mbt.md`. Inside a project, use
the package-level `moon check` and `moon test` instead.

If you want to prevent a code snippet from being treated as a document test,
mark it with a language id other than `mbt check` on the markdown code block:

```moonbit
/// `c_incr(x)` is the same as the following C code:
/// ```c
/// x++
/// ```
pub fn c_incr(x : Ref[Int]) -> Int {
  let old = x.val
  x.val += 1
  old
}
```

Currently, document tests are always [blackbox tests](tests.md#blackbox-tests-and-whitebox-tests).
So private definitions cannot have document test.

<!-- path: language/attributes.md -->
### Attribute

Attributes are annotations placed before structures in source code. They take the form `#attribute(...)`.
An attribute occupies the entire line, and newlines are not allowed within it.
Attributes do not normally affect the meaning of programs. Unused attributes will be reported as warnings.

The syntax of attributes is defined as follows:

```plaintext
attribute ::= '#' attribute-name
            | '#' attribute-name '(' attribute-arguments ')' 

attribute-name ::= LIDENT | LIDENT '.' LIDENT

attribute-arguments ::= attribute-argument (',' attribute-argument )*

attribute-argument ::= expr | LIDENT '=' expr 

expr ::= LIDENT | UIDENT | STRING | 'true' | 'false'
       | LIDENT '.' LIDENT
       | LIDENT '(' attribute-arguments ')'
       | LIDENT '.' LIDENT '(' attribute-arguments ')'
```

Attributes have two categories: the built-in attributes and user-defined attributes. For example:

```default
###deprecated("message")
###custom.attribute(key="value", flag=true)
```

The first attribute is a built-in attribute; it does not have a namespace prefix in the attribute name. Built-in attributes are recognized by the MoonBit compiler and have specific meanings.

The second attribute is a user-defined attribute; it has a namespace prefix `custom.` in the attribute name. User-defined attributes are ignored by the compiler, but can be used by external tools via parsing the source code.

###### NOTE
MoonBit is designed not to support runtime reflection. It's easy to abuse, making it impossible for toolchains (e.g., the compiler) to catch errors at compile time, which makes code harder to maintain. It also negatively impacts performance optimization.

We perfer to use compile-time code generation, keeping the benefits of static typing and performance (should also be used judiciously to avoid unnecessary complexity).

#### Deprecated Attribute

The `#deprecated` attribute is used to mark an API as deprecated. MoonBit emits
a warning when the deprecated API is used, and if the API is listed in completion,
it will be shown with a strikethrough style. For example:

```moonbit
###deprecated
pub fn foo() -> Unit {
  ...
}

###deprecated("Use Bar2 instead")
pub(all) enum Bar {
  Ctor1
  Ctor2
}
```

The `#deprecated` attribute can be used in the following contexts:

- Top-level value declarations (including `fn`, `let`, and `const`)
- Top-level type declarations (including `type`, `struct`, and `enum`)
- Trait method declarations
- Trait default implementations

It has three forms:

- `#deprecated`

  Marks the item as deprecated with a default warning message.
- `#deprecated("Use new_function instead")`

  Marks the item as deprecated with a custom warning message. Every time the deprecated API is used, the provided message will be displayed as a warning.
- `#deprecated("Use new_function instead", skip_current_package=true)`

  Marks the item as deprecated with a custom warning message, but skips emitting warnings when the deprecated API is used within the same package.

#### Alias Attribute

The `alias` attribute is used to overload operators related to indexing, or to create an alias name for a top-level function or variable. It has two forms:

- `#alias("op")`: where `op` is one of the following strings representing the indexing operators:
  - `_[_]`: for the indexing operator
  - `_[_]=_`: for the indexing assignment operator
  - `_[_:_]`: for the as view operator
- `#alias(id)`: where `id` is a identifier representing the alias name.

Both forms allowed additional arguments:

- `visibility="modifier"`

  A labeled argument, changes the visibility of the alias. The `modifier` can be `pub` or `priv`. If not specified, the alias will have the same visibility as the original function or variable.
- `deprecated` or `deprecated="message"`

  Marks the alias as deprecated. If a message is provided, it will be displayed as a warning when the alias is used.

To graceful migration from old API to new API, you can rename the old API directly, and create an alias with the old name, mark it as deprecated. For
example:

```moonbit
###alias("old_name", deprecated)
fn new_name() -> Unit {
  ...
}
```

#### `label_migration` Attribute

The `#label_migration` attribute is used to help you safely evolve your API
by warning users during the transition period.

It has three following forms:

- `#label_migration(id, fill=true, msg="message")`

  The `fill` argument is used when you want to refactor an optional parameter.
  You can use `fill=true` when you want to eventually make an optional
  parameter required. You can use `fill=false` when you want to eventually
  remove an optional parameter.

  The `msg` argument is an string that provides additional information about the migration.
  ```moonbit
  #label_migration(x, fill=true)
  #label_migration(y, fill=false)
  fn f(x?: Int = 0, y?: Int = 1) -> Unit { ... }
  fn main {
    f(x=1, y=1) // warn on y being filled
    f()         // warn on x not being filled
  }
  ```
- `#label_migration(id, allow_positional=true, msg="message")`

  The `allow_positional` argument is used when you want a labelled parameter to be
  used without its label being provided. When the parameter is used positionally
  (without a label), the compiler reports a warning. This is useful when you want to change a positional parameter
  to a labelled parameter without breaking the downstream code.

  The `msg` argument is an string that provides additional information about the migration.
  ```moonbit
  #label_migration(x, allow_positional=true)
  fn f(x~: Int) -> Unit { ... }

  fn main {
    f(42) // warn on positional argument 42 used without label
  }
  ```
- `#label_migration(id, alias=new_id, msg="message")`

  The alias argument allows you to provide an alternative name to a labelled
  parameter. This is useful when renaming a parameter to maintain backward
  compatibility. If a warning message is provided, the compiler warns when
  using the alias; otherwise, the alias can be used without warnings.

  The `msg` argument is an string that provides additional information about the migration.
  ```moonbit
  #label_migration(x, alias=xx)
  #label_migration(x, alias=y, msg="warning")
  fn f(x~: Int) -> Unit { ... }

  fn main {
    f(xx=42) // no warning
    f(y=42)  // warning
  }
  ```

#### Visibility Attribute

###### NOTE
This topic does not covered the access control. To learn more about `pub`, `pub(all)` and `priv`, see [Access Control](packages.md#access-control).

The `#visibility` attribute is similar to the `#deprecated` attribute, but it is used to hint that a type will change its visibility in the future.
For outside usages, if the usage will be invalidated by the visibility change in future, a warning will be emitted.

```moonbit
// in @util package
###visibility(change_to="readonly", "Point will be readonly in the future.")
pub(all) struct Point {
  x : Int
  y : Int
}

###visibility(change_to="abstract", "Use new_text and new_binary instead.")
pub(all) enum Resource {
  Text(String)
  Binary(Bytes)
}

pub fn new_text(str : String) -> Resource {
  ...
}

pub fn new_binary(bytes : Bytes) -> Resource {
  ...
}

// in another package
fn main {
  let p = Point::{ x: 1, y: 2 } // warning 
  let { x, y } = p // ok
  println(p.x) // ok
  match Resource::Text("") { // warning
    Text(s) => ... // waning
    Binary(b) => ... // warning
  }
}

```

The `#visibility` attribute takes two arguments: `change_to` and `message`.

- The `change_to` argument is a string that indicates the new visibility of the type. It can be either `"abstract"` or `"readonly"`.

  | `change_to`   | Invalidated Usages                                                                                                     |
  |---------------|------------------------------------------------------------------------------------------------------------------------|
  | `"readonly"`  | Creating an instance of the type or mutating the fields of the instance.                                               |
  | `"abstract"`  | Creating an instance of the type, mutating the fields of the instance, pattern matching, or accessing fields by label. |
- The `message` argument is a string that provides additional information about the visibility change.

#### Internal Attribute

The `#internal` attribute is used to mark a function, type, or trait as internal.
Any usage of the internal function or type in other modules will emit an alert warning.

```moonbit
###internal(unsafe, "This is an unsafe function")
fn unsafe_get[A](arr : Array[A]) -> A {
  ...
}
```

The internal attribute takes two arguments: `category` and `message`.
`category` is a identifier that indicates the category of the alert, and `message` is a string that provides additional message for the alert.

The alert warnings can be turn off by setting the `warn-list` in `moon.pkg.json`.
For more detail, see [alert warning](../toolchain/moon/package.md#alert-warning).

#### Warnings Attribute

The `#warnings` attribute is used to configure warning settings for a specific
top-level declaration. It can enable, disable or treat an enabled warning as error
for specific warnings in that declaration.

The argument is a string that specifies the warning list. It can contain multiple
warning names, each prefixed with a sign:

```moonbit
###warning("-unused_value@deprecated")
fn f() -> Unit {
  let x = 42 
}
```

The prefixes have the following meanings:

- `+warning_name`: enable the warning
- `-warning_name`: disable the warning
- `@warning_name`: treat a enabled warning as an error

Currently this attribute only works with some specific warnings.

To learn more about warning names, see [warning list](../toolchain/moon/package.md#warning-list).

#### External Attribute

The `#external` attribute is used to mark an abstract type as external type.

- For Wasm(GC) backends, it would be interpreted as `anyref`.
- For JavaScript backend, it would be interpreted as `any`.
- For native backends, it would be interpreted as `void*`.

```moonbit
###external
type Ptr
```

#### Borrow and Owned Attribute

The `#borrow` and `#owned` attribute is used to indicate that a FFI takes ownership of its arguments. For more detail, see [FFI](ffi.md#the-borrow-and-owned-attribute).

#### `as_free_fn` Attribute

The `#as_free_fn` attribute is used to mark a method that it is declared as a free function as well.
It can also change the visibility of the free function, the name of the free function, and provide separate deprecation warning.

```moonbit
###as_free_fn(dec, visibility="pub", deprecated="use `Int::decrement` instead")
###as_free_fn(visibility="pub")
fn Int::decrement(i : Self) -> Self {
  i - 1
}

test {
  let _ = decrement(10)
  let _ = (10).decrement()
}
```

#### Callsite Attribute

The `#callsite` attribute is used to mark properties that happen at callsite.

It could be `autofill`, which is to autofill the arguments [SourceLoc and ArgLoc](fundamentals.md#autofill-arguments)
at callsite.

#### Skip Attribute

The `#skip` attribute is used to skip a single test block. The type checking will still be performed.

#### Configuration attribute

The `#cfg` attribute is used to perform conditional compilation. Examples are:

<!-- MANUAL CHECK -->
```moonbit
###cfg(true)
###cfg(false)
###cfg(target="wasm")
###cfg(not(target="wasm"))
###cfg(all(target="wasm", true))
###cfg(any(target="wasm", target="native"))
```

#### Module attribute

The `module` attribute is used to declare the module dependency for JavaScript backend.

In `cjs` format, it is interpreted as `require`, and in `esm` format, it is interpreted as `import`.

<!-- MANUAL CHECK -->
```moonbit
###module("node:fs")
pub fn write_file_sync(file : String, data : String) = "writeFileSync"
```

<!-- path: language/ffi.md -->
### Foreign Function Interface (FFI)

What we've introduced is about describing pure computation. In reality, you'll need
to interact with the real world. However, the "world" is different for each backend (C, JS, Wasm, WasmGC)
and is sometimes based on runtime ([Wasmtime](https://wasmtime.dev/), Deno, Browser, etc.).

#### Backends

MoonBit currently have five backends:

- Wasm
- Wasm GC
- JavaScript
- C
- LLVM (experimental)

##### Wasm

By Wasm we refer to WebAssembly with some post-MVP proposals including:

- bulk-memory-operations
- multi-value
- reference-types

For better compatibility, the `init` function will be compiled as [`start` function](https://webassembly.github.io/spec/core/syntax/modules.html#start-function), and the `main` function will be exported as `_start`.

###### NOTE
For Wasm backends, all functions interacting with outside world relies on the host. For example, the `println` for Wasm and Wasm GC backend relies on importing a function `spectest.print_char` that prints a UTF-16 code unit for each call. The `env` package in standard library and some packages in `moonbitlang/x` relies on specific host function defined for MoonBit runtime. Avoid using them if you want to make the generated Wasm portable.

##### Wasm GC

By Wasm GC we refer to WebAssembly with Garbage Collection proposal, meaning that data structures will be represented with reference types such as `struct` `array` and the linear memory would not be used by default. It also supports other post-MVP proposals including:

- multi-value
- JS string builtins

For better compatibility, the `init` function will be compiled as [`start` function](https://webassembly.github.io/spec/core/syntax/modules.html#start-function), and the `main` function will be exported as `_start`.

###### NOTE
For Wasm backends, all functions interacting with outside world relies on the host. For example, the `println` for Wasm and Wasm GC backend relies on importing a function `spectest.print_char` that prints a UTF-16 code unit for each call. The `env` package in standard library and some packages in `moonbitlang/x` relies on specific host function defined for MoonBit runtime. Avoid using them if you want to make the generated Wasm portable.

##### JavaScript

JavaScript backend will generate a JavaScript file, which can be a CommonJS module, an ES module or an IIFE based on the [configuration](../toolchain/moon/package.md#js-backend-link-options).

##### C

C backend will generate a C file. The MoonBit toolchain will also compile the project and generate an executable based on the [configuration](../toolchain/moon/package.md#native-backend-link-options).

##### LLVM

LLVM backend will generate an object file. The backend is experimental and does not support FFIs.

#### Declare Foreign Type

You can declare a foreign type using the `#external` attribute like this:

```moonbit
###external
type ExternalRef
```

##### Wasm & Wasm GC

This will be interpreted as an [`externref`](https://webassembly.github.io/spec/core/syntax/types.html#reference-types).

##### JavaScript

This will be interpreted as a JavaScript value.

##### C

This will be interpreted as `void*`.

#### Declare Foreign Function

To interact with the outside world, you can declare foreign functions.

###### NOTE
MoonBit does not support polymorphic foreign functions.

##### Wasm & Wasm GC

There are two ways to declare a foreign function: importing a function or writing an inline function.

You can import a function given the module name and the function name from the runtime host:

```moonbit
fn cos(d : Double) -> Double = "math" "cos"
```

Or you can write an inline function using Wasm syntax:

```moonbit
extern "wasm" fn identity(d : Double) -> Double =
  #|(func (param f64) (result f64))
```

###### NOTE
When writing the inline function, do not provide a function name.

##### JavaScript

There are two ways to declare a foreign function: importing a function or writing an inline function.

You can import a function given the module name and the function name, which will be interpreted as `module.function`. For example,

```moonbit
fn cos(d : Double) -> Double = "Math" "cos"
```

would refer to the function `const cos = (d) => Math.cos(d)`

Or you can write an inline function defining a JavaScript lambda:

```moonbit
extern "js" fn cos(d : Double) -> Double =
  #|(d) => Math.cos(d)
```

##### C

You can declare a foreign function by importing a function given the function name:

```moonbit
extern "C" fn put_char(ch : UInt) = "function_name"
```

If a package needs to dynamically link with foreign C library, add `cc-link-flags` to `moon.pkg.json`. It would be passed to C compiler directly.

```json
{
  // ...
  "link": {
    "native": {
      "cc-link-flags": "-l<c library>"
    }
  },
  // ...
}
```

To define wrapper functions, you can add a C stub file to a package, and add the following to the `moon.pkg.json` of the package:

```json
{
  // ...
  "native-stub": [ 
    // list of stub file names
  ],
  // ...
}
```

You would probably like to `#include "moonbit.h"`, which contains type definitions and handy utilities for MoonBit's C interface. The header is located in `~/.moon/include`, check its content for more details.

##### Types

When declaring functions, you need to make sure that the signature corresponds to the actual foreign function.
When a function returns nothing (e.g. `void`), ignore the return type annotation in the function declaration.
The table below shows the underlying representation of some MoonBit types:

##### Wasm

| MoonBit type                       | ABI         |
|------------------------------------|-------------|
| `Bool`                             | `i32`       |
| `Int`                              | `i32`       |
| `UInt`                             | `i32`       |
| `Int64`                            | `i64`       |
| `UInt64`                           | `i64`       |
| `Float`                            | `f32`       |
| `Double`                           | `f64`       |
| constant `enum`                    | `i32`       |
| external type (`#external type T`) | `externref` |
| `FuncRef[T]`                       | `funcref`   |

##### Wasm GC

| MoonBit type                       | ABI                                     |
|------------------------------------|-----------------------------------------|
| `Bool`                             | `i32`                                   |
| `Int`                              | `i32`                                   |
| `UInt`                             | `i32`                                   |
| `Int64`                            | `i64`                                   |
| `UInt64`                           | `i64`                                   |
| `Float`                            | `f32`                                   |
| `Double`                           | `f64`                                   |
| constant `enum`                    | `i32`                                   |
| external type (`#external type T`) | `externref`                             |
| `String`                           | `externref` iff JS string builtin is on |
| `FuncRef[T]`                       | `funcref`                               |

##### JavaScript

| MoonBit type                       | ABI          |
|------------------------------------|--------------|
| `Bool`                             | `boolean`    |
| `Int`                              | `number`     |
| `UInt`                             | `number`     |
| `Float`                            | `number`     |
| `Double`                           | `number`     |
| constant `enum`                    | `number`     |
| external type (`#external type T`) | `any`        |
| `String`                           | `string`     |
| `FixedArray[Byte]`/`Bytes`         | `Uint8Array` |
| `FixedArray[T]` / `Array[T]`       | `T[]`        |
| `FuncRef[T]`                       | `Function`   |

###### NOTE
The `FixedArray[T]` for numbers may migrate to `TypedArray` in the future.

##### C

| MoonBit type                       | ABI                                    |
|------------------------------------|----------------------------------------|
| `Bool`                             | `int32_t`                              |
| `Int`                              | `int32_t`                              |
| `UInt`                             | `uint32_t`                             |
| `Int64`                            | `int64_t`                              |
| `UInt64`                           | `uint64_t`                             |
| `Float`                            | `float`                                |
| `Double`                           | `double`                               |
| constant `enum`                    | `int32_t`                              |
| abstract type (`type T`)           | pointer (must be valid MoonBit object) |
| external type (`#external type T`) | `void*`                                |
| `FixedArray[Byte]`/`Bytes`         | `uint8_t*`                             |
| `FixedArray[T]`                    | `T*`                                   |
| `FuncRef[T]`                       | Function pointer                       |

###### NOTE
If the return type of `T` in `FuncRef[T]` is `Unit`, then it points to a function that returns `void`.

Types not mentioned above do not have a stable ABI, so your code should not depend on their representations.

##### Callbacks

Sometimes, we want to pass a MoonBit function to the foreign interface as callback. In MoonBit, it is possible to have closures. Per [MDN glossary](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures):

> A closure is the combination of a function bundled together (enclosed) with references to its surrounding state (the lexical environment). In other words, a closure gives a function access to its outer scope. In JavaScript, closures are created every time a function is created, at function creation time.

In some cases, we would like to pass the callback function which doesn't capture any local free variables. For this purpose, MoonBit provides a special type `FuncRef[T]`, which represents closed function of type `T`. Values of type `FuncRef[T]` must be closed function of type `T`, otherwise [a type error](error_codes/E4151.md) would occur.

In other cases, a MoonBit function parameter would be represented as a function and an object containing the surrounding state.

##### Wasm & Wasm GC

For Wasm backends, the callbacks will be passed as `externref`, which represents a function of the host. However, it is essential to convert the function together with the captured data to the host's function.

To do so, the Wasm module will import a function under the module `moonbit:ffi` and function name `make_closure`. This function takes a function and an object, where the function's first parameter should be the object, and should return a host's function. That is, the host is responsible for doing the partial application. A possible implementation would be:

```javascript
{ 
  "moonbit:ffi": {
    "make_closure": (funcref, closure) => funcref.bind(null, closure)
  } 
}
```

##### JavaScript

JavaScript supports closure, so there's nothing special to be done here.

##### C

Some C library functions allow supplying extra data in addition to the callback function.
Assume we have the following C library function:

```c
void register_callback(void (*callback)(void*), void *data);
```

we can bind this C function and pass closure to it using the following trick:

```moonbit
extern "C" fn register_callback_ffi(
  call_closure : FuncRef[(() -> Unit) -> Unit],
  closure : () -> Unit
) = "register_callback"

fn register_callback(callback : () -> Unit) -> Unit {
  register_callback_ffi(
    fn (f) { f() },
    callback
  )
}
```

##### Customize integer value of constant enum

In all backends of MoonBit, constant enum (`enum` where all constructors have no payload) are translated to integer.
It is possible to customize the actual integer representation of each constructor,
by adding `= <integer literal>` after constructor declaration:

```moonbit
enum SpecialNumbers {
  Zero = 0
  One
  Two
  Three
  Ten = 10
  FourtyTwo = 42
}
```

If a constructor's integer value is unspecified,
it defaults to one plus the value of the previous constructor (or zero for the first constructor).
This feature is particular useful for binding flags of C libraries.

#### Export Functions

For public functions that are neither methods nor polymorphic, they can be exported by configuring the `exports` field in [link configuration](../toolchain/moon/package.md#link-options).

```json
{
  "link": {
    "<backend>": {
      "exports": [ "add", "fib:test" ]
    }
  }
}
```

The previous example exports functions `add` and `fib`, where `fib` will be exported as `test`.

##### Wasm & Wasm GC

###### NOTE
It is only effective for the package that configures it, i.e. it doesn't affect the downstream packages.

##### JavaScript

###### NOTE
It is only effective for the package that configures it, i.e. it doesn't affect the downstream packages.

There's another `format` option to export as CommonJS module (`cjs`), ES Module (`esm`), or `iife`.

##### C

###### NOTE
It is only effective for the package that configures it, i.e. it doesn't affect the downstream packages.

Renaming the exported function is not supported for now

#### Lifetime management

MoonBit is a programming language with garbage collection. Thus when handling external object or passing MoonBit object to host, it is essential to keep in mind the lifetime management. Currently, MoonBit uses reference counting for Wasm backend and C backend. For Wasm GC backend and JavaScript backend, the runtime's GC is reused.

##### Lifetime management of external object

When handling external object/resource in MoonBit, it is important to destroy object or release resource in time to prevent memory/resource leak.

###### NOTE
For C backend only

`moonbit.h` provides an API `moonbit_make_external_object` for handling lifetime of external object/resource using MoonBit's own automatic memory management system:

```c
void *moonbit_make_external_object(
  void (*finalize)(void *self),
  uint32_t payload_size
);
```

`moonbit_make_external_object` will create a new MoonBit object of size `payload_size + sizeof(finalize)`,
the layout of the object is as follows:

```default
| MoonBit object header | ... payload | finalize function |
                        ^
                        |
                        |_
                           pointer returned by `moonbit_make_external_object`
```

so you can treat the object as a pointer to its payload directly. When MoonBit's automatic memory management system finds that an object created by `moonbit_make_external_object` is no longer alive, it will invoke the function `finalize` with the object itself as argument. Now, `finalize` can release external resource/memory held by the object's payload.

###### NOTE
`finalize` **must not** drop the object itself, as this is handled by MoonBit runtime.

On the MoonBit side, objects returned by `moonbit_make_external_object`
should be bind to an *abstract* type, declared using `type T`,
so that MoonBit's memory management system will not ignore the object.

##### Lifetime management of MoonBit object

When passing MoonBit objects to the host through functions, it is essential to take care of the lifetime management of MoonBit itself. As mentioned before, MoonBit's Wasm backend and C backend uses compiler-optimized reference counting to manage lifetime of objects. To avoid memory error or leak, FFI functions must properly maintain the reference count of MoonBit objects.

###### NOTE
For C backend and for Wasm backend only.

###### The calling convention of reference counting

By default, MoonBit uses an owned calling convention for reference counting. That is, callee (the function being invoked) is responsible for dropping its parameters using the `moonbit_decref` / `$moonbit.decref` function. If the parameter is used more than once, the callee should increase the reference count using the `moonbit_incref` / `$moonbit.incref` function. Here are the rules for the necessary operations to perform in different circumstances:

| event                            | operation   |
|----------------------------------|-------------|
| read field/element               | nothing     |
| store into data structure        | `incref`    |
| passed to MoonBit function       | `incref`    |
| passed to other foreign function | nothing     |
| returned                         | nothing     |
| end of scope (not returned)      | `decref`    |

For example, here's a lifetime-correct binding to the standard `open` function for opening a file:

```moonbit
extern "C" fn open(filename : Bytes, flags : Int) -> Int = "open_ffi"
```

```c
int open_ffi(moonbit_bytes_t filename, int flags) {
  int fd = open(filename, flags);
  moonbit_decref(filename);
  return fd;
}
```

###### The managed types

The following types are always unboxed, so there is no need to manage their lifetime:

- builtin number types, such as `Int` and `Double`
- constant `enum` (`enum` where all constructors have no payload)

The following types are always boxed and reference counted:

- `FixedArray[T]`, `Bytes` and `String`
- abstract types (`type T`)

External types (`#external type T`) are also boxed, but they represent external pointers,
so MoonBit will not perform any reference counting operations on them.

The layout of `struct`/`enum` with payload is currently unstable.

###### The borrow and owned attribute

When passing a parameter through the FFI, its ownership may or may not be kept.
The `#borrow` and `#owned` attributes can be used to specify these two conditions.

###### WARNING
We are in the process of migrating the default semantics to `#borrow` instead of `#owned`

The syntax of `#borrow` and `#owned` are as follows:

```moonbit
###borrow(params..)
extern "C" fn c_ffi(..) -> .. = ..
```

where `params` is a subset of the parameters of `c_ffi`.

Parameters of `#borrow` will be passed using borrow based calling convention, that is, the invoked function does not need to `decref` these parameters. If the FFI function only read its parameter locally (i.e. does not return its parameters and does not store them in data structures), you can directly use the `#borrow` attribute. For example, the `open` function mentioned above could be rewritten using `#borrow` as follows:

```moonbit
###borrow(filename)
extern "C" fn open(filename : Bytes, flags : Int) -> Int = "open"
```

There is no need for a stub function anymore: we are binding to the original version of `open` here. With the `#borrow` attribute, this version is still lifetime-correct.

Even if a stub function is still necessary for other reasons, `#borrow` can often simplify the lifetime management. Here are the rules for the necessary operations to perform **on borrow parameters** in different circumstances:

| event                                                   | operation   |
|---------------------------------------------------------|-------------|
| read field / element                                    | nothing     |
| store into data structure                               | `incref`    |
| passed to MoonBit function                              | `incref`    |
| passed to other C function / `#borrow` MoonBit function | nothing     |
| returned                                                | `incref`    |
| end of scope (not returned)                             | nothing     |

The opposite is the `#owned` semantic, where the parameter is stored by the FFI function, and the `decref` needs to be executed manually later.
One use case is registering the callback where the closure would be **owned**.

<!-- path: language/async-experimental.md -->
### Async programming support

MoonBit adopts a coroutine based approach to async programming which is similar to [Kotlin](https://kotlinlang.org/docs/coroutines-overview.html).
The compiler support and concrete syntax is stable while the async library is still under development and considered experimental.

<!-- We highly appreciate any feedback or experiment with current design. -->

#### Async function

Async functions are declared with the `async` keyword.
They implicitly [`raise`](error-handling.md#throwing-errors) errors
and need to declare `noraise` explicitly if otherwise.

```moonbit
async fn my_async_function() -> Unit noraise {
  ...
}

///| anonymous/local function
test {
  let async_lambda = async fn() noraise { ... }
  async fn local_async_function() noraise {
    ...
  }


}
```

Since MoonBit is a statically typed language, the compiler will track its
asyncness, so you can just call async functions like normal functions, the
MoonBit IDE will highlight the async function call with a different style.

```moonbit

///|
async fn some_async_function() -> Unit raise {
  ...
}

///|
async fn another_async_function() -> Unit raise {
  some_async_function() // rendered in italic font
}
```

Async functions can only be called inside async functions.

###### WARNING
Currently, async functions
have not be supported in the body of `for .. in` loops yet, this
will be addressed in the future.

#### Async primitives for suspension

MoonBit provides two core primitives for `%async.suspend` and `%async.run`:

```moonbit

///| `run_async` spawn a new coroutine and execute an async function in it
fn run_async(f : async () -> Unit noraise) -> Unit = "%async.run"

///| `suspend` will suspend the execution of the current coroutine.
/// The suspension will be handled by a callback passed to `suspend`
async fn[T, E : Error] suspend(
  // `f` is a callback for handling suspension
  f : (
    // the first parameter of `f` is used to resume the execution of the coroutine normally
    (T) -> Unit,
    // the second parameter of `f` is used to cancel the execution of the current coroutine
    // by throwing an error at suspension point
    (E) -> Unit,
  ) -> Unit,
) -> T raise E = "%async.suspend"
```

There two primitives are not intended for direct use by end users.
However, since MoonBit's standard library for async programming is still under development,
currently users need to bind these two primitives manually to do async programming.

There are two ways of reading these primitives:

- The coroutine reading: `%async.run` spawns a new coroutine,
  and `%async.suspend` suspends the current coroutine.
  The main difference with other languages here is:
  instead of yielding all the way to the caller of `%async.run`,
  resumption of the coroutine is handled by the callback passed to `%async.suspend`
- The delimited continuation reading: `%async.run` is the `reset` operator in
  delimited continuation, and `%async.suspend` is the `shift` operator in
  delimited continuation

Here's an example of how these two primitives work:

```moonbit

///|
suberror MyError derive(Show)

///|
async fn async_worker(
  logger~ : &Logger,
  throw_error~ : Bool,
) -> Unit raise MyError {
  suspend(fn(resume_ok, resume_err) {
    if throw_error {
      resume_err(MyError)
    } else {
      resume_ok(())
      logger.write_string("the end of the coroutine\n")
    }
  })
}

///|
test {
  // when supplying an anonymous function
  // to a higher order function that expects async parameter,
  // the `async` keyword can be omitted
  let logger = StringBuilder::new()
  fn local_test() {
    run_async(() => try {
      async_worker(logger~, throw_error=false)
      logger.write_string("the worker finishes\n")
    } catch {
      err => logger.write_string("caught: \{err}\n")
    })
    logger.write_string("after the first coroutine finishes\n")
    run_async(() => try {
      async_worker(logger~, throw_error=true)
      logger.write_string("the worker finishes\n")
    } catch {
      err => logger.write_string("caught: \{err}\n")
    })
  }

  local_test()
  inspect(
    logger,
    content=(
      #|the worker finishes
      #|the end of the coroutine
      #|after the first coroutine finishes
      #|caught: MyError
      #|
    ),
  )
}
```

In `async_worker`, `suspend` will capture the rest of the current coroutine as two "continuation" functions, and pass them to a callback.
In the callback, calling `resume_ok` will resume execution at the point of `suspend(...)`,
all the way until the `run_async` call that start this coroutine.
calling `resume_err` will also resume execution of current coroutine,
but it will make `suspend(...)` throw an error instead of returning normally.

Notice that `suspend` type may throw error, even if `suspend` itself never throw an error directly.
This design makes coroutines cancellable at every `suspend` call: just call the corresponding `resume_err` callback.

#### Integrating with JS Promise/callback based API

Since MoonBit's standard async library is still under development,
so there is no ready-to-use implementation for event loop and IO operations yet.
So the easiest way to write some async program is to use MoonBit's Javascript backend,
and reuse the event loop and IO operations of Javascript.
Here's an example of integrating MoonBit's async programming support with JS's callback based API:

```moonbit
###external
type JSTimer

///|
extern "js" fn js_set_timeout(f : () -> Unit, duration~ : Int) -> JSTimer =
  #| (f, duration) => setTimeout(f, duration)

///|
async fn sleep(duration : Int) -> Unit raise {
  suspend(fn(resume_ok, _resume_err) {
    js_set_timeout(duration~, fn() { resume_ok(()) }) |> ignore
  })
}

///|
test {
  run_async(fn() {
    try {
      sleep(500)
      println("timer 1 tick")
      sleep(1000)
      println("timer 1 tick")
      sleep(1500)
      println("timer 1 tick")
    } catch {
      _ => panic()
    }
  })
  run_async(fn() {
    try {
      sleep(600)
      println("timer 2 tick")
      sleep(600)
      println("timer 2 tick")
      sleep(600)
      println("timer 2 tick")
    } catch {
      _ => panic()
    }
  })
}
```

Integrating with JS Promise is easy too:
just pass `resume_ok` as the `resolve` callback and `resume_err` as the `reject` callback to a JS promise.

<!-- path: language/error_codes/index.md -->
### Error Codes Index

###### WARNING
The error codes index is currently WIP.

Many of the entries contains only verify brief description of the error code.
You are more than welcomed to expand any of the entries by submitting a PR to
[moonbitlang/moonbit-docs](https://github.com/moonbitlang/moonbit-docs).

This page lists all error codes produced by the MoonBit compiler.

* [E0001](E0001.md)
* [E0002](E0002.md)
* [E0003](E0003.md)
* [E0004](E0004.md)
* [E0005](E0005.md)
* [E0006](E0006.md)
* [E0007](E0007.md)
* [E0008](E0008.md)
* [E0009](E0009.md)
* [E0010](E0010.md)
* [E0011](E0011.md)
* [E0012](E0012.md)
* [E0013](E0013.md)
* [E0014](E0014.md)
* [E0015](E0015.md)
* [E0016](E0016.md)
* [E0017](E0017.md)
* [E0018](E0018.md)
* [E0019](E0019.md)
* [E0020](E0020.md)
* [E0021](E0021.md)
* [E0022](E0022.md)
* [E0023](E0023.md)
* [E0024](E0024.md)
* [E0025](E0025.md)
* [E0026](E0026.md)
* [E0027](E0027.md)
* [E0028](E0028.md)
* [E0029](E0029.md)
* [E0030](E0030.md)
* [E0031](E0031.md)
* [E0032](E0032.md)
* [E0033](E0033.md)
* [E0034](E0034.md)
* [E0035](E0035.md)
* [E0036](E0036.md)
* [E0037](E0037.md)
* [E0038](E0038.md)
* [E0039](E0039.md)
* [E0040](E0040.md)
* [E0041](E0041.md)
* [E0042](E0042.md)
* [E0043](E0043.md)
* [E0044](E0044.md)
* [E0045](E0045.md)
* [E0046](E0046.md)
* [E0047](E0047.md)
* [E0049](E0049.md)
* [E0050](E0050.md)
* [E0051](E0051.md)
* [E0052](E0052.md)
* [E0053](E0053.md)
* [E0054](E0054.md)
* [E0055](E0055.md)
* [E0056](E0056.md)
* [E0057](E0057.md)
* [E0058](E0058.md)
* [E0059](E0059.md)
* [E0060](E0060.md)
* [E0061](E0061.md)
* [E0062](E0062.md)
* [E0063](E0063.md)
* [E0064](E0064.md)
* [E0065](E0065.md)
* [E0066](E0066.md)
* [E0067](E0067.md)
* [E0068](E0068.md)
* [E0069](E0069.md)
* [E1001](E1001.md)
* [E3001](E3001.md)
* [E3002](E3002.md)
* [E3003](E3003.md)
* [E3004](E3004.md)
* [E3005](E3005.md)
* [E3006](E3006.md)
* [E3007](E3007.md)
* [E3008](E3008.md)
* [E3009](E3009.md)
* [E3010](E3010.md)
* [E3011](E3011.md)
* [E3012](E3012.md)
* [E3014](E3014.md)
* [E3015](E3015.md)
* [E3016](E3016.md)
* [E3017](E3017.md)
* [E3018](E3018.md)
* [E3019](E3019.md)
* [E3020](E3020.md)
* [E3800](E3800.md)
* [E4000](E4000.md)
* [E4001](E4001.md)
* [E4002](E4002.md)
* [E4003](E4003.md)
* [E4004](E4004.md)
* [E4005](E4005.md)
* [E4006](E4006.md)
* [E4007](E4007.md)
* [E4008](E4008.md)
* [E4009](E4009.md)
* [E4010](E4010.md)
* [E4011](E4011.md)
* [E4012](E4012.md)
* [E4013](E4013.md)
* [E4014](E4014.md)
* [E4015](E4015.md)
* [E4016](E4016.md)
* [E4017](E4017.md)
* [E4018](E4018.md)
* [E4019](E4019.md)
* [E4020](E4020.md)
* [E4021](E4021.md)
* [E4023](E4023.md)
* [E4024](E4024.md)
* [E4027](E4027.md)
* [E4028](E4028.md)
* [E4029](E4029.md)
* [E4031](E4031.md)
* [E4032](E4032.md)
* [E4033](E4033.md)
* [E4034](E4034.md)
* [E4036](E4036.md)
* [E4037](E4037.md)
* [E4038](E4038.md)
* [E4039](E4039.md)
* [E4040](E4040.md)
* [E4041](E4041.md)
* [E4042](E4042.md)
* [E4043](E4043.md)
* [E4044](E4044.md)
* [E4046](E4046.md)
* [E4047](E4047.md)
* [E4048](E4048.md)
* [E4049](E4049.md)
* [E4050](E4050.md)
* [E4051](E4051.md)
* [E4052](E4052.md)
* [E4053](E4053.md)
* [E4054](E4054.md)
* [E4055](E4055.md)
* [E4056](E4056.md)
* [E4057](E4057.md)
* [E4059](E4059.md)
* [E4061](E4061.md)
* [E4063](E4063.md)
* [E4064](E4064.md)
* [E4065](E4065.md)
* [E4066](E4066.md)
* [E4067](E4067.md)
* [E4068](E4068.md)
* [E4069](E4069.md)
* [E4070](E4070.md)
* [E4071](E4071.md)
* [E4073](E4073.md)
* [E4074](E4074.md)
* [E4075](E4075.md)
* [E4077](E4077.md)
* [E4078](E4078.md)
* [E4080](E4080.md)
* [E4081](E4081.md)
* [E4082](E4082.md)
* [E4084](E4084.md)
* [E4085](E4085.md)
* [E4086](E4086.md)
* [E4087](E4087.md)
* [E4089](E4089.md)
* [E4091](E4091.md)
* [E4092](E4092.md)
* [E4093](E4093.md)
* [E4094](E4094.md)
* [E4095](E4095.md)
* [E4096](E4096.md)
* [E4099](E4099.md)
* [E4100](E4100.md)
* [E4101](E4101.md)
* [E4102](E4102.md)
* [E4103](E4103.md)
* [E4104](E4104.md)
* [E4105](E4105.md)
* [E4106](E4106.md)
* [E4107](E4107.md)
* [E4108](E4108.md)
* [E4109](E4109.md)
* [E4110](E4110.md)
* [E4111](E4111.md)
* [E4112](E4112.md)
* [E4113](E4113.md)
* [E4114](E4114.md)
* [E4115](E4115.md)
* [E4116](E4116.md)
* [E4117](E4117.md)
* [E4118](E4118.md)
* [E4119](E4119.md)
* [E4120](E4120.md)
* [E4121](E4121.md)
* [E4122](E4122.md)
* [E4124](E4124.md)
* [E4125](E4125.md)
* [E4127](E4127.md)
* [E4128](E4128.md)
* [E4130](E4130.md)
* [E4131](E4131.md)
* [E4132](E4132.md)
* [E4133](E4133.md)
* [E4134](E4134.md)
* [E4135](E4135.md)
* [E4136](E4136.md)
* [E4137](E4137.md)
* [E4138](E4138.md)
* [E4139](E4139.md)
* [E4140](E4140.md)
* [E4141](E4141.md)
* [E4142](E4142.md)
* [E4143](E4143.md)
* [E4144](E4144.md)
* [E4145](E4145.md)
* [E4146](E4146.md)
* [E4147](E4147.md)
* [E4148](E4148.md)
* [E4149](E4149.md)
* [E4151](E4151.md)
* [E4153](E4153.md)
* [E4154](E4154.md)
* [E4155](E4155.md)
* [E4156](E4156.md)
* [E4157](E4157.md)
* [E4158](E4158.md)
* [E4159](E4159.md)
* [E4160](E4160.md)
* [E4162](E4162.md)
* [E4163](E4163.md)
* [E4164](E4164.md)
* [E4167](E4167.md)
