JuliaLang / julia

The Julia Programming Language
https://julialang.org/
MIT License
45.74k stars 5.48k forks source link

implement method dispatch for a union of functions #54620

Open nsajko opened 5 months ago

nsajko commented 5 months ago

I'd like this to work:

function f end
function g end
function (::Union{typeof(f),typeof(g)})()
    7
end

using Test
@test f() === g()

However, it doesn't work:

julia> function f end
f (generic function with 0 methods)

julia> function g end
g (generic function with 0 methods)

julia> function (::Union{typeof(f),typeof(g)})()
           7
       end
ERROR: Method dispatch is unimplemented currently for this method signature
Stacktrace:
 [1] top-level scope
   @ REPL[3]:1

julia> versioninfo()
Julia Version 1.12.0-DEV.617
Commit 337b952625d (2024-05-29 13:31 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 8 × AMD Ryzen 3 5300U with Radeon Graphics
  WORD_SIZE: 64
  LLVM: libLLVM-17.0.6 (ORCJIT, znver2)
Threads: 1 default, 0 interactive, 1 GC (on 8 virtual cores)

This would occasionally be nice for defining a single method for several functions, to prevent code duplication.

nsajko commented 4 months ago

NB: the same thing, method for a Union, works fine as long as none of the types in the Union were defined with function. Example:

julia> struct T <: Function end

julia> struct S <: Function end

julia> (::Union{S,T})() = 7

julia> S()()
7

julia> @which S()()
(::Union{S, T})()
     @ Main REPL[3]:1

julia> versioninfo()
Julia Version 1.12.0-DEV.766
Commit 9d8ecaa899d (2024-06-21 17:00 UTC)
Build Info:
  Official https://julialang.org/ release
Platform Info:
  OS: Linux (x86_64-linux-gnu)
  CPU: 8 × AMD Ryzen 3 5300U with Radeon Graphics
  WORD_SIZE: 64
  LLVM: libLLVM-17.0.6 (ORCJIT, znver2)
Threads: 1 default, 0 interactive, 1 GC (on 8 virtual cores)