I think you have to use the internals of the Set implementation to have an
O(1) algorithm here. For example, the following seems to work:
import Base: GLOBAL_RNG, isslotfilled, rand
function rand(r::AbstractRNG, s::Set)
isempty(s) && throw(ArgumentError("set must be non-empty"))
n = length(s.dict.slots)
while true
i = rand(r, 1:n)
isslotfilled(s.dict, i) && return s.dict.keys[i]
end
end
rand(s::Set) = rand(Base.GLOBAL_RNG, s)
Something like this should probably be in Base. This could make a good PR
if you want to add a test case, documentation, etc.