# 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>> {
...
}
```