scala / scala3

The Scala 3 compiler, also known as Dotty.
https://dotty.epfl.ch
Apache License 2.0
5.89k stars 1.06k forks source link

`inline def derived` instead of `inline given derived` in the derivation doc example #15848

Open cayhorstmann opened 2 years ago

cayhorstmann commented 2 years ago

Compiler version

3.1.3

Actual

In https://docs.scala-lang.org/scala3/reference/contextual/derivation.html, I believe the declaration of the Eq typeclass has an error. The declaration

inline given derived[T](using m: Mirror.Of[T]): Eq[T] =

causes the given to be available whether or not a class asks for it with derives. See https://scastie.scala-lang.org/gHhbWQ0bT56wG1t4H2mFpw

Expectation

I expect the given only to be available when a class has a derives clause. One gets this behavior with

inline def derived[T](using m: Mirror.Of[T]): Eq[T] =

I hesitated to report this because many blogs do the same (https://www.47deg.com/blog/scala-3-deriving-typeclasses/, https://blog.philipp-martini.de/blog/magic-mirror-scala3/, https://medium.com/riskified-technology/type-class-derivation-in-scala-3-ba3c7c41d3ef, ), Maybe I misunderstand the feature. But then consider clarifying what derives is intended to do.

KacperFKorban commented 2 years ago

Both of those declarations have their own use cases. The first one is often referred to as automatic derivation, and the second one is often called semi-automatic derivation (at least in magnolia's nomenclature).

Did that answer your question? Or is there a specific part of the text that you think is wrong or written in a confusing way?

cayhorstmann commented 2 years ago

I guess that in the context of Scala 3, automatic derivation means to provide

inline given anyName[T](using m: Mirror.Of[T]): Eq[T] =

inside the companion object. Then all matching types (here, sums of products with Eq components) automatically join the typeclass without having to declare derives Eq.

And i guess further that semiautomatic derivation means to provide

inline def derived[T](using m: Mirror.Of[T]): Eq[T] =

In that case, a type needs to declare derives Eq to join the typeclass.

Is that correct?

If so, it would be a really good idea (1) to use def, not given, in the declaration of Eq (2) when intentionally using given to show automatic derivation, not to call the method derived, and (3) to use the semiautomatic terminology in https://dotty.epfl.ch/docs/reference/contextual/derivation.html#type-classes-supporting-automatic-deriving