# Is this an expected behavior of rand.()?

**URL:** <https://discourse.julialang.org/t/is-this-an-expected-behavior-of-rand/97735>\
**Category:** General Usage\
**Tags:** random\
**Created:** [April 21, 2023, 9:36am UTC](https://discourse.julialang.org/t/is-this-an-expected-behavior-of-rand/97735 "2023-04-21T09:36:10Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![ovt](https://avatars.discourse-cdn.com/v4/letter/o/87869e/32.png) [@ovt](https://discourse.julialang.org/u/ovt)\
**Post date:** [April 21, 2023, 9:36am UTC](https://discourse.julialang.org/t/is-this-an-expected-behavior-of-rand/97735/1 "2023-04-21T09:36:10Z")

</div>

```julia
julia> A = zeros(3,3)
3×3 Matrix{Float64}:
 0.0 0.0 0.0
 0.0 0.0 0.0
 0.0 0.0 0.0

julia> true ? A .= rand.() : nothing
3×3 Matrix{Float64}:
 0.191487 0.0617435 0.279438
 0.47524 0.467929 0.45603
 0.212515 0.21998 0.51552

julia> A.= true ? rand.() : 0
3×3 Matrix{Float64}:
 0.30043 0.30043 0.30043
 0.30043 0.30043 0.30043
 0.30043 0.30043 0.30043

```

The behavior of `A.= true ? rand.() : 0` is equivalent to `A.= true ? rand() : 0`.

---

<div class="post-metadata">

**Author:** ![fatteneder](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fatteneder/32/33991_2.png) [@fatteneder](https://discourse.julialang.org/u/fatteneder)\
**Post date:** [April 21, 2023, 10:08am UTC](https://discourse.julialang.org/t/is-this-an-expected-behavior-of-rand/97735/2 "2023-04-21T10:08:51Z")

</div>

I would say yes, because they can be translated to

```julia
if true
  A .= rand.()
else
  nothing
end

```

and

```julia
for i = 1:length(A)
   if true
      A[i] = rand.()
   else
      A[i] = 0
   end
end

```

Note that `rand.()` alone gives only one random number, unless it is used in a broadcast.

---

<div class="post-metadata">

**Author:** ![Jollywatt](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jollywatt/32/202198_2.png) [@Jollywatt](https://discourse.julialang.org/u/Jollywatt)\
**Post date:** [April 21, 2023, 11:00am UTC](https://discourse.julialang.org/t/is-this-an-expected-behavior-of-rand/97735/3 "2023-04-21T11:00:55Z")

</div>

I agree with @fatteneder, it is expected. To explain why, your code is an example of how syntactic loop fusion does not fuse across non-broadcasted calls (in this case, ternary `⋯ ? ⋯ : ⋯` is not broadcasted) although it is an admittedly opaque example.

Here’s an excellent blog post on [syntactic loop fusion](https://julialang.org/blog/2017/01/moredots/#syntactic_loop_fusion_in_julia). In brief:

Syntactic loop fusion transforms an expression like `A .= f.(g.(h.(x)))` into a single loop:

```julia
for i in eachindex(x)
    A[i] = f(g(h(x[i])))
end

```

But loops are not fused across non-broadcasted barriers, so `A .= f.(g(h.(x)))` is equivalent to:

```julia
temp1 = h.(x) # one loop
temp2 = g(temp1) # no loop
A .= f.(temp2) # another loop

```

In your case, it might help to rephrase it as it as:

```julia
ifelse(true, A .= rand.(), nothing)
# vs
A .= ifelse(true, rand.(), 0)

```

This makes it clearer why the second example results in two separate loops (the first loop is just `rand.()` generating a single number). The first example _is_ one loop, where `rand` is broadcasted to the shape `A`, producing different numbers…

---

<div class="post-metadata">

**Author:** ![ovt](https://avatars.discourse-cdn.com/v4/letter/o/87869e/32.png) [@ovt](https://discourse.julialang.org/u/ovt)\
**Post date:** [April 21, 2023, 11:48am UTC](https://discourse.julialang.org/t/is-this-an-expected-behavior-of-rand/97735/4 "2023-04-21T11:48:24Z")

</div>

I see, thanks for the clear explanation.

---

<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:** [April 21, 2023, 1:23pm UTC](https://discourse.julialang.org/t/is-this-an-expected-behavior-of-rand/97735/5 "2023-04-21T13:23:52Z")

</div>

> [@Jollywatt](#):
>
> `ifelse(true, A .= rand.(), nothing)`

Careful: `ifelse(false, A .= rand.(), nothing)` will still overwrite `A`, because `ifelse` is a function (not special syntax like `if` or `?`) that evaluates all arguments before deciding which one to return.
