Live data from Hacker News

Rich Hickey – Inside Transducers [video]

youtube.com

11–20 of 50 posts

Re: Rich Hickey – Inside Transducers [video]

#11
So Transducers generalize the usage of Enumerable functions such as map, reduce, filter, flatMap (...).

Please could someone tell me if this is conceptually different from ruby's Enumerable module which only needs the class its included in to implement `each` so anything can be enumerable ? Or is it a similar but just in translated to the FP world ?

Re: Rich Hickey – Inside Transducers [video]

#12

So Transducers generalize the usage of Enumerable functions such as map, reduce, filter, flatMap (...). Please could someone tell me if this is conceptually different from ruby's Enumerable module which only needs the class its included in to implement `each` so anything can be enumerable ? Or is it a similar but just in translated to the FP world ?

What's you're thinking of is more like ISeq in Clojure, or Foldable is Haskell. The more interesting generalisation is not between arrays, vectors and hashsets, but between data structures and event streams.

Re: Rich Hickey – Inside Transducers [video]

#13

So Transducers generalize the usage of Enumerable functions such as map, reduce, filter, flatMap (...). Please could someone tell me if this is conceptually different from ruby's Enumerable module which only needs the class its included in to implement `each` so anything can be enumerable ? Or is it a similar but just in translated to the FP world ?

Yes; There are differences.

1. Transducers are parallel under the covers. Since the expectations is that the code that the predicate or mapping functions that you pass into map, filter and reduce are pure (no variables are changed, no state is modified, just a calculation that is only dependent on arguments) the parallelism is hidden away from you, but it's there. Ruby's Enumerable can't do parallelism

2. When you compose transducers, there are no intermediate sequences generated. The simplest example is this:

In Ruby: [1, 2, 3].map {|x| x + 1}.map {|x| x+ 2} will generate an intermediate array [2, 3, 4] after the first map, and then will generate [4, 5, 6] when it has evaluated the whole expression.

In Clojure (I am sure I got the syntax wrong for this one) (transduce (map #(+ 2 %) (map inc)) [1 2 3]) will create an intermediate mapping function that will first increment, then add 2 to its argument, and then will map once using that intermediate function.

Re: Rich Hickey – Inside Transducers [video]

#14
post #2

Again a more technical talk. I really liked it. Specially the end bit about pipelines, that seams like it would be really usful. Transducers overall are quite intressting, I am exited to see what other transducer context people come up with.

It's not that clear there will be one. Transducers have three steps: begin, during and end. In practice, start is only used for reduce operations and outside of reduce operations end can only be used for its side effects.

There's also definitional issues e.g. can you have an async transducer?

Re: Rich Hickey – Inside Transducers [video]

#15

So Transducers generalize the usage of Enumerable functions such as map, reduce, filter, flatMap (...). Please could someone tell me if this is conceptually different from ruby's Enumerable module which only needs the class its included in to implement `each` so anything can be enumerable ? Or is it a similar but just in translated to the FP world ?

Yes; There are differences. 1. Transducers are parallel under the covers. Since the expectations is that the code that the predicate or mapping functions that you pass into map, filter and reduce are pure (no variables are changed, no state is modified, just a calculation that is only dependent on arguments) the parallelism is hidden away from you, but it's there. Ruby's Enumerable can't do parallelism 2. When you co…

Transducers _can be_ parallelized (TODO) but some transducer implementations do contain state, like `take` and therefore cannot be parallelized.

The big thing is no intermediate results.

Re: Rich Hickey – Inside Transducers [video]

#16
post #14
post #2

Again a more technical talk. I really liked it. Specially the end bit about pipelines, that seams like it would be really usful. Transducers overall are quite intressting, I am exited to see what other transducer context people come up with.

It's not that clear there will be one. Transducers have three steps: begin, during and end. In practice, start is only used for reduce operations and outside of reduce operations end can only be used for its side effects. There's also definitional issues e.g. can you have an async transducer?

Yes you can have async and blocking transducers. Forward to the point in the video about channels for a discussion.

Re: Rich Hickey – Inside Transducers [video]

#17
post #15

Earlier quoted context omitted.

Yes; There are differences. 1. Transducers are parallel under the covers. Since the expectations is that the code that the predicate or mapping functions that you pass into map, filter and reduce are pure (no variables are changed, no state is modified, just a calculation that is only dependent on arguments) the parallelism is hidden away from you, but it's there. Ruby's Enumerable can't do parallelism 2. When you co…

Transducers _can be_ parallelized (TODO) but some transducer implementations do contain state, like `take` and therefore cannot be parallelized. The big thing is no intermediate results.

So transducers are like .Net/LINQ enumerables?

Re: Rich Hickey – Inside Transducers [video]

#18

So Transducers generalize the usage of Enumerable functions such as map, reduce, filter, flatMap (...). Please could someone tell me if this is conceptually different from ruby's Enumerable module which only needs the class its included in to implement `each` so anything can be enumerable ? Or is it a similar but just in translated to the FP world ?

Yes; There are differences. 1. Transducers are parallel under the covers. Since the expectations is that the code that the predicate or mapping functions that you pass into map, filter and reduce are pure (no variables are changed, no state is modified, just a calculation that is only dependent on arguments) the parallelism is hidden away from you, but it's there. Ruby's Enumerable can't do parallelism 2. When you co…

Thanks for the answer. Indeed Ruby in general has the limitations inherent to its "non functional" nature. However regarding 2) Enumeration can now (in ruby 2.0) be lazy and thus take each item one after the other through the whole chain.

(1..Float::INFINITY).lazy.map{|a| p a; a*10}.map{|a| p a+1} # => 1 11 2 21 etc...

So it can work with streams & so on... But I know (from a Jessica Kerr presentation) it also has limitations there.

Re: Rich Hickey – Inside Transducers [video]

#19
post #4
post #3

For those not familiar with Clojure, here's a great demonstration of the concept done up in JavaScript: http://jlongster.com/Transducers.js--A-JavaScript-Library-fo...

From that link: "The reduce function is the base transformation; any other transformation can be expressed in terms of it (map, filter, etc)." This seems so obvious in retrospect -- I can't believe I had never made that connection before.

Yeah. That's actually how you implement lists in lambda calculus, as opaque functions that accept a "visitor". There are two different ways of doing it:

    -- Mogensen-Scott encoding
    data ScottList a = ScottList (forall r. (a -> ScottList a -> r) -> r -> r)

    -- Boehm-Berarducci encoding
    data ChurchList a = ChurchList (forall r. (a -> r -> r) -> r -> r)
Roughly, the first encoding gives you pattern matching, and the second gives you foldr (reduce). Either of these operations is sufficient to do anything with the list.

Also note that both of these are encodings of lazy (potentially infinite) lists. To encode strict (guaranteed finite) lists, you really need algebraic data types like in ML, the visitor pattern can't do that.

Re: Rich Hickey – Inside Transducers [video]

#20
post #15

Earlier quoted context omitted.

Yes; There are differences. 1. Transducers are parallel under the covers. Since the expectations is that the code that the predicate or mapping functions that you pass into map, filter and reduce are pure (no variables are changed, no state is modified, just a calculation that is only dependent on arguments) the parallelism is hidden away from you, but it's there. Ruby's Enumerable can't do parallelism 2. When you co…

Transducers _can be_ parallelized (TODO) but some transducer implementations do contain state, like `take` and therefore cannot be parallelized. The big thing is no intermediate results.

If you watch the first Rich Hickey Transducers talk, he shows that some transducers (the ones that rely in the underlying reduce implementation that uses fork/join and assumes that reducing the collection is associative) are already parallelized. I agree with you regarding `take`
Post reply on HN