Transforming a type

I have a Person type and I want to make another type that’s similar but allows missing values in the fields. Is this possible?

struct Person
    name::String
    age::Int
end

struct IncompletePerson
    name::Union{String,Missing}
    age::Union{Int,Missing}
end

function allow_missing(t::DataType)::DataType

end

# @test allow_missing(Person).types == IncompletePerson.types

This should be possible, but you would need to use eval (to define the new type in global scope) after constructing the AST for the new type definition via introspection.

(You should probably view such a function as a convenience to save you from typing out the new definition, e.g. at module-loading time, but not something you would be normally be doing lots of at runtime.)

If you find yourself wanting to define lots of new types at runtime, you might consider using named tuples instead (which are basically anonymous struct types that can be constructed as needed).

3 Likes

Another possibility would be to define person as:

struct _Person{T}
    name::Union{String, T}
    age::Union{Int, T}
end

const Person = _Person{Union{}}

And then you can simply define the version that allows missing as:

const IncompletePerson = _Person{Missing}

That will only work if you define the struct yourself though, not if it comes from another package.

5 Likes