5 ms·
Does current Rust contain a way to mark functions as Pure?
by radarsat1 9y ago
Does current Rust contain a way to mark functions as Pure?
- kibwen 9y agoNot in the referentially-transparent sense. Most Rust functions meet almost all of the practical criteria for for purity (i.e. does not mutate global state (or otherwise any state that was not explicitly passed in to the function), does not do I/O), but that's only a comfort for the programmer's ability to reason about the code; this weakened notion of purity-by-default isn't enough to allow the typical optimizations via purity (e.g. memoization).
- stcredzero 9y agobut that's only a comfort for the programmer's ability to reason about the code A way to mark functions as pure for this purpose would be great! Especially if it's not as fraught as const in C++.
- steveklabnik 9y agoWe actually did have this once, but it wasn't really worth it, so it was removed. https://news.ycombinator.com/item?id=6940624 https://news.ycombinator.com/item?id=6940624 is the HN discussion, but it looks like the link might now be wrong? It was also a very, very long time ago, and so today's Rust might be different enough that those reasons don't apply any more.
- tormeh 9y agoThe reason at that point vis that there weren't any practical benefits and that it was preferable to wait for a more general mechanism. The first claim is dubious, but I can empathize with second, as long as it doesn't become tacked on. Haskell can do cool optimizations that make it feel like magic sometimes.
- steveklabnik 9y agoIn some ways, const fn reminds me of this.
- Gankro 9y agoNote that a lot of these optimizations aren't necessary in Rust -- e.g. list fusion is only valuable in Haskell because mapping over lists is exposed as a one-shot operation that produces a new list. So `map map map list` is conceptually building 2 whole lists of temporaries you don't care about (and you often don't actually care about the last one either, in cases where you just iterate over it and discard it). Meanwhile mapping in Rust generally takes an iterator and produces another iterator that will apply the given closure to the current element as it's yielded. So the naive codegen for iter().map().map().map().collect() is exactly what list fusion is trying to produce -- no temporary lists. TL;DR: making "map" having the monadic `T[U] -> T[V]` signature is really expensive. ¯\_(ツ)_/¯
- radarsat1 9y ago> We actually did have this once, but it wasn't really worth it, so it was removed. Ah, yeah I had a vague memory that that was the case, which is why I asked.. I seem to recall it being removed, but I only follow Rust news, don't use it, so I wasn't sure of the reasons or implications.
- stcredzero 9y agoI think that being able to enforce purity would be fantastic for actors, agents, and/or game loops. https://news.ycombinator.com/item?id=8609775 https://news.ycombinator.com/item?id=8609775
- pcwalton 9y agoIt wouldn't help in most of these cases. It'd be too burdensome to require that map/filter/etc. take pure arguments. In the absence of that, the compiler is left with examining the specific function being called, which it can already do as a direct call as long as the body is visible (#[inline]). If the body is visible, LLVM will internally automatically mark the function as pure (readnone) if it is.
- dom0 9y agoconst does not imply pure. If applied to a member function, it makes this const; if applied to types it makes types const. Purity is a different concept. The closest match would probably be constexpr.
- stcredzero 9y agoconst does not imply pure. If applied to a member function, it makes this const; if applied to types it makes types const. You just demonstrated what I mean when I comment that const is fraught. Purity is a different concept. Purity more easily maps more closely to an abstract concept and is easier to for people reason about.