Very short version of my question, I am wondering if something like this is going to be efficient, without intermediate collections created by the eductions and with execution of the eduction transducers deferred until the end. Oversimplified approximation of what I’m actually doing:
(->> (myapp/retrieve-posts) ;intermediate coll here
(eduction (map assoc-post-access-level)
(filter post-is-public?)) ;eduction, nothing happens yet
(eduction (map myapp/assoc-tags)) ;eduction passed to eduction, what happens?
(into [] (comp (map myapp/assoc-view-stuff) (take 10)))) ;both eductions called here right? efficient since reducible context?
myapp/template-render
eduction produces a reducible application of the transducers it takes over the coll it takes. From what I can tell looking at clojure.core source, eduction itself also provides a reducible application since it calls transduce on the coll in a reducible context. So neither eduction should have its trasnducers called until we get to into?
This slightly longer example hopefully shows why I want to do this, again a very simplified version of my actual code:
(let [posts (myapp/retrieve-posts)
posts (if anonymous-user?
(eduction (map assoc-post-access-level)
(filter post-is-public?)
posts)
posts)
posts (if need-tags?
(eduction (map myapp/assoc-tags) posts)
posts)]
(myapp/template-render (into []
(comp
(map myapp/assoc-view-stuff)
(take 10))
posts)))
Longer explanation:
Basically what I’m doing is building a site with Pedestal. In Pedestal a web response is built up using a pipeline of narrowly-targeted “interceptors,” which are basically just functions inside of a map.
The idea is to keep each interceptor simple and focused so it can be composed with other interceptors like Lego bricks. So let’s say I’m building up a collection of content posts. I might want to compose a series of functions that do approximately
- Retrieve post maps →
filterpublic posts unless user logged in →- enrich posts (
mapassoc) with tags if we’ll be displaying tags → - enrich posts (
mapassoc) with attributes needed for this particular view template → - render response (with somewhat generic code reusable in other contexts)
It seems to me like eductions are a good use case for this because I’d like to avoid creating intermediate collections in steps 2, 3, and 4. It seems like eduction offers a way to buid up a transduction over a specific collection after that collection is bound into the transduction process early on.
But I am not sure - I am new to eduction and trying to learn where it might be useful. I feel more comfortable with other transducing functions like transduce, sequence, and into.
So I thought I’d ask you folks if anyone knows if this seems like a good/reasonable way to use eductions. Thanks very much in advance for any feedback.