Get vs get!

I do not know what could get! do to an object. Shouldn’t a get function be non-transformative of the input? I am accesing a value…

1 Like

Let’s compare by using help mode (you enter by typing a leading ? and exit by backspacing it):

help?> get
search: get get! let Set getkey Text getpid Meta

  get(collection, key, default)

  Return the value stored for the given key, or the given default value if no mapping for the key is present.

vs

help?> get!
search: get! get getkey let Set put! getpid Meta

  get!(collection, key, default)

  Return the value stored for the given key, or if no mapping for the key is present, store key => default, and return default.

get! has the extra step of storing the default. Could have been called something like get_maybe_set_default!, but it’s more typing and would make it unfair to omit the default behavior from get_maybe_default. get! is enough of a hint if you already know what get does (and it’s not the same as getindex for brackets syntax).

3 Likes

Especially the method computing the default value

get!(f::Union{Function, Type}, collection, key)

is super handy for memoization:

julia> function slowfib(n::Integer)
           n < 2 ? 1 : slowfib(n-1) + slowfib(n-2)
       end

julia> function fastfib(n::T; cache = Dict{T,T}()) where {T <: Integer}
           get!(cache, n) do
               n < 2 ? 1 : fastfib(n-1; cache=cache) + fastfib(n-2; cache = cache)
           end
       end

julia> fastfib.(BigInt.(1:100))  # Don't try this with slowfib!
100-element Vector{BigInt}:
                     1
                     2
                     3
                     5
                     8
4 Likes

That’s a reasonable expectation and is true for get. On the other hand get! ends with an exclamation mark, which in Julia is a naming convention for functions that change their input in some way.

4 Likes