examples of Recovering Purity with Comonads and Capabilities - General

Welcome to the Functional Programming Zulip Chat Archive. You can join the chat here.

Julian KG

A paper I hear discussed a lot in FP spaces is Recovering Purity with Comonads and Capabilities. I've read the first two sections, but things start to go over my head after that. My question is: are there any examples (even toy ones) of using comonads to recover purity in impure languages that I can run, and play around with?

TheMatten

Not runnable, but you could implement such system e.g. in Rust:

// opaque "newtype"
struct Pure<T>(T);

// We could create some macro which enforces use of pure building
// blocks in expressions/declarations/whatever - we could make it so
// that it implicitly unwraps "Pure" inside and wraps returned values
// again.
macro pure { $x }

impl<T> Pure<T> {
  // We provide way to "unbox" that pure value using method
  fn extract(self) -> T {
    self.0
  }
}

pure! {
  fn add(a: i32, b: i32) -> i32 {
    a + b
  }
}
// gets turned into e.g.:
// // const functions must be executable at compile-time (and pure)
// const fn _add(a: i32, b: i32) -> i32 {
//   a + b
// }
// val add: Pure<fn(i32, i32) -> i32> = Pure(_add);

fn main() {
  println!("Sum is: {}", pure! { add(1, 2) }.extract());
}
TheMatten

Or language developers could do something as simple as adding const marker to types that allows you to require pure arguments