Thursday 1 August 2013

some more honest work

This morning I implemented getters for ltuples. You can now do things like

fmpzxx a;
int b = 0;
ltupleref(a, b).get<0>() == a;

Depending on the situation, the get() call may evaluate a lazy tuple (if the return type cannot be made lazy), or yield a lazy expression, or yield a reference without needing to evaluate (if the tuple itself is immediate).


After that I began work on allowing lazy functions with more than two arguments. This requires writing generic code to evaluate n possibly lazy expressions. Things can get as complicated as one wants, but for the sake of (a) simplicity, (b) compilation performance and (c) because of my distrust in the optimizer, I have now decided to do the following: If there are precisely two non-immediate subexpressions, do the clever logic we already have. Otherwise, we evaluate things strictly in-order.

This way no tests are broken, and the minimal number of temporaries is used if there are at most two non-immediate subexpressions. If there are more than two, then the code might be (slightly) non-optimal. I assume this should not be a particularly common case.

4 comments:

  1. This comment has been removed by the author.

    ReplyDelete
  2. This comment has been removed by the author.

    ReplyDelete
  3. That would indeed be uncommon. I can't even think of an exception off the top of my head.

    The tuple syntax looks reasonable under the circumstances.

    Perhaps the preprocessor might allow:

    #define item(x) get< x>()

    ReplyDelete
  4. I think most of the time clients would not use the get() syntax but instead the ltupleref(e1, e2) = ... syntax; the point being that since get only extracts one of the members, it is typically inefficient (e.g. divrem returns two things, but there are separate functions if you only want one of them).

    ReplyDelete