Seems like the next step for this would be for me to put together a blog with an example Component system, and its equivalent Yoyo system?! :) Should have time for that over the weekend.
James On Thursday, 25 June 2015 09:05:39 UTC+1, James Henderson wrote: > > > > On Wednesday, 24 June 2015 11:17:41 UTC+1, Atamert Ölçgen wrote: >> >> >> >> On Tue, Jun 23, 2015 at 11:47 PM, James Henderson <ja...@jarohen.me.uk> >> wrote: >> >>> Hi Atamert - thanks :) >>> >>> I thought it might be preferable to keep the call to (latch)explicit - >>> it means that ylet can be used in nested calls, too - for example, to >>> set up and compose groups of components/sub-systems: (contrived example, >>> though!) >>> >>> ;; (docs for ylet at >>> https://github.com/james-henderson/yoyo#introducing-ylet ) >>> >>> (require '[yoyo :refer [ylet]]) >>> >>> (defn with-connections [config f] >>> (ylet [db-pool (with-db-pool (:db config)) >>> es-conn (with-es-connection (:elasticsearch config))] >>> >>> (f {:db-pool db-pool >>> :es-conn es-conn}))) >>> >>> (defn make-system [latch] >>> (let [config ...] >>> (ylet [connections (with-connections system) >>> _ (with-webserver {:handler (make-handler (merge connections >>> {:config >>> config})) >>> :port 3000})] >>> (latch)))) >>> >>> >>> How would you see the with-* functions working, btw? >>> >> >> I think the general idea should be to provide a clean API to the consumer >> (of your lib). Perhaps something that accepts a start function, a stop >> function and some sort of main loop (f in your example). >> > > Not sure I understand what you mean here? Tbh, I was trying to get away > from the idea of separate start & stop functions - it seems 'cleaner' to me > without them! (although of course that's subjective). > > Also, the 'with-*' functions here are consumer code - the only Yo-yo > functions/macros in this example are 'run-system!' and 'ylet'. Yo-yo itself > is *tiny* (<100 LoC) - my aim was for a library that solely dealt with > starting/stopping a provided system, and *no more* :) > > Maybe it'd be worth fleshing out an example of what you were looking for? > > Cheers, > > James > > >> >>> >>> Cheers, >>> >>> James >>> >>> On Tuesday, 23 June 2015 09:57:16 UTC+1, Atamert Ölçgen wrote: >>>> >>>> Hi James, >>>> >>>> Interesting idea. Thanks for sharing. >>>> >>>> I think you can simplify this: >>>> >>>> (yoyo/run-system! >>>> (fn [latch] >>>> (ylet [db-pool (with-db-pool {...}) >>>> :let [server-opts {:handler (make-handler {:db-pool db-pool}) >>>> :port 3000}] >>>> web-server (with-web-server server-opts)] >>>> (do-this web-server) >>>> (do-that db-pool web-server) >>>> (latch)))) >>>> >>>> >>>> to: >>>> >>>> (yoyo/foo! [db-pool (with-db-pool {...}) >>>> :let [server-opts {:handler (make-handler {:db-pool >>>> db-pool}) >>>> :port 3000}] >>>> web-server (with-web-server server-opts)] >>>> (do-this web-server) >>>> (do-that db-pool web-server)) >>>> >>>> >>>> I believe with-* function can also be simplified further. >>>> >>>> >>>> On Tue, Jun 23, 2015 at 1:18 AM, James Henderson <ja...@jarohen.me.uk> >>>> wrote: >>>> >>>>> Hi all, >>>>> >>>>> I've just released an early version of 'Yo-yo', a protocol-less, >>>>> function composition-based alternative to Component. It's still in its >>>>> early stages, so feedback would be very much appreciated! >>>>> >>>>> https://github.com/james-henderson/yoyo >>>>> >>>>> Yo-yo was also an experiment to see what could be de-coupled from the >>>>> concept of 'reloadable systems', so you won't find any configuration, >>>>> dependency injection, etc - just a way to write a system that can be >>>>> easily >>>>> started, stopped, and reloaded. >>>>> >>>>> Fundamentally, we start by assuming there's a function available that >>>>> only returns 'when the system stops' - a 'latch', say. If we had such a >>>>> function, we could start our system, call that function, then stop the >>>>> system (closing any necessary resources). A database pool, for example, >>>>> might look like this: >>>>> >>>>> (defn with-db-pool [db-config f] >>>>> (let [db-pool (start-pool! db-config)] >>>>> (try >>>>> (f db-pool) >>>>> >>>>> (finally >>>>> (stop-pool! db-pool))))) >>>>> >>>>> Here, we're assuming that we'll be passed 'f', the 'latch' function. >>>>> A web server would be similar, and, because they're both functions, >>>>> they're >>>>> very simple to compose: >>>>> >>>>> (with-db-pool {...} >>>>> (fn [db-pool] >>>>> (with-web-server {:handler (make-handler {:db-pool db-pool}) >>>>> :port ...} >>>>> (fn [web-server] >>>>> ;; TODO: Ah. We've run out of turtles. :( >>>>> )))) >>>>> >>>>> This is where Yo-yo comes in - there’s a function called run-system!, >>>>> which takes a function that accepts a latch: >>>>> >>>>> (:require [yoyo]) >>>>> >>>>> (yoyo/run-system! >>>>> (fn [latch] >>>>> (with-db-pool {...} >>>>> (fn [db-pool] >>>>> (with-web-server {:handler (make-handler {:db-pool db-pool}) ; >>>>> n.b. we have access to the db-pool here - no need for global state! >>>>> :port ...} >>>>> (fn [web-server] >>>>> (latch))))))) ; Aha! >>>>> >>>>> run-system! then returns a promise - deliver any value to it, and >>>>> it'll stop the system. >>>>> >>>>> And that's pretty much it! There are a few more functions - mostly to >>>>> do with easily starting/stopping/reloading a system through the REPL, and >>>>> a >>>>> macro to simplify the 'function staircase' - these are covered in more >>>>> detail in the README. There are some also common components - a database >>>>> pool, a web server, and a simple integration for existing Component >>>>> systems. >>>>> >>>>> It'd be great to hear your thoughts/ideas, whatever they may be - >>>>> either through here, e-mail, Github, or Twitter - thanks! >>>>> >>>>> James >>>>> >>>>> -- >>>>> You received this message because you are subscribed to the Google >>>>> Groups "Clojure" group. >>>>> To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com. >>>>> For more options, visit https://groups.google.com/d/optout. >>>>> >>>> >>>> >>>> >>>> -- >>>> Kind Regards, >>>> Atamert Ölçgen >>>> >>>> ◻◼◻ >>>> ◻◻◼ >>>> ◼◼◼ >>>> >>>> www.muhuk.com >>>> >>> -- >>> You received this message because you are subscribed to the Google >>> Groups "Clojure" group. >>> To post to this group, send email to clo...@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+u...@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+u...@googlegroups.com. >>> For more options, visit https://groups.google.com/d/optout. >>> >> >> >> >> -- >> Kind Regards, >> Atamert Ölçgen >> >> ◻◼◻ >> ◻◻◼ >> ◼◼◼ >> >> www.muhuk.com >> > -- 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.