# Start of an effects system RFC (for async etc) - is there any interest in this?

**URL:** <https://internals.rust-lang.org/t/start-of-an-effects-system-rfc-for-async-etc-is-there-any-interest-in-this/7215>\
**Category:** Uncategorized\
**Created:** [April 3, 2018, 7:03am UTC](https://internals.rust-lang.org/t/start-of-an-effects-system-rfc-for-async-etc-is-there-any-interest-in-this/7215 "2018-04-03T07:03:31Z")\
**Posts on this page:** 1\
**Showing post:** 8

<div class="post-metadata">

**Author:** ![Ixrec](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ixrec/32/6754_2.png) [@Ixrec](https://internals.rust-lang.org/u/Ixrec)\
**Post date:** [April 3, 2018, 6:44pm UTC](https://internals.rust-lang.org/t/start-of-an-effects-system-rfc-for-async-etc-is-there-any-interest-in-this/7215/8 "2018-04-03T18:44:15Z")

</div>

First, thank you for writing up this RFC. I have no background in “effect systems” or the kinds of languages where such things exist, but after reading that RFC draft I feel like I finally understand the general idea and motivation well enough to provide a coherent reply to it, rather than just asking “but what does any of that actually mean?” or “but how would any of this actually work?”

My type-fu is still not capable of a sophisticated reply, but I can at least manage a coherent one. So here are some of my knee-jerk and just-after-knee-jerk reactions to various parts of this proposal, without any serious attempt at reaching a conclusion:

- There’s an enormous risk of the perfect being the enemy of the good here
- Are any of today’s stable and unstable mechanisms for allocation, panicking, async I/O, and blocking I/O forward-compatible with this? What would it take to make them compatible?
- In a Rust-with-effect-systems world, when I want to write some code that prints to stdout, do I need to care about every possible implementation of `Io`? (including wacky only-theoretically-possible implementations like QuanumEntangledDistributedIo?) Would I have to fall back on the legacy explicitly-blocking or explicitly-threading APIs in order to allow myself to not care? Would we have to forbid such non-effect-polymorphic APIs in order to gain any of the benefits of this system? What if I’m not even writing I/O code myself but calling a bunch of libraries that happen to do I/O, and passing them handlers I don’t even know about that violate those libraries’ basic assumptions?
- The idea of automagically transforming synchronous I/O code into asynchronous I/O code terrifies me. I’ve introduced and fixed so many race conditions in Javascript code (N.B.: a single threaded event loop language) at work when _manually_ changing blocking APIs to use promises that an `Io` effect abstracting over sync/async-ness sounds to me like a footgun of biblical proportions. I can understand the proposals to make `await` implicit, even if I dislike them, but the idea of making `await` implicit _and conditional_ feels dangerously close to [releasing Zalgo](http://blog.izs.me/post/59142742143/designing-apis-for-asynchrony); maybe it’s not like that at all, but it’s not obvious that it’s not.
- Corollary to previous knee-jerk: That just happens to be the only example of an effect shift (???) that I’ve had the experience of doing manually. Are any of the other transformations similarly perilous? There must be some unsafe code out there which is abort-safe and not panic-safe, right?
- Even if this is amazing in practice, I have no idea how we’d begin to teach this sort of thing to Rustaceans. I’m the kind of person that reads _Types and Programming Languages_ **for fun** , and I don’t even know how to _investigate_ the answers to most of the other questions I’m asking in this list, much less concisely and intuitively justify those answers to a real working programmer that just wants to get their widgets frobnicated already. I only just managed to understand the _motivation_ behind these ideas today.
- Corollary to previous knee-jerk: It seems like adding an effect system to Rust can only be a net benefit if we manage to preserve “incremental complexity”. By that I mean, I should be able to write “typical” sync I/O, async I/O, allocator, panic, etc code without understanding the underlying effect system; ideally without even seeing the syntax and terminology of effect systems come up at all. Is it possible to reimplement `#[async]/await!()` as sugar over effects? I assume we’d also need “default effect fallback” of some sort so that I can call `my_sleeping_fn()` without having to bring in effect blocks every single time? What if different libraries want different defaults for the same effects?

---

_[View the full topic](https://internals.rust-lang.org/t/start-of-an-effects-system-rfc-for-async-etc-is-there-any-interest-in-this/7215)._
