# Broadcast over struct fields?

**URL:** <https://discourse.julialang.org/t/broadcast-over-struct-fields/101307>\
**Category:** General Usage\
**Tags:** broadcast, dictionary, struct\
**Created:** [July 7, 2023, 10:27am UTC](https://discourse.julialang.org/t/broadcast-over-struct-fields/101307 "2023-07-07T10:27:29Z")\
**Posts on this page:** 13\
**Page:** 1

<div class="post-metadata">

**Author:** ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)\
**Post date:** [July 7, 2023, 10:27am UTC](https://discourse.julialang.org/t/broadcast-over-struct-fields/101307/1 "2023-07-07T10:27:29Z")

</div>

For a struct with elements of the same type.  
Is there a way to broadcast operations over the elements, and create a new struct.  
Like you can for a Dictionary.

```julia
struct X
    a::Float64
    b::Float64
    c::Float64
end

x = X(1,2,3)
x.^2 #X(1,4,9) a way to do this ?

d = Dictionary([:a,:b,:c],[1,2,3])
d.^2 #Dictionary([:a,:b,:c],[1,4,9]) like this

```

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [July 7, 2023, 11:05am UTC](https://discourse.julialang.org/t/broadcast-over-struct-fields/101307/2 "2023-07-07T11:05:45Z")

</div>

Couple ways:

```julia
X( ( (getfield.(Ref(x), 1:fieldcount(X) )) .^ 2)...)
X( ( (getfield.(Ref(x), fieldnames(X) )) .^ 2)...)

```

> [@Lincoln\_Hannah](#):
>
> d = Dictionary([:a,:b,:c],[1,2,3])  
> d.^2 #dictionary([:a,:b,:c],[1,4,9]) like this

I’m not familiar with this dictionary type or this broadcasting behavior

---

<div class="post-metadata">

**Author:** ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)\
**Post date:** [July 7, 2023, 11:12am UTC](https://discourse.julialang.org/t/broadcast-over-struct-fields/101307/3 "2023-07-07T11:12:25Z")

</div>

Dictionaries.jl its pretty cool:)

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [July 8, 2023, 8:21pm UTC](https://discourse.julialang.org/t/broadcast-over-struct-fields/101307/4 "2023-07-08T20:21:30Z")

</div>

Do you want the same struct back, but with modified fields? This kind of operation is what so-called “lenses” do, in Julia they are implemented in `Accessors.jl` composably and with a very nice interface.

Your specific example, squaring all properties in `x`:

```julia
julia> using Accessors

julia> x
X(1.0, 2.0, 3.0)

julia> @modify(v -> v^2, x |> Properties())
X(1.0, 4.0, 9.0)

```

---

<div class="post-metadata">

**Author:** ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)\
**Post date:** [July 9, 2023, 11:44pm UTC](https://discourse.julialang.org/t/broadcast-over-struct-fields/101307/5 "2023-07-09T23:44:47Z")

</div>

Thanks.  
I wasn’t aware of `Accessors.jl`  
That’s a nice ability to modify existing or create a new struct.

---

<div class="post-metadata">

**Author:** ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)\
**Post date:** [July 9, 2023, 11:45pm UTC](https://discourse.julialang.org/t/broadcast-over-struct-fields/101307/6 "2023-07-09T23:45:54Z")

</div>

Can the below approach for multiplication be extended to more operations without writing each individually ?

```julia
import Base.*

struct X
    a::Float64
    b::Float64
    c::Float64
end

X(x::Vector)=X(x...)
((;a,b,c)::X)() = [a,b,c]
*(y::Number,x::X) = y * x() |> X
*(x::X,y::Number) = y * x() |> X

julia> 10X(1,2,3)
X(10.0, 20.0, 30.0)

```

---

<div class="post-metadata">

**Author:** ![Benny](https://avatars.discourse-cdn.com/v4/letter/b/49beb7/32.png) [@Benny](https://discourse.julialang.org/u/Benny)\
**Post date:** [July 10, 2023, 12:12am UTC](https://discourse.julialang.org/t/broadcast-over-struct-fields/101307/7 "2023-07-10T00:12:42Z")

</div>

I don’t think it’s possible to write a definition for multiple operations at once because functions aren’t grouped together in any way besides subtyping `Function`, and you are not allowed to annotate a called instance with `Function` in a method definition. If that’s not true or there’s a workaround, someone please correct me.

If the definitions’ expressions share a structure, you can write them in a looped $-interpolated `eval` instead of repeatedly pasting and tweaking code, here’s the [Code Generation](https://docs.julialang.org/en/v1/manual/metaprogramming/#Code-Generation) docs about it.

---

<div class="post-metadata">

**Author:** ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)\
**Post date:** [July 10, 2023, 6:38am UTC](https://discourse.julialang.org/t/broadcast-over-struct-fields/101307/8 "2023-07-10T06:38:10Z")

</div>

> [@Lincoln\_Hannah](#):
>
> I wasn’t aware of `Accessors.jl`  
> That’s a nice ability to modify existing or create a new struct.

`Accessors` always create a new struct: it’s cleaner and often more performant.

> [@Lincoln\_Hannah](#):
>
> Can the below approach for multiplication be extended to more operations without writing each individually ?

If you need basic vector arithmetic, consider using or subtyping StaticArrays.FieldVector.

---

<div class="post-metadata">

**Author:** ![oxinabox](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/oxinabox/32/206603_2.png) [@oxinabox](https://discourse.julialang.org/u/oxinabox)\
**Post date:** [July 10, 2023, 7:04am UTC](https://discourse.julialang.org/t/broadcast-over-struct-fields/101307/9 "2023-07-10T07:04:11Z")

</div>

Depending what your original problem is, you might want to use LabelledArrays  
([GitHub - SciML/LabelledArrays.jl: Arrays which also have a label for each element for easy scientific machine learning (SciML)](https://github.com/SciML/LabelledArrays.jl)) rather than your own struct.

---

<div class="post-metadata">

**Author:** ![Lincoln\_Hannah](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lincoln_hannah/32/19198_2.png) [@Lincoln\_Hannah](https://discourse.julialang.org/u/Lincoln_Hannah)\
**Post date:** [July 10, 2023, 7:50am UTC](https://discourse.julialang.org/t/broadcast-over-struct-fields/101307/10 "2023-07-10T07:50:07Z")

</div>

Legend! - just what I needed

```julia
import StaticArrays.FieldVector

struct Point3D <: FieldVector{3, Float64} 
    x::Float64
    y::Float64
    z::Float64
end

A = Point3D(1,2,3)

A *= 2

A.z

```

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [July 10, 2023, 8:25am UTC](https://discourse.julialang.org/t/broadcast-over-struct-fields/101307/11 "2023-07-10T08:25:06Z")

</div>

This is a “technique” I’ve seen used in some library function to override a group of functions.

```julia
import Base.*, Base.+,Base.-,Base./

struct X
    a::Float64
    b::Float64
    c::Float64
end

X(x::Vector)=X(x...)
((;a,b,c)::X)() = [a,b,c]
julia> for o in (:*,:+,:-,:/)
           @eval $o(y::Number,x::X) = ($o).(y, x()) |> X
           @eval $o(x::X,y::Number) = ($o).(x(), y) |> X
       end

julia> X(12,24,30)/3
X(4.0, 8.0, 10.0)

julia> 1/3*X(12,24,30)
X(4.0, 8.0, 10.0)

julia> X(1,2,3)-3
X(-2.0, -1.0, 0.0)

julia> -3+ X(1,2,3)
X(-2.0, -1.0, 0.0)

julia> 10 - X(1,2,3)
X(9.0, 8.0, 7.0)

```

The main reason for my post (rather than suggesting an alternative solution to those already provided) is to ask for enlightenment on the logic of the expression `((;a,b,c)::X)() = [a,b,c]`

I understand how it is used operationally but I would like to understand the meaning of the syntax (starting from the use of the ‘;’) . Is it a function? what kind of function? or what else is it?

---

<div class="post-metadata">

**Author:** ![Sevi](https://avatars.discourse-cdn.com/v4/letter/s/c67d28/32.png) [@Sevi](https://discourse.julialang.org/u/Sevi)\
**Post date:** [July 10, 2023, 8:45am UTC](https://discourse.julialang.org/t/broadcast-over-struct-fields/101307/12 "2023-07-10T08:45:00Z")

</div>

> [@rocco\_sprmnt21](#):
>
> The main reason for my post (rather than suggesting an alternative solution to those already provided) is to ask for enlightenment on the logic of the expression `((;a,b,c)::X)() = [a,b,c]`
> 
> I understand how it is used operationally but I would like to understand the meaning of the syntax (starting from the use of the ‘;’) . Is it a function? what kind of function? or what else is it?

This looks like “Argument Destructuring” [Functions · The Julia Language](https://docs.julialang.org/en/v1/manual/functions/#man-argument-destructuring)  
Basically just a shorthand for writing out `X.a`, `X.b`, etc. the function should be identical to

```julia
(x::X)() = [x.a,x.b,x.c]

```

And the whole expression is turning `X` into a “callable type”: [Methods · The Julia Language](https://docs.julialang.org/en/v1/manual/methods/#Function-like-objects)

---

<div class="post-metadata">

**Author:** ![rocco\_sprmnt21](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rocco_sprmnt21/32/20127_2.png) [@rocco\_sprmnt21](https://discourse.julialang.org/u/rocco_sprmnt21)\
**Post date:** [July 10, 2023, 9:54am UTC](https://discourse.julialang.org/t/broadcast-over-struct-fields/101307/13 "2023-07-10T09:54:55Z")

</div>

Thank you very much.  
I add some links related to the many ways to define methods of functions.

- [many way to define a function discussion](https://medium.com/@evalparse/there-are-so-many-ways-to-define-a-function-sort-of-in-julia-7821e49373cd)
- [related blog](https://discourse.julialang.org/t/all-ways-to-define-functions-in-julia/45816/40)
