Skip to content

Comments

Turn enforce into an eponymous template + undocument enforceEx#6086

Merged
dlang-bot merged 3 commits intodlang:masterfrom
wilzbach:enforceEx
Feb 6, 2018
Merged

Turn enforce into an eponymous template + undocument enforceEx#6086
dlang-bot merged 3 commits intodlang:masterfrom
wilzbach:enforceEx

Conversation

@wilzbach
Copy link
Contributor

Follow-up to #5234 and #6080.

tl;dr summary

However, if enforce can't fully replace enforceEx, then it needs to stick around for at least one more release so that we can have a release where enforce can fully replace enforceEx. That way, someone can build their code with both the latest release and master without getting a bunch of deprecation messages. And clearly, from how enforceEx is being used in Phobos, enforce needs to be improved first. So, please create a PR to improve enforce, and then we can deprecate enforceEx after the improved enforce has been put out in a release.

I already added the warning in the documentation and removed enforceEx from the bookmark summary at the top.

@dlang-bot
Copy link
Contributor

Thanks for your pull request, @wilzbach!

Bugzilla references

Your PR doesn't reference any Bugzilla issue.

If your PR contains non-trivial changes, please reference a Bugzilla issue or create a manual changelog.

std/json.d Outdated
struct JSONValue
{
import std.exception : enforceEx, enforce;
import std.exception : enforce, enforce;
Copy link
Member

Choose a reason for hiding this comment

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

Just one should be enough.

@CyberShadow
Copy link
Member

std/exception.d Outdated
import std.conv : ConvException;
alias enf = enforce!ConvException;
assertNotThrown(enf(true));
assertThrown(enf(false, "blah"));
Copy link
Member

Choose a reason for hiding this comment

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

How about assertThrown!ConvException ?

std/exception.d Outdated
@safe unittest
{
import std.conv : ConvException;
alias enf = enforce!ConvException;
Copy link
Member

Choose a reason for hiding this comment

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

alias convEnforce = enforce!ConvException;

std/exception.d Outdated
// @@@DEPRECATED_2019-07@@@
/++
$(RED Deprecated. Please use $(LREF enforce) instead. This function will be removed
in July 2019.)
Copy link
Member

Choose a reason for hiding this comment

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

Hmm, are we still doing deprecations by dates? I thought there was consensus that deprecating by D versions is overall better.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Ehm our deprecation process definitely needs some guidelines because I wasn't aware of this.
I would prefer D versions too.

Copy link
Member

Choose a reason for hiding this comment

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

By version would be nice. @MartinNowak what do you think?

Copy link
Member

Choose a reason for hiding this comment

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

I've been using month/year, because historically, our releases haven't been consistent enough to use any kind of release numbers when deprecating things. I can easily pick a month a year from now and put that in the message. Historically, that hasn't worked at all with versions. Martin has improved that situation considerably, but they're still not completely consistent. And as a user, it's far easier to look at a date and see about when the symbol is going away than it is to try and figure out when on earth a specific version is going to be released. If the date is a year from now, then it's clear that I have a year. If it's a version number, then it's not at all clear how long I have. I'd have to examine what the release schedule has been and estimate about when the symbol is going away.

Copy link
Member

Choose a reason for hiding this comment

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

However, the date in this case should be more like 2019-02, since it's supposed to be about a year from now (after which, it will be undocumented and have a non-ddoc comment indicating a date about a year from then for when it will be fully removed).

Copy link
Member

@CyberShadow CyberShadow Jan 28, 2018

Choose a reason for hiding this comment

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

And as a user, it's far easier to look at a date and see about when the symbol is going away than it is to try and figure out when on earth a specific version is going to be released.

Err, sorry, I think that's a bit removed from reality. Essentially that's only true (and useful) if you're always using the latest version of DMD, and use nothing but the latest version of DMD. While this is mostly true for us who contribute to DMD and core D components frequently, it likely isn't for most D users.

Using dates is less useful for answering these questions:

  • Upgrading to which version of DMD will break my code?
  • Downgrading to which version of DMD will get my code to build again?
  • In which version of LDC or GDC will this code stop working?
  • Will upgrading to the next release of my Linux distribution mean I'll have fix my code?

Essentially, dates become a lot less useful in any situation where the user is not using the latest version of Phobos, whether that's thanks to a rolling release Linux distro, using D-apt, or religious frequent manual updates. In all other cases (Windows, tarballs, dlang.org distro packages, install script, builds from git), I believe version numbers would be more useful and easier to look up.

Copy link
Member

Choose a reason for hiding this comment

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

Well, technically, it keeps working for about a year after it's removed from the docs, so I'd be inclined to argue that the imprecision with regards to how it matches up with ldc releases or whatnot doesn't matter much, and the site always has the latest docs only, but if we get to the point that we have the docs for previous releases like we've discussed before, then dates definitely become worse.

So, fine, if you guys really want version numbers, then we go with version numbers, but it's going to make the actual time frame of deprecations more inconsistent, since it'll be harder to target a year ahead, but while they've usually been in the ballpark of where they should be, they don't always get moved along quite when they should anyway.

In that case, let's change it to say

// @@@DEPRECATED_2.084@@@

and

This function will be removed in 2.084.

and I'll have to create some PRs to fix the existing deprecations.

Copy link
Member

Choose a reason for hiding this comment

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

since it'll be harder to target a year ahead,

I don't think we need to try to target deprecations using calendar time, just use "N major versions ahead" instead of "N months ahead".

but while they've usually been in the ballpark of where they should be, they don't always get moved along quite when they should anyway.

Yeah, one advantage of using dates is that when we don't honor our own deprecation deadlines, it's easier to excuse that for dates than version numbers.

Copy link
Member

Choose a reason for hiding this comment

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

And as a user, it's far easier to look at a date and see about when the symbol is going away than it is to try and figure out when on earth a specific version is going to be released.

Thinking more on this, I think I understand better what you meant here.

If you are maintaining an open-source project (especially a library), a deprecation date (on a symbol used in your code) will tell you what's the latest point in time that the deprecation is guaranteed to still work for everyone, everywhere, so you don't need to really worry about it until then. Anything past that date, though, and there appears the chance that someone, somewhere is going to start having trouble building your software.

So... I'd say version numbers are more useful if you're writing code for yourself or your company, and deprecation dates are more useful if you're writing open-source software.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In that case, let's change it to say

OK. Changed. We should probably add a short documentation in the wiki or as a markdown document this repo about the deprecation process.

@wilzbach
Copy link
Contributor Author

wilzbach commented Jan 28, 2018

Existing usage: https://github.com/search?q=enforceEx+language%3Ad&type=Code&utf8=%E2%9C%93

Thanks! Though this PR doesn't depend on a decision on whether is worthwhile to deprecate this as it's just the preparation to make enforce equal to enforceEx.
Also if the potential breakage is a real concern here, we have multiple options here that improve the status quo without any cost of breakage:

  • just mark enforceEx as deprecated in the docs
  • just remove enforceEx from the docs
  • trigger a deprecation warning, but never follow through with the removal (preferred)

@CyberShadow
Copy link
Member

CyberShadow commented Jan 28, 2018

This case doesn't seem too different from the others in which we've deprecated then removed Phobos symbols, so I see no reason to not stick to the current policy. It's also a super-easy fix, and it's going to be backwards-compatible through a few releases.


T enforce(T)(T value, lazy const(char)[] msg = null,
string file = __FILE__, size_t line = __LINE__)
if (is(typeof({ if (!value) {} })))
Copy link
Member

Choose a reason for hiding this comment

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

We have ifTestable, though I have to say this is nicer.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, ifTestable is one of those one-liners that cost a lot more than they are worth it:

enum ifTestable(T, alias pred = a => a) = __traits(compiles, { if (pred(T.init)) {} });

Interestingly it crept into Phobos with other one-liners: #3395

std/exception.d Outdated
// @@@DEPRECATED_2019-07@@@
/++
$(RED Deprecated. Please use $(LREF enforce) instead. This function will be removed
in July 2019.)
Copy link
Member

Choose a reason for hiding this comment

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

By version would be nice. @MartinNowak what do you think?

enforce can't fully replace enforceEx, hence it needs to stick around for at least one more release so that we can have a release where enforce can fully replace enforceEx. That way, someone can build their code with both the latest release and master without getting a bunch of deprecation messages.
@wilzbach
Copy link
Contributor Author

wilzbach commented Feb 2, 2018

(added a changelog entry)

Anything else needed for this PR? It uses a version for the deprecation now and once @JackStouffer's deprecation DIP has been approved we will have to update all the existing deprecations anyways.

It would be great to get this in before 2.079, s.t. enforce is fully capable of replacing enforceEx and we can start the deprecation cycle with 2.080.

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants