[rust-dev] Why in the Rust language functions are not pure by default?

Patrick Walton pwalton at mozilla.com
Sat Jan 12 12:34:54 PST 2013

On 1/12/13 7:59 AM, Andres G. Aragoneses wrote:
> (It's just that this small room for improvement seems the only blocker
> for me to take a serious look at Rust. So I feel I could manage to
> create a patch to inverse the default purity, but of course I could not
> manage any simplification over this because I've never looked at rust's
> implementation and likely won't have enough time to figure out.)

Once the write barrier ("Imagine Never Hearing the Phrase 'Aliasable, 
Mutable' Again") changes go through, purity will not be needed for 
soundness in any part of the language (with the exception of the 
"unsafe" effect). When that happens, I think "pure" should be removed 
from the language, and future efforts toward effect systems would likely 
be better spent investigating pluggable effect systems along the lines 
of "Lightweight Polymorphic Effects" proposed for Scala [1].

The reasons are: (a) there are many effects that programmers may want, 
"pure" being only one of a large set; and (b) there's been an endless 
debate since we started about what "pure" actually means.

To elaborate on (a), consider that there are many useful invariants that 
you might want the compiler to check. For instance, if you're building a 
mobile app that needs touch responsiveness, you might want at "gc" 
effect to help the compiler ensure that you aren't using the GC on the 
UI thread. For another example, you might want the compiler to verify 
that you can't do blocking I/O on your server; this would be a 
"blocking" effect. If you're doing functional programming, you might 
want a "pure" effect that's stronger than the "pure" we have now. These 
examples aren't just made up; people have asked for all of these at some 
point or another. It strikes me as better to see whether we can roll 
these ideas together into one simple system than to try to build more 
and more into the language over time, or to try to layer static analysis 
tools on top of the language that won't work as well as they would if we 
build the system into the language to begin with.

Regarding (b), formulating a concept of purity that's precise enough to 
be useful but forgiving enough to be practical has been hard. For 
example, can you write to "&mut" parameters in pure functions? Allowing 
it is extremely useful and has no effect on safety, but it strays far 
enough from the formal notion of purity that some have questioned Rust 
for it. There are tougher questions as well -- for instance, can you log 
errors in a pure function? You might think that it's obviously harmless 
to do so, but consider the case in which you're running a server and 
your error logging is sent over the network; now pure functions can 
perform random network I/O. Yet if you can't log errors this has serious 
ramifications for usability; even Haskell breaks purity for 
`Debug.Trace`. The take-away from all of this, to me, is that there are 
different notions of purity that are useful in different circumstances, 
and instead of debating about which one is the best one we should 
investigate whether we can allow programmers to define a notion of 
purity suitable for the task at hand.

Incidentally, pluggable effect systems strike me as very much not a Rust 
1.0 feature; I'd like to leave the door open for them at a later date, 
but they'd most likely strain the complexity and time budget too much to 
be worth it.


[1]: http://infoscience.epfl.ch/record/175240/files/ecoop_1.pdf

More information about the Rust-dev mailing list