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, matthe...@gmail.com 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, <matthe...@gmail.com> 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.
>>> 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