Enforcing function signatures by both argument & return types

Is there any ongoing work concerning this? Any plans to have built-in syntax for function types?

Right now it doesn’t seem possible to write out the full type of a function, like:

g(f::Function{Int, (Int, )}, v::Int)::Int = f(v)
  • FunctionWrappers.jl seems to be alive and well, but there’s no documentation, only tests
  • This RFC has been open and basically untouched since 2015
  • Answers to this post from 2019 say that it’s not possible to specify the type of a function argument which is supposed to be a function. The answers link to an entire PhD thesis and say that specifying the function signature won’t bring performance benefits. But the real benefit here is that it’ll make it easier for the programmer to understand what kind of arguments higher-order functions expect.

Why is there no built-in way of even expressing types of functions? Is this not an important feature? Specifically for a language that’s basically all about functions? AFAIK, Rust doesn’t have syntax to express types of (certain kinds of) closures, so there must be something difficult about that (I guess the difficult thing is the need to describe variables captured by the closure?), but Julia doesn’t seem to have syntax to express types of functions at all, which seems unnecessarily limiting. Is it way too difficult to implement?

I’m not an expert and couldn’t really keep up with this: Function Parameter Speculation #17168, but why is, according to this comment, “What is the type of a function?” a “hard question”? Isn’t it (Arg1Type, Arg2Type) -> ResultType? Or function(Type1, Type2)::RetType? Or Callable{RetType, (Type1, Type2)}?

Why not have something like function pointers, similar to C? Sure, function pointer types can get illegible really quickly, but at least they’re there if you need them.