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/

Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to