# Dynamically mutate type parameter

**URL:** https://discourse.julialang.org/t/dynamically-mutate-type-parameter/41811
**Category:** General Usage
**Tags:** type
**Created:** [June 21, 2020, 12:05pm UTC](https://discourse.julialang.org/t/dynamically-mutate-type-parameter/41811 "2020-06-21T12:05:57Z")
**Posts on this page:** 7
**Page:** 1

<div class="post-metadata">

### Author: ![D\_A](https://avatars.discourse-cdn.com/v4/letter/d/8dc957/32.png) [@D\_A](https://discourse.julialang.org/u/D_A)
#### Post date: [June 21, 2020, 12:05pm UTC](https://discourse.julialang.org/t/dynamically-mutate-type-parameter/41811/1 "2020-06-21T12:05:57Z")

</div>

Hello,

I would like to know if there is a way to mutate the type parameter of an object during runtime (dynamically).

MWE:

```julia
mutable struct Text{Format<:Union{Integer, AbstractString}} # For MWE, in reality it is like Union{AbstractString, HTMLDocument, XMLDocument}…
    content::Format
    test_field::Union{Integer, AbstractString}
end

function clean(text::Text{<:AbstractString})
    println("I am a string")
end

function clean(text::Text{<:Integer}) # For MWE, in reality it is like HTMLDocument…
    println("I am an integer")
end

text1 = Text("content", 1) # Text{String}("content", "string")
clean(text1) # I am a string
text2 = Text(55, 1) # Text{Int64}(55, 1)
clean(text2) # I am an integer
text1.test_field = "string" # No problem.
text1.content = 55 # ERROR: MethodError: Cannot `convert` an object of type Int64 to an object of type String

```

In order to avoid to create a new Text object in a recursive function which cleans for example an HTML document (sometimes nodes, sometimes raw text (with source and language type parameters, not shown in this MWE), I prefer to mutate, if possible, the type parameter.  
Is it possible (I did not find the syntax to do so), and if not, is there a nice workaround except recreate a Text object which takes the cleaned new content of previous Text object?

Sincerely

---

<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: [June 21, 2020, 12:29pm UTC](https://discourse.julialang.org/t/dynamically-mutate-type-parameter/41811/2 "2020-06-21T12:29:36Z")

</div>

> [@D\_A](#):
>
> Is it possible (I did not find the syntax to do so), and if not, is there a nice workaround except recreate a Text object which takes the cleaned new content of previous Text object?

It is not possible.

If you don’t care about performance (which is implicitly assumed if you are doing something like this), why don’t you just leave the type of `content` as either `Any` or some `Union` (it should not matter if it contains abstract types), and modify it when needed? Eg

```julia
mutable struct Text
   content
   test_field::Union{Integer, AbstractString}
end

text1.content = 55 

```

etc.

---

<div class="post-metadata">

### Author: ![D\_A](https://avatars.discourse-cdn.com/v4/letter/d/8dc957/32.png) [@D\_A](https://discourse.julialang.org/u/D_A)
#### Post date: [June 21, 2020, 12:39pm UTC](https://discourse.julialang.org/t/dynamically-mutate-type-parameter/41811/3 "2020-06-21T12:39:08Z")

</div>

Hum, about performance, I must admit I am not sure why you say it is implicitly assumed that I don’t care about it…

If I remove the type parameter, as in your example, the multiple dispatch will not be involved and I will need several tests in different places for nested functions (`if text.content isa AbstractString`, `if text.content isa HTMLNode`, etc.), because the methods depend on the type of content.

---

<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: [June 21, 2020, 1:01pm UTC](https://discourse.julialang.org/t/dynamically-mutate-type-parameter/41811/4 "2020-06-21T13:01:05Z")

</div>

> [@D\_A](#):
>
> I must admit I am not sure why you say it is implicitly assumed that I don’t care about it…

Because the way Julia works. You get optimized code when concrete types (or small unions of them) are known at compile time. If you want to change this during runtime, you have to live with suboptimal performance (which may still be fine, of course, and this may not be a practical concern).

You may want to read through

[https://docs.julialang.org/en/v1/manual/performance-tips/](https://docs.julialang.org/en/v1/manual/performance-tips/)

> [@D\_A](#):
>
> the multiple dispatch will not be involved and I will need several tests in different places for nested functions

Make a wrapper function like

```julia
f(text) = _f(text.content, text.test_field)
_f(::Integer, ::Integer) = :both_are_integers

```

etc.

---

<div class="post-metadata">

### Author: ![marius311](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/marius311/32/3953_2.png) [@marius311](https://discourse.julialang.org/u/marius311)
#### Post date: [June 21, 2020, 8:04pm UTC](https://discourse.julialang.org/t/dynamically-mutate-type-parameter/41811/5 "2020-06-21T20:04:28Z")

</div>

Another option is to use [Setfield](https://github.com/jw3126/Setfield.jl),

```julia
using Setfield
@set! text1.content = 55 # works

```

Note this doesn’t mutate the original object, but creates a new one and binds it to `text1`, but is maybe good enough for what you need.

---

<div class="post-metadata">

### Author: ![D\_A](https://avatars.discourse-cdn.com/v4/letter/d/8dc957/32.png) [@D\_A](https://discourse.julialang.org/u/D_A)
#### Post date: [June 21, 2020, 10:08pm UTC](https://discourse.julialang.org/t/dynamically-mutate-type-parameter/41811/6 "2020-06-21T22:08:16Z")

</div>

For performances, I tried with abstract and concrete types for my custom type fields and because it was always faster (and with less allocations) with abstract ones, I kept them, even if it was not expected…

Thank you for this module, I think I will one day try both solutions.

---

<div class="post-metadata">

### Author: ![D\_A](https://avatars.discourse-cdn.com/v4/letter/d/8dc957/32.png) [@D\_A](https://discourse.julialang.org/u/D_A)
#### Post date: [June 22, 2020, 10:31am UTC](https://discourse.julialang.org/t/dynamically-mutate-type-parameter/41811/7 "2020-06-22T10:31:20Z")

</div>

@Tamas_Papp OK, after having a bug I just solved because I miscleaned my code after my small abstract versus concrete benchmark, I just remembered why I have chosen to use by default abstract types for my custom type fields and function arguments: to avoid things like `Union{Dict, OrderedDict}`, `Union{String, SubString, Regex}`, `Union{String, SubString, SubstitutionString}`, etc. I could take habit to make these unions, but you said “small unions”, from when does it start to be too big?

There is another reason I used custom abstract types in my case (not shown in the MWE): to avoid mutually circular type declarations (see this [issue](https://github.com/JuliaLang/julia/issues/269)), because I have 3 custom types (like book, chapter, tale, etc.) all subtypes of respective abstract types (themselves subtypes of one general custom abstract type when I need to refer to all of them in a recursive way, and all of them parameterized), because all children have link field to parent and parents all have a link field vector of children.

So, for former case, I could use union of concrete types, but for latter case, Maybe I can’t avoid abstract types…

I must mention that I almost never work with integers, floats, number matrices, etc. (I never wrote `Float` in Julia yet), but mainly only with Unicode characters, strings, regexes, etc.
