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

Tracking issue for make_ascii_{upper,lower}case #27809

Closed
alexcrichton opened this issue Aug 13, 2015 · 52 comments
Closed

Tracking issue for make_ascii_{upper,lower}case #27809

alexcrichton opened this issue Aug 13, 2015 · 52 comments
Labels
B-unstable Blocker: Implemented in the nightly compiler and unstable. final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@alexcrichton
Copy link
Member

This is a tracking issue for the unstable ascii feature in the standard library. These functions have the somewhat odd naming scheme of make_* (not found elsewhere in the standard library). The utility with &mut str is also somewhat questionable as there's not a lot of support for that in the standard library.

Overall this probably just largely needs a decision.

@alexcrichton alexcrichton added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. B-unstable Blocker: Implemented in the nightly compiler and unstable. labels Aug 13, 2015
@alexcrichton
Copy link
Member Author

cc @SimonSapin

@Gankra
Copy link
Contributor

Gankra commented Aug 13, 2015

Minor correction: Rc::make_unique is another example of this naming.
Unstable of course.
On Aug 13, 2015 10:09 AM, "Alex Crichton" [email protected] wrote:

cc @SimonSapin https://github.com/SimonSapin


Reply to this email directly or view it on GitHub
#27809 (comment).

@SimonSapin
Copy link
Contributor

There should be a way to do this operation without allocating. I don’t have a strong opinion on in place with &mut str v.s. consuming and returning String (as in the now-deprecated OwnedAsciiExt trait), except that the former is sometimes slightly less convenient. (You need three statements instead of one expression.)

@Ms2ger
Copy link
Contributor

Ms2ger commented Aug 31, 2015

I don't like the &mut approach, but that might be because I'm not yet used to it.

@nox
Copy link
Contributor

nox commented Aug 31, 2015

I would prefer consuming the given String too.

@murarth
Copy link
Contributor

murarth commented Oct 20, 2015

The &mut str approach has the advantage that it can be used to convert an arbitrary subslice within a String. If the consuming String approach is adopted instead, the ability to do that would be lost.

@SimonSapin
Copy link
Contributor

You can always iterate the &mut u8 bytes in a string and map them to upper case one by one (which is what the &mut str impl does). (Although yes, doing so is unsafe and it’s nice to have a safe wrapper for it.)

@barosl
Copy link
Contributor

barosl commented Oct 27, 2015

As for naming, something like to_ascii_uppercase_in_place might be better. It clearly states the purpose of the function, and it also has a bonus point that this function will be sorted around the more canonical to_ascii_uppercase function. The drawback is that the name is much longer, but I think it won't be much a problem as the usage of this operation might be much rarer.

@barosl
Copy link
Contributor

barosl commented Oct 27, 2015

But I also think make_ makes sense if we go the route of consuming String and returning String. In that case, we would lose a safe wrapper on slices, but that's for another decision.

@SimonSapin
Copy link
Contributor

+1 for *_in_place if we keep &mut self mutating method (as opposed to self consuming methods).

@SimonSapin
Copy link
Contributor

If the libs team has the bandwidth, I’d like to nominate this for discussion. To sum up, options are:

  • Current semantics, maybe with a rename
  • Change these methods to into_ascii_*case(self) -> Self. This may need to be a separate trait.

Both are equally general: at worst if all you have is a &mut String, you can do the mem::replace dance to use methods that consume and return an owned String.

@SimonSapin
Copy link
Contributor

Also, it’s possible to build this out of tree:

for byte in &mut (bytes: Vec<u8>) {
    *byte = byte.to_ascii_lowercase()
}

for byte in unsafe { (s: String).as_mut_vec() } {
    *byte = byte.to_ascii_lowercase()
}

… though it would be nice to encapsulate the unsafety in the String case.

@alexcrichton
Copy link
Member Author

🔔 This issue is now entering its cycle final comment period to be deprecated in 1.8 🔔

@alexcrichton alexcrichton added final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. and removed I-nominated labels Jan 29, 2016
@SimonSapin
Copy link
Contributor

What’s the rationale for not stabilizing any of the two proposed designs?

@alexcrichton
Copy link
Member Author

Ah yes, to clarify we concluded that this stuck out enough and could be easily enough built on crates.io (e.g. externally) that it wasn't necessary to stabilize in libstd at this time.

@SimonSapin
Copy link
Contributor

could be easily enough built on crates.io

The same can be said of the entire std::ascii module (and other things in std). I don’t understand having some of the related functionality in, but leave these couple methods out (which for the str case require unsafe.)

@alexcrichton
Copy link
Member Author

Sure, but that part's already stable. The make_ convention sticks out (at least to me) and I would prefer to not stabilize this.

@SimonSapin
Copy link
Contributor

I’m not a big fan of make_* either.

What about .into_ascii_lowercase(self) -> Self?

@alexcrichton
Copy link
Member Author

If those methods could be merged into the AsciiExt trait itself I'd be more comfortable with that, but previously they were a separate trait.

@SimonSapin
Copy link
Contributor

Alright. IIRC we had a separate trait because dynamically-sized types and methods taking self by value don’t play nice with each other. But it turns out Iterator already does this: the trick is having a default implementation with a where Self: Sized bound.

See PR #31335.

@ollie27
Copy link
Member

ollie27 commented Feb 1, 2016

What do into_ascii_{upper,lower}case offer that make_ascii_{upper,lower}case don't?

Both are equally general: at worst if all you have is a &mut String, you can do the mem::replace dance to use methods that consume and return an owned String.

Is that true? If so how do you handle &mut str and &mut [u8] without two more implementations of AsciiExt for them?

If naming is still an issue with make_* how about just uppercase_ascii() and lowercase_ascii()? "uppercase" and "lowercase" are also verbs so this fits the current naming scheme.

SimonSapin added a commit to SimonSapin/rust that referenced this issue Mar 6, 2016
Implementing `AsciiExt` for `String` and `Vec<u8>` caused a regression:
rust-lang#32074
and the `where Self: Sized` hack to have the `into_` methods in that trait
(which is also implemented for DST `str` and `[u8]`) was rather clunky.

CC rust-lang#27809
@alexcrichton alexcrichton added final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. and removed I-nominated labels Mar 11, 2016
@aturon
Copy link
Member

aturon commented Mar 11, 2016

This API is going back into final comment period.

We were previously unable to reach consensus on a good convention for make_ascii_*case, and tried to make some progress by going forward with into_* variants in the meantime. However:

We've always been somewhat ambivalent about ASCII support in std, and have scaled it back over time, but at this point, we're reasonably committed to some core functionality, and we'd like to settle these remaining APIs.

As such, we're going to:

  • Revert the change with into_ variants as well as the introduction of additional impls to support it.
  • Try FCP again for determining a convention around the make_ variants.

We had a lengthy discussion in the libs team last time about conventions. The key problem is that mutating methods are usually reasonably clear verb forms (like push), and it feels unfortunate to introduce a prefix like make_. We discussion variations around _in_place but found this to be extremely verbose. And as several people have pointed out on thread, using conversion prefixes here doesn't feel great either -- it's a mutation, not a conversion.

Perhaps we can look at some other languages for inspiration on this convention. But let's try to get it settled this cycle.

@SimonSapin
Copy link
Contributor

Revert the change with into_ variants as well as the introduction of additional impls to support it.

Is #32076 what you have in mind here?

alexcrichton added a commit to alexcrichton/rust that referenced this issue Mar 17, 2016
The addition of these methods in rust-lang#31335 required adding impls of the trait for
the `String` and `Vec<T>` types. This unfortunately caused a regression (rust-lang#32074)
in type inference for using these methods which the libs team has decided to not
push forward with. These methods were stabilized in rust-lang#32020 which was intended to
get backported to beta, but the backport hasn't happened just yet. This commit
reverts both the addition and stabilization of these methods.

One proposed method of handling this, in rust-lang#32076, was to move the methods to an
extra trait to avoid conflicts with type inference. After some discussion,
however, the libs team concluded that we probably want to reevaluate what we're
doing here, so discussion will continue on the tracking issue, rust-lang#27809.
bors added a commit that referenced this issue Mar 19, 2016
std: Revert addition of `into_ascii_*` methods

The addition of these methods in #31335 required adding impls of the trait for
the `String` and `Vec<T>` types. This unfortunately caused a regression (#32074)
in type inference for using these methods which the libs team has decided to not
push forward with. These methods were stabilized in #32020 which was intended to
get backported to beta, but the backport hasn't happened just yet. This commit
reverts both the addition and stabilization of these methods.

One proposed method of handling this, in #32076, was to move the methods to an
extra trait to avoid conflicts with type inference. After some discussion,
however, the libs team concluded that we probably want to reevaluate what we're
doing here, so discussion will continue on the tracking issue, #27809.

Closes #32074
@aturon
Copy link
Member

aturon commented Mar 21, 2016

@SimonSapin I think you already saw, but for the record, #32314 is what we had in mind.

alexcrichton added a commit to alexcrichton/rust that referenced this issue Mar 24, 2016
The addition of these methods in rust-lang#31335 required adding impls of the trait for
the `String` and `Vec<T>` types. This unfortunately caused a regression (rust-lang#32074)
in type inference for using these methods which the libs team has decided to not
push forward with. These methods were stabilized in rust-lang#32020 which was intended to
get backported to beta, but the backport hasn't happened just yet. This commit
reverts both the addition and stabilization of these methods.

One proposed method of handling this, in rust-lang#32076, was to move the methods to an
extra trait to avoid conflicts with type inference. After some discussion,
however, the libs team concluded that we probably want to reevaluate what we're
doing here, so discussion will continue on the tracking issue, rust-lang#27809.

Conflicts:
	src/libstd/ascii.rs
@aturon
Copy link
Member

aturon commented Apr 5, 2016

Revisiting the naming concerns, I continue to feel like the sticking point is needing a verb, which we can get either through make as today, or by treating e.g. uppercase itself as a verb (as in uppercase_ascii or ascii_uppercase). I continue to prefer the latter, and agree with @ollie27 that uppercase_ascii is the smoothest name.

@SimonSapin
Copy link
Contributor

I agree that all nouns can be verbed, but since uppercase-as-a-verb is spelled the same as uppercase-as-a-noun I think that uppercase_ascii doesn’t give enough information about how it differs from to_uppercase_ascii.

@sfackler
Copy link
Member

sfackler commented Apr 6, 2016

I agree with Simon's concerns about ambiguity. How about uppercasify_ascii? :D

But in all seriousness, make_uppercase_ascii seems like the least-bad approach I've seen.

@aturon
Copy link
Member

aturon commented Apr 6, 2016

@SimonSapin Ah, that's an excellent point.

Maybe the right thing to do is to stick with make_ as @sfackler is saying -- and perhaps there's a latent convention here, for cases where the word for the method is not usually used as a verb, but rather an adjective (i.e., when it's describing a property rather than an action).

@alexcrichton
Copy link
Member Author

The libs team discussed this issue during triage yesterday and the conclusion was to stabilize under the names make_*. There didn't seem to be any better alternative and we concluded that this is perhaps a convention to start.

alexcrichton added a commit to alexcrichton/rust that referenced this issue Apr 11, 2016
This commit applies all stabilizations, renamings, and deprecations that the
library team has decided on for the upcoming 1.9 release. All tracking issues
have gone through a cycle-long "final comment period" and the specific APIs
stabilized/deprecated are:

Stable

* `std::panic`
* `std::panic::catch_unwind` (renamed from `recover`)
* `std::panic::resume_unwind` (renamed from `propagate`)
* `std::panic::AssertUnwindSafe` (renamed from `AssertRecoverSafe`)
* `std::panic::UnwindSafe` (renamed from `RecoverSafe`)
* `str::is_char_boundary`
* `<*const T>::as_ref`
* `<*mut T>::as_ref`
* `<*mut T>::as_mut`
* `AsciiExt::make_ascii_uppercase`
* `AsciiExt::make_ascii_lowercase`
* `char::decode_utf16`
* `char::DecodeUtf16`
* `char::DecodeUtf16Error`
* `char::DecodeUtf16Error::unpaired_surrogate`
* `BTreeSet::take`
* `BTreeSet::replace`
* `BTreeSet::get`
* `HashSet::take`
* `HashSet::replace`
* `HashSet::get`
* `OsString::with_capacity`
* `OsString::clear`
* `OsString::capacity`
* `OsString::reserve`
* `OsString::reserve_exact`
* `OsStr::is_empty`
* `OsStr::len`
* `std::os::unix::thread`
* `RawPthread`
* `JoinHandleExt`
* `JoinHandleExt::as_pthread_t`
* `JoinHandleExt::into_pthread_t`
* `HashSet::hasher`
* `HashMap::hasher`
* `CommandExt::exec`
* `File::try_clone`
* `SocketAddr::set_ip`
* `SocketAddr::set_port`
* `SocketAddrV4::set_ip`
* `SocketAddrV4::set_port`
* `SocketAddrV6::set_ip`
* `SocketAddrV6::set_port`
* `SocketAddrV6::set_flowinfo`
* `SocketAddrV6::set_scope_id`
* `<[T]>::copy_from_slice`
* `ptr::read_volatile`
* `ptr::write_volatile`
* The `#[deprecated]` attribute
* `OpenOptions::create_new`

Deprecated

* `std::raw::Slice` - use raw parts of `slice` module instead
* `std::raw::Repr` - use raw parts of `slice` module instead
* `str::char_range_at` - use slicing plus `chars()` plus `len_utf8`
* `str::char_range_at_reverse` - use slicing plus `chars().rev()` plus `len_utf8`
* `str::char_at` - use slicing plus `chars()`
* `str::char_at_reverse` - use slicing plus `chars().rev()`
* `str::slice_shift_char` - use `chars()` plus `Chars::as_str`
* `CommandExt::session_leader` - use `before_exec` instead.

Closes rust-lang#27719
cc rust-lang#27751 (deprecating the `Slice` bits)
Closes rust-lang#27754
Closes rust-lang#27780
Closes rust-lang#27809
Closes rust-lang#27811
Closes rust-lang#27830
Closes rust-lang#28050
Closes rust-lang#29453
Closes rust-lang#29791
Closes rust-lang#29935
Closes rust-lang#30014
Closes rust-lang#30752
Closes rust-lang#31262
cc rust-lang#31398 (still need to deal with `before_exec`)
Closes rust-lang#31405
Closes rust-lang#31572
Closes rust-lang#31755
Closes rust-lang#31756
bors added a commit that referenced this issue Apr 12, 2016
std: Stabilize APIs for the 1.9 release

This commit applies all stabilizations, renamings, and deprecations that the
library team has decided on for the upcoming 1.9 release. All tracking issues
have gone through a cycle-long "final comment period" and the specific APIs
stabilized/deprecated are:

Stable

* `std::panic`
* `std::panic::catch_unwind` (renamed from `recover`)
* `std::panic::resume_unwind` (renamed from `propagate`)
* `std::panic::AssertUnwindSafe` (renamed from `AssertRecoverSafe`)
* `std::panic::UnwindSafe` (renamed from `RecoverSafe`)
* `str::is_char_boundary`
* `<*const T>::as_ref`
* `<*mut T>::as_ref`
* `<*mut T>::as_mut`
* `AsciiExt::make_ascii_uppercase`
* `AsciiExt::make_ascii_lowercase`
* `char::decode_utf16`
* `char::DecodeUtf16`
* `char::DecodeUtf16Error`
* `char::DecodeUtf16Error::unpaired_surrogate`
* `BTreeSet::take`
* `BTreeSet::replace`
* `BTreeSet::get`
* `HashSet::take`
* `HashSet::replace`
* `HashSet::get`
* `OsString::with_capacity`
* `OsString::clear`
* `OsString::capacity`
* `OsString::reserve`
* `OsString::reserve_exact`
* `OsStr::is_empty`
* `OsStr::len`
* `std::os::unix::thread`
* `RawPthread`
* `JoinHandleExt`
* `JoinHandleExt::as_pthread_t`
* `JoinHandleExt::into_pthread_t`
* `HashSet::hasher`
* `HashMap::hasher`
* `CommandExt::exec`
* `File::try_clone`
* `SocketAddr::set_ip`
* `SocketAddr::set_port`
* `SocketAddrV4::set_ip`
* `SocketAddrV4::set_port`
* `SocketAddrV6::set_ip`
* `SocketAddrV6::set_port`
* `SocketAddrV6::set_flowinfo`
* `SocketAddrV6::set_scope_id`
* `<[T]>::copy_from_slice`
* `ptr::read_volatile`
* `ptr::write_volatile`
* The `#[deprecated]` attribute
* `OpenOptions::create_new`

Deprecated

* `std::raw::Slice` - use raw parts of `slice` module instead
* `std::raw::Repr` - use raw parts of `slice` module instead
* `str::char_range_at` - use slicing plus `chars()` plus `len_utf8`
* `str::char_range_at_reverse` - use slicing plus `chars().rev()` plus `len_utf8`
* `str::char_at` - use slicing plus `chars()`
* `str::char_at_reverse` - use slicing plus `chars().rev()`
* `str::slice_shift_char` - use `chars()` plus `Chars::as_str`
* `CommandExt::session_leader` - use `before_exec` instead.

Closes #27719
cc #27751 (deprecating the `Slice` bits)
Closes #27754
Closes #27780
Closes #27809
Closes #27811
Closes #27830
Closes #28050
Closes #29453
Closes #29791
Closes #29935
Closes #30014
Closes #30752
Closes #31262
cc #31398 (still need to deal with `before_exec`)
Closes #31405
Closes #31572
Closes #31755
Closes #31756
alexcrichton added a commit to alexcrichton/rust that referenced this issue Apr 12, 2016
This commit applies all stabilizations, renamings, and deprecations that the
library team has decided on for the upcoming 1.9 release. All tracking issues
have gone through a cycle-long "final comment period" and the specific APIs
stabilized/deprecated are:

Stable

* `std::panic`
* `std::panic::catch_unwind` (renamed from `recover`)
* `std::panic::resume_unwind` (renamed from `propagate`)
* `std::panic::AssertUnwindSafe` (renamed from `AssertRecoverSafe`)
* `std::panic::UnwindSafe` (renamed from `RecoverSafe`)
* `str::is_char_boundary`
* `<*const T>::as_ref`
* `<*mut T>::as_ref`
* `<*mut T>::as_mut`
* `AsciiExt::make_ascii_uppercase`
* `AsciiExt::make_ascii_lowercase`
* `char::decode_utf16`
* `char::DecodeUtf16`
* `char::DecodeUtf16Error`
* `char::DecodeUtf16Error::unpaired_surrogate`
* `BTreeSet::take`
* `BTreeSet::replace`
* `BTreeSet::get`
* `HashSet::take`
* `HashSet::replace`
* `HashSet::get`
* `OsString::with_capacity`
* `OsString::clear`
* `OsString::capacity`
* `OsString::reserve`
* `OsString::reserve_exact`
* `OsStr::is_empty`
* `OsStr::len`
* `std::os::unix::thread`
* `RawPthread`
* `JoinHandleExt`
* `JoinHandleExt::as_pthread_t`
* `JoinHandleExt::into_pthread_t`
* `HashSet::hasher`
* `HashMap::hasher`
* `CommandExt::exec`
* `File::try_clone`
* `SocketAddr::set_ip`
* `SocketAddr::set_port`
* `SocketAddrV4::set_ip`
* `SocketAddrV4::set_port`
* `SocketAddrV6::set_ip`
* `SocketAddrV6::set_port`
* `SocketAddrV6::set_flowinfo`
* `SocketAddrV6::set_scope_id`
* `<[T]>::copy_from_slice`
* `ptr::read_volatile`
* `ptr::write_volatile`
* The `#[deprecated]` attribute
* `OpenOptions::create_new`

Deprecated

* `std::raw::Slice` - use raw parts of `slice` module instead
* `std::raw::Repr` - use raw parts of `slice` module instead
* `str::char_range_at` - use slicing plus `chars()` plus `len_utf8`
* `str::char_range_at_reverse` - use slicing plus `chars().rev()` plus `len_utf8`
* `str::char_at` - use slicing plus `chars()`
* `str::char_at_reverse` - use slicing plus `chars().rev()`
* `str::slice_shift_char` - use `chars()` plus `Chars::as_str`
* `CommandExt::session_leader` - use `before_exec` instead.

Closes rust-lang#27719
cc rust-lang#27751 (deprecating the `Slice` bits)
Closes rust-lang#27754
Closes rust-lang#27780
Closes rust-lang#27809
Closes rust-lang#27811
Closes rust-lang#27830
Closes rust-lang#28050
Closes rust-lang#29453
Closes rust-lang#29791
Closes rust-lang#29935
Closes rust-lang#30014
Closes rust-lang#30752
Closes rust-lang#31262
cc rust-lang#31398 (still need to deal with `before_exec`)
Closes rust-lang#31405
Closes rust-lang#31572
Closes rust-lang#31755
Closes rust-lang#31756
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
B-unstable Blocker: Implemented in the nightly compiler and unstable. final-comment-period In the final comment period and will be merged soon unless new substantive objections are raised. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests