# Strange dot-syntax result

**URL:** <https://discourse.julialang.org/t/strange-dot-syntax-result/47840>\
**Category:** New to Julia\
**Created:** [October 6, 2020, 7:00am UTC](https://discourse.julialang.org/t/strange-dot-syntax-result/47840 "2020-10-06T07:00:26Z")\
**Posts on this page:** 18\
**Page:** 1

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [October 6, 2020, 7:00am UTC](https://discourse.julialang.org/t/strange-dot-syntax-result/47840/1 "2020-10-06T07:00:26Z")

</div>

the following is strange to me:

```julia
julia> a = [11, 12, 13, 14];
julia> a[2:4] .= view(a, 1:3);
julia> a
4-element Array{Int64,1}:
 11
 11
 12
 13

```

which, in my understanding, the above assignment should be equivalent to:

```julia
julia> a = [11, 12, 13, 14];

julia> for i in 1:3
           a[i + 1] = a[i]
       end

julia> a
4-element Array{Int64,1}:
 11
 11
 11
 11

```

that said, `[11, 11, 12, 13]` should be the result of `a[4:-1:2].=view(a,3:-1:1)`, but **not** from `a[2:4].=view(a,1:3)` !

help please. thanks.

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [October 6, 2020, 7:31am UTC](https://discourse.julialang.org/t/strange-dot-syntax-result/47840/2 "2020-10-06T07:31:28Z")

</div>

~~I think your assumption, that broadcasting is acting like a loop, is wrong. If this would be the case, it wouldn’t be very efficient and would be just a convenience to write shorter code, which it isn’t. You may try to benchmark it and I predict, broadcasting is faster.~~  
This is what your assignment looks like:

```julia
 julia> Meta.@lower a[2:4] .= view(a, 1:3)
:($(Expr(:thunk, CodeInfo(
    @ none within `top-level scope'
1 ─ %1 = 2:4
│ %2 = Base.dotview(a, %1)
│ %3 = 1:3
│ %4 = view(a, %3)
│ %5 = Base.broadcasted(Base.identity, %4)
│ %6 = Base.materialize!(%2, %5)
└── return %6
))))

```

~~There is no loop and~~ my guess is, that materialize! does some efficient memory moving in a _single_ step.

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [October 6, 2020, 7:46am UTC](https://discourse.julialang.org/t/strange-dot-syntax-result/47840/3 "2020-10-06T07:46:56Z")

</div>

> [@oheil](#):
>
> _single_ step

how??? There’s no magic, no matter how there must be a **sequence** of computations.

noted that the RHS of `a[2:4].=view(a,1:3)` is a `SubArray`. That means **no** copy of a[1:3] is generated and being maintained. So, after the content at the address of `a[2]` was overwritten by that in `a[1]`, the next operation (that puts the content pointed by `a[2]` into the address of `a[3]`) should be side-effected. I really not understand how the `.=` assignment works??? 😵

---

<div class="post-metadata">

**Author:** ![paulmelis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paulmelis/32/35063_2.png) [@paulmelis](https://discourse.julialang.org/u/paulmelis)\
**Post date:** [October 6, 2020, 8:00am UTC](https://discourse.julialang.org/t/strange-dot-syntax-result/47840/4 "2020-10-06T08:00:18Z")

</div>

Perhaps the loop is executed in reverse (i.e. with decreasing indices). In that case a[4] gets overwritten first with 13, etc.

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [October 6, 2020, 8:01am UTC](https://discourse.julialang.org/t/strange-dot-syntax-result/47840/5 "2020-10-06T08:01:17Z")

</div>

> [@oheil](#):
>
> There is no loop and my guess is, that materialize! does some efficient memory moving in a _single_ step.

using `Debugger.@enter` to check, **there is indeed a loop** called inside `copyto!()` (inside `materialize!()`).

Now I realize the actual problem is: using `view()` in manner like `a[2:4].=view(a,1:3)` _ **still generates a copy and allocates memory** _!!!

```julia-auto
julia> a = randn(20);

julia> @btime a[2:20] .= view(a, 1:19);
  705.296 ns (6 allocations: 416 bytes)

julia> @btime a[2:20] .= a[1:19];
  608.807 ns (4 allocations: 320 bytes)

```

that means using `view()` is actually **slower** and **costs more memory**??!!

compared to:

```julia-auto
julia> b = randn(20);

julia> @btime a[2:20] .= view(b, 1:19);
  618.799 ns (4 allocations: 128 bytes)

julia> @btime a[2:20] .= b[1:19];
  611.046 ns (4 allocations: 320 bytes)

```

now, _without read from and writing into the same vector_, `view()` can **save** some memory.

---

<div class="post-metadata">

**Author:** ![paulmelis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paulmelis/32/35063_2.png) [@paulmelis](https://discourse.julialang.org/u/paulmelis)\
**Post date:** [October 6, 2020, 8:04am UTC](https://discourse.julialang.org/t/strange-dot-syntax-result/47840/6 "2020-10-06T08:04:00Z")

</div>

The source and destination memory regions overlap so making a copy before executing the statement wouldn’t be unreasonable (to avoid undefined behaviour). Perhaps there is a remark on this in the docs, although I can’t immediately find it.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [October 6, 2020, 8:12am UTC](https://discourse.julialang.org/t/strange-dot-syntax-result/47840/7 "2020-10-06T08:12:25Z")

</div>

Which julia version are you using? Your example works fine for me:

```julia
julia> a = [11, 12, 13, 14];

julia> a[2:4] .= view(a, 1:3)
3-element view(::Array{Int64,1}, 2:4) with eltype Int64:
 11
 12
 13

julia> a
4-element Array{Int64,1}:
 11
 11
 12
 13

julia> versioninfo()
Julia Version 1.5.2
Commit 539f3ce943 (2020-09-23 23:17 UTC)
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: Intel(R) Core(TM) i7-6600U CPU @ 2.60GHz
  WORD_SIZE: 64
  LIBM: libopenlibm
  LLVM: libLLVM-9.0.1 (ORCJIT, skylake)
Environment:
  JULIA_NUM_THREADS = 4

```

---

<div class="post-metadata">

**Author:** ![paulmelis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paulmelis/32/35063_2.png) [@paulmelis](https://discourse.julialang.org/u/paulmelis)\
**Post date:** [October 6, 2020, 8:14am UTC](https://discourse.julialang.org/t/strange-dot-syntax-result/47840/8 "2020-10-06T08:14:19Z")

</div>

> [@Sukera](#):
>
> Your example works fine for me:

I think the issue here is what “fine” means exactly 😉 The OP was expecting certain order-dependent behaviour, but found the results to be different.

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [October 6, 2020, 8:21am UTC](https://discourse.julialang.org/t/strange-dot-syntax-result/47840/9 "2020-10-06T08:21:11Z")

</div>

> [@tomtom](#):
>
> how??? There’s no magic, no matter how there must be a **sequence** of computations.

Of course, in the end, there must be a loop, to copy memory. But it is not the equivalence to looping over the array/view elements. The lowered code implies, that the source and destination is prepared into %2(destination in array) and %5(source view) before looping and moving the data from source to destination.

And than the problems seems to be the call to Base.identity:

```julia
julia> Base.identity.(view(a, 1:3))
3-element Array{Int64,1}:
 11
 12
 13

```

which now is an Array and not a view anymore.

And indeed, using view uses an additional allocation:

```julia
julia> @btime a[2:4] .= a[1:3]
  323.909 ns (5 allocations: 240 bytes)

julia> @btime a[2:4] .= view(a, 1:3)
  370.588 ns (6 allocations: 352 bytes)

```

All in all, yes, thats interesting and I wait now for those which more indepth knowledge 😉

---

<div class="post-metadata">

**Author:** ![bkamins](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/bkamins/32/208538_2.png) [@bkamins](https://discourse.julialang.org/u/bkamins)\
**Post date:** [October 6, 2020, 8:21am UTC](https://discourse.julialang.org/t/strange-dot-syntax-result/47840/10 "2020-10-06T08:21:11Z")

</div>

This behavior is expected. Broadcasting does unaliasing before making an operation. Other than that broadcast is just a loop (but making sure to produce a correct type and shape of the output and making sure looping is efficient).

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [October 6, 2020, 8:21am UTC](https://discourse.julialang.org/t/strange-dot-syntax-result/47840/11 "2020-10-06T08:21:57Z")

</div>

> [@bkamins](#):
>
> Broadcasting does unaliasing before making an operation.

Is this the call to `Base.identity` ?

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [October 6, 2020, 8:24am UTC](https://discourse.julialang.org/t/strange-dot-syntax-result/47840/12 "2020-10-06T08:24:40Z")

</div>

For the interested, the unaliasing is happening in `copyto!`:

```julia
In copyto!(dest, src) at abstractarray.jl:837
 837 function copyto!(dest::AbstractArray, src::AbstractArray)
 838 isempty(src) && return dest
 839 src′ = unalias(dest, src)
>840 copyto_unaliased!(IndexStyle(dest), dest, IndexStyle(src′), src′)
 841 end

```

This is both expected and necessary.

---

<div class="post-metadata">

**Author:** ![tomtom](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tomtom/32/5106_2.png) [@tomtom](https://discourse.julialang.org/u/tomtom)\
**Post date:** [October 6, 2020, 8:26am UTC](https://discourse.julialang.org/t/strange-dot-syntax-result/47840/13 "2020-10-06T08:26:10Z")

</div>

> [@paulmelis](#):
>
> The source and destination memory regions overlap so making a copy before executing the statement wouldn’t be unreasonable (to avoid undefined behaviour).

this coping behavior is “too smart” in my point of view…

so, the optimal way to deal with this situation should be:

```julia
julia> a = 1.0:100.0;
julia> a_buffer = randn(99); # pre-allocation

julia> @btime (a_buffer .= view(a, 1:99);
               a[2:100] .= a_buffer;); # best !
  1.366 μs (6 allocations: 160 bytes)

julia> @btime a[2:100] .= view(a, 1:99); # worst !
  883.761 ns (6 allocations: 1.05 KiB)

julia> @btime a[2:100] .= a[1:99]; # bad
  743.496 ns (4 allocations: 976 bytes)

```

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [October 6, 2020, 8:29am UTC](https://discourse.julialang.org/t/strange-dot-syntax-result/47840/14 "2020-10-06T08:29:33Z")

</div>

> [@tomtom](#):
>
> this coping behavior is “too smart” in my point of view…

I disagree. Syntax wise `a[2:4] .= view(a, 1:3);` means “put whatever is on the RHS at the time of writing this into the LHS”. Whether that is done with a loop or a memory copy of whole chunks of memory is an implementation detail. The syntax, however, is unambigous. If you want to fill your array (or a slice of it) with a specific value, use `fill!` (or `fill!(view(a, 2:4), ...`) instead.

---

<div class="post-metadata">

**Author:** ![paulmelis](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/paulmelis/32/35063_2.png) [@paulmelis](https://discourse.julialang.org/u/paulmelis)\
**Post date:** [October 6, 2020, 8:32am UTC](https://discourse.julialang.org/t/strange-dot-syntax-result/47840/15 "2020-10-06T08:32:25Z")

</div>

> [@tomtom](#):
>
> > [@paulmelis](#):
> >
> > The source and destination memory regions overlap so making a copy before executing the statement wouldn’t be unreasonable (to avoid undefined behaviour).
> 
> this coping behavior is “too smart” in my point of view…

Well, the alternative would be that the end result would depend on the exact order in which the copy (or other operation) is done. Which isn’t a very nice way to specify a language. It would also inhibit certain optimizations the compiler can do, which is what is happening here.

---

<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:** [October 6, 2020, 8:32am UTC](https://discourse.julialang.org/t/strange-dot-syntax-result/47840/16 "2020-10-06T08:32:27Z")

</div>

> [@tomtom](#):
>
> so, the optimal way to deal with this situation should be

… using a loop.

AFAIK the traversal order of broadcasting is undefined on purpose (to allow future optimizations), so you may not want to rely on it even if it appears to work. This could change in some future version of Julia.

---

<div class="post-metadata">

**Author:** ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)\
**Post date:** [October 6, 2020, 8:38am UTC](https://discourse.julialang.org/t/strange-dot-syntax-result/47840/17 "2020-10-06T08:38:09Z")

</div>

My understanding is that these points are all wrong 😉

> [@oheil](#):
>
> I think your assumption, that broadcasting is acting like a loop, is wrong.

It is like a loop, aside from, apparently un-aliasing.

> [@oheil](#):
>
> If this would be the case, it wouldn’t be very efficient

Yes, it would. Loops are fast in Julia.

> [@oheil](#):
>
> would be just a convenience to write shorter code, which it isn’t.

I believe that’s what it is.

> [@oheil](#):
>
> You may try to benchmark it and I predict, broadcasting is faster.

Without testing, it think they should be the same, or the loop would be faster.

---

<div class="post-metadata">

**Author:** ![oheil](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oheil/32/220745_2.png) [@oheil](https://discourse.julialang.org/u/oheil)\
**Post date:** [October 6, 2020, 8:53am UTC](https://discourse.julialang.org/t/strange-dot-syntax-result/47840/18 "2020-10-06T08:53:29Z")

</div>

True. I edited above wrong statements to not confuse future readers.
