-
Notifications
You must be signed in to change notification settings - Fork 30
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SIP-66 - Implicit macro conversions #86
base: main
Are you sure you want to change the base?
Conversation
This should be sip 66 |
This is also required for Mill, which uses a lot of macro implicit conversions for its Task DSL |
Yes. That's why I included it in the Motivation section 👍 @lihaoyi mentioned it first in this thread |
Hello @smarter, do you have any news on it ? 🙏 |
|
||
or alternatively: | ||
|
||
```scala |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the full class should look like this:
@java.lang.FunctionalInterface
abstract class InlineConversion[-T, +U]:
inline def apply(x: T): U
extension (x: T) inline def convert = this(x)
I prefer InlineConversion
over MacroConversion
since the implementations need not necessarily be macros; they could just be inline methods.
parameter, a "proxy given" can be defined: | ||
|
||
```scala | ||
inline given [T, U](using macroConv: MacroConversion[T, U]): Conversion[T, U] = new: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this would do the right thing either. The apply
method would pass a non-inlined x
macroConv
. I don't think that macroConv
will be able to anything significant with x
in this case.
I believe we just have to accept that InlineConversion
and Conversion
cannot be mixed.
def myMethod(using Conversion[Foo, Bar]) = ??? | ||
``` | ||
|
||
In this case, according to implicit rules and the `given` instance [previously defined](#support-using-conversion), the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As I wrote before, I don't think this given
instance will work.
val x: Bar = Foo() | ||
``` | ||
|
||
Therefore, the third option seems to be the most suited. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree. I believe a good way to conceptualize this is that for finding a conversion between A
and B
we do an implicit search for Conversion[A, B] | InlineConversion[A, B]
. And if there is one of each, we get an ambiguity.
|
||
### Abuse concerns | ||
|
||
Implicit conversions, especially in Scala 2, were criticized for being prone to abuse, making code more confusing and |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have come around to accept that macro conversions cannot be avoided in some existing use cases. So if we want to get rid of the old implicit def syntax, we need to provide a solution.
This proposal was discussed in today's SIP committee meeting. There was general agreement that inline/macro implicit conversions do have important use cases and will need to be supported going forwards. However the conclusion was that we can't make a decision about this proposal without first deciding on the future syntax and restrictions for regular implicit conversions. That may take some time - I don't think there's even a SIP for it yet, although there have been various discussions on the contributors forum. I believe the intention is to retain support for the current |
One problematic aspect in the proposal is to have two type classes for But there is an alternative, which I discovered when playing with another potential SIP. We can make abstract class InlineConversion[-From, +To]:
inline def applyInline(inline x: From): To
extension (x: From) inline def convertInline: To = applyInline(x)
abstract class Conversion[-From, +To] extends InlineConversion[From, To]:
def apply(x: From): To
inline def applyInline(inline x: From): To = apply(x)
extension (x: From) def convert: To = apply(x) When searching for an implicit conversion from Another advantage of this scheme is that any questions how to disambiguate between inline and regular conversions are already answered by the standard given priority rules. That is, from 3.7 on inline conversion would win over conversion since it is more general. |
No description provided.