Correction on the self-reference example:
a0 := A{}
// equal
a1 := A{a0, A{}}
a1[0] = a1
a2 := A{a1, a1[1]}
// not equal
a3 := A{A{a1, a1[1]}, a1[1]}
Thanks,
Matt
On Tuesday, January 30, 2018 at 5:19:44 PM UTC-6, [email protected] wrote:
>
> - When slices can be compared, they can be used as map keys. What happens
>> if the contents of a slice are changed after it has been added to a map?
>
>
> I’m not too familiar with Go map internals, but my thought is the key hash
> would depend on the backing array values. Go maps also allow reading the
> keys back using iteration so the slice backing array (up to length) would
> have to be copied. If the slice contents are changed then that would be a
> different key and the original key would be intact.
>
> - It is possible to have self-referential slices [1]. How would
>> comparison work in such a case?
>
>
> Perhaps a slice of slices would compare the contents, the slice headers,
> to each other like structs.
>
> type A []A
>
> // not equal
> a0 := A{A{}}
> a1 := A{}
>
> // not equal
> a2 := A{A{}, A{A{}}}
> a3 := A{A{}, A{A{}}}
>
> // not equal
> a4 := A{a0}
> a5 := A{A{A{}}}
>
> // equal
> a6 := A{a0}
> a7 := A{a0}
>
> // equal
> a8 := A{a0}
> a8[0] = a1
> a9 := A{a1}
>
> The self-reference:
>
> a0 := A{}
> // equal
> a1 := A{a0, A{}}
> a1[0] = a1
> a2 := A{a0, a1[1]}
> // not equal
> a3 := A{A{}, a1[1]}
>
> I'm not sure about this one since it seems to go against the idea of slice
> comparison by values.
>
> Matt
>
> On Tuesday, January 30, 2018 at 2:33:38 PM UTC-6, rog wrote:
>>
>> Two significant issues that need to be thought about:
>>
>> - When slices can be compared, they can be used as map keys. What happens
>> if the contents of a slice are changed after it has been added to a map?
>>
>> - It is possible to have self-referential slices [1]. How would
>> comparison work in such a case?
>>
>>
>> [1] https://play.golang.org/p/lTqhKjD842K
>>
>> On 30 Jan 2018 16:45, <[email protected]> wrote:
>>
>>> Here’s a draft for a Go 2 proposal that I’d like to add to the issue
>>> tracker since there’s no discussion there about this:
>>>
>>> Slices should have equality defined.
>>>
>>> https://golang.org/doc/faq#map_keys
>>>
>>> Map lookup requires an equality operator, which slices do not implement.
>>>> They don't implement equality because equality is not well defined on such
>>>> types; there are multiple considerations involving shallow vs. deep
>>>> comparison, pointer vs. value comparison, how to deal with recursive
>>>> types,
>>>> and so on.
>>>
>>>
>>> This proposal allows slices to be used as map keys and for comparison
>>> with == and !=.
>>>
>>> https://golang.org/ref/spec#Comparison_operators
>>>
>>> Slice, map, and function values are not comparable.
>>>
>>>
>>> An initial proposal is that slices are compared by nil versus non-nil,
>>> length and backing array pointer, and then by the rules for array if length
>>> is equal but different arrays are pointed:
>>>
>>> Array values are comparable if values of the array element type are
>>>> comparable. Two array values are equal if their corresponding elements are
>>>> equal.
>>>
>>>
>>> reflect.DeepEqual defines a similar slice equality except “deeply equal”
>>> defines additional criteria: https://golang.org/pkg/reflect/#DeepEqual
>>>
>>> Slice values are deeply equal when all of the following are true: they
>>>> are both nil or both non-nil, they have the same length, and either they
>>>> point to the same initial entry of the same underlying array (that is,
>>>> &x[0] == &y[0]) or their corresponding elements (up to length) are deeply
>>>> equal. Note that a non-nil empty slice and a nil slice (for example,
>>>> []byte{} and []byte(nil)) are not deeply equal.
>>>
>>>
>>> A use case for me was a map keyed by varying length paths where the map
>>> was not shared between different path generating computations. With this
>>> proposal such a type could have shared generated paths as keys.
>>>
>>> Ian suggests in a [this] golang-nuts thread that there are varying use
>>> cases:
>>>
>>> The problem is that different programs need different things for slice
>>>> equality. Some want pointer equality as you suggest. Some want element
>>>> comparisons, as is done for array equality. Without an obvious semantics
>>>> for the operation, the language omits it entirely.
>>>>
>>>
>>> But I don’t know where slice pointer equality would be useful. I'm also
>>> not clear on the recursive type problem.
>>>
>>> Matt
>>>
>>> On Monday, July 4, 2016 at 2:29:18 AM UTC-5, Chad wrote:
>>>>
>>>> I realize that the issue might be about changing/ adding a builtin:
>>>>
>>>> - either add a builtin deep value Comparison function (via
>>>> reflection)
>>>> - or add a snapshot type refinement which triggers the allocation
>>>> of an immutable copy of a reference type
>>>> (and we would recover the behaviour of the string implementation
>>>> which is a special case of []byte snapshot, i.e. a value type*)
>>>>
>>>> I would still expect the behaviour previously mentioned for the "=="
>>>> operator.
>>>>
>>>> (*) I keep using reference/value type terminology but it is indeed
>>>> slightly tricky. But for lack of a better one...
>>>>
>>> --
>>> You received this message because you are subscribed to the Google
>>> Groups "golang-nuts" group.
>>> To unsubscribe from this group and stop receiving emails from it, send
>>> an email to [email protected].
>>> For more options, visit https://groups.google.com/d/optout.
>>>
>>
--
You received this message because you are subscribed to the Google Groups
"golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.