Check that all fields are concrete types?

I’ve discovered that I may have introduced some performance-sapping code into my project because of the following issue. I have two structs A and B like this:

    struct A
        field1::Int
    end
    struct B
        containedA::A
    end

Later I decide to rewrite A with a parameter:

    struct A{T}
        field1::T  
    end

According to my understanding of the language, I should now also parametrize B with T, else the contained field A is an abstract type and anything that uses B will involve run-time dispatch. However, in many places in my code, I forgot to do this and am just now noticing the issue.

First, is my understanding correct? Is there a performance hit for not parameterizing B?

Second, if this is indeed the case, is there a technique to discover this problem (i.e., a technique to confirm that all fields of a struct are concrete) aside from running code_warntype and poring over the output?

1 Like

Yes,

you could use a macro (only tested on 0.7):

macro concrete(expr)
    @assert expr.head == :struct
    S = expr.args[2]
    return quote
        $(esc(expr))

        for n in fieldnames($S)
            if !isconcretetype(fieldtype($S, n))
                error("field $n is not concrete")
            end
        end
    end
end
julia> @concrete struct Foo
           v::Array{Int}
       end
ERROR: field v is not concrete
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] top-level scope at REPL[1]:9

julia> struct Bar{Int} end

julia> @concrete struct Foob
           v::Bar
       end
ERROR: field v is not concrete
Stacktrace:
 [1] error(::String) at ./error.jl:33
 [2] top-level scope at REPL[1]:9

julia> @concrete struct Foobar
           v::Bar{Float64}
       end
7 Likes

A quick question about this macro: could it be simplified by invoking isconcretetype on S itself instead of on the fields?

struct S
  ...
end

is always concrete.

Resurrecting this old topic.

isabstract and isconcrete and with their Base. prefixes are not defined for me in Julia 1.6, has it been deprecated?

Can I confirm that, I thought the idea of personalising structs was that the struct is concrete only if all of its properties are concrete types?

Base.isconcretetype is in 1.5

2 Likes

Maybe you are looking for isabstracttype and isconcretetype?

2 Likes

Yes, thanks guys.

I kicked myself when, after reading your two replies, I tried ?isconcrete and it suggested isconcretetype.

1 Like