Ability to define function templates

I’ve ran into multiple scenarios now where I’d like to pass a function as an argument to another function, but I want to make sure it conforms to a certain type signature.

For example:

function dosomething(times::Int,doit::Function)
    for i=1:times
         doit(i)
    end
end

What I’d like to do in the above example is restrict doit() to any Function that takes a single Int argument. Obviously, I could just document that in the usage, and “hope” that it works out. But, I think it would be cleaner to be able to specify the type signature I require somehow.

I can’t see a straightforward way to do this. Am I missing something? Would this be a useful feature to add to the language? I’ve enjoyed a similar feature, “Protocols” in Objective-C.

Thanks.

2 Likes

That’s tough because functions don’t take in arguments. Methods have a well-defined number of arguments. And what you’re looking for then is a Method which works with an Int, which can be f(x), i.e. no types mentioned could be the one that works great on an Int.

To add to the complications here, not every function subtypes Function (which is just an abstract type which any function defined by the function f(x) ... will subtype, so not every function!).

Something like this could be interesting, but it would need to take multiple-dispatch seriously.

Do that. If you could require a signature for the function, you would get a MethodError when calling dosomething. Since you can’t, you will get a MethodError when calling doit. I don’t see this as much of a problem.

In dynamic languages with multiple dispatch, it is OK to only restrict types of arguments when you want different behavior based on them, not to preclude the possibility of a MethodError later. You get one anyway, just at a different point, which is OK.

2 Likes

It’s not ideal, but you can @assert applicable(doit, (Int,)) "doit must accept an Int argument"

Recently I had a similar question: Classification of functions.

Something like “protocols” in Objective-C would be a great thing.
Perhaps add it to the whishlist?

See crazy idea: dispatch on return type · Issue #19206 · JuliaLang/julia · GitHub and the links therein.

See also https://github.com/JuliaLang/julia/issues/210, a rather long-standing issue! We don’t have this feature yet, but it’s interesting to think about how it might work.

Also, as a minor aside, in typical terminology this is not called a template, but a function type or arrow type.

That just replaces MethodError with AssertionError.

I guess now that I think through it, I can’t see why there’s an advantage to having the parameters be specified initially, rather than throwing an error later when the function is called. Just seems sloppy – although I can’t think of a functional difference that would motivate adding the feature.

As it stands, it seems simply calling the function, and raising a MethodError, is the most straightforward solution. Along with providing appropriate documentation of the arguments.