Hi, I'm new to Clojure, using it for a reasonably sized project for the first time, and I'm trying to do test-driven development.
While it does work well technically - clojure.test is very nice to use and feels a lot like JUnit 4's assertThat() - I'm wondering if I'm trying to program Java in Clojure. Here's an example: I'm writing a class (Um. I mean, a ... namespace? Well, a horde of functions.) that accesses web pages from a backend, which can e.g. take these from the filesystem or from a database. In Java or C++, I'd use an interface for that and create one implementation for the filesystem and one for the database: interface Provider { String loadPage(String name); } This is possible in Clojure: (defprotocol Provider (load-page [this name]) It can be implemented using deftype: (deftype DatabaseProvider [] Provider (load-page [this name] (have-fun-with-the-database))) And I can call it like this: (load-page (DatabaseProvider.) "foo") Feels a little weird (especially since all examples of defprotocol and deftype use camel case for type names), but works. Back to my question: Am I trying to do Java in Clojure? Is there a more Lisp-y way to do this? As you may have suspected, this design wasn't my initial intention, it was driven by TDD: This allows me to create a mock implementation against which I can write my test cases without having having to depend on external resources. Typical TDD design. In fact, there will only be one backend for now. This made me wonder if test-driven development was desirable in Clojure at all, or even in functional programming in general. There's a few articles on the issue. Many seem to be from Clojure newcomers, asking questions themselves, and none handles design issues like mock objects [1]. One guy basically said that he stopped doing TDD because the REPL makes it possible to test specific functions directly [2]. I can see how he says that the *driven* aspect of TDD can be performed by the REPL, but I find it too inconvenient for extensive use. Bob Martin says that, because functional programming differs from object-oriented programming (In my opinion, these paradigms are compatible - did he mean imperative programming?), test-driven development has to start by testing the details, and work up to testing the big picture. TDD in e.g. Java starts with the big picture and moves down. I don't understand his points completely, but if he's right, this might be a fundamental problem for TDD in functional languages. One guy partly disagrees with him on some matters, but doesn't really mention the bottom-up thing [4]. What are your thoughts on these issues? Is anybody here doing TDD in Clojure? Is anybody against it? [1]: http://www.magpiebrain.com/2010/02/16/struggling-with-test-driven-clojure/ [2]: http://s-expressions.com/2009/07/28/clojure-the-repl-and-test-driven-development/ [3]: http://blog.objectmentor.com/articles/2010/06/03/tdd-in-clojure [4]: http://ericlefevre.net/wordpress/2010/06/04/bob-martin-on-tdd-in-clojure/
signature.asc
Description: OpenPGP digital signature