Transducers now available for Java/JavaScript/Ruby(cognitect-labs.github.io)
cognitect-labs.github.io
Transducers now available for Java/JavaScript/Ruby
http://cognitect-labs.github.io/
4 comments
I don't understand anything on the linked page. I have a CS degree.
I wouldn't worry. There's more to CS that any one person can know :) I can't play the violin, even though I have a degree in playing the piano.
Trite. A good a CS education will help you understand the relationships between abstractions like these and the physical circuitry that makes it possible. You don't get to just write the significance of this design pattern off because you can't grok it.
Playing the violin takes hard earned, tactile expertise to the specific end of being able to pay the violin (not required: the ability to read music, compose original pieces, or know how to physically construct a violin).
Separating implementation details from performant, coherent, composible abstractions is not just another skill to specialize in, not just another programing language specialization to acquire- it's the entire pursuit of our industry.
Playing the violin takes hard earned, tactile expertise to the specific end of being able to pay the violin (not required: the ability to read music, compose original pieces, or know how to physically construct a violin).
Separating implementation details from performant, coherent, composible abstractions is not just another skill to specialize in, not just another programing language specialization to acquire- it's the entire pursuit of our industry.
As best I can tell, it separates iteration ("stepping") from transformation, so that transformers can be applied more flexibly and be composed more easily.
This is certainly elegant but I'm not sure I'd want to work in a large codebase full of this kind of code. Sometimes it's easier to just see a loop spelled out in front of you. I'm a critic of Go in many ways but I do think there is something to their principle of keeping code very simple and readable and localized.
I think this is ok if you only use once, but as soon as you begin to use the same alorithm in multible places and contects you be happy with having it stored in one place.
In go you will have to replicate to logic every single time. I have not used much, but the fact that I cant even use generic map/filter things make me not want to try it. Even when I first learned programming (in C) I was trying to figure out how not to write for (int x=0;x==5;x++) again and again. I dont really want to go back to that.
In go you will have to replicate to logic every single time. I have not used much, but the fact that I cant even use generic map/filter things make me not want to try it. Even when I first learned programming (in C) I was trying to figure out how not to write for (int x=0;x==5;x++) again and again. I dont really want to go back to that.
I'm sure something said that about for loops vs goto some time ago :) Personally (which is important, readability is relative) I find for loops less readable than traditional FP functions like filter, any?, map, etc - I don't have to carefully read the entire for loop to know what's going on. I prefer composability of known pieces, over constructs that can do anything.
Much of the spec and the lib for the ruby version reads like it was written by a clojurist. That may sound funny, but it was all written by David Chelimsky, a long time rubyist who maintained RSpec.
To me the most interesting aspect of the Ruby implementation is the use of pseudo macros that meta-program most of the implementation.
To me the most interesting aspect of the Ruby implementation is the use of pseudo macros that meta-program most of the implementation.
Agreed, the code could be made a bit more idiomatic.
Introducing a Transducable module would also make sense in the OOP perspective. Replacing Transducer.transduce(transducer, ...) calls with transducer.transduce(...), same with Transducer.compose
Introducing a Transducable module would also make sense in the OOP perspective. Replacing Transducer.transduce(transducer, ...) calls with transducer.transduce(...), same with Transducer.compose
In python I can do:
filter(lambda x: x%2==0, xrange(10))
Is this basically the same concept?No, because chaining that with an additional filter operation will create intermediate lists.
If filter() returned an iterator instead of a list would the answer be yes?
Essentially, yes. The performance benefit that transducers provide can also be obtained by using iterator versions of map, reduce, and filter.
Unlike those traditional functions, however, transducer versions are composable. So I can put a whole bunch of maps, reducers, and filters in a row, and assign that composition to a variable. Then I can apply that composition to any type of collection and know that it only requires one pass.
Unlike those traditional functions, however, transducer versions are composable. So I can put a whole bunch of maps, reducers, and filters in a row, and assign that composition to a variable. Then I can apply that composition to any type of collection and know that it only requires one pass.
Or by a sufficiently smart compiler that realises it can fuse the intermediate steps into a single loop (like GHC)?).
So, the appeal of transducers is plug-and-play fusion. Like, it takes quite a bit of work to get newly created non-list types to fuse correctly in Haskell (that being said: you can do it in Haskell, which is kind of amazing considering how ridiculously impossible this is in almost every toolset, and popular libraries already have, which is also amazing). Transducers get you stream fusion for e.g. channels in a close-to-free way (you define the stepping function, you get takeWhile, partition-by, etc. all for free, so it's O(1) instead of O(n)-O(n^2) to figure out all the combos you want to stream together).
EDIT: _part_ of the appeal. The other is concisely describing things like takeWhile in a way that's both polymorphic and doesn't require multiple implementations. Good refactor motivation in general, happens to have the above property, which is good.
EDIT: _part_ of the appeal. The other is concisely describing things like takeWhile in a way that's both polymorphic and doesn't require multiple implementations. Good refactor motivation in general, happens to have the above property, which is good.
[deleted]
in python3 filter returns an iterator.