Monday, August 15, 2016

[kctmprub] Selecting function arguments by type

Some programming languages permit a function to refer the arguments passed to it by number instead of by name, for example, Perl's @_ array.

We propose a similar mechanism of referring to function arguments by type.  This can only be done if there is only one argument of the given type in the list of parameters.  We introduce a special keyword, ARGUMENT_OF_TYPE, which when used with a type yields the desired argument.  Below, we use a syntax inspired by Haskell.

replicate_strings :: Int -> String -> String;
replicate_strings UNNAMED UNNAMED = concat $ intersperse " " $ replicate (ARGUMENT_OF_TYPE::Int) (ARGUMENT_OF_TYPE::String);

Somewhat more ambitious, possibly more confusing, would be to have type inference figure out which argument is needed.

replicate_strings :: Int -> String -> String;
replicate_strings UNNAMED UNNAMED = concat $ intersperse " " $ replicate ARGUMENT_OF_TYPE ARGUMENT_OF_TYPE;

The keyword UNNAMED marks the function arguments subject to this kind of inference.  They are awkward, but without them, it may be difficult or awkward for a function to return a function, i.e., it is a higher order function.  Perhaps it has a polymorphic return type which might or might not be function.

More ambitiously, if the arguments are of distinct types, then there could be some mechanism by which the order of the arguments at the call site does not matter.  Previously related ideas, for multiple element tuples and pairs.

Another idea: instead of UNNAMED being a keyword, let the parameters be user-chosen identifiers that do not have to be different for each parameter, but if they have the same name, they must be different types.  Add a (possibly optional) OVERLOADED_PARAMETER annotation to make things less confusing to others reading the code:

replicate_strings2 :: Int -> String -> Int -> String -> (String, String);
replicate_strings2 (OVERLOADED_PARAMETER x) (OVERLOADED_PARAMETER x) (OVERLOADED_PARAMETER y) (OVERLOADED_PARAMETER y) = (concat $ intersperse " " $ replicate (x::Int) (x::String), concat $ intersperse " " $ replicate (y::Int) (y::String))

No comments :