I’ll answer on code style first. Doing these changes on the standard library might have other lower-level considerations (I don’t know if the generated code is binary compatible, but that’s best found out through a PR).
A few general questions that are relevant when discussing such code style issues (about abstraction) are:
- who is your audience? This is especially hard to answer for the std. library;
- writing less by omitting redundant info (like here) can make reading harder for some; is there (IDE) support to help them understand? Here, can they easily jump to
Equiv's definition? (for IDE users, I’d guess yes here).
- others might prefer the more abstract/simplified code because it’s more concise. Can it code be understood (by the audience) without expanding it back into the old code?
Not sure these matters are standardized enough (yet), and not sure there’s a one-size fit all standard.
In this case, for a reader who knows or can easily see/guess what’s
Equiv[T], this definition seems best — names like
y add almost no info. Some of the more meaningful names might be useful to keep, instead.
def reference[T <: AnyRef]: Equiv[T] = _ eq _
I can now read this code as,
reference is an
T implemented by reference equality (
_ eq _). Seems clear enough. The extra material is boilerplate.
The simplified code was already legal Scala in earlier releases, though only with
Equiv[T] defined as
type Equiv[T] = T => T. This might confuse some readers during transition.
OTOH, in some contexts one might wonder what is being inferred—that’s harder to figure out in the new code (though an IDE might help). This example is very lucky because the compact code can be read directly, but I’m not sure all examples are so easy.