Description
Slices - Why the messaging is wrong / confusing and needs to be clarified
In my experience teaching newbies about rust (mostly on the community discord and in person) there has always been a speed-bump in the learning process, and that's slices.
The way we talk about slices is confusing and ambiguous - we first (IMO incorrectly) teach that &[T]
is called a slice, but then later when we introduce unsized types and reveal that actually [T]
is a slice, but also continue to call &[T]
a slice in extensive documentation.
Things become even more confusing when some documentation also uses the terms "shared slice" and "mutable slice", or defines a slice as a "view into a contiguous sequence" (which IMO conveys a sense of indirection?). Things that add to the confusion:
- Owned slices such as
Box<[T]>
and even the rareBox<str>
[T]
/str
as a generic parameter (why is or isn't it&[T]
/&str
?).- How does
[T]
relate to[T; N]
ie. (if&[T]
is a slice then is&[T; N]
an array?)
Due to the langage we use to teach, rust beginners must learn and then unlearn the terminology several times before they arrive at the correct nuances of how slices work and in what contexts we use what terms. I believe this should change.
While I believe using "slice" to mean &[T]
informally is acceptable, I think having this language present in documentation does the community a disservice and makes everything more difficult than it needs to be.
How we could fix it
We need to focus on accurately teaching the language, and using the terminology consistently:
[T]
is a slice - an unsized type that needs to be behind some form of pointer / reference / indirection&[T]
is a slice reference / slice ref - a fat pointer which includes the length of the slice.&mut [T]
should be called a mutable slice ref&str
- what should we call this? a "string ref" / "str ref" maybe? currently it is often called a "string slice" but that is inaccurate...
These basics should not be conflated - especially in documentation. Make it clear which ones are slices and which ones are references. (yes, I know that it's more words to type out)- Introducing the terms "shared" and "unique", while accurate, are confusing since they are not used anywhere else
- Calling
&[T]
a "shared slice" is confusing since it implies that the type is a kind of slice, when in fact it is a reference to a slice. - The documentation needs to be overhauled in several places to make this messaging accurate and consistent.
- I think methods such as
.as_slice()
and.as_mut_slice()
, while technically incorrect (they return slice references) should be fine to stay since it's still fairly clear what the user is getting back.
If we really want to continue calling &[T]
a "slice" and &mut [T]
a "mutable slice", then we must come up with a new name for a [T]
to avoid ambiguous language.
Locations (not comprehensive)
- Confusing language exists throughout the documentation
- stdlib:
primitive slice
- A slice is a "dynamically-sized view into a contiguous sequence"
- They are "either mutable or shared" - neglecting the existance of owned slices
- The type is for slice primitives, but the documentation generally describes slice references
std::slice
- same documentation as for the slice primitive, but then additionally describes traits and methods which apply to the primitive type
std::slice::from_raw_parts
returns a "slice"std::slice::from_raw_parts_mut
returns a "mutable slice"- Nowhere in the documentation is an actual slice described, and the difference between slices and references to them is never made clear
- the rust book - slice chapter
- "Slices let you reference a contiguous sequence of elements in a collection rather than the whole collection"
- "A slice is a kind of reference, so it does not have ownership" - incorrect
- "array" is used interchangably with "slice" without definitions being clarified
- generally uses "slice" to mean
&[T]
- the rust reference
- Glossary
-
"A slice is dynamically-sized view into a contiguous sequence, written as [T].
It is often seen in its borrowed forms, either mutable or shared. The shared slice type is &[T], while the mutable slice type is &mut [T], where T represents the element type." - This is the best description so far, but again, the reference type names are used interchangably with an actual slice type.
-
- Slice types
- "A slice is a dynamically sized type representing a 'view' into a sequence of elements of type T. The slice type is written as [T]"
- "&[T]: a 'shared slice', often just called a 'slice'. It doesn't own the data it points to; it borrows it.
&mut [T]: a 'mutable slice'. It mutably borrows the data it points to.
Box<[T]>: a 'boxed slice'"
- Glossary
TL;DR: Using "slice" to mean &[T]
is bad, confusing, and hard to learn.
Does anyone else think this is a problem? Please bikeshed your &[T]
and &mut [T]
names and other thoughts below :)