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. >
signature.asc
Description: OpenPGP digital signature