Fanx的閉包不是DSL

不少人看到這樣的示例代碼,覺得是什麼DSL。正則表達式

using vaseGui

class HelloTest
{
  static Void main() {
    root := Frame {
      VBox {
          Label { text = "HelloWorld" },
          Button {
            text = "Press Me"
            onClick {
              Toast("Hello World").show(it)
            }
          },
      },
    }
    root.show
  }
}

事實上這不是DSL,而是標準的Fanx代碼。編程

Fanx語言中寫出上面的代碼,使用了幾個重要的技術:It塊、尾綴閉包、with塊、逗號操做符。這裏的設計很是巧妙。比Kotlin用更少的複雜性和更少的代碼,實現了相似的功能。閉包

尾綴閉包

正常的Fanx閉包/lambda是這樣的:編程語言

10.times( |Int x| { echo(x) } )

咱們在函數最後一個參數爲閉包時省略調圓括號,叫作尾綴閉包。寫成這樣:函數

10.times |Int x| { echo(x) }

It塊

10.times |Int x->Void| { echo(x) }

當閉包參數少於一個時,咱們省略函數參數,使用時用it關鍵字代替。變成了這樣:ui

10.times { echo(it) }

逗號操做符

咱們的運算符重載大概是這樣的語法糖this

a + b       =>    a.plus(b)

加號均可以是運算符,逗號也相似。不過逗號運算符被設計爲須要和It塊配合。插件

a,b,c       =>    it.add(a).add(b).add(c)

With塊

全部對象都有一個with方法。with定義在Obj中,Obj.with像這樣:設計

virtual This with(|This| f)
{
  f(this)
  return this
}

使用with函數像這樣code

list := [,].with { fill("x", 3)

咱們能夠省略with名稱,寫出這樣:

list := [,] { fill("x", 3) }

揭曉謎底

VBox {
  Label { .. },
  Button { .. },
}

這樣的代碼大概至關於

VBox().with( |VBox v| {
  v.add( Label().with( |Label a| {
    ...  
  }))
  v.add( Button().with( |Button b| {
    ... 
  }))
})

可見編程語言對可讀性的改善的重要性。

Fanx中的DSL

Fanx中也有DSL的術語,但指的是編譯插件。例如正則表達式和SQL這種叫作DSL。正則表達式的DSL長這樣

reg := Regex<|\(.*\)|>

這是一個編譯器插件,可作內嵌語言的語法錯誤檢測、IDE語法高亮。DSL中能夠有任何字符,免去了字符串內部字符須要轉意的麻煩。

更多關於Fanx的信息見:

相關文章
相關標籤/搜索