Clojure让vs多元化

时间:2017-08-17 01:37:23

标签: java clojure let arity

思维功能,但在clojure中,对JVM更好,更具性能和更轻松

(defn- on-message
  ([options ch {:keys [headers delivery-tag]} ^bytes payload ^CompanyProto$Company$Builder company]
   (check-id company)
   (save company options)
   (basic/ack ch delivery-tag))
  ([options ch ^PersistentHashMap kwargs ^bytes payload]
   (on-message options
               ch
               kwargs
               payload
               (-> (CompanyProto$Company/newBuilder)
                   (.mergeFrom payload)))))

(defn- on-message [options ch {:keys [headers delivery-tag] ^bytes payload}]
  (let [company (-> (CompanyProto$Company/newBuilder) (.mergeFrom payload))]
    (check-id company)
    (save company options)
    (basic/ack ch delivery-tag)))

2 个答案:

答案 0 :(得分:1)

如果您使用Java互操作进行开发,请将true设置为filter。如果有警告,您需要使用类型提示消除它。然后你会得到“穿孔而且不那么沉重的JVM”代码。

P.S。具有可变性的数值计算,简单的JVM类型和未检查的溢出是另一个故事,如果是你的情况,你也需要检查它。

答案 1 :(得分:0)

直接问题的答案是,函数调用中没有引入任何开销,因为该函数恰好具有多个arities。在Clojure中,所有函数调用都被编译为方法调用。调用的确切方法取决于参数的数量 - 就JVM而言,每个arity都被编译为不同的方法。确定在编译时调用哪个方法,因此在运行时没有开销。

话虽如此,进行嵌套函数调用还是有一些开销。具体来说,每次调用都会使调用堆栈增加一个常量,直到该调用返回为止。但是,这种开销很小,在这种情况下不太可能对性能产生可测量的影响。

  

@ToniVanhala我先做了,但朋友说让我们不好   而且没有功能(他是一个erlang开发人员),我是功能新手   langs ......他说的另一件事就是clojure很奇怪   不堆叠

这似乎是一个真正的问题。所以值得解决这个问题。

let只是一个允许我们将值绑定到变量的表达式。这些绑定是不可变的。此外,众所周知,let可以实现为对lambda的宏观抽象(或者,在Clojure的词汇中,fn)。所以let肯定没有让它成为"没有功能"。

也没有什么"奇怪的"或者令人费解的是Clojure不是无堆叠的。 Clojure是一种JVM语言,并且调用栈深深地嵌入在JVM的抽象计算模型中。虽然有办法解决这个问题(例如,继续传递样式),但这些方法要么放弃深度JVM互操作和/或要求性能损失。 Clojure首先是一种务实的语言,这是一种务实的让步。

此外,Clojure(作为一个Lisp)实际上是一个语言框架,您可以用它来构建您想要的语言。您的语言可能会做出不同的权衡。例如,您的语言可能是"stackless"。或者它可能有first-class continuations(免责声明:我是pulley.cps的作者)。或者它可能有completely different paradigm(即逻辑与功能)。但它也可以很简单。使用Clojure,您可以选择您所支付的费用。

具有讽刺意味的是,你的朋友对于无法正常运行的代码是正确的。但是,这不是因为let。相反,几乎所有之外的let都不起作用。例如,(save company options)显然是一个副作用操作。但这并不一定意味着你的代码很糟糕 - 即使是最纯粹的功能程序,如果它具有任何实际价值,它必须在某些时候与现实世界互动。