Live data from Hacker News

Magical, Mystical JavaScript Transducers

jrsinclair.com

1–10 of 51 posts

Re: Magical, Mystical JavaScript Transducers

#2
Every time I see this blog I'm extremely interested in the content, but the stylized presentation is so jarring and tough to read. I doubt this is an original qualm and I'm fully able to switch to reading mode in Firefox to mitigate this problem, but frankly it's off-putting.

Re: Magical, Mystical JavaScript Transducers

#3
Impressive amount of code and words. I think I'd think twice before approving this in a code review, though.

Why is this not the obvious solution to the stated problem?

  function avgPopularity(slang) {
    let sum = 0;
    let count = 0;
    for (item of slang) {
      if (item.popularity > 0) {
        sum += item.popularity;
        count += 1;
      }
    }
    return sum / count;
  }

Re: Magical, Mystical JavaScript Transducers

#4
post #3

Impressive amount of code and words. I think I'd think twice before approving this in a code review, though. Why is this not the obvious solution to the stated problem? function avgPopularity(slang) { let sum = 0; let count = 0; for (item of slang) { if (item.popularity > 0) { sum += item.popularity; count += 1; } } return sum / count; }

Amen.

Re: Magical, Mystical JavaScript Transducers

#5
post #3

Impressive amount of code and words. I think I'd think twice before approving this in a code review, though. Why is this not the obvious solution to the stated problem? function avgPopularity(slang) { let sum = 0; let count = 0; for (item of slang) { if (item.popularity > 0) { sum += item.popularity; count += 1; } } return sum / count; }

because something something mutable state

Re: Magical, Mystical JavaScript Transducers

#6
post #3

Impressive amount of code and words. I think I'd think twice before approving this in a code review, though. Why is this not the obvious solution to the stated problem? function avgPopularity(slang) { let sum = 0; let count = 0; for (item of slang) { if (item.popularity > 0) { sum += item.popularity; count += 1; } } return sum / count; }

Because a bunch of those lines are concerned with the boring mechanics of how to compute this thing rather than what is being computed. It’s reasonable to say having a big system of composable transducers is pointless for one computation. It’s harder for 1000.

This point isn’t about transducers specifically but more about avoiding specifying the things you don’t care about. Eg, in Common Lisp (which was old enough to somewhat care about how to iterate things):

  (defun avg-popularity (list)
    (loop for item in list
      when (plusp (popularity item))
        sum pop into s
        count t into c
      finally (return (/ s c))))
This avoids having to care about the mechanics of how to sum or count things and I think it’s too sequential, when you don’t really care about that. One can certainly imagine a simpler to express solution in e.g. apl.

Re: Magical, Mystical JavaScript Transducers

#7
post #3

Impressive amount of code and words. I think I'd think twice before approving this in a code review, though. Why is this not the obvious solution to the stated problem? function avgPopularity(slang) { let sum = 0; let count = 0; for (item of slang) { if (item.popularity > 0) { sum += item.popularity; count += 1; } } return sum / count; }

Nitpick: There should be a check for zero count to avoid a divide-by-zero. It's missing in the original article as well.

Re: Magical, Mystical JavaScript Transducers

#8
post #3

Impressive amount of code and words. I think I'd think twice before approving this in a code review, though. Why is this not the obvious solution to the stated problem? function avgPopularity(slang) { let sum = 0; let count = 0; for (item of slang) { if (item.popularity > 0) { sum += item.popularity; count += 1; } } return sum / count; }

Of course trivial toy examples demand simple answers. But as you add more processing (partitioning + further operations on partitions, take every nth, stop when some predicate is true...), transducers let you build each in isolation and compose them easily. Your obvious solution might start to get a bit strained, and the code for any single process in the chain can't be reused.

Re: Magical, Mystical JavaScript Transducers

#9
post #3

Impressive amount of code and words. I think I'd think twice before approving this in a code review, though. Why is this not the obvious solution to the stated problem? function avgPopularity(slang) { let sum = 0; let count = 0; for (item of slang) { if (item.popularity > 0) { sum += item.popularity; count += 1; } } return sum / count; }

The article obfuscates the point. Reducers/transducers are from the FP world. In FP avoiding mutable state is one the main point.

    dot = field => obj => obj[field]                        // unsafe
    Array.average = self -> reduce(add, self) / self.length // unsafe
    slang.filter(s -> s.popularity > 0)
         .map(dot('popularity'))
         .average()
Bonus points:

    - no state
    - reusable pure functions
    - a tad shorter
    - maybe as readable as the `for over state` idiom ? (depending on habits)

Re: Magical, Mystical JavaScript Transducers

#10
post #3

Impressive amount of code and words. I think I'd think twice before approving this in a code review, though. Why is this not the obvious solution to the stated problem? function avgPopularity(slang) { let sum = 0; let count = 0; for (item of slang) { if (item.popularity > 0) { sum += item.popularity; count += 1; } } return sum / count; }

Yours is the obvious solution but the problem is a simple example to help people understand the more complex idea of transducers. It's for situations where the code inside the for loop is so complex that it would be nice to organize it with functional programming principals.

The problem with functional programming is that the obvious approach is not efficient since it passes the array several times. So the goal is to make the functional approach as efficient as the imperative for loop.

Now if you do that by hand, you end up with some messy code. So the article shows how you can combine the operations with a helper library in a structured way.

That said, it kind of reminds me of The Evolution of a Haskell Programmer [0]

[0] https://www.cs.utexas.edu/~cannata/cs345/Class%20Notes/10%20...

Post reply on HN