Iota 0.1.0 Released

Iota 0.1.0 Released

We are proud to announce a new open source library, Iota 0.1.0.

Iota is a small library to make coproducts easier to use in Scala by providing a simpler syntax with a fast underlying implementation.

Traditional coproduct implementations are implemented as binary trees or linked lists at both the type and value level. The syntax for traditional coproducts can become unwieldy as the number of disjunct types grows.

import cats.data._

// a coproduct of types using scala.util.Either
type EitherFoo = Either[Int, Either[String, Double]]

// a coproduct of type constructors using cats.data.Coproduct
type CoproductBar0[A] = Coproduct[List, Seq, A]
type CoproductBar[A] = Coproduct[Option, CoproductBar0, A]

In the example above, both EitherFoo and CoproductBar will become difficult to read as the number of types increases.

Iota addresses this by using linked lists at the type level.

import iota._
import TList.::
import KList.:::

// a coproduct of types
type Foo = Cop[Int :: String :: Double :: TNil]

// a coproduct of type constructors
type Bar[A] = CopK[Option ::: List ::: Seq ::: KNil, A]

At the value level, values are stored directly along with an index of the corresponding type in the type linked list. This allows for minimal overhead when dealing with coproducts of many types.

Additionally, this allows for very fast interpretation of algebras with automatically generated interpreters.

sealed abstract class UserOp[A]
sealed abstract class OrderOp[A]
sealed abstract class PriceOp[A]

type Algebra[A] = CopK[UserOp ::: OrderOp ::: PriceOp ::: KNil, A]

val evalUserOp : UserOp  ~> Future = dummyInterpreter
val evalOrderOp: OrderOp ~> Future = dummyInterpreter
val evalPriceOp: PriceOp ~> Future = dummyInterpreter

// create the interpreter

val evalAlgebra0: Algebra ~> Future = CopK.FunctionK.of(
  evalUserOp, evalOrderOp, evalPriceOp)

// note: order doesn't matter when creating the interpreter since
// iota will sort it out for you

val evalAlgebra1: Algebra ~> Future = CopK.FunctionK.of(
  evalOrderOp, evalPriceOp, evalUserOp)

// if your interpreters are implicitly available, you can summon
// a fan in interpreter

implicit val _evalUserOp  = evalUserOp
implicit val _evalOrderOp = evalOrderOp
implicit val _evalPriceOp = evalPriceOp

val evalAlgebra2: Algebra ~> Future = CopK.FunctionK.summon

The interpreters created by Iota are optimized for speed and have a constant evaluation time. The overhead for traditional binary tree coproducts increases as the number of algebras increase. Below is a benchmark comparison of the worst case performance of interpreters for iota.CopK and cats.data.Coproduct.

Iota vs Cats benchmark

To get started with Iota, checkout the Iota repository on GitHub. Additionally, be sure to check out Freestyle, which relies on Iota for improved runtime performance. Read more on this here: Freestyle 0.1.0 Released.

blog comments powered by Disqus

Ensure the success of your project

47 Degrees can work with you to help manage the risks of technology evolution, develop a team of top-tier engaged developers, improve productivity, lower maintenance cost, increase hardware utilization, and improve product quality; all while using the best technologies.