Live data from Hacker News

Transducers are coming to Clojure

blog.cognitect.com

1–10 of 103 posts

Re: Transducers are coming to Clojure

#3

Not sure I understand - so Clojure is getting first class support for lazy collections and curried combinators? Or am I missing the important part?

Many Clojure abstractions need things like map, filter, concat, etc. Reducers are eager, lazy-seqs are lazy, and core.async channels are lazy and push-based. This is a way to unify all these abstractions so that you can write a single map/filter/concat transform once, and use it in many different ways.

Re: Transducers are coming to Clojure

#4

Not sure I understand - so Clojure is getting first class support for lazy collections and curried combinators? Or am I missing the important part?

I think this is just announcing that the Clojure core libraries are gaining another arity for many functions specifically for this usage so that you don't have to use (partial) or the short-hand #() syntax to use this pattern. I assume the goal is more community awareness and cleaner syntax for the re-use of this pattern.

Re: Transducers are coming to Clojure

#5
post #3

Not sure I understand - so Clojure is getting first class support for lazy collections and curried combinators? Or am I missing the important part?

Many Clojure abstractions need things like map, filter, concat, etc. Reducers are eager, lazy-seqs are lazy, and core.async channels are lazy and push-based. This is a way to unify all these abstractions so that you can write a single map/filter/concat transform once, and use it in many different ways.

Isn't there some overlap between this and extend-protocol? To my vague understanding this is from the functional composition angle instead of a type, but otherwise don't they accomplish the same thing?

Re: Transducers are coming to Clojure

#6

Not sure I understand - so Clojure is getting first class support for lazy collections and curried combinators? Or am I missing the important part?

I think this is just announcing that the Clojure core libraries are gaining another arity for many functions specifically for this usage so that you don't have to use (partial) or the short-hand #() syntax to use this pattern. I assume the goal is more community awareness and cleaner syntax for the re-use of this pattern.

No, (map f) is not curried map. It returns an entirely different thing - a function of reducing function to reducing function, aka a reducing function transformer, aka a transducer.

Re: Transducers are coming to Clojure

#7
post #3

Not sure I understand - so Clojure is getting first class support for lazy collections and curried combinators? Or am I missing the important part?

Many Clojure abstractions need things like map, filter, concat, etc. Reducers are eager, lazy-seqs are lazy, and core.async channels are lazy and push-based. This is a way to unify all these abstractions so that you can write a single map/filter/concat transform once, and use it in many different ways.

> This is a way to unify all these abstractions so that you can write a single map/filter/concat transform once, and use it in many different ways.

I don't understand why these things aren't all unified in the first place, it's just function composition we're talking about here right?

Edit: I mean it's clearly not just simple function composition, but I don't understand why not

    (def xform (comp (map inc) (filter even?))) ; xform is a transducer
    (defn xform [aseq] (->> aseq (map inc) (filter even?))) ; xform is a fn
Why do these have to be different things? Why is there a need for machinery to do what fn composition is supposed to do?

Re: Transducers are coming to Clojure

#8
post #3

Not sure I understand - so Clojure is getting first class support for lazy collections and curried combinators? Or am I missing the important part?

Many Clojure abstractions need things like map, filter, concat, etc. Reducers are eager, lazy-seqs are lazy, and core.async channels are lazy and push-based. This is a way to unify all these abstractions so that you can write a single map/filter/concat transform once, and use it in many different ways.

Yeah, when looking at core.async transformers and the reducer library, it seemed clear that there was some generality in there that could be factored out. Glad someone smarter than me figured out what it was.

Re: Transducers are coming to Clojure

#9
post #3

Earlier quoted context omitted.

Many Clojure abstractions need things like map, filter, concat, etc. Reducers are eager, lazy-seqs are lazy, and core.async channels are lazy and push-based. This is a way to unify all these abstractions so that you can write a single map/filter/concat transform once, and use it in many different ways.

> This is a way to unify all these abstractions so that you can write a single map/filter/concat transform once, and use it in many different ways. I don't understand why these things aren't all unified in the first place, it's just function composition we're talking about here right? Edit: I mean it's clearly not just simple function composition, but I don't understand why not (def xform (comp (map inc) (filter even…

Your typical definition of map, filter etc includes concrete usage of e.g. lists. These don't. Transducers are not just currying or partial application of the map function over lists, they isolate the logic of map, filter etc from lists or any particular context, allowing them to be used in very different (e.g. non-collection) contexts.

Re: Transducers are coming to Clojure

#10

Earlier quoted context omitted.

> This is a way to unify all these abstractions so that you can write a single map/filter/concat transform once, and use it in many different ways. I don't understand why these things aren't all unified in the first place, it's just function composition we're talking about here right? Edit: I mean it's clearly not just simple function composition, but I don't understand why not (def xform (comp (map inc) (filter even…

Your typical definition of map, filter etc includes concrete usage of e.g. lists. These don't. Transducers are not just currying or partial application of the map function over lists, they isolate the logic of map, filter etc from lists or any particular context, allowing them to be used in very different (e.g. non-collection) contexts.

By "map in a non-collection context", what would be an example? Say, mapping a boolean negation function over the bits of an integer, to produce its complement? How does that look with transducers?
Post reply on HN