rssh / dotty-cps-async

experimental CPS transformer for dotty
Apache License 2.0
178 stars 22 forks source link

Extension methods for await/unlift/reflect #83

Closed cornerman closed 3 weeks ago

cornerman commented 3 months ago

It would be great to have chainable methods for awaiting a value inside an async block like this:

async {
  Future(1).await + Future(2).await
}

I find it a nice because it requires less braces than await(Future(1)). Furthermore, it would support the syntax from https://github.com/typelevel/cats-effect-cps here. So, it very easy to switch.

As far as I understand, this could be achieved by making await/unlift/reflect extension methods on F[T], defining it like this:

extension[F[_],T,G[_]](f: F[T]) {
  def await(using ctx: CpsMonadContext[G], conversion: CpsMonadConversion[F,G]): T = ???
}

Afaik, it should then be available as method await(f) and as an extension f.await. What do you think?

cornerman commented 3 months ago

When talking about short syntax: I actually really like the short syntax !. But now I stumbled on a case of !IO(true) and felt a bit confused about it. What do you think about using ~ instead (or additionally?). This is bit-wise negation, which I actually never used before - so maybe it would be less likely to have a clash of meanings.

rssh commented 3 months ago

Yes, it (postfix await) makes sense. Two questions

rssh commented 3 weeks ago

Oops -- looks like in 3.5.0 we can't define an extension with the same name as a method, because the compiler begins to understand prefix invocation as an overloaded application.

I will submit it to the compiler team, but I am unsure if it will be classified as unexpected behavior.

rssh commented 3 weeks ago

Hmm, maybe we can use only extensions instead ...yes, this works

cornerman commented 3 weeks ago

Awesome, I am very happy that it works :)

rssh commented 3 weeks ago

0.9.22. with await extension method is published on maven central