[rust-dev] Why in the Rust language functions are not pure by default?
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 .
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.
More information about the Rust-dev