1 - Parameterization functions.
It is theoretically possible for the compiler to parameterize the type of function; You can add this as a function. However, this is not entirely trivial, because functions are contravariant in their arguments and covariant in their return value:
trait Function1[+T,-R] { ... }
which means that another function that can take more arguments is considered a subclass (since it can handle everything that the superclass can handle), and if it produces a smaller set of results, this is normal (since it will also obey the superclass build this way). But how do you code
def fn[A](a: A) = a
in this structure? The thing is that the return type is equal to the type passed, regardless of what type should be. You will need
Function1[ ThisCanBeAnything, ThisHasToMatch ]
as your type of function. "It can be anything" Any is well represented if you need one type, but then you can return something as the original type is lost. This does not mean that it is impossible to implement, but it does not fit well into the existing infrastructure.
2 - Speed โโof execution of functions.
It is really simple: a function is an apply method on another object. You must have this object to call its method. It will always be slower (or at least not faster) than calling your own method, as you already have it.
As a practical matter, JVMs can do a very good job by inserting functions these days; there is often no performance difference if you mainly use your method or function without creating the function object again and again. If you have deeply embedded very short loops, you can create too many functions for yourself; moving them to the shafts outside the enclosed hinges can save time. But do not worry until you compare and know that there is a bottleneck; usually the JVM does the right thing.
source share