Could pop!(::Dict, key, default) have a do-block method?

Currently pop! has a method that requires all arguments to be evaluated beforehand:

julia> a = Dict("x" => 3, "y" => 4)
Dict{String,Int64} with 2 entries:
  "x" => 3
  "y" => 4

julia> @time pop!(a, "x", (sleep(10); 5))
 10.000316 seconds (1.00 k allocations: 22.312 KiB)
3

However in this case there’s no need to evaluate the default argument. Would it make sense to add a method analogous to get! that accepts a function as the first argument, so that it’s possible to pass something like this:

julia> pop!(a, "x") do 
         sleep(10)
         return 5
       end

Feature requests are better on GitHub.
Even if you are not sure they are s good idea yet, it is best to have them with the others.

1 Like

Why not use this pattern:

a = Dict("x" => 3, "y" => 4)

v = pop!(a, "x", nothing)
if v === nothing
    sleep(10)
    v = 5
end

IMO it would be a bit strange for pop! to accept a function like this since that function doesn’t need access to the object a (e.g. to add a key like the get! version that accepts a function). There is just no reason to move that code block inside pop! when it could just as well be outside.

1 Like

This certainly works, and I guess this would not have type-inference impacts as such because of Union splitting?

That code would fail though on Dict("x" => nothing, "y" => 4), and to truly handle that right without sacrificing performance, I think you basically have to write out something similar to the do-block get! function, so from that angle I think it could be a useful addition to have it for pop! too.

2 Likes