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
Proclaim that EXPERIMENTAL APIs can be changed after 1.0.0 #238
Comments
How would you suggest the API be marked as such? Are you suggesting the possibility of moving (a project) to 1.0.0 while still having an experimental API? |
For example it could be documented somewhere, or be marked as such in the doc-comment. I do not think we would need to clarify how it should be marked, considering the fact that the current specification does not define how public API should be marked.
Yes. In most cases, development continues after reaching 1.0.0. And in some cases (especially in large-scale projects) it is usual to have an unstable API that is provided through several minor releases. But the current specification is silent in how such APIs should be provided, even though it specifically discusses about 0.x.y (which are unstable development releases) and a.b.c-(alpha/beta)d releases (which are pre-releases of specific versions). To me it seems like confusing; so I decided to open this issue. |
I'm definitely interested. I'd definitely like to hear some more views on the topic. |
Hopefully, git provides branches. For example :
|
@linkdd Yes, git provides branches, as does all the other popular source control systems out there that I'm aware of. Separating experimental from development and/or pre-release branches doesn't really solve the problem, as each of them still should have a unique version. That being said, it might be sufficient to declare a particular version (whether it is in a different branch or not) as experimental, and note in the README as such. Keeping that experimental branch private is all well and good until you want to have it tested more: once that happens, and it gets out in the world, it should definitely have a unique version attached to it, so anyone helping with the experiment can properly upgrade to non-experimental. So, all that being said, it seems as though we've almost come full-circle. Keeping an experiment private and contained (never releasing it to anyone and storing it in a branch) is probably not a great way to go. Have I missed something? |
@linkdd Thank you for the suggestion. IMO, using two version numbers in parallel (1.a.b for a release containing only public APIs only and 0.c.d for a release containing experimental APIs as well) would make release engineering complicated. And it also makes the user-side code complicated. The idea behind semver is to define a formal method for determining whether a certain feature is provided by a software. For example, with semver it is possible to write code like:
However the scheme would not work if you are to number the releases with experimental APIs with
And what make it even worse is you cannot even use
As can be seen, all the merits for using semver has gone. EDIT: expanded my understanding why it is not a good idea. |
Semver doesn't mandate how the public API is documented. If your project says that "experimental" APIs are not part of the official public API, then you are following the spec.
|
This sounds too much like breaking semver. Can't you just:
Then you can merge/rebase back and forth as you want to get yourself plenty of time to do your experiments before they mature enough to be considered for merging into 1.1.0 or 2.0.0. If you want to expose the "future API" you can always share the actual repos, you can have separate document that includes also the experimental changes somewhere in notes/ sub-folder in your repo, or in a completely separate repo. |
My 2 cents on this
|
@kazuho, is there some reason why you can't use prerelease tags on these experimental versions? The spec unambiguously defines what the prerelease tags means in terms of the semantics of the version string and it seems to be exactly what you need. Unless you have further questions or comments, please close this issue at your earliest possible convenience. |
I've seen this situation in Gradle. They have a lot of ongoing parallel projects to deliver new functionality. They instead follow @alechenninger opinion and mark new API as |
@grv87 , the main problem with that approach is your consumers automation is likely not constructing an AST of the API's and reasoning about the relative risks for production or test consumption. Their tooling is making decisions based on the contents of the SemVer string. It is very bad form to release experimental API's in packages that are marked as stable and also bad form to only ever publish prereleases. It's just bad hygiene from an engineering viewpoint and not conforming to SemVer. But then, SemVer is not required in many cases and echo-systems develop around common practice, however unsound they might be. |
@jwdonahue I'm not big fan of what @grv87 mentioned, but is it really so bad to add API? Can addition break anything? IMO the real trouble starts if someone uses the experimental API, and if they do so in production environment. Now if the (in-)stability of the API is made clear, the onus is on the developer to read all the words in the reference and restrain from using it. I agree it's not the best hygiene to mix experimental and stable; it's much cleaner to provide stone-stable releases with stone-set APIs. I just think it's not really matter of automation but of development. For this to cause a real problem requires even worse hygiene on consumer part. (Of course it depends on what "addition" means: defining new Python method sure is addition. Inserting element into struct in C is probably not.) |
@AloisMahdal, the spec does leave a lot of wiggle room wrt exactly what is being versioned, so I can't really answer your question definitively. Adding API's is one thing, removing or altering it later simply because it had been tagged with a language specific keyword, and not bumping the appropriate version at that point, has a bad smell. The spec says your documentation or code defines your API, and that would include language keywords such as EXPERIMENTAL. So technically, breaking changes in such code does not require a major version bump. But you've got developers busy breaking things in the code, how stable is the implementation behind the published non-experimental API? @grv87 says "If they tag each release with experimental API as prerelease they would never make a release". While obviously not true, that suggests an unstable product to me, but I don't really know the details of how Gradle is developed. It is obvious from their published versions, they don't use SemVer. It's one thing to suggest that "this API is subject to change" and entirely different to add "without notice". Do they bump their major version when they make a change in an experimental API? |
@jwdonahue, yes, Gradle doesn't use SemVer. I just chose it to demonstrate the concept of experimental (incubating) features. I believe this could work the same way with SemVer. @AloisMahdal, I agree that this is not the best option, but one of. Better way is to split the product to separate plugins/modules and version them separately. Adding API in existing classes can break subclasses (in some languages). Also, adding API could create conflicts if other projects use the same class/method/… names. But I haven't seen an example when anybody would truly consider these as breaking changes. |
Thanks everyone for contributions, you're amazing 🎆 Did you find any consensus? |
Just adding my 2cents: Ruby started to adding "experimental" features in minor release to gather feedback from the community. Not only bugs, but to really experiment how those new features feel. Experimental features may be removed or have breaking changes in between minor releases. This approach allowed maintainers to add new features and collaborate with the community without keeping a separated branch or releasing a major release every time. More about Ruby's versioning here. |
Update FAQs in Korean documents
From my thoughts, this issue is completely solved by spec item 9, the solution being use pre-release versions (e.g.
What are your thoughts? |
A discussion about semver has ensued because a library we are developing intends to ship a new (undocumented) property named Clarity on this in the not-too-distant-future would be much appreciated! :-D |
@davidmurdoch it's not clear, actually - in practice, people will grow to depend on this property, and breaking it will break them. If you don't want something to be part of your API, don't make it reachable from your API. |
@ljharb if that is the stance semver takes then we don't need semver at all; ever single change is breaking. Someone might come to rely on a bug, or might rely on a feature being missing... |
Making a slippery slope argument doesn't change anything. There is a huge difference between a bug and an undocumented property. |
Dismissing my counter argument as a slippery slope is a straw man. I noticed you work at Coinbase... if you are in NYC for the NFT NYC conference maybe we could debate these things in person 😁. |
Yes, SemVer is not always the correct approach and we should not try to make it the be-all/end-all scheme, that would just complicate it too much.
I don't see how anybody could take a dependency on a non-existent feature, but it is the case that developers take dependencies on bugs. I know of more than a few cases where publishers got locked-in to supporting a small set of them due to the sizeable fraction of their customers who came to depend on them, before said bugs were identified. They are mostly low severity bugs that don't have to get fixed, but in some cases, they represented security issues and then the publisher had to break everybody. When SemVer is used in such cases, the major version bump, tends to slow adoption of the critical security fixes, and require more PR effort to drive adoption. It is less disruptive than releasing the breaking change(s) as a patch however. Annoying the hell out of your customers is not the best way to get them to accept your critical security patches. In many cases, the publishers were well within their rights of claiming that said bugs were not part of the defined API of the product, issuing patches for them and accepting that a small percentage of their user base might not be very happy about it.
If your API docs clearly state your intention that __experimental_info is not part of your supported API, then you are well within your rights to remove it later, without the major version bump. However, the '_experimental' part of that name alone, is not sufficient to indicate that particular publicly available symbol is not part of the supported API, without additional documentation indicating that it is the case. The SemVer spec already allows for that. First it establishes that you define what your API is, then it defines the syntax and rules for bumping/resetting the various SemVer fields. @kazuho 's proposed change should be rejected IMO. The -prerelease mechanism is already sufficient and I don't see how "marked as experimental" should necessarily be translated to "not part of my API". |
People often wonder if going to version 1.0.0 would slow the development. IMO this is because the specification / FAQ is silent about how to develop additional APIs after reaching to 1.0.0 while specifically stating that 0.x.y is a development release.
To tackle such (mis)understanding, I think adding a clause like below would make us more comfortable.
The text was updated successfully, but these errors were encountered: