Hi, I was hanging around Base and I found this method.
@edit Base.hash_32_32(UInt32(1)) # juila 1.6.1
function hash_32_32(n::UInt32)
a::UInt32 = n # what is it the purpose of this line?
a = a + 0x7ed55d16 + a << 12
a = a ⊻ 0xc761c23c ⊻ a >> 19
a = a + 0x165667b1 + a << 5
a = a + 0xd3a2646c ⊻ a << 9
a = a + 0xfd7046c5 + a << 3
a = a ⊻ 0xb55a4f09 ⊻ a >> 16
return a
end
I have no idea of the purpose of the first line of the method!
Why is it necessary the type assertion?
The first line probably exists to avoid mutating n. If you got rid of that line, it would be customary to call the function hash_32_32! to make it clear that it returns the answer in place (EDIT: This is nonsense, sorry!). If you are only curious about the type assertion, I agree it seems redundant.
Operations on numbers (like UInt32) are never “in place” (since they’re immutable) so the function wouldn’t need the !. The reason for the line a::UInt32 is that, in that context, the type annotation is a “guarantee” that a will always be a UInt32, no matter what happens to it. In practice, this means that every a = a... operation is followed by a convert(UInt32, a).
See:
julia> function foo(x::Int)
y::Int = x
y += 1.0
y
end
foo (generic function with 1 method)
julia> function bar(x::Int)
y = x
y += 1.0
y
end
bar (generic function with 1 method)
julia> foo(1)
2
julia> bar(1)
2.0
edit with another example, with a number that cannot be converted back to Int
julia> function baz(x)
y::Int = x
y += 1.1
y
end
baz (generic function with 1 method)
julia> baz(1)
ERROR: InexactError: Int64(2.1)
Stacktrace:
[1] Int64 at ./float.jl:710 [inlined]
[2] convert at ./number.jl:7 [inlined]
[3] baz(::Int64) at ./REPL[39]:3
[4] top-level scope at REPL[40]:1