---
# System prepended metadata

title: 'Contexts, capabilities and overloading ahoy'

---

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