# Immutable composite type?

**URL:** https://discourse.julialang.org/t/immutable-composite-type/15406
**Category:** General Usage
**Created:** [September 24, 2018, 1:49am UTC](https://discourse.julialang.org/t/immutable-composite-type/15406 "2018-09-24T01:49:16Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![LeoK987](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leok987/32/4880_2.png) [@LeoK987](https://discourse.julialang.org/u/LeoK987)
#### Post date: [September 24, 2018, 1:49am UTC](https://discourse.julialang.org/t/immutable-composite-type/15406/1 "2018-09-24T01:49:16Z")

</div>

I have a composite type with many fields. The instance of it is essentially unchanged after initialization. So it could be declared as a immutable struct. But since it has many fields, I currently declared it as a mutable struct so that I use a constructor that looks more elegant like:

```julia
function MyStruct(some values, etc)
    this = new()
    this.field1 = such such
    this.field2 = such such
    ....
    this.fieldN = such such
    this
end

```

If I make it immutable, the way to code the constructor as I know would be much less elegant (or is it not?), like this:

```julia
function MyStruct(some values, etc)
    field1 = such such
    field2 = such such
    ....
    fieldN = such such
    new(field1, field2, ..., fieldN)
end

```

The “new” statement can be quite messy with strict care of ordering of arguments and spanning to many lines.

So is there better way to define an immutable type? Or, is it worthwhile to make such large composite type immutable?

---

<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: [September 24, 2018, 2:12am UTC](https://discourse.julialang.org/t/immutable-composite-type/15406/2 "2018-09-24T02:12:49Z")

</div>

Check out [https://github.com/mauro3/Parameters.jl](https://github.com/mauro3/Parameters.jl)

---

<div class="post-metadata">

### Author: ![LeoK987](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leok987/32/4880_2.png) [@LeoK987](https://discourse.julialang.org/u/LeoK987)
#### Post date: [September 24, 2018, 2:37am UTC](https://discourse.julialang.org/t/immutable-composite-type/15406/3 "2018-09-24T02:37:57Z")

</div>

Parameters seems to only deal with primitive types. There are arrays and strings in my structs.

---

<div class="post-metadata">

### Author: ![djsegal](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/djsegal/32/13752_2.png) [@djsegal](https://discourse.julialang.org/u/djsegal)
#### Post date: [September 24, 2018, 2:51am UTC](https://discourse.julialang.org/t/immutable-composite-type/15406/4 "2018-09-24T02:51:05Z")

</div>

> [@LeoK987](#):
>
> Parameters seems to only deal with primitive types

I don’t think thats true?

This file includes: vectors, dicts, SymEngine symbols, etc.

> <https://github.com/djsegal/Fussy.jl/blob/master/src/structs/reactor.jl>

---

<div class="post-metadata">

### Author: ![LeoK987](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leok987/32/4880_2.png) [@LeoK987](https://discourse.julialang.org/u/LeoK987)
#### Post date: [September 24, 2018, 3:14am UTC](https://discourse.julialang.org/t/immutable-composite-type/15406/5 "2018-09-24T03:14:01Z")

</div>

Thanks for pointing that out and showing an example of using Parameters. But since I don’t have default values, what benefits does Parameters provide over regular mutable struct?

---

<div class="post-metadata">

### Author: ![pmarg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pmarg/32/936_2.png) [@pmarg](https://discourse.julialang.org/u/pmarg)
#### Post date: [September 24, 2018, 4:39am UTC](https://discourse.julialang.org/t/immutable-composite-type/15406/6 "2018-09-24T04:39:43Z")

</div>

Does Parameters.jl still have a performance penalty in Julia 0.7?

---

<div class="post-metadata">

### Author: ![LeoK987](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leok987/32/4880_2.png) [@LeoK987](https://discourse.julialang.org/u/LeoK987)
#### Post date: [September 24, 2018, 4:44am UTC](https://discourse.julialang.org/t/immutable-composite-type/15406/7 "2018-09-24T04:44:38Z")

</div>

@pmarg, please, I am not convinced on using Parameters. Can you post your question elsewhere?

---

<div class="post-metadata">

### Author: ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)
#### Post date: [September 24, 2018, 5:34am UTC](https://discourse.julialang.org/t/immutable-composite-type/15406/8 "2018-09-24T05:34:23Z")

</div>

> [@LeoK987](#):
>
> would be much less elegant

The `new` code has a close number of characters to the other code. One problem in both codes however is replicating the word `field` or replicating the word `this`. This problem can be overcome with Paramters.jl and a twist.

If you define your `such such` in functions, then you can have a somewhat elegant code that looks like this:

```julia
julia> using Parameters

julia> f1() = 1; f2() = 2;

julia> @with_kw struct MyType
           a::Int = f1()
           b::Int = f2()
       end
MyType

julia> MyType(1, 2)
MyType
  a: Int64 1
  b: Int64 2

julia> MyType()
MyType
  a: Int64 1
  b: Int64 2

julia> MyType(a = 1, b = 2)
MyType
  a: Int64 1
  b: Int64 2

```

Note that you have access to the keyword constructor and the positional argument constructor. Also the default values are optional.

Given the above keyword constructor you can then define another external constructor that looks more like the function you want:

```julia
function MyStruct(some values, etc)
    MyStruct(field1 = such such, 
             field2 = such such, 
    	     fieldN = such such)
end

```

If `such such` is small, this will look elegant, otherwise your original attempt will probably be more elegant. Note that you have more flexibility now in wrapping `such such` in functions or macros since we are outside the type definition, so you can pass on `some values` and `etc` to another function to do a computation and come back with the result. Or you can contract some code in `such such` in a macro as such:

```julia
macro suchsuch1
	return esc(quote
	        such such
		such such
	end)
end

```

and the same thing for the macros `suchsuch2` and `suchsuch3`. Then at call site just use:

```julia
function MyStruct(some values, etc)
    MyStruct(field1 = @suchsuch1, 
	     field2 = @suchsuch2, 
             fieldN = @suchsuch3)
end

```

The macro approach means that you don’t have to pass any arguments.

The same macro approach can be used with the positional argument constructor or perhaps even simpler, straight into your inner constructor. This is probably the solution you were looking for, but since I wrote all the above anyways, I am commenting the whole thing anyways!

---

<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 24, 2018, 5:47am UTC](https://discourse.julialang.org/t/immutable-composite-type/15406/9 "2018-09-24T05:47:17Z")

</div>

> [@LeoK987](#):
>
> I have a composite type with many fields.

Generally, I try to avoid composite types with many (say 7+) fields. I don’t know the specifics of your problem, but perhaps you can try to organize them into smaller composite types, or use fields of type `SVector` (if some of them have a natural integer indexing), `NamedTuple`, etc.

---

<div class="post-metadata">

### Author: ![pmarg](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/pmarg/32/936_2.png) [@pmarg](https://discourse.julialang.org/u/pmarg)
#### Post date: [September 24, 2018, 6:06am UTC](https://discourse.julialang.org/t/immutable-composite-type/15406/10 "2018-09-24T06:06:59Z")

</div>

This is not a personal question because I don’t use or consider using `Parameters.jl`. But since someone suggested this package, I thought it would be helpful to discuss performance issues because it might not be appropriate for your problem.

---

<div class="post-metadata">

### Author: ![Raf](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/raf/32/3383_2.png) [@Raf](https://discourse.julialang.org/u/Raf)
#### Post date: [September 24, 2018, 6:24am UTC](https://discourse.julialang.org/t/immutable-composite-type/15406/11 "2018-09-24T06:24:39Z")

</div>

While everyone is talking about Parameters.jl I may as well add that I wrote this recently:  
[https://github.com/rafaqz/Defaults.jl](https://github.com/rafaqz/Defaults.jl)

It’s kind of a minimalist version of Parameters.jl, with easy override of field values and the ability to add default constructors to 3rd party structs. It’s 46 lines, with a single 180 line dependency. But not in the registry yet, and probably not for ages at the rate I’m actually registering my packages right now…

---

<div class="post-metadata">

### Author: ![mauro3](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mauro3/32/292_2.png) [@mauro3](https://discourse.julialang.org/u/mauro3)
#### Post date: [September 24, 2018, 7:30am UTC](https://discourse.julialang.org/t/immutable-composite-type/15406/12 "2018-09-24T07:30:44Z")

</div>

We should not derail this topic, so I give you a brief answer. If that this not sufficient, then you should open a new topic (and ping me). As of Julia 0.7, keyword arguments are fast, although not quite as fast as normal ones and this shows in Parameters.jl:

```julia
julia> using Parameters, BenchmarkTools                                           
                                                                                  
julia> @with_kw struct B; a::Int = 1; b::Float64 = 1; end
B

julia> @btime B(); # as fast as possible                                                          
  1.972 ns (0 allocations: 0 bytes)                                               
                                                                                  
julia> @btime B(a=2); # slight hit                                                     
  4.477 ns (0 allocations: 0 bytes)                                               
                                                                                  
julia> @btime B(2,3); # positional is also as fast as possible                                                       
  1.965 ns (0 allocations: 0 bytes)                                               

```

---

<div class="post-metadata">

### Author: ![LeoK987](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leok987/32/4880_2.png) [@LeoK987](https://discourse.julialang.org/u/LeoK987)
#### Post date: [September 24, 2018, 8:24am UTC](https://discourse.julialang.org/t/immutable-composite-type/15406/13 "2018-09-24T08:24:29Z")

</div>

@Tamas_Papp, can you please explain about what you were saying?

---

<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 24, 2018, 8:29am UTC](https://discourse.julialang.org/t/immutable-composite-type/15406/14 "2018-09-24T08:29:22Z")

</div>

I am not sure which part is unclear.

---

<div class="post-metadata">

### Author: ![LeoK987](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leok987/32/4880_2.png) [@LeoK987](https://discourse.julialang.org/u/LeoK987)
#### Post date: [September 24, 2018, 8:32am UTC](https://discourse.julialang.org/t/immutable-composite-type/15406/15 "2018-09-24T08:32:48Z")

</div>

Why you would avoid composite type in preference of SVector or NameTuple? And what are the problems of composite types with many fields?

---

<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 24, 2018, 8:46am UTC](https://discourse.julialang.org/t/immutable-composite-type/15406/16 "2018-09-24T08:46:36Z")

</div>

I would not _avoid_ a composite type, but combine it with the latter two. Eg instead of

```julia
struct BigProblem
    α
    β
    γ
    κ₁
    κ₂
end

#vs

struct BigProblem
    greeks::NamedTuple{(α, β, γ)}
    κs::SVector{2} # in a real life problem I would parametrize <:Real, too
end

```

Of course the above example is inane, one would need to know about the problem domain to organize things conceptually.

---

<div class="post-metadata">

### Author: ![LeoK987](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leok987/32/4880_2.png) [@LeoK987](https://discourse.julialang.org/u/LeoK987)
#### Post date: [September 24, 2018, 8:49am UTC](https://discourse.julialang.org/t/immutable-composite-type/15406/17 "2018-09-24T08:49:11Z")

</div>

What problem are you solving by doing this?

---

<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 24, 2018, 9:00am UTC](https://discourse.julialang.org/t/immutable-composite-type/15406/18 "2018-09-24T09:00:52Z")

</div>

As I said above, having too many fields in a `struct`. I think of that as code smell.

---

<div class="post-metadata">

### Author: ![LeoK987](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/leok987/32/4880_2.png) [@LeoK987](https://discourse.julialang.org/u/LeoK987)
#### Post date: [September 24, 2018, 9:07am UTC](https://discourse.julialang.org/t/immutable-composite-type/15406/19 "2018-09-24T09:07:40Z")

</div>

Thanks for answering.

But what’s in your mind that says many fields in a composite type pose a problem?

---

<div class="post-metadata">

### Author: ![jw3126](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jw3126/32/3086_2.png) [@jw3126](https://discourse.julialang.org/u/jw3126)
#### Post date: [September 24, 2018, 2:00pm UTC](https://discourse.julialang.org/t/immutable-composite-type/15406/20 "2018-09-24T14:00:44Z")

</div>

I consider it as a code smell too. It usually leads to less generic and more cumbersome and buggy code.  
For instance

```julia
struct Particle
   x
   y
   z
   u
   v
   w
end

```

vs

```julia
struct Particle{N,T}
    position::SVector{N,T}
    velocity::SVector{N,T}
end

```

Say you want to do things like rotate and translate you particle.  
With the latter definition no problem:

- It is just vector addition/matrix multiplication
- Works in any dimension

With the former its more work and prone to typos. Also if one day you need 2d particles, you have to duplicate all the code.
