-
Notifications
You must be signed in to change notification settings - Fork 205
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
In a function, non-nullable optional parameters with default value should allow to be called with nullable values #1639
Comments
Why not just declare the type of the optional parameter as I don't think it's a great idea to allow passing null as the value of an optional parameter even in the case where that parameter has a non-nullable type: This just means that we give up null checks on that parameter, and that means that we can have a number of bugs where the parameter gets the default value because of an unintended null, which is basically just another kind of null error. Conversely, if the parameter has a nullable type then it would surely be confusing if passing null to that parameter wouldn't cause that parameter to have the value null. void f([int? i = 42]) => print(i);
void main() => f(null); // Prints '42'! |
Because I know that this parameter should never be null in my
the parameter would get the default value in the case of an implicit |
Yes, that is another solution, but not really satisfying either as it obfuscate the fact that x would actually receive a default value (when calling the function from another part of your code, you will have to actually look at the content of the function to see that x is assigned a default value, the description of the function will no longer make a reference to the fact that x has a default value. It therefore amounts to no longer being able to benefit from the advantage for which the parameter declaration with a default value was created in the language: knowing at a glance which parameter of a function will be assigned a default value in case of lack of information on its value.) |
@ramsestom wrote:
I don't see how it could be justified to say that null is passed implicitly in the situation where a given optional parameter isn't passed. It's not there, and there is no particular value that you can claim for it. In that situation the default value will be passed, and that doesn't have to be null (and with a non-nullable type it actually can't be null). void print2([String s = 'No argument provided!']) => print(s);
// Works like a set of functions, one for each actual argument list shape:
void print2$0() => print2$1('No argument provided!'); // Pass default values for each omitted argument.
void print2$1(String s) => print(s);
I mentioned two cases:
|
@ramsestom wrote:
I just don't buy this. |
call So yes f() and f(null) is exactly the same thing. An optional parameter is automatically considered as |
With |
Can't disagree more.
|
I also want to treat passing It's not what we did, and changing it now is a breaking change. |
Including this one?: void main() {
print('Hello, world!', null); // OK!
} |
I'd put it the opposite way: Passing nothing for a parameter is the same as passing Let's define fully what I'd want (and will likely never get):
I'm fairly sure I am forgetting at least one thing which really annoyingly doesn't work well. |
I saw you exemple but in my point of view the goal of the NNBD approach is not to detect any kind of typo in a code.
or simply forgot to call the computeCreditScore with a second argument
the result would be the same and the compiler won't complain, with or without the NNBD. |
I am not proposing to ignore a null value due to a non or miss-assigment in absolute.
I'm not a fan of NNBD either ;) |
@ramsestom, what would you have the following program print: foo([String? optional = "default") {
print(optional);
}
main() {
foo(null));
} In other words, in cases where Whichever answer you choose, how can you be certain that that is the behavior that most Dart users will intuitively expect? |
@munificent foo([String optional = "default") {
print(optional);
}
main() {
foo(null));
} So you know that you would never want a String? nativehi = "bonjour";
String hi = nativhi ?? "hello"; //<- notice the typo on nativehi here
print(hi); The compiler won't crash on the So if you have printHi([String hi = "hello"]) {
print(hi);
}
String? nativehi = "bonjour";
printHi(nativhi); it should be exactly the same. As for the possibility to have a nullable optional parameter with a default like: foo([String? optional = "default") {
print(optional);
} and what to do if we pass this function a |
@munificent I'd very happily make it print "default". |
Prior to NNBD, Dart was automatically giving a foo([String optional = "default") {
print(optional);
}
main() {
foo(null));
} would print "default" prior to NNBD. Even if the ability to distinguish |
@ramsestom @tatumizer A quick code search finds a few cases of a nullable parameter with a (non- I'd say that it's almost invariably a bug to have a nullable parameter with a non-null default value. |
I think this issue just highlights the importance of having some way to programmatically not pass an argument, preferably relying on null. I know there is discussion of this on #219, and I particularly support the use of the Combining @munificent's example here with one of @tatumizer's proposals on @219: printNullableWithDefault([String? optional = "This is the default option"]) {
print(optional);
}
String? getValue() => null; // pretend this does actual work
main() {
String? value = getValue(); // turns out to be null
printNullableWithDefault(value); // prints null
printNullableWithDefault(value ?? default); // prints the default value
} Since |
I would really like to have a similar solution to avoid redundant code and improve readability and maintainability. Examples (from Levi-Lesches' quoted code): Above code prints the default value because it's equivalent to
This would allow to code new functions/classes/FlutterWidgets reusing/calling/returning existing functions/classes/FlutterWidgets having optional parameters with defined defaults, without the need to redefine the default value. |
Expanding on previous reasoning, i've focused on two main reason to consider this feature, as i mentioned in #2269 1. Default values duplicationExtending a class which constructor parameters are non-nullable and have default values:
We are forced to duplicate default values definition. This adds boilerplate and/or sources of bugs if a default value is modified. In a chain of extensions the problem increases even more. What is desired is something like:
2. Ignore passed argument value if nullAnother related issue, that needs a different solution, arises when you have to pass a nullable value to a non-nullable parameter with defined default and you want to use default value if null:
In this case, desired solution is something like:
|
I am trying to migrate a (large) flutter app to null sound safety and I encountered an issue on some functions where the dart control flow analyzer is complaining if I try to assign a nullable value to a non nullable optional parameter with a default value
For exemple, I have a function defined like this:
static Vector pixelsToWorld(Vector xyz, Matrix4 pixelUnprojectionMatrix, [double targetZ=0])
So the
targetZ
parametter is optional and default to 0The problem is I have some objects that have a
targetZ
nullable property (double?
) and that have to keep this as it is (because I want to be able to differentiate objects that have some information on thistargetZ
property (targetZ
can have a 0 value or something else in this case) from those that don't (in that case thetargetZ
property would be null)).When I try to call my
pixelsToWorld
function from one of these objects, the flow analyzer is complaining thatThe argument type 'double?' can't be assigned to the parameter type 'double'
So, if I want to get rid of this error, I have to test if my
targetZ
value is null or not before calling thepixelsToWorld
function without or with this optional parameter, which is not really convenient...Wouldn't it make more sense to automatically attribute an optional parametter with a default value its default value if the function is called with a null value for it? (alter all that is what default parameter values are meant for, assign a default value in case of a missing information on the value of this parameter, be it because of an implicit or explicit
null
)The text was updated successfully, but these errors were encountered: