DSL 的特殊性
2008 年 12 月 22 日
撰寫關於外部 特定領域語言 的棘手之處之一,在於我正在踏入程式語言社群已經深入探索過的領域。程式語言研究一直是學術活動中熱門的領域,而我必須承認,我在這個主題上的深度遠不及在這個領域研究多年的許多人。因此,難免會有人提出疑問,像我這樣的菜鳥憑什麼認為自己可以在這個眾人踏過的領域寫書?
最主要的原因是,沒有其他人寫過一本以實務為導向的 DSL 書籍。我喜歡像這樣眾人踏過但鮮少有人寫得好的主題。然而,在我花時間探索這些途徑時,我認為還有另一個因素在起作用。
關於程式語言的研究很多,但幾乎所有研究都集中在通用程式語言上。DSL 被視為通用程式語言思維的一個小而簡單的子集。因此,人們認為通用語言適用的規則也適用於 DSL(暗示 DSL 太小,不值得多加思考)。
我越來越持相反的結論。DSL 的規則與通用語言的規則不同,而且這適用於多個面向。
首先在語言設計上。我曾與一位我非常敬重的語言設計師交談,他強調語言的一項關鍵功能是定義新抽象的能力。我不認為這適用於 DSL。在大部分 DSL 中,DSL 會選擇您使用的抽象,如果您想要不同的抽象,則可以使用不同的 DSL(或可能擴充您正在使用的 DSL)。有時需要新的抽象,但這些情況是少數,而且當它們發生時,抽象是有限的。我確實認為無法定義新抽象是區分 DSL 和通用語言的因素之一。
在實作與語言搭配的工具時,所採用的方法也會有所不同。通用語言的持續問題是處理大型輸入,因為實際的程式會有數千或數百萬行程式碼。因此,許多工具和技術會涉及讓解析更難以遵循,但支援這些大型輸入的層面。DSL 腳本往往小很多,因此這些權衡會以不同的方式運作。
在我的工作中,我非常重視使用 DSL 來填入語意模型,並使用該模型作為任何進一步處理的基礎:詮釋、視覺化或產生程式碼。我所看過的大量語言撰寫往往強調產生程式碼,通常直接從語法檔案產生程式碼。很少討論中間表示,而當它們出現時,它們更像是抽象語法樹,而不是語意模型。嚴謹的編譯器確實會使用中間表示,例如程式依賴性圖,但這些被視為(正確地)進階主題。我認為語意模型是簡化 DSL 使用的真正有價值的工具,讓您可以將解析與語意分開。
由於 DSL 的表達力較低,您可以為它們設計更簡單的語言。語言社群的許多文章都在討論如何處理複雜通用語言的難題,而 DSL 的挑戰在於撰寫一種可讀性高的語言,供目標受眾(可能包括非程式設計師)使用,而且也應該容易解析(以簡化解析器的維護)。這不僅會導致語言設計的不同決策,也表示您實際上只需要解析器產生器的功能子集。
這導致的結果是 DSL 的撰寫預期每個個別 DSL 都無法解決手邊的整個問題,而且您經常需要結合 DSL。傳統的語言思考並未探索可組合語言的概念,但我認為隨著 DSL 的發展,這個主題非常重要。思考可組合語言應該對語言設計和語言工具產生重大影響。
因此我越來越傾向於認為,DSL 啟發了我們一些思考程式語言的截然不同的方式。它也可能導致開發出更適合 DSL 工作的不同類型的剖析工具 - 通常是更簡單的工具。我希望現今 DSL 獲得的關注度提升,將導致更多人將 DSL 視為一級研究主題,而非一般用途語言的簡化形式。