Tuple functional spec draft

I put up a preliminary functional spec for tuples:

https://github.com/stan-dev/stan/wiki/Functional-Spec:-List-Tuple-types

Feedback is most welcome.

There are two problems I discuss in the draft spec:

  1. need a standalone sized data structure declaration syntax (easy)

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

  • Bob

This also depends on what version of the C++ library we are targeting. See
https://github.com/CppCon/CppCon2016/blob/master/Presentations/tuple,%20What’s%20New,%20And%20How%20It%20Works/tuple,%20What’s%20New,%20And%20How%20It%20Works%20-%20Stephan%20T.%20Lavavej%20-%20CppCon%202016.pdf

If foo[int] in the Stan language yields get<int>(foo) in C++, we would know it is the integer element.

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:

http://www.boost.org/doc/libs/1_61_0/libs/tuple/doc/tuple_users_guide.html#accessing_elements

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.

Just some thoughts which may bring some ideas, not a solution.

I do agree on the fact that I do not see how to calculate the return type for something dynamic like:

type? operator[](const int idx)

  • On the dynamic side I think the cleanest way to do that is by using something like std::variant

Maybe interesting to read the C++17 ruminations there: C++17 std::variant
There is also a boost implementation available there: boost.variant (boost 1.61)

  • On the static side

Personally I would prefer something like

template <int IDX<
auto& operator[](std::integral_constant<int,IDX< idx)

instead of:

template <int IDX<
auto& get()

IMHO the advantages are twofold:
1/ syntactically dynamic & static cases are nearly identical
2/ the C++ trend is to use things like:

template<int INTEGER<
constexpr integer_c = std::integral_constant<int,INTEGER<();

and to redefine operators to allow static computations like:

auto a = integer_c<4>();
auto b = 4*a+a;
auto result = my_tuple[b];

See Boost Hana library for instance.

Vincent

ps: I do not know how to write well formed template <> here, each time I use > the text after < is erased. That is the reason why I wrote

template<something<

Is there a trick to fix that?

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.

I’ll definitely check out Boost Hana.

  • Bob
1 Like

template

template <T>  

template <T>

Does it really show up right in the preview but wrong after posting?

It works either between back-ticks or in the “code” environment.

It does not work (for me) à in the preview
For instance I get:
template

When I write:
template >sometext<
(where i have reversed the < > order)

lt ampersand and gt ampersand in code context (triple back ticks)

template &lt;typename T&gt;

or just plain old angles:

template <typename T>

Or in running text with the escapes: <typename T>

  • Bob

in running text single backticks get you code context. These: `

Hi!

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 {};

Sebastian

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.

Sebastian

+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).

  • Bob

Boost Tuple has everything we need:

http://www.boost.org/doc/libs/1_61_0/libs/tuple/doc/tuple_users_guide.html

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.

  • Bob

Hi!

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.

Sebastian

I think Boost tuple will do everything we want. There’s also
a std::tuple in C++11:

http://www.cplusplus.com/reference/tuple/

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.

  • Bob