Thanks for your feedback! Response below.
> On Oct 12, 2016, at 5:40 AM, Daniel Vollmer via swift-evolution
> <[email protected]> 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
>> <[email protected]> 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?
> 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
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution