# Broadcasting with functions of structs

**URL:** <https://discourse.julialang.org/t/broadcasting-with-functions-of-structs/88975>\
**Category:** General Usage\
**Tags:** question, broadcast, struct\
**Created:** [October 19, 2022, 5:17pm UTC](https://discourse.julialang.org/t/broadcasting-with-functions-of-structs/88975 "2022-10-19T17:17:16Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![AstroBarker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/astrobarker/32/15170_2.png) [@AstroBarker](https://discourse.julialang.org/u/AstroBarker)\
**Post date:** [October 19, 2022, 5:17pm UTC](https://discourse.julialang.org/t/broadcasting-with-functions-of-structs/88975/1 "2022-10-19T17:17:16Z")

</div>

Hey folks,  
I have a struct with some large arrays that need to be updated in place. The updates are not quite trivial and are in a function. What I would like to be able to do is something of the sort `@. updatefunc( my_struct )` This seems to fail with an error `ERROR: LoadError: MethodError: no method matching length(::my_struct)`. I have a minimally working example below. What is the reason for this behavior and is there a way to do what I would like to do (efficiently)?

```julia
struct test
  x::Vector{Int}
end

function update( var::test )
  var.x += 1
end

var = test( ones(Int, 5) )

@. var.x += 1
@show var

@. update( var ) # This call fails

```

---

<div class="post-metadata">

**Author:** ![StevenWhitaker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevenwhitaker/32/9749_2.png) [@StevenWhitaker](https://discourse.julialang.org/u/StevenWhitaker)\
**Post date:** [October 19, 2022, 5:26pm UTC](https://discourse.julialang.org/t/broadcasting-with-functions-of-structs/88975/2 "2022-10-19T17:26:07Z")

</div>

Why can’t you do

```julia
function update!(var::test)
    @. var.x += 1
end

update!(var)

```

Why do you want to broadcast over the struct (as opposed to broadcasting over the arrays contained in the struct)?

---

<div class="post-metadata">

**Author:** ![LaurentPlagne](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/laurentplagne/32/10103_2.png) [@LaurentPlagne](https://discourse.julialang.org/u/LaurentPlagne)\
**Post date:** [October 19, 2022, 5:26pm UTC](https://discourse.julialang.org/t/broadcasting-with-functions-of-structs/88975/3 "2022-10-19T17:26:10Z")

</div>

It looks that you want to do

```julia
var.x .+=1

```

in your code you broadcast update on var which is not a collection  
oops cross posting

---

<div class="post-metadata">

**Author:** ![AstroBarker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/astrobarker/32/15170_2.png) [@AstroBarker](https://discourse.julialang.org/u/AstroBarker)\
**Post date:** [October 19, 2022, 5:34pm UTC](https://discourse.julialang.org/t/broadcasting-with-functions-of-structs/88975/4 "2022-10-19T17:34:28Z")

</div>

Okay yeah this is easier. What about a slightly separate case, where an array needs to be updated in place by a quantity computed from a struct? e.g.,

```julia
struct test
  x::Int
end

# Compute a generally complex quantity from members of a struct
function update( var::test )
  return var.x
end

var = test( 1 )

myarray = zeros(5)
@. myarray += update( var ) # fails

```

---

<div class="post-metadata">

**Author:** ![Jeff\_Emanuel](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jeff_emanuel/32/15440_2.png) [@Jeff\_Emanuel](https://discourse.julialang.org/u/Jeff_Emanuel)\
**Post date:** [October 19, 2022, 5:41pm UTC](https://discourse.julialang.org/t/broadcasting-with-functions-of-structs/88975/5 "2022-10-19T17:41:14Z")

</div>

> [@AstroBarker](#):
>
> `@. myarray += update( var )`

The `@.` will transform `update(var)` to `update.(var)`, which is not what you want. Just put the `.` on the `+=` where you want it: `myarray .+= update(var)`

---

<div class="post-metadata">

**Author:** ![AstroBarker](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/astrobarker/32/15170_2.png) [@AstroBarker](https://discourse.julialang.org/u/AstroBarker)\
**Post date:** [October 19, 2022, 5:46pm UTC](https://discourse.julialang.org/t/broadcasting-with-functions-of-structs/88975/6 "2022-10-19T17:46:39Z")

</div>

Ah I didn’t notice that `@.` was putting the `.` _everywhere_. Thanks!

---

<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:** [October 19, 2022, 5:52pm UTC](https://discourse.julialang.org/t/broadcasting-with-functions-of-structs/88975/7 "2022-10-19T17:52:47Z")

</div>

> [@AstroBarker](#):
>
> `@. myarray += update( var ) # fails`

It also works if you define:

```julia
Base.broadcastable(x::test) = Ref(x)

```

which you should often do for new data types if you want to treat them as “scalars” (rather than containers) for broadcasting.

You can alternatively write `myarray .+= update(var)` explicitly as noted above, or “opt-out” the `update` function from `@.` with `@. myarray += $update(var)`.

I’ve been hoping to make this more explicit in the manual: [many types should define broadcastable(o) = Ref(o) by stevengj · Pull Request #44093 · JuliaLang/julia · GitHub](https://github.com/JuliaLang/julia/pull/44093)
