2017-05-22 37 views

回答

5

读者宏改变语言的语法(例如,@foo变成(deref foo)),通常的宏不能这样做(一个普通的宏将无法摆脱括号,所以你会有做一些像(@ foo))。它被称为读取器宏,因为它在repl的read传递中执行(检出source)。作为一个clojure开发者,你只会创建常规的宏,但是你将会使用大量的宏读取器,而不必明确地考虑它们。

读者宏的完整列表在这里:https://clojure.org/reference/reader和包括像@',并#{}共同的东西。

Clojure的(不像其他一些的Lisp)不支持用户定义的读者宏,但有一些扩展经由tagged literals(例如#inst#uuid

3

TL内置到阅读器;博士*

宏[正常宏]评价(REPL的E)期间被扩展,捆绑到码元,对口齿不清对象进行操作,并且出现在第一或“功能”,一种形式的一部分。 Clojure和所有lisp都允许定义新的宏。在评价之前在读取期间运行

读卡器宏,是单个字符,对字符串操作之前,所有从读取器发射的口齿不清对象,并且不限于在第一或“功能”是,是表单的一部分。 Clojure的,不像一些其他的Lisp,不允许定义新的读者宏,编辑短Clojure的编译器本身。

更多的话:

正常的非读者宏,或只是“宏”,操作上口齿不清的对象。考虑:

(and 1 b :x)

and的宏将与两个值被调用,一个值是1,另一个是由符号b(未b的值)和关键字:x的列表。宏正在处理的所有and已经是lisp(Clojure)值。

宏扩展仅在宏是在列表的开始发生。 (and 1 2)扩展and宏。 (list and)返回错误“无法获取宏的值”

读者重新负责将字符串转换为In Clojure读者宏是一个单独的字符,它改变了读者,负责转向的部分文本流成口齿不清对象,进行操作。Clojure的lisp阅读器的发送是LispReader.java。正如Alejandro C.所述,Clojure不支持添加阅读器宏。

阅读器宏是一个字符。 (我不知道这是否适用于所有lisps,但Clojure目前的实现仅支持单字符阅读器宏。)

阅读器宏可以存在于窗体中的任何位置。考虑(conj [] 'a)如果'宏是正常的,则tick将需要变成lisp对象,所以代码将是符号conj,空向量,符号'以及最后符号a的列表。但是现在的规则要求自己评估'。取而代之的是,读者在看到'包装完整的s-exp后跟quote,以便返回给评估者的值是conj,一个空向量和一个quote后跟a的列表。现在quote是列表的头,并且可以更改它引用内容的评估规则。

1

简而言之,读者宏是一个低级特征。这就是为什么有这么几个(只是@,退出和更多)。必须遵守许多读者规则才能将任何语言变成一团糟。

一个常规宏是一个在Clojure中广泛使用的工具。作为开发人员,如果您不是Clojure的核心开发人员,欢迎您编写自己的常规宏而不是读者宏。

您可能总是使用您自己的标签文字作为读者规则的替代,例如#inst "2017"会给你一个Date实例等等。

相关问题