-
Notifications
You must be signed in to change notification settings - Fork 1k
@stableABI
SIP.
#654
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
@stableABI
SIP.
#654
Conversation
|
||
__Dmitry Petrashko__ | ||
|
||
__first submitted 13 February 2017__ |
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.
It's currently January, not February yet ;-)
This seems to be a replacement for java-defined interfaces, why not name it |
will be compatible across major version of Scala. | ||
|
||
## Use Cases | ||
Dotty currently uses java defined interfaces as public API for SBT in order to ensure binary compatibility. |
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.
Actually dotty-interfaces
is not used by sbt at all. dotty-sbt-bridge
depends on dotty itself, and sbt will automatically compile it from source against the current version of dotty
(this is nothing new, the same thing happens with the scalac sbt bridge).
However, dotty-interfaces
is used by IntelliJ IDEA.
@densh, it does not only apply to interfaces. It also applies to classes. Given that there's an assumption that this feature is rarely used and only used by advanced users, I'd prefer not to give it a common name such as |
I'm not clear on the benefits of adding to the language specification for such an apparently narrow use case. Are there any concrete examples of where this might be useful other than the SBT bridge? If not then I'm not sure why a Java shim or some other ad hoc approach isn't adequate and appropriate. FWIW, it seems that the criteria for |
@milessabin thanks for your comment.
Inside the bodies of methods one can use all the features of Scala, as they won't be seen in the binary API observed from outside. I think I should be explicit about it and include examples that illustrate this. Thank you for pointing this out. |
👍, but also 👍 to reconsidering the name. In the cases where I've personally wanted something like this, the goal has been ease of Java interop in a multi-language codebase, not primarily binary compatibility as I think most people would understand it. |
I think this would be a very useful, but I agree with previous commenters that the name should be more specific. Something that suggests that only platform signatures are being used. |
Do you mean absolutely any synthetic construct? For instance, should bit-fields for lazy values be considered as those? Or stuff like |
|
||
## Introduction ## | ||
|
||
Scala is a language which evolves fast and thus made a decision to only promise binary compatibility across minor releases. |
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.
This is a very apt description. I wonder whether there are publications/talks that provide more context on the matter.
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.
What's a minor release and what's a major release? There are different conventions that people follow in our community.
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'll add a link defining both terms. Thank you.
|
||
Scala is a language which evolves fast and thus made a decision to only promise binary compatibility across minor releases. | ||
At the same time, there is a demand to develop APIs that live longer than a major release cycle of Scala. | ||
This SIP introduces an annotation `@binaryCompatible` that checks that `what you write is what you get`. |
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 with other commenters that a different name would be beneficial. To me, saying that something is binary compatible, immediately raises the question "with what?". This annotation doesn't answer that question.
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.
While I agree that the @binaryCompatible
name isn't perfect, I didn't yet find a better one.
As this annotation is intended to be rarely used and only by advanced users, I don't think we should concentrate that much on the name, but I welcome name suggestions.
that would be locally compiled. | ||
|
||
There's also a use-case of defining a class which is supposed to be also used from Java. | ||
`@binaryCompatible` will ensure that there are no not-expected methods that would show up in members of a class or an interface. |
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.
s/not-expected/unexpected/
As long as signatures of methods in source is not changed, `@binaryCompatible` annotated class | ||
will be compatible across major version of Scala. | ||
|
||
## Use Cases |
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.
Can we number these use cases, i.e. have this section look as follows:
1) Use case 1
<explanation>
2) Use case 2
<explanation>
etc
|
||
## Overview ## | ||
In order for a class or a trait to succeed compilation with the `@binaryCompatible` annotation it has to be: | ||
- defined on the top level; |
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.
Why limit this to just top-level classes? If I recall correctly, MiMa also flags changes to nested classes and synthetic stuff generated for things like new {}
and old-style lambdas.
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.
Why limit this to just top-level classes?
- Allowing to define
@stableABI
inner classes will most likely fail compilation due to second reason, as they will get successors synthesized to access the outer class; - there are several subtleties in how outer class can affect compilation of inner class, eg by converting private method to public;
- use-case of an inner class can be easily handled by defining a top-level supper class and making inner class extend it;
In order to have a more user-friendly behavior than 1 & 2, and given presence of a simple workaround, I've decided to prohibit it.
- defined on the top level; | ||
- use a subset of Scala that during compilation does not require changes to public API of the class, including | ||
- synthesizing new members, either concrete or abstract; | ||
- changing binary signatures of existing members, either concrete or abstract; |
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.
Are changes to the public API of class's companion also prohibited?
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.
added.
check which is sufficient to promise binary compatibility. | ||
|
||
## Overview ## | ||
In order for a class or a trait to succeed compilation with the `@binaryCompatible` annotation it has to be: |
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.
What about objects?
|
||
## Features that will fail compilation with `@binaryCompatible` | ||
The features listed below have complex encodings that may change in future versions. We prefer not to compromise on them. | ||
Most of those features can be simulated in a binary compatible way by writing a verbose re-impelemtation |
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.
Typo.
- default arguments; | ||
- default methods. See Addendum; | ||
- constant types(both explicit and inferred); | ||
- inline. |
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.
Why exclude inline?
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.
The idea is that @stableABI
classes don't need @scalaSignature
or @tasty
to compile against. In order for inline to work, we'll need to be able to read the trees from those sections and make assumptions about those trees, that can be dependent on compiler version.
I propose to go conservative route here, we'll have an opportunity to allow more features later, but we won't have an opportunity to remove them.
## Compilation scheme ## | ||
No modification of typer or any existing phase is planned. The current proposed scheme introduces a late phase that runs before the very bytecode emission that checks that: | ||
- classes and traits annotated as `@binaryCompatible` are on the top level; | ||
- no non-private members where introduced inside classes and traits annotated as `@binaryCompatible` by compiler using phase travel; |
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.
What's phase travel?
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 Compilation scheme
section needs explanation of common terms used inside both compilers.
At the same time, there is a demand to develop APIs that live longer than a major release cycle of Scala. | ||
This SIP introduces an annotation `@binaryCompatible` that checks that `what you write is what you get`. | ||
It will fail compilation in case emitted methods or their signatures | ||
are different from those written by users. |
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.
s/users/authors/
|
||
__first submitted 13 January 2017__ | ||
|
||
## Introduction ## |
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 that this document would benefit from the definitions of the following terms:
- Binary compatibility (both the intransitive and transitive variations used in the text below)
- Public API
- Binary signature
- The notion of signatures being different from those written by their authors.
I'd suggest having a small example that introduces and illustrates these notions.
@xeno-by, thank you for your through review. As most questions are asking about definitions of terms, I think I'll introduce a new section that defines terms used in this SIP. It's indeed harder to follow than most sips as current writing assumes knowledge of both compiler internals and JVM spec. |
Speaking of the name, I welcome suggestions. |
Just had a Dotty meeting, which was also joined by @retronym. |
FWIW. With |
The CI seems to fail, without reporting any errors. |
It won't be displayed even if the CI succeeds. The GitHub pages builds are also timing out and failing. So until we can move this site to chara/alaska, or fix #607, this page can't be displayed on the site. |
@heathermiller, ouch. Thanks for having a look. |
Hey @DarkDimius, a fix is on the way #684. When we merge it, can you rebase your changes so that Travis doesn't time out? |
Can you please rebase on top of #685? |
4e13db2
to
810637b
Compare
@jvican thank you for the ping. Rebased. |
I'm a bit confused about the current name for the annotation. Is it |
TLDR:
This is intended to be @tailrec - like annotation that will fail compilation in case emitted methods or their signatures are different from those written by users. In order for @stableabi compatible class to succeed compilation there should be: no methods synthesized and no signatures changed.
The intended use-case is providing binary compatibility across major Scala versions by ensuring that a class or a trait
is compiled as written by developer
.UPD: changed name of the annotation and the SIP.