Description
Feature idea
TLDR: Named arguments/parameters have the potential to make certain types of function invocations much more readable and concise and make it easier to extend APIs without breaking existing code. On the other hand, they can also sometimes unnecessarily bloat code and lead to problems when renaming parameters. I therefore suggest adding support for this feature to ASPL but leaving positional arguments as the default.
Note
When I'm talking about "functions" here, I am actually refering to "callables" in general (that is, the whole set of "invocable" things, including actual functions, methods and callbacks; reactive properties are also "callables", but they do not play a role here), but since this is common terminology, most readers will probably be familiar with this use of the word "function" already.
Have a look at the following code example:
function log(double value, double base = 2.718281828459045, double? modulus = null) returns double{
// ...
}
This log
function computes the logarithm of value
with respect to base
and optionally applies a modulo operation at the end, keeping the return value between 0 and modulus
.
Currently, if you want to compute some modular ln(x)
with this function (i.e. only passing arguments for value
and modulus
and keeping base
as e
), you still have to provide values for all three parameters like this:
log(x, 2.718281828459045, m)
There are at least three major problems with this:
-
You still have to pass a value for
base
even though you wanted to rely on the default; this is okay here ase
is simply a constant, but for more complicated functions, you might not even know or care about the value of some parameters and it would be much better if the compiler allowed you to automatically insert a default value specified in the function signature - which it already does (this feature is called "optional parameters/arguments"), just not when you want to set a value for another parameter after the one you want to leave out. -
It is not directly apparent what each value in your function invocation is supposed to mean - of course, if you read the signature or documentation of that function or if your IDE hints you with the associated parameter names, this shouldn't be a major problem, but it's still a little unreadable in certain situations.
-
Adding more parameters to a function or changing the order of them can easily break existing code that includes calls to that function.
The - in my opinion - most straight-forward and powerful solution to these problems is the use of "named arguments". A call to log
using named arguments might look like this:
log(value: x, modulus: m)
Or, if we allow mixing positional and named arguments, it might simply be:
log(x, modulus: m)
I'm not sure yet if allowing such mixed function calls is a good idea though - what do you think?
Possible solutions/implementations
No response
Alternatives considered
One relatively common alternative to named arguments are trailing struct literals (like in V for example). But I don't think this really fits the design of ASPL and would bring unnecessary boilerplate code to most codebases that need such a feature.
Another thing that would reduce but not entirely eliminate the need of named arguments could be a default
keyword to leave out optional parameters and tell the compiler to use the default value there:
log(x, default, m)
But I personally find that this is not so easy to read and still maintains some of the other problems discussed above (changing a function signature breaks code very easily, unneccessarily long arguments list for functions with lots of optional parameters, ...). Thus, I would instead favour named arguments over a default
keyword.
Additional context
We could also make named arguments the default or even obligatory, but I think this would unnecessarily bloat up most code, so I probably wouldn't do that. What do you think?
And finally, there's the syntactic discussion: instead of a colon (:
) (which is what most languages use for named arguments), we could also use an equals sign (=
) (which would more closely resemble all other assignments in ASPL) or some other symbol like the arrow used for key-value pairs in maps (=>
). We could also add a prefix for the argument name, e.g. @modulus: x
. I'm open for discussion here.
Contributing guidelines
- I agree to follow this project's contributing guidelines