That is a good point. So I’m quoting it to stress it.
I do have a segue about it, though: still using Laminar as my “benchmark” for what a good design using implicits looks like. In Laminar it is common practice to define user functions that take Modifier
s as arguments. See here for one of the examples that does that (function renderInputRow
):
and here for the sequence of the “Big Video” tutorial that explains the rationale:
For these user functions, we also want stuff that can be converted to Modifier[El]
to be converted. With the into
keyword at parameter site, it means we’ll have to teach users of Laminar that they need to define all parameters of type Modifier[El]
with the into
keyword.
It is quite likely that, in those situations, the alternative of “use one extra import statement” is likely to prevail. Even with a carefully-crafted library code.
This wouldn’t be an issue if we could instead annotate the definition of Modifier
itself, as a type-to-convert-to.
Now, if we do annotate types instead of parameters, how can we still respect the meta-design point mentioned at
?
I think we can do this by being quite specific about what we can annotate, and where those annotations are looked up. For the purposes of giving examples, I will use the following syntax:
conversionTarget trait Foo
I believe it would be fine to restrict what we can annotate to nominal type definitions. That means:
class
definitionstrait
definitionsopaque type
definitions
Specifically, this excludes (non-opaque) type aliases and type parameters. This is an important ingredient to limit the influence of type inference on where implicit conversions can happen.
The other ingredient is when do we even look for an implicit conversion? I think for that we can stick to the existing rules, modulo the conversionTarget
restriction: if I have an expected type E
known to be a reference to a conversionTarget T
, and the term doesn’t conform to E
, we can look for implicit conversions to E
. Since conversionTarget
only applies to nominal types, and we must know that E
is a reference to a conversionTarget
before starting to look for implicit conversions, that should dramatically reduce the influence of type inference on where implicit conversions can enter into play.