Clojure是否支持“整个语言始终可用”的特性?

16
保罗·格雷厄姆在他的文章《为何Lisp与众不同》中第九条提到:

9. 整个语言始终可用。

不存在阅读时间、编译时间和运行时间之间的真正区别。您可以在阅读时编译或运行代码,在编译时阅读或运行代码,以及在运行时阅读或编译代码。

在阅读时运行代码使用户重新编程Lisp的语法;在编译时运行代码是宏的基础;在运行时编译是Lisp作为Emacs等程序扩展语言的基础;而在运行时阅读则能够使用s表达式进行通信,这一想法最近被重新发现并用作XML。

这个最后一条对于Clojure是否成立?

Clojure是一种基于Lisp的方言,因此它保留了Lisp的大部分特性,包括第九条所述的整个语言始终可用。因此,Clojure也允许在阅读时编译或运行代码,在编译时阅读或运行代码,以及在运行时阅读或编译代码。
2个回答

13
你可以在Clojure中自由混合运行时和编译时,尽管Common Lisp在这方面仍然稍微更加灵活(由于存在编译器宏和符号宏以及完全支持的macrolet)。Clojure在宏卫生方面采用了酷炫的方法,通过语法引用中的自动化符号解析。读取器目前已关闭,因此无法自由混合运行时、编译时和读取时1

1除非通过不受支持的“巧妙黑科技”clever hacks


5
只是为了明确,Clojure中可以在任意时间“读取”代码,然后编译和执行它;但是,不可能像在Common Lisp中那样插入到阅读器中,在读取时执行任意代码。 - Michał Marczyk
喜欢这个技巧。谢谢分享链接!:-D - missingfaktor
3
Clojure可以使用#=阅读器宏在读取时执行任意代码。 - Stuart Sierra
@Stuart Sierra:感谢您的评论,我应该提到这一点!不过,那还远远不是可编程阅读器,这正是我理解PG观点的关键所在(你不能使用#=来“重新编程[Clojure]的语法”)。此外,这是一个可怕的安全隐患(而且默认情况下*read-eval*true似乎是一个错误的特性);这当然是想要在像现在这样的情况下提到它的一个非常好的理由,所以再次感谢。 - Michał Marczyk

4

它确实保持着,

(eval (read-string "(println \"Hello World!!\")"))
Hello World!!
nil

就像emacs一样,你可以使用Clojure来配置程序。我知道一个使用Clojure的项目是static,它允许你将模板作为Clojure向量以及在读取时执行的任意代码。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接