@avehtari and I were discussing today that there are many cases where tuples can be used but are sub-optimal because you need to track that t.1 is one thing and t.2 is another, without naming those.
The natural extension of this is a named tuple/struct/record type, where which would enable usages like qr_result = qr(M); print(qr_result.Q);
The implementation difficulty of these types was mostly solved while developing tuples.
But there is a lot of language-level questions we’d want to answer before adding them to Stan, which is the point of this post to ask for feedback on (basically the only thing I think people do already agree on is that variable.name would be how you access a piece of one)
Question 1: Syntax for types
How do you write down a type of these? Lets say I want a type with an element named Q and an element named R.
tuple(Q : matrix[N,N], R : matrix[N, N])?
struct { matrix[N,N] Q; matrix[N,N] R; };?
…?
Presumably we would also like to give names to these types. Should we have a types {} block before functions {}? How would that look?
types {
type my_struct = ...;
}
types {
struct my_struct { ... } ;
}
…
Note that we’d really need these to be parameterized over sizes, so something like type[N,M] my_struct = tuple(vector[N], vector[M]); would be possible
Do we want to allow inline usages, or should we force you to give them all names?
Question 2: Syntax for expressions
Essentially the same question as above: how do we want it to look to create a value of one of these types.
If they have names, we could use ‘constructor style’: my_struct(Q, R)
If they don’t, we could introduce some new syntax. In ML family of languages, they use {Q=...; R=...}.
Question 3: Does order matter?
Is struct { matrix[N,N] Q; matrix[N,N] R; }; a different type than struct { matrix[N,N] R; matrix[N,N] Q; };?
This influences the syntax question above. C family languages usually say yes; ML family and dynamic languages like Javascript would say no.
Question 4: Is subtyping possible?
Related to the ordering question, if I have a function that expects a { real x; real y; } struct, should I be able to pass { int x; int y; } to it? Should I be able to pass { real x; real y; real z; }?