跳到主要内容

weekly 2024-04-15

· 阅读需 2 分钟

MoonBit is a Rust-like language (with GC support) and toolchain optimized for WebAssembly experience. This is our recent update:

Core Update

We have received 221 Repositories to MoonBit core since its open source in March, with 26 excellent contributors contributing about 10,000 lines of code of high quality. Thanks a lot for your passion and support for MoonBit!

0.PNG

Language Update

  • Expanded array patterns in pattern matching.

    • Support the vec type in the standard library.
    • Support for generic types [a, .., b].
    fn main {
      let xs = @vec.from_array([1, 2, 3])
      match xs {
        [1, .., 3] => { println("ok")}
        _ => println("not ok")
      }
      // Output: ok
    }

IDE Update

  • Changed the printing output of the online IDE from the Output channel to the terminal. Fixed the issue where the printing output was occasionally truncated in Firefox browsers. ANSI escape sequences can be used in browser code, for example:

1.PNG

  • Support autocompletion in the form of x |> @pkg.

1.5.PNG

  • Disabled inlay hint for matrix functions.

Before

2.PNG

After

3.PNG

Toolchain Update

  • Added (experimental) test coverage tools. (*Windows is not supported at the moment)

    • Added -enable-coverage option to moon test for enabling coverage during runtime.
    • Added moon coverage command for reading and processing coverage data.
      • After testing, moon coverage report -f <format> can be used to output coverage data. Supported output formats include:
        • bisect (default output format of OCaml Bisect tool)
        • html (output result webpage)
        • coveralls (JSON format suitable for CodeCov and Coveralls tool upload)
        • summary (output summary in the terminal) More functionalities can be viewed through moon coverage report -h.
      • moon coverage clean command can be used to clean up previous coverage data output.
  • The build system has added the moon info command for generating public interface files of software packages. (*Windows is not supported at the moment) Example:

    $ moon new hello
    $ cd hello
    $ moon info
    $ cat lib/lib.mbti
    package username/hello/lib
    
        // Values
        fn hello() -> String
    
        // Types and methods
    
        // Traits
    
        // Extension Methods
        ```
    
  • Fixed the issue where the annotation was misaligned caused by trailing commas in moonfmt.

  • Fixed the issue where file paths cannot contain spaces in moon.

weekly 2024-04-08

· 阅读需 1 分钟

MoonBit更新

  • 支持 array.iter intrinsic 并且已经对标准库中的函数进行标注,从而可以在特定情况下将循环进行内联,以提升运行效率

    /// @intrinsic %array.iter
    pub fn iter[T](self : Array[T], f : (T) -> Unit) -> Unit {
      for i = 0; i < self.length(); i = i + 1 {
        f(self[i])
      }
    }

工具链更新

  • 支持实验性的测试覆盖率统计工具
    • 工具已经实验性支持 MoonBit Core CI
    • 我们正在优化面向用户的接口

image

image

  • 默认关闭Alerts pragmas 中 unsafe/throw/raise 类别的警告,启用了 deprecated alert。
  • moonfmt
    • 修复带负号的字面量打印后注释错位的问题
    • 修复带负号字面量打印后括号消失的问题
  • 修复变量高亮
  • moonrun 支持 UTF-16 字符串的打印

构建系统更新

  • expect test 支持处理 Unicode 字符

image

weekly 2024-04-01

· 阅读需 4 分钟

MoonBit 更新

1. expect 测试添加 inspect 函数

expect 测试添加针对 Show 接口的 inspect 函数,签名如下:

pub fn inspect(
  obj: Show,
  ~content: String = "",
  ~loc: SourceLoc = _,
  ~args_loc: ArgsLoc = _
) -> Result[Unit, String]

⚠️ 此API暂不稳定,在未来可能会更改为 expect 函数

使用 inspect 可以更方便编写测试,例如对于如下代码:

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

test {
  inspect(add(1, 2))?
}

test {
  (add(3, 4) |> inspect)?
}

执行 moon test -u 之后,文件被自动更新为:

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

test {
  inspect(add(1, 2), ~content="3")?
}

test {
  (add(3, 4) |> inspect(~content="7"))?
}

2.编译器内置函数迁移到标准库

把原本的在编译器内部的一些基础的 MoonBit 定义迁移到了标准库中。在线IDE上也可以使用标准库了

3. 支持 alert pragam

MoonBit 现在支持在顶层的文档注释中书写多个 pragam。所有的 pragam 以@开头,并且独占一行。

Untitled

目前支持函数和方法的 alert pragma,当被标记了 alert 的函数和方法被使用时会产生警告。这个机制可以用来标记已经弃用或者不安全的函数。alert pragma 的格式为@alert id "explain string",其中id可以是任意的标识符。

Untitled

4. 支持在 pragma 中标注 intrinsic

比如标准库中的如下代码在被标注 intrinsic 之后,在 JavaScript 后端会使用 String(..) 函数来将浮点数转化为字符串,后续会加入更多函数的 intrinsic 支持。

/// @intrinsic %f64.to_string
pub fn to_string(self : Double) -> String {
  double_to_string(self)
}

5. 生成代码性能和体积的改进

  • 引入了消除局部 alias 的优化,从而避免生成无用的局部变量
  • 引入了常量传播的优化
  • 优化了生成的 wasm 代码中类型声明的部分,减少了冗余的类型声明

https://picx.zhimg.com/80/v2-18712f8e289e2548fdafcd3775aa060e_1440w.jpg?source=d16d100b

6. moonfmt 改进

  • 调整 function for loop 的打印格式,特殊情况不再打印分号
  • 针对 if/match 这种可读性差的嵌套的情况,格式化后加上额外的括号。格式化前和格式化后的效果:

格式化前:

Untitled

格式化后:

Untitled

7. 改进模式匹配完备性检查

8. 调整字符串的编码为UTF-16

构建系统更新

moon.pkg.json 中支持自定义函数导出名称

moon.pkg.json 中支持使用 ["link"][BACKEND]["exports] 字段自定义函数导出名称,并且默认不再导出所有的 pub 函数,必须要在 exports 中显式指定。此外,现在支持通过设置 link 字段链接非 main 包。

例如使用 moon new hello 创建一个新项目,其目录结构为:

.
├── README.md
├── lib
│   ├── hello.mbt
│   ├── hello_test.mbt
│   └── moon.pkg.json
├── main
│   ├── main.mbt
│   └── moon.pkg.json
└── moon.mod.json

在过去,执行 moon build,只有 main 包会生成 wasm 文件。

现在,在 moon.pkg.json 中支持 link 字段,可以对非 main 包生成 wasm 文件。link 字段的内容可以是一个布尔值:

{
  "link": true // 表示当前包需要被链接
}

或者是一个对象,可以给不同的后端如 wasm 或者 wasm-gc ,设定链接选项。目前只支持 exports 选项,exports 是一个字符串数组,包含需要导出的函数及其需要导出的名称:

{
  "link": {
    "wasm": {
      "exports": [
        "hello" // 这里将函数 hello 导出为 hello,
      ]
    },
    "wasm-gc": {
      "exports": [
        "hello:hello_wasm_gc" // 这里将函数 hello 导出为 hello_wasm_gc
      ]
    }
  }
}

如果将 lib/moon.pkg.json 中的内容修改为:

{
  "link": {
    "wasm": {
      "exports": [
        "hello"
      ]
    }
  }
}

然后执行 moon build --output-wat,可以观察到输出的 target/wasm/release/build/lib/lib.wat 中包含如下内容:

(func $$username/hello/lib.hello.fn/1 (export "hello") (result i32)
 (i32.const 10000))

其中的 (export "hello") 表示配置生效了。

IDE 更新

vscode 插件支持安装或更新 MoonBit工具链。

Untitled

weekly 2024-03-25

· 阅读需 2 分钟

构建系统更新

1. 支持 expect testing

a. 使用 moon new 新建一个 MoonBit 项目。

b. 在 lib/hello.mbt中写入:

pub fn hello() -> String {
  "Hello, world!"
}

test {
  let buf = Buffer::make(10)
  buf.write_string(hello())
  buf.expect()?
}

c. 然后运行 moon test --update或者 moon test -u:

$ moon test --update
expect test failed at lib/hello.mbt:8:3-8:15
Diff:
----
Hello, world!
----

Total tests: 1, passed: 0, failed: 1.

Auto updating expect tests and retesting ...

Total tests: 1, passed: 1, failed: 0.

d. 再次打开 lib/hello.mbt 文件,可以看到已经将测试结果 promote 到源码中。

pub fn hello() -> String {
  "Hello, world!"
}

test {
  let buf = Buffer::make(10)
  buf.write_string(hello())
  buf.expect(~content="Hello, world!")?
  //         ^~~~~~~~~~~~~~~~~~~~~~~~ 测试结果更新
}

2. moon run 不再支持 --output-wat选项。

MoonBit 更新

1. 支持多参数构造器的后端代码生成

支持多参数构造器(multi-argument constructor)的后端代码生成。现在构造一个泛型类型的值的时候,如果泛型参数为元组的话必须要写括号,即:

enum A[X] {
  A(X)
}

fn init {
  // Error, expecting 1 arg, getting 2
  A::A(1, 2) |> ignore

  // Ok
  A::A((1, 2)) |> ignore
}

多参数构造器 unbox 了参数,能够提高生成的代码的性能,也允许程序员对数据的内存布局有了更多的掌控。

2. 调整了Int64的lsl, lsr, asr方法

现在移位参数不再是Int64,而是Int。同时调整了clz, ctz, popcnt方法,现在返回类型不再是Int64,而是Int。此项改变有助于我们在不支持原生Int64的平台上生成更高效的代码。

IDE 更新

1. 支持带标签参数的重命名。

2. VSCode 插件支持自动安装或者更新 MoonBit

a. 更新插件后,如果没有安装 moon 或者 moon 不是最新的时候,VSCode 右下角弹出自动安装/升级的提示。

Untitled

b. 点击 "yes", 来执行自动安装任务。任务完成后就可以用了。

Untitled

weekly 2024-03-18

· 阅读需 2 分钟

语言更新

1. 实验性地添加对 trait 实现默认方法的功能

trait MyShow {
  repr(Self) -> String
  str (Self) -> String // it has a default implementation
}

impl MyShow::str(self : Self) -> String {
  // default implementation of str
  self.repr()
}

type MyInt Int
fn repr(self:MyInt) -> String {
  self.0.to_string()
}
// Now MyInt implements MyShow now

2. 允许类型定义的类型参数为 _

_可以用来定义 phantom type,来限制一些程序逻辑上非法的操作。例如我们希望不同单位的长度不能够相加:

type Length[_] Int

type Kilometer
type Mile

fn add[T](x: Length[T], y:Length[T]) -> Length[T] {
  Length::Length(x.0 + y.0)
}

let d_km: Length[Kilometer] = Length(10)
let d_mile: Length[Mile] = Length(16)

此时,两个单位不同的长度并不能够直接相加:

fn init {
  add(d_km, d_mile) |> ignore
  //        ^~~~~~ Error: Expr Type Mismatch
}

而两个单位相同的长度可以相加:

fn init {
  add(d_km, d_km) |> ignore
  // OK
}

3. 现在 Toplevel 函数没有标记返回值的行为改成报错

Toplevel 函数没有标记返回值的行为从之前的默认设置为 Unit 改成报错。

fn print_hello() {
// ^~~~~~~~~~~ Error:
// Missing type annotation for the return value.
  println("Hello!")
}

4. 添加了按位取反的操作符

fn main {
  println((1).lnot())
}

输出:

-2

5. 改进 List::to_string/debug_write 的输出

fn main {
  let l = List::Cons(1, Cons(2, Cons(3, Nil)))
  println(l)
}

输出:

List::[1, 2, 3]

6. 添加了 Byte 类型

byte 字面量由 b 作为前缀,使用方式如下:

fn init {
  let b1 = b'a'
  println(b1.to_int())
  let b2 = b'\xff'
  println(b2.to_int())
}

更多关于 Byte 的功能还在完善中

IDE更新

1.支持对 moonbitlang/core 的补全

2. 格式化的更新和修复:

  • 调整空的 struct、enum、trait,避免出现空行。

之前:

struct A {

}

之后:

struct A {}
  • 修复 continue 的错误缩进。
  • 修复多行语句格式化后出现分号的问题。

构建系统更新

1. moon.mod.json 添加了 test_import 字段

test_import这个字段中用到的依赖只会在测试的时候被用到。

2. 优化 moon test 输出

默认只输出失败的测试用例信息,如果需要完整输出可使用moon test -v命令。

weekly 2024-03-11

· 阅读需 4 分钟

01 MoonBit 更新

1. moonbitlang/core 开源

moonbitlang/core(MoonBit标准库)现已开源。我们很高兴收到社区的积极反馈,想了解更多与moonbitlang/core开源的详情,可点击这里查看:国人自主研发的编程语言 MoonBit Core 开源啦!

Github链接:

https://github.com/moonbitlang/core

2. 支持带标签/可选参数

支持带标签参数(labelled argument)和可选参数(optional argument)。带标签参数有助于区分相同类型,不同功能的函数:

fn greeting(~name: String, ~location: String) {
  println("Hi, \\(name) from \\(location)!")
}

fn init {
  greeting(~name="somebody", ~location="some city")
  let name = "someone else"
  let location = "another city"
  greeting(~name, ~location)// `~label=label` 可以简写成 `~label`
}

可选参数必须带标签,并且指定默认值。在函数调用的时候,如果没有手动指定参数,则取默认值。注意:默认值在每次调用的时候都会被重新求值:

fn greeting(~name: String, ~location: Option[String] = None) {
  match location {
    Some(location) => println("Hi, \\(name)!")
    None => println("Hi, \\(name) from \\(location)!")
  }
}

fn init {
  greeting(~name="A")// Hi, A!
  greeting(~name="B", ~location=Some("X")// Hi, B from X!
}

3. 提供了内建类型 SourceLoc

SourceLoc,表示源码中的位置。假如某个函数声明了一个类型为 SourceLoc、默认值为 _ 的可选参数,那么每次调用这个函数时,MoonBit 会自动插入调用处的位置作为这个参数的默认值:

fn f(~loc : SourceLoc = _) {
  println("called at \\(loc)")
}

fn g(~loc : SourceLoc = _) {
  f()// 显示 `g` 内部的位置
  f(~loc)// 自动注入的参数也可以手动覆盖。这一次调用会显示 `g` 的调用者的位置
}

test "source loc" {
  g()
}

try.moonbitlang.cn 新建一个名为 test.mbt 的文件,放入上述代码,并运行代码中的测试,可以得到如下的输出:

test source loc ...
called at memfs:/sample-folder/test.mbt:6:3-6:6
called at memfs:/sample-folder/test.mbt:11:3-11:6

SourceLoc 可以用于编写测试相关的函数,用于在测试失败时输出有用的位置信息:

fn assert_eq[X: Eq + Show](result: X, expect: X, ~loc : SourceLoc = _) -> Result[Unit, String] {
  if (result == expect) {
    Ok(())
  } else {
    Err("\\(loc): Assertion failed: \\(result) != \\(expect)")
  }
}

test "1 =? 2" {
  assert_eq(1, 2)?
}
running 1 tests
test 1 =? 2 ... FAILED memfs:/sample-folder/test.mbt:10:3-10:18: Assertion failed: 1 != 2

test result: 0 passed; 1 failed

4. === 已经弃用,可以使用 physical_equal 作为代替

5. 添加新的内置类型 UnsafeMaybeUninit[T]

添加新的内置类型 UnsafeMaybeUninit[T] 和对于该类型的一些相关操作,用以在 MoonBit Core 中实现 Vector 等数据结构,因为其不安全性,普通的 MoonBit 程序中应尽可能避免使用该类型。

02构建系统更新

1. 支持 JavaScript 后端

可以通过 --target js 来生成后端代码。例如:

a. 通过 moon new hello 新建一个名为 hello 的项目

b. 在 main/main.mbt 中写入:

fn main {
  println("Hello from JavaScript!")
}

c. 在命令行中构建生成 JavaScript 代码,并使用 Node 运行。

$ moon build --target js
moon: ran 2 tasks, now up to date
$ node target/js/release/build/main/main.js
Hello from JavaScript!

d. 你也可以方便地通过 moon run main --target js 来编译并运行编译到 JavaScript 的 MoonBit 代码。

$ moon run main --target js
Hello from JavaScript!

2. 修复了一些 moonbuild 的问题

a. 修复了 Windows 上 moon upgrade 失败的问题。

b. 修复了 moon add 添加新版本没有移除旧版本的问题。

c. 修复了本地 moon check 失败仍然能够 publish 的问题。

IDE更新

1. 线上 IDE 支持通过 CodeLens 的方式运行测试

ide更新|306x168

2. 大幅度改善 moonfmt 的对于包含注释的源代码的处理。

3. 提升 IDE 和 VSCode 插件的稳定性和用户体验

a. VSCode插件现在是在文件更改的时候调用moon check而非启动moon check -w

b. 提升了多行字符串和文档注释(docstring)的输入体验。现在在多行字符串/文档注释内部换行会自动补上 #| 或者 /// 的前缀。

c. 修复了 hover、moon.pkg.json 出错,空文件等导致 lsp 报错的问题。

工具链更新

Markdown linter 支持 expr 标签

举个例子:

```moonbit expr
1 * 2 + 3

可以在运行 mdlint 的时候看到对应的输出:

5

weekly 2024-03-04

· 阅读需 4 分钟

一、MoonBit更新

1. 添加了 += 系列语句

包括+=、-=、*=、/=,支持运算符重载:

fn init {
  let array = [1,2,3,4]
  array[2] *= 10
  println(array) // [1, 2, 30, 4]
}

fn init {
  let mut a = 1
  a += 20
  println(a) // 21
}
struct Foo {
  data : Array[Int]
} derive(Debug)

fn op_set(self : Foo, index : Int, value : Int) {
  self.data[index] = value
}

fn op_get(self : Foo, index : Int) -> Int {
  self.data[index]
}

fn init {
  let foo : Foo = { data: [0,0,0,0] }
  foo[2] -= 10
  debug(foo) // {data: [0, 0, -10, 0]}
}

2. 现在 toplevel 如果没有顶格会报错

如下图所示:

image|690x204

3. 引入 super-trait 机制

Super-trait 通过如下的语法指定:

trait A {
  // ...
}

trait B : A { // A is a super trait of B, B is a sub trait of A
  // ...
}

可以通过 + 来指定多个 Super-trait,表示该 sub-trait 依赖这几个 super-trait:

// ...

trait B: A + Compare + Debug {
  //       ^~~ B is a sub-trait of A *and* Compare *and* Debug
  // ...
}

在使用上,可以将 sub-trait 当作 super trait 使用,但是不能够将 super-trait 当作 sub-trait 使用。目前Compare是Eq的 sub-trait,意味着实现了Compare的类型能够在要求Eq的情况下使用,所以以这两个代码为例:

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

trait Compare: Eq {
  compare(Self, Self) -> Int
}

fn eq[X: Compare](this: X, that: X) -> Bool {
  this == that
}
fn compare[X: Eq](this: X, that: X) -> Int {
  this.compare(that)
  //   ^~~~~~~ Type X has no method compare.
}

4. 添加T::[x, y, ...]的语法

这种语法结构会被解糖成T::from_array([x, y, ...])的形式。这种语法使得列表等线性数据结构的初始化更加易读。

enum List[X] {
  Nil
  Cons(X, List[X])
} derive(Show, Debug)

fn List::from_array[X](array: Array[X]) -> List[X] {
  let mut list = List::Nil
  for i = array.length() - 1; i >= 0; i = i - 1 {
    list = Cons(array[i], list)
  }
  list
}

fn main {
  println(List::[1, 2, 3])
}

输出:

Cons(1, Cons(2, Cons(3, Nil)))

5. 调整自动生成的 Show 的实现的逻辑

现在它会调用 Debug 作为实现。这意味着,现在 derive(Show) 之前需要先 derive 或自行实现 Debug。Debug 的输出是 MoonBit 语法下合法的值,而 Show 可以用于输出更美观的内容。这修复了之前 derive(Show) 在有 String 的结构体上的错误行为:

struct T {
  x: String
} derive(Show, Debug)

fn init {
  println({ x: "1, y: 2" })
  // 之前: {x: 1, y: 2}
  // 现在: {x: "1, y: 2"}
}

6. 目前已不支持fn hello() = "xx"的语法

fn hello() = "xx"的语法目前已经不适用了。我们建议用户这样写:

extern "wasm" fn hello () =
  #| ...

现在 inline stubs 只支持 wasmgc,不支持 wasm1。

7. 现在丢弃非 Unit 的值会直接报错,如果需要丢弃需要显式使用 ignore。

fn f() -> Int {
  ignore(3)   // Ok.
  3 |> ignore // Ok.
  3           // Err: Expr Type Mismatch: has type Int, wanted Unit
  3           // Ok, as this value is returned, not dropped
}

8. 移除了test作为标识符使用的支持

二、IDE更新

1. 提供更好的线上 IDE Markdown 支持

  • 可以在线上 IDE 中使用 Marp 插件来查看之前现代编程思想课的内容了。

image|690x481

  • Markdown 中内嵌的 MoonBit 的代码块支持语法高亮。

image|690x475

  • 针对内嵌有 MoonBit 代码的 Markdown 文本开发了语法检查的程序,开源在:GitHub链接。使用方法可以参考项目的 README。

三、构建系统更新

1. 添加 main 函数的支持

  • main只能写在main包(is_main: true的包)里
  • main 包中应当有且仅有一个main 函数
  • main函数的执行顺序在所有init函数之后
  • main包中不能有test

2. 目前可以通过 moon upgrade 升级 MoonBit 工具链的版本了。

p.s. 但是在使用之前,必须再用安装脚本安装一次:-)

3. moon check|build|run 现在默认链接到 moonbitlang/core。

weekly 2024-02-26

· 阅读需 3 分钟

MoonBit 更新

1. 支持云原生调试功能

现在,你可以通过访问 try.moonbitlang.cn,直接在浏览器中使用 devtools 调试 MoonBit 程序,无需安装任何软件。具体的使用步骤如下:

2. MoonBit 支持使用 for 关键字定义的函数式循环控制流

MoonBit 现在支持使用 for 关键字定义的函数式循环控制流,其性能接近于 C/C++ 等底层语言,比如 fib 函数可以写成如下形式:

fn fib( n : Int ) -> Int {
    for i = 0, a = 1, b = 2
        i < n
        i = i + 1, a = b, b = a + b {
    } else { b }
}

MoonBit 的 for 循环可以作为表达式返回一个值,比如上述程序中在循环结束后使用 b 作为整个 for 循环的值,也可以在 for 的循环体中通过 break 提前返回,比如:

fn exists(haystack: Array[Int], needle: Int) -> Bool {
  for i = 0; i < haystack.length(); i = i + 1 {
    if haystack[i] == needle {
      break true
    }
  } else {
    false
  }
}

此外,在 for 循环中可以像传统语言一样使用 continue 进入下一次循环,MoonBit 额外提供了带参数的 continue 来指定下一次循环过程中循环变量的值,比如:

fn find_in_sorted[T](xs: Array[(Int, T)], i: Int) -> Option[T] {
  for l = 0, r = xs.length() - 1; l < r; {
    let mid = (l + r) / 2
    let k = xs[mid].0
    if k == i {
      break Some(xs[mid].1)
    } else if k > i {
      continue l, mid
    } else {
      continue mid + 1, r
    }
  } else {
    None
  }
}

在不需要返回值的情况下,else 分支可以省略,比如:

fn print_from_0_to(n: Int) {
  for i = 0; i <= n; i = i + 1 {
    println(i)
  }
}

3. Inline test 改进

测试的返回类型从Unit改成了Result[Unit,String],用于表示测试的结果:

 test "id" {
      if (id(10) != 10) { return Err("The implementation of `id` is incorrect.") }
    }

编译器会自动将test "id" {...} 的语句块{...}使用Ok()包裹起来。因此,当语句块的类型为Unit并且没有提前return时,表示inline test测试通过。配合问号操作符,可以让测试变得更加优雅:

fn id(x : Int) -> Int {
     x + 1 // incorrect result
   }

   fn assert(x : Bool, failReason : String) -> Result[Unit,String] {
     if x { Ok(()) } else { Err(failReason) }
   }

   test "id" {
     assert(id(10) == 10, "The implementation of `id` is incorrect.")?
   }

执行moon test,输出如下:

my-project moon test
running 1 tests in package username/hello/lib
test username/hello/lib::hello ... ok

test result: 1 passed; 0 failed

running 1 tests in package username/hello/main
test username/hello/main::id ... FAILED: The implementation of `id` is incorrect.

test result: 0 passed; 1 failed

Hello, world!

4. 改进 VS Code 插件的函数签名提示,现在会显示参数名:

5. 改进了 VS Code 插件对 core 包开发的支持

6. moon new 支持快速创建新项目

  • moon new hello 在文件夹 hello 中创建一个名为 username/hello 的可执行项目
  • moon new hello --lib 在文件夹 hello 中创建一个名为 username/hello 的模块

weekly 2024-02-19

· 阅读需 2 分钟

MoonBit更新

1. 增加了functional for loop控制流支持

与传统的命令式for loop 不同,循环变量是不可变的。这样的设计将来也容易抽取出来做形式化验证:

fn init {
  for i = 0; i < 5; i = i + 1 {
    debug(i)
    // i = i + 4  error: The variable i is not mutable.
  }
}

输出:

01234

functional for loop也支持多个绑定。与其他语言不同的是,x和y在functional for loop的第三个表达式里具有同时更新的语义:

fn init {
  for x = 0, y = 0; x < 10; x = x + 1, y = x + 1 {
                                        // ^~~ 这里x的值是更新前的
    println("x: \(x), y: \(y)")
  }
}

输出:

x: 0, y: 0
x: 1, y: 1
x: 2, y: 2
x: 3, y: 3
x: 4, y: 4
x: 5, y: 5
x: 6, y: 6
x: 7, y: 7
x: 8, y: 8
x: 9, y: 9

functional for loop内部也支持使用breakcontinue

fn init {
  let xs = [0,1,2,3,4,5,6,7,8]
  let mut sum = 0
  for i = 0, v = xs[0]; i < xs.length(); i = i + 1, v = xs[i + 1] {
    if v % 2 == 0 { continue }
    if v >= 7 { break }
    sum = sum + v
  }
  debug(sum) //output: 9
}

2. 改进moon new创建项目的向导

现在可以用方向键选择创建lib或者exec项目:

3. IDE支持管道运算符的智能补全

对于第一个参数类型与管道左侧表达式类型相等的函数,会放在补全列表的顶部,其它的补全选项仍然会显示在列表后。

4. 根据社区反馈调整了pipe表达式

现在管道运算符右侧支持Double::to_int这样的函数调用。

fn init {
  debug(3.14 |> Double::to_int) // output: 3
  debug(4 |> Array::make('c')) // output: ['c', 'c', 'c', 'c']
}

5. 修复IDE中缀表达式错误地插入inlay hint的问题

weekly 2024-02-05

· 阅读需 2 分钟

MoonBit 更新

1. 新增多行字符串支持

每行需要以#|开头。多行字符串每行之间允许断开、插入注释,字符串内不支持转义和字符串插值。

2. 新增函数式的loop循环

其中continue 只允许出现在尾递归调用的位置,loop内允许使用break提前返回一个值。

3. 提供Trait::method调用支持

支持以Debug::debug_write(self, buf)的形式调用trait method

4. 添加实验性标准库机制

最新的安装脚本会将标准库下载到 ~/.moon/lib/core 目录下。目前标准库的内容以及相关IDE支持暂不稳定,因此构建系统默认不链接标准库。对于想要提前体验标准库功能的开发者们,可以在 moon check|build|run|test 命令后添加 --std 选项用于链接标准库到当前项目。

5. 支持隐式到trait object的转换

在上下文中明确需要一个trait object时,会自动插入 as SomeTrait。例如下面的代码:

现在我们可以省略as Debug

6. 支持函数参数的inlay hint

7. 字符串和char字面量支持unicode转义、十六进制转义和八进制转义