I'd like to see an example of this "functional worker" style you mention. As it sounds a lot like your definition of OOP to me. Not to mention that anything that talks to a queue is performing io and is therefore not functionally pure. So it sounds like you went and re-built component, but this time around message passing, and mutable actors.
On Sunday, June 21, 2015, Lawrence Krubner <lawre...@rollioforce.com> wrote: > There are ways to handle dependencies without going down the OOP route > that Stuart Sierra took. However, there are a lot of good ideas in Stuart > Sierra's Component library, and to the extent that you can borrow those > ideas, you end up with code that resembles "best practice" in the Clojure > community. > > For me, one "Big Idea" that I got from Stuart Sierra is that there should > be a "start" method that can be called either from the REPL or from -main > (for when you app runs as a daemon). The other "Big Idea" I got was that > there should be functions for handling the lifecycle of all the components > in your app, so you can easily start and stop and restart. So nowadays my > "core.clj" tends to look like this: > > (ns salesslick.core > (:gen-class) > (:require > [salesslick.start :as start] > [salesslick.stop :as stop])) > > ;; what you would call from the REPL to re-initate the app > (defn start [] > (try > (start/start) > (catch Exception e (println e)))) > > (defn stop [] > (try > (stop/stop) > (catch Exception e (println e)))) > > ;; Enable command-line invocation > (defn -main [& args] > (.addShutdownHook (Runtime/getRuntime) > (Thread. > #(do (println "Salesslick is shutting down") > (stop)))) > (start)) > > So I can call "start" and "stop" from the REPL, or, if the app is running > as a daemon, "start" gets called by -main, and "stop" is registered as a > shutDownHook. > > These are great ideas that I got from Stuart Sierra, however, I did not > feel the need to go as far toward OOP as Stuart Sierra did. And some of > things he has suggested as "best practice" really strike me as odd. To be > honest, some of the things he said were astonishing and went against > everything I have learned over the years. I'm thinking of what he says in > these 2 videos: > > http://www.infoq.com/presentations/Clojure-Large-scale-patterns-techniques > > Stuart Sierra - Components Just Enough Structure > <https://www.youtube.com/watch?v=13cmHf_kt-Q> > > At one point he says that "Object Oriented code has the advantage that it > is obvious where you configure your code." > > Wow!!! What can I say about that!!! > > I have lost entire days because I was dragged into stupid, tedious > meetings whose subject was "How should we refactor these fat Rails models?" > > I've been dragged into incredibly boring meetings to discuss Rails versus > Sinatra, where the main thing under discussion was really the issue of > configuration. > > When I am on my deathbed, looking back, I will recall some days fondly, > and other days I will recall as wasted, and the most sadly wasted days of > all are the days I was forced to discuss Dependency Injection with my > co-workers. > > None of my experiences allow me to agree with Stuart Sierra that OOP makes > it obvious how to configure an app. > > Still, without a doubt, there are good ideas in Stuart Sierra's Component > library, and it is worth digging into them to find the good ideas. > > The place where I diverge from Stuart Sierra is in his use of Records. His > main concern seems to be making dependencies visible. It's the same issue > that Alex Miller focuses on here: > > http://tech.puredanger.com/2014/01/03/clojure-dependency-injection/ > > My own preference for making dependancies obvious is to use :pre > assertions. I'm looking at Typed Clojure as a possibility for going further > down that road. > > There might be use cases where it is fundamentally imperative to use > something like Stuart Sierra's pseudo-OOP style, but I have not met those > use cases yet. Most of the work I do tends to be the kind of thing where I > can spin up some internal "workers" and have them pull work off a queue. I > can initiate the workers from my "start" function and stop them with the > "stop" function. Typically, each worker will have its own connection to 1 > or more databases, and each worker takes responsibility for closing its > database connections once the "stop" function has been called. > > All of this is easy to do within the Functional Paradigm. > > I think there is a fascinating sociological question that haunts the > Clojure community, regarding OOP. Many of the best Clojure developers spent > 10 or 20 years doing OOP before they came to Clojure, so how much do they > bring OOP with them because they feel its natural, and they feel it natural > because they spent so many years with the OOP style? > > > > > > > > > > > > > > On Wednesday, June 17, 2015 at 10:15:21 PM UTC-4, Xiangtao Zhou wrote: >> >> hi guys, >> >> Constructing simple clojure project is trival, just make functions. if >> the project grows large, with more datasources, message queue, and other >> storages, dependencies problem is on the table. >> >> One solution is stuartsierra/component, using system to configure >> dependencies graph, make component and dependencies resolution separate. >> >> If we make namespace must run with code block that init the namespace, >> like the "start" method in component, is this a good way to solve the >> dependencies? >> >> because when the namespace is required the first time, the init block >> worked once. >> >> any suggestion is appreciated. >> >> >> - Joe >> > -- > You received this message because you are subscribed to the Google > Groups "Clojure" group. > To post to this group, send email to clojure@googlegroups.com > <javascript:_e(%7B%7D,'cvml','clojure@googlegroups.com');> > Note that posts from new members are moderated - please be patient with > your first post. > To unsubscribe from this group, send email to > clojure+unsubscr...@googlegroups.com > <javascript:_e(%7B%7D,'cvml','clojure%2bunsubscr...@googlegroups.com');> > For more options, visit this group at > http://groups.google.com/group/clojure?hl=en > --- > You received this message because you are subscribed to the Google Groups > "Clojure" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to clojure+unsubscr...@googlegroups.com > <javascript:_e(%7B%7D,'cvml','clojure%2bunsubscr...@googlegroups.com');>. > For more options, visit https://groups.google.com/d/optout. > -- “One of the main causes of the fall of the Roman Empire was that–lacking zero–they had no way to indicate successful termination of their C programs.” (Robert Firth) -- You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en --- You received this message because you are subscribed to the Google Groups "Clojure" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojure+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.