Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/clojure/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Clojure lisp宏在典型开发中真的有用吗?_Clojure_Scheme_Lisp_Elisp_Clojurescript - Fatal编程技术网

Clojure lisp宏在典型开发中真的有用吗?

Clojure lisp宏在典型开发中真的有用吗?,clojure,scheme,lisp,elisp,clojurescript,Clojure,Scheme,Lisp,Elisp,Clojurescript,关于Lisp中的宏有很多令人愉快的观点,但我真的找不到一本可以在我的日常工作流程中使用的入门书。我是web开发人员,但使用emacs大约有10年了。我想了解宏是否真的对每个人都有用,或者它只是非常特定任务的杀手级功能 大多数使用宏的引物都试图在lisp的基础上生成DSL。有时候它可能很有用,但据我所知,在商业开发中创建语法扩展是一种糟糕的做法。大多数语言都有标准特性,如for、if、while、foreach操作符,以及类、名称空间、模块、闭包(lambda)等常见概念。因此,所有程序通常都是从

关于Lisp中的宏有很多令人愉快的观点,但我真的找不到一本可以在我的日常工作流程中使用的入门书。我是web开发人员,但使用emacs大约有10年了。我想了解宏是否真的对每个人都有用,或者它只是非常特定任务的杀手级功能

大多数使用宏的引物都试图在lisp的基础上生成DSL。有时候它可能很有用,但据我所知,在商业开发中创建语法扩展是一种糟糕的做法。大多数语言都有标准特性,如for、if、while、foreach操作符,以及类、名称空间、模块、闭包(lambda)等常见概念。因此,所有程序通常都是从这些片段构建的,而检查代码的新程序员已经知道这些片段并可以操作它们。对于基于宏构建的DSL,程序员不仅需要探索业务逻辑,还需要学习您的DSL。商业开发倾向于典型的解决方案,这些解决方案具有易支持性和程序员的高可替换性

下一步-在宏的顶部创建模板引擎。现在的行业标准是Twig,Jinja2,模板工具包-您可以创建自己的模板系统,但是。。。现在是2015年,而不是保罗·格雷厄姆(Paul Graham)的Viaweb创建的2001年。现代模板系统彼此非常相似——它们经过多年的开发,有很多概念,如块、过滤器、继承、i18n。所以在2001年创建自己的模板引擎是有意义的,但现在有了适合所有生活突发事件的复杂模板引擎

下一步-使用宏创建独立于传递给宏的数据的算法。这个概念是有道理的,但它真的需要宏吗?例如,大多数脚本语言支持通过引用传递函数——这意味着您可以创建抽象函数,该函数将接受数据和数据处理函数作为参数。当然,您需要创建一些数据处理函数来支持所有需要的数据类型,但您将能够将所有这些函数传递给抽象函数,抽象函数的长度将与可比较的lisp宏一样短

下一步——算法本身。如今,90%的web开发人员只使用现成的库和算法。所以,即使我在前一段中完全错了,宏在我们的工作中的作用也很小


那么,你真的每天都在使用宏吗?或者你只是非常优雅地解决宏的一些问题,并推断在接下来的几个月内可能会出现这种情况?

引用

我在Clojure社区多次看到这样一句话:

数据>函数>宏

数据

为什么??数据是惊人的:你可以打印它,转换它,序列化它发送到网络。。。它也是语言不可知论者。您可以将其转换为另一种表示形式,并让另一种语言编写的程序使用它。这有多强大? 作为Clojure法学家,您可以看到几乎所有Clojure函数都是用来操作数据的。操纵数据是一种乐趣。引述:

静态格式良好的数据在编程中尽可能接近完美。所有的废话都把它放在了那里

功能

然后是函数:在lisp中,我们很幸运地让它们镜像了一个数据结构(列表),但它的可组合性仍然不如数据。 例如,您可以
merge
code吗?我们假设在这种情况下,
merge
意味着
comp
ose。你能说出函数的来源吗?你能
diff
it吗?所以在某种意义上,函数是穷人的数据

但Clojure试图减轻痛苦。它有一些工具可以做到这一点。有些是简单的(比如
meta
,它将数据附加到函数)或宏。 我们真幸运!我们有宏来操作代码。它仍然不如操纵原始数据那么令人愉快,但它让我们达到了目的。现在来看“但是函数是Clojure中的数据”的常见论点:有多少Clojure数据函数在函数上工作?不过有一个很大的不便。引述:

宏在运行时是不透明的

也就是说,他们不是一等公民,不能将宏作为值传递。那么我们如何编写宏呢?更多宏?它感觉像一条滑动的路径

到现在为止,你可以感觉到我们宁愿不使用它们。它们当然非常强大(改变代码的代码?听起来很酷!)

顺便说一句,我觉得(尽管我没有任何参考资料)Clojure试图比其他Lisp更具可读性和更少的括号,代价是使宏编写稍微困难一些

简而言之,宏是一个非常强大的工具,我不认为我会想用一种不再有宏的语言编程。但你必须好好利用它

示例

我能想到的最经典的宏用法是定义
if
构造。我们可以用一个函数吗?让我们试试:

(defn if [condition if-true if-false]
   ...)
这行吗?否,因为向函数传递参数时,将对其求值。因此,以下是:

(if true (println "true!") (println "false!)) ;; prints both "true!" and "false!"
宏不计算其参数,因此在本例中使用宏。您可以在
[clojure.core][3]
中找到一些。 至于典型的web开发(定义“典型”?),让我们看看一些野生的宏

[mori][3]
中,wiki中有一个关于的页面,我们可以看到函数是用多个算术定义的。定义并使用用于导出这些函数的宏

从同一位作者那里,我们可以看到
Om
[defui][6]

我在野外看到的许多宏也只是为了简化声明,比如
Compojure
中的
[defroute][6]

如果你有时间读我的答案,你应该