# Avoiding long unnamed parameters in constructors

**URL:** <https://discourse.julialang.org/t/avoiding-long-unnamed-parameters-in-constructors/16855>\
**Category:** New to Julia\
**Created:** [October 27, 2018, 9:49am UTC](https://discourse.julialang.org/t/avoiding-long-unnamed-parameters-in-constructors/16855 "2018-10-27T09:49:44Z")\
**Posts on this page:** 14\
**Page:** 1

<div class="post-metadata">

**Author:** ![davidm](https://avatars.discourse-cdn.com/v4/letter/d/71e660/32.png) [@davidm](https://discourse.julialang.org/u/davidm)\
**Post date:** [October 27, 2018, 9:49am UTC](https://discourse.julialang.org/t/avoiding-long-unnamed-parameters-in-constructors/16855/1 "2018-10-27T09:49:44Z")

</div>

Sometimes I have structs with quite a few properties. This makes my constructor look really ugly and makes it difficult to modify later.

What do you I could do to improve this?

For example, see how the return is so ugly with so many arguments

```julia
mutable struct Scene
    field::String
    shader::GLShader
    renderer::GLShader
    pointcloud::GLBuffer
    cmdBuffer::GLBuffer
    meshBuffer::GLBuffer
    mesh::Array{Float64}
    normals::Array{Float64}
    files::Array{String}
    errorComputer::GLShader
    pointcloudVAO
end

function Scene(fieldPath::String)::Scene
    field = open(fieldPath) do file
        read(file, String)
    end
    computer = genFieldComputeShader(field)
    renderer = GLShader("MeshRenderer", "./vertex.glsl", "./fragment.glsl", ["\$df" => field])
    pointcloud, cmdBuffer, pointcloudVAO = computePointCloud(computer)
    errorComputer = GLShader("MeshDistanceErrorComputer", "./computeMeshError.glsl", ["\$df" => field])
    mesh, normals, meshBuffer = computeMeshFromPointCloud(cmdBuffer, pointcloud)
    return Scene(field, computer, renderer, pointcloud, cmdBuffer, meshBuffer, mesh, normals, [fieldPath], errorComputer, pointcloudVAO)
end

```

---

<div class="post-metadata">

**Author:** ![fredrikekre](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/fredrikekre/32/1688_2.png) [@fredrikekre](https://discourse.julialang.org/u/fredrikekre)\
**Post date:** [October 27, 2018, 10:17am UTC](https://discourse.julialang.org/t/avoiding-long-unnamed-parameters-in-constructors/16855/2 "2018-10-27T10:17:32Z")

</div>

Split it up on multiple lines?

```julia
[...]
    return Scene(field, computer, renderer, pointcloud,
                 cmdBuffer, meshBuffer, mesh, normals,
                 [fieldPath], errorComputer, pointcloudVAO)
end

```

---

<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:** [October 27, 2018, 10:23am UTC](https://discourse.julialang.org/t/avoiding-long-unnamed-parameters-in-constructors/16855/3 "2018-10-27T10:23:54Z")

</div>

> [@davidm](#):
>
> quite a few properties

Consider a constructor method with keywords. `Base.@kwdef` and similar functionality in some packages (eg Parameters.jl) should make it easy.

> [@davidm](#):
>
> makes it difficult to modify later.

Keywords should help with some of that. You could also group fields that belong together into composite types.

---

<div class="post-metadata">

**Author:** ![davidm](https://avatars.discourse-cdn.com/v4/letter/d/71e660/32.png) [@davidm](https://discourse.julialang.org/u/davidm)\
**Post date:** [October 27, 2018, 10:34am UTC](https://discourse.julialang.org/t/avoiding-long-unnamed-parameters-in-constructors/16855/4 "2018-10-27T10:34:07Z")

</div>

> [@Tamas\_Papp](#):
>
> kwdef

Could you explain this a little bit more? I found [https://github.com/JuliaLang/julia/blob/master/base/util.jl](https://github.com/JuliaLang/julia/blob/master/base/util.jl) and I saw how to specify default values, but in my example I don’t have default values.

> [@Tamas\_Papp](#):
>
> Keywords

I don’t know if you are referring to `@kwdef` again or I am missing something else

Thanks!

---

<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:** [October 27, 2018, 10:37am UTC](https://discourse.julialang.org/t/avoiding-long-unnamed-parameters-in-constructors/16855/5 "2018-10-27T10:37:17Z")

</div>

Read the example more carefully; you don’t need to specify default values (missing values will just error).

```julia
julia> Base.@kwdef struct Foo
           a
           b
       end
Foo

julia> Foo(a = 1, b = 2)
Foo(1, 2)

julia> Foo()
ERROR: UndefKeywordError: keyword argument a not assigned
Stacktrace:
 [1] Foo() at ./util.jl:673
 [2] top-level scope at none:0

```

---

<div class="post-metadata">

**Author:** ![davidm](https://avatars.discourse-cdn.com/v4/letter/d/71e660/32.png) [@davidm](https://discourse.julialang.org/u/davidm)\
**Post date:** [October 27, 2018, 10:38am UTC](https://discourse.julialang.org/t/avoiding-long-unnamed-parameters-in-constructors/16855/6 "2018-10-27T10:38:01Z")

</div>

This improves things a little bit, but still, if I add a new property to the struct I will need to find in that list where exactly should it go.

---

<div class="post-metadata">

**Author:** ![davidm](https://avatars.discourse-cdn.com/v4/letter/d/71e660/32.png) [@davidm](https://discourse.julialang.org/u/davidm)\
**Post date:** [October 27, 2018, 10:44am UTC](https://discourse.julialang.org/t/avoiding-long-unnamed-parameters-in-constructors/16855/7 "2018-10-27T10:44:24Z")

</div>

I see, I think this is what I was looking for, I’ll try it! Thx!

Another question, I’m trying to understand Julia more and I usually try to see similarities with other languages. With `@kwdef` I clearly see a similarity with Javascript:

```julia
function factory(params){
     ...
}
factory({
  param1: 123,
  param2: 34,
  ...
});

```

Is there also a way to solve this with a C++ like approach like:

```julia
class MyClass{
     MyClass(){
         this.prop1 = ...;
         this.prop2 = ...;
         ...
      }
}

```

?

---

<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:** [October 27, 2018, 10:48am UTC](https://discourse.julialang.org/t/avoiding-long-unnamed-parameters-in-constructors/16855/8 "2018-10-27T10:48:14Z")

</div>

Not sure what the question is. But named keyword arguments exist in most modern languages. The macro is just a way to define them quickly, you can also make an outer constructor

```julia
Foo(; a, b) = Foo(a, b)

```

yourself.

---

<div class="post-metadata">

**Author:** ![carstenbauer](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/carstenbauer/32/4981_2.png) [@carstenbauer](https://discourse.julialang.org/u/carstenbauer)\
**Post date:** [October 27, 2018, 11:57am UTC](https://discourse.julialang.org/t/avoiding-long-unnamed-parameters-in-constructors/16855/9 "2018-10-27T11:57:55Z")

</div>

See for example [performance - Julia - Mutable struct with Attribute which is a Function and @code\_warntype - Stack Overflow](https://stackoverflow.com/questions/52992375/julia-mutable-struct-with-attribute-which-is-a-function-and-code-warntype) However, I wouldn’t recommend it.

---

<div class="post-metadata">

**Author:** ![greg\_plowman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/greg_plowman/32/8100_2.png) [@greg\_plowman](https://discourse.julialang.org/u/greg_plowman)\
**Post date:** [October 29, 2018, 12:12am UTC](https://discourse.julialang.org/t/avoiding-long-unnamed-parameters-in-constructors/16855/10 "2018-10-29T00:12:13Z")

</div>

I also struggled with this.  
Not so much that the constructor looked ugly, but rather that maintaining the code, especially calling the constructor, was easy to get wrong when rearranging, adding and deleting fields (which I do often).

So I wrote a macro to make this a bit easier.

```julia
macro CompositeFieldConstructor(T)
    dataType = eval(current_module(), T)
    esc(Expr(:call, T, fieldnames(dataType)...))
end

```

(Note: macro works on v0.6, probably need modifying to work with v1.0)

Essentially, the constructor needs to _define a local variable with the same name_ for each field in the struct.  
Order of variable definitions doesn’t matter.

So your constructor becomes:

```julia
function Scene(fieldPath::String)::Scene
    field = open(fieldPath) do file
        read(file, String)
    end
    shader = genFieldComputeShader(field)
    renderer = GLShader("MeshRenderer", "./vertex.glsl", "./fragment.glsl", ["\$df" => field])
    pointcloud, cmdBuffer, pointcloudVAO = computePointCloud(computer)
    errorComputer = GLShader("MeshDistanceErrorComputer", "./computeMeshError.glsl", ["\$df" => field])
    mesh, normals, meshBuffer = computeMeshFromPointCloud(cmdBuffer, pointcloud)
 
    return @CompositeFieldConstructor(Scene)
end

```

Note I had to change local variable `computer` to `shader` to match the field name.

---

<div class="post-metadata">

**Author:** ![davidm](https://avatars.discourse-cdn.com/v4/letter/d/71e660/32.png) [@davidm](https://discourse.julialang.org/u/davidm)\
**Post date:** [October 30, 2018, 10:20pm UTC](https://discourse.julialang.org/t/avoiding-long-unnamed-parameters-in-constructors/16855/11 "2018-10-30T22:20:54Z")

</div>

Wow!

Your macro is amazing!

I changed it to make it work with v1.0:

```julia
macro Compose(T)
    esc(Expr(:call, T, fieldnames(eval(T))...))
end

```

---

<div class="post-metadata">

**Author:** ![davidm](https://avatars.discourse-cdn.com/v4/letter/d/71e660/32.png) [@davidm](https://discourse.julialang.org/u/davidm)\
**Post date:** [October 30, 2018, 10:28pm UTC](https://discourse.julialang.org/t/avoiding-long-unnamed-parameters-in-constructors/16855/12 "2018-10-30T22:28:56Z")

</div>

To make it work from other modules (in v1):

```julia
macro Compose(T)
    esc(Expr(:call, T, fieldnames(Base.@eval( __module__ , $(T)))...))
end

```

---

<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:** [October 30, 2018, 11:53pm UTC](https://discourse.julialang.org/t/avoiding-long-unnamed-parameters-in-constructors/16855/13 "2018-10-30T23:53:07Z")

</div>

I always do this for a constructor. I found it more convenient about the ordering. Seems this is no longer in the new documentation?

```julia
mutable struct Foo
    a::int 
    b::Float64
    ... 

    function Foo(a::Int, ...)
        this = new()
        this.b = 3.0 * a # order does not matter
        this.a = a
        ......
        this
    end
end

```

---

<div class="post-metadata">

**Author:** ![kristoffer.carlsson](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kristoffer.carlsson/32/22_2.png) [@kristoffer.carlsson](https://discourse.julialang.org/u/kristoffer.carlsson)\
**Post date:** [October 31, 2018, 12:18am UTC](https://discourse.julialang.org/t/avoiding-long-unnamed-parameters-in-constructors/16855/14 "2018-10-31T00:18:31Z")

</div>

Inner constructors should be used sparingly cf the docs

> It is considered good form to provide as few inner constructor methods as possible: only those taking all arguments explicitly and enforcing essential error checking and transformation. Additional convenience constructor methods, supplying default values or auxiliary transformations, should be provided as outer constructors that call the inner constructors to do the heavy lifting.
