One major side effect has been to mitigate the kinds of heavy nesting you see in functional languages like WL and Clojure. Personally I think the resulting code resembles the phrase structure of English much more closely. It's a huge readability win.
The original motivations for operator forms were in fact writing Queries [1] against Datasets [2], for which you want to represent complex operations independent of their execution.
[0] http://reference.wolfram.com/language/guide/FunctionComposit...
I don't think the exact details are the same, because our operators don't actually evaluate to transformers (they remain totally symbolic). Rather, the conversion of composed operators to an actual reducer pipeline happens lazily 'at the right time', which I think will make optimization a bit easier to express.
Map[#^2&] /* Select[PrimeQ] /* Select[OddQ]
into Select[OddQ[#] && PrimeQ[#]&] /* Map[#^2&]
and so on via rules that look like: Select[s1_] /* Select[s2_] :> Select[s1[#] && s2[#]&]
Map[f_ ? SideEffectFreeQ] /* s_Select :> s /* Map[f]
Map[Extract[p_Integer | p_Key]] :> Extract[{All, p}]
I'm already doing a bunch of that for Dataset.But in reality you need to move to a DSL for complex enough rules, and then Clojure and WL will be on the same footing (Clojure even a bit stronger, maybe, WL doesn't really have a proper macro system).
Does Clojure core do or allow for any of that kind of optimization already?
even_selector = Select[EvenQ]
incrementor = Map[Inc]
decrementor = Map[Dec]
even_incremented_selector = incrementor * even_selector (????)
odd_selector = even_incremented_selector * decrementor
even_selector[{1,2,3,4,5,6,7}] => {2,4,6}
even_incremented_selector[{1,2,3,4,5,6,7}] => {2,4,6,8}
odd_selector[{1,2,3,4,5,6,7}] => {1,3,5,7}
However I'm not entirely sure I've understood things correctly, I just stared at it for a while and need to get back to work...
(edit: HN does _not_ like formatting)
Rich is talking about something deeper, in which operators like filter become transformers that themselves operate on stateful processors (reducers) to produce new stateful processors that have incorporated the action described by the original operator.
(comp (transducer map inc) (transducer filter even?))
Of course, it's more typing and doesn't look as nice as single-arity map, but it goes along quite well with (partial map inc).
I can be wrong but to this date Clojure didn't have a function that produces completely different things based on arity, did it?
There is no reason the exact same name should be used for two different things. It is a lot harder to tell the difference between (map inc) and (map inc xs) then it is to tell the difference between (transducer-map inc) and (map inc xs).