繁体   English   中英

Clojure的优化工作如何工作,它在哪里?

[英]How does Clojure's optimiser work, and where is it?

我是Clojure的新手,但不是lisp。 一些设计决策对我来说很奇怪 - 特别是需要一个向量用于函数参数并使用recur显式请求尾调用。

将列表转换为向量(反之亦然)是优化器的标准操作。 通过在编译为字节代码之前重写为等效的clojure,可以将尾调用转换为迭代。 []和recur语法表明当前实现中都没有这些优化。

我想在什么地方在执行我能找到的任何/所有源到源变换通行证。 我不会说Java很好,所以我很难在代码库中导航。

如果在逐个函数转换为JVM的字节代码之前没有任何优化,我会对此的设计原理感兴趣。 也许是为了实现更快的编译?

谢谢。

编译器代码中没有显式的优化器包。 任何优化都是“内联”完成的。 有些可以通过编译器标志启用或禁用。


观察函数参数的文字向量是如何在源代码中表示函数的语法选择。 它们是否表示为向量或列表或其他任何内容都不会影响运行时,因此无法进行优化。

关于自动recur ,Rich Hickey 在此解释了他的决定:

在谈到一般TCO时,我们不仅讨论递归自调用,还讨论对其他函数的尾调用。 后一种情况下的完整TCO目前在JVM上是不可能的,同时保留Java调用约定(即不解释或插入蹦床等)。

虽然自我尾调用跳转很容易(毕竟,这就是recur所做的),但隐含地这样做会对那些来自的人产生错误的期望,例如具有完全TCO的Scheme。 所以,我们有一个明确的重复构造。

从本质上讲,它归结为仅仅优化和语义承诺之间的差异。 在我能做出承诺之前,我宁愿没有部分TCO。

有些人甚至更喜欢“重复”到功能名称的冗余重述。 此外,复发可以强制执行尾部呼叫位置。

特别要求向量用于函数参数

大多数其他lisps用语法列表构建结构。 例如,对于关联的“地图”,您可以构建列表列表。 对于“矢量”,您可以列出一个列表。 对于类似条件切换的表达式,您可以列出列表列表。 很多列表,很多括号。

Clojure明确的目标是使lisp的语法更具可读性和冗余性。 地图,集合,列表,向量都有自己的语法分隔符,因此它们会跳出来,同时还提供特定功能,否则如果它们都是列表,则必须使用函数显式请求。 除了这些结构基元之外,其他函数(如cond通过为表达式中的每一对删除一层括号来最小化括号,而不是将另一对包装在另一个分组括号中。 这种理念贯穿整个语言及其核心库,因此代码更具可读性和优雅性。

作为向量的函数参数只是此语法的一部分。 它不是关于语言是否可以轻松地将列表转换为向量,而是关于语言如何需要在函数定义中放置函数参数 - 它通过明确要求向量来实现。 事实上,你可以在defn的源代码中清楚地看到这defn

https://github.com/clojure/clojure/blob/clojure-1.7.0/src/clj/clojure/core.clj#L296

这只是函数编写的一个要求,就是这样。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM