Instantiating function from type?

Given the type F of a function, is there a good/documented way to instantiate the underlying function if possible?

F() doesn’t work, but I feel like it should:

julia> F = typeof(sin)
typeof(sin) (singleton type of function sin, subtype of Function)

julia> F()
ERROR: MethodError: no method matching typeof(sin)()
Stacktrace:
 [1] top-level scope
   @ REPL[52]:1

You can use the undocumented internal field F.instance:

julia> F.instance
sin (generic function with 14 methods)

so the best I can come up with is:

(::Type{F})() where {F<:Function} = Base.issingletontype(F) ? F.instance : throw(MethodError(F, ()))

Is there something better than issingletontype to determine whether a Function type corresponds to a generic function, as opposed to some other user-defined datatype?

(Obviously, this is type piracy … in a package this would better be named functioninstance(F) or something like that. But I’m thinking that something like this should go into Base.)

PS. On a related note, it feels like there should be a GenericFunction <: Function supertype for all Function types that come from bona-fide Julia functions, as opposed to user-defined functor types.

6 Likes

Not sure whether there exist other solutions, but what you suggest here is more or less the same as the solution provided by @Mason in this older thread:

You can use incomplete initialization to get a valid instance of any singleton type, instead of using the undocumented instance field. I have a tiny package for it here: Neven Sajko / InstanceOfSingletonType.jl · GitLab. Registering it.

Related thread:

There is Core.Compiler.singleton_type.

julia> const F = typeof(sin)
typeof(sin) (singleton type of function sin, subtype of Function)

julia> Core.Compiler.singleton_type(F)
sin (generic function with 14 methods)
1 Like