Reputation: 968
(deftask test1 "first test task" [] (print "1") identity)
(deftask test2 "second test task" [] (print "2") identity)
(boot (comp (test1) (test2)))
=> 12nil
(boot (comp (fn [x] (print "1") identity) (fn [x] (print "2") identity)))
=> 21nil
If I use comp
on tasks, the execution order is from left to right. If I use comp
on anonymous functions, the execution order is from right to left. How is this inconsistency reasonable?
Upvotes: 1
Views: 283
Reputation: 13185
The reason for that difference is that when you use comp
with boot tasks is that they are not bare logic that gets composed but each boot tasks returns a function which will be invoked later and that function wraps another function which is passed to it (like in ring middleware).
With plain functions it works like this:
(comp inc dec)
produces a function which does following:
(inc (dec n))
In boot tasks are similar to ring middleware. Each task is a function which returns another function that will wrap the next handler from the pipeline. It works like that (not literally, it's simplified for readability sake):
(defn task1 []
(fn [next-handler]
(fn [fileset]
(print 1) ;; do something in task1
(next-handler fileset))) ;; and call wrapped handler
(defn task2 []
(fn [next-handler]
(fn [fileset]
(print 2) ;; do something in task1
(next-handler fileset)))) ;; and call wrapped handler
So when you do:
(comp (task1) (task2))
And execute such composed task it works as if it was:
(fn [fileset1]
(print 1)
((fn [fileset2]
(print 2)
(next-handler fileset2))
fileset1))
Because a function produces by (task2)
will be passed to function produced by (task1)
which will wrap the one from (task2)
(and call it after printing 1
).
You can read more on boot tasks anatomy in its wiki. It might be also useful to read on ring middleware.
Upvotes: 6