Hacker News new | ask | show | jobs
by lenkite 1046 days ago
The main issue is that Clojure compiler doesn't really optimize lazy sequences right ? Most language compilers do this. Rust lazy iterators for example many times exhibit faster performance than for-lops.

And clojure also doesn't give an error/warning when lazy sequences aren't finalized.

3 comments

It's not really Rust's compiler that 'optimises lazy sequences'. It's LLVM, which notices that the code emitted happens to be able to be optimised down, if you run it for a really, really long time with some very strong optimisations.

GHC would be a better example, I think. It performs stream fusion. This means it can turn 'map f (map g xs)' into 'map (f . g) xs', and of course it gets more complex than that, but that's the basics. It directly optimises lists (which, this being Haskell, are lazy sequences).

> GHC would be a better example, I think. It performs stream fusion. This means it can turn 'map f (map g xs)' into 'map (f . g) xs', and of course it gets more complex than that, but that's the basics. It directly optimises lists (which, this being Haskell, are lazy sequences).

Is it for built-in map or it would work in a general way for, say, `myMap f (myMap g xs)` ?

> Is it for built-in map or it would work in a general way for, say, `myMap f (myMap g xs)` ?

Just the stdlib `map`, but it's all ordinary library code. You can easily add your own rewrite rules.

Rust's lazy iterators don't cache the results, to be iterated over again. It allows the optimiser to inline all calls and end up with a loop that doesn't need bounds checks, which is why they can be faster than C-style loops over arrays.
This critique is mostly about the semantics. And I agree. For me it's mainly that things happening out of order introduces surprises for reasoning in the normal edit-debug cycle if you've forgotten to use the *v versions of functions. As for performance optimizations, there are some, such as chunking and locals clearing mentioned in the article.