5 ms·
I also find it to be the exact other way around. A lot of mathematical transformations, on the inside, break down neatly into sequential mutations, and you rea
by fiatmoney 13y ago
I also find it to be the exact other way around.
A lot of mathematical transformations, on the inside, break down neatly into sequential mutations, and you really do need to express them imperatively for maximum performance. Fortunately, you can look at the math and verify they compose appropriately, and use testing to verify you've implemented each step correctly.
But if I'm doing anything involving state, particularly interdependent state like a simulation, functional algorithms make a lot of sense as a way to ensure that I always have a valid object handle (because I'm always returning a new, valid object as a result of a computation) and give you a somewhat easier route to refactor while maintaining the same semantics (because there are no rogue mutations or global state updates I need to conform to), as well as parallelizing updates to the object graph for performance.
Clojure's semi-famous "ants" demo is a good example of this.
http://www.youtube.com/watch?v=dGVqrGmwOAw http://www.youtube.com/watch?v=dGVqrGmwOAw
https://gist.github.com/spacemanaki/1093917 https://gist.github.com/spacemanaki/1093917
- tikhonj 13y agoHmm, if the mutation is just purely sequential, it's just an implementation detail. Ideally, you would express the solution at a high-level, close to the mathematics and without mentioning mutation, and have your code optimized to the mutable version for you. After all, it's just a series of transformations over some data--exactly what functional programming is! This sounds like an appeal to a "sufficiently smart compiler", but really we're already part of the way there with things like vector and stream fusion in Haskell. I know that some of Haskell's vector functions are already smart enough to run in-place if they can get away with it.
- username223 13y ago> This sounds like an appeal to a "sufficiently smart compiler" Because it is. It's a long road from "gee, I changed something, better copy everything" to something as good as FFTW or ATLAS. GHC is pretty smart, but not smart enough to be trusted.
- shoki 13y ago> It's a long road from "gee, I changed something, better copy everything" to something as good as FFTW or ATLAS. CUDA implementations of FFTs and matrix operations are faster than both FFTW and ATLAS, and they are neither sequential nor functional. CUDA, C, and Haskell all have domains they typically outperform one another. The math vs. simulation divide sketched in this blog post is more an expression of the author's own psychology more than anything else.
- kkjkok 13y agoTo be fair, the FFTW/CUDA thing is due to fundamentally different hardware architectures which drove design constraints for these types of libraries. FFTW was never meant to run on a dedicated, ultra-parallel processor with highly optimized floating point instructions (GPU), but it is incredibly fast considering it runs on general purpose hardware. I am sure the FFTW authors could have done something to squeeze out more performance if they controlled both the hardware and software as NVidia does. And the transfer time to/from the GPU does matter, especially for smaller/more frequent operations... All that aside, the psychology of pure functional vs. pure OOP vs. some hybrid methodology is really interesting, and even the view of what a "clean solution" is becomes tainted based on past experiences with other code written in that style.