Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deprecate stdlib modules dedicated to numeric constants and move those constants to associated consts #2700

Open
wants to merge 3 commits into
base: master
from

Conversation

Projects
None yet
10 participants
@bstrie
Copy link
Contributor

commented May 13, 2019

Add the relevant associated constants to the numeric types in the standard library, and consider a timeline for the deprecation of the corresponding (and originally intended to be temporary) primitive numeric modules and associated functions.

Rendered

@SimonSapin

This comment has been minimized.

Copy link
Contributor

commented May 13, 2019

Thanks @bstrie for extensively documenting the intent that we collectively had all along. I don’t expect this to be controversial, but this is what the FCP period is for:

@rfcbot fcp merge

@rfcbot

This comment has been minimized.

Copy link

commented May 13, 2019

Team member @SimonSapin has proposed to merge this. The next step is review by the rest of the tagged team members:

Concerns:

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@Ekleog

This comment has been minimized.

Copy link

commented May 13, 2019

Does it really make sense to have f64::PI as an associated const? While I totally agree for min, max and the like (that really define the type), things like PI, LN_2, LN_10, FRAC_2_SQRT_PI etc. are less obvious to me.

@Centril
Copy link
Contributor

left a comment

Some thoughts...

Also, I think it's premature to jump to PFCP so quickly when no discussion has been had at all.


2. Documentation. On the front page of the [standard library API docs](https://doc.rust-lang.org/std/index.html), 14 of the 56 modules in the standard library (25%) are the aforementioned numeric modules whose only purpose is to namespace these constants. This number will continue to rise as new numeric primitives are added to Rust, as already seen with `i128` and `u128`. Although deprecated modules cannot be easily removed from std, they can be removed from the documentation, making the stdlib API docs less cluttered and easier to navigate.

3. Beginner ease. For a beginner, finding two identical ways to achieve something immediately raises the question of "why", to which the answer here is ultimately uninteresting (and even then, the question of "which one to use" remains unanswered; neither current approach is idiomatic). As noted, deprecated items can be removed from the documentation, thereby decreasing the likelihood of head-scratching and incredulous sidelong glances from people new to Rust.

This comment has been minimized.

Copy link
@Centril

Centril May 13, 2019

Contributor

I think the motivation doesn't sufficiently justify why the current constants are harmful. Meanwhile, I think there's plenty of harm caused by deprecation of constants that on initial inspection seem like they would be widely used. At minimum, I think there should be a crater run to see how much churn there would be.

# Drawbacks
[drawbacks]: #drawbacks

Deprecation warnings are annoying.

This comment has been minimized.

Copy link
@Centril

Centril May 13, 2019

Contributor

There's an additional technical drawback to associated constants:

  • You are forged to reference them through the type; I agree with @Ekleog that it's less clear that we want to force this.
    • This technical limitation may be lifted by the language in the future, but for now it exists.
@liigo

This comment has been minimized.

Copy link
Contributor

commented May 14, 2019

Replace each item with an associated const value on the appropriate type

a good rfc requires an explicite list

@SimonSapin

This comment has been minimized.

Copy link
Contributor

commented May 14, 2019

I think it's premature to jump to PFCP so quickly when no discussion has been had at all.

I took the links in the motivation section as showing there had been ample discussion elsewhere already. That said, let’s register this as a concern to give more time:

@rfcbot concern more discussion before FCP start

@bstrie

This comment has been minimized.

Copy link
Contributor Author

commented May 14, 2019

Does it really make sense to have f64::PI as an associated const? While I totally agree for min, max and the like (that really define the type), things like PI, LN_2, LN_10, FRAC_2_SQRT_PI etc. are less obvious to me.

@Ekleog , I have added language to the section on alternatives further elaborating on the rationale here.

Updates to the text regarding other concerns are forthcoming, as my busy schedule playing Minecraft with my girlfriend permits.

@newpavlov

This comment has been minimized.

Copy link

commented May 14, 2019

While I support deprecation of module-level constants in favor of associated constants (also I think we should add std::time::UNIX_EPOCH to the list), I think we should first allow import of associated constants or otherwise it may be an ergonomic hit, e.g. use std::time::SystemTime::UNIX_EPOCH; will not work today.

@sfackler

This comment has been minimized.

Copy link
Member

commented May 15, 2019

@newpavlov

This comment has been minimized.

Copy link

commented May 15, 2019

Yes, I know. My point is about marking std::time::UNIX_EPOCH as deprecated and allowing associated constants import before module-level constants deprecation.

@bstrie

This comment has been minimized.

Copy link
Contributor Author

commented May 15, 2019

Though note that the inability to bring associated items into scope via use doesn't preclude aliasing them in other ways. If someone's using un-prefixed UNIX_EPOCH in their code, then that would require them to already have a line like:

use std::time::UNIX_EPOCH;

...which, if std::time::UNIX_EPOCH were deprecated in favor of the associated const std::time::SystemTime::UNIX_EPOCH, then the one and only change that would need to be made to any module with the aforementioned import would be to change the use line to:

use std::time::SystemTime;
const UNIX_EPOCH: SystemTime = SystemTime::UNIX_EPOCH;

Furthermore, because all primitive types are already in the prelude, doing the same transition for the numeric types as proposed in this RFC would be even easier, requiring only a line such as:

use std::i32::MAX;

...to become:

const MAX: i32 = i32::MAX;

Finally, whereas I can totally see someone wanting to use UNIX_EPOCH as an un-prefixed identifier, I think it is much less likely that someone would import constants like MAX or MIN to use un-prefixed, precisely because there are no less than twelve different maxes and mins in the stdlib, and the types are very useful for mental disambiguation (in addition, the types are extremely concise, unlike SystemTime).

So while it would be nice to be able to import associated consts, (and associated items in general; has anyone ever submitted an RFC for this?) I don't necessarily think it will be such a hindrance in this case if we chose not to wait until that were possible.

@Centril

This comment has been minimized.

Copy link
Contributor

commented May 15, 2019

Finally, whereas I can totally see someone wanting to use UNIX_EPOCH as an un-prefixed identifier, I think it is much less likely that someone would import constants like MAX or MIN to use un-prefixed, precisely because there are no less than twelve different maxes and mins in the stdlib, and the types are very useful for mental disambiguation (in addition, the types are extremely concise, unlike SystemTime).

@bstrie Sure, it seems clear that u8::MAX is more understandable than MAX. For other constants the matter seems different. I would suggest cutting back to just MAX & MIN.

@bstrie

This comment has been minimized.

Copy link
Contributor Author

commented May 15, 2019

@Centril, note that all the integral modules contain only MAX and MIN, so reducing the RFC's scope to those constants would be equivalent to the alternative discussed in the RFC where these changes would be made only to the integral modules and not for the float modules. (Although personally I find the visual difference between f32::PI and f64::PI to be just as important, to say nothing of the hypothetical f16::PI, f80::PI, and f128::PI that we may have someday).

I'll summarize this discussion and add it to the Drawbacks section.

# Rationale and alternatives
[rationale-and-alternatives]: #rationale-and-alternatives

There is an alternative design where the proposed changes are only made to the integral numeric modules in the standard library, leaving alone `f32` and `f64`. Unlike the integral modules, these modules do not contain both constants and redundant associated items. In addition, these two modules contain submodules named `consts`, which contain constants of a more mathematical bent (the sort of thing other languages might put in a `std::math` module). This RFC argues for giving the float modules the same treatment as the integral modules, both since associated consts are "obviously the right thing" in this case and because we do not consider the mathematical/machine constant distinction to be particularly useful or intuitive. In particular, this distinction is not consistent with the existing set of associated functions implemented on `f32` and `f64`, which consist of a mix of both functions concerned with mathematical operations (e.g. `f32::atanh`) and functions concerned with machine representation (e.g. `f32::is_sign_negative`). As noted, if a `math` module existed in Rust's stdlib this would be the natural place to put them, however, such a module does not exist; further, any consideration of this hyptothetical module would, for the sake of consistency, want to also adopt not only the aforementioned mathematical associated functions that currently exist on `f32` and `f64`, but would also want to adopt the integral mathematical functions such as `i32::pow`--all while in some way recreating the module-level distinction between the operations as they exist on the various different numeric types. This is all to say that such a `std::math` module is out of scope for this proposal, in addition to lacking the technical motivation of this proposal. Ultimately, however, leaving `f32` and `f64` along and making the proposed changes only to the integral types would still be considered a success by this RFC.

This comment has been minimized.

Copy link
@Centril

Centril May 16, 2019

Contributor

(please use linebreaks or semantic linefeeds...)

This RFC argues for giving the float modules the same treatment as the integral modules, both since associated consts are "obviously the right thing" in this case [...]

Please make an effort beyond "obviously the right thing". It's often not obvious, even if you think it is.

@scottmcm

This comment has been minimized.

Copy link
Member

commented May 17, 2019

Yes please! I always just type u32::MAX then get sad when the compiler reminds me it doesn't work...

@avl

This comment has been minimized.

Copy link

commented May 21, 2019

Also, f32::PI would be very nice! The chance that someone ever types that intending something other than the mathematical constant Pi seems infinitesimal. I think Pi and other mathematical constants are fundamental enough that they don't deserve being shuffled out of sight to a 'constants' namespace.

@avl

This comment has been minimized.

Copy link

commented May 21, 2019

Couldn't deprecation wait til next edition (2021?). But introduce the new names now?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.