improvement-proposals
improvement-proposals copied to clipboard
SIP-61 - Unroll Default Arguments for Binary Compatibility
CC @eed3si9n @alexarchambault @julienrf, who have worked on similar proposals/libraries/compiler-plugins in the past
@alexarchambault please give it a try! Do note that the current published compiler plugin uses an older version of the proposal. You can take a look at the linked example PRs to see how to use it
I have updated the writeup and prototype implementation with support for abstract method defs, with the same limitation that any downstream implementations must be final (i.e. no override alliowed). This opens up @unroll for usage in interfaces, which will definitely prove handy: interface methods have to evolve just as much as final methods do!
I am reasonably confident the treatment of abstract method defs is correct, but please help me take a look at the section Abstract Methods and help me double check things.
Also CC @lefou and @lolgab as the folks who have been pushing for binary-compatibility and semantic versioning within the com.lihaoyi ecosystem; would be great if you guys could help give this proposal a read through and see if it makes sense
Adding an abstract method to an open hierarchy is never a backward binary compatible change: it breaks existing subclasses. It's OK if the whole hierarchy is sealed.
Adding an abstract method to an open hierarchy is never a backward binary compatible change: it breaks existing subclasses. It's OK if the whole hierarchy is sealed.
in this case, @unroll generates reverse forwarders such that no abstract methods are added or removed. MiMa passes, and my own ad-hoc classpath munging tests pass.
I don't know whether you've read through the updated proposal, but there's a whole section on the unrolling of abstract methods and why it allows addition of default parameters to be backwards binary compatible and semantically compatible. If there's something I missed please call it out for discussion
I think having at least the option to mark the generated forwarder methods as deprecated is important. Although binary compatibility is the driving concern here, APIs are use by developers who need to understand and decide which method they should go for. Without any @deprecation notice, they may choose the wrong, resulting in unnecessarily limited compatibility. And I'm also having polyglot APIs, reflection acces and ScalaDoc in mind, where it matters, which explicit API is recent and what is deprecated; in contrast to pure Scala code, where the compile is most likely deciding which override to call.
And since @deprecated takes a since parameter which is IMHO important, we most likely need a since in @unroll too.
@lrytz suggested that in Scala 2 we could generate the forwarders post pickler phase, which makes them invisible to downstream Scala compilation runs. And Scala 3 there is an Invisible annotation that does the same thing
I havent implemented these in the prototype yet, bit they sound like they would work
I have updated the prototype implementation to use the post-pickler/invisible approach to hiding the generated forwarder methods, and updated the doc accordingly
@alexarchambault I have published the latest version of @unroll, in accordance to this proposal. You can use it in Mill via
def scalacPluginIvyDeps = super.scalacPluginIvyDeps() ++ Agg(ivy"com.lihaoyi::unroll-plugin:0.1.12")
def ivyDeps = super.ivyDeps() ++ Agg(ivy"com.lihaoyi::unroll-annotation:0.1.12")
@lrytz I have moved the Abstract Methods section out of the main proposal into the Alternatives section, as discussed during the meeting since we won't be implementing it as part of this proposal
The proposal was unanimously "Accepted for implementation" in the May SIP meeting, given these latest changes:
@unrollis only supported on final methods; the "Abstract Methods" section is now under "Alternatives"@unrollAllis also under "Alternatives", so not part of the accepted proposal
@lihaoyi does the text in the merged file represent the current state approved spec?
@bishabosha yes that's the current state of the approved spec. The Scala 3 compiler plugin in https://github.com/com-lihaoyi/unroll should mostly work, though we'd need to disable to abstract method support and replace it with error reporting for that and any non-final methods
FYI for everyone, @bishabosha will be picking up the work integrating the current POC compiler plugin into the dotty mainline repo