我試圖感受到Lisp的部分,我至今還沒有使用過。讀宏已經引起了我的注意。關於他們的使用沒有大量的信息,這將有助於瞭解人們與他們做了什麼,既可以瞭解他們如何工作的例子,也可以看到他們可以接觸哪些問題。在此之後,是否有任何準則來了解什麼構成讀取宏的好壞使用?閱讀宏:你用它們做什麼?
回答
S表達式是Lisp數據的Lisp語法。使用READ函數讀取S表達式,讀取宏是Lisp內置的擴展閱讀器的方式。這意味着讀取宏的最直接使用是實現預定義的數據語法,並且可以改變或擴展Lisp讀取s表達式的方式。
Lisp爲許多數據類型提供了預定義的外部語法:符號,數字,字符串,數組,字符,列表,列表,結構等等。它允許打印和讀回數據對象。
Lisp缺少其他幾種數據類型的語法 - 突出顯示的散列表和CLOS對象。因此,在用戶代碼中首次使用讀取宏將擴展閱讀器以便能夠讀取散列表,並行向量,新數字類型等數據結構...基本上每個數據類型的開發人員都希望有一個可以回讀的外部語法。
由於Lisp也將s表達式用於代碼,讀取宏的第二次使用是擴展Lisp程序的表示法。一個典型的例子是使用[和]編寫嵌入式SQL代碼。通常的Lisp語法看起來很相似,但[和]的使用有助於SQL表達式在代碼中脫穎而出。另一個例子是使用讀取宏爲嵌入式編程語言提供標識符,如Objective C常量,消息等.Clozure CL使用它來表示區分大小寫的情況下保留標識符,並在讀取時使用索引來查找它們的定義外部可用的標識符。
第三個用法是將不同的語法嵌入到Lisp語法中。一個古老的例子是中綴讀宏,它允許嵌入中綴表達式。其他示例是嵌入式HTML或XML語法,或其他編程語言語法的嵌入式片段。
有時,讀取宏用於實現其他(相關)語言,這些語言使用與預定義的Common Lisp語法不同的s-expression語法。一個例子是Scheme s-expressions的讀者,它與Common Lisp略有不同。
雖然我使用了很多宏,但我從來沒有發現需要使用讀宏,除了偶然的實驗。如果有幫助,在「Let Over Lambda」上,您會發現關於它們的廣泛討論:http://letoverlambda.com/index.cl/toc
我實際上傾向於爲我的普通Lisp代碼避開它們;最近,我甚至因爲使用讀取器宏而發現拒絕第三方庫。這主要是由於這樣一個事實:與符號不同,讀者宏只有一個「命名空間」。在選擇合適的調度角色時,我似乎常常不同意圖書館的作者對他們品味的看法。
但是,我使用定製的非標準閱讀表+ 閱讀成功進行簡單的解析任務。到目前爲止我使用自定義的可讀取的實現的最複雜的解析器是HTML模板引擎(又一個抱歉),其語法類似於JSP/ASP,但使用Common Lisp作爲實際模板語言,因此您可以使用就像
<% (for (title . link) in breadcrumb do %><a href="<%= link %>"><%= title %></a><%) %>
(雖然代碼不得不經過預處理階段,但是沒有單獨使用可讀取的黑客來完成)。
閱讀器宏用於存在您可能想要的文字對象的語法。他們遇到的唯一問題是可能的語法的平面命名空間(但是,有辦法解決這個問題)。 閱讀器宏沒有太多的用法。浮現在我的腦海裏是一些例子:
- http://weitz.de/cl-interpol/ - 字符串插值和擴展字符串符號
- http://trac.clozure.com/openmcl/wiki/OpenMclFfi語法 - 從C語言(FFI的自動形式)
- http://clsql.b9.com/manual/sql.html進口符號的語法 - 對SQL查詢語法 - 不是非常有用
- http://www.agentsheets.com/lisp/XMLisp/ - 文字XML片段嵌入到Lisp代碼
可以嵌入讀取宏的一種特別常見且有用的替代語法是regex語法。實現它並不難,因爲它只是讀取具有不同轉義規則的字符串,但如果您經常使用正則表達式,則它可以真正付清。 dmitry-vk提到的CL-INTERPOL庫提供了該功能,以及批號的其他功能。
我在Github上有兩個小項目,它們展示了在Common Lisp中如何以及爲什麼要使用閱讀器宏。這些是SHELLSHOCK和BOXEN。正如其他答案中提到的,CL-INTERPOL是一個非常有用的例子。
是否這些都是不錯閱讀器宏的使用顯然是主觀的,但肯定我必須認爲它們很有用,否則我不會寫代碼!
- 1. 你用Scheme Scheme宏做了些什麼?
- 2. UDP和TCP數據包有什麼區別?你用它們做什麼?
- 3. 你無法用Angular.js做什麼,你可以用jQuery做什麼
- 4. 什麼是斷言?你爲什麼要使用它們?
- 5. 你能用System.DirectoryServices.Protocols.ExtendedRequest做什麼?
- 6. 你用Object.clone()做了什麼?
- 7. 這些宏做什麼(LLVM)?
- 8. 宏在MASM32中做什麼?
- 9. 如果你不用Java進行克隆,那麼你做什麼,你叫什麼?
- 10. 屏幕閱讀器使用省略號unicode字符做什麼?
- 11. 什麼是資源,瞭解選擇器模式意味着什麼,在什麼方向閱讀它們?
- 12. Clojure沒有共同的Lisp閱讀器宏有什麼優勢?
- 13. HttpWebRequest.UserAgent:它做什麼
- 14. 爲什麼Jekyll會閱讀我的文章,但沒有編寫它們?
- 15. 球拍閱讀器宏
- 16. 你使用Apache Kafka做什麼?
- 17. 你使用Android Terminal Emulator做什麼?
- 18. 你用什麼工具做burndown圖表?
- 19. 你可以用AppleScript做什麼?
- 20. 爲什麼使用讀者宏#'?
- 21. 爲什麼你可以閱讀但不能修改全局值?
- 22. 你叫什麼以及如何閱讀? (解析方案)
- 23. 什麼數學你需要閱讀計算機編程藝術?
- 24. 像_GNU_SOURCE這樣的宏,它們是什麼意思?
- 25. ERP什麼閱讀/練習?
- 26. 宏記錄用戶已閱讀文件
- 27. 裝配需要什麼?爲什麼我們使用它們?
- 28. 你如何閱讀JavaDoc?
- 29. 這個C++宏是做什麼的?
- 30. 找出什麼工作簿叫做宏