Seven at one blow – New & polished features in Scalaz 7

A1216674d5c9747bcdcc716872439137?s=47 Lars Hupel
February 08, 2013

Seven at one blow – New & polished features in Scalaz 7

My talk at the Northeast Scala Symposium 2013, featuring: À-la-carte implicits, Unapply, Law checking, Type-level programming, and Community involvement.

Slides are prepared with LaTeX beamer/XeLaTeX, fonts: Roboto and DejaVu Sans Mono, code highlighting: minted/pygments.

A1216674d5c9747bcdcc716872439137?s=128

Lars Hupel

February 08, 2013
Tweet

Transcript

  1. 1.

    Seven at one blow New & polished features in Scalaz

    7 Lars Hupel Februrary 8th, 2013
  2. 2.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement About @larsr

    h ▶ studies Computer Science ▶ first contribution December 2011 ▶ committer since February 2012 ▶ active (co)maintainer since October 2012 ▶ did not invent any of the following Lars Hupel Seven at one blow Februrary 8th, 2013 2 / 35
  3. 3.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement About Scalaz

    Scalaz is a Scala library for functional programming. ▶ purely functional data structures ▶ type classes known from Haskell ▶ current stable version: 6.0.4 ▶ successor under development for over a year compatible with 2.9.x, 2.10.x (and probably 2.11.x) Lars Hupel Seven at one blow Februrary 8th, 2013 3 / 35
  4. 4.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement À-la-carte implicits

    Unapply Laws Type-level programming Community involvement Lars Hupel Seven at one blow Februrary 8th, 2013 4 / 35
  5. 5.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement À-la-carte implicits

    Unapply Laws Type-level programming Community involvement Lars Hupel Seven at one blow Februrary 8th, 2013 5 / 35
  6. 6.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Previously, in

    Scalaz 6 all-you-can-eat object provides most of the implicits Lars Hupel Seven at one blow Februrary 8th, 2013 6 / 35
  7. 7.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Previously, in

    Scalaz 6 Example // import everything import scalaz._ import Scalaz._ // get all instances implicitly[Monad[Option]] // get all syntax (10.some |@| none) { (_: Int) |+| (_: Int) } Lars Hupel Seven at one blow Februrary 8th, 2013 7 / 35
  8. 8.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Now, in

    Scalaz 7 Distinction between different kinds of implicits 1. type class instances ▶ ... of our own data types ▶ ... of standard library types 2. syntax: infix operators ▶ ... for type class instances ▶ ... for standard library types 3. functions on our own data types Lars Hupel Seven at one blow Februrary 8th, 2013 8 / 35
  9. 9.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Now, in

    Scalaz 7 Example import scalaz._ { // import the instance import std.option._ Monad[Option] } Lars Hupel Seven at one blow Februrary 8th, 2013 9 / 35
  10. 10.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Now, in

    Scalaz 7 Example import scalaz._ { import std.option._, std.anyVal._ import syntax.apply._ import syntax.semigroup._ import syntax.std.option._ (10.some |@| none) { (_: Int) |+| (_: Int) } } Lars Hupel Seven at one blow Februrary 8th, 2013 9 / 35
  11. 11.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Now, in

    Scalaz 7 Example import scalaz._ { import std.option._, std.anyVal._ import syntax.all._, syntax.std.all._ (10.some |@| none) { (_: Int) |+| (_: Int) } } Lars Hupel Seven at one blow Februrary 8th, 2013 9 / 35
  12. 12.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Why is

    this better? Disadvantages ▶ more import statements ▶ makes compile-time debugging harder Lars Hupel Seven at one blow Februrary 8th, 2013 10 / 35
  13. 13.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Why is

    this better? Advantages ▶ you can use syntax, but you don’t have to ▶ improves readability of the code ▶ makes compile-time debugging easier ▶ increases compilation speed Lars Hupel Seven at one blow Februrary 8th, 2013 10 / 35
  14. 14.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement À-la-carte implicits

    Unapply Laws Type-level programming Community involvement Lars Hupel Seven at one blow Februrary 8th, 2013 11 / 35
  15. 15.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement The problem

    def f[M[_], A](x: M[A]): M[A] = x f { (x: Int) => x } Lars Hupel Seven at one blow Februrary 8th, 2013 12 / 35
  16. 16.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement The problem

    def f[M[_], A](x: M[A]): M[A] = x f { (x: Int) => x } Prints a type error: found : Int => Int required: ?M[?A] Lars Hupel Seven at one blow Februrary 8th, 2013 12 / 35
  17. 17.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement The problem

    Candidates ▶ M[X] = Int ⇒ X ▶ M[X] = X ⇒ Int ▶ M[X] = X ⇒ X ▶ M[X] = Int ⇒ Int ▶ ... This is a known limitation (SI-2712). Lars Hupel Seven at one blow Februrary 8th, 2013 13 / 35
  18. 18.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement The problem

    Candidates ▶ M[X] = Int ⇒ X ▶ M[X] = X ⇒ Int ▶ M[X] = X ⇒ X ▶ M[X] = Int ⇒ Int ▶ ... This is a known limitation (SI-2712). Lars Hupel Seven at one blow Februrary 8th, 2013 13 / 35
  19. 19.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement The problem

    Candidates ▶ M[X] = Int ⇒ X ▶ M[X] = X ⇒ Int ▶ M[X] = X ⇒ X ▶ M[X] = Int ⇒ Int ▶ ... This is a known limitation (SI-2712). Lars Hupel Seven at one blow Februrary 8th, 2013 13 / 35
  20. 20.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement The problem

    Candidates ▶ M[X] = Int ⇒ X ▶ M[X] = X ⇒ Int ▶ M[X] = X ⇒ X ▶ M[X] = Int ⇒ Int ▶ ... This is a known limitation (SI-2712). Lars Hupel Seven at one blow Februrary 8th, 2013 13 / 35
  21. 21.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement The problem

    Candidates ▶ M[X] = Int ⇒ X ▶ M[X] = X ⇒ Int ▶ M[X] = X ⇒ X ▶ M[X] = Int ⇒ Int ▶ ... This is a known limitation (SI-2712). Lars Hupel Seven at one blow Februrary 8th, 2013 13 / 35
  22. 22.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Let’s use

    math! ▶ known as Higher-order unification ▶ Scala adds subtyping ▶ everything is subtype of Any ▶ Any is always well-kinded ▶ ambiguous ▶ undecidable Lars Hupel Seven at one blow Februrary 8th, 2013 14 / 35
  23. 23.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Let’s use

    math! ▶ known as Higher-order unification ▶ Scala adds subtyping ▶ everything is subtype of Any ▶ Any is always well-kinded ▶ ambiguous ▶ undecidable Lars Hupel Seven at one blow Februrary 8th, 2013 14 / 35
  24. 24.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Let’s use

    math! ▶ known as Higher-order unification ▶ Scala adds subtyping ▶ everything is subtype of Any ▶ Any is always well-kinded ▶ ambiguous ▶ undecidable Lars Hupel Seven at one blow Februrary 8th, 2013 14 / 35
  25. 25.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Let’s use

    math! ▶ known as Higher-order unification ▶ Scala adds subtyping ▶ everything is subtype of Any ▶ Any is always well-kinded ▶ ambiguous ▶ undecidable Lars Hupel Seven at one blow Februrary 8th, 2013 14 / 35
  26. 26.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Let’s use

    math! ▶ known as Higher-order unification ▶ Scala adds subtyping ▶ everything is subtype of Any ▶ Any is always well-kinded ▶ ambiguous ▶ undecidable Lars Hupel Seven at one blow Februrary 8th, 2013 14 / 35
  27. 27.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Let’s use

    math! ▶ known as Higher-order unification ▶ Scala adds subtyping ▶ everything is subtype of Any ▶ Any is always well-kinded ▶ ambiguous ▶ undecidable Lars Hupel Seven at one blow Februrary 8th, 2013 14 / 35
  28. 28.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Let’s use

    math! ▶ known as Higher-order unification ▶ Scala adds subtyping ▶ everything is subtype of Any ▶ Any is always well-kinded ▶ ambiguous ▶ undecidable Lars Hupel Seven at one blow Februrary 8th, 2013 14 / 35
  29. 29.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Let’s approximate!

    def f[M[_], A](x: M[A]): M[A] = x f { (x: Int) => x } A type constructor without a type class is rarely useful. Lars Hupel Seven at one blow Februrary 8th, 2013 15 / 35
  30. 30.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Let’s approximate!

    def f[M[_] : Monad, A](x: M[A]): M[B] = ??? f { (x: Int) => x } Now: more information which can guide type inference Lars Hupel Seven at one blow Februrary 8th, 2013 15 / 35
  31. 31.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Dependent types

    to the rescue Define a proof object containing: ▶ the type constructor M[_] ▶ the inner type A ▶ the type class instance M[_] : Monad ... and have lots of implicits guided by: ▶ prioritisation ▶ availability of type class instances Lars Hupel Seven at one blow Februrary 8th, 2013 16 / 35
  32. 32.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Dependent types

    to the rescue Define a proof object containing: ▶ the type constructor M[_] ▶ the inner type A ▶ the type class instance M[_] : Monad ... and have lots of implicits guided by: ▶ prioritisation ▶ availability of type class instances Lars Hupel Seven at one blow Februrary 8th, 2013 16 / 35
  33. 33.
  34. 34.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Does it

    work? Yes! ▶ Scalaz 6: conversions for each concrete type ▶ now: general mechanism for common shapes ▶ in many cases, type parameters can be omitted List(1, 2, 3) traverseU { a => State { x: Int => (x + 1, a) } } Lars Hupel Seven at one blow Februrary 8th, 2013 18 / 35
  35. 35.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Does it

    work? Well, sort of. ▶ 500 lines of boilerplate ▶ one implicit per type shape (there are infinitely many) ▶ compile errors can get a little funky ▶ needs dependent types Lars Hupel Seven at one blow Februrary 8th, 2013 18 / 35
  36. 36.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement À-la-carte implicits

    Unapply Laws Type-level programming Community involvement Lars Hupel Seven at one blow Februrary 8th, 2013 19 / 35
  37. 37.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Contracts .

    . “ The equals method implements an equivalence relation on non-null object references: ▶ It is reflexive: for any non-null reference value x, x.equals(x) should return true. ▶ It is symmetric: for any non-null reference values x and y, x.equals(y) should return true if and only if y.equals(x) returns true. ▶ ... Java API: Object#equals . . ” Lars Hupel Seven at one blow Februrary 8th, 2013 20 / 35
  38. 38.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Type classes

    & Lavs ▶ type classes abstract over types ▶ offer common functionality ▶ users expect similar behaviour ▶ ... which needs to be formalised Lars Hupel Seven at one blow Februrary 8th, 2013 21 / 35
  39. 39.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Type classes

    & Lavs ▶ type classes abstract over types ▶ offer common functionality ▶ users expect similar behaviour ▶ ... which needs to be formalised Lars Hupel Seven at one blow Februrary 8th, 2013 21 / 35
  40. 40.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Type classes

    & Lavs ▶ type classes abstract over types ▶ offer common functionality ▶ users expect similar behaviour ▶ ... which needs to be formalised Lars Hupel Seven at one blow Februrary 8th, 2013 21 / 35
  41. 41.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Legal problems

    . . “ I have a legal question: Is this a lawful monoid to you? Tony Morris . . ” Lars Hupel Seven at one blow Februrary 8th, 2013 22 / 35
  42. 42.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Laws in

    Scalaz ▶ embedded in type classes, mirroring their hierarchy ▶ one method per law ▶ ScalaCheck tests instances ▶ ... by producing random input ▶ Not a theorem prover! ▶ ... but better than usual unit tests ▶ our bindings can be used by other projects ▶ 332 occurences of checkAll in our tests Lars Hupel Seven at one blow Februrary 8th, 2013 23 / 35
  43. 43.
  44. 44.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement À-la-carte implicits

    Unapply Laws Type-level programming Community involvement Lars Hupel Seven at one blow Februrary 8th, 2013 25 / 35
  45. 46.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement It’s in

    the types Scalaz has heterogeneous lists too! ▶ ... but not as general as in Shapeless ▶ used for: ▶ Applicative syntax ▶ String formatting ▶ type class composition Lars Hupel Seven at one blow Februrary 8th, 2013 27 / 35
  46. 47.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Heterogeneous lists

    Everybody loves tuples. ▶ fixed arity, different element types ▶ maximum arity 22, one class per arity ▶ but: no useful manipulations (reverse, append, access, ...) Lars Hupel Seven at one blow Februrary 8th, 2013 28 / 35
  47. 48.
  48. 49.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement À-la-carte implicits

    Unapply Laws Type-level programming Community involvement Lars Hupel Seven at one blow Februrary 8th, 2013 30 / 35
  49. 50.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement What happened

    in the past year? We got tons of contributions (≈ 200 issues & pull requests). ▶ folding non-empty data structures ▶ Lens families ▶ documentation & test fixes ▶ interoperability with other libraries ▶ new data types ▶ less lawless classes ▶ ... Lars Hupel Seven at one blow Februrary 8th, 2013 31 / 35
  50. 51.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement Validation DSL

    check(”123456789012345”). checkThat(strLength(16, ”wrong length”)). checkThat(luhn(”wrong checksum”)). convertTo(int(”not an integer”)). toValidation // Result: // Failure(NonEmptyList(wrong length, wrong checksum)) Lars Hupel Seven at one blow Februrary 8th, 2013 32 / 35
  51. 52.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement What can

    you do? ... if you’re using Scalaz 6 ▶ migrate to the latest milestone ▶ Tell us about it! ... if you’re not using Scalaz ▶ adopt Scalaz 7 ▶ Ask questions! Lars Hupel Seven at one blow Februrary 8th, 2013 33 / 35
  52. 53.

    À-la-carte implicits Unapply Laws Type-level programming Community involvement What are

    we going to do? ▶ release 7.0.0-final soon ... probably this year ▶ not break too much until then ▶ stay binary compatible in the 7.0.x series ▶ revamp our web site(s) Lars Hupel Seven at one blow Februrary 8th, 2013 34 / 35