3

Consider the following code which prints out the even numbers up to 20:

import std.stdio;

class count_to_ten{
    static int opApply()(int delegate(ref int) dg) {
        int i = 1;
        int ret;
        while(i <= 10){
            ret = dg(i);
            if(ret != 0) {
                break;
            }
            i++;
        }
        return ret;
    }
}

void main() {
    int y = 2;
    foreach(int x; count_to_ten) {
        writeln(x * y);
    }
}

The syntax of opApply requires that it take a delegate or function as a normal argument. However, even if we relaxed that and allowed opApply to take a function as a template argument, we still would have no recourse for delegates because D doesn't provide any way to separate the stack-frame pointer from the function pointer. However, this seems like it should be possible since the function-pointer part of the delegate is commonly a compile-time constant. And if we could do that and the body of the loop was short, then it could actually be inlined which might speed this code up quite a bit.

Is there any way to do this? Does the D compiler have some trick by which it happens automagically?

dspyz
  • 5,280
  • 2
  • 25
  • 63
  • You could use a, so called, external iteration to enable foreach for your types. It wouldn't have the inlining problems you've described. Are you aware of that approach? – Sergei Nosov Mar 12 '14 at 10:17
  • No, could you explain it? – dspyz Mar 12 '14 at 14:15
  • If you implement 3 methods - bool empty(), T front() and void popFront() for your type, then it will be considered an InputRange by the language and foreach loop will be able to iterate through it. Ranges are fundamental concepts in D, you can read more about it here http://ddili.org/ders/d.en/ranges.html – Sergei Nosov Mar 12 '14 at 14:44
  • If the compiler is smart it will be able to inline `opApply` and then the loop body. From there it should be able to generate efficient code. – BCS Mar 12 '14 at 14:59
  • @SergeiNosov That really defeats the purpose. Iterators are available in any language (C++, Java, etc.). The point here was to have an generator-like approach to iteration that's just as efficient as a standard iterator-like approach. Is there really no way to separate the function pointer and stack frame pointer in a delegate? I don't care so much whether I can use the nifty foreach syntax, but this seems like something D should offer considering that D is so concerned with efficiency and this is a fairly common pattern. – dspyz Mar 12 '14 at 16:07
  • @BCS How do I know that opApply is being inlined? Can I make that happen? What if opApply is large and I don't want it to be inlined, just the argument to it? Can I do that? – dspyz Mar 12 '14 at 16:15
  • Hold on, now I'm even more confused. I just realized I've seen examples before where a delegate is taken as a template parameter. How is that possible? Does D special-case delegates-as-templates so that the stack-frame pointer is actually passed as a hidden argument separate from the function pointer? I'll open a new question for that – dspyz Mar 12 '14 at 16:24
  • @SergeiNosov Would you mind taking a look at the question I just posted? http://stackoverflow.com/questions/22358067/how-does-d-allow-delegates-as-template-parameters – dspyz Mar 12 '14 at 16:46
  • @BCS Would you mind taking a look at the question I just posted? http://stackoverflow.com/questions/22358067/how-does-d-allow-delegates-as-template-parameters – dspyz Mar 12 '14 at 16:46
  • 1
    You can check if a function is inlined by looking at the disassembly. -- As to the size of `opApply`: in-lining the delegate will have the exact same cost as fully inlining things because you would need to generate a new copy of the `opApply` code for every `foreach` either way (the inlined delegate is different for every site). – BCS Mar 12 '14 at 17:01
  • @BCS Oh of course (duh). Thanks, you're quite right. There is no reason not to inline it if it's a template. – dspyz Mar 12 '14 at 17:21
  • @BCS compilers aren't smart (they are reactive systems -> stupid) BUT the people who wrote it are smart – Quonux Mar 13 '14 at 18:20
  • Possible duplicate of [pure function of functions that returns functions in D](http://stackoverflow.com/questions/6805566/pure-function-of-functions-that-returns-functions-in-d) – Paul Sweatte May 20 '17 at 18:55

0 Answers0