[swift-evolution] [Review] SE-0065 A New Model for Collections and Indices
Dave Abrahams
dabrahams at apple.com
Tue Apr 12 16:37:18 CDT 2016
on Mon Apr 11 2016, Nate Cook <natecook-AT-gmail.com> wrote:
> Proposal link:
> https://github.com/apple/swift-evolution/blob/master/proposals/0065-collections-move-indices.md
>
> On Apr 11, 2016, at 2:59 PM, Dave Abrahams via swift-evolution
> <swift-evolution at swift.org> wrote:
>
> Thanks for your comments, Brent!
>
> on Sun Apr 10 2016, Brent Royal-Gordon <swift-evolution at swift.org> wrote:
>
> The shift described in this proposal is extremely valuable and makes
> implementing collections far more intuitive, as all the collection's logic lives
> "inside" the collection itself. My only hesitation is with the naming of the
> method that Brent also called out:
>
> ... snip ...
>
> func index(n: IndexDistance, stepsFrom i: Index) -> Index
>
> Oof, I am really not a fan of this name. `steps` is sort-of a label on
> the `n` parameter, but it's attached to `i`.
>
> Oof indeed! This is a very unusual method in the standard library, since we're
> calling on one instance to perform an action on another. My problems with the
> naming are twofold:
>
> (1) Collision with the index(of:) and index(where:) APIs
> The existing methods are used for searching a collection, possibly finding a
> matching index, possibly not. The new ones deterministically find an new index
> at a prescribed distance, with important and slightly complicated preconditions.
> These differences make the use and "flavor" of the two sets of methods distinct
> enough that I think they should have different names.
Yup, I think that's a strong argument.
>
>
> (2) Arguments are reversed
> I think the ideal API for this would be index.advanced(by: 5, in: c), but I
> prefer keeping the index-moving implementation in the collection, not the index.
> I would favor any naming for this method that puts the index before the
> distance, keeping the overall shape of the advanced(by:) method. c.advance(i,
> by: 4) would be my pick.
Right, that would be great, except that it's a non-side-effectful method
and if we “noun the verb” (e.g. c.advanced(...)) it is now a method that
should return a modified version of the receiver, which it does not. In
other words, there's no path to a non-mutating variant of the method.
One other possible approach: make the only method mutating, so instead
of
let j = c.index(5, stepsFrom: i)
you get:
var j = i
c.advance(&j, by: 5)
// ...use j...
I think being forced to accept making j mutable would be a sad tradeoff
to make just because the name of the method makes us uncomfortable, but
it's an option.
> ....and finally I'll just go ahead and say again that I prefer -InPlace over
> form-.
Yer preachin' to the choir, brother.
> That's all, I'm done!
>
> Nate
>
> ps. Seriously, collections make so much more sense with this change. +1000
>
> Yes, it's an awkward thing to name. Better suggestions most welcome.
>
> Other collection APIs use `distance`, not `steps` (although "steps"
> does appear in the documentation of the `Distance` associated
> type). `index` puts it in a method family with `index(predicate:)` and
> `index(of:)`, but those two are user-facing while this one is part of
> the collection API. Even the word `index` itself is redundant with the
> method return type.
>
> I do understand how this is kind of parallel to `index(of:)` and
> `index(predicate:)`, in that they all return an index calculated from
> the parameters, but I think these methods are more different than they
> are similar.
>
> Compared to this:
>
> collection.index(5, stepsFrom: i)
>
> I would prefer any of these (ordered from least favorite to most):
>
> collection.index(distance: 5, from: i)
>
> I'm OK with this one, but am not sure it's an improvement over the
> proposal. I'd like to hear other peoples' arguments on this.
>
> collection.index(5, from: i)
>
> I don't think this one reads clearly enough.
>
> collection.traveling(5, from: i)
> collection.striding(5, from: i)
> collection.advancing(i, by: 5)
>
> None of the “ing” names work, IMO because that suffix suggests you're
> returning a modified version of the receiver.
>
> A word on `striding(_:from:)` appearing in that list: Although
> redesigning Strideable is not directly in scope for this proposal,
> I've noticed that our discussions on modernizing Strideable seem to be
> trending towards the idea that it operates on collections (or rather,
> on an as-yet-unnamed supertype of `BidirectionalCollection` or
> `RandomAccessCollection`) and strides by repeatedly calling a method
> with the same semantics as this one. Thus, there seems to be an
> intimate connection between this operation and Strideable. I think we
> ought to choose a method name which suits that, and I don't think
> `index` is it.
>
> func index(n: IndexDistance, stepsFrom i: Index, limitedBy
> limit: Index) -> Index
>
> I have a few issues with this API.
>
> 1. As aforementioned, I'm not a big fan of using `index` as the base
> method name.
>
> 2. This method can move the index either forwards or backwards, but
> only one limit is specified. Would we be better off having the `limit`
> be a range?
>
> That would add a cost for checking that one doesn't want to pay in
> algorithms that need this method.
>
> 3. What is the use case for returning the `limit` instead of returning
> the fact that we crossed it? I have a hard time thinking of a case
> where I would want to just bump up against the limit and use it rather
> than *detect* that I've hit the limit (which would probably call for a
> return type of `Index?`). Are there common needs that I'm just not
> thinking of?
>
> Sure, for example
>
> x[i..<x.index(n, stepsFrom: i, limitedBy: x.endIndex)].sort()
>
> Should we offer both?
>
> Definitely not, IMO! They are utterly redundant, are they not?
>
> * What is your evaluation of the proposal?
>
> Despite my criticisms, this is fundamentally a very good design. It
> will not only improve the language, it will also open the door to
> further improvements.
>
> * Is the problem being addressed significant enough to warrant a
> change to Swift?
>
> Yes. I believe this change is complicating in the short run but
> actually simplifying in the long run, eliminating concepts like the
> Index protocols which represented several overlapping semantics.
>
> * Does this proposal fit well with the feel and direction of
> Swift?
>
> Yes.
>
> * If you have you used other languages or libraries with a
> similar feature, how do you feel that this proposal compares to
> those?
>
> Nothing with a collection design as rich as Swift's.
>
> * How much effort did you put into your review? A glance, a
> quick reading, or an in-depth study?
>
> Somewhere between the latter two. I wouldn't call it in-depth when
> it's such a big change, but I feel like I have too much background to
> say it's a quick reading, either.
>
> --
> Dave
>
> _______________________________________________
> 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