Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Library functions vs Java methods in Clojure

While reading 'Programming Clojure', I noticed that there are alternative ways to perform some operations in Clojure. For example, let's say we need to convert all characters of a string to their upper-case variants.

We can use .toUpperCase:

user> (.toUpperCase "foo")
;; => "FOO"

As well as clojure.string/upper-case:

user> (clojure.string/upper-case "foo")
;; => "FOO"

While clojure.string/upper-case is a function and we can treat it as such:

user> (map clojure.string/upper-case ["foo" "bar" "baz"])
;; => ("FOO" "BAR" "BAZ")

...we cannot do the same with .toUpperCase:

user> (map .toUpperCase ["foo" "bar" "baz"])
CompilerException java.lang.RuntimeException: Unable to resolve symbol...

I guess that .toUpperCase is direct call of Java method, and Clojure knows how to deal with this symbol when it is first element of a form.

Q: what should I use .toUpperCase or clojure.string/upper-case and what's difference between:

(map clojure.string/upper-case ["foo" "bar" "baz"])

and

(map (fn [x] (.toUpperCase x)) ["foo" "bar" "baz"])
like image 651
Mark Karpov Avatar asked Aug 22 '14 05:08

Mark Karpov


People also ask

Is clojure better than Java?

Clojure and Java can be categorized as "Languages" tools. "It is a lisp", "Concise syntax" and "Persistent data structures" are the key factors why developers consider Clojure; whereas "Great libraries", "Widely used" and "Excellent tooling" are the primary reasons why Java is favored.

Is clojure easier than Java?

For these Clojure defenders, this programming language is better than Java for many reasons. For example, they state that with Clojure, they can write better and more flexible programs.

What does do in Clojure?

( do expr*)Evaluates the expressions exprs in order and returns the value of the last. If no expressions are supplied, returns nil .


2 Answers

Either works: it's basically a trade-off as follows:

Advantages of wrapped Clojure functions:

  • More idiomatic Clojure style
  • More likely to be portable (e.g. to ClojureScript)
  • Can be passed to higher order functions

Advantages of using Java methods:

  • Slightly better performance (assuming you use type hints correctly to avoid reflection)
  • More transparent if you are working with Java programmers / Java code bases

Normally, I prefer to use wrapped Clojure functions, unless I have benchmarked and identified a performance problem, at which point I might drop down to direct Java interop.

like image 132
mikera Avatar answered Nov 09 '22 20:11

mikera


clojure.string/upper-case is just a wrapper function of java.lang.String.toUpperCase method. You can check in in your repl.

user=> (source clojure.string/upper-case)
(defn ^String upper-case
  "Converts string to all upper-case."
  {:added "1.2"}
  [^CharSequence s]
  (.. s toString toUpperCase))

As you can see, upper-case just invoke toUpperCase.

I don't think there's any strong rule to choose only one between them. However, as you already know, .toUpperCase method is not a clojure function and cannot be passed as an argument to other higher order functions. So, it would be better to use clojure.string/upper-case, if you don't have any specific reasons to use .toUpperCase method.

like image 29
ntalbs Avatar answered Nov 09 '22 19:11

ntalbs