Hi all,
I think we need to talk about deprecations.
A recent example on [Phobos][#5532] uncovered an ugly truth: many
people don't seem care about deprecation warnings.
#5532 wanted to remove the symbols scheduled for deprecation -
most noteworthy here the removal of std.c.
FYI std.c was [deprecated in September 2014][#2337].
Now, almost three years later, we have Martin's great project
tester and for the first time we can assess the impact of turning
deprecations into errors on the D ecosystem. The problem here is
that the Project-Tester doesn't even get to the state of testing
external projects, because it already fails on building
[DUB][dub] and [rdmd][rdmd].
Without being able to see the failing, external projects on the
Project-Tester I can only guess and with from looking at a few
projects (e.g. [vibe.d][vibe.d]) it doesn't seem that there's fun
ahead.
Proposals
---------
I think we should learn from the past. Here are a couple of ideas:
1) Stop making such a fuzz about having a long deprecation
period. Most people will only care about a deprecation when their
project doesn't compile anymore. A deprecation period of two
releases is more than enough for users that care. As seen even
_eight_ releases don't help! (std.c was deprecated in 2.067)
2) List deprecations in the changelog - users who care read it
(and as seen there isn't any point to cater or wait for those who
don't. I stress this point because people notoriously don't add
their breaking changes to the changelog, which I guess has led to
frustration & complains in the past and thus resulted in the
currently cautious attitude against deprecations).
3) Ship a tool like dfmt with new releases that allows easy
upgrades to new releases
4) Solve the problem automatically: let a bot that crawl _all_ D
source code on GH and let it submits PRs for trivial deprecations
(could be based on dfmt or other tools)
Especially with (3) (and optionally (4)) deprecations should
become a lot less painless and they might again gain the glance
of "awesome, we are getting rid of old, ugly stuff" instead
"please don't break anything".
[#5532]: https://github.com/dlang/phobos/pull/5532
[#2337]: https://github.com/dlang/phobos/pull/2337
[dub]: https://github.com/dlang/dub/issues/1183
[tools]: https://github.com/dlang/tools/issues/238
[vibe.d]: https://github.com/rejectedsoftware/vibe.d/issues/1811

Proposals
---------
I think we should learn from the past. Here are a couple of
ideas:
1) Stop making such a fuzz about having a long deprecation
period. Most people will only care about a deprecation when
their project doesn't compile anymore. A deprecation period of
two releases is more than enough for users that care. As seen
even _eight_ releases don't help! (std.c was deprecated in
2.067)

The only concern I have with this is that not everyone uses DMD.
LDC typically lags the development cycle, although we try to keep
up as fast as we can.
I'm no sure about the state of GDC though. I think Iain has it up
to 2.072?
This makes it a pain for library writers who want to be
compatible with all the compilers.

2) List deprecations in the changelog -

Do we not do this already?

users who care read it (and as seen there isn't any point to
cater or wait for those who don't. I stress this point because
people notoriously don't add their breaking changes to the
changelog, which I guess has led to frustration & complains in
the past and thus resulted in the currently cautious attitude
against deprecations).
3) Ship a tool like dfmt with new releases that allows easy
upgrades to new releases

Definitely!

4) Solve the problem automatically: let a bot that crawl _all_
D source code on GH and let it submits PRs for trivial
deprecations (could be based on dfmt or other tools)

Proposals
---------
I think we should learn from the past. Here are a couple of ideas:
1) Stop making such a fuzz about having a long deprecation period. Most
people will only care about a deprecation when their project doesn't compile
anymore. A deprecation period of two releases is more than enough for users
that care. As seen even _eight_ releases don't help! (std.c was deprecated
in 2.067)

The only concern I have with this is that not everyone uses DMD.
LDC typically lags the development cycle, although we try to keep up as fast
as we can.
I'm no sure about the state of GDC though. I think Iain has it up to 2.072?
This makes it a pain for library writers who want to be compatible with all
the compilers.

Can we tag compiler versions in dub? I think you have such a
construct in npm...
Found it, https://docs.npmjs.com/files/package.json#engines
Yeah - compiler, os, and cpu all seem like something that should be
made available in the dub package format.

Can we tag compiler versions in dub? I think you have such a
construct in npm...
Found it, https://docs.npmjs.com/files/package.json#engines
Yeah - compiler, os, and cpu all seem like something that
should be made available in the dub package format.

1) Stop making such a fuzz about having a long deprecation
period. Most people will only care about a deprecation when
their project doesn't compile anymore. A deprecation period of
two releases is more than enough for users that care. As seen
even _eight_ releases don't help! (std.c was deprecated in
2.067)

Long deprecation periods are really useful for situations where
you need to support a wide range of compiler frontend versions
(e.g. DMD and GDC, or whatever ancient D version is packaged on
Debian/CentOS stable). They're also very helpful for regression
testing, as you don't have to add static ifs all over just to
test if the same otherwise effectively identical code worked in
older compilers.
Once the relevant symbols are deprecated and removed from
documentation, they have almost no cost, so there is no pressure
to remove them quickly. I think overall it's more useful to leave
old stuff around for longer rather than shorter amounts of time.

Hi all,
I think we need to talk about deprecations.
A recent example on [Phobos][#5532] uncovered an ugly truth: many
people don't seem care about deprecation warnings.
#5532 wanted to remove the symbols scheduled for deprecation -
most noteworthy here the removal of std.c.
FYI std.c was [deprecated in September 2014][#2337].
Now, almost three years later, we have Martin's great project
tester and for the first time we can assess the impact of turning
deprecations into errors on the D ecosystem. The problem here is
that the Project-Tester doesn't even get to the state of testing
external projects, because it already fails on building
[DUB][dub] and [rdmd][rdmd].
Without being able to see the failing, external projects on the
Project-Tester I can only guess and with from looking at a few
projects (e.g. [vibe.d][vibe.d]) it doesn't seem that there's fun
ahead.
Proposals
---------
I think we should learn from the past. Here are a couple of ideas:
1) Stop making such a fuzz about having a long deprecation
period. Most people will only care about a deprecation when their
project doesn't compile anymore. A deprecation period of two
releases is more than enough for users that care. As seen even
_eight_ releases don't help! (std.c was deprecated in 2.067)
2) List deprecations in the changelog - users who care read it
(and as seen there isn't any point to cater or wait for those who
don't. I stress this point because people notoriously don't add
their breaking changes to the changelog, which I guess has led to
frustration & complains in the past and thus resulted in the
currently cautious attitude against deprecations).
3) Ship a tool like dfmt with new releases that allows easy
upgrades to new releases
4) Solve the problem automatically: let a bot that crawl _all_ D
source code on GH and let it submits PRs for trivial deprecations
(could be based on dfmt or other tools)
Especially with (3) (and optionally (4)) deprecations should
become a lot less painless and they might again gain the glance
of "awesome, we are getting rid of old, ugly stuff" instead
"please don't break anything".
[#5532]: https://github.com/dlang/phobos/pull/5532
[#2337]: https://github.com/dlang/phobos/pull/2337
[dub]: https://github.com/dlang/dub/issues/1183
[tools]: https://github.com/dlang/tools/issues/238
[vibe.d]: https://github.com/rejectedsoftware/vibe.d/issues/1811

Usually, these discussions go in the opposite direction, with some folks
arguing that deprecated stuff should be left around forever, which I don't
want to see happen, which is part of why I specifically avoid ever starting
discussions about how long depreactions are. What we've been doing (one year
as deprecated and documented and and one year as deprecated but undocumented
- and then removal) has largely been working.
Remember, not everyone is rebuilding all their stuff with every dmd release.
If something is working, many folks have no reason to rebuild it for months,
so they're not going to see any deprecation messages. Heck, at one point,
_Walter_ complained, because of a project of his wouldn't compile anymore,
because symbols had been removed from Phobos, and those symbols had gone
through the full two-year deprecation process, and he'd never seen the
deprecation messages. He hadn't touched that project in over two years. In
that sort of situation, it's reasonable to grab a year-old compiler, fix all
the deprecations, and then get it working with the current compiler, but if
we're deprecating and removing symbols within only a few months, you risk
having to try a whole series of compiler releases to track down and fix all
of the changes. And Walter was annoyed enough at the idea of having to use
_one_ intermediate compiler to get the missed deprecation messages. _I_ sure
wouldn't want to have to try a series of intermediate compilers to be able
to update my code.
Those who build their stuff frequently and care will see the deprecation
messages and update their stuff relatively quickly. Those who don't build
their stuff often are _far_ more likely to see the deprecation messages when
the deprecation cycle is longer and thus have fewer problems. And those who
don't care won't change their stuff until they're forced to, so why should
we care what they do?
It makes sense to list it in the changelog when something is deprecated
(that happens at least some of the time, but I don't know how frequently;
personally, I stopped bothering with the changelog for anything ages ago,
because it was too much of a pain to deal with, and we keep changing how it
even works to add anything to it), but someone who isn't going to pay
attention to a deprecation message, isn't going to pay attention to the
changelog, and in general, the deprecation message is going to reach _far_
more people than the changelog, because as soon as you compile, you see the
deprecation message, but no one actually _needs_ to look at the changelog
for anything. It's just a useful resource for those who bother reading it.
So, having stuff in the changelog is good, but it's just a way to help
inform people, not a way that you can guarantee anything about the affected
folks finding out - let alone caring enough to update their code.
Ultimately, the way that folks find out about needing to change their code
is compiling it and seeing the deprecation messages - or getting compilation
errors if they wait too long, but that's a _lot_ more of a pain to deal with
than the deprecation messages, so we really don't want to rush the removal.
The reality of the matter is that we will _always_ have to deal with users
who failed to compile their code frequently enough to catch the deprecation
messages and that we'll always have to deal with users who just won't bother
updating their code until it won't compile anymore, because the symbol was
removed. But by having longer deprecation cycles, we give folks ample time
to find out that their project needs to be updated so that we're not
screwing over users who aren't constantly upgrading. Anything we want to do
with the changelog to inform people or with tools to help people make the
transition is fine, but I see no reason to change what we've been doing with
the length of the deprecation process. Overall, it's been working just fine,
and there really haven't been many complaints about it. And those who have
complained have generally complained because a symbol was deprecated at all,
not because the length of the deprecation process was too long.
No matter what you do, you're not going to solve the problem of _someone_
not updating their code to deal with a deprecation unless you simply don't
deprecate anything - which just causes a different set of problems. And
remember that folks who are constantly dealing with the most up-to-date dmd
are unlikely to be the norm, even if most of the folks who post anything
here generally do use a recent compiler version.
- Jonathan M Davis

Ultimately, the way that folks find out about needing to change
their code is compiling it and seeing the deprecation messages
- or getting compilation errors if they wait too long, but
that's a _lot_ more of a pain to deal with than the deprecation
messages, so we really don't want to rush the removal.

Something that has worked well for me in other languages (in the
few cases I've encountered it) has been renaming deprecated
functions rather than removing them. So rather than foo, the
function becomes foo_legacy. If foo disappears, the fix is simple
- change the name to foo_legacy. I try to do that myself, because
it's not unusual to run across code I haven't used in a few
years, or code I gave to someone else a few years ago, and you
don't even remember what the function does, much less how to fix
it.

Ultimately, the way that folks find out about needing to change
their code is compiling it and seeing the deprecation messages
- or getting compilation errors if they wait too long, but
that's a _lot_ more of a pain to deal with than the deprecation
messages, so we really don't want to rush the removal.

Something that has worked well for me in other languages (in the
few cases I've encountered it) has been renaming deprecated
functions rather than removing them. So rather than foo, the
function becomes foo_legacy. If foo disappears, the fix is simple
- change the name to foo_legacy. I try to do that myself, because
it's not unusual to run across code I haven't used in a few
years, or code I gave to someone else a few years ago, and you
don't even remember what the function does, much less how to fix
it.

Anyone who wants to continue to use a deprecated function is free to copy it
into their own code and continue to use it under whatever name they wish,
but keeping something in Phobos means maintaining it, and if we're trying to
get rid of it, maintaining something permanently under a different name
simply doesn't make sense.
The unDead project exists to make it easier for folks to continue to use
some of the major stuff that was deprecated and removed (or at least ease
the transition when fixing old code that hasn't been updated in years), but
even that has already caused us some maintenance problems, because it does
depend on Phobos on some level and occasionally breaks.
So, in general, I think that it's a big mistake to keep deprecated stuff
along on a permanent or semi-permanent basis. Keeping it around for about
two years like we do now is already quite a long time in that regard. As
long as the symbol doesn't require any maintenance, then it's not a big
deal, but too often, _some_ maintenance does end up being required.
- Jonathan M Davis

So, in general, I think that it's a big mistake to keep
deprecated stuff along on a permanent or semi-permanent basis.
Keeping it around for about two years like we do now is already
quite a long time in that regard. As long as the symbol doesn't
require any maintenance, then it's not a big deal, but too
often, _some_ maintenance does end up being required.

For Phobos, changing the name would be less about keeping the
function around for a long time than about offering an easy fix
once the code does break. The current approach to deprecations is
that you get a warning that at some point the function might be
removed, then you update the compiler and you have broken code
without an obvious fix. A broken build gets your attention, but
you have a short-term fix. The total length of the deprecation
cycle wouldn't have to change.

So, in general, I think that it's a big mistake to keep
deprecated stuff along on a permanent or semi-permanent basis.
Keeping it around for about two years like we do now is
already quite a long time in that regard. As long as the
symbol doesn't require any maintenance, then it's not a big
deal, but too often, _some_ maintenance does end up being
required.

For Phobos, changing the name would be less about keeping the
function around for a long time than about offering an easy fix
once the code does break. The current approach to deprecations
is that you get a warning that at some point the function might
be removed, then you update the compiler and you have broken
code without an obvious fix. A broken build gets your
attention, but you have a short-term fix. The total length of
the deprecation cycle wouldn't have to change.

I don't get it: how is linking old and unmaintained code "fixing"
anything? Dead code is dead, if it's been two years already let
it die and fix your own, anything else can't be future-proof.

I don't get it: how is linking old and unmaintained code
"fixing" anything? Dead code is dead, if it's been two years
already let it die and fix your own, anything else can't be
future-proof.

I don't understand your comment. I'm suggesting a way to ease the
transition when deprecated functions are killed off. You appear
to be arguing that there shouldn't be a deprecation process -
just delete the functions and leave it up to the user to figure
out what to do.