Skip to content

Replacing "when" by "when and only when"#619

Closed
patricekrakow wants to merge 1 commit into
semver:masterfrom
patricekrakow:master
Closed

Replacing "when" by "when and only when"#619
patricekrakow wants to merge 1 commit into
semver:masterfrom
patricekrakow:master

Conversation

@patricekrakow

Copy link
Copy Markdown

Fixes #475

@ljharb ljharb left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should not land. The only thing that needs preventing is breaking changes in a non-major. It is always perfectly acceptable to bump the major even when there are no changes whatsoever.

@patricekrakow

Copy link
Copy Markdown
Author

Hello @ljharb thanks for your comment. Following your reaction, as well as the ones from the issue #475, I was wondering if I should continue or just close this PR/issue. If I understand you correctly, you are OK with:

breaking-change(s) => MAJOR++
if there is a breaker change, then the MAJOR must be incremented

but, you are not OK with the opposite proposition:

MAJOR++ => breaking-change(s)
if the MAJOR has been incremented, then there must have been a breaking change.

In order words, you are not OK with the equivalence between the presence of a breaking change and the increment of the MAJOR:

breaking-change(s) <=> MAJOR++
there is a breaking change if and only if the MAJOR has been incremented
or
MAJOR++ <=> breaking-change(s)
the MAJOR is incremented if and only if there is a breaking change

Personally, I still believe that the equivalence is key if you take the point of view of the consumer. From the consumer point of view, while she/he is not interested by new features, she/he wants the interface (and its behavior) to be stable. So, the key information is the increment of the MAJOR. If the MAJOR has not been incremented, she/he can be quite confident that the interface (and its behavior) will remain stable from her/his point of view, and consequently she/he does not have to plan a costly upgrade.
On the other hand, if the MAJOR has been incremented, she/he has no choice to plan a costly upgrade, and what a frustration if at the end, she/he realized that there was no breaking change. How could the producer justify that she/he has increment the MAJOR just because it was "nice", while the consumer would have wasted her/his resources.

I don't know if that resonates with your experience, maybe I am missing other use cases, but let me try one more time to sell the equivalence between breaking change and MAJOR increment...

@ljharb

ljharb commented Sep 28, 2020

Copy link
Copy Markdown
Contributor

If the major is incremented, they have no choice but to read the changelog and plan the upgrade, which might be costly, or may even have no cost at all. Majors don’t implicitly carry any cost - breaking changes do. Majors just warn of a potential breakage, and then the user has to figure out what it is, if it exists.

I’m not a maintainer here, but if i were I’d suggest the issue/PR be closed.

@patricekrakow

Copy link
Copy Markdown
Author

@ljharb thanks again for your comment. I have read again the https://semver.org/ and it is clear that the point 8 gives an only-one-way-implication:

backwards incompatible changes => MAJOR++

It clearly looks OK to you, and many others, but I still can't stop thinking that a two-way equivalence would be way better:

backwards incompatible changes <=> MAJOR++

which would mean:

( backwards incompatible changes => MAJOR++ ) AND ( MAJOR++ => backwards incompatible changes )

setting an additional constraint on the producer.

I am also realizing that I use semantic versioning not only for packages that are statically linked (imported) to other packages, but also for software that are accessed via the network. And, within this latest use case, I plan to use semantic versioning in order to take run-time routing decision. It might be why I found the two-way equivalence more appealing... In addition to that, I am now also wondering if the sentence "packages you integrate into your software" and in particular the word "into" exclude the situations in which the package/software is accessed via the network (or simply via an inter-process communication) from the semantic versioning scope...

@Nixinova

Copy link
Copy Markdown

Considering the 1:4 like:dislike ratio on #475 I think this PR should be closed due to lack of support. This is too major a change to implement while controversial.

@patricekrakow

Copy link
Copy Markdown
Author

Let me try one more time ;-)

Let's focus on the first sentence only:

Given a version number MAJOR.MINOR.PATCH, increment the MAJOR version when you make incompatible API changes.

Let's re-write this sentence as an implicational relationship between two statements:

Incompatible API changes => MAJOR++ (1)

Therefore, the core of our discussion is about the validity of the reciprocal relationship:

MAJOR++ => Incompatible API changes (2)

This second implicational relationship would then lead to an equivalence relation:

Incompatible API changes <=> MAJOR++ (3)

Following the comments I received, I do realize that a lot of people disagree on the validity of (2). Still, I may have found another way to explain the relation (2), starting for the original text. Let's start from the following paragraph of the section "Why Use Semantic Versioning?".

Consider a library called "Firetruck." It requires a Semantically Versioned package named "Ladder." At the time that Firetruck is created, Ladder is at version 3.1.0. Since Firetruck uses some functionality that was first introduced in 3.1.0, you can safely specify the Ladder dependency as greater than or equal to 3.1.0 but less than 4.0.0. Now, when Ladder version 3.1.1 and 3.2.0 become available, you can release them to your package management system and know that they will be compatible with existing dependent software.

I would naturally complement this paragraph by:

On the other hand, when Ladder version 4.0.0 become available, you cannot release it to your package management system as you know that it will not be compatible with existing dependent software.

And, this new sentence could be expressed as the following implicational relationship between two statements:

MAJOR++ => Incompatible API changes (2)

@ljharb

ljharb commented Feb 5, 2021

Copy link
Copy Markdown
Contributor

However, that is false - because you CAN upgrade to it if you know that your usage of it isn't the breaking part.

In other words, even with your nonexistend-but-desired restriction, the breaking change in a package's major bump still might not be used by a particular consumer, thus, to that consumer, the major bump contains no breaking change.

@sheldonh

Copy link
Copy Markdown

@patricekrakow Is there anything anyone could say to you that would have you accept that you have been heard and understood, but not agreed with? If so, please consider it said. You don't need to keep trying to be understood.

@patricekrakow

Copy link
Copy Markdown
Author

@sheldonh I am afraid I will continue trying to be understood... For instance, you wrote: "Ask yourself why you would want to prevent me from arbitrarily bumping the MAJOR version number for reasons you haven't considered." in #475. And, I am trying to say that you can't (from a logical point of view) say something like that since we are talking about a "semantic version" and not any kind of "version". The idea behind having a "semantic version" is to have a "version" that convey "semantics", i.e. meaning. When you talk about "arbitrarily bumping the MAJOR version", you do not respect the semantics, i.e. the meaning, of your "semantic version".

Having a "semantic version" means that I can get some semantics, i.e. meaning, out of it, if you increment the "semantic version" arbitrarily, without taking into account its semantics, that's not a "semantic version" anymore.

I do acknowledge that I am also taking the point of view of the consumer. For me, a "semantic version" is there to convey semantics, i.e. meaning, to the consumer and that, naturally, put more constraints on the producer. But, again, what's the value of "semantic version" that allows the producer to arbitrarily increment the "version"... the consumer can't learn anything from it. If you say to your consumer I have incremented the MAJOR because I have made incompatible API changes, or because I wanted to, you have said nothing. On the other hand, if you say to your consumer I have incremented the MAJOR because I have made incompatible API changes, (and not just because I wanted to) then you send a clear message that can be used to make a decision.

I will stop for now, but I have the impression this is not over... I am still looking for a better - maybe more formal - way to explain my point...

@sheldonh

sheldonh commented Feb 23, 2021

Copy link
Copy Markdown

@sheldonh I am afraid I will continue trying to be understood...

It is supremely arrogant to conclude that you are not being understood when people do not agree with you.

For instance, you wrote: "Ask yourself why you would want to prevent me from arbitrarily bumping the MAJOR version number for reasons you haven't considered." in #475. And, I am trying to say that you can't (from a logical point of view) say something like that since we are talking about a "semantic version" and not any kind of "version". The idea behind having a "semantic version" is to have a "version" that convey "semantics", i.e. meaning. When you talk about "arbitrarily bumping the MAJOR version", you do not respect the semantics, i.e. the meaning, of your "semantic version".

This is what you are wrong about. The semantics allow arbitrary bumping of the major version. They do this by failing to forbid it. You are saying that the semantics should forbid it and we are disagreeing with you.

Having a "semantic version" means that I can get some semantics, i.e. meaning, out of it, if you increment the "semantic version" arbitrarily, without taking into account its semantics, that's not a "semantic version" anymore.

This is nonsense. It does mean something. The semantics simply do not mean what you want them to mean. It means "this release is a big deal, see the release notes." We have had a practical example at work where it has made sense to bump the major version even though the API itself is backward compatible (ops concerns).

I do acknowledge that I am also taking the point of view of the consumer.

Indeed. I understand that there is consumer value in the revised definition that you would like the spec to adopt. But a consequence of your revised definition is a restriction that producers do not want.

I will stop for now, but I have the impression this is not over... I am still looking for a better - maybe more formal - way to explain my point...

My suggestion is that you stop before you do your reputation harm. You have been very clear with your point and it's insulting to continue to argue as if you are not being understood. The implication is that your perspective trumps everyone else's and you must be right.

@patricekrakow

Copy link
Copy Markdown
Author

@sheldonh - I am super sorry that you perceived the fact that I was thinking I am not able to explain myself properly as supremely arrogant.

I do appreciate your comment:

Indeed. I understand that there is consumer value in the revised definition that you would like the spec to adopt. But a consequence of your revised definition is a restriction that producers do not want.

And, then, conclude that what I am looking for is something else than semantic versioning, and therefore defines it as another versioning scheme.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Replacing "when" by "when and only when"?

4 participants