Clojure真正针对Java而不是并发/不可变性特征相关的任何例子?

时间:2009-12-08 03:42:31

标签: java functional-programming clojure

我完全可以理解为什么Clojure非常适合并发编程。我也可以看到FP在这方面的优势。

但显然,并非我们编写的每一行代码都是线程的一部分或需要并发访问。对于代码的那些部分(更简单和连续的代码片段),Java真正错过了Clojure提供的内容是什么?

在Java中是否真的错过了Multimethods,Dynamic binding,Destructuring bind等功能?

我认为我的问题也可以被描述为:

  • 如果Clojure没有 它具有的并发功能 整个不变性/可变性 那么问题不是我们关心的问题 Clojure提供的其他功能 这将使你使用它而不是 Java?

3 个答案:

答案 0 :(得分:25)

  

在Java中是否真的错过了Multimethods,Dynamic binding,Destructuring bind等功能?

是。也...

  1. 一流的功能。美味的一流功能。这不仅仅是FP的事情。人们迫切要求Java 7中的闭包。

  2. 码是数据。这是任何Lisp的好处。 Lisp代码不仅仅是您在编译器口中提供的文本blob,而且永远不会再看到它,它是可以通过编程方式操作的列表和向量以及符号和文字的结构。这导致了强大的宏和一流的符号以及许多其他好东西。它导致了一种高度可扩展和强大的语言。

  3. Clojure具有更好的控制和循环结构,能够通过宏和一流函数创建自己的构造。 Java有forforeach以及while(多年来甚至没有foreach)。 Clojure有mapfilterreducemapcat,许多do表单,大量ifwhen表单,列表推导通过for,等等。如果这些不存在,您可以自己编写。在Java中,您需要等待十年才能成为一个委员会(也许)批准这些功能。

  4. 减去那些处理静态类型的人,为Java 7设置的所有功能,Clojure已经拥有或可能具有琐碎的功能。 “自动资源管理”,Clojure有with-open。 “对集合的语言支持”,Clojure(以及Ruby,Perl,Python ......)已经有了。 “切换中的字符串”,Clojure具有更强大的类似案例的构造,如condp,以及您能想到的任何其他内容。你可以在十几行Clojure中自己写这些。

  5. 列表,地图,数组,集合,有序集,有序映射等的简明语法以及几乎可互换的使用都归功于seq抽象。对正则表达式,字符,匿名函数等的字面支持

  6. Java有强制检查的异常,这很烦人; Clojure没有。

  7. Java语法冗长且不规则。 Clojure语法简洁而有规律。由于像->doto之类的宏,以及像proxy和(很快)reify这样的构造,即使用Clojure编写的Java通常也比用Java编写的Java更简洁。

  8. Java代码有太多强制性的样板和无休止的重复。 public static void main(String[] args){...}等等.Clojure几乎没有这个样板,而在表现力或力量方面几乎没有牺牲。即使是今天其他静态类型的语言似乎也在采用类型推理的方式。你需要一个庞大的以Java为中心的IDE来编写并无休止地“重构”Java代码,这是有充分理由的。用手写它会让你发疯,并用手指捏住小块。

  9. 在Java中,一切都是类或接口,无论是否应该是,这都是不必要的复杂性的原因。有许多程序必须被忽视以适应OOP风格。 Clojure让你避免这种情况。 A nice rant to this effect. Clojure主要关注动词。

  10. 通过REPL进行交互式编程很有趣。编译/运行/调试周期不是。如果你想要的话,Clojure仍会编译成.class文件;在此期间,您可以坐在代码中间,在运行时自由修补。

  11. Clojure的元数据和理智的平等测试很愉快。正如它自动推广int到long到Bigint,本地处理有理数,等等。

  12. 动态类型导致更短,更通用,因此更可重用,因此比静态类型更强大的代码。 (这显然是一个备受争议的问题,所以我把它放在最后。)

  13. Scala和Groovy以及JRuby和Jython以及其他JVM语言的流行 - 这不是Java应该被视为一个很好的迹象,虽然JVM很好,但Java语言对许多人来说都是令人不快的人

答案 1 :(得分:7)

布莱恩已经很好地总结了它。这是给我留下深刻印象的东西。 (摘自Stuart Halloway的书Programming Clojure

来自Apache Commons的Java代码:

public class StringUtils {
    public static boolean isBlank(String str) {
        int strLen;
        if (str == null || (strLen = str.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if ((Character.isWhitespace(str.charAt(i)) == false)) {
                return false;
            }
        }
        return true;
    }
}

以下是Clojure中的类似实现:

(defn blank? [s] (every? #(Character/isWhitespace %) s))

答案 2 :(得分:2)

对于一个人而言,在Clojure中通常会有很少的“仪式”。像Python和Ruby这样的语言也比Java更具优势(因此JRuby,Jython的流行)。

但请注意,尽管可能存在明确的模式,但有时Java中无法避免冗长。 Clojure的宏在这里是一个巨大的胜利 - 甚至超过其他类似的动态语言。

另一件需要考虑的事情是Clojure程序往往是并发安全的。因此,如果您决定将特定应用程序并发,那就不会太痛苦。如果不事先做出很多决定,使用Java将会更加困难。

还想知道如果Clojure缺乏强大的并发性原语,而且不变性就像是说“如果Clojure不是Clojure会怎么样?”,那么Clojure是否会比Java有明显优势。