I just want to reiterate something that I say in a child comment in this thread: thanks to its thoughtful design, many of the advantages of purity are less appreciable in Rust than they would be in, say, C++.<p>In Rust, everything is immutable unless you opt-in to mutability. Looking at a function signature will tell you which of its arguments can possibly be mutated. Global mutable state is <i>highly</i> discouraged, by requiring you to wrap code that accesses global mutable state in a dreaded `unsafe {}` block. As for optimization capabilities, LLVM itself can (AFAIK) infer when functions are "pure" and mark them as `readonly` or `readnone` (not sure what the limitations to this approach are, though).<p>So don't make the mistake of thinking that Rust is a free-for-all due to the long-ago removal of its `pure` keyword. Many (dare I say a majority?) of the nice features of purity are merely provided by different mechanisms (for those use cases that Rust does not satisfy, Graydon's own explanation should suffice regarding their enormous added complexity in a language that is not Haskell).
Since this author is reasoning through proposed purity in Rust by comparing it with purity in Haskell...<p>- I personally have never felt constrained by Haskell's purity. During development I use `Debug.Trace` to do any debug printing I need to do in pure functions, and I design a program so that in production code I can do appropriate logging before and/or after any calls to pure functions.<p>- Managing monad stacks in Haskell isn't that tricky. This is the kind of thing that people get scared away from not because they actually tried to learn it and couldn't, but because people make it out to be so hard.<p>- The Haskell STM example the author links to is actually really simple, especially in terms of monad stacks. It seems dense at first glance only because of the `forkIO`, `timesDo`, and `milliSleep` calls, but you would need these functions' logical equivalents no matter what language you wanted to implement this example in.
Interestingly, D has this and everybody considers it great. The community consensus is that pure should have been the default, but it is not changed for backwards compatibility.<p><a href="http://qznc.github.io/d-tut/idiomatic.html#purity" rel="nofollow">http://qznc.github.io/d-tut/idiomatic.html#purity</a>
The corresponding reddit thread at /r/programming: <a href="http://www.reddit.com/r/programming/comments/1t8y6g/why_rust_ditched_pure_functions/" rel="nofollow">http://www.reddit.com/r/programming/comments/1t8y6g/why_rust...</a>
This discussion is very interesting to me because I am just starting to learn about pure functions and functional programming in general.<p>Coming from an OOP background, I am used to bundling functionality into objects that loosely represent real-world people, places or things, but I'm starting to experiment with using these more abstract "pure" methods.<p>For example, I'm working on a GPS-based JavaScript game that uses a "check-in" system to encourage users to travel spontaneously. Initially, I designed a tightly encapsulated "Check-in" object responsible for fetching & interpreting users' locations.<p>Inspired by reading about functional programming on HN and elsewhere, I'm trying to break up some of the general geo-processing logic such as looping, array filtering, map/reduce, etc., into general functions with predicable results that can be used throughout my application.<p>It's definitely a different way of thinking that I'm not entirely comfortable with yet, but I can see how it allows for faster, more efficient code. I have been able to replace 50-line code blacks with 10-line blocks that are more efficient and - believe it or not - legible.