One of the reasons I think people may find clojure hard to read is that there isn't much vertical spacing. Do you find this translation of js to clojure any easier?
function doThis(arg1, arg2){
var m = arg1 + 3;
var n = modifyArg(arg2);
if (m > 3){
System.out.println("bigger!");
}
return m + n;
}
(defn do-this [arg1, arg2]
(let
[m (+ arg1 3)
n (modifyArg arg2)]
(if (> m 3)
(println "bigger!")
)
(+ m n)
)
)
I'm not suggesting this is good clojure, but it's closer to the way imperative languages are written.
One thing which still causes me to expend a few extra brain cycles for me is the [] in the let clause. The fact that the locally scoped vars m and n are contained within a syntactic block, as it were, makes me feel that they're within an inner scope and not available to the code below. It's really trivial and absolutely a feel thing, but it does have small effect on the ease of readability.
This is why I like nimrod, which gives you the best both worlds
proc doThis(arg1, arg2: int): int =
let m = arg1 + 3
let n = modifyArg(arg2)
if m > 3:
echo("bigger!")
return m+n
With the added bonus that you get compile-time type checking (as well as a fair bit of type inference - notice I didn't have to specify any types other than the function signature), and the code itself compiles down to highly efficient C (https://gist.github.com/tylereaves/8116774 if you're really curious, do remember that code isn't intended to be human readable/modifiable).
Yeah, in thinking about my example a little more and generalizing, I think one of the problems that people have with reading clojure is that it doesn't have as robust a syntactic indication of scope that other languages have.
Don't you mean clojure has a MORE robust indication of scope than other languages? In clojure you can nest lets, and it is very obvious when the binding is out of scope, but in c-style languages, once bound, they stay bound till the end of the function.
function doThis(arg1, arg2){
}(defn do-this [arg1, arg2]
)I'm not suggesting this is good clojure, but it's closer to the way imperative languages are written.
One thing which still causes me to expend a few extra brain cycles for me is the [] in the let clause. The fact that the locally scoped vars m and n are contained within a syntactic block, as it were, makes me feel that they're within an inner scope and not available to the code below. It's really trivial and absolutely a feel thing, but it does have small effect on the ease of readability.