>
> - 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, <matthe...@gmail.com <javascript:>> 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 golang-nuts...@googlegroups.com <javascript:>.
>> 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 golang-nuts+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to