# Weird behavior for types within type definitions

**URL:** <https://discourse.julialang.org/t/weird-behavior-for-types-within-type-definitions/99581>\
**Category:** Internals & Design\
**Tags:** bug, type, compatibility\
**Created:** [May 29, 2023, 10:54pm UTC](https://discourse.julialang.org/t/weird-behavior-for-types-within-type-definitions/99581 "2023-05-29T22:54:42Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [May 29, 2023, 10:54pm UTC](https://discourse.julialang.org/t/weird-behavior-for-types-within-type-definitions/99581/1 "2023-05-29T22:54:42Z")

</div>

Minimal example: `struct A struct B end end`. This puts both `A` and `B` into the global scope, `A` without constructors and B with a constructor. Why would `B` be put into global scope even though no `global` keyword was used?

More extreme example:

```julia
struct A struct B struct C struct D end end end end

```

In this case all four types are put into global scope, with the innermost type, `D`, being the only one with any constructors.

It seems like it might be good to just disallow `struct`-within-`struct` constructs, if the inner types are just going to end up in the global scope anyway. If that’s possible without breaking backwards compatibility, that is.

---

<div class="post-metadata">

**Author:** ![albheim](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/albheim/32/34660_2.png) [@albheim](https://discourse.julialang.org/u/albheim)\
**Post date:** [June 2, 2023, 11:11am UTC](https://discourse.julialang.org/t/weird-behavior-for-types-within-type-definitions/99581/2 "2023-06-02T11:11:19Z")

</div>

That can’t be the intended behavior. Have you filed an issue for it?

Seems like some other things also remove the constructor, e.g.

```julia
julia> struct A3
           q::Int
           function c(d)
               d+1
           end
       end

julia> methods(A3)
# 0 methods for type constructor

```

while

```julia
julia> struct A5
           q::Int
           begin end
       end

julia> methods(A5)
# 2 methods for type constructor:
 [1] A5(q::Int64)
     @ REPL[37]:2
 [2] A5(q)
     @ REPL[37]:2

```

does not, so it is not just that any expression after the fields that does it.

---

<div class="post-metadata">

**Author:** ![nsajko](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/nsajko/32/221187_2.png) [@nsajko](https://discourse.julialang.org/u/nsajko)\
**Post date:** [June 2, 2023, 2:46pm UTC](https://discourse.julialang.org/t/weird-behavior-for-types-within-type-definitions/99581/3 "2023-06-02T14:46:19Z")

</div>

> [@albheim](#):
>
> Have you filed an issue for it?

I did now:

> <https://github.com/JuliaLang/julia/issues/50040>
>
> It seems that defining types in a nested manner inside other type definitions ex…poses the inner types as global names, even though no \`global\` was used.
> 
> Furthermore, the existence of the inner type seems to inhibit the creation of a constructor for the outer type, which seems inconsistent with the fact that the inner type is not restricted to the outer type's scope (or whatever that's called).
> 
> Reproducible on master.
> 
> \`\`\`julia-repl
> julia\> versioninfo()
> Julia Version 1.8.5
> Commit 17cfb8e65ea (2023-01-08 06:45 UTC)
> Platform Info:
> OS: Linux (x86\_64-linux-gnu)
> CPU: 8 × AMD Ryzen 3 5300U with Radeon Graphics
> WORD\_SIZE: 64
> LIBM: libopenlibm
> LLVM: libLLVM-13.0.1 (ORCJIT, znver2)
> Threads: 1 on 8 virtual cores
> 
> julia\> struct A struct B end end
> 
> julia\> B
> B
> 
> julia\> methods(A)
> \# 0 methods for type constructor
> 
> julia\> struct S0 struct S1 struct S2 struct S3 end end end end
> \`\`\`

> [@albheim](#):
>
> Seems like some other things also remove the constructor

I _think_ that’s as intended, although there’s perhaps a kludgy feel to it. The idea is that whenever one defines any method, there is no automatic generation of constructors. To make this more useful (?), there’s one undocumented/internal (?) feature that I alluded to in the OP: using the `global` keyword to expose such a “back door” constructor.

---

<div class="post-metadata">

**Author:** ![Sukera](https://avatars.discourse-cdn.com/v4/letter/s/ce7236/32.png) [@Sukera](https://discourse.julialang.org/u/Sukera)\
**Post date:** [June 3, 2023, 12:26am UTC](https://discourse.julialang.org/t/weird-behavior-for-types-within-type-definitions/99581/4 "2023-06-03T00:26:03Z")

</div>

I think the global assignment is purely a result from the fact that structs can’t be defined in local scopes; they always fall back to global scopes, because julia does not have a local `eval`. The “no constructors” thing seems like a bug though.
