# Is there a reason a \`MersenneTwister\` value is not broadcastable?

**URL:** <https://discourse.julialang.org/t/is-there-a-reason-a-mersennetwister-value-is-not-broadcastable/20774>\
**Category:** General Usage\
**Tags:** broadcast\
**Created:** [February 14, 2019, 4:53am UTC](https://discourse.julialang.org/t/is-there-a-reason-a-mersennetwister-value-is-not-broadcastable/20774 "2019-02-14T04:53:47Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![fjarri](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fjarri/32/630_2.png) [@fjarri](https://discourse.julialang.org/u/fjarri)\
**Post date:** [February 14, 2019, 4:53am UTC](https://discourse.julialang.org/t/is-there-a-reason-a-mersennetwister-value-is-not-broadcastable/20774/1 "2019-02-14T04:53:47Z")

</div>

I have multiple functions with the same pattern:

```
foo(rng::AbstractRNG, x::ValueType) = ...

```

which are commonly applied to arrays as

```
foo.(rng::AbstractRNG, a::Array{ValueType}) 

```

which is supposed to be equivalent to, essentially

```
reshape([foo(rng, x) for x in a], size(a))

```

`rng` here is a `MersenneTwister`-type value, but I guess the question applies to any other kind of RNG. For just the code above, I get an error

```
MethodError: no method matching length(::MersenneTwister)

```

In order to make it work I have to wrap a `MersenneTwister` in my own type and define `length()` and `iterate()` for it.

Is there some caveat I’m missing which is the reason these methods are not defined in `Random`?

In fact, since I need this kind of “broadcastability” for many other types, I have the following abstract type defined:

```
abstract type BroadcastableSingleton end
Base.length(::BroadcastableSingleton) = 1
Base.iterate(x::BroadcastableSingleton) = (x, nothing)
Base.iterate(x::BroadcastableSingleton, state) = nothing

```

This reduces boilerplate code, but won’t be too clear if there are already some complicated abstract type hierarchies in place. I wonder if there is a better way to do it? (Can’t help but miss Haskell’s data classes here)

---

<div class="post-metadata">

**Author:** ![rdeits](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rdeits/32/286_2.png) [@rdeits](https://discourse.julialang.org/u/rdeits)\
**Post date:** [February 14, 2019, 5:01am UTC](https://discourse.julialang.org/t/is-there-a-reason-a-mersennetwister-value-is-not-broadcastable/20774/2 "2019-02-14T05:01:10Z")

</div>

A `Ref` is already designed to do exactly what your custom `BroadcastableSingleton` does. Wrapping something in a `Ref` will scalarize it in a broadcasted computation:

```julia
foo.(Ref(rng), a)

```

---

<div class="post-metadata">

**Author:** ![fjarri](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fjarri/32/630_2.png) [@fjarri](https://discourse.julialang.org/u/fjarri)\
**Post date:** [February 14, 2019, 5:05am UTC](https://discourse.julialang.org/t/is-there-a-reason-a-mersennetwister-value-is-not-broadcastable/20774/3 "2019-02-14T05:05:04Z")

</div>

Thanks, it does work that way, but:

1. This call pattern is quite common in my code, and is present in the public API as well. It won’t look good to ask a user to wrap every value that needs this in `Ref`.

2. Neither the name nor the docstring for `Ref` give any indication that it may be used for this purpose. It seems more like an undocumented feature that can change at any time.

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [February 14, 2019, 5:57am UTC](https://discourse.julialang.org/t/is-there-a-reason-a-mersennetwister-value-is-not-broadcastable/20774/4 "2019-02-14T05:57:34Z")

</div>

You are mistaken — it is the standard API, and happens to be well-documented.

[https://docs.julialang.org/en/v1/manual/arrays/#Broadcasting-1](https://docs.julialang.org/en/v1/manual/arrays/#Broadcasting-1)  
[https://docs.julialang.org/en/v1/base/arrays/#Base.Broadcast.broadcast](https://docs.julialang.org/en/v1/base/arrays/#Base.Broadcast.broadcast)

---

<div class="post-metadata">

**Author:** ![fjarri](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fjarri/32/630_2.png) [@fjarri](https://discourse.julialang.org/u/fjarri)\
**Post date:** [February 14, 2019, 6:19am UTC](https://discourse.julialang.org/t/is-there-a-reason-a-mersennetwister-value-is-not-broadcastable/20774/5 "2019-02-14T06:19:24Z")

</div>

I would disagree.

1. ‘treats any argument that is not an array … as a “scalar”’ in the first link is incorrect; the second link correctly states that everything but certain predetermined types are iterated over.

2. Moreover, in the first link it says ‘and treats any argument that is not an array, tuple or Ref (except for Ptr) as a “scalar”’, but the `Ref` arguments _are_ treated as scalars.

3. The second link seems more consistent with the actual behaviour. But it only mentions `Ref` as one of the types that can be broadcasted over by default. There is no indication that it is _supposed_ to be used to create singletons (even though it _does_ create them). Neither, again, there is any indication of that in the docstring of `Ref` itself.

4. I don’t need all these low-level effects `Ref` provides (“This type is guaranteed to point to valid, Julia-allocated memory of the correct type. The underlying data is protected from freeing by the garbage collector as long as the Ref itself is referenced.” and so on). I only need a broadcastable singleton. So in addition to not being the intended usage, it seems like a serious overkill.

5. My point about this being an unnecessary boilerplate (exaggerated by the fact that from the user’s standpoint it seems like some kind of black magic) is still valid.

6. _Edit:_ One more thing. `typeof(Ref(x)) != typeof(x)`, so I would have to explicitly ask for `Ref` objects in the function signature.

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [February 14, 2019, 7:28am UTC](https://discourse.julialang.org/t/is-there-a-reason-a-mersennetwister-value-is-not-broadcastable/20774/6 "2019-02-14T07:28:37Z")

</div>

Why don’t you just fix the docs a little? The problem seems to be that the docs for Ref are incorrect and not lightweight enough in the introductory paragraphs, not that Ref is not lightweight enough.

And Ref arguments are not treated as scalars. In broadcast Ref is unwrapped and its contents passed to the method. A scalar is itself passed to the method unaltered. You don’t have to ask for Ref in the method signature because it _isn’t_ treated as a scalar.

---

<div class="post-metadata">

**Author:** ![fjarri](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fjarri/32/630_2.png) [@fjarri](https://discourse.julialang.org/u/fjarri)\
**Post date:** [February 14, 2019, 8:43am UTC](https://discourse.julialang.org/t/is-there-a-reason-a-mersennetwister-value-is-not-broadcastable/20774/7 "2019-02-14T08:43:53Z")

</div>

> [@Raf](#):
>
> Why don’t you just fix the docs a little? The problem seems to be that the docs for Ref are incorrect and not lightweight enough in the introductory paragraphs, not that Ref is not lightweight enough.

They are not incorrect. I actually don’t have anything against the docs for `Ref`, they seem to contain exactly what they need to contain. It could perhaps have been stated that it is an iterable, but that seems like an implementation detail to me, not related to its purpose.

On the other hand, [Single- and multi-dimensional Arrays · The Julia Language](https://docs.julialang.org/en/v1/manual/arrays/#Broadcasting-1) seems to contain some incorrect statements (not related to `Ref`). Although I wouldn’t mind if it was correct though, that is if every non-iterable object _was_ treated as a scalar.

> [@Raf](#):
>
> And Ref arguments are not treated as scalars. In broadcast Ref is unwrapped and its contents passed to the method. A scalar is itself passed to the method unaltered.

Yes, I agree, that is technically correct. `Ref`’s contents is treated as a scalar.

> [@Raf](#):
>
> You don’t have to ask for Ref in the method signature because it _isn’t_ treated as a scalar.

Yes, I agree with that as well.

Nevertheless, I still feel like I failed to put the issue across. Instead of `Ref(x)` I could have used `(x,)`, `[x]`, `Set(x)` or whatever else built-in iterable container to create a singleton (in fact, I’m surprised that `Ref` was proposed instead of a tuple - what makes it a better choice? At least with a tuple you can guess that the author of the code wanted to make an iterable). But all of these are clutches. They create noise in the code, they are unintuitive. I think that behaving like a singleton in broadcasting is a natural behaviour for anything that is not an iterable.

---

<div class="post-metadata">

**Author:** ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)\
**Post date:** [February 14, 2019, 9:06am UTC](https://discourse.julialang.org/t/is-there-a-reason-a-mersennetwister-value-is-not-broadcastable/20774/8 "2019-02-14T09:06:41Z")

</div>

Sure, I meant either of those docs, some improvements connecting Ref and broadcast. But I also agree that it seems arbitrary which wrapper to use. `(,)` does seem more intuitive.

Treating everything as an iterable by default could probably be achieved with:

```julia
length(x) = 1

```

but there is probably a reason that’s a bad idea, broadcast has a few more moving parts than this…

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [February 14, 2019, 9:12am UTC](https://discourse.julialang.org/t/is-there-a-reason-a-mersennetwister-value-is-not-broadcastable/20774/9 "2019-02-14T09:12:59Z")

</div>

> [@fjarri](#):
>
> I’m surprised that `Ref` was proposed instead of a tuple - what makes it a better choice?

```julia
julia> (1,) .+ 2
(3,)

julia> Ref(1) .+ 2
3

```

---

<div class="post-metadata">

**Author:** ![fjarri](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fjarri/32/630_2.png) [@fjarri](https://discourse.julialang.org/u/fjarri)\
**Post date:** [February 14, 2019, 9:14am UTC](https://discourse.julialang.org/t/is-there-a-reason-a-mersennetwister-value-is-not-broadcastable/20774/10 "2019-02-14T09:14:30Z")

</div>

You’d have to define `iterate` as well. Alternatively, you could broadcast as singleton anything that _doesn’t_ define `length()`, but I suspect it would affect performance (reflection like that is probably too slow).

---

<div class="post-metadata">

**Author:** ![fjarri](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fjarri/32/630_2.png) [@fjarri](https://discourse.julialang.org/u/fjarri)\
**Post date:** [February 14, 2019, 9:16am UTC](https://discourse.julialang.org/t/is-there-a-reason-a-mersennetwister-value-is-not-broadcastable/20774/11 "2019-02-14T09:16:09Z")

</div>

I see. I feel like we’re getting offtopic, but this behaviour of `Ref` seems weird to me. It’s a container like a tuple, why isn’t it preserved?

_Edit:_ Actually, sorry, I see that there’s a difference, but I don’t see why it makes `Ref` a better choice.

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [February 14, 2019, 9:23am UTC](https://discourse.julialang.org/t/is-there-a-reason-a-mersennetwister-value-is-not-broadcastable/20774/12 "2019-02-14T09:23:04Z")

</div>

```julia
julia> axes((1,))
(Base.OneTo(1),)

julia> axes(Ref(1))
()

```

Basically, a tuple is one dimensional while a `Ref` is zero dimensional.

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [February 14, 2019, 12:37pm UTC](https://discourse.julialang.org/t/is-there-a-reason-a-mersennetwister-value-is-not-broadcastable/20774/13 "2019-02-14T12:37:18Z")

</div>

As mentioned by others, `broadcast` defaults to treating its arguments as collections. Types can opt in to being treated as “scalars” by defining `Base.broadcastable(x::MyType) = Ref(x)`, or you can opt-in at the call site with an explicit `Ref`.

That being said, I agree that RNG types should opt-in to being treated as scalars. Fortunately, it is a one-line non-breaking change to add this to any existing type:

[https://github.com/JuliaLang/julia/issues/31071](https://github.com/JuliaLang/julia/issues/31071)

---

<div class="post-metadata">

**Author:** ![fjarri](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fjarri/32/630_2.png) [@fjarri](https://discourse.julialang.org/u/fjarri)\
**Post date:** [February 14, 2019, 1:00pm UTC](https://discourse.julialang.org/t/is-there-a-reason-a-mersennetwister-value-is-not-broadcastable/20774/14 "2019-02-14T13:00:05Z")

</div>

> [@stevengj](#):
>
> `Base.broadcastable(x::AbstractRNG)`

Thanks for that, it seems like a better way to customise broadcasting behaviour than overriding `length` and `iterate`.

I’m still a bit weirded out by using `Ref` in this context though. Namely, I don’t understand why it having zero dimensions makes it a better choice; and, more importantly, why `Ref` _incidentally_ having zero dimensions (which is kind of implied by `Ref objects are dereferenced (loaded or stored) with [].` in its docstring, but seems like an implementation detail, because it can easily get a custom `getindex()` in future) means that it should be used here. Would it really be clear for anyone with some Julia programming experience why `Ref` is used in that line?

---

<div class="post-metadata">

**Author:** ![Tamas\_Papp](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tamas_papp/32/25949_2.png) [@Tamas\_Papp](https://discourse.julialang.org/u/Tamas_Papp)\
**Post date:** [February 14, 2019, 1:15pm UTC](https://discourse.julialang.org/t/is-there-a-reason-a-mersennetwister-value-is-not-broadcastable/20774/15 "2019-02-14T13:15:03Z")

</div>

> [@fjarri](#):
>
> in its docstring, but seems like an implementation detail

I think that historically `Ref` precedes the current broadcasting implementation, and was kind of hijacked for the purpose. It is innocuous, but I agree that it can be confusing. See

> <https://github.com/JuliaLang/julia/issues/18379>
>
> I found myself needing a \`Scalar\` type for broadcasting purposes, to trick \`broa…dcast\` into \_not\_ trying to broadcast something, even though it is a matrix. An initial (bad) implementation is \[here\](https://github.com/TotalVerb/Scalars.jl).
> 
> With https://github.com/JuliaLang/julia/pull/16986 close to merging, I wonder if such a feature would be desirable in \`Base\`.

---

<div class="post-metadata">

**Author:** ![tkf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tkf/32/17635_2.png) [@tkf](https://discourse.julialang.org/u/tkf)\
**Post date:** [February 14, 2019, 11:37pm UTC](https://discourse.julialang.org/t/is-there-a-reason-a-mersennetwister-value-is-not-broadcastable/20774/16 "2019-02-14T23:37:52Z")

</div>

It’s still an off topic, but let me mention that a syntax `&x` for making `x` a scalar in broadcast is proposed:

[https://github.com/JuliaLang/julia/issues/27563](https://github.com/JuliaLang/julia/issues/27563)

If this happens I think `Ref` just becomes a lower-level detail for most of users.

---

<div class="post-metadata">

**Author:** ![fjarri](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fjarri/32/630_2.png) [@fjarri](https://discourse.julialang.org/u/fjarri)\
**Post date:** [February 14, 2019, 11:51pm UTC](https://discourse.julialang.org/t/is-there-a-reason-a-mersennetwister-value-is-not-broadcastable/20774/17 "2019-02-14T23:51:42Z")

</div>

Honestly, I don’t really see a qualitative difference between it and `Ref`. It’s a contraction, which is nice, but `&` is just as low-level. It is still associated with “reference”, not with “scalar”. My point (which I think people keep missing) was that I, or a user of my library, _shouldn’t have to do anything_ to mark that something that is not an iterable (and the compiler knows that) should be treated as a scalar. @stevengj above agreed that RNG objects should be treated as scalars; why doesn’t it apply to any other non-iterable? Is there some conceptual problem with that, or is it just impossible to implement at this point without breaking existing code?

---

<div class="post-metadata">

**Author:** ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)\
**Post date:** [February 15, 2019, 1:54am UTC](https://discourse.julialang.org/t/is-there-a-reason-a-mersennetwister-value-is-not-broadcastable/20774/18 "2019-02-15T01:54:44Z")

</div>

> [@fjarri](#):
>
> why doesn’t it apply to any other non-iterable? Is there some conceptual problem with that, or is it just impossible to implement at this point without breaking existing code?

It’s not currently possible to identify “non-iterable” reliably at compile-time, because “iterable” is not a type.

There was a basic design choice that needed to be made for `broadcast`: should it default to treating arguments as scalars or as collections, with the opposite behavior being opt-in? Initially, it defaulted to treating things as scalars, but it was changed to default to collections after a long discussion ([https://github.com/JuliaLang/julia/issues/18618](https://github.com/JuliaLang/julia/issues/18618) and [https://github.com/JuliaLang/julia/pull/26435](https://github.com/JuliaLang/julia/pull/26435)). At this point, the default is set in stone — it cannot be changed in 1.x without breaking backwards compatibility.

There were reasonable arguments on both sides. One advantage of defaulting to a collection is that when a type like `AbstractRNG` arises where this is the wrong choice, we can update it in 1.x without breaking anything, which is not true of the opposite default.
