Let's TDD clojure.core/map

Eric Normand's Newsletter
Software design, functional programming, and software engineering practices
Over 5,000 subscribers

Summary: Learning to write map is a good lesson because it has recursion, list building, and higher order functions. It's everything that makes Lisp great.

map is one of those functions that you should learn to write yourself. It's a good exercise in recursion, the idea of building a list up, and it's a higher order function. And it's also simple enough to do in a few lines.

map is also amenable to Test Driven Development. Test Driven Development can really help focus. You work on one small step at a time. It's great for working on bigger problems.

UPDATE: The software below is broken. Sorry!

I wrote some software to help code with TDD. It's totally new^1^, so there may be problems. The goal is to turn all of the tests green. As you turn each test green, a new test appears. Remember to focus on each test as it comes up. Then make sure to keep the existing tests green as you pass new ones. Try it! And if it doesn't work, or if you have any suggestions, please let me know! (hints below)

Specification

Define a function my-map that takes a function f (of one argument) and a collection coll. It returns a new list containing the result of f applied to the elements of coll, in order, one at a time.

my-map
(and js/window
js/window.cljs
js/window.cljs.user
(js-delete js/window.cljs.user "my_map"))
;; This is a live editor. Make changes to turn the tests above green.
(defn my-map [f coll])

empty list returns empty list

(my-map inc [])
()

inc applied to first

(my-map inc [1]) [2]

inc applied to first

(my-map inc [2]) [3]

inc applied to all

(my-map inc [1 2 3]) [2 3 4]

dec applied to all

(my-map dec [1 2 3]) [0 1 2]

test a big list

(my-map even? (range 10)) [true false true false true false true false true false]

Hints

  1. (= () []) Empty list is equal to empty vector.
  2. (if test then else) You will need an if.
  3. (empty? []) gives true.
  4. (first [3]) gives 3.
  5. (cons 1 ()) gives (1) (cons adds an element to the front of a list).
  6. There's always recursion (a function calling itself).

Conclusion

I hope you like it. If you liked this, you may like LispCast Introduction to Clojure. It's a video course about Clojure, starting from the ground up. It has exercises, animations, visuals, and code. Try it!


  1. [Many thanks to the ClojureScript contributors who made this possible in the browser.]
Sean Allen
Sean Allen
Your friendly reminder that if you aren't reading Eric's newsletter, you are missing out…
👍 ❤️
Nicolas Hery
Nicolas Hery
Lots of great content in the latest newsletter! Really glad I subscribed. Thanks, Eric, for your work.
👍 ❤️
Mathieu Gagnon
Mathieu Gagnon
Eric's newsletter is so simply great. Love it!
👍 ❤️