# Contexts, capabilities and overloading ahoy ## 2022-06-02 ## 2022-05-05 ```rust // this seems fine for<effect K> const<K> fn foo() { bar::<K>() } // but this looks like `async` and `const` must be in lock-step, // because effect K looks like a bool: for<effect K> const<K> async<K> fn foo() { bar::<K>() } ``` - Niko: bounding K - reminds of "algebraic subtyping" If we apply restrictions on the usage of the effect ```rust for<effect X> async<X> fn bar() {} for<effect K> const<K> fn foo() { bar::<async::No>(); // fine, no await needed bar::<K>(); // error: await needed, because K could be `async::Yes` bar::<K / async>(); // fine: removed async from the set // with sugar considered: bar(); // fine, `async` is not part of the set because `foo` is not async. } foo::<async>() // useless (not actually useless: `bar` might be using it) ``` ```rust for<effect X> async<X> fn bar() {} async<X> fn bar<effect X>() {} ``` ```rust fn map( closure: impl X * FnMut(u32) ) { } ``` - Niko: should we have a shorthand syntax? - whatever effects exist on the closure, we want too. So is it worth spelling out, or can we just define relations? https://effekt-lang.org/#intro-polymorphism ```rust fn map( closure: impl FnMut(u32) ) { } fn map( closure: &mut dyn FnMut(u32) ) where WF(&mut dyn FnMut(u32)) { } ``` - [halt safety draft](https://deploy-preview-48--yoshuawuyts-blog.netlify.app/halt-safety/) ## 2022-04-21 * Update on [keyword generics](https://github.com/yoshuawuyts/keyword-generics-initiative) * Plan * Create initiative repository * Do some stuff in MIR * ### The plan 0. keyword generics initiative repo 1. constness generic param to simplify `~const` implementation 2. lang team MCP for keyword generics, but only `async` and `const` for now, further keywords need to be MCPed seperately 3. `async_select` in the spirit of `const_eval_select` Defer: - how to do overloading - whether to use `match` on keyword params, or other stuff. We don't need to decide now. ### are these in some way the same feature? Niko thinks kind of "no", because no CPS https://gist.github.com/tmandry/270c7fb103d1d6622dcecf253c25071e [tmandry's random notes](https://hackmd.io/tcNdYge-QGOKSLV-a-2X2g) ## 2022-03-24 * Overloading * Polymorphism ```rust struct Foo { socket: Box<dyn AsyncRead> } impl Foo { pub fn new<trait AutoTrait>(socket: Box<dyn AsyncRead + AutoTrait>) -> Self + AutoTrait { } } ``` `SendIf<T>` ```rust= // oli's MIR lowering thoughts: const fn foo<constness C>(read: Read<C>) {} ``` ```rust= const fn foo(read: readonly? Read) -> readonly? Read{} // short for const fn foo<readonly R>(read: R Read) -> R Read{} ``` ```rust fn foo() {} // There's both a type `foo` and a value `foo` let x: foo = foo; const fn call_something(f: impl Fn() + Safe + Const) { f() } call_something(x); ``` * Things we know people want to track and care about * Const -- nothing * "Dynamic" -- things that require runtime * Safe -- only safe things * Unsafe * Allocation * Blocking I/O * Awaiting * Any I/O * Failure (Err) -- abruptly terminates * Result / fallible * Panicking * Suspending/awaiting * Exclusivity (&mut vs &, writes) * Interior mutability (Freeze) * Thread safety ```rust // without any effects fn find<I>( iter: impl Iterator<Item = I>, closure: impl FnMut(&I) -> bool, ) -> Option<I> { ... } fn try_find<I, E>( iter: impl TryIterator<Item = I, E>, closure: impl TryFnMut<(&I), E> -> bool, ) -> Result<Option<I>, E> { ... } fn async_find<I, O, E>( iter: impl AsyncIterator<Item = I>, closure: impl AsyncFnMut(&I) -> bool, ) -> impl Future<Output = Option<I>> { ... } fn any_find<I, effect F>( iter: impl F * Iterator<Item = I>, closure: impl F * FnMut(&I) -> bool, ) -> F * Option<I> { ... } ``` ```rust // without any effects fn map<I, O>( iter: impl Iterator<Item = I>, closure: impl FnMut(I) -> O, ) -> impl Iterator<Item = O> { ... } fn try_map<I, O, E>( iter: impl Iterator<Item = I>, closure: impl FnMut(I) -> Result<O, E>, ) -> impl Iterator<Item = Result<O, E>> { ... } fn async_map<I, O, E>( iter: impl Iterator<Item = I>, closure: impl FnMut(I) -> Result<O, E>, ) -> impl Iterator<Item = Result<O, E>> { ... } ```