language icon indicating copy to clipboard operation
language copied to clipboard

Allow augmenting function declarations to specify default values.

Open lrhn opened this issue 1 year ago • 1 comments

TL;DR: Allow an augmenting function to provide a default value for an optional parameter, if one is missing (parameter non-nullable and has no default value), and allow the base declaration to omit default values.

An augmenting function (top-level, static or method) is currently specified as not being allowed to declare any default values. All default values must be supplied by the original non-augmenting declaration (let's call it the "base declaration" for shortness).

That prevents one possible use, which is to have the base declaration not declare a default value, and provide on in an augmentation. It's fair that anything you can see on the base declaration is true, but a base declaration doesn't have to be complete. It can, fx, choose to have no body, and have the implementation supplied by an augmentation.

It seems fair to allow a base declaration to declare no body and an optional parameter with no default value, and then have an augmentation provide the entire impelmentation, including the choice of default value. That choice is linked to the body, which is the code that receives the value.

I suggest allowing an augmenting function declaration to specify a default value for an optional parameter, if and only ifthe augmented declaration has no default value for that parameter, and the parameter is not nullable. (That is, if the default value is clearly missing.)

We can also allow overriding the declared default value, but that's can be more confusing to a reader, who might think they can omit an argument when it's equal to the existing default value. If the default value then changes, then that conclusion may be wrong. (I'm personally strongly of the opinion that default values shouldn't be considered public API, but rather an internal implementation detail, so nobody should use that kind of logic. That's not how it's presented today, though.) If we want to allow overriding default values, we could allow so also if: * The augmented declaration has no default value for that parameter, and has no body (after applying all prior augmentations). (No existing code will see a surprising new default value.) * The augmenting declaration has a body. (Only the new body sees the new default value. Calling augmented should be done carefully, but it always should.)

This should still ensure that no augmented code sees a new and surprising default value.

lrhn avatar May 15 '24 11:05 lrhn

How would this interact with inferring required for parameters?

Whether a parameter is required or not is a part of the functions core API (and even its type, I assume). This works OK with todays semantics, but if we start inferring required then an augmentation can alter that property (change a parameter from required to not).

If I had to choose between allowing augmentations to provide a default value versus removing all the unnecessary required keywords, I would choose the latter.

jakemac53 avatar May 15 '24 14:05 jakemac53

I am going to close this as not planned. We could re-evaluate it later if we have a compelling use case, but I think it isn't worth the potential of making inferring required more difficult in the future.

jakemac53 avatar Jul 31 '24 17:07 jakemac53