4 ms·
In a functional language `map` and `filter` are nice to chain together. For instance in Haskell: [1, 2, 3] & map (* 3) & filter (> 4) & sum This takes the
by kinjba11 5y ago
In a functional language `map` and `filter` are nice to chain together. For instance in Haskell:
[1, 2, 3] & map (* 3) & filter (> 4) & sum
This takes the array, maps it, filters and sums it in one go. If the array was say 1,000,000 elements and you used multiple `map`, `filter`, and other similar functions you'd soon run out memory (or use much more than needed) if they were eager and allocated a million-element array at each step as opposed to running through the array one time.
The alternative is to use imperative style (for loops and such), but the functional style is often more declarative and easier to read and write (think SQL).
- geokon 5y agoOkay I hadn't thought of that :) I guess even after all this time using these functions I'm still not entirely comfortable with the lazyness. I think a more explicit method in Clojure is to use `eduction` (if I'm not misunderstanding!) https://clojuredocs.org/clojure.core/eduction https://clojuredocs.org/clojure.core/eduction This allows you to be more explicit and say you want to chain these transducers together. The lazy variant makes it more difficult to reason about performance (and this being a "math" language - that seems a priority) b/c you need to read the tea leaves to see where the sequence gets realized. It really requires a gear shift in reasoning about your code b/c you need to think "okay, I'm writing this huge reduction, but I don't care about its size b/c it won't all get realized b/c I did this other thing later on". My gut feeling is it's a bit hard to keep track of everything :) But I'd be curious to hear an alternative.. I remember writing some math code and finding it was really challenging to get the lazy operations to chain together well. It was over a year ago, so the details are a bit hazy.. but I needed it to run down an array of numbers and do some operations and this lazy method ended up being incredibly slow. Unfortunately I don't remember the ultimate cause, but I'm guessing it thrashed the cache. It could also just be a limitation in Clojure internals when it comes to compositing lazy seq's - but again, I'm not quite sure.