Skip to content
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

Need clarification on Table constraint type & Table constructor #502

Closed
mohanvive opened this issue Apr 30, 2020 · 9 comments
Closed

Need clarification on Table constraint type & Table constructor #502

mohanvive opened this issue Apr 30, 2020 · 9 comments
Assignees
Labels
Area/Lang Relates to the Ballerina language specification design/incomplete Part of design not yet worked out

Comments

@mohanvive
Copy link

mohanvive commented Apr 30, 2020

I am expecting some clarification on the below statement regarding the Table.

"If there is no contextually expected type, then the member type of the inherent type is derived from the static type of the expressions for the members: the member type will be the smallest record type that is a supertype of the static types of all the expressions in the expr-list.
"

var tab = table [{ id: 13 , name: "Sanjiva", lname: "Weerawarana" },
                            { id: 23 , name: "James" },
                            { id: 133 , name: "Mohan", lname: "JJ" , address: "Colombo"} ];
  1. If we consider the above example what would be the member type. Whether below one is correct?
record {| 
    int id; 
    string name; 
    string lname?; 
    string address?; 
|}

Another question is, as per the spec table constraint type should be a subtype of map<any|error>. Then, it is possible to have a table as given below.

type CustomerTable table<map<any>>;
CustomerTable customerTable = table [{ id: 13 , name: "Sanjiva", lname: "Weerawarana" },
              { id: 23 , name: "James" , lname: "Clark" }];

But, in the spec when we talk about key specifiers and key constraint it is somewhat bound to record fields (i.e, record type).

  1. Is that meant, if the constraint type is other than record (for example, map) then it is always a keyless table?
@mohanvive mohanvive added the Area/Lang Relates to the Ballerina language specification label Apr 30, 2020
@jclark
Copy link
Collaborator

jclark commented Apr 30, 2020

There are three expressions for the members:

{ id: 13 , name: "Sanjiva", lname: "Weerawarana" }, // 1
 { id: 23 , name: "James" }, //2
 { id: 133 , name: "Mohan", lname: "JJ" , address: "Colombo"} //3

The static types of those expressions are determined as specified by the mapping constructor section of the spec:

record {| int id; string name; string lname; |} // 1
record {| int id; string name;  |} // 2
record {| int id; string name; string lname; string address; |} // 3

You get the smallest record type by unioning the types of the members, and making the fields that are not always present be optional, giving

record {| int id; string name; string lname?; string address?; |}

as you correctly deduced.

As for your question 2, if a table has an inherent type that is table<map<T>> key(S), then S must be empty. However, if a table belongs to type table<map<T>>, it means just that all we know about the table is that its rows belong to map<T>.

@jclark jclark closed this as completed Apr 30, 2020
@mohanvive
Copy link
Author

Thanks James for the prompt reply..

@mohanvive
Copy link
Author

mohanvive commented May 6, 2020

@jclark , there is a followup question on this. I appreciate, your input on this.
Let's take the below example,

var tabObj = table key(id) [];

As per the current grammar, the above syntax is possible. Then what is the member of the table?
Whether below is correct?

record {| int id; |}

or do you have any other suggestions?

@jclark
Copy link
Collaborator

jclark commented May 6, 2020

I would either make this a compile-time error, or infer a type of

record {  // NB: open
  (anydata & readonly) id;
};

since there is no information that indicates a more restrictive type than this.

@jclark
Copy link
Collaborator

jclark commented May 6, 2020

The spec should say something about this.

@jclark jclark reopened this May 6, 2020
@jclark jclark added the design/incomplete Part of design not yet worked out label May 6, 2020
@jclark jclark added this to the 2020R2 milestone May 6, 2020
@mohanvive
Copy link
Author

mohanvive commented May 6, 2020

I have mixed opinions on both options.
If we consider the option #2, then for below example

var tabObj = table [];

member type needs to be something like below,

record {  // NB: open

};

Providing a compile error might be a simple and good solution. Then, we could simply mention that mapping constructor exprs are a must to infer the member type.

@jclark
Copy link
Collaborator

jclark commented May 6, 2020

I am fine with a compile error. If it turns out to be a problem, we can always relax the constraint.

@pcnfernando
Copy link
Member

As for your question 2, if a table has an inherent type that is table<map<T>> key(S), then S must be empty. However, if a table belongs to type table<map<T>>, it means just that all we know about the table is that its rows belong to map<T>.

Should the spec say something about this?

@pcnfernando pcnfernando reopened this Jul 6, 2021
@jclark
Copy link
Collaborator

jclark commented Jul 6, 2021

@pcnfernando If there's something that's still not clear in the spec after 65074f9, please open a new issue with an example that the spec is not clear about and link to this issue.

@jclark jclark closed this as completed Jul 6, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area/Lang Relates to the Ballerina language specification design/incomplete Part of design not yet worked out
Projects
None yet
Development

No branches or pull requests

3 participants