Skip to content

kyay10/wither

Repository files navigation

Wither

(This README, in all its ridiculousness, is entirely human-made)

Have you ever had to bring in multiple receivers or contexts? Did you end up with code that looks like this?

context(Foo, Bar, Baz) {
  // ...
  if (someCondition) {
    context(A, B) {
      context(makeCFromAandB()) {
        context(nowMakeDAsWellUsingC()) {
          with(contextOf<Foo>()) { // oops, I actually really need Foo as a receiver here...
            finallyDoTheGoshDarnThing()
          }
        }
      }
    }
  }
}

Introducinnnnng, Wither! Your code can be flattened down to look like this instead:

context(Foo, Bar, Baz)
// ...
if (someCondition) {
  context(A, B)
  context(makeCFromAandB())
  context(nowMakeDAsWellUsingC())
  with(contextOf<Foo>()) // oops, I actually really need Foo as a receiver here...
  finallyDoTheGoshDarnThing()
}

Isn't that beautiful! Oh, how, you may ask? ✨Compiler magic✨ Kotlin DataFrame uses similar magic, so this'll probably stay somewhat supported (at least for with, but context is hacky and might not!) Features:

  • with and context can contain multiple values with("Hi", 42), with semantics similar to context parameter groups (for with, currently, the values are introduced as extension receivers, so scope pollution may apply!)

  • multiple with and context calls can override each other:

with("Hi")
with("Low")
println(contextOf<String>()) // prints "Low"
  • withs and contexts are scoped inside of the local block, and so you can have use them inside an if or a when branch, and it won't affect other call sites. This means you can also have them in lambdas!

Try it out today! All it takes is just:

plugins {
  id("io.github.kyay10.wither") version "0.0.2"
}

and simply import io.github.kyay10.wither.with or io.github.kyay10.wither.context

I'll eventually add multi-version support, but for now, the plugin is only tested against 2.4.10. YMMV on other versions.

About

A Kotlin Compiler Plugin that allows local `with` calls, so that adding receivers doesn't result in deeply nested code. This is especially important with context parameters. The name reflects the hope that this plugin will "wither" away and become unnecessary, through Kotlin adopting a way to do this

Resources

License

Stars

12 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors