Prior Art

C++: noexcept(noexcept(…))

C++'s noexcept(noexcept(…)) pattern is used to declare something as noexcept if the evaluated pattern is also noexcept. This makes noexcept conditional on the pattern provided.

This is most commonly used in generic templates to mark the output type as noexcept if all of the input types are noexcept as well.

C++: implicits and constexpr

constexpr can be applied based on a condition. The following example works:

C++ 11

template <
class U = T,
detail::enable_if_t<std::is_convertible<U &&, T>::value> * = nullptr,
detail::enable_forward_value<T, U> * = nullptr>
constexpr optional(U &&u) : base(in_place, std::forward<U>(u)) {}

template <
class U = T,
detail::enable_if_t<!std::is_convertible<U &&, T>::value> * = nullptr,
detail::enable_forward_value<T, U> * = nullptr>
constexpr explicit optional(U &&u) : base(in_place, std::forward<U>(u)) {}

C++ 20

template <
class U = T,
detail::enable_forward_value<T, U> * = nullptr>
explicit(std::is_convertible<U &&, T>::value) constexpr optional(U &&u) : base(in_place, std::forward<U>(u)) {}

todo: validate what this does exactly by someone who can actually read C++.

Rust: maybe-async crate

Rust: fn main

Rust provides overloads for async fn main through the Termination trait. The main function can optionally be made fallible by defining -> Result<()> as the return type. In the ecosystem it's common to extend fn main with async capabilities by annotating it with an attribute. And this mechanism has been shown to work in the compiler as well by implementing Termination for F: Future.

The mechanism of overloading for fn main differs from what we're proposing, but the outcomes are functionally the same: greater flexibility in which function modifiers are accepted, and less need to duplicate / wrap code.

Zig: async functions

Zig infers whether a function is async, and allows async/await on non-async functions, which means that Zig libraries are agnostic of blocking vs async I/O. Zig avoids function colors.

β€” Zig contributors, β€œZig In-Depth Overview: Concurrency via Async Functions,” October 1, 2019

Swift: async overloading

// Existing synchronous API
func doSomethingElse() { ... }

// New and enhanced asynchronous API
func doSomethingElse() async { ... }
  • https://github.com/apple/swift-evolution/pull/1392