from Hacker News

Magical, Mystical JavaScript Transducers

by ecbu on 6/29/19, 3:10 AM with 50 comments

  • by donut on 6/29/19, 4:36 AM

    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;
      }
  • by chunkstuntman on 6/29/19, 4:27 AM

    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.
  • by SigmundA on 6/29/19, 11:30 AM

    I am somewhat confused here, I primarily do C# so I am used to IEnumerable and Linq for doing this kind of stuff and you would just do .Where().Select().Average() without worrying about intermediate memory usage. In C# you do this stuff with millions of results from a database (although you would do in the db if you can, but might be a flat file too).

    Linq with IEnumerable doesn't necessarily create intermediate list (js arrays) in memory unless it has to like say .OrderBy()

    So I basically assumed js was the same since it has generators but its seems map and filter etc don't support them yet?:

    https://dev.to/nestedsoftware/lazy-evaluation-in-javascript-...

    So then you get a solution like this that looks to me very confusing vs a fluent style.

    Please tell me I am missing something

  • by bjoli on 6/29/19, 7:47 AM

    I recently wrote a srfi (scheme request for implementation) for transducers, if anyone is interested. The code is guile-specific, but is easily portable to other schemes. It is still a draft, so it is bound to change: https://srfi.schemers.org/srfi-171/srfi-171.html
  • by Waterluvian on 6/29/19, 1:50 PM

    In almost all cases you don't need to worry this much about performance. Just traverse the array three times and move on. Go measure and improve if it becomes an issue.
  • by blunte on 6/29/19, 12:52 PM

    It's so depressing that JavaScript is growing in use, especially when I see articles like TFA. I hate that momentum has allowed a clusterf*ck of a language to become the standard for front end and now one of the top 3 for back-end.

    Here's Clojure's explanation of transducers: https://clojure.org/reference/transducers

    The whole concept is explained more clearly and with far fewer words and code; and the final result is pretty, or at least clean and tidy.

  • by talkingtab on 6/29/19, 2:56 PM

    The concept of transducers - I think of it is a conveyor belt of functionality - is great and I periodically run into problems where having an easy to use JavaScript transducer system would be great. Right now I'm processing sets of markdown files, reading shortcodes from them, generating html, applying more shortcodes, adding variables and then using mustache ... It is just a conveyor belt, but with lots of little odds and ends - perfect for a transducer, especially with async.

    Ramada looks interesting ...

  • by sametmax on 6/29/19, 1:06 PM

    Isn't it exactly the use case of generators ? I though js had the yield keyword by now.
  • by tomxor on 6/29/19, 2:59 PM

      function isFound(item) {
          return item.found;
      };
    
    Every time I see this pattern in code (one line accessors) I have a sinking feeling in my stomach in expectation of whats to come.

    This is the best example of a forced pattern.

  • by Veedrac on 6/30/19, 10:05 PM

    I recommend ignoring transducers unless you know you really need push-based iteration, which probably isn't the case. Generators are generally a superior approach otherwise.
  • by mbostock on 6/29/19, 1:53 PM

    I know this is cheating and missing the point, but using d3-array:

    d3.mean(victorianSlang, d => d.popularity)

    This implicitly ignores invalid values (null, NaN or undefined) after coercing to a number.

  • by fulafel on 6/29/19, 1:23 PM

    Related: Transducers for Python and related HN discussion https://news.ycombinator.com/item?id=10591118

    I don't know how JS generators work but Python users seemed to think Python's generators cover most transducer use cases.

  • by mtarnovan on 6/29/19, 2:04 PM

    Correct me if i'm wrong but if you use something like Elixir's Stream you get composability for free and don't need transducers.