Weird behavior for types within type definitions

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:

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.

5 Likes

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> struct A3
           q::Int
           function c(d)
               d+1
           end
       end

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

while

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.

I did now:

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.

1 Like

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.

1 Like