# How do I write a @generated inner constructor?

**URL:** <https://discourse.julialang.org/t/how-do-i-write-a-generated-inner-constructor/2817>\
**Category:** New to Julia\
**Created:** [March 22, 2017, 12:58pm UTC](https://discourse.julialang.org/t/how-do-i-write-a-generated-inner-constructor/2817 "2017-03-22T12:58:20Z")\
**Posts on this page:** 12\
**Page:** 1

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [March 22, 2017, 12:58pm UTC](https://discourse.julialang.org/t/how-do-i-write-a-generated-inner-constructor/2817/1 "2017-03-22T12:58:20Z")

</div>

I’m trying to create a type with an `@generated` inner constructor, but it seems I’m doing something wrong? Or maybe generated inner constructors are not permitted?

Here’s my attempt:

```julia
julia> immutable T
         @generated T() = :( new() )
       end

julia> T()
ERROR: UndefVarError: new not defined
Stacktrace:
 [1] T() at ./REPL[10]:2

```

---

<div class="post-metadata">

**Author:** ![mkborregaard](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkborregaard/32/556_2.png) [@mkborregaard](https://discourse.julialang.org/u/mkborregaard)\
**Post date:** [March 22, 2017, 4:34pm UTC](https://discourse.julialang.org/t/how-do-i-write-a-generated-inner-constructor/2817/2 "2017-03-22T16:34:55Z")

</div>

What are you trying to achieve?

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [March 22, 2017, 4:57pm UTC](https://discourse.julialang.org/t/how-do-i-write-a-generated-inner-constructor/2817/3 "2017-03-22T16:57:37Z")

</div>

I don’t think it’s currently easy to do. You can generate the `Expr(:new)` manually but maybe we can fix the generated function lowering for inner constructors…

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [March 22, 2017, 5:23pm UTC](https://discourse.julialang.org/t/how-do-i-write-a-generated-inner-constructor/2817/4 "2017-03-22T17:23:54Z")

</div>

`Expr(:new)` gave a segfault when I tried it. `Expr(:call, :new)` gave the same error message as `:( new() )`.

The reason I would like a generated inner constructor is that I want to do some sanity checks on type parameters, and throw an exception if there’s a problem. I had expected to be able to do this without any performance penalty, since type parameters are known constants when the method is compiled. But it turns out to be more complicated than I first thought. Instructions related to garbage collection sometimes get added even though they are not needed. (Apparently the compiler does not always realize when the garbage collected objects are constants that get folded away.) A generated function would not have this problem.

---

<div class="post-metadata">

**Author:** ![yuyichao](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/yuyichao/32/20_2.png) [@yuyichao](https://discourse.julialang.org/u/yuyichao)\
**Post date:** [March 22, 2017, 5:27pm UTC](https://discourse.julialang.org/t/how-do-i-write-a-generated-inner-constructor/2817/5 "2017-03-22T17:27:18Z")

</div>

… Well, you don’t just do `Expr(:new)`. You need to fill in the argument. Check `code_lowered` of a constructor to see what you should generate.

```julia
julia> type A
       A() = new()
       end

julia> @code_lowered A()
CodeInfo(:(begin
        nothing
        return $(Expr(:new, :(Main.A)))
    end))

```

This is also mentioned in the [dev doc](http://docs.julialang.org/en/latest/devdocs/ast.html#Expr-types-1). Note that this is the internal AST so it can break more easily than the surface AST.

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [March 22, 2017, 5:27pm UTC](https://discourse.julialang.org/t/how-do-i-write-a-generated-inner-constructor/2817/6 "2017-03-22T17:27:46Z")

</div>

> [@Per](#):
>
> The reason I would like a generated inner constructor is that I want to do some sanity checks on type parameters, and throw an exception if there’s a problem.

Just use dispatch to other functions that do the type checks for you. Those will receive the same optimizations for known types. Cf. [https://github.com/JuliaLang/julia/blob/003a14fd215954581147df49d37e7c05fb826771/base/subarray.jl#L15](https://github.com/JuliaLang/julia/blob/003a14fd215954581147df49d37e7c05fb826771/base/subarray.jl#L15)

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [March 22, 2017, 5:37pm UTC](https://discourse.julialang.org/t/how-do-i-write-a-generated-inner-constructor/2817/7 "2017-03-22T17:37:25Z")

</div>

> [@yuyichao](#):
>
> … Well, you don’t just do `Expr(:new)`. You need to fill in the argument. Check `code_lowered` of a constructor to see what you should generate.

Awesome! Thanks.

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [March 22, 2017, 5:54pm UTC](https://discourse.julialang.org/t/how-do-i-write-a-generated-inner-constructor/2817/8 "2017-03-22T17:54:06Z")

</div>

> [@mbauman](#):
>
> Just use dispatch to other functions that do the type checks for you. Those will receive the same optimizations for known types.

I had tried this, but it did not work when I passed the type parameters as arguments to the checking function. (Apparently the types themselves become garbage collected objects at that point.) The example you give instead infers the type parameters anew from the the types of passed-through arguments. I can see why that should work much better. I will try this!

---

<div class="post-metadata">

**Author:** ![mbauman](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mbauman/32/31082_2.png) [@mbauman](https://discourse.julialang.org/u/mbauman)\
**Post date:** [March 22, 2017, 6:12pm UTC](https://discourse.julialang.org/t/how-do-i-write-a-generated-inner-constructor/2817/9 "2017-03-22T18:12:07Z")

</div>

It should also work when passing types to the checking function. The key is to put your logic into the dispatch table instead of inside a single method. Dispatching on `::Type{…}` isn’t really any different than dispatching on concrete types… although invariance can make it a little harder to express.

---

<div class="post-metadata">

**Author:** ![Per](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/per/32/10387_2.png) [@Per](https://discourse.julialang.org/u/Per)\
**Post date:** [March 22, 2017, 6:44pm UTC](https://discourse.julialang.org/t/how-do-i-write-a-generated-inner-constructor/2817/10 "2017-03-22T18:44:41Z")

</div>

I put the logic in a `@generated` checking function. Equivalent to putting it in the dispatch table in a way, but gives more flexibility. Works great! Thanks for the tip.

---

<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:** [September 8, 2019, 7:54pm UTC](https://discourse.julialang.org/t/how-do-i-write-a-generated-inner-constructor/2817/11 "2019-09-08T19:54:58Z")

</div>

Is there a new way to have a generated inner constructor in Julia 1+ ? The `@code_lowered` on 1.2 didn’t give me any hints for how I should do it:

```julia
julia> struct Foo
           Foo() = new()
       end

julia> 

julia> @code_lowered Foo()
CodeInfo(
1 ─ %1 = %new(Main.Foo)
└── return %1
)

```

which suggested I might try this, but it doesn’t work:

```julia
julia> struct Foo
           @generated Foo() = :(new(Foo))
       end

julia> Foo()
ERROR: UndefVarError: new not defined
Stacktrace:
 [1] macro expansion at ./REPL[6]:2 [inlined]
 [2] Foo() at ./REPL[6]:2
 [3] top-level scope at REPL[7]:1

```

FWIW my use case is that I have a complicated type with lots of parameters and ways to construct it, and I think it would be far clearer code to deal with ambiguities in the body of a generated function rather than with dispatch logic.

---

<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:** [September 8, 2019, 8:10pm UTC](https://discourse.julialang.org/t/how-do-i-write-a-generated-inner-constructor/2817/12 "2019-09-08T20:10:22Z")

</div>

Ah I should have just tried the old thing, it seems to work still,

```julia
struct Foo
    @generated Foo() = :($(Expr(:new, :(Foo))))
end

```
