Как реализовать цикл while в D?

Я знаю, что в D уже есть цикл while, но из-за его расширенных функций я хотел бы посмотреть, как бы он выглядел, если бы цикл while был реализован в коде.

мотивация: принятый ответ на этот вопрос на SO.


person Arlen    schedule 14.07.2011    source источник
comment
n.b. -- Если кому-то интересно, ответ, называемый мотивацией, касается Haskell, и я предполагаю, что это помечено как таковое.   -  person C. A. McCann    schedule 14.07.2011
comment
@camccann Верно. Я начал изучать Haskell и достаточно знаю D, чтобы захотеть увидеть цикл while, реализованный в D, просто для сравнения.   -  person Arlen    schedule 14.07.2011
comment
Все в порядке. Просто из вопроса не было ясно, почему он был помечен [haskell], комментарий был направлен на людей, читающих вопрос, а не на вас. Хотя может быть не помешает добавить некоторые детали (например, что в другом вопросе есть код Haskell, что вас интересует сравнение и т. д.).   -  person C. A. McCann    schedule 14.07.2011
comment
@Arlen: Цель пометки вопроса как Haskell состоит в том, чтобы привлечь к вопросу людей, заинтересованных в Haskell. Эти люди очень удивлены, что вопрос не о Haskell.   -  person Dietrich Epp    schedule 14.07.2011


Ответы (2)


Использование ленивых параметров функции:

void whileLoop(lazy bool cond, void delegate() loopBody) {
Begin:
    if(!cond) return;
    loopBody();
    goto Begin;
}

// Test it out.
void main() {
    import std.stdio;

    int i;
    whileLoop(i < 10, {
        writeln(i);
        i++;
    });
}
person dsimcha    schedule 14.07.2011

используя функцию с рекурсией: (хвостовой вызов будет оптимизирован;))

void whileLoop(bool delegate() cond,void delegate() fun){
    if(cond()){
        fun();
        whileLoop(cond,fun);
    }
}

замыкания должны использоваться с этим

или используя чрезмерно/недостаточно используемый goto

startloop:if(!condition)goto endloop;
//code
goto startloop;
endloop:;
person ratchet freak    schedule 14.07.2011
comment
оптимизация хвостового вызова [необходима ссылка]? - person BCS; 14.07.2011
comment
@BCS рекурсивный вызов будет преобразован в goto к началу функции, и во время рекурсии не будет создаваться накладных расходов стека (это можно сделать, когда при возврате не требуется выполнять код разрыва стека) - person ratchet freak; 14.07.2011
comment
Хорошо, я думаю, я был двусмысленным. Я имел в виду; Это деталь реализации DMD или D требует, чтобы это было сделано? -- Если это первое, это может привести к сбою с соответствующими компиляторами. Если второе, дайте ссылку. - person BCS; 15.07.2011
comment
@BCS это может сделать любой приличный компилятор с любой оптимизацией, но на самом деле это деталь DMD, а не D - person ratchet freak; 15.07.2011