[Haskell-cafe] ANN: network 3.0.0.0
Alexander Kjeldaas
alexander.kjeldaas at gmail.com
Sun Jan 20 20:22:47 UTC 2019
While those are good suggestions, the biggest problem is not whether a
given deprecation strategy is correct or not.
The biggest problem with the PVP in this case is that it does *not say
anything about how to release a "pre" release* so any deprecation strategy
could be tested by the community.
This makes the concept of *learning* painful, because mistakes are way too
expensive.
Can this be fixed first, then later we can figure out how to do
deprecations? Or am I wrong?
Alexander
On Sat, Jan 19, 2019 at 6:38 PM Niklas Hambüchen <mail at nh2.me> wrote:
> Thanks for the quick reply!
>
> > I'd love to hear ideas.
>
> I recommend the following way:
>
> * Never change the type of an existing function unless absolutely
> necessary.
> * Do not change the the behaviour/semantics of a function unless it's an
> obvious fix/improvement.
> (In other words, if somebody may in some reasonable way rely on the old
> behaviour, don't change it).
> * Improve functions by introducing new functions with names, marking the
> old functions as deprecated.
> * GHC will show deprecation warnings to users.
> ** In the deprecation message, point out the intended replacement.
> ** If a deprecated function is planned to be removed in the next release,
> say it in the message.
> * Consider removing deprecated functions after some years. But only if
> e.g. maintainability demands it.
> ** In some cases, consider moving the functions to an `.Old` module or
> similar.
>
> Key point:
> * Use deprecations and new functions liberally to make progress. Almost
> never break existing functions.
>
> I like to call this approach "the Java way of deprecation", and it helps
> an ecosystem to move forward swiftly while keeping people happy a whole
> lot. This is because it allows incremental transitions instead of hard
> cutoff points that often don't align with people's schedules or test plans.
>
> How this relates to the PVP:
> This thought process happens *before* PVP considerations enter the stage.
> After you've made your changes (hopefully as few breaking ones as
> possible), you can use the PVP to determine what the new version should be.
> The reverse logic should not be applied: If some change made demands a
> major version bump (e.g. removal of an old deprecated function that nobody
> uses), that does not "allow" other functions to be removed more liberally.
> The rationale is that our goal is not to do as much as a given version jump
> allows, but to minimise breaking changes for users even when we know that
> some breaking changes must be made.
>
> (Also, while the PVP as mentioned doesn't tell you what to do with your
> package contents and applies afterwards, the diagram in
> https://pvp.haskell.org/pvp-decision-tree.svg mentions "Consider renaming
> the function instead" next to "Did the behaviour of any exported functions
> change", so I think what I recommend is in the spirit of those that came up
> with the process).
>
> Concrete example:
>
> This is how I imagine applying the above to network 3.0.0.0 would have
> worked:
>
> * Deprecate `send`, `sendTo`, `recv`, etc. (As correctly done in
> network-2.7)
> * Do NOT remove them. Leave at least 2 years time before touching them.
> * In this case, move them to Network.Socket.String, instead of removing
> them. For 2 reasons:
> ** These functions have been this ways since forever and lots of code will
> use them. Putting them into a legacy module will allow projects to
> trivially get into a compiling state again with one `import` change, vs
> having to fix every use site. This eases migration.
> ** While certainly not a good idea, the String based functions aren't so
> fatally flawed that they have no justification for further existence, so
> keeping them in a legacy module would do no harm.
> * Introduce `socketToFd :: Socket -> IO CInt`
> * Deprecate `fdSocket`, saying why it's bad and that `socketToFd` is the
> replacement
> * Keep `fdSocket` forever
>
> (Just to be clear, I think the `String` based network API is bug; a
> reasonable and modern programming ecosystem shouldn't have that, and this
> should be addressed. So I'm not recommending this approach because I think
> these functions are great, but because I think this is how to transition
> away from design bugs in general.)
>
> Then, looking at the above changes, if we follow PVP, we'd look at the PVP
> decision tree, and determine what the new version should be that way. If
> (after a long time period) we'd do the "move to Network.Socket.String", it
> would tell us that a major bump is necessary.
> Of course one can also introduce a major version bump when PVP says that a
> minor bump would be sufficient if one wants to "mark an epoch change" --
> that is at the liberty of the maintainer.
>
> Discussion:
>
> I found this approach to work very well and am convinced of it.
> But I'm happy to hear other people's opinion about it to see if it's
> really as agreeable as I think.
> If yes, I'd be happy to write down these deprecation guidelines in some
> repo so that projects can refer to them and say "we follow that general
> approach" (similar to the PVP FAQ link).
>
> What do you think?
>
> Niklas
> _______________________________________________
> Haskell-Cafe mailing list
> To (un)subscribe, modify options or view archives go to:
> http://mail.haskell.org/cgi-bin/mailman/listinfo/haskell-cafe
> Only members subscribed via the mailman list are allowed to post.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.haskell.org/pipermail/haskell-cafe/attachments/20190120/ef1bdc75/attachment.html>
More information about the Haskell-Cafe
mailing list