This is the third Chapter of a series of posts about porting The Little Schemer to Clojure. You may wish to read the intro.
The first function we look at is rember
.
(def rember (fn [ a lat] (cond (null? lat) '() true (cond (= (first lat) a) (rest lat) true (cons (first lat) (rember a (rest lat))))))) (println (rember 'banana '(apple banana orange)))
The big idea here is list construction. We’re applying the second commandment of the Little Lisper – use cons to build lists [sequences].
The next function we look at is firsts
.
(def firsts (fn [l] (cond (null? l) '() true (cons (first (first l)) (firsts (rest l)))))) (println (firsts '((large burger)(fries coke)(chocolate sundae))))
Here we also meet the Third Commandment of TLS. This states when building a list, describe the typical element, and then cons it onto the natural recursion. This goes back to the discussion on lat?
we were having in the previous chapter. You have to identify the base case, and then build on it.
You can see it working here.
If you’re building on previous chapters, didn’t you want to use the null? function here rather than empty??
Thanks for the feedback – this has been updated.
Your definition of firsts uses rest after the cons, and thus returns the rests. It should use first, and thus return the firsts.
I haven’t read Little Schemer. I am just trying out the examples in this site for fast-tracking Clojure. However, isn’t the firsts function you have implemented actually doing “lasts”?
> (firsts ‘((large burger bacon) (fries coke hamster) (chocolate sundae mushroom)))
…
((burger bacon) (coke hamster) (sundae mushroom))
—
Shouldn’t it be something like
(def firsts
(fn [l]
(if (empty? l)
‘()
(cons (first (first l))
(firsts (rest l))))))
Thanks for the feedback – I’ve updated the post.