Hacker News new | past | comments | ask | show | jobs | submit login

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.


Nope, Nimrod (at least) has full lexical scopes if you want

    proc foo(x: int): int = 
      let z = x * 2
      #z visible
      block:
        let y = z * 4 #z & y visible
      let foo = 3 #z and foo visible, y out of scope


I said "c-style", not ML style.




Consider applying for YC's Summer 2025 batch! Applications are open till May 13

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: