Live data from Hacker News

Rich Hickey – Inside Transducers [video]

youtube.com

41–50 of 50 posts

Re: Rich Hickey – Inside Transducers [video]

#41
post #33
post #29

Earlier quoted context omitted.

Nah, Clojure seqs are more like .NET/LINQ enumerables. Functions that work over seqs/enumerables return a new seq/enumerable. From what I understand, and I'm sure I am wrong, a transducer receives and transforms a value, and may call the next transducer with the transformed value. The nice thing is that a transducer does not create intermediate results (a seq/enumerable), and that it doesn't make any assumptions on t…

A contrived example in C#/LINQ Enumerable.Range(1, 100) .Where(n => n % 2 == 0) .Select(n => n * 2) .ToList(); And as a transducer it could looks something like this? sequence( Enumerable.Range(1, 100), compose( filter(n => n %2 == 0), map(x => x + 1) ) ).ToList(); On the linq side it would create only 2 enumerable objects (one for where and select) and the ToList would result in a copy the object pointer as it was p…

With Linq you can't really create an object/function that describes the transformation that should happen. I start with an enumerable, describe how to transform /that/ enumerable, and in the end have something that describes a transformation applied to a particular initial data. I can't do anything with it but laziy read the transformed values for the original input.

With transducers I can describe a transformation that should happen to /some/ reducable input, and in the end have something that represents just the transformation. I. An then apply that to any reducable input I have.

[edit]

Your example becomes:

  var incrementedEvens = compose(
      filter(n => n %2 == 0),
      map(x => x + 1)
  );
  transduce(Enumerable.range(0, 100), incrementEvens);

  var lowerAlph = compose(
    filter(x => Character.isAlpha(x)),
    map(x => x.ToLowercase())
  );
  System.in.setTransducer(lowerAlpha);
You can really do that in Linq.

Re: Rich Hickey – Inside Transducers [video]

#42
post #9

Earlier quoted context omitted.

Most people use underscore/lodash for this stuff. The difference is that the js transducers libraries don't create intermediate arrays, only do enough work to produce the requested output, and work on top of anything that can be coerced into the iteration protocol. I've seen demos of using Facebook's Immutable JS, CSP.js [1], and I don't see why you couldn't put them on top of Typed Arrays or a FRP library like Kefir…

Yeah, the overhead of creating intermediate typed arrays is exactly what I'm trying to avoid with this.

Lo-Dash 3.0 will have support for lazy evaluation in its chaining syntax that supports shortcut fusion and avoids intermediate arrays as well.

Re: Rich Hickey – Inside Transducers [video]

#43
post #31

Earlier quoted context omitted.

People keep attacking him whenever he interduces something. Why? Every time he releases something, he also shows from what research it originated. Go back to the first transducer talk and you will see the references.

Personally, I don't mind him too much even though I'm a typeful-programming weenie. That said, he does have a tendency to somewhat unfoundedly say "... and you couldn't do this in a typed language" (or at least allude to it)... whereas people again and again show that, yes, it could be done in a statically typed language. In fact, this is trivially true in a sense as shown by Bob Harper[1] another person who is undou…

In the strangeloop talk his argument seemed to be that you couldn't use types to describe the entire and exact contract of transducers. Which is true (and true of almost anything), but you can at least describe a significant enough chunk of it to reduce errors.

As always it's a trade off. As you try to capture more of the contract, you massively increase complexity, sometimes to the point of reducing usability (i.e. staring at an obtuse type error, or trying to work out how to do basic things with a function just from a Scala type)

It's my interpretation that "you can't type transducers" is an invitation to think more deeply about types and the limitations in what they can express, mixed in with some "get off my back about creating a dynamically typed language".

Re: Rich Hickey – Inside Transducers [video]

#44

Earlier quoted context omitted.

Personally, I don't mind him too much even though I'm a typeful-programming weenie. That said, he does have a tendency to somewhat unfoundedly say "... and you couldn't do this in a typed language" (or at least allude to it)... whereas people again and again show that, yes, it could be done in a statically typed language. In fact, this is trivially true in a sense as shown by Bob Harper[1] another person who is undou…

In the strangeloop talk his argument seemed to be that you couldn't use types to describe the entire and exact contract of transducers. Which is true (and true of almost anything), but you can at least describe a significant enough chunk of it to reduce errors. As always it's a trade off. As you try to capture more of the contract, you massively increase complexity, sometimes to the point of reducing usability (i.e.…

Isn't the problem with transducer typing is that transducers aren't very functional? In one of your posts you wrote:

   System.in.setTransducer(lowerAlpha);
In the LINQ/functional origami world, you could only produce new streams, not transform an existing stream in place. Because a new stream is computed, a new type can be computed. However, from what I've seen with transducers, they would be limited to basically Func, T> signatures.

Re: Rich Hickey – Inside Transducers [video]

#45

Even if you forget entirely about Clojure for a second, Rich has this very rare gift to take a complicated subject and make it easy for the audience to understand.

This is a double-edged sword. Forgive me a small anecdote: I once had a wonderful tutor who could explain any advanced concept in highly intuitive terms and it just made sense... until I got out of the classroom. At which point I'd just have this feeling of "Hang on, whaaaaaa...?". The first time I attempted the exam in this particular subject matter, I failed miserably (rightly so). Having learned my lesson, I went…

The difference here is that Rich Hickey is explaining a fundamental computing mechanism that many programmers have come in with but few think about enough to give a name: the finite state transducer [see Wikipedia].

The name "transducers" is not an invention, it's basic computer science. The idea of using transducers to abstract over an input is not really controversial in the sense that it's the essence of what turns source into executable code on digital computers. Sure, Ther are tradeoffs relative to which flavor of Turing machine underpins any abstraction, but at least this is an area where we can achieve clarity.

This is something Hickey implemented, not invented. Like all of automata, understanding the concept is likely non-trivial for some pretty smart people since it requires thinking about first principles of computing.

Re: Rich Hickey – Inside Transducers [video]

#46
post #42

Earlier quoted context omitted.

Yeah, the overhead of creating intermediate typed arrays is exactly what I'm trying to avoid with this.

Lo-Dash 3.0 will have support for lazy evaluation in its chaining syntax that supports shortcut fusion and avoids intermediate arrays as well.

Do you know if they work with typed arrays?

Re: Rich Hickey – Inside Transducers [video]

#47
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.

Graham Hutton has a very nice tutorial [0] on the universality of fold, which shows this elegantly (in Haskell, though).

[0] Graham Hutton, "A tutorial on the universality and expressiveness of fold", J. Functional Programming 9(4): 355–372, July 1999. http://www.cs.nott.ac.uk/~gmh/fold.pdf

Re: Rich Hickey – Inside Transducers [video]

#48
post #38

Earlier quoted context omitted.

They can also be (T1,T2)->T3

Not really? When you reduce with function f(T1, T2) -> T3 the result of previous iteration becomes first argument for the next iteration, so they must be of the same "type". Or am I missing something?

Ah, no, you're right.

I was thinking that mapping can be f(T1)->T2 and how reducing can change types too, but I guess I wasn't paying enough attention because of course the reduce signature is f(accumulator, input) and the output is accumulator, so yea, you're absolutely right: f(T1,T2)->T1

Re: Rich Hickey – Inside Transducers [video]

#49
post #16
post #14

Earlier quoted context omitted.

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.

But if you use an async transducer on a channel, it fails. (Actual tested code, sadly.)

Which might be okay, but my basic point that it's definitionally fuzzy still holds.

Re: Rich Hickey – Inside Transducers [video]

#50

Earlier quoted context omitted.

In the strangeloop talk his argument seemed to be that you couldn't use types to describe the entire and exact contract of transducers. Which is true (and true of almost anything), but you can at least describe a significant enough chunk of it to reduce errors. As always it's a trade off. As you try to capture more of the contract, you massively increase complexity, sometimes to the point of reducing usability (i.e.…

Isn't the problem with transducer typing is that transducers aren't very functional? In one of your posts you wrote: System.in.setTransducer(lowerAlpha); In the LINQ/functional origami world, you could only produce new streams, not transform an existing stream in place. Because a new stream is computed, a new type can be computed. However, from what I've seen with transducers, they would be limited to basically Func…

That's part of it, but of course you can embed monadic types/effects within the appropriate combinators. (I think "tel" showed an example of this in the original "transducers" post)
Post reply on HN