Skip to content

Release notes: shapeless 2.0.0 M1

Miles Sabin edited this page Sep 1, 2013 · 1 revision

A first milestone for the next major release of shapeless.

This is the first milestone release of shapeless-2.0.0. Most new features and refactorings are in place for the final release, and this preview is intended to provide a context for feedback from prospective users and users of the current release. Detailed migration notes are available.

A big "Thank You!" to everyone who has contributed to this release, either directly in code or by using and discussing it, by inviting me to talk about it, and especially by ignoring my adivce that shapeless was experimental and should under no circumstances be used in production. In particular I would like to thank Mathias Doenitz (@sirthias) and Eric Torreborre (@etorreborre) for taking the plunge and using shapeless in Spray routing and Specs 2 respectively. I am also very grateful to Eugene Burmako (@xeno_by) for his work on Scala macros, implicit macros in particular, which have enabled much of what's new.

Code contributors for shapeless 2.0.0 are,

Many thanks to all of you.

There are a large number of new features, refactorings and bugfixes in shapeless 2.0.0. The most significant of these are,

  • Scala 2.10.2 or later is now required. The advantages offered by implicit macros are so significant that all current and future shapeless development has committed to them.

    Regrettably this means that shapeless-1.2.4 will very likely be the last release for Scala 2.9.x. It might be possible to backport some of the cosmetic changes to Scala 2.9.x, but I'd like to gauge the level of interest in continued support for older Scala releases before embarking on that. It might also be feasible to backport the major new features via a compiler plugin for Scala 2.9.x. Anyone interested in contributing to or sponsoring such work should [get in touch with me](mailto:[email protected]).

  • HList-style operations are now available directly on native Scala tuples. This supports a wide variety of tuple manipulation operations which would otherwise be extremely tedious to implement manually. Examples can be found here and here.

  • shapeless's Isos have been completely reworked as the new Generic type, which closely resembles the generic programming capabilities introduced to GHC 7.2. Generic[T], where T is a case class or an abstract type at the root of a case class hierarchy, maps between values of T and a generic sum of products representation (HLists and Coproducts). Values of Generic for a given case class are materialized using an implicit macro, allowing a wide variety of structural programming problems to be solved with no or minimal boilerplate.

    In particular the existing [lens][lenses], [Scrap Your Boilerplate][sybclass] and [generic zipper][zipper] implementations are now available for any case class family ([recursive families included] [recursive]) without any additional boilerplate being required.

  • Based on and extending Generic, Lars Hupel has contributed the TypeClass type class, which provides automatic type class derivation facilities roughly equivalent to those available with GHC as described in "A Generic Deriving Mechanism for Haskell". There is a description of the Scala mechanism here, and examples of its use deriving Show and Monoid instances here and here. The shapeless-contrib project also contains automatically derived type class instances for Scalaz, Spire and Scalacheck.

  • Support has been added for working directly with singleton-typed literal values in Scala. Although Scala's typechecker has always represented these types internally, there has not previously been syntax available to express them, other than by modifying the compiler. This omission has been remedied by the use of implicit macros.

    Singleton types bridge the gap between the value level and the type level and hence allow the exploration in Scala of techniques which would typically only be available in languages with support for full-spectrum dependent types. The latest iteration of shapeless records (see next bullet) makes a start on that, and the [examples in the tests][singletons] illustrate other possibilities.

  • As a first application of singleton-typed literals, shapeless records are now represented as HLists of values tagged with the singleton types of their keys. This means that there is no concrete representation needed at all for the keys. Amongst other things this will allow subsequent work on Generic to map case classes directly to records with their member names encoded in their element types.

    Joni Freeman contributed an [updateWith][updatewith] operation. His library [sqltyped][sqltyped] [makes extensive use][sqltypedeg] of shapeless records.

  • The same implicit macro conversion mechanism which allows literal values to be converted to their singleton-typed equivalents is now also used to allow Int literals to be used where Nat values were previously required. Amongst other things, this allows HLists and tuples to be indexed using Ints.

  • The library's namespace has been reorganized to bring it into better alignment with the other typelevel projects, Scalaz and Spire, and to reduce general clutter. See the migration guide for more details.

    • Extension methods are now brought into scope by importing from an object in the shapeless.syntax package (eg. import shapeless.syntax.singleton_ to import singleton type related extension methods). Extensions to standard Scala types can typically be found under shapeless.syntax.std (eg. import shapeless.syntax.std.tuple._).
    • Type classes and the implicits which materialize them are now imported from the shapeless.ops package (eg. import shapeless.ops.hlist._).
    • The previous shapeless convention of providing two variants of all type classes, one with result types as members and one (with an Aux suffix) with result types as additional type parameters, has been refined. Now only the definition with type members is provided as a first-class trait or class, and the additional type parameter variant is defined via a type alias in the former's companion object. This results in a significantly smaller number of class files and also simplifies implicit resolution in some cases.
    • The Poly and Case name conventions have been aligned with the new shapeless type class name convention.
    • The internals of Poly had (ironically) a large amount of arity specific/restricted artefacts. These have now been largely eliminated, yielding a more consistent structure.
    • The type classes and extension methods for converting between functions of multiple arguments and functions with a single HList argument have been renamed more transparently.
    • All implict definitions now have explicit result types, which should result in improved compile times.
  • Various improvements to HList,

    • Added zipConst to zip an HList with a constant (thanks to Cody Allen).
    • The base case for removeAll is now HNil allowing removals to be more uniform where the list of removed types is a type variable which might be HNil (thanks to Michael Donaghy).
    • Added the SubtypeUnifier type class for normalizing subtypes of a given type in an HList to that type (thanks to Travis Brown)
    • Some unexpected Filter type class instances are no longer created (thanks Travis Brown).
    • The HNil trait is now sealed, eliminating non-exhaustiveness warnings in pattern matching.
    • zipped and unzipped have been renamed to zip and unzip for consistency with the corresponding new operations provided for tuples, which are so-named to avoid clashing with the preexisting zipped on Tuple2 and Tuple3.
    • Added minimally witnessed instances for toList[Any] and toArray[Any].
    • Added HKernel, an attempt to reduce the number of implicit witnesses required to perform operations on HLists whose elements share a common outer type constructor.

  • Libraries like shapeless which make extensive use of type-level computation and implicit resolution often need to provide guarantees that certain expressions don't typecheck. Testing these guarantees is now supported via the illTyped macro, and all tests have been updated to use it where appropriate.

  • The Sized type is now a value class, eliminating much of its runtime overhead.

  • Polymorphic methods can now be automatically converted to polymorphic function values.

  • Nat additions including Min and Pow type classes and type level factorial and gcd examples (thanks to George Leontiev)

  • New and improved examples: the type class instance packing and unpacking example now provides completely automatic unpacking as well as packing; and an example illustrating the use of singleton types and path dependent types to encode things normally only expressible in full spectrum dependently typed languages has been added.

There have also been many improvements to the build,

  • Support for Scala 2.11.x has been moved to its own branch.
  • Snapshot builds of master and the scala-2.11.x branch are now built and published automatically using Travis CI
  • shapeless is now built with SBT 0.13.0.
  • The build now uses the sbt-buildinfo and sbt-git plugins to provide useful runtime build information (see shapeless.BuildInfo), and the sbt-release plugin is used to prepare releases.
  • The sbt-osgi plugin is now used to add OSGi metadata to the core library jar (thanks to Michael Pilquist).
  • Whilst the examples are not strictly speaking tests, they are canaries for potential issues, and a run-all SBT task has been added to support verifying that they execute without runtime errors.
  • A .jvmopts file has been added to the root of the project to provide a sensible configuration for the sbt-extras SBT launcher script.
  • Added 'import shapeless. _ ' as a console initial command.