# Question about functors and closures (I think 😅), with an example, but really a general Q

**URL:** https://discourse.julialang.org/t/question-about-functors-and-closures-i-think-with-an-example-but-really-a-general-q/88758
**Category:** New to Julia
**Tags:** closure, functors
**Created:** [October 14, 2022, 10:28pm UTC](https://discourse.julialang.org/t/question-about-functors-and-closures-i-think-with-an-example-but-really-a-general-q/88758 "2022-10-14T22:28:28Z")
**Posts on this page:** 1
**Showing post:** 20

<div class="post-metadata">

### Author: ![suavesito](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/suavesito/32/34386_2.png) [@suavesito](https://discourse.julialang.org/u/suavesito)
#### Post date: [October 16, 2022, 9:10am UTC](https://discourse.julialang.org/t/question-about-functors-and-closures-i-think-with-an-example-but-really-a-general-q/88758/20 "2022-10-16T09:10:20Z")

</div>

> [@fins](#):
>
> ```julia
> next(r::MaskedRNG) = next(r.rng) & r.mask # r.rng!
> next(r::Union{RNG, MaskedRNG}, m::Integer) = next(r.rng) & m # r.rng!
> 
> ```

I think is enough with the next

```julia
next(r::MaskedRNG) = next(r.rng) & r.mask
next(r::Union{RNG, MaskedRNG}, m::Integer) = next(r) & m

```

Because the second `next(r)` will be dispatched correctly (without the `m` argument) to the first two.

Actually, I would go event further and write everything as follows, to avoid needing to write overly specific types.

```julia
mutable struct RNG <: AbstractRNG
    state::UInt64
end
# the default constructor promote to Integer by default

RNG() = RNG(time_ns())

struct MaskedRNG <: AbstractRNG
    rng::RNG
    mask::UInt64
end

MaskedRNG(nbits) = MaskedRNG(RNG(), (1 << UInt8(nbits)) - 1)
# MaskedRNG(seed::Integer, nbits) = MaskedRNG(RNG(seed), (1 << UInt8(nbits)) - 1) # error when nbits = 64
# this next version allows setting high nbits using negatives, like -8 to mask to 0xff00000000000000
# in benchmarking it takes the same time as the above
MaskedRNG(seed::Integer, nbits) = MaskedRNG(RNG(seed), ~UInt64(0) >> ifelse(0 < abs(nbits) <= 64, sign(nbits)*64 - nbits, 64))

next(r::RNG) = (r.state = _rng(r.state))
next(r::MaskedRNG) = next(r.rng) & r.mask
next(r::Union{RNG, MaskedRNG}, m::Integer) = next(r) & m # this will dispatch correctly

function _rng(x::UInt64)
    x ⊻= (x << 21)
    x ⊻= (x >>> 35)
    x ⊻= (x << 4)
    return x % UInt64
end

```

---

_[View the full topic](https://discourse.julialang.org/t/question-about-functors-and-closures-i-think-with-an-example-but-really-a-general-q/88758)._
