There are two problems I discuss in the draft spec:
need a standalone sized data structure declaration syntax (easy)
can’t calculate return type of operator[] statically, either in
C++ or Stan
The first one has a suggested solution, but the second is truly problematic
in that it means either we abandon static strong type checking for Stan
programs with a pointer-based hack, or we don’t allow indexing. Or someone
figures out a clever way we can have our cake and eat it too, but I don’t think
it’s logically possible.
I didn’t see a run-time indexing operation. They did provide one
that works statically, which won’t help us in Stan (unless we restrict
indexes to literals). I just don’t think it’s possible to do in
C++ with typing because there’s no way to resolve the type statically.
Boost does what I was suggesting and what I saw in the C++ presentation
Ben linked:
which is to have a function that takes the index as a static template
param.
The boost doc’s useful as they’ve thought this through more in
terms of promotions allowed in assignments of one tuple to another
(for us, that’d just mean int promoting to real).
Bob
P.S. I really didn’t need a broken pronunciation guide to "tuple"
written by someone who doesn’t understand English pronunciation and
accent variation. Never trust a Star Trek fan’s opinion of languages.
I’m already disliking how Discourse monkeys with our posts.
This is what you get with “markdown”.
I’m guessing you need “& g t ;” without space to get a right-angle,
as in here: >
I believe we’re still waiting on some C++11 issues with R
before we move on from C++03.
We could return a variant type on the C++ side, but that’s not
going to help on the Stan side, and it’s a huge pain to use such
a thing (as evidenced by our uses in the parser through Boost Spirit
Qi).
I don’t see how the integer constant types help, but I think I
may just be having trouble parsing the int and INT things.
Isn’t the boost fusion library what you want here? The fusion vector can hold a sequence of arbitrary typed objects and I guess they have the facilities to deduce the return type you want.
To get the template stuff correctly displayed, you can either put extra spaces
template < typename XX >
struct {};
or you put things here by using single back-quotes template <typename XX> struct {};
editing my last post does not work, so here again:
[Edit]: Sorry, now I see - you problem is to get from a runtime index to the static type at the given position. Counter-question: Is this really needed? I think this tuple stuff would already be very useful if we access positions of the tuple with some compile-time indexing only facility - so something like a tuple_instance<3> would give the 3. entry of the tuple. That can then be translated to fusion calls to get.
+1 To “do we need this”. I think tuples mostly solve the problem of multiple return types that can’t be packaged into an int[] or real[] or vector etc… so maybe we can just skip the headache here? Maybe it would be clearer that it’s worth the effort if we had use cases for it?
Krzysztof: I agree that we need it for multiple returns
Sebastian: I think we have to do what you suggest because there’s
no other alternative. We can use Boost’s tuples, which have a built-in
get function. We’d have to decide what to call the get functions in Stan.
They have to be static, so the only thing allowed will be a literal
(e.g., 3 not n) or literal expression (e.g., (4 * (4 + 1)) / 2).
Fusion is for adapting structures to act like lists/sequences.
It’s used all over the parser to define semantic structures
automatically in parser rules.
Maybe we can get the design such that the static get-operator can be applied to dynamically sized objects as well? If that is easy than this could be nice for users. Should this be hard to implement, then we should not bother.
If tupple does what we want, then that’s perfectly fine. From a quick read over the boost docu I thought it was too limiting, but I was really quick in reading.
The get operator requires its index to be static — it’s a template
parameter int.
Typing, such as matrix, has to be determined statically, but
sizing, such as 5 by 7, is dynamic. It’ll be just like the rest of
Stan (and C++ without pointer casts) as far as that goes.