JuliaLang/julia

FR: Random sampler for `Iterators.ProductIterator`

Open

#43,266 opened on Nov 30, 2021

View on GitHub
 (4 comments) (2 reactions) (0 assignees)Julia (5,773 forks)batch import
featuregood first issuerandomness

Repository metrics

Stars
 (48,709 stars)
PR merge metrics
 (Avg merge 20d 6h) (157 merged PRs in 30d)

Description

Feature

I love Iterators.product, and it would be great if I could call rand on it directly:

julia> Iterators.product([1,2],[3,4,5]) |> rand
(1, 5)

Currently, this does not work, because no sampler is defined:

julia> Iterators.product([1,2],[3,4,5]) |> rand

ERROR: ArgumentError: Sampler for this object is not defined
Stacktrace:
 [1] Random.Sampler(#unused#::Type{Random.MersenneTwister}, sp::Random.SamplerTrivial{Base.Iterators.ProductIterator{Tuple{Vector{Int64}, Vector{Int64}}}, Tuple{Int64, Int64}}, #unused#::Val{1})
   @ Random /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.6/Random/src/Random.jl:145
 [2] Random.Sampler(rng::Random.MersenneTwister, x::Random.SamplerTrivial{Base.Iterators.ProductIterator{Tuple{Vector{Int64}, Vector{Int64}}}, Tuple{Int64, Int64}}, r::Val{1})
   @ Random /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.6/Random/src/Random.jl:139
 [3] rand(rng::Random.MersenneTwister, X::Random.SamplerTrivial{Base.Iterators.ProductIterator{Tuple{Vector{Int64}, Vector{Int64}}}, Tuple{Int64, Int64}}) (repeats 2 times)
   @ Random /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.6/Random/src/Random.jl:253
 [4] rand(X::Base.Iterators.ProductIterator{Tuple{Vector{Int64}, Vector{Int64}}})
   @ Random /Users/julia/buildbot/worker/package_macos64/build/usr/share/julia/stdlib/v1.6/Random/src/Random.jl:258

Implementation

A simple implementation would be this:

function Random.rand(
    rng::Random.AbstractRNG,
    iterator::Random.SamplerTrivial{Base.Iterators.ProductIterator{T}},
) where {T}
    r(x) = rand(rng, x)
    r.(iterator[].iterators)
end

Would this PR be welcome? Where in the codebase should the implementation go? Should it be a method of Random.Sampler?

Contributor guide