不少人看到這樣的示例代碼,覺得是什麼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) }
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定義在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的術語,但指的是編譯插件。例如正則表達式和SQL這種叫作DSL。正則表達式的DSL長這樣
reg := Regex<|\(.*\)|>
這是一個編譯器插件,可作內嵌語言的語法錯誤檢測、IDE語法高亮。DSL中能夠有任何字符,免去了字符串內部字符須要轉意的麻煩。
更多關於Fanx的信息見: