Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/function/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
Function Clojure星号特殊表格(fn*、let*等)_Function_Clojure_Macros_Special Form - Fatal编程技术网

Function Clojure星号特殊表格(fn*、let*等)

Function Clojure星号特殊表格(fn*、let*等),function,clojure,macros,special-form,Function,Clojure,Macros,Special Form,我发现很多“特殊形式”只是在后台使用星号版本的宏(fn*、let*和其他所有形式) 例如,在fn的情况下,它将分解功能添加到混合中,而fn*本身不提供这种功能。我试图找到一些关于fn*能做什么和不能做什么的详细文档,但我没那么幸运 它肯定支持: &/catchall指示器 (fn* [x & rest] (do-smth-here...)) 奇怪的是,arity上的重载,如: (fn* ([x] (smth-with-one-arg ...) ([x y] (smth-

我发现很多“特殊形式”只是在后台使用星号版本的宏(fn*、let*和其他所有形式)

例如,在fn的情况下,它将分解功能添加到混合中,而fn*本身不提供这种功能。我试图找到一些关于fn*能做什么和不能做什么的详细文档,但我没那么幸运

它肯定支持:

  • &/catchall指示器

    (fn* [x & rest] (do-smth-here...))
    
  • 奇怪的是,arity上的重载,如:

    (fn* ([x] (smth-with-one-arg ...) 
         ([x y] (smth-with-two-args ...))
    
所以我的最后一个问题是,为什么不定义:

(fn& [& all-args] ...)
这将是绝对最小的,并且可以通过宏提供所有的arity选择(检查参数列表的大小,if/case语句指向代码路径,将前几个参数绑定到所需的符号,等等)


这是出于性能原因吗?也许有人甚至可以在手边找到星号特殊表单的实际标准定义的链接。

我的猜测这是方便性/可扩展性驱动的。编译器(其中fn*实际上是“定义的”/“处理的”)是用java编写的,它处理所需的最低功能,以便引导语言,而fn是构建在它之上的宏。其他一些形式也一样。Rich在某个地方发表声明说,他可以将编译器从java重写为clojure,但没有看到好处(如果错了,请纠正我)。

是的,您可以在您提出的超原语
fn&
的基础上,以宏的形式完成所有这一切,这肯定会简化编译器的实现。之所以不这样做,部分是因为性能原因(速度相当慢,JVM已经有了基于算术的快速调度功能),部分是因为“装饰性”:这意味着函数的每一个算术都是一个函数编译到的JVM类的不同方法,这使得stacktraces更好。这也有助于JIT更好地“理解”我们的函数,从而可以相应地进行优化。

Arity selection利用了JVM虚拟方法分派:对于21+-arg Arity,只有一种方法


您可能会注意到
applyTo
方法,这是一种与您建议的
fn&
类似的通用方法。它的实现只是选择正确的专门化方法的一个步骤。

您的意思是上面的“(fn*…”而不是“(fn&…”)?fn&由一名编辑从我最初编写的fn*更改为清晰的版本。在本例中,fn&代表了fn*的一个相当小的版本。然而,这个版本并不存在,只是一个假设的构造。
fn&
编写起来比
fn*
is要简单得多,而用构建
fn*
的宏要简单得多ode>fn&并不是很难。实际操作的方式肯定不如Rich采用简单的
fn&
方法方便。我的想法是,当前的实现不利于方便性和可扩展性,因为只需将所有参数应用于函数并在向量/列表中传递它们(如&rest)对于最简单的情况(fn*),让宏处理单个绑定比通过特殊形式直接将一些参数(在&rest之前)绑定到“单个”变量更容易。此外,特殊形式(fn*)现在必须处理算术解析本身,这可能(在我的“建议”中)也是一个库功能(由fn提供)。我认为这是两个很好的理由。Clojure正在使用/调整底层JVM架构,以使其在其他领域也能发挥优势。因此,这可能是一种向编译器/JVM传递有用信息的方式,否则这些信息将通过宏丢失。之所以被接受,是因为它提供了fn*为何如此的最佳概述。