Hi, I did some progress here, I was able to manage to create a custom filter transducer that works seamlessly with regular values and channels and can be composed with other transducers:
; on JVM I did this using protocols, but in ClojureScript I could not make it work (some error when I tried to extend the ReadPort type), but this works as same (defn -expand [v f] (if (satisfies? cljs.core.async.impl.protocols/ReadPort v) (take! v f) (f v))) ; my filter transducer that supports async operations (defn filter-ext [pred] (fn [f1] (fn ([] (f1)) ([result] (f1 result)) ([result input] (-expand (pred input); here is the trick, so in this case I made every operation dependent on a callback, so they can be normalized (fn [v] (if v (f1 result input) result))))))) (let [value-chan (fn [v] (let [c (chan 1)] ; simple helper to simulate an async operation that just returns the input (put! c v) (close! c) c)) xform (comp (filter-ext value-chan) ; ok, filter async (filter-ext #(>= % 2))) ; now filter sync c (chan 1 xform)] (async/onto-chan c [1 false 2 3]) (go (println (<! (async/into [] c))))) ; prints: [2 3] I could have my extended versions of every transducer to add the support, the code is pretty much the same but has the extra step of checking for the returned value on the operation. Not sure how that could ever be integrated into regular transducers (maybe they could be extended somehow to include this feature selectively to avoid the overhead), but for now this is the best that I could came up with. --- Wilker LĂșcio http://about.me/wilkerlucio/bio Woboinc Consultant +55 81 82556600 On Sun, Sep 21, 2014 at 10:39 PM, Wilker <wilkerlu...@gmail.com> wrote: > > On Sun, Sep 21, 2014 at 10:08 PM, Sean Corfield <s...@corfield.org> wrote: > >> > Hi Sean, > > Sorry, I don't really understood your suggestion... But let me try to make > myself more clear of what I'm trying to accomplish: > > First let me say that I have a more Javascript background than Java, and > my issue is more into ClojureScript world > > Javascript has a lot of async issues, specially when you are working on > Node.JS world, every IO operation is async, although they have sync > versions those versions block the world so I need to keep away from then, > so, async callbacks is my only real options here. > > The first thing that I like to do in my async code is to wrap than into > something that I can handle generically, in JS I used to do a lot of > promises code, but now I'm core async, so I think making then "single > channel value" just fits nice, and wrapping that way I can compose very > well. > > Now I'm at this place, I have all those async functions that I wanna use > to process my data, I wanna use those async functions, also regular > functions. > > Before transducers, I've used the David Nolen's reactive helpers (on his > blog source) to do my data processing using those channels, a good example > on how I used to manage complex async pipelines are like this: > > (->> (scan-path "root/path") ; this will produce a channel that will > output every file/dir path recursive from given path > (r/filter-async is-file?) ; this requires async call to filter > (f/filter (match-extension? #{"avi" "mpg"})) ; this will just check > on the name, no async required > (r/map-async read-hash-info) ; another async call, will generate a > hash info from the path > (r/map #(hash-map :hash %)) ; build a map from the value > ) > > So, I like how the previous code is build, because I can really just > composed from my simple sync and async functions, but all these use "custom > transducers" you can say... > > Then comes Transducers that can rise the bar on the abstraction level, so > I now can get rid of all those custom transducers, right? > > So, it just would be nice if I could get the same clean way to build my > pipeline like I did before, but with transducers. > > --- > Wilker LĂșcio > http://about.me/wilkerlucio/bio > Woboinc Consultant > +55 81 82556600 > -- 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.