[swift-evolution] [SHORT Review] SE-0132: Rationalizing Sequence end-operation names

Dave Abrahams dabrahams at apple.com
Tue Jul 26 14:45:39 CDT 2016


on Mon Jul 25 2016, Jacob Bandes-Storch <swift-evolution at swift.org> wrote:

>>
>>
>> https://github.com/apple/swift-evolution/blob/master/proposals/0132-sequence-end-ops.md
>>
>>         * What is your evaluation of the proposal?
>>
>
> +1 on drop{First,Last}() → removing{First,Last}().
> +1 on drop{First,Last}(_:) → removing{Prefix,Suffix}(_:).
> +1 on drop(while:) → removingPrefix(while:).
> +1 on starts(with:[by:]) → hasPrefix(_:[by:]).
> +1 on index({of:,where:}) → firstIndex({of:,where:}).
> +1 on prefix and postfix versions of ..< and the prefix version of the ...
> operator. For a while I thought I might prefer labeled subscripts, but
> after writing them out I agree the operators are better.
>
> The rest is a stream of consciousness:.
>
> I don't think postfix ... is necessary. When does one ever combine a
> ClosedRange with endIndex?

+1

There is a use case for it, but IMO it's a corner that doesn't need
terse syntax.

> I don't agree that "drop" sounds particularly scary, 

It's scary because it's active.  “Dropping” has other issues, as you
note below.

> but I'm fine with "removing" as an alternative to
> "drop"/"dropping". Scatologists will be disappointed, I'm sure.
>
> I'd forgotten about prefix(while:), which apparently isn't implemented yet.
> I think I'd prefer if this were named prefix(where:) instead.

+1

> I'm struggling a little with the distinction between length-based and
> index-based methods/subscripts. Are "prefix(_ length: Int)" and
> "prefix(upTo end: Index)" really different enough that one of them should
> be a subscript and the other a method? 

> The same question applies to prefix(through:) and suffix(from:). I
> kinda wish these could all be methods or all subscripts.

Me too.  That was the motivation for my suggestion of x[..<$+n], meaning
x.prefix(n).

However, that proposal is a failure (I just wrote it wrong above again
before correcting myself)!

The main point of changing prefix(to:) and suffix(from:) into x[..<i]
and x[i..<] is not to make them subscripts, but to re-use the cognitive
power users have already invested in range expressions.  Writing them as
something like x.slice(..<i) and x.slice(i..<), would accomplish that,
too.

> I have to say I don't fully understand the need for (or benefits of)
> RangeExpression and the relative(to:) API (perhaps because I don't have
> much experience using the most recent collection/index/range APIs). 

It collapses a whole raft of overloads into two (except for subscript,
because we don't have generic subscript yet, which is a temporary
limitation).  In general if you want to implement a collection method
that takes a range today, you really should implement four overloads.
With the introduction of the incomplete ranges it's six or eight.

> Since the conforming type's Bound is already required to be the
> collection's Index, it seems pointless to have an API to access this
> as a Range...there should just be Collection subscript methods which
> accept the conforming types. I suppose it's nice to get all these for
> free by implementing just one subscript function (excepting the
> current lack of generic subscripts)...but is it even possible to
> express every RangeExpression as a Range? 

For the purposes of creating a range of valid indices in a collection, yes.

> What about a ClosedRange<Int> whose upperBound is Int.max? (Wasn't
> that the whole point of introducing ClosedRange in the first place?)
>
> Random question: why do we have both removeFirst and popFirst?  

We don't.

> ...on further reading I see you covered this in Future Directions. I'd
> be happy to discuss merging these. I wonder if it's important to do
> for Swift 3 (although we're basically out of time)?
>
> The name IncompleteRange makes sense, but could be a little misleading if
> ..<(Bound?,Bound?) is called with two non-nil operands: based on my
> reading, it sounds like the returned IncompleteRange wouldn't actually
> change when you call completed(by:) (since it's not actually incomplete).
> However, I can't come up with any better naming suggestions.
>
>>         * Is the problem being addressed significant enough to warrant a
>> change to Swift?
>>
>
> Yes.
>
>>         * Does this proposal fit well with the feel and direction of Swift?
>>
>
> Mostly. Not sure there's enough consistency between
> subsequence-length-based and index-based APIs, namely that prefix(upTo:)
> becomes a subscript but prefix(_:) doesn't.
>
>         * If you have used other languages or libraries with a similar
>> feature, how do you feel that this proposal compares to those?
>>
>
> I've used Python and Mathematica, which both have functionality similar to
> "incomplete range subscripts":
>
>     Python: http://stackoverflow.com/a/509295/23649
>     Mathematica: https://reference.wolfram.com/language/ref/Span.html
>
> Based on my experience there, this is a good first (second?) step for Swift
> to take.
>
> Both Mathematica and Python support a *stride* as well as start/end indices
> in their subscripting syntax. It would be nice for Swift to support
> something like this, but some versions of that would require custom ternary
> operators (or weird intermediate types to fake a custom ternary operator).
> We might also consider labelled multi-argument subscripts like
> "collection[start..<end, by: 2]".

There's a point at which we should stop trying to overload subscript
syntax and just use stride(...).

> They also both support *negative indices *which count from the end. 

That's another thing I was getting at with x[..<$-n]
(a.k.a. x.removingSuffix(ofMaxLength: n)).  But again, #FAIL.

> Swift's suffix-based APIs are limited; I'd like to see an in-depth
> consideration of this down the line. Now is probably not the time,
> unless anyone can think of reasons it would affect the syntax/naming
> we choose in this proposal.
>
> (It's also interesting to note that Mathematica's subscripts (Part
> <https://reference.wolfram.com/language/ref/Part.html>) support
> multi-dimensional arrays:  matrix[[3;;4, -5;;]] would be the submatrix
> containing the last 5 entries in rows 3 and 4 of the original matrix.)
>
>>         * How much effort did you put into your review? A glance, a quick
>> reading, or an in-depth study?
>>
>
> A mostly-thorough reading of the proposal.
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>

-- 
Dave



More information about the swift-evolution mailing list