non-backward compatible packages (Was: [racket-users] [ann] gregor (date + time library) updates)

85 views
Skip to first unread message

Neil Van Dyke

unread,
Aug 31, 2015, 10:27:54 AM8/31/15
to Racket Dev List
What's the current new package system policy on non-backward-compatible
changes in a package version?

I think, originally, it was that a non-backward-compatible package had
to use a different name (say, package `foo` must then be released as
under the package name `foo2`). I don't know whether that's the current
policy.

(I'm not picking on this interesting-sounding calendar library. Just
wondering about the general question, since I haven't decided how to
version my own packages in the new package system.)

Neil V.

Jay McCarthy

unread,
Aug 31, 2015, 10:35:10 AM8/31/15
to Neil Van Dyke, Racket Dev List
I wouldn't say there is or has been a policy. There's advice based on
what the release process packages do.

Generally, adding a new export or module is not considered
incompatibility. (Although technically it is, because it could reduce
the set of other packages that can be simultaneously installed.)

Once you've committed to compatibility (by labeling a package with
version "1.0"), then any incompatible change should end up in a new
package/module, because at that point there's really no meaningful
connection between the old code and the new code, except maybe similar
purpose.

I think in the case of gregor, since interface was removed, then it is
"incompatible" in the sense we normally mean in Racket. I think it
would come down to whether it was ever at 1.0 and whether it had
actually been used by anyone.

Jay
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Developers" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-dev+...@googlegroups.com.
> To post to this group, send email to racke...@googlegroups.com.
> To view this discussion on the web visit
> https://groups.google.com/d/msgid/racket-dev/55E46464.3070603%40neilvandyke.org.
> For more options, visit https://groups.google.com/d/optout.



--
Jay McCarthy
http://jeapostrophe.github.io

"Wherefore, be not weary in well-doing,
for ye are laying the foundation of a great work.
And out of small things proceedeth that which is great."
- D&C 64:33

Jon Zeppieri

unread,
Aug 31, 2015, 10:42:00 AM8/31/15
to Neil Van Dyke, Racket Dev List
On Mon, Aug 31, 2015 at 10:27 AM, Neil Van Dyke <ne...@neilvandyke.org> wrote:
> What's the current new package system policy on non-backward-compatible
> changes in a package version?

Good question.

>
> I think, originally, it was that a non-backward-compatible package had to
> use a different name (say, package `foo` must then be released as under the
> package name `foo2`). I don't know whether that's the current policy.

That was my understanding, too, though, as you can see, I didn't do
that. My reasoning went like this:

- As far as I know, no one is using this library. (But, if anyone is,
please let me know.)
- It's actually extremely unlikely that the changes would break any
existing code, even if the library were being used. (But, if I have
broken your code, again, please let me know.)

-Jon

Jon Zeppieri

unread,
Aug 31, 2015, 10:43:59 AM8/31/15
to Jay McCarthy, Neil Van Dyke, Racket Dev List
On Mon, Aug 31, 2015 at 10:35 AM, Jay McCarthy <jay.mc...@gmail.com> wrote:
> I wouldn't say there is or has been a policy. There's advice based on
> what the release process packages do.
>
> Generally, adding a new export or module is not considered
> incompatibility. (Although technically it is, because it could reduce
> the set of other packages that can be simultaneously installed.)
>
> Once you've committed to compatibility (by labeling a package with
> version "1.0"), then any incompatible change should end up in a new
> package/module, because at that point there's really no meaningful
> connection between the old code and the new code, except maybe similar
> purpose.
>
> I think in the case of gregor, since interface was removed, then it is
> "incompatible" in the sense we normally mean in Racket. I think it
> would come down to whether it was ever at 1.0 and whether it had
> actually been used by anyone.

To clarify: no interfaces were removed. Interfaces were added.

>
> Jay
>

Jay McCarthy

unread,
Aug 31, 2015, 10:44:36 AM8/31/15
to Jon Zeppieri, Neil Van Dyke, Racket Dev List
IMHO, being able to think like this is a feature of the package
system. Compatibility/etc is not a technical question but a social one
and we'd like ways of easily providing the technical details and forum
for that conversation to take place. I can imagine ways it could be
better, like a tool that helps authors tell how and where their code
was used.

Jay McCarthy

unread,
Aug 31, 2015, 10:46:03 AM8/31/15
to Jon Zeppieri, Neil Van Dyke, Racket Dev List
I was referring to these comments:

"So, for example, `+years` is no longer part of the `date-provider`
interface; it's now part of `date-arithmetic-provider`, and values
that satisfy `date-period?` also satisfy `date-arithmetic-provider?`."

"And `duration-between` was removed in favor of
date-period-between, time-period-between, and
period-between."

The first sounds like a function isn't in a module anymore and the
second sounds like a function is just gone. But I didn't look at the
code or docs.

Jay

Faré

unread,
Aug 31, 2015, 10:48:37 AM8/31/15
to Jay McCarthy, Neil Van Dyke, Racket Dev List
On Mon, Aug 31, 2015 at 10:35 AM, Jay McCarthy <jay.mc...@gmail.com> wrote:
> I wouldn't say there is or has been a policy. There's advice based on
> what the release process packages do.
>
> Generally, adding a new export or module is not considered
> incompatibility. (Although technically it is, because it could reduce
> the set of other packages that can be simultaneously installed.)
>
Indeed, the question is not one of extent, but of intent.

*Any* semantically-visible change, including the most trivial bug fix,
will by definition break some potential client. e.g. a client that
would expect the buggy case to be a bug, or the set of working cases
to be exhaustively covered by some inductive definition (e.g.
type-checker), etc. Adding a working case will break those clients,
those types, etc.

The question is one of intent. Are the intended clients going to keep
working and/or be updated to keep working with the current library, or
are you making such changes that they will break and won't want to
adapt to the modified API?


> Once you've committed to compatibility (by labeling a package with
> version "1.0"), then any incompatible change should end up in a new
> package/module, because at that point there's really no meaningful
> connection between the old code and the new code, except maybe similar
> purpose.
>
My experience with ASDF taught me that "compatibility" is not a social
notion, not a strictly technical one. See my ASDF3 article:
http://fare.tunes.org/files/asdf3/asdf3-2014.html#%28part._backward_compat%29

—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org
Be yourself, everybody else is taken. — Oscar Wilde

Jon Zeppieri

unread,
Aug 31, 2015, 10:49:56 AM8/31/15
to Jay McCarthy, Neil Van Dyke, Racket Dev List
On Mon, Aug 31, 2015 at 10:46 AM, Jay McCarthy <jay.mc...@gmail.com> wrote:
> On Mon, Aug 31, 2015 at 10:43 AM, Jon Zeppieri <zepp...@gmail.com> wrote:
>> To clarify: no interfaces were removed. Interfaces were added.
>
> I was referring to these comments:
>
> "So, for example, `+years` is no longer part of the `date-provider`
> interface; it's now part of `date-arithmetic-provider`, and values
> that satisfy `date-period?` also satisfy `date-arithmetic-provider?`."
>
> "And `duration-between` was removed in favor of
> date-period-between, time-period-between, and
> period-between."
>
> The first sounds like a function isn't in a module anymore and the
> second sounds like a function is just gone. But I didn't look at the
> code or docs.

Ah, in the second case, you're correct. `duration-between` is simply
gone. That is a plain old breaking change.

In the first case, however, the function is still part of the same
module. The change is that it's part of a new generic interface.
However, both interfaces are exported by the `gregor` module. (And all
existing structs that implement the old interface also implement the
new one, which is why this change is unlikely to break anything.)

-Jon

Jon Zeppieri

unread,
Aug 31, 2015, 11:09:29 AM8/31/15
to Neil Van Dyke, Racket Dev List
On Mon, Aug 31, 2015 at 10:42 AM, Jon Zeppieri <zepp...@gmail.com> wrote:
>
> - As far as I know, no one is using this library. (But, if anyone is,
> please let me know.)

More importantly, if you're not using gregor and you are doing
date/time calculations in metric, please let me know why you're not
using it.
- Is there a critical missing feature?
- Is it because it isn't supposed by other libraries (e.g., the db library)?
- Is it because of the design of the library?

I'd very much like gregor to be useful.

-Jon

Alexander D. Knauth

unread,
Aug 31, 2015, 11:11:02 AM8/31/15
to Jay McCarthy, Jon Zeppieri, Neil Van Dyke, Racket Dev List

On Aug 31, 2015, at 10:44 AM, Jay McCarthy <jay.mc...@gmail.com> wrote:

> On Mon, Aug 31, 2015 at 10:42 AM, Jon Zeppieri <zepp...@gmail.com> wrote:
>> My reasoning went like this:
>>
>> - As far as I know, no one is using this library. (But, if anyone is,
>> please let me know.)
>> - It's actually extremely unlikely that the changes would break any
>> existing code, even if the library were being used. (But, if I have
>> broken your code, again, please let me know.)
>
> IMHO, being able to think like this is a feature of the package
> system. Compatibility/etc is not a technical question but a social one
> and we'd like ways of easily providing the technical details and forum
> for that conversation to take place. I can imagine ways it could be
> better, like a tool that helps authors tell how and where their code
> was used.

This wouldn't completely solve that problem, but it would go part way:
Would it be possible to get a list of all of the packages that declare a dependency on a certain package?
It should be; I think the pkg-dep-draw package does something similar.

Neil Van Dyke

unread,
Aug 31, 2015, 11:26:02 AM8/31/15
to Racket Dev List
My super-strongly preferred engineering notion: backward-compatibility
of a package refers to the *documented* behavior of the package, not to
actual behavior.

For the moment, disregard the exception cases arising when actual
behavior of a version doesn't comply with documented behavior for that
version. I think it's important to focus first on human
expression&interpretation of *documented* behavior. Developing to
interface documentation (like to specs of a bolt from the manufacturer)
helps a lot of engineering processes work, especially between
organizations. I think that this "between organizations" should be the
usual case with the package system.

(Even if you had some breakthrough halting-problem-transwarp approach to
determining backward-compatibility programmatically, with a pretty
DrRacket smiley/frowny-face icon indicator, I would still expect to be
able to work from the English documentation of behavior. I'm not
ignoring the possibilities of unit tests and formal specification, but,
at the end of the day, I think your documentation needs to be
human-readable, for preferred engineering processes as we know them to
work.)

Neil V.

Jens Axel Søgaard

unread,
Aug 31, 2015, 1:21:56 PM8/31/15
to Neil Van Dyke, Racket Dev List
One possible convention that allows users of old versions to switch at their convenience.

  foo       imports and exports foo-n
  foo-1    version 1
  foo-2    version 2
  ....
  foo-n     current version

/Jens Axel



--
You received this message because you are subscribed to the Google Groups "Racket Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to racket-dev+...@googlegroups.com.
To post to this group, send email to racke...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.



--
--
Jens Axel Søgaard

Greg Hendershott

unread,
Sep 1, 2015, 12:53:03 PM9/1/15
to Jay McCarthy, Racket Dev List
What happens to the version in info.rkt?

Does a foo2 package have version "2.x" in info.rkt?

Or does it get reset to "1.x"? (On the theory that there's no such
thing as a backward-incompatible version of a package, just a new
package. And on the assumption a major version change implies
backward-incompatible.)

Both answers seem slightly weird to me. I suppose the first one seems
less weird.
> To view this discussion on the web visit https://groups.google.com/d/msgid/racket-dev/CAJYbDano0BxJJ19RN6%3Df7mh%2BZHnM-%3D1zJ-4PqDA63S%3DGt0JQZg%40mail.gmail.com.

Jay McCarthy

unread,
Sep 1, 2015, 12:56:41 PM9/1/15
to Greg Hendershott, Racket Dev List
The version field in the info file can use any numbers you want under
any circumstance. It has nothing to do with the package name. It could
start at 4.x or 1.x or 99.x, whatever you want.

There is no connection between two packages with different names, no
matter if they share prefixes, suffixes, internal substrings, etc.

Jay

Jack Firth

unread,
Sep 1, 2015, 1:42:52 PM9/1/15
to Racket Developers
Personally I think it would also be helpful to encourage people to make `unstable` collections for their packages so they know they have somewhere to experiment with new features before committing to them fully. This is the approach Alex and I have been using on our lens package and it's working fairly well.

Spencer Florence

unread,
Sep 1, 2015, 5:22:43 PM9/1/15
to Racket Developers
I have some concerns about the "a backwards-incompatible change should result in a new package" idea.

Firstly, it would clutter the package server. This would also confuse new users, who would arrive at the package server and see several editions of the same package. For just Cover we would have two packages already, and Cover is under a year old. 

Secondly, while I agree that compatibility is a primarily social question, our tooling should make answering that question easy, not cumbersome. Having to create a new package for something that is logically a modified version of an existing package seems cumbersome, for both the package maintainer and for the package user.

Finally, a question, assuming we with stick with the creating new packages for incompatible changes. If one discovers that some part of their interface is a mistake, but that fixing/removing it would be backwards incompatible, is creating a new package still the correct decision? For example, in Cover's upcoming release we have split the repository into a two parts, partitioning the Coveralls support into a separate package. This is because we don't want to implicitly endorse Coveralls as a coverage front end, and because we would like to support several coverage front ends without making each user install all of them. Should we, for our next release, create a "cover2" and "cover-coveralls" package, leaving the package server with "cover", "cover2", and "cover-coveralls" packages?

--Spencer


On Tue, Sep 1, 2015 at 12:42 PM Jack Firth <jackh...@gmail.com> wrote:
Personally I think it would also be helpful to encourage people to make `unstable` collections for their packages so they know they have somewhere to experiment with new features before committing to them fully. This is the approach Alex and I have been using on our lens package and it's working fairly well.

--
You received this message because you are subscribed to the Google Groups "Racket Developers" group.
To unsubscribe from this group and stop receiving emails from it, send an email to racket-dev+...@googlegroups.com.
To post to this group, send email to racke...@googlegroups.com.

Jack Firth

unread,
Sep 1, 2015, 6:31:56 PM9/1/15
to Racket Developers
I agree with the points about clutter and cumbersome-ness, but I think that could be fixed with smarter UI and the like on the package server and package installation process. A simple thing to do would be to just have multiple packages like `foo`, `foo2`, `foo3` not shown, and only the latest shown. Renaming the collections and modules from `foo` to `foo2` as part of the release process is still a complete pain, but that's trickier to get around.

Faré

unread,
Sep 1, 2015, 6:42:59 PM9/1/15
to Jack Firth, Racket Developers
It would be nice for packages to be able to be declared deprecated (if
possible by the author, or else by a third party with review by the
repository maintainer) and offer a link to one or many suggested
replacement.

—♯ƒ • François-René ÐVB Rideau •Reflection&Cybernethics• http://fare.tunes.org
If normative judgments cannot be rational, then science is actually useless.
— François Guillaumat

Neil Van Dyke

unread,
Sep 1, 2015, 6:46:42 PM9/1/15
to Racket Developers
Another thing that's important to what I need from the package system...

I'd like to promote a model of software development based on a mix of
many modules written from the start to be reusable. A system comprises
modules both off-the-shelf third-party and developed in-house. The
in-house modules are developed in such a way that you can often
selectively open-source the non-strategic ones at negligible cost.

A reality affecting this is that, as organizations develop their
systems, they will often coordinate non-backward-compatible changes
among their modules. Keeping the barrier to maintaining the open-source
releases of those modules low means that open-source releases will also
be non-backward-compatible at times I'd like the packaging and
versioning scheme to make the incentive/altruistic dynamic work for both
producer and open-source consumer of a package.

PLaneT had a very simple 90%+ solution to package naming and versioning
that I thought was palatable to both producers and open-source
consumers. Names were stable, major version were incremented to say
believed-non-backward-compatible, consumers could say their baseline
compatible version ("1.3+") or live dangerously, a Racket installation
could have multiple versions of a package, and done. (There were some
layered things that would have been very useful to add to PLaneT, such
as a system version manifest, but the simple version model generally
satisfied its purpose, and I'd say the main adoption barrier of PLaneT
was only that the tools should've automated more.)

I appreciate that the new package system does a lot more than PLaneT,
and also has some new conveniences (e.g., arbitrary HTTP and `git`
locations). I'm not criticizing it. I just haven't figured out how to
get it to do what I liked about PLaneT.

I'd like to use the new package system to work even better than PLaneT
for my purposes. Maybe someone already has a great approach supporting
the development model I described. If so, I'd like to hear about the
approach, so that hopefully I can adopt it the next time I have a free
weekend. (I had intended to convert my PLaneT packages&tools&workflow
to the new package system before the end of summer, but I haven't had
what seemed like a sufficient block of free time to get it over with.
Not knowing how I'm going to handle versioning in a satisfying way make
me think I'd need more than a weekend.)

You might be thinking "well, people can just copy the various package
code versions that they want into their SCM repositories, who needs
versioning." That does happen, and that also is an easy way for code to
get privately forked and improvements not shared back (or later dumped
on github in unusable form), licenses lost as code is copied&pasted.
New versions of the open source releases can also be hard for a consumer
to adopt, when they get into copying and modifying. I'd like to
encourage open source packages maintaining their identity, and have them
work smoothly in the kind of reusability&modularity and open source
sharing that we'd like to see, within the various incentive/altruism
dynamics we have.

Neil V.

Reply all
Reply to author
Forward
0 new messages