Description
If we change the declaration of the Function
class to class Function<P extends Record, R>
and special-case Function<(int, int), int>
to mean the function type int Function(int, int)
, and allowing Function<Record, T>
to represent any function with return type T
, then we get a way to abstract over parameter list shape, while knowing the return type: Function<Record, int> f
is a function which returns an int
.
The grammar is free since Function<...>
must currently be part of the special form Function<...>(...)
for a generic function type, it's a compile-time error to have Function<...>
not followed by a parenthesis.
Not all parameter lists can be represented by records. A record cannot represent optional parameters. We can see methods with optional parameters as a kind of union type, and this syntax only produces the leaf types used by those unions.
I still think it will be very useful in some kinds of code (Even just making Function.apply
have type R apply<R>(Function<Record, R> f, List positionalArguments, [Map<Symbol, Object?>? namedArguments]))
would be an improvement, we could tell the return type from the invocation, without being able to represent the entire function type.
Maybe this is no better than simply giving Function
as single type argument, which is the return type, and not try to abstract over argument shapes.