Stefan, If I'm reading between the lines correctly, the default/existing hash function is based on the last byte of the ID? Is there a reason we don't make the table wider to reduce the chances of collisions (or would this have bad effects on memory utilization)?
On Thursday, July 16, 2015 at 8:50:52 AM UTC-7, Stefan Karpinski wrote: > > Well, that's it then. Cause: accidental hash collision. The fix is to > define hash for the type. This makes me wonder if we shouldn't just leave > hash undefined for custom mutable types and make it easy to opt into > hashing by identity. At least then you'll get a clear no method error (and > we could trap that and add more helpful information), instead of weird > behavior when you define == but not hash for your types. > > On Thu, Jul 16, 2015 at 11:39 AM, milktrader <milkt...@gmail.com > <javascript:>> wrote: > >> julia> hash(foos[1]) #and hash(foos[2]) >> 0xfa40ebab47e8bee1 >> >> julia> hash(foos[2]) >> 0x00ef97f955461671 >> >> On Thursday, July 16, 2015 at 11:36:03 AM UTC-4, Stefan Karpinski wrote: >>> >>> Dan and/or Seth, can you try that again and check if hash(foos[1]) and >>> hash(foos[2]) have the same last hex digit? >>> >>> On Thu, Jul 16, 2015 at 11:30 AM, Matt Bauman <mba...@gmail.com> wrote: >>> >>>> Bizarre. I happen to have last updated on *exactly* the same commit >>>> SHA, but I'm seeing the original (expected) behavior: >>>> >>>> $ julia -q >>>> julia> versioninfo() >>>> Julia Version 0.4.0-dev+5860 >>>> Commit 7fa43ed (2015-07-08 20:57 UTC) >>>> Platform Info: >>>> System: Darwin (x86_64-apple-darwin14.3.0) >>>> CPU: Intel(R) Core(TM) i5 CPU M 520 @ 2.40GHz >>>> WORD_SIZE: 64 >>>> BLAS: libopenblas (USE64BITINT NO_AFFINITY NEHALEM) >>>> LAPACK: libopenblas >>>> LIBM: libopenlibm >>>> LLVM: libLLVM-3.3 >>>> >>>> julia> type Foo >>>> x::Int >>>> end >>>> >>>> julia> ==(f1::Foo, f2::Foo) = f1.x == f2.x >>>> == (generic function with 109 methods) >>>> >>>> julia> unique([Foo(4),Foo(4)]) >>>> 2-element Array{Foo,1}: >>>> Foo(4) >>>> Foo(4) >>>> >>>> julia> @which hash(Foo(4), zero(UInt)) >>>> hash(x::ANY, h::UInt64) at hashing.jl:10 >>>> >>>> Might there be some package that changes this behavior? Is the result >>>> of `@which hash(Foo(4), zero(Uint))` the same as what I show above? >>>> >>>> >>>> On Thursday, July 16, 2015 at 11:02:46 AM UTC-4, Seth wrote: >>>>> >>>>> I can confirm this works as described by milktrader on 0.4.0-dev+5860 >>>>> (2015-07-08 20:57 UTC) Commit 7fa43ed (7 days old master). >>>>> >>>>> julia> unique(foos) >>>>> 1-element Array{Foo,1}: >>>>> Foo(4) >>>>> >>>>> >>>>> On Thursday, July 16, 2015 at 7:52:03 AM UTC-7, Stefan Karpinski wrote: >>>>>> >>>>>> I don't see that on 0.4-dev – it also doesn't seem possible without >>>>>> having defined a hash method since unique is implemented with a dict. >>>>>> >>>>>> On Thu, Jul 16, 2015 at 10:29 AM, milktrader <milkt...@gmail.com> >>>>>> wrote: >>>>>> >>>>>>> Julia 0.4- has different behavior ... >>>>>>> >>>>>>> First, with 0.3.9 >>>>>>> >>>>>>> julia> versioninfo() >>>>>>> Julia Version 0.3.9 >>>>>>> Commit 31efe69 (2015-05-30 11:24 UTC) >>>>>>> Platform Info: >>>>>>> System: Darwin (x86_64-apple-darwin13.4.0) >>>>>>> CPU: Intel(R) Core(TM)2 Duo CPU P7350 @ 2.00GHz >>>>>>> WORD_SIZE: 64 >>>>>>> BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Penryn) >>>>>>> LAPACK: libopenblas >>>>>>> LIBM: libopenlibm >>>>>>> LLVM: libLLVM-3.3 >>>>>>> >>>>>>> julia> type Foo >>>>>>> x::Int >>>>>>> end >>>>>>> >>>>>>> julia> import Base: == >>>>>>> >>>>>>> julia> ==(f1::Foo, f2::Foo) = f1.x == f2.x >>>>>>> == (generic function with 80 methods) >>>>>>> >>>>>>> julia> foos = [Foo(4), Foo(4)] >>>>>>> 2-element Array{Foo,1}: >>>>>>> Foo(4) >>>>>>> Foo(4) >>>>>>> >>>>>>> julia> unique(foos) >>>>>>> 2-element Array{Foo,1}: >>>>>>> Foo(4) >>>>>>> Foo(4) >>>>>>> >>>>>>> julia> unique(foos)[1] == unique(foos)[2] >>>>>>> true >>>>>>> >>>>>>> And now 0.4-dev >>>>>>> >>>>>>> julia> versioninfo() >>>>>>> Julia Version 0.4.0-dev+5587 >>>>>>> Commit 78760e2 (2015-06-25 14:27 UTC) >>>>>>> Platform Info: >>>>>>> System: Darwin (x86_64-apple-darwin13.4.0) >>>>>>> CPU: Intel(R) Core(TM)2 Duo CPU P7350 @ 2.00GHz >>>>>>> WORD_SIZE: 64 >>>>>>> BLAS: libopenblas (USE64BITINT DYNAMIC_ARCH NO_AFFINITY Penryn) >>>>>>> LAPACK: libopenblas >>>>>>> LIBM: libopenlibm >>>>>>> LLVM: libLLVM-3.3 >>>>>>> >>>>>>> julia> type Foo >>>>>>> x::Int >>>>>>> end >>>>>>> >>>>>>> julia> import Base: == >>>>>>> >>>>>>> julia> ==(f1::Foo, f2::Foo) = f1.x == f2.x >>>>>>> == (generic function with 108 methods) >>>>>>> >>>>>>> julia> foos = [Foo(4), Foo(4)] >>>>>>> 2-element Array{Foo,1}: >>>>>>> Foo(4) >>>>>>> Foo(4) >>>>>>> >>>>>>> julia> unique(foos) >>>>>>> 1-element Array{Foo,1}: >>>>>>> Foo(4) >>>>>>> >>>>>>> julia> unique(foos)[1] == unique(foos)[2] >>>>>>> ERROR: BoundsError: attempt to access 1-element Array{Foo,1}: >>>>>>> Foo(4) >>>>>>> at index [2] >>>>>>> in getindex at array.jl:292 >>>>>>> >>>>>>> >>>>>>> >>>>>>> On Thursday, July 16, 2015 at 9:36:21 AM UTC-4, Stefan Karpinski >>>>>>> wrote: >>>>>>>> >>>>>>>> You need to also define a hash method for this type. >>>>>>>> >>>>>>>> >>>>>>>> On Jul 16, 2015, at 9:16 AM, Marc Gallant <marc.j....@gmail.com> >>>>>>>> wrote: >>>>>>>> >>>>>>>> The unique function doesn't appear to work using iterables of >>>>>>>> custom composite types, e.g., >>>>>>>> >>>>>>>> julia> type Foo >>>>>>>> x::Int >>>>>>>> end >>>>>>>> >>>>>>>> julia> import Base: == >>>>>>>> >>>>>>>> julia> ==(f1::Foo, f2::Foo) = f1.x == f2.x >>>>>>>> == (generic function with 85 methods) >>>>>>>> >>>>>>>> julia> unique(foos) >>>>>>>> 2-element Array{Foo,1}: >>>>>>>> Foo(4) >>>>>>>> Foo(4) >>>>>>>> >>>>>>>> julia> unique(foos)[1] == unique(foos)[2] >>>>>>>> true >>>>>>>> >>>>>>>> >>>>>>>> Is this the intended behaviour? >>>>>>>> >>>>>>>> >>>>>> >>> >