Transducer: Composition, Abstraction, Performance (2018)
Postedabout 2 months agoActiveabout 2 months ago
funktionale-programmierung.deTechstory
calmpositive
Debate
20/100
TransducersClojureFunctional Programming
Key topics
Transducers
Clojure
Functional Programming
The article discusses transducers, a concept in functional programming, and their benefits in terms of composition, abstraction, and performance, with commenters sharing their experiences and alternative perspectives.
Snapshot generated from the HN discussion
Discussion Activity
Light discussionFirst comment
4d
Peak period
5
96-108h
Avg / period
3.3
Key moments
- 01Story posted
Nov 4, 2025 at 5:32 AM EST
about 2 months ago
Step 01 - 02First comment
Nov 8, 2025 at 12:16 AM EST
4d after posting
Step 02 - 03Peak activity
5 comments in 96-108h
Hottest window of the conversation
Step 03 - 04Latest activity
Nov 8, 2025 at 9:33 PM EST
about 2 months ago
Step 04
Generating AI Summary...
Analyzing up to 500 comments to identify key contributors and discussion patterns
ID: 45809429Type: storyLast synced: 11/20/2025, 12:08:29 PM
Want the full context?
Jump to the original sources
Read the primary article or dive into the live Hacker News thread when you're ready.
A transducer is simply a function of the form `a -> List<b>`. Yes this is fully polymorphic, i.e. it holds even for transducers that only operate over just lists.
In this case `mapping` is just
This lens views a transducer through the lens of the `eduction` function as a more souped up `map`. Whereas with a normal `map` you only get to use a function `a -> b`, which means you can't change the underlying structure, with `eduction` you get to use `a -> List<b>` (again a transducer), where you "keep" any elements that are in the output list and you "discard" any elements not in the output list.
So e.g. `mapping` would be:
or in Python and `filtering` would be: or in Python In my opinion way clearer and easier!For more details on the full equivalence see https://news.ycombinator.com/item?id=27778423
The current presentation of transducers has always felt like a wart in Clojure.
I don't see what your functions have to do with that.
My functions are exactly equivalent to transducers.
My link in the original comment goes over it at a more theoretical level.
But if you want runnable code, I've included Clojure below that translates between the two representations (there's some annoying multi-arity stuff I haven't handled very rigorously, but that's mainly an artifact of the complection in the traditional Clojure representation of transducers and goes away when you think of them as just `a -> List<b>`).
There's a line in the original article that the author doesn't go far enough on. "Everything is a fold." Yes more than that, folding is not just a function over a list, a fold is a list and vice versa (this holds for any algebraic datatype). Transducers are just one example of this, where Clojure has decided to turn a concrete data structure into a higher order function (wrongly I believe; although I haven't gone to the effort of truly specializing all my functions to verify my suspicions that you can actually get even better performance with the concrete data representation as long as you use specialized data containers with specialized behavior for the zero and one element cases).
The thing about transducers is that once you start using them, the abstractions click in your mind and you start using them more and more in your code. Many things our software does can be looked at as pipelines, and transducers let you write composable functions and put them together into pipelines. As you see more pipelines in your code, you will write those composable functions and reuse them in various places.
Experienced Clojure programmers will rarely use loops, for me transducers are the #1 choice whenever I have to process a collection of any kind.
Their efficiency (no intermediate collections!) is a nice bonus — you get both high-level composable code and efficiency, which is incredible.
One thing I dislike about transducers is when I need a stateful one: these are hard to understand and very difficult to write. I rarely do this, except when I really want to stick to the transducer abstraction and I have a couple of hours to spend on a puzzle. But you rarely need to write your own stateful transducers, usually the built-in ones are enough (things like take/drop).
See `ttake` here: https://news.ycombinator.com/item?id=45859831
So something to note about transduce is that it looks a lot like reduce but suddenly the examples [0] start being more complex functions where some elements of the collection get removed, order matters and state begins to appear during the fold. Functions like `take`, `filter`, `partition`, `interpose`, `dedupe`, etc, etc.
As with many things in the functional world (cough monads) I feel the explanations don't make a lot of sense before meeting the problem they solve in the wild. As with a lot of Clojure's better parts transducers are a state management tool.
[0] https://clojure.org/reference/transducers
It starting to be quite some time ago, but I can answer some questions if you have any.