3 ms·
Low signal-to-noise posts about Clojure are damaging to adoption because it doesn't say anything about why Clojure is a good option on the JVM. Instead, I will
by pgt 8y ago
Low signal-to-noise posts about Clojure are damaging to adoption because it doesn't say anything about why Clojure is a good option on the JVM.
Instead, I will try to give some reasons why Clojure is a good fit for high-performance stream fusion, which I presume AppsFlyer has to do a lot of:
- [Onyx](https://github.com/onyx-platform/onyx https://github.com/onyx-platform/onyx) for distributed, masterless, fault-tolerant data processing
- [core.async](https://github.com/clojure/core.async https://github.com/clojure/core.async) for CSP-style events through a channel abstraction. I miss core.async so much in every other language, I generally end up implementing a subset of the semantics.
- [Transducers](https://clojure.org/reference/transducers https://clojure.org/reference/transducers) for composable transformations, e.g.
(filter odd?) ;; returns a transducer that filters odd
(map inc) ;; returns a mapping transducer for incrementing
(take 5) ;; returns a transducer that will take the first 5 values of a sequence
(def xf
(comp
(filter odd?)
(map inc)
(take 5)))
(into [] xf (range 100)) ;; => [2 4 6 8 10]
Note that no intermediate data structures are created during these transformations, so it's super fast.
- [Specter](https://github.com/nathanmarz/specter https://github.com/nathanmarz/specter) decomplects navigation and transformation, pulling apart the "where" from the "how". In most imperative languages whenever the shape or performance characteristics your data structures change, you also have to update all the code that transforms it. Not with Specter.
- Zach Tellman's [Manifold](https://github.com/ztellman/manifold https://github.com/ztellman/manifold) provides event-streaming abstractions on top of async workflows like lazy sequences, core.async and Java's BlockingQueues.
- madmulita 8y agoWait! What? That's what 'transducers' means? Being new to Clojure I've been avoiding some concepts until later, but if they hadn't renamed old concepts, ie: higher order functions to transducers, maybe newbies wouldn't get scared.
- andrenth 8y agoI’m not a Clojure programmer but from the example given, “transducers” would be equivalent to lazy evaluation / stream fusion. Simple HOFs wouldn’t prevent the elements to be traversed in each subsequent function call.
- the2bears 8y agoThat's not what transducers are, though. They're a "recipe" for a function composite. I'm simplifying things, but transducers compose to form a function that then executes against each element in the collection passed in. The main difference is that no intermediary data collections are created. There's more, and it's worth reading up on them.
- zh217 8y agoI totally agree with the "missing core.async" part. Actually I miss them so much in python that I implemented the complete set of semantics in [aiochan](https://github.com/zh217/aiochan https://github.com/zh217/aiochan). (disclaimer: I am the author of aiochan)