On Wed, Oct 12, 2016 at 10:31 AM, Nate Cook via swift-evolution < swift-evolution@swift.org> wrote:
> Thanks for your feedback! Response below. > > On Oct 12, 2016, at 5:40 AM, Daniel Vollmer via swift-evolution < > swift-evolution@swift.org> wrote: > > Hi, > > I very much think the points mentioned in the motivation are worth > addressing (and IMO this is not an area where “maybe the optimizer can be > made smarter” can cut it; I want performance guarantees, not hopes). > > On 11 Oct 2016, at 23:28, Nate Cook via swift-evolution < > swift-evolution@swift.org> wrote: > > > [snip] > > On a shallow read I like presented approach, except for > > Both the keys and values collections share the same index type as > Dictionary. This allows the above sample to be rewritten as: > > // Using `dict.keys.index(of:)` > if let i = dict.keys.index(of: "one") { > dict.values[i].append(1) > } else { > dict["one"] = [1] > } > > > The asymmetry between the if / else branches seems ugly to me. That is > once obtaining the value “directly” from dict, and once through the > values-view. I don’t have a great solution here, but is is possible to > subscript the dict by its `Index` as well as its `Key`? > > ``` > // Using `dict.keys.index(of:)` > if let i = dict.keys.index(of: "one") { > dict[i].append(1) > } else { > dict["one"] = [1] > } > ``` > > > I share your concern with this, and there is an approach that would make > this kind of interface possible. Basically, what you're describing here > would necessitate changing Dictionary to act like a mutable collection of > values, and instead of presenting `keys` and `values` views, we would > probably offer `keys` and `keysAndValues` (or something) views. With that > new model, we'd have code like the following: > > var dict = ["one": [1], "two": [2, 2], "three": [3, 3, 3]] > > // Iterating the dictionary itself would be like we now iterate the values > collection > for val in dict { > print(val) > } > // Output is just the values (unordered as usual) > // [1] > // [3, 3, 3] > // [2, 2] > > // Iterating a new view would act like the dictionary currently does > for (key, val) in dict.keysAndValues { > print(key, val) > } > // "one", [1] > // "three", [3, 3, 3] > // "two", [2, 2] > > > Any sequence or collections operations on the dictionary itself would only > interact with values: > > print(dict.first) > // Optional([1]) > print(dict.first(where: { $0.count > 2 })) > // Optional([3, 3, 3]) > > > I'm not strictly opposed to this approach, but I do prefer the way the > current dictionary implementation presents its elements as key-value pairs. > When you iterate a dictionary you're seeing *all* of its contents, which > I like, but there are clear tradeoffs between the two. Making Dictionary a > collection of values is also a much more significant change than the one > proposed—we'd need to do some research into the ways dictionaries are used > to know how much larger an effect that would be. > > What do others think of this as an alternative solution for the motivating > issues? Does anyone actually use indices right now to work with > dictionaries, or is key-based read/write pretty much the only interface? > I much, much prefer your proposed solution to this alternative. Most of it is just a gut reaction, I have to admit. However, let me try to verbalize some reasons: For one, the performance issues are the motivating problem, and they are solved with minimal disruption to the current Dictionary API in your currently proposed solution. Second, I think the asymmetry identified (while aesthetically less than perfectly pleasing) is in the nature of opaque indices and is consistent with precedent in String. Finally, I think it's ideal that we can introduce collection types to learners by pointing out that arrays are notionally index-based and dictionaries are key-based (however these types are actually implemented behind the scenes); permitting direct subscripting by dictionary indices muddies that distinction. On another note, I’m not sure whether there is a way (or whether it’s even > worth trying) to avoid hashing the key twice when the `else` branch is > taken. > > > This is outside the scope of the proposal, but as far as I can see I don't > think there's a solution for this that wouldn't overly expose the internal > workings of the dictionary. > > Thanks again, > Nate > > > > _______________________________________________ > swift-evolution mailing list > swift-evolution@swift.org > https://lists.swift.org/mailman/listinfo/swift-evolution > >
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution