是否考虑一下 Swift 的 implicit member expression

对应 swift 当中的文档 Documentation

其他例子 Using dot syntax for static properties and initializers | Swift by Sundell

Swift 中的案例

最近在 Swift 中使用标签参数比较多, 跟 MoonBit 做一下参考, 觉得这个功能挺方便的, 特别集中在数据结构初始化的场景,

比如:

public extension RepeatMode {
    static var never: RepeatMode {
        return .times(0) // <--- 这里 times 方法根据上下文推断得到所属类型, 于是可以省略类型
    }
    static var once: RepeatMode {
        return .times(1) 
    }
}

另一个例子,

rootEntity.components.set(
  CollisionComponent(
    shapes: [
      .generateBox( // <- 这里 shapes 成员类型为 [ShapeResource],
                    //   数组内通过推断获得 ShapeResource.generateBox 静态方法
        width: bounds.extents.x * 4,
        height: bounds.extents.y * 4,
        depth: bounds.extents.z * 4)
    ]
  )
)

这个例子中 Implicit Member Expression 跟标签函数一起用, 就显得更加灵活,

extension ImageFilter {
    static var dramatic: Self {
        ImageFilter(
            name: "Dramatic",
            icon: .drama,
            transforms: [
                .portrait(withZoomMultipler: 2.1), // <-- 这里
                .contrastBoost,
                .grayScale(withBrightness: .dark)
            ]
        )
    }
}

或者搭配标签参数创建颜色,

UIColor(
    red:.random(in: 0...1),
    green: .random(in: 0...1),
    blue: .random(in: 0...1),
    alpha: 1
)

MoonBit 中假想案例

对应到 MoonBit 比如在定义 CSS 样式的时候(这个我遇到比较多), 在 style 的位置推断到类型是 CSSProperties,

div(style= ... , [])

那么 .init() 方法配合标签参数就可以简写或者说通过 . 打开补全菜单直接找到初始化的方法, 从而减少手动引入额外一个方法来提供 labelled arguments,

div(style=.init(color="red", font_size=13) , [])

这个写法可以用在更多可以推断类型的场景, 比如, 变量初始化,

let xs: Array[string] = .with_capacity(8)
let ys: @list.T[Int] = .from_array([1,2,3,4])

比如 Option 类型的数据,

fn display(x: Option[String]) { ... }

display(.some("demo"))

// 这个写法可能体现不出优势
// display(Some("demo"))

总体上说, 对于 UI 这一类需要撰写嵌套的 DSL, 反复初始化多种结构, 配置参数, 的场景, 我觉得帮助会比较明显. 特别是类似 Swift 这样 IDE 中使用 . 开始打开菜单就能探索方法的场景.

另外, 这个写法应该有一些限制, 要求推断上下文得到的类型比如 S, 跟调用的方法返回的类型, 应该是一致的, 也就是 Self, 因此可以作为 initializer 而简写,

fn S::f(a: A, b: B) -> Self { ... }

我觉得这个功能现在已有的 enum contructor 自动推断也是不错的补充, enum constructor 已经很灵活但传递的参数直接用于构造类型, 可以用这个语法封装逻辑来做更复杂的初始化功能.