1. 16

    This is a mix of great advice, things that are hopefully obvious, and a few terrible ideas just to spice things up. In particular the example of (comp str/capitalize str/trim) being labeled as “hard to read” compared to the lambda version is just bizarre, and the convention of marking reference types with * “because it resembles C/C++ pointers” would be a huge red flag if I saw it during code review. Adding in extra newlines sounds like a great idea if you always work plugged into an external display or two but shows a disregard for your colleagues who may prefer to work from a laptop.

    1. 6

      I thought the * prefix was interesting in that it offers up a solution to naming references. I find it difficult to name references something other than the thing they point to.

      1. 2

        I think you could make a case for a special naming convention for top-level def reference types, but it’s not helpful when it’s a local, which hopefully is the more common case.

      2. 5

        I had similar thoughts. It seems peculiar to offer a recommendation “Avoid higher-order functions” in a functional language.

        The article did put me in mind of Stuart Sierra’s series of posts Clojure Dos and Don’ts. I also like How to Name Clojure Functions.

        Regarding the recommendation to replace the threading macro with a let: an advantage (for me) of the threading macro, is that it’s immediately clear that the result of a function is not used again. It’s a temporary value that doesn’t matter after the next function in line has been called. In a let you have to scan the surrounding code to see how the value is used.

        As an aside: I quite dislike that the code examples are images without alt text.

        1. 1

          Also, avoiding the threading operator just to obscure the computation going on with some (probably badly) named steps (remember, naming is hard) is not the best.

          At work we used ->> a lot, because it both frees you from giving strange names to intermediate computation results and allows you to plug in whatever function you want to intercept the computation without having to rewrite your code.

        1. 3

          Where Erlang uses true as a catch-all, Clojure has the :else keyword. This makes it more readable.

          (cond
            (< n 0) "negative"
            (> n 0) "positive"
            :else "zero"))
          
          1. 16

            :else isn’t anything special in Clojure, it’s just truthy. The following is the same:

            (cond
              (< n 0) "negative"
              (> n 0) "positive"
              true "zero"))
            
            1. 5

              I regularly use :else as the catchall clause in Elixir (same rules as Erlang). Anything truthy will work.

            1. [Comment removed by author]

              1. 1

                It’s in the ‘Pushing the Limits’ section.

              1. 5

                If you use Emacs check out magit.