13 ms·
Magical, Mystical JavaScript Transducers
- bjoli 7y agoI 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 https://srfi.schemers.org/srfi-171/srfi-171.html
- SigmundA 7y agoI 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-with-generators-map-filter-and-reduce--36h5 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
- chunkstuntman 7y agoEvery 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.
- noir_lord 7y agoOn the other hand I have zero issues with the design, like it aesthetically and find it a refreshing change to see a blog clearly designed to be functional and refreshingly different.
- Waterluvian 7y agoI wouldn't describe it as "functional" given the unnecessary font and background.
- chris_st 7y agoI don't mind the font, but the pointlessly narrow column (which makes you have to horizontally scroll the code examples) is unfortunate. Please, I have a wide screen, let me use it.
- donut 7y agoImpressive 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; }
- dheerajvs 7y agoNitpick: There should be a check for zero count to avoid a divide-by-zero. It's missing in the original article as well.
- ec109685 7y agoWhy isn’t NaN the right result for the average of an empty set?
- sooheon 7y agoOf 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.
- agumonkey 7y agoThe 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)
- chris_st 7y ago
- blunte 7y agoIt'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 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.
- Waterluvian 7y agoI really disliked how talkative this author is. So many unnecessary sentences. But I don't think that has anything to do with the language.
- darepublic 7y agoI love js and was into it before it was cool. Only sad thing is the momentum to make it typed
- sametmax 7y agoIsn't it exactly the use case of generators ? I though js had the yield keyword by now.
- fulafel 7y agoRelated: Transducers for Python and related HN discussion https://news.ycombinator.com/item?id=10591118 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.
- Waterluvian 7y agoIn 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.
- mbostock 7y agoI 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.
- mtarnovan 7y agoCorrect me if i'm wrong but if you use something like Elixir's Stream you get composability for free and don't need transducers.
- talkingtab 7y agoThe 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 ...
- tomxor 7y agofunction 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.
- Veedrac 7y agoI 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.