# Create a function as a attribute to a struct

**URL:** <https://discourse.julialang.org/t/create-a-function-as-a-attribute-to-a-struct/107817>\
**Category:** General Usage\
**Tags:** metaprogramming, struct, functions\
**Created:** [December 19, 2023, 2:20pm UTC](https://discourse.julialang.org/t/create-a-function-as-a-attribute-to-a-struct/107817 "2023-12-19T14:20:06Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Maddy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maddy/32/210658_2.png) [@Maddy](https://discourse.julialang.org/u/Maddy)\
**Post date:** [December 19, 2023, 2:20pm UTC](https://discourse.julialang.org/t/create-a-function-as-a-attribute-to-a-struct/107817/1 "2023-12-19T14:20:06Z")

</div>

I want to create a clock object with the attributes clock.initial, clock.current and clock.elapsed.

I now want functions like initialize, update, play and pause. Is there a way to have something like

> clock.initialize()

setting clock.initial = time()

> clock.update()

setting clock.current = time() and setting clock.elapsed = clock.current - clock.initial

Or something similar?

```julia
julia> Base.@kwdef mutable struct Mytype
       mystring::String = ""
       f::Function = function sayhello(string=mystring) println("hello " * string) end
       end
Mytype

julia> m = Mytype(mystring = "Aryan")
Mytype("Aryan", var"#sayhello#27"{String}("Aryan"))

julia> m.f()
hello Aryan

```

I was able to do this… add a function to some struct but when trying something like:

```julia
set_init::Function = function something!()
    global initial = time()
end

```

I get an error message saying

`setfield! fields of Types should not be changed.`

How do I achieve what I want?  
(I know I can have initialize(clock::Clock) and have initialize(clock) be called as a separate function which wouldn’t hinder with other predefined functions either or something similar; I’m just exploring the language and the metaprogramming sides of it while working on a cool project)

---

<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:** [December 19, 2023, 2:31pm UTC](https://discourse.julialang.org/t/create-a-function-as-a-attribute-to-a-struct/107817/2 "2023-12-19T14:31:18Z")

</div>

It’s possible, but then you are fighting the language, and its fundamental paradigm. It will probably also hurt performance. If you strongly prefer this style, you may not be happy with Julia.

In idiomatic Julia, you define methods externally to the structs:

```julia
initialize(clock) 
update(clock) 

```

etc.

---

<div class="post-metadata">

**Author:** ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)\
**Post date:** [December 19, 2023, 2:38pm UTC](https://discourse.julialang.org/t/create-a-function-as-a-attribute-to-a-struct/107817/3 "2023-12-19T14:38:23Z")

</div>

The pattern you’re describing is Object Oriented Programming – data and behavior stored together in classes/objects.

Base Julia does not support OOP directly. Instead, it separates data and behavior into structs and functions. So an OOP approach might be

```julia
class Clock():
    init_time
    elapsed_time
    def update(self):
        self.elapsed_time = current_time - self.init_time

clock = Clock()
clock.update()

```

But the Julian way is

```julia
mutable struct Clock
    init_time
    elapsed_time
end

function update(c::Clock)
    c.elapsed_time = current_time - c.init_time
end

clock = Clock()
update(clock)

```

There are packages that will let you emulate OOP in Julia, but the are not necessary because OOP vs multiple dispatch (Julia’s pattern) are both fully sufficient design patterns.

Edit: both of the code snippets above are pseudocode and will not run!

---

<div class="post-metadata">

**Author:** ![mike.ingold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mike.ingold/32/203749_2.png) [@mike.ingold](https://discourse.julialang.org/u/mike.ingold)\
**Post date:** [December 19, 2023, 2:51pm UTC](https://discourse.julialang.org/t/create-a-function-as-a-attribute-to-a-struct/107817/4 "2023-12-19T14:51:28Z")

</div>

Concur with the other responses here. [Multiple dispatch](https://www.youtube.com/watch?v=kc9HwsxE1OY) can be awesome if you give it a chance, but trying to shoe-horn an OOP structure into it just makes the language feel clunky, versus playing to its strengths.

As a rule of thumb, if your function is defined the same for all structs then the function should be defined separately, like the one in @mrufsvold’s example. If you have a case where the function is unique to the specific instance of a struct, then it might make sense to store it in the struct. Essentially, structs are just containers for storing a specific set of information (state), while functions can be used to change that information or act on it.

---

<div class="post-metadata">

**Author:** ![Maddy](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maddy/32/210658_2.png) [@Maddy](https://discourse.julialang.org/u/Maddy)\
**Post date:** [December 19, 2023, 4:00pm UTC](https://discourse.julialang.org/t/create-a-function-as-a-attribute-to-a-struct/107817/5 "2023-12-19T16:00:41Z")

</div>

@DNF @mike.ingold @mrufsvold thank you all for replying.  
I understand that Julia uses multiple dispatch and how nice it is! I just want to play around with the language, understand the extents of metaprogramming and all that.

I was just asking for a way to do it. I know it’s not efficient and all that but CAN we do it in Julia? If yes, how?

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [December 19, 2023, 4:44pm UTC](https://discourse.julialang.org/t/create-a-function-as-a-attribute-to-a-struct/107817/6 "2023-12-19T16:44:20Z")

</div>

```julia
julia> mutable struct Clock
           time::UInt64
           initialize::Function
           update::Function
           play::Function
           pause::Function
           function Clock(time=0x0)
               self::Clock = new(
                   time,
                   ()->println("initialize ", self.time += 1),
                   ()->println("update ", self.time += 1),
                   ()->println("play ", self.time += 1),
                   ()->println("pause ", self.time += 1),
                )
            end
       end

julia> Base.show(io::IO, c::Clock) = print(io, "time = $(c.time)")

julia> c = Clock()
time = 0

julia> c.play()
play 1

julia> c.play()
play 2

julia> c.pause()
pause 3

julia> c.update()
update 4

julia> c.initialize()
initialize 5

```
