Seelengrab/RequiredInterfaces.jl

Require a method with kwargs

BatyLeo opened this issue · 1 comments

Hello,
While trying the new support for callable structs (it works perfectly, thanks!), I found that methods with keyword arguments are not supported:

using RequiredInterfaces

abstract type CallableAbstract end

@required CallableAbstract begin
    (c::CallableAbstract)(; kwargs...)
end

throws an error: ERROR: LoadError: ArgumentError: Invalid required function!.

Is there a way to make it work?

Keywords are a bit tricky; the way they're handled by Julia is pretty internal, especially when it comes to required/optional keywords. For example:

julia> struct Foo end

julia> (f::Foo)(a; b=2, d, kwargs...) = "bar"

julia> using RequiredInterfaces; const RI = RequiredInterfaces
RequiredInterfaces

julia> RI.instancemethods(Foo, (Any,))
# 1 method for callable object:
 [1] (f::Foo)(a; b, d, kwargs...)
     @ Main REPL[2]:1

To a high-level inspection, the methods defined here all look the same, even though only d is required to be passed:

julia> Foo()(1)
ERROR: UndefKeywordError: keyword argument `d` not assigned
Stacktrace:
 [1] (::Foo)(a::Int64)
   @ Main ./REPL[2]:1
 [2] top-level scope
   @ REPL[5]:1

julia> Foo()(1; d=3)
"bar"

I don't think it's impossible to add, but this is likely a bit trickier and requires a bit of a redesign of how the checking for interface compliance is done.