拥有宏是否真的需要同质性?

gre*_*man 8 lisp macros clojure

2012-02-04由"homoiconicity"字样赞助http://en.wikipedia.org/wiki/Homoiconicity.

背景:我即将选择哪本关于Clojure的书 - "Clojure in Action"或(4月底传入)"Clojure Programming"(您可以通过O'Reilly Rough Cuts阅读 ,一半页面是可见的).令我震惊的是,在这两本书中,这种属性 - 同质性 - 得到了如此重视.

由于Clojure的根源是以Lisp为基础的,所以我提到 "死性感"这本书真是太重要了.好吧,我可以看到详细解释的宏,但我没有听到提到的重点.现在比较一下(引自"Clojure in Action")

这种同质性也是Clojure宏观系统成为可能的原因.

它几乎看起来没有它,宏是不可能的.甚至维基百科声明(上面的链接)也更加平衡,但这些来源(*)都没有计算人为因素而支持英语语法.

如果我没有弄错的话,宏语法(类似于Lisp)可以在C#中实现(例如),只需要C#团队付出更多努力.但这是设计师团队的成本,而不是用户(?).第二 - habbits很重要.如果在现实生活中你认为"a + b",并且在计算机世界中你不断将它翻译成"+ a b",那么生产力就会受到影响(当我从C++ functor转到C#lambdas时,我可以看到这一点).

这个赞美,即Clojure程序员几乎直接将程序编写为AST,让我感到害怕,因为"由于直接用十六进制代码编写代码,不仅你学习十六进制系统,而且你更接近机器".

总结一下 - 我喜欢元编程,我喜欢类似Lisp的宏(虽然我不是Lisper),但我在这里看到两件事 - 宏和同质性.第一个毫无疑问是伟大的,第二个 - 不是那么多(至于我的理解),因为它使人类适合计算机的需要,它应该是另一种方式.

这个问题

同性恋真的对人类(语言的最终用户)有益,或者它实际上几乎只对语言设计者有益吗?非常欢迎例子!

或者以防万一我改写 - 假设给定的语言有Lisp-macros,"增加"同质性会提高最终用户的生产力吗?Expresiveness?还是相反?

(*)我不能百分百肯定,因为我只看到一小部分Clojure书籍,我不是在阅读它们,只是评估它们的购买.

更新

谢谢大家的答案,可惜我只选择一个作为解决方案:-),这并不意味着我更少重视别人,这对我来说是最完整的.

Fre*_*Foo 10

不,你不一定需要同质性来创建一个强大的,类似Lisp的宏系统.同质性只是使这样一个系统更容易使用; 没有它,你需要另一种语法来表达宏在评估时产生的AST.在同性语言中,宏观系统感觉很自然,因为程序和元程序看起来是一样的.


mik*_*era 9

宏并不严格要求同源性(例如:C/C++预处理器实现了编译时宏系统).

然而homoiconcity使得宏更有效和更容易使用:

  • 您无需使用语法分析步骤:在像Clojure这样的同色语言中,源代码可以直接用作编译器的抽象语法树.减少编译器的性能开销,减少用户的概念开销.
  • 代码生成更容易 - 您只需要组装正确的数据结构,而不是以可以成功编译的形式仔细生成文本源代码.通常,文本代码生成在非为其设计的语言中可能是一个非常棘手的问题(您需要考虑许多事情,如符号名称生成,库导入,引用规则,编译器是否需要写入源文件磁盘等)
  • 您的宏语言与源语言相同.无需为宏学习单独的语言或构造集.
  • 恕我直言同源性使宏更简单,优雅和可读.在许多情况下,您的宏最终看起来就像正确代码的模板一样.

作为一个小例子,这里是一个宏,它为Clojure添加了一个Java/C#样式"for"循环.

(defmacro for-loop [[sym init check change :as params] & steps]
 `(loop [~sym ~init value# nil]
    (if ~check
      (let [new-value# (do ~@steps)]
        (recur ~change new-value#))
      value#)))

;; Usage:
(for-loop [i 0 (< i 10) (inc i)] 
  (println i))
Run Code Online (Sandbox Code Playgroud)

就是这样 - 一种新的语言结构,增加了六行代码.你可以清楚地看到同音性 - 整个"循环"形式只是一个引用的Clojure数据结构.init,check和change参数也是传递给宏的homoiconic clojure数据结构,表示循环控制表达式.没有必要进行任何解析来支持我的新语法.

我认为用简洁或简单的非同性语言来做这件事是非常困难的.


Rai*_*wig 5

同质性是一个定义不明确的概念.

使Lisp与众不同的是它具有源代码的数据表示,并且求值程序将其作为输入.将源代码作为数据处理很容易,因为Lisp的所有常用功能都适用.

它提供了什么:

  • 阅读文本源并创建它的数据结构
  • 将源处理为数据
  • 将"源作为数据"打印为文本,包括漂亮的代码打印等内容

宏是转换源代码的函数.因此,您所需要的只是源代码的一些表示,以及执行此转换步骤的编程语言的执行/编译/解释中的一个步骤.

Lisp的工作方式使其变得方便,因为源代码是一种数据结构,可以使用大量内置函数和工具进行操作.需要注意的是更复杂的变换,其中一个需要理解的语言Lisp语言的语法,也不易在Lisp中做-尽管工具已实现(例如所谓的代码步行者).

还有Lisps有一个语法,它不是基于s表达式.一个例子是RLISP,计算机代数系统REDUCE的实现语言.RLISP还支持宏.

可以基于字符串和字符串操作来定义类似的方案.您还可以根据某种AST定义宏系统.

具有此类宏的语言示例:

  1. 迪伦.请参阅:http://opendylan.org/books/dpg/macros.html
  2. 朱莉娅.请参阅:https://en.wikipedia.org/wiki/Julia_ (programming_language)
  3. Nemere.请参阅:https://github.com/rsdn/nemerle/wiki/Macros-tutorial