moonscratch 0.1.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/.agents/skills/moonbit-agent-guide/LICENSE +202 -0
  2. package/.agents/skills/moonbit-agent-guide/SKILL.mbt.md +1126 -0
  3. package/.agents/skills/moonbit-agent-guide/SKILL.md +1126 -0
  4. package/.agents/skills/moonbit-agent-guide/ide.md +116 -0
  5. package/.agents/skills/moonbit-agent-guide/references/advanced-moonbit-build.md +106 -0
  6. package/.agents/skills/moonbit-agent-guide/references/moonbit-language-fundamentals.mbt.md +422 -0
  7. package/.agents/skills/moonbit-agent-guide/references/moonbit-language-fundamentals.md +422 -0
  8. package/.agents/skills/moonbit-practice/SKILL.md +258 -0
  9. package/.agents/skills/moonbit-practice/assets/ci.yaml +25 -0
  10. package/.agents/skills/moonbit-practice/reference/agents.md +1469 -0
  11. package/.agents/skills/moonbit-practice/reference/configuration.md +228 -0
  12. package/.agents/skills/moonbit-practice/reference/ffi.md +229 -0
  13. package/.agents/skills/moonbit-practice/reference/ide.md +189 -0
  14. package/.agents/skills/moonbit-practice/reference/performance.md +217 -0
  15. package/.agents/skills/moonbit-practice/reference/refactor.md +154 -0
  16. package/.agents/skills/moonbit-practice/reference/stdlib.md +351 -0
  17. package/.agents/skills/moonbit-practice/reference/testing.md +228 -0
  18. package/.agents/skills/moonbit-refactoring/LICENSE +21 -0
  19. package/.agents/skills/moonbit-refactoring/SKILL.md +323 -0
  20. package/.githooks/README.md +23 -0
  21. package/.githooks/pre-commit +3 -0
  22. package/.github/workflows/copilot-setup-steps.yml +40 -0
  23. package/.turbo/turbo-typecheck.log +2 -0
  24. package/AGENTS.md +91 -0
  25. package/LICENSE +21 -0
  26. package/PLAN.md +64 -0
  27. package/README.mbt.md +77 -0
  28. package/README.md +84 -0
  29. package/TODO.md +120 -0
  30. package/a.png +0 -0
  31. package/benchmarks/calc.bench.ts +144 -0
  32. package/benchmarks/draw.bench.ts +215 -0
  33. package/benchmarks/load.bench.ts +28 -0
  34. package/benchmarks/render.bench.ts +53 -0
  35. package/benchmarks/run.bench.ts +8 -0
  36. package/benchmarks/types.d.ts +15 -0
  37. package/docs/scratch-vm-specs/eventloop.md +103 -0
  38. package/docs/scratch-vm-specs/moonscratch-time-separation.md +50 -0
  39. package/index.html +91 -0
  40. package/js/AGENTS.md +5 -0
  41. package/js/a.ts +52 -0
  42. package/js/assets/AGENTS.md +5 -0
  43. package/js/assets/base64.test.ts +14 -0
  44. package/js/assets/base64.ts +21 -0
  45. package/js/assets/build-asset.test.ts +26 -0
  46. package/js/assets/build-asset.ts +28 -0
  47. package/js/assets/create.test.ts +142 -0
  48. package/js/assets/create.ts +122 -0
  49. package/js/assets/index.test.ts +15 -0
  50. package/js/assets/index.ts +2 -0
  51. package/js/assets/types.ts +26 -0
  52. package/js/assets/validation.test.ts +34 -0
  53. package/js/assets/validation.ts +25 -0
  54. package/js/assets.test.ts +14 -0
  55. package/js/assets.ts +1 -0
  56. package/js/index.test.ts +26 -0
  57. package/js/index.ts +3 -0
  58. package/js/render/index.test.ts +65 -0
  59. package/js/render/index.ts +13 -0
  60. package/js/render/sharp.ts +87 -0
  61. package/js/render/svg.ts +68 -0
  62. package/js/render/types.ts +35 -0
  63. package/js/render/utils.ts +108 -0
  64. package/js/render/webgl.ts +274 -0
  65. package/js/sharp-optional.d.ts +16 -0
  66. package/js/test/helpers.ts +116 -0
  67. package/js/test/hikkaku-sample.test.ts +37 -0
  68. package/js/test/rubik-components.input-motion.test.ts +60 -0
  69. package/js/test/rubik-components.lists.test.ts +49 -0
  70. package/js/test/rubik-components.operators.test.ts +104 -0
  71. package/js/test/rubik-components.pen.test.ts +112 -0
  72. package/js/test/rubik-components.procedures-loops.test.ts +72 -0
  73. package/js/test/rubik-components.variables-branches.test.ts +57 -0
  74. package/js/test/rubik-components.visibility-entry.test.ts +31 -0
  75. package/js/test/test-projects.ts +598 -0
  76. package/js/test/variable.ts +200 -0
  77. package/js/test/warp.test.ts +59 -0
  78. package/js/vm/AGENTS.md +6 -0
  79. package/js/vm/README.md +183 -0
  80. package/js/vm/bindings.test.ts +13 -0
  81. package/js/vm/bindings.ts +5 -0
  82. package/js/vm/compare-operators.test.ts +145 -0
  83. package/js/vm/constants.test.ts +11 -0
  84. package/js/vm/constants.ts +4 -0
  85. package/js/vm/effect-guards.test.ts +68 -0
  86. package/js/vm/effect-guards.ts +44 -0
  87. package/js/vm/factory.test.ts +486 -0
  88. package/js/vm/factory.ts +615 -0
  89. package/js/vm/headless-vm.test.ts +131 -0
  90. package/js/vm/headless-vm.ts +342 -0
  91. package/js/vm/index.test.ts +28 -0
  92. package/js/vm/index.ts +5 -0
  93. package/js/vm/internal-types.ts +32 -0
  94. package/js/vm/json.test.ts +40 -0
  95. package/js/vm/json.ts +273 -0
  96. package/js/vm/normalize.test.ts +48 -0
  97. package/js/vm/normalize.ts +65 -0
  98. package/js/vm/options.test.ts +30 -0
  99. package/js/vm/options.ts +55 -0
  100. package/js/vm/pen-transparency.test.ts +115 -0
  101. package/js/vm/program-wasm.ts +322 -0
  102. package/js/vm/scheduler-render.test.ts +401 -0
  103. package/js/vm/scratch-assets.test.ts +136 -0
  104. package/js/vm/scratch-assets.ts +202 -0
  105. package/js/vm/types.ts +358 -0
  106. package/js/vm/value-guards.test.ts +25 -0
  107. package/js/vm/value-guards.ts +18 -0
  108. package/moon.mod.json +10 -0
  109. package/package.json +33 -0
  110. package/scripts/preinstall.ts +4 -0
  111. package/src/AGENTS.md +6 -0
  112. package/src/api.mbt +161 -0
  113. package/src/api_aot_commands.mbt +184 -0
  114. package/src/api_effects_json.mbt +72 -0
  115. package/src/api_options.mbt +60 -0
  116. package/src/api_program_wasm.mbt +1647 -0
  117. package/src/api_program_wat.mbt +2206 -0
  118. package/src/api_snapshot_json.mbt +44 -0
  119. package/src/cmd/AGENTS.md +5 -0
  120. package/src/cmd/main/AGENTS.md +5 -0
  121. package/src/cmd/main/main.mbt +29 -0
  122. package/src/cmd/main/moon.pkg +7 -0
  123. package/src/cmd/main/pkg.generated.mbti +13 -0
  124. package/src/json_helpers.mbt +176 -0
  125. package/src/moon.pkg +65 -0
  126. package/src/moonscratch.mbt +3 -0
  127. package/src/moonscratch_wbtest.mbt +40 -0
  128. package/src/parser_sb3.mbt +890 -0
  129. package/src/pkg.generated.mbti +479 -0
  130. package/src/runtime_eval.mbt +2844 -0
  131. package/src/runtime_exec.mbt +3850 -0
  132. package/src/runtime_render.mbt +2550 -0
  133. package/src/runtime_state.mbt +870 -0
  134. package/src/test/AGENTS.md +3 -0
  135. package/src/test/projects/AGENTS.md +6 -0
  136. package/src/test/projects/moon.pkg +4 -0
  137. package/src/test/projects/moonscratch_compat_test.mbt +642 -0
  138. package/src/test/projects/moonscratch_core_test.mbt +1332 -0
  139. package/src/test/projects/moonscratch_runtime_test.mbt +1087 -0
  140. package/src/test/projects/pkg.generated.mbti +13 -0
  141. package/src/test/projects/test_support.mbt +35 -0
  142. package/src/types_effects.mbt +20 -0
  143. package/src/types_error.mbt +4 -0
  144. package/src/types_options.mbt +31 -0
  145. package/src/types_runtime_structs.mbt +254 -0
  146. package/src/types_vm.mbt +109 -0
  147. package/tsconfig.json +29 -0
  148. package/viewer/index.ts +399 -0
  149. package/viewer/vite.d.ts +1 -0
  150. package/viewer/worker.ts +161 -0
  151. package/vite.config.ts +11 -0
@@ -0,0 +1,116 @@
1
+ ## Code Navigation with `moon ide`
2
+
3
+ **ALWAYS use `moon ide` for code navigation in MoonBit projects instead of manual file searching, grep, or semantic search.**
4
+
5
+ This tool provides two essential commands for precise code exploration:
6
+
7
+ ### Core Commands
8
+
9
+ - `moon ide goto-definition` - Find where a symbol is defined
10
+ - `moon ide find-references` - Find all usages of a symbol
11
+
12
+ ### Query System
13
+
14
+ Symbol lookup uses a two-part query system for precise results:
15
+
16
+ #### 1. Symbol Name Query (`-query`)
17
+
18
+ Fuzzy search for symbol names with package filtering support:
19
+
20
+ ```bash
21
+ # Find any symbol named 'symbol'
22
+ moon ide goto-definition -query 'symbol'
23
+
24
+ # Find methods of a specific type
25
+ moon ide goto-definition -query 'Type::method'
26
+
27
+ # Find trait method implementations
28
+ moon ide goto-definition -query 'Trait for Type with method'
29
+
30
+ # Find symbol in specific package using @pkg prefix
31
+ moon ide goto-definition -query '@moonbitlang/x encode'
32
+
33
+ # Find symbol in multiple packages (searches in pkg1 OR pkg2)
34
+ moon ide goto-definition -query '@username/mymodule/pkg1 @username/mymodule/pkg2 helper'
35
+
36
+ # Find symbol in nested package
37
+ moon ide goto-definition -query '@username/mymodule/mypkg helper'
38
+ ```
39
+
40
+ **Supported symbols**: functions, constants, let bindings, types, structs, enums, traits
41
+
42
+ **Package filtering**: Prefix your query with `@package_name` to scope the search. Multiple `@pkg` prefixes create an OR condition.
43
+
44
+ #### 2. Tag-based Filtering (`-tags`)
45
+
46
+ Pre-filter symbols by characteristics before name matching:
47
+
48
+ **Visibility tags**:
49
+
50
+ - `pub` - Public symbols
51
+ - `pub all` - Public structs with all public fields
52
+ - `pub open` - Public traits with all methods public
53
+ - `priv` - Private symbols
54
+
55
+ **Symbol type tags**:
56
+
57
+ - `type` - Type definitions (struct, enum, typealias, abstract)
58
+ - `error` - Error type definitions
59
+ - `enum` - Enum definitions and variants
60
+ - `struct` - Struct definitions
61
+ - `alias` - Type/function/trait aliases
62
+ - `let` - Top-level let bindings
63
+ - `const` - Constant definitions
64
+ - `fn` - Function definitions
65
+ - `trait` - Trait definitions
66
+ - `impl` - Trait implementations
67
+ - `test` - Named test functions
68
+
69
+ **Combine tags with logical operators**:
70
+
71
+ ```bash
72
+ # Public functions only
73
+ moon ide goto-definition -tags 'pub fn' -query 'my_func'
74
+
75
+ # Functions or constants
76
+ moon ide goto-definition -tags 'fn | const' -query 'helper'
77
+
78
+ # Public functions or constants
79
+ moon ide goto-definition -tags 'pub (fn | const)' -query 'api'
80
+
81
+ # Public types or traits
82
+ moon ide goto-definition -tags 'pub (type | trait)' -query 'MyType'
83
+ ```
84
+
85
+ ### Practical Examples
86
+
87
+ ```bash
88
+ # Find public function definition
89
+ moon ide goto-definition -tags 'pub fn' -query 'maximum'
90
+
91
+ # Find all references to a struct
92
+ moon ide find-references -tags 'struct' -query 'Rectangle'
93
+
94
+ # Find trait implementations
95
+ moon ide goto-definition -tags 'impl' -query 'Show for MyType'
96
+
97
+ # Find errors in specific package
98
+ moon ide goto-definition -tags 'error' -query '@mymodule/parser ParseError'
99
+
100
+ # Find symbol across multiple packages
101
+ moon ide goto-definition -query '@moonbitlang/x @moonbitlang/core encode'
102
+
103
+ # Combine package filtering with tags
104
+ moon ide goto-definition -tags 'pub fn' -query '@username/myapp helper'
105
+ ```
106
+
107
+ ### Query Processing
108
+
109
+ The tool processes queries in this order:
110
+
111
+ 1. Filter symbols by `-tags` conditions
112
+ 2. Extract package scope from `@pkg` prefixes in `-query`
113
+ 3. Fuzzy match remaining symbols by name
114
+ 4. Return top 3 best matches with location information
115
+
116
+ **Best Practice**: Start with `-tags` to reduce noise, then use `@pkg` prefixes in `-query` to scope by package for precise navigation.
@@ -0,0 +1,106 @@
1
+ ## Conditional Compilation
2
+
3
+ Target specific backends/modes in `moon.pkg.json`:
4
+
5
+ ```json
6
+ {
7
+ "targets": {
8
+ "wasm_only.mbt": ["wasm"],
9
+ "js_only.mbt": ["js"],
10
+ "debug_only.mbt": ["debug"],
11
+ "wasm_or_js.mbt": ["wasm", "js"], // for wasm or js backend
12
+ "not_js.mbt": ["not", "js"], // for nonjs backend
13
+ "complex.mbt": ["or", ["and", "wasm", "release"], ["and", "js", "debug"]] // more complex conditions
14
+ }
15
+ }
16
+ ```
17
+
18
+ **Available conditions:**
19
+
20
+ - **Backends**: `"wasm"`, `"wasm-gc"`, `"js"`, `"native"`
21
+ - **Build modes**: `"debug"`, `"release"`
22
+ - **Logical operators**: `"and"`, `"or"`, `"not"`
23
+
24
+ ## Link Configuration
25
+
26
+ ### Basic Linking
27
+
28
+ ```json
29
+ {
30
+ "link": true, // Enable linking for this package
31
+ // OR for advanced cases:
32
+ "link": {
33
+ "wasm": {
34
+ "exports": ["hello", "foo:bar"], // Export functions
35
+ "heap-start-address": 1024, // Memory layout
36
+ "import-memory": {
37
+ // Import external memory
38
+ "module": "env",
39
+ "name": "memory"
40
+ },
41
+ "export-memory-name": "memory" // Export memory with name
42
+ },
43
+ "wasm-gc": {
44
+ "exports": ["hello"],
45
+ "use-js-builtin-string": true, // JS String Builtin support
46
+ "imported-string-constants": "_" // String namespace
47
+ },
48
+ "js": {
49
+ "exports": ["hello"],
50
+ "format": "esm" // "esm", "cjs", or "iife"
51
+ },
52
+ "native": {
53
+ "cc": "gcc", // C compiler
54
+ "cc-flags": "-O2 -DMOONBIT", // Compile flags
55
+ "cc-link-flags": "-s" // Link flags
56
+ }
57
+ }
58
+ }
59
+ ```
60
+
61
+ ## Warning Control
62
+
63
+ Disable specific warnings in `moon.mod.json` or `moon.pkg.json`:
64
+
65
+ ```json
66
+ {
67
+ "warn-list": "-2-29" // Disable unused variable (2) & unused package (29)
68
+ }
69
+ ```
70
+
71
+ **Common warning numbers:**
72
+
73
+ - `1` - Unused function
74
+ - `2` - Unused variable
75
+ - `11` - Partial pattern matching
76
+ - `12` - Unreachable code
77
+ - `29` - Unused package
78
+
79
+ Use `moonc build-package -warn-help` to see all available warnings.
80
+
81
+ ## Pre-build Commands
82
+
83
+ Embed external files as MoonBit code:
84
+
85
+ ```json
86
+ {
87
+ "pre-build": [
88
+ {
89
+ "input": "data.txt",
90
+ "output": "embedded.mbt",
91
+ "command": ":embed -i $input -o $output --name data --text"
92
+ },
93
+ ... // more embed commands
94
+ ]
95
+ }
96
+ ```
97
+
98
+ Generated code example:
99
+
100
+ ```mbt check
101
+ ///|
102
+ let data : String =
103
+ #|hello,
104
+ #|world
105
+ #|
106
+ ```
@@ -0,0 +1,422 @@
1
+ # MoonBit Language Fundamentals
2
+
3
+ ## Quick reference:
4
+
5
+ ```mbt check
6
+ ///|
7
+ /// comments doc string
8
+ pub fn sum(x : Int, y : Int) -> Int {
9
+ x + y
10
+ }
11
+
12
+ ///|
13
+ struct Rect {
14
+ width : Int
15
+ height : Int
16
+ }
17
+
18
+ ///|
19
+ fn Rect::area(self : Rect) -> Int {
20
+ self.width * self.height
21
+ }
22
+
23
+ ///|
24
+ pub impl Show for Rect with output(_self, logger) {
25
+ logger.write_string("Rect")
26
+ }
27
+
28
+ ///|
29
+ enum MyOption {
30
+ MyNone
31
+ MySome(Int)
32
+ } derive(Show, ToJson, Eq, Compare)
33
+
34
+ ///|
35
+ /// match + loops are expressions
36
+ test "everything is expression in MoonBit" {
37
+ // tuple
38
+ let (n, opt) = (1, MySome(2))
39
+ // if expressions return values
40
+ let msg : String = if n > 0 { "pos" } else { "non-pos" }
41
+ let res = match opt {
42
+ MySome(x) => {
43
+ inspect(x, content="2")
44
+ 1
45
+ }
46
+ MyNone => 0
47
+ }
48
+ let status : Result[Int, String] = Ok(10)
49
+ // match expressions return values
50
+ let description = match status {
51
+ Ok(value) => "Success: \{value}"
52
+ Err(error) => "Error: \{error}"
53
+ }
54
+ let array = [1, 2, 3, 4, 5]
55
+ let mut i = 0 // mutable bindings (local only, globals are immutable)
56
+ let target = 3
57
+ // loops return values with 'break'
58
+ let found : Int? = while i < array.length() {
59
+ if array[i] == target {
60
+ break Some(i) // Exit with value
61
+ }
62
+ i = i + 1
63
+ } else { // Value when loop completes normally
64
+ None
65
+ }
66
+ assert_eq(found, Some(2)) // Found at index 2
67
+ }
68
+
69
+ ///|
70
+ /// global bindings
71
+ pub let my_name : String = "MoonBit"
72
+
73
+ ///|
74
+ pub const PI : Double = 3.14159 // constants use UPPER_SNAKE or PascalCase
75
+
76
+ ///|
77
+ pub fn maximum(xs : Array[Int]) -> Int raise {
78
+ // Toplevel functions are *mutually recursive* by default
79
+ // `raise` annotation means the function would raise any Error
80
+ // Only add `raise XXError` when you do need track the specific error type
81
+ match xs {
82
+ [] => fail("Empty array") // fail() is built-in for generic errors
83
+ [x] => x
84
+ // pattern match over array, the `.. rest` is a rest pattern
85
+ // it is of type `ArrayView[Int]` which is a slice
86
+ [x, .. rest] => {
87
+ let mut max_val = x // `mut` only allowed in local bindings
88
+ for y in rest {
89
+ if y > max_val {
90
+ max_val = y
91
+ }
92
+ }
93
+ max_val // return can be omitted if the last expression is the return value
94
+ }
95
+ }
96
+ }
97
+
98
+ ///|
99
+ /// pub(all) means it can be both read and created outside the package
100
+ pub(all) struct Point {
101
+ x : Int
102
+ mut y : Int
103
+ } derive(Show, ToJson)
104
+
105
+ ///|
106
+ pub enum MyResult[T, E] {
107
+ MyOk(T) // semicolon `;` is optional when we have a newline
108
+ MyErr(E) // Enum variants must start uppercase
109
+ } derive(Show, Eq, ToJson)
110
+ // pub means it can only be pattern matched outside the package
111
+ // but it can not be created outside the package, use `pub(all)` otherwise
112
+
113
+ ///|
114
+ /// pub (open) means the trait can be implemented for outside packages
115
+ pub(open) trait Comparable {
116
+ compare(Self, Self) -> Int // `Self` refers to the implementing type
117
+ }
118
+
119
+ ///|
120
+ test "inspect test" {
121
+ let result = sum(1, 2)
122
+ inspect(result, content="3")
123
+ // The `content` can be auto-corrected by running `moon test --update`
124
+ let point = Point::{ x: 10, y: 20 }
125
+ // For complex structures, use @json.inspect for better readability:
126
+ @json.inspect(point, content={ "x": 10, "y": 20 })
127
+ }
128
+ ```
129
+
130
+ ## Complex Types
131
+
132
+ ```mbt check
133
+ ///|
134
+ pub type UserId = Int // Int is aliased to UserId - like symlink
135
+
136
+ ///|
137
+ /// Tuple-struct for callback
138
+ pub struct Handler((String) -> Unit) // A newtype wrapper
139
+
140
+ ///|
141
+ /// Tuple-struct syntax for single-field newtypes
142
+ struct Meters(Int) // Tuple-struct syntax
143
+
144
+ ///|
145
+ let distance : Meters = Meters(100)
146
+
147
+ ///|
148
+ let raw : Int = distance.0 // Access first field with .0
149
+
150
+ ///|
151
+ struct Addr {
152
+ host : String
153
+ port : Int
154
+ } derive(Show, Eq, ToJson, FromJson)
155
+
156
+ ///|
157
+ /// Structural types with literal syntax
158
+ let config : Addr = Addr::{
159
+ // `Type::` can be omitted since the type is already known
160
+ host: "localhost",
161
+ port: 8080,
162
+ }
163
+
164
+
165
+ ```
166
+
167
+ ## Common Derivable Traits
168
+
169
+ Most types can automatically derive standard traits using the `derive(...)` syntax:
170
+
171
+ - **`Show`** - Enables `to_string()` and string interpolation with `\{value}`
172
+ - **`Eq`** - Enables `==` and `!=` equality operators
173
+ - **`Compare`** - Enables `<`, `>`, `<=`, `>=` comparison operators
174
+ - **`ToJson`** - Enables `@json.inspect()` for readable test output
175
+ - **`Hash`** - Enables use as Map keys
176
+
177
+ ```mbt check
178
+ ///|
179
+ struct Coordinate {
180
+ x : Int
181
+ y : Int
182
+ } derive(Show, Eq, ToJson)
183
+
184
+ ///|
185
+ enum Status {
186
+ Active
187
+ Inactive
188
+ } derive(Show, Eq, Compare)
189
+ ```
190
+
191
+ **Best practice**: Always derive `Show` and `Eq` for data types. Add `ToJson` if you plan to test them with `@json.inspect()`.
192
+
193
+ ## Reference Semantics by Default
194
+
195
+ MoonBit passes most types by reference semantically (the optimizer may copy
196
+ immutables):
197
+
198
+ ```mbt check
199
+ ///|
200
+ /// Structs with 'mut' fields are always passed by reference
201
+ struct Counter {
202
+ mut value : Int
203
+ }
204
+
205
+ ///|
206
+ fn increment(c : Counter) -> Unit {
207
+ c.value += 1 // Modifies the original
208
+ }
209
+
210
+ ///|
211
+ /// Arrays and Maps are mutable references
212
+ fn modify_array(arr : Array[Int]) -> Unit {
213
+ arr[0] = 999 // Modifies original array
214
+ }
215
+
216
+ ///|
217
+ test "reference semantics" {
218
+ let counter : Ref[Int] = Ref::{ val: 0 }
219
+ counter.val += 1
220
+ assert_true(counter.val is 1)
221
+ let arr : Array[Int] = [1, 2, 3] // unlike Rust, no `mut` keyword needed
222
+ modify_array(arr)
223
+ assert_true(arr[0] is 999)
224
+ let mut x = 3 // `mut` neeed for re-assignment to the bindings
225
+ x += 2
226
+ assert_true(x is 5)
227
+ }
228
+ ```
229
+
230
+ ## Pattern Matching
231
+
232
+ ```mbt check
233
+ ///|
234
+ #warnings("-unused_value")
235
+ test "pattern match over Array, struct and StringView" {
236
+ let arr : Array[Int] = [10, 20, 25, 30]
237
+ match arr {
238
+ [] => ... // empty array
239
+ [single] => ... // single element
240
+ [first, .. middle, rest] => {
241
+ let _ : ArrayView[Int] = middle // middle is ArrayView[Int]
242
+ assert_true(first is 10 && middle is [20, 25] && rest is 30)
243
+ }
244
+ }
245
+ fn process_point(point : Point) -> Unit {
246
+ match point {
247
+ { x: 0, y: 0 } => ...
248
+ { x, y } if x == y => ...
249
+ { x, .. } if x < 0 => ...
250
+ ...
251
+ }
252
+ }
253
+ /// StringView pattern matching for parsing
254
+ fn is_palindrome(s : StringView) -> Bool {
255
+ loop s {
256
+ [] | [_] => true
257
+ [a, .. rest, b] if a == b => continue rest
258
+ // a is of type Char, rest is of type StringView
259
+ _ => false
260
+ }
261
+ }
262
+
263
+
264
+ }
265
+ ```
266
+
267
+ ## Functional `loop` control flow
268
+
269
+ The `loop` construct is unique to MoonBit:
270
+
271
+ ```mbt check
272
+ ///|
273
+ /// Functional loop with pattern matching on loop variables
274
+ /// @list.List is from the standard library
275
+ fn sum_list(list : @list.List[Int]) -> Int {
276
+ loop (list, 0) {
277
+ (Empty, acc) => acc // Base case returns accumulator
278
+ (More(x, tail=rest), acc) => continue (rest, x + acc) // Recurse with new values
279
+ }
280
+ }
281
+
282
+ ///|
283
+ /// Multiple loop variables with complex control flow
284
+ fn find_pair(arr : Array[Int], target : Int) -> (Int, Int)? {
285
+ loop (0, arr.length() - 1) {
286
+ (i, j) if i >= j => None
287
+ (i, j) => {
288
+ let sum = arr[i] + arr[j]
289
+ if sum == target {
290
+ Some((i, j)) // Found pair
291
+ } else if sum < target {
292
+ continue (i + 1, j) // Move left pointer
293
+ } else {
294
+ continue (i, j - 1) // Move right pointer
295
+ }
296
+ }
297
+ }
298
+ }
299
+ ```
300
+
301
+ **Note**: You must provide a payload to `loop`. If you want an infinite loop, use `while true { ... }` instead. The syntax `loop { ... }` without arguments is invalid.
302
+
303
+ ## Methods and Traits
304
+
305
+ Methods use `Type::method_name` syntax, traits require explicit implementation:
306
+
307
+ ```mbt check
308
+ ///|
309
+ struct Rectangle {
310
+ width : Double
311
+ height : Double
312
+ }
313
+
314
+ ///|
315
+ // Methods are prefixed with Type::
316
+ fn Rectangle::area(self : Rectangle) -> Double {
317
+ self.width * self.height
318
+ }
319
+
320
+ ///|
321
+ /// Static methods don't need self
322
+ fn Rectangle::new(w : Double, h : Double) -> Rectangle {
323
+ { width: w, height: h }
324
+ }
325
+
326
+ ///|
327
+ /// Show trait now uses output(self, logger) for custom formatting
328
+ /// to_string() is automatically derived from this
329
+ pub impl Show for Rectangle with output(self, logger) {
330
+ logger.write_string("Rectangle(\{self.width}x\{self.height})")
331
+ }
332
+
333
+ ///|
334
+ /// Traits can have non-object-safe methods
335
+ trait Named {
336
+ name() -> String // No 'self' parameter - not object-safe
337
+ }
338
+
339
+ ///|
340
+ /// Trait bounds in generics
341
+ fn[T : Show + Named] describe(value : T) -> String {
342
+ "\{T::name()}: \{value.to_string()}"
343
+ }
344
+
345
+ ///|
346
+ /// Trait implementation
347
+ impl Hash for Rectangle with hash_combine(self, hasher) {
348
+ hasher..combine(self.width)..combine(self.height)
349
+ }
350
+ ```
351
+
352
+ ## Operator Overloading
353
+
354
+ MoonBit supports operator overloading through traits:
355
+
356
+ ```mbt check
357
+ ///|
358
+ struct Vector(Int, Int)
359
+
360
+ ///|
361
+ /// Implement arithmetic operators
362
+ pub impl Add for Vector with add(self, other) {
363
+ Vector(self.0 + other.0, self.1 + other.1)
364
+ }
365
+
366
+ ///|
367
+ struct Person {
368
+ age : Int
369
+ } derive(Eq)
370
+
371
+ ///|
372
+ /// Comparison operators
373
+ pub impl Compare for Person with compare(self, other) {
374
+ self.age.compare(other.age)
375
+ }
376
+
377
+ ///|
378
+ test "overloading" {
379
+ let v1 : Vector = Vector(1, 2)
380
+ let v2 : Vector = Vector(3, 4)
381
+ let _v3 : Vector = v1 + v2
382
+
383
+ }
384
+ ```
385
+
386
+ ## Access Control Modifiers
387
+
388
+ MoonBit has fine-grained visibility control:
389
+
390
+ ```mbt check
391
+ ///|
392
+ /// `fn` defaults to Private - only visible in current package
393
+ fn internal_helper() -> Unit {
394
+ ...
395
+ }
396
+
397
+ ///|
398
+ pub fn get_value() -> Int {
399
+ ...
400
+ }
401
+
402
+ ///|
403
+ // Struct (default) - type visible, implementation hidden
404
+ struct DataStructure {}
405
+
406
+ ///|
407
+ /// `pub struct` defaults to readonly - can read, pattern match, but not create
408
+ pub struct Config {}
409
+
410
+ ///|
411
+ /// Public all - full access
412
+ pub(all) struct Config2 {}
413
+
414
+ ///|
415
+ /// Abstract trait (default) - cannot be implemented by
416
+ /// types outside this package
417
+ pub trait MyTrait {}
418
+
419
+ ///|
420
+ /// Open for extension
421
+ pub(open) trait Extendable {}
422
+ ```