# Why Julia returns error on myit .+ 1 in the following code?

**URL:** https://discourse.julialang.org/t/why-julia-returns-error-on-myit-1-in-the-following-code/15021
**Category:** General Usage
**Created:** [September 16, 2018, 4:26pm UTC](https://discourse.julialang.org/t/why-julia-returns-error-on-myit-1-in-the-following-code/15021 "2018-09-16T16:26:41Z")
**Posts on this page:** 9
**Page:** 1

<div class="post-metadata">

### Author: ![AdamR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adamr/32/5109_2.png) [@AdamR](https://discourse.julialang.org/u/AdamR)
#### Post date: [September 16, 2018, 4:26pm UTC](https://discourse.julialang.org/t/why-julia-returns-error-on-myit-1-in-the-following-code/15021/1 "2018-09-16T16:26:41Z")

</div>

I want to learn the broadcasting, and play with the following type, that mimics the UnitRange type:

```julia
julia> struct MyArr 
    m_begin::NTuple{3, Int32}
    m_count::NTuple{3, UInt32}
end

julia> myit=MyArr((2,3,4), (3,2,1))

julia> broadcasted(::typeof(+), ma::MyArr, i::Number) = MyAr(ma.m_begin .+ i, ma.m_count)

julia> myit .+ 1
ERROR: MethodError: no method matching length(::MyArr)
Closest candidates are:
  length(::Core.SimpleVector) at essentials.jl:571
  length(::Base.MethodList) at reflection.jl:728
  length(::Core.MethodTable) at reflection.jl:802
  ...
Stacktrace:
 [1] _similar_for(::UnitRange{Int64}, ::Type, ::MyArr, ::Base.HasLength) at ./array.jl:532
 [2] _collect(::UnitRange{Int64}, ::MyArr, ::Base.HasEltype, ::Base.HasLength) at ./array.jl:563
 [3] collect(::MyArr) at ./array.jl:557
 [4] broadcastable(::MyArr) at ./broadcast.jl:609
 [5] broadcasted(::Function, ::MyArr, ::Int64) at ./broadcast.jl:1139
 [6] top-level scope at none:0

```

I would expect an object `MyArr((3,4,5), (3,2,1))`, not error.

---

<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: [September 16, 2018, 4:28pm UTC](https://discourse.julialang.org/t/why-julia-returns-error-on-myit-1-in-the-following-code/15021/2 "2018-09-16T16:28:15Z")

</div>

```julia
 Base.Broadcast.broadcasted(::typeof(+), ma::MyArr, i::Number) = MyArr(ma.m_begin .+ i, ma.m_count)

```

You need to extend the `broadcasted` function.

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [September 16, 2018, 4:56pm UTC](https://discourse.julialang.org/t/why-julia-returns-error-on-myit-1-in-the-following-code/15021/3 "2018-09-16T16:56:36Z")

</div>

It appears that you are trying to implement a custom array type. You will probably want to subtype AbstractArray in that case and read the section on implementing array types:

[https://docs.julialang.org/en/v1/manual/interfaces](https://docs.julialang.org/en/v1/manual/interfaces)

---

<div class="post-metadata">

### Author: ![AdamR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adamr/32/5109_2.png) [@AdamR](https://discourse.julialang.org/u/AdamR)
#### Post date: [September 16, 2018, 7:21pm UTC](https://discourse.julialang.org/t/why-julia-returns-error-on-myit-1-in-the-following-code/15021/4 "2018-09-16T19:21:36Z")

</div>

Thanks, but it is not my goal - I want to understand how the broadcasting works. That’s why I start with as little help of `Base` as possible and proceed from that.

If I subtype from an `AbstractArray` (and implement its informal interface) I will get too much help from the Base Julia library, and lose a sense what can be customized and how.

In particular, I would like to understand how to implement proper broadcasting of arrays held in GPU memory (to help to implement the `TensorFlow.jl` module).

I also want to learn if (and how) I can implement broadcasting over arrays that are indexed base 0 (like in C++).

Do you know of someone who has both knowledge and time to share knowledge of an (informal) interface of the AbstractRange type family? I can write the documentation in return.

---

<div class="post-metadata">

### Author: ![StefanKarpinski](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stefankarpinski/32/24_2.png) [@StefanKarpinski](https://discourse.julialang.org/u/StefanKarpinski)
#### Post date: [September 16, 2018, 7:36pm UTC](https://discourse.julialang.org/t/why-julia-returns-error-on-myit-1-in-the-following-code/15021/5 "2018-09-16T19:36:41Z")

</div>

There’s also a section in there on broadcasting specifically:

[https://docs.julialang.org/en/v1/manual/interfaces/#man-interfaces-broadcasting-1](https://docs.julialang.org/en/v1/manual/interfaces/#man-interfaces-broadcasting-1)

There was also a blog post about this back when the new broadcasting infrastructure landed in 0.7:

> **[Extensible broadcast fusion](https://julialang.org/blog/2018/05/extensible-broadcast-fusion/)**
>
> Extensible broadcast fusion | Julia version 0.7 brings with it an exciting new feature: the ability to customize broadcast...

---

<div class="post-metadata">

### Author: ![AdamR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adamr/32/5109_2.png) [@AdamR](https://discourse.julialang.org/u/AdamR)
#### Post date: [September 16, 2018, 11:20pm UTC](https://discourse.julialang.org/t/why-julia-returns-error-on-myit-1-in-the-following-code/15021/6 "2018-09-16T23:20:57Z")

</div>

Thank you! I did not know about the last link. I still have some questions, though.

1. Is BroadcastStyle only a trait, or does it have an interface? Or is it a function? Is `Base.BroadcastStyle` the constructor for this type, or is it syntactically unrelated function? The manual says “BroadcastStyle is an abstract type and trait-function. (…)”.

2. What exactly is the difference between `materialize` and `copy[to!]`? In the source I can find a call to the `instantiate` function that inserts `axes`. Why does it do that? What is the use case that takes advantage of this indirection?

3. What exactly is the relationship between `IndexStyle` and `BroadcastStyle`? Is the only thing that relates them is the default implementation of the `copy[to!]` (or maybe `materialize`?) functions?

4. Do you know about (and is there any possibility to have) any other `IndexStyle` than `IndexLinear` and `IndexCartesian`?

5. Why do I need to specialize `copy` when there is a `copyto!`? Isn’t the `copy` always inferior w.r.t. performance?

6. Am I right to assume that the `similar(::Broadcasted{MyBroadcastStyle}, ::Type{ElType})` function is only called by the default implementation of the `copy(::Broadcasted)`? How can I ensure, that only `copyto!(dest, ::Broadcasted)` is called?

7. Broadcast style and IndexStyle are related to each other, and so does the AbstractRange type family. Yet these types’ interface is not (yet) documented… and I suspect their implementations do play an important role in the performance of the broadcast mechanism.

---

<div class="post-metadata">

### Author: ![AdamR](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/adamr/32/5109_2.png) [@AdamR](https://discourse.julialang.org/u/AdamR)
#### Post date: [September 16, 2018, 11:28pm UTC](https://discourse.julialang.org/t/why-julia-returns-error-on-myit-1-in-the-following-code/15021/7 "2018-09-16T23:28:42Z")

</div>

Here are my sources of information, so far:

1. The manual (specifically the chapters about arrays, interfaces and broadcasting)
2. The talk by Matt Bauman on the JuliaCon 2018 in London ([An introduction to high performance custom arrays | Matt Bauman - YouTube](https://www.youtube.com/watch?v=jS9eouMJf_Y)(
3. Matt Bauman’s post in the discourse: [How to customize the new broadcasting infrastructure in v0.7 - #4 by mbauman](https://discourse.julialang.org/t/how-to-customize-the-new-broadcasting-infrastructure-in-v0-7/11322/4)
4. [JuliaLang.org](http://JuliaLang.org) blog entry about the broadcast function in 0.7 ([Extensible broadcast fusion](https://julialang.org/blog/2018/05/extensible-broadcast-fusion))

I almost never read the source code. I still hope to get a higher level explanation from the devs. :-)…

---

<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: [September 17, 2018, 8:59am UTC](https://discourse.julialang.org/t/why-julia-returns-error-on-myit-1-in-the-following-code/15021/8 "2018-09-17T08:59:44Z")

</div>

> [@AdamR](#):
>
> I almost never read the source code.

You are missing a lot then. `Base` has a lot of great examples.

---

<div class="post-metadata">

### Author: ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)
#### Post date: [September 17, 2018, 6:22pm UTC](https://discourse.julialang.org/t/why-julia-returns-error-on-myit-1-in-the-following-code/15021/9 "2018-09-17T18:22:52Z")

</div>

> [@AdamR](#):
>
> 1. Is BroadcastStyle only a trait, or does it have an interface? Or is it a function? Is `Base.BroadcastStyle` the constructor for this type, or is it syntactically unrelated function? The manual says “BroadcastStyle is an abstract type and trait-function. (…)”.

It is indeed all of the above. It’s an abstract type. As you cannot construct abstract types, its “constructor” function is what you call (and/or implement) to determine which style a given object has. Its “interface” (if you want to call it that) is extremely minimal — if you define your own subtype of `BroadcastStyle` you need to “hook it up” by implementing that abstract constructor to return your subtype as appropriate.

> [@AdamR](#):
>
> 1. What exactly is the difference between `materialize` and `copy[to!]` ? In the source I can find a call to the `instantiate` function that inserts `axes` . Why does it do that? What is the use case that takes advantage of this indirection?

There are a few reasons for this:

- `materialize` provides a stable entry point for the parser. It’s the front end, and you really should not need to override this. It’s a really simple function: it `instantiate`s the Broadcasted and then `copy[to!]`s it.
- Now why do we have `instantiate`? Walking through all the arguments, checking their shapes, and computing the resulting outermost shape can be expensive… and we don’t want to have to pay that cost every time someone calls `axes(bc)` — that’s a simple function that is typically considered free or cheap. So `Broadcasted` objects have an optional third field — the cached axes. So why don’t we just always do this in `copy[to!]`? Well, then it’d mean that every custom implementation would need to deal with this. Further, some implementations just want to opt out of the axis caching behavior because computing the result _is indeed cheap!_ Examples here include tuples and 0-dimensional arrays, both of which have their own style.
- There’s another reason for instantiate, though: in the case of broadcasted assignment (`.=`), the LHS of the expression _doesn’t appear_ in the `Broadcasted` object but it _completely determines_ the resulting axes! So `instantiate` takes an optional second argument, which is the shape that the `Broadcasted` object must evaluate to.

> [@AdamR](#):
>
> 1. What exactly is the relationship between `IndexStyle` and `BroadcastStyle` ? Is the only thing that relates them is the default implementation of the `copy[to!]` (or maybe `materialize` ?) functions?

It’s completely unrelated. Iterating over `eachindex(bc)` will always return an index that indexes at the full dimensionality of the resulting shape.

> [@AdamR](#):
>
> 1. Do you know about (and is there any possibility to have) any other `IndexStyle` than `IndexLinear` and `IndexCartesian` ?

Again, completely unrelated from broadcasting and broadcast styles. I experimented with adding my own index style back around 0.4/0.5 timeframe with the un-registered and un-supported [RaggedArrays.jl](https://github.com/mbauman/RaggedArrays.jl). You can see what it required back then, but this isn’t something that Julia itself officially supports doing, so doing so will require you to dig into the source code and see what’s required there.

> [@AdamR](#):
>
> 1. Why do I need to specialize `copy` when there is a `copyto!` ? Isn’t the `copy` always inferior w.r.t. performance?

Julia isn’t always able to construct the appropriate resulting container in order to defer to `copyto!`. Indeed, it can only do that when it can divine out the return type of the broadcasted operation. So you cannot count on `copy` simply calling `similar` and then `copyto!`. That’s why you should implement `copy`. Unfortunately, this is a hard thing to implement in the type-unstable case because we cannot rely on getting a good answer from inference. We need to incrementally pull out each element, make sure it can fit, and if it doesn’t fit, copy all the incremental progress to a new, wider container, and then keep going.

> [@AdamR](#):
>
> 1. Am I right to assume that the `similar(::Broadcasted{MyBroadcastStyle}, ::Type{ElType})` function is only called by the default implementation of the `copy(::Broadcasted)` ? How can I ensure, that only `copyto!(dest, ::Broadcasted)` is called?

I don’t fully understand these questions. We don’t (yet) have an officially supported first class way to construct `Broadcasted`s, so I suppose that for now whatever method `copy(::Broadcasted{MyBroadcastStyle})` hits will be the only one to have a chance to call `similar`, but that might change in the future. But it really shouldn’t matter — you need to return appropriate storage regardless of the caller.

> [@AdamR](#):
>
> 1. Broadcast style and IndexStyle are related to each other, and so does the AbstractRange type family. Yet these types’ interface is not (yet) documented… and I suspect their implementations do play an important role in the performance of the broadcast mechanism.

I really don’t think that you need to fully understand `IndexStyle` and `AbstractRange` here. Their implementations are not relevant for broadcasting and implementing custom broadcasting.
