ballerina-spec
ballerina-spec copied to clipboard
What is role of filler value in choosing inherent type for list constructor?
Intuitively filler values should only be used if an inherent type can't be selected without it.
Eg:
[int]|[int, int] t1 = [1];
in this case it should pick [int]
.
[int, int]|[int, int, int] t2 = [1];
in this case it should pick [int, int]
.
The spec https://ballerina.io/spec/lang/master/#section_6.7.1 is not super clear here, but, as written, the filler value is not considered when figuring out which member of the union to use.
Related to this is what is role of when choosing inherent type for mapping constructor.
Another point is whether fromJsonWithType/cloneWithType should use filler values. I don't think they should.
Another point is whether fromJsonWithType/cloneWithType should use filler values. I don't think they should.
~~Doesn't this goes against the principal that 'code should be more picky than fromJsonWithType' we are going to use when selecting form a union?~~
Edit:
You are proposing not to use filler for determining union for both fromJsonWithType and code.
This means:
[int, int] a = [1];
works, use filler
[int, int]|string a = [1];
works, use filler
[int, int]|[int, int, int] t2 = [1];
compile time error
Sound good to me.
I think the principles are:
- we should encourage code to be explicit except where this would be unacceptably inconvenient
- fromJsonWithType should work sensibly with types generated from OpenAPI schemas
I don't think filling is consistent with 2. If my schema has [int, int]
, and my document has [1]
, then I think the right behavior for fromJsonWithType
is to say that the document does not conform to the schema.
On the other hand, filling is needed in code so I can e.g. conveniently initialize an int[1000]
with all zeros.
So you are suggesting to
[int, int]|string a = [1];
is should be a compile time error ryt?
Isn't this is also inconsistent, because we allow filling for [int, int] a = [1];
I agree with James's comment that the filler value should work with cases like int[1000]
and not with cases like fromJsonWithType
. This means is constructors and fromJsonWithType
cases diverge a bit.
I also think, we should give a compile time error, when the compiler can't infer the type for a constructor safely i.e., int[2]|int[3] x = [];
, string[1]|int[1] = [];
. It is good to ask the code to be explicit in such cases. For the case @SasinduDilshara mentioned, we can safely pick a type for the constructor, and we can allow it.
@hasithaa I agree with your comment.
The case I am not sure about is
int[1] | int[2] x = [17];
In this case, the list constructor is compatible with the first alternative int[1]
without filling, but is compatible with the second alternative with filling. If we did not do filling, there would be no possible ambiguity here. The rules for filling should not, in my view, create ambiguity where previously there was none, which suggests that this should be allowed.
Had a discussion with @jclark and I too agree the example int[1] | int[2] x = [17];
should work. The filling is a mechanism to help the developer and we should apply only when needed.