ballerina-spec icon indicating copy to clipboard operation
ballerina-spec copied to clipboard

What is role of filler value in choosing inherent type for list constructor?

Open manuranga opened this issue 2 years ago • 9 comments

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].

manuranga avatar Aug 02 '22 02:08 manuranga

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.

jclark avatar Aug 02 '22 03:08 jclark

Related to this is what is role of when choosing inherent type for mapping constructor.

jclark avatar Aug 02 '22 03:08 jclark

Another point is whether fromJsonWithType/cloneWithType should use filler values. I don't think they should.

jclark avatar Aug 02 '22 03:08 jclark

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.

manuranga avatar Aug 02 '22 03:08 manuranga

I think the principles are:

  1. we should encourage code to be explicit except where this would be unacceptably inconvenient
  2. 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.

jclark avatar Aug 02 '22 04:08 jclark

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];

SasinduDilshara avatar Aug 09 '22 06:08 SasinduDilshara

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 avatar Sep 20 '22 03:09 hasithaa

@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.

jclark avatar Sep 20 '22 03:09 jclark

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.

hasithaa avatar Sep 20 '22 04:09 hasithaa