Skip to content

Return types conforming to interfaces and other interface ideas #11

@jkrumbiegel

Description

@jkrumbiegel

I think it's common enough in generic programming that one works with different layers of objects. For example some iterator of objects, where the iterator could be an array, a tuple, etc. and the object anything that serves some further purpose. That further purpose could again be locked down by an interface I thought. Here I jotted down some code where I made a ReturnInterface that should guarantee a given signature returns an object that conforms to a given interface (that interface can simply be that it should be a certain type, or whatever more complex thing).

I also had the idea of splitting run time and compile time traits and only allowing composition of compile time traits into new compile time traits, but I haven't followed that here. Just including it for inspiration. I bet that relying on _return_type has all sorts of problems, I already hit some uninferred cases during casual testing. But it seems like the only thing we got after all?

abstract type Interface end
abstract type CompileTimeInterface <: Interface end
abstract type RunTimeInterface <: Interface end
abstract type CompositeInterface <: Interface end

struct AndInterface{T<:Tuple} <: CompositeInterface
    interfaces::T
end

test_implements(x, a::AndInterface) = all(i -> test_implements(x, i), a.interfaces)

struct OrInterface{T<:Tuple} <: CompositeInterface
    interfaces::T
end

test_implements(x, a::AndInterface) = any(i -> test_implements(x, i), a.interfaces)

struct HasMethodInterface{SIG} <: CompileTimeInterface
    signature::SIG
end

test_implements(x, m::HasMethodInterface) = hasmethod(x, m.signature)

struct TypeInterface3{T<:Type} <: CompileTimeInterface
    type::T
end

test_implements(x, t::TypeInterface3) = x <: t.type

struct ReturnInterface{SIG,I<:Interface} <: CompileTimeInterface
    signature::SIG
    returninterface::I
end

function test_implements(x, r::ReturnInterface)
    ret = Base._return_type(x, r.signature)
    ret === Base.Bottom && return false
    test_implements(ret, r.returninterface)
end

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions