# Question on Defining Functions Inside Structs

**URL:** <https://discourse.julialang.org/t/question-on-defining-functions-inside-structs/70532>\
**Category:** General Usage\
**Tags:** struct, constructors\
**Created:** [October 28, 2021, 4:17am UTC](https://discourse.julialang.org/t/question-on-defining-functions-inside-structs/70532 "2021-10-28T04:17:48Z")\
**Posts on this page:** 9\
**Page:** 1

<div class="post-metadata">

**Author:** ![TI36XPro](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ti36xpro/32/33658_2.png) [@TI36XPro](https://discourse.julialang.org/u/TI36XPro)\
**Post date:** [October 28, 2021, 4:17am UTC](https://discourse.julialang.org/t/question-on-defining-functions-inside-structs/70532/1 "2021-10-28T04:17:48Z")

</div>

I noticed in this [video](https://www.youtube.com/watch?v=Gi4ZZVS2GLA&t=878s) here that several constructors for the struct are defined inside the struct block itself. I’ve not personally done this to date, it just didn’t occur to me. I’ve always defined alternate constructors outside the struct block.

Is there any particular reason to do this or not do this (define outer constructors inside the struct block)?

---

<div class="post-metadata">

**Author:** ![mmiller](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mmiller/32/20805_2.png) [@mmiller](https://discourse.julialang.org/u/mmiller)\
**Post date:** [October 28, 2021, 5:39am UTC](https://discourse.julialang.org/t/question-on-defining-functions-inside-structs/70532/2 "2021-10-28T05:39:18Z")

</div>

[This section](https://docs.julialang.org/en/v1/manual/constructors/#man-inner-constructor-methods) of the docs is quite helpful for this.

There are two use cases which cannot be done by outside outer constructors:

> While outer constructor methods succeed in addressing the problem of providing additional convenience methods for constructing objects, they fail to address the other two use cases mentioned in the introduction of this chapter: enforcing invariants, and allowing construction of self-referential objects. For these problems, one needs _inner_ constructor methods.

---

<div class="post-metadata">

**Author:** ![TI36XPro](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ti36xpro/32/33658_2.png) [@TI36XPro](https://discourse.julialang.org/u/TI36XPro)\
**Post date:** [October 28, 2021, 11:55am UTC](https://discourse.julialang.org/t/question-on-defining-functions-inside-structs/70532/3 "2021-10-28T11:55:38Z")

</div>

I’ve read the section in the manual on inner and outer constructors several times but its possible I still missed it - but if you look at the video that isn’t what is going on (I don’t think).

There is no use of the keyword `new`. He is defining outer constructors inside the struct block. I’m asking if that matters or means anything. Is there any reason to do that versus defining them outside the struct block.

---

<div class="post-metadata">

**Author:** ![gbaraldi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gbaraldi/32/22101_2.png) [@gbaraldi](https://discourse.julialang.org/u/gbaraldi)\
**Post date:** [October 28, 2021, 12:07pm UTC](https://discourse.julialang.org/t/question-on-defining-functions-inside-structs/70532/4 "2021-10-28T12:07:43Z")

</div>

Outside of being able to enforce invariants and self-referential objects. There is no difference between internal methods and external. There is a disadvantage tho, external methods can easily be redefined, while internal ones can’t

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [October 28, 2021, 12:19pm UTC](https://discourse.julialang.org/t/question-on-defining-functions-inside-structs/70532/5 "2021-10-28T12:19:02Z")

</div>

One example:

```julia
julia> struct A
           x
           A(x) = new(2*x) # ambiguous, overwrites the default A(x)
       end

julia> A(x,y) = A(x+y) # outer constructor, not ambiguous
A

julia> A(1)
A(2)

julia> A(1,2)
A(6)

julia> A(x) = A(3*x) # this will be ambiguous, self-referential
A

julia> A(1)
ERROR: StackOverflowError:
Stacktrace:
 [1] A(x::Int64) (repeats 79984 times)
   @ Main ./REPL[8]:1

```

thus, one of the uses is to avoid self-referential constructors, when the parameters of the method are the same as that of the default constructor.

---

<div class="post-metadata">

**Author:** ![TI36XPro](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ti36xpro/32/33658_2.png) [@TI36XPro](https://discourse.julialang.org/u/TI36XPro)\
**Post date:** [October 28, 2021, 12:38pm UTC](https://discourse.julialang.org/t/question-on-defining-functions-inside-structs/70532/6 "2021-10-28T12:38:11Z")

</div>

I am not referring to or asking about the distinction between inner and outer constructors. If you watch the video (the link contains the time where it occurs) you’ll see he’s defining outer constructors inside the struct block. I’m asking if there is anything special or reason to do that as opposed to defining them outside the struct block.

I say they are outer constructors because there is no use of the keyword `new` which would indicate to me it is an inner constructor. Maybe that’s what I have misunderstood.

---

<div class="post-metadata">

**Author:** ![gbaraldi](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/gbaraldi/32/22101_2.png) [@gbaraldi](https://discourse.julialang.org/u/gbaraldi)\
**Post date:** [October 28, 2021, 12:43pm UTC](https://discourse.julialang.org/t/question-on-defining-functions-inside-structs/70532/7 "2021-10-28T12:43:51Z")

</div>

I think you might have misread it

 ![image](https://global.discourse-cdn.com/julialang/original/3X/3/4/349ad023efb32533ea4518f34a37827ba9a7df2e.jpeg)  
Those are all outer constructors, it’s just that he put them all inside a `begin end` block. IIRC he has to do that because of pluto.

---

<div class="post-metadata">

**Author:** ![lmiq](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lmiq/32/18314_2.png) [@lmiq](https://discourse.julialang.org/u/lmiq)\
**Post date:** [October 28, 2021, 1:06pm UTC](https://discourse.julialang.org/t/question-on-defining-functions-inside-structs/70532/8 "2021-10-28T13:06:52Z")

</div>

You can create inner constructors that could be written as well as outer constructors:

```julia
julia> struct A
           x
           A(x,y) = new(x + y)
       end

julia> A(1,2)
A(3)

```

There is no difference relative to defining it outside with `A(x,y) = A(x + y)`. But [it is not the recommended pattern](https://docs.julialang.org/en/v1/manual/constructors/#man-inner-constructor-methods):

> It is good practice 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. This separation is typically quite natural.

---

<div class="post-metadata">

**Author:** ![TI36XPro](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ti36xpro/32/33658_2.png) [@TI36XPro](https://discourse.julialang.org/u/TI36XPro)\
**Post date:** [October 28, 2021, 1:20pm UTC](https://discourse.julialang.org/t/question-on-defining-functions-inside-structs/70532/9 "2021-10-28T13:20:31Z")

</div>

ahhh, you are right! I see the reason for my confusion now. Thank you!
