@@ -85,6 +85,14 @@ Like `Index`, uses of this notation will auto-deref just as if they were method
85
85
invocations. So if ` T ` implements ` Slice<uint, [U]> ` , and ` s: Smaht<T> ` , then
86
86
` s[] ` compiles and has type ` &[U] ` .
87
87
88
+ Note that slicing is "exclusive" (so ` [n..m] ` is the interval `n <= x
89
+ < m` ), while ` ..` in ` match` patterns is "inclusive". To avoid
90
+ confusion, we propose to change the ` match ` notation to ` ... ` to
91
+ reflect the distinction. The reason to change the notation, rather
92
+ than the interpretation, is that the exclusive (respectively
93
+ inclusive) interpretation is the right default for slicing
94
+ (respectively matching).
95
+
88
96
## Rationale for the notation
89
97
90
98
The choice of square brackets for slicing is straightforward: it matches our
@@ -98,12 +106,54 @@ for slicing has precedent in Perl and D.
98
106
See [ Wikipedia] ( http://en.wikipedia.org/wiki/Array_slicing ) for more on the
99
107
history of slice notation in programming languages.
100
108
109
+ ### The ` mut ` qualifier
110
+
111
+ It may be surprising that ` mut ` is used as a qualifier in the proposed
112
+ slice notation, but not for the indexing notation. The reason is that
113
+ indexing includes an implicit dereference. If ` v: Vec<Foo> ` then
114
+ ` v[n] ` has type ` Foo ` , not ` &Foo ` or ` &mut Foo ` . So if you want to get
115
+ a mutable reference via indexing, you write ` &mut v[n] ` . More
116
+ generally, this allows us to do resolution/typechecking prior to
117
+ resolving the mutability.
118
+
119
+ This treatment of ` Index ` matches the C tradition, and allows us to
120
+ write things like ` v[0] = foo ` instead of ` *v[0] = foo ` .
121
+
122
+ On the other hand, this approach is problematic for slicing, since in
123
+ general it would yield an unsized type (under DST) -- and of course,
124
+ slicing is meant to give you a fat pointer indicating the size of the
125
+ slice, which we don't want to immediately deref. But the consequence
126
+ is that we need to know the mutability of the slice up front, when we
127
+ take it, since it determines the type of the expression.
128
+
101
129
# Drawbacks
102
130
103
131
The main drawback is the increase in complexity of the language syntax. This
104
132
seems minor, especially since the notation here is essentially "finishing" what
105
133
was started with the ` Index ` trait.
106
134
135
+ ## Limitations in the design
136
+
137
+ Like the ` Index ` trait, this forces the result to be a reference via
138
+ ` & ` , which may rule out some generalizations of slicing.
139
+
140
+ One way of solving this problem is for the slice methods to take
141
+ ` self ` (by value) rather than ` &self ` , and in turn to implement the
142
+ trait on ` &T ` rather than ` T ` . Whether this approach is viable in the
143
+ long run will depend on the final rules for method resolution and
144
+ auto-ref.
145
+
146
+ In general, the trait system works best when traits can be applied to
147
+ types ` T ` rather than borrowed types ` &T ` . Ultimately, if Rust gains
148
+ higher-kinded types (HKT), we could change the slice type ` S ` in the
149
+ trait to be higher-kinded, so that it is a * family* of types indexed
150
+ by lifetime. Then we could replace the ` &'a S ` in the return value
151
+ with ` S<'a> ` . It should be possible to transition from the current
152
+ ` Index ` and ` Slice ` trait designs to an HKT version in the future
153
+ without breaking backwards compatibility by using blanket
154
+ implementations of the new traits (say, ` IndexHKT ` ) for types that
155
+ implement the old ones.
156
+
107
157
# Alternatives
108
158
109
159
For improving the ergonomics of ` as_slice ` , there are two main alternatives.
0 commit comments