Clojure协议和Groovy类别之间的差异

Clojure协议和Groovy类别之间的差异,groovy,clojure,protocols,categories,Groovy,Clojure,Protocols,Categories,最近我看到了Clojure协议的一个演示,我对通过这种方式扩展现有类型的简洁方式印象深刻。 然而,我很确定已经在其他语言中看到了类似的方法,过了一段时间我发现这是Groovy类别 比较一下: @Category(String) ​class StringCategory { String lower() { return this.toLowerCase() } } use (StringCategory) { println("TeSt".lower())

最近我看到了Clojure协议的一个演示,我对通过这种方式扩展现有类型的简洁方式印象深刻。 然而,我很确定已经在其他语言中看到了类似的方法,过了一段时间我发现这是Groovy类别

比较一下:

 @Category(String) ​class StringCategory {
   String lower() {
     return this.toLowerCase()
   }
 }

 use (StringCategory) {
   println("TeSt".lower())
   assert "test" == "TeSt".lower()
 }
与Clojure协议等效(取自)

我的问题是:

  • 除了性能差异(据说Clojure在这方面进行了高度优化)之外,这两种方法之间是否存在语义差异
  • 除了笨拙的语法之外,Groovy方法在逻辑上还有什么问题吗

  • 免责声明:我是一个完全的Clojure新手

    他所指的Clojure功能看起来像:

    (defprotocol StringMunging
      (lower [this]))
    
    (extend-protocol StringMunging
      String
      (lower [this]
        (.toLowerCase this))
    
      clojure.lang.Keyword
      (lower [this]
        (keyword (lower (name this)))))
    
    user> (lower "TeSt")
    "test"
    user> (lower :TeSt)
    :test
    
    可以随时为任何类型添加实现——我编写的两个实现不需要以任何方式进行协作


    然而,我对Groovy的理解还不够透彻,无法对这个问题本身做出任何实质性的评论;我只能帮助描述问题的Clojure方面。

    以下是使用协议的大致等效Clojure代码:

    (defprotocol Lowerable
      (lower [x]))
    
    (extend-protocol Lowerable
      String
        (lower [s] 
          (.toLowerCase s)))
    
    (lower "HELLO")
    => "hello"
    
    关于Clojure协议需要注意的关键区别(我认为这使它区别于Groovy版本)

    • Clojure协议定义不包含任何实现(在这方面它更像一个接口)。实现是单独提供的:您可以将Lowerable协议扩展到任意多个不同的类,而无需对类本身或协议定义进行任何更改。例如,您可以定义
      lower
      来处理一个文件
    • 上面的Groovy类别专门用于字符串-Clojure协议并非如此。在本例中,Clojure协议“Lowerable”是在没有说明任何参数类型的情况下定义的
    • lower
      是一个合适的一级功能。因此,您可以使用它来构建高阶抽象(通过高阶函数),从而接受Lowerable协议扩展到的任何参数
    • Clojure协议经过了大量优化,因为它们旨在利用JVM的快速方法调度。因此,它们被编译成非常高效的代码(不需要动态对象检查或反射)

    Clojure协议实际上是一个相当独特的协议(链接视频非常有趣)。我认为在另一种语言中与Clojure协议最接近的等价物实际上是Haskell类型的类。尽管如此,这还是有点牵强,因为Haskell是静态类型的,Clojure是动态类型的……

    我觉得这个问题很有趣。为了我们中的非Clojure启蒙者,以及为了语法/简洁性比较,您是否可以添加Clojure等价物对不起,我想,只是我不能。在网站上有一个非常类似的示例,但是现在我无法测试等效的代码,因此我不想发布一些可能不起作用的代码。遗憾的是,没有一个web控制台像Groovy web控制台那样(try-clojure.org上有一个,但我甚至在粘贴换行分隔的代码行时失败了)。也许可以尝试使用?谢谢提示,它确实有效,至少在添加println语句时是如此。我使用了mikera的版本。谢谢,这是一个很好的解释,有不同的实现实际上更强大。然而,我必须尝试一种{{mixed}}、{{Delegate}}和{{Category}}方法,但即使它可能会起作用,协议也似乎更接近。我希望您不介意我在ideone链接中用您的解决方案(以及添加的println)扩展我的问题,以进行澄清。
    (defprotocol Lowerable
      (lower [x]))
    
    (extend-protocol Lowerable
      String
        (lower [s] 
          (.toLowerCase s)))
    
    (lower "HELLO")
    => "hello"