Stream: helpdesk (published)

Topic: Parent type of all callables?


view this post on Zulip Júlio Hoffimann (Oct 03 2025 at 12:09):

Is there a parent type for all callable objects?

I am trying to constrain the arguments of a function to Function + constructors. Something like Union{<:Function,<:Constructor} but Constructor doesn't exist. Is there a general type that I can use in this scenario?

view this post on Zulip Andy Dienes (Oct 03 2025 at 12:12):

nope

view this post on Zulip Júlio Hoffimann (Oct 03 2025 at 12:15):

I am considering Union{Function,Type}. Experimenting with it...

view this post on Zulip Andy Dienes (Oct 03 2025 at 12:17):

why not Any ? there's nothing really generic you can do over "callables" anyway

view this post on Zulip Júlio Hoffimann (Oct 03 2025 at 12:18):

Andy Dienes said:

why not Any ? there's nothing really generic you can do over "callables" anyway

Ambiguity with other types. It is a more convoluted use case.

view this post on Zulip Júlio Hoffimann (Oct 03 2025 at 12:19):

# supported argument types
const Callable = Union{Function,Type}
const Target = Union{Symbol,AbstractString}
const ColsCallableTarget = Pair{<:Any,<:Pair{<:Callable,<:Target}}
const ColsCallable = Pair{<:Any,<:Callable}
const CallableTarget = Pair{<:Callable,<:Target}
const MapArg = Union{ColsCallableTarget,ColsCallable,CallableTarget,Callable}

MapArg is the type that I want to constrain at the end. My function definition will have a VargArg of them:

function foo(arg::MapArg...)
end

view this post on Zulip Júlio Hoffimann (Oct 03 2025 at 12:20):

The VarArg requirement forces this non-idiomatic approach with explicit types. I would use simple dispatch if I could.

view this post on Zulip Andy Dienes (Oct 03 2025 at 12:21):

does does foo do?

view this post on Zulip Júlio Hoffimann (Oct 03 2025 at 12:21):

Let me finish the PR and you can see the whole picture :slight_smile:

view this post on Zulip Mason Protter (Oct 03 2025 at 12:22):

julia> struct Foo end

julia> (::Foo)(x, y) = x + y

julia> Foo()(1, 2)
3

julia> supertype(Foo)
Any

view this post on Zulip Júlio Hoffimann (Oct 03 2025 at 12:23):

Yes, I am thinking of types as possible callables.

view this post on Zulip Mason Protter (Oct 03 2025 at 12:24):

that wasn't a type

view this post on Zulip Mason Protter (Oct 03 2025 at 12:24):

julia> Foo() isa Type
false

view this post on Zulip Júlio Hoffimann (Oct 03 2025 at 12:24):

Oh I see your point.

view this post on Zulip Júlio Hoffimann (Oct 03 2025 at 12:24):

You are mentioning the case of an instance that is callable and not a subtype of Function.

view this post on Zulip Júlio Hoffimann (Oct 03 2025 at 12:24):

I don't want to support this use case.

view this post on Zulip Mason Protter (Oct 03 2025 at 12:25):

It's callable :shrug:

view this post on Zulip Júlio Hoffimann (Oct 03 2025 at 12:26):

I know. It wouldn't hurt to support this case, but since Julia doesn't have a Callable super type, I don't need to cover it in practice.

view this post on Zulip Júlio Hoffimann (Oct 03 2025 at 12:26):

The use case is pretty simple: take a function or constructor and map over an array of arguments. The PR is almost ready...

view this post on Zulip Júlio Hoffimann (Oct 03 2025 at 12:51):

https://github.com/JuliaML/TableTransforms.jl/pull/305

view this post on Zulip Júlio Hoffimann (Oct 03 2025 at 12:51):

The PR above should clarify the use case. It is working fine :slight_smile:

view this post on Zulip Mosè Giordano (Oct 03 2025 at 16:59):

Júlio Hoffimann said:

Julia doesn't have a Callable super type

Technically there's https://github.com/JuliaLang/julia/blob/85687b522a6e73836b6ae95e65a8dc1723427d32/base/essentials.jl#L5 but it isn't public.

view this post on Zulip Júlio Hoffimann (Oct 03 2025 at 17:15):

Interesting. The exact same definition.

view this post on Zulip aplavin (Oct 03 2025 at 17:52):

For not-really-generic code it's totally fine to dispatch on Union{Function, Type} to catch many callables, but in generic code there's no way to select callables just by their supertype. That's why generic API is designed so that there's no confusion – whether a callable should be in this argument or not.

view this post on Zulip Neven Sajko (Oct 04 2025 at 07:57):

Relevant discussion on the Julia issue tracker:

view this post on Zulip Neven Sajko (Oct 04 2025 at 07:59):

The design of Julia is such that anything may be callable, just give it a method. Thus a Callable type would not make sense.

view this post on Zulip Timothy (Oct 04 2025 at 09:40):

Yea, I've writen functions like (f::Foo)(x) = ... before.


Last updated: Oct 18 2025 at 04:39 UTC