Inner constructor with type parameter not in signature

I would like to “store” some information (basically, a tuple of symbols) in a type parameter, eg

immutable Foo{X} end

which works:

julia>  Foo{(:A)}()
Foo{:A}()

But at the same time I also want to use an inner constructor to check it:

immutable Foo2{X}
    function Foo2{X}()
        @assert isa(X, Tuple{Vararg{Symbol}}) && length(X) == 3
        new{X}()
    end
end

for which I get

WARNING: static parameter X does not occur in signature for Type at REPL[108]:3.
The method will not be callable.

Is there a way I can get both, ie a validating inner constructor and a type parameter that is not in the signature? Of course in practice I would use an outer constructor, I want to do something like

Foo2((:a,:b,:c))  # OK
Foo2((:a,1))      # error

X is already defined inside the type-declaration:

julia> immutable Foo2{X}
           function Foo2(); @show X
               @assert isa(X, Tuple{Vararg{Symbol}}) && length(X) == 3
               new()
           end
       end

julia> Foo2{(:a,:b,:c)}()
X = (:a,:b,:c)
Foo2{(:a,:b,:c)}()

julia> Foo2{(:a,:b)}()
X = (:a,:b)
------ AssertionError ------------------ Stacktrace (most recent call last)

 [1] — Foo2{(:a,:b)}() at REPL[1]:3

AssertionError: isa(X,Tuple{Vararg{Symbol}}) && length(X) == 3
2 Likes

This is a case where the implicit inner constructors of 0.5 are really unfortunate. In 0.6, implicit inner constructors are deprecated, and hopefully eventually (maybe 2.0) the code in your original post will work.