I see. So instead of using interfaces and implementations of these, I
would simply use closures, one for mock and one for production? That was
actually my first attempt, but I didn't like it back then.

Take this code for example - passing a function just to have it called
feels weird:

(defn load-page [provider name]
  (provider name))

(load-page (make-mock-provider) "home")

In Java, this would probably look like this:

class PageLoader {
    Provider provider;

    PageLoader(Provider p) {
        provider = p;
    }

    Page loadPage(String name) {
        provider.loadPage(name);
    }
}

PageLoader l = new PageLoader(new MockProvider());
l.loadPage("home");

Then again, it might just feel weird because I've gotten very used to
OOP. In my Java code, loading pages is a responsibility of the
PageLoader and it delegates it to the Provider. Objects have
responsibilities and send messages to each other to fulfill these,
that's OOP.

In functional programming, there's simply a function that has a certain
functionality, and everything it needs to fulfill it has to be provided
by the caller. That's at least how I understand it by now.

Maybe I should just call the function returned by (make-mock-provider)
directly? The interface in Java has the great benefit of ensuring type
safety (plus there's no closures yet, so it's the only way), but does
this make sense in a dynamic language? I mean, if I passed an
implementation of the wrong interface or a closure with the wrong number
of arguments, wouldn't both situations result in weird runtime errors?

On 12/10/10 22:34, Armando Blancas wrote:
>> Back to my question: Am I trying to do Java in Clojure? Is there a more
>> Lisp-y way to do this?
> 
> You can hide the types so your client code is more lispy:
> (defn load-page [prov] (.loadPage prov))
> ;;test
> (def mp (make-mock-provider)) ... (load-page mp)
> ;;production
> (def prov (make-provider)) ... (load-page prov)
> 
> Depending on your app the provider could be a singleton and need not
> be passed to each function. Another option is multimethods, in which
> case you'd be using mock functions with an argument that would
> indicate which version to dispatch to.
> 
> As for the repl, I think it works just as well for bottom-up and top-
> down development. I use it for both all the time and to avoid throw-
> away tests I write them top-down, black-box for only what's visible to
> client/interop code first, then move down the layers as the code is
> more mature and stable. I'm not really into TDD but I depend on a test
> suite as complete as I can get it.
> 


Attachment: signature.asc
Description: OpenPGP digital signature

Reply via email to