I'm learning Clojure using tutorials and going through problems like 4clojure and 99 lisp problems. I do fine with solving problems, but my code always seem to come out to be a mess like the example below.
For a language as flexible as Clojure, how can a beginner learn the idiomatic ways without having somebody else hand holding along the way?
An example of my mess:
(defn intersectall [lset]
(when-not (empty? (first lset))
(if (reduce #(and %1 %2) (map #(stars/member* (front lset) %) (rest lset)))
(cons (front lset) (intersectall (cons (rest (first lset)) (rest lset))))
(intersectall (cons (rest (first lset)) (rest lset))))))
In case you're wondering, the function intersectall
merely returns a list of the common elements in all sub-lists of input.
So for:
(def lset '((6 :pears :and)
(3 :peaches :and 6 :peppers)
(8 :pears :and 6 :plums)
(:and 6 :prunes :with some :apples)))
=> (intersectall lset)
(6 :and)
This problem is from The Little Schemer pg 117.
If you really want to GET Clojure, I strongly recommend The Joy of Clojure book. It is written by two of the guys who know the language best next to the original creator. They explain what you can do, how you should do it, and then the whys. I don't think it is a good FIRST book/learning experience on the language, however I think it is the required SECOND book to study from once you have your fundamentals.
Both writing and reading code are appropriate and necessary. If the Clojure source code seems intimidating, start with smaller projects, e.g., https://github.com/technomancy/robert-hooke. Since you have been doing the 4Clojure problems, why not look at others' solutions after you have written your own? Search for the hashtag #4clojure in twitter or just visit https://twitter.com/#!/search/%234clojure.
Good luck!
Abstract your code into smaller functions that do one thing and one thing well. Once you have achieved this you can try to make it more elegant. Sometimes you notice your final result is so sweet and short you actually end up inlining it.
Bind the values you have already obtained by using let
. For instance calling (first lset)
several times in several different places makes your code more verbose.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With