Generators and Coroutines

itRec recursive???

recursive use of generators does not work! they have to pass the yield back throu the whole chain of calls
# key current
0 ( + 0) 0 0
1 ( + 1) 1 eins
2 ( + 2) (2 + 0) 2, 0 20
3 ( + 2) (2 + 1) (2, 1 + 0) 2, 1, 0 210
4 ( + 2) (2 + 1) (2, 1 + 1) 2, 1, 1 zweihundertelf
5 ( + 2) (2 + 1) (2, 1 + 2) (2, 1, 2 + 0) 2, 1, 2, 0 2120
6 ( + 2) (2 + 1) (2, 1 + 2) (2, 1, 2 + 1) 2, 1, 2, 1 2121
7 ( + 2) (2 + 1) (2, 1 + 3) 2, 1, 3 zweihundertdreizehn
8 ( + 2) (2 + 2) 2, 2 22
9 ( + 3) 3 drei
10 ( + 4) (4 + 0) 4, 0 40
11 ( + 4) (4 + 1) (4, 1 + 0) 4, 1, 0 410
12 ( + 5) 5 fuenfSchluss

itStack: simulating recursion by a manual stack of course works

# key current
0 0 0
1 1 eins
2 2, 0 20
3 2, 1, 0 210
4 2, 1, 1 zweihundertelf
5 2, 1, 2, 0 2120
6 2, 1, 2, 1 2121
7 2, 1, 3 zweihundertdreizehn
8 2, 2 22
9 3 drei
10 4, 0 40
11 4, 1, 0 410
12 5 fuenfSchluss

itOne

  1. main calls itOne(1) = Generator Object ( )
  2. itOne 1 begin
  3. itOne1 2 foreach vor yield itOne arg=1
  4. main it->valid() true , key() 0 , current = itOne arg=1
  5. itOne1 3 nach yield got null
  6. itOne1 4 foreach vor yield one
  7. main it->next() null , it->valid() true , key() 1 , current = one
  8. itOne1 5 nach yield got [so, send, it]
  9. itOne 1 begin
  10. itOne2 2 foreach vor yield itOne arg=2
  11. itOne1 6 subiterator got 0 => itOne arg=2 , yield+
  12. main it->send([so send it]) itOne arg=2+ , it->valid() true , key() 0+ , current = itOne arg=2+
  13. itOne2 3 nach yield got null
  14. itOne2 4 foreach vor yield one
  15. itOne1 7 subiterator got 1 => one , yield+
  16. main it->next() null , it->valid() true , key() 1+ , current = one+
  17. itOne2 5 nach yield got null
  18. itOne2 6 foreach vor yield zwei => two
  19. itOne1 8 subiterator got zwei => two , yield+
  20. main it->next() null , it->valid() true , key() zwei+ , current = two+
  21. itOne2 7 nach yield got null
  22. itOne2 8 foreach vor yield [nine, neun]
  23. itOne1 9 subiterator got 2 => [nine, neun] , yield+
  24. main it->next() null , it->valid() true , key() 2+ , current = [nine, neun]
  25. itOne2 9 nach yield got null
  26. itOne2 10 end
  27. itOne1 10 foreach vor yield zwei => two
  28. main it->next() null , it->valid() true , key() zwei , current = two
  29. itOne1 11 nach yield got null
  30. itOne1 12 foreach vor yield [nine, neun]
  31. main it->next() null , it->valid() true , key() 2 , current = [nine, neun]
  32. itOne1 13 nach yield got null
  33. itOne1 14 end
  34. main it->next() null , it->valid() false , key() null , current = null
  35. main it->next() null , it->valid() false , key() null , current = null

End e14genCorou.php

args

e14genCorou.php

/home/ch45859/web/wlkl.ch/public_html/inf/php/e14genCorou.php

*** code does not have a span berfore first <br>***
<?php

require_once('env.php');
outBegin('Generators and Coroutines');


function itRec($a, $p='') {
    if (! is_array($a)) {
        yield $p => $a;
    } else {
        $q = $p === '' ? '' : $p . ', ';
        foreach($a as $k => $v) {
            foreach( itRec($v, $q . $k) as $u => $v)
                yield "($p + $k) $u" => $v;
        }
    }
}

function itStack($arg) {
    $stack = [];
    $a = $arg;
    reset($a);
    $p = '';   

    while (true) {
        if (false === $c = current($a)) {
            if (null === $a = array_pop($stack))
                return;
            $p = substr($p, 0, strrpos($p, ','));
        } else {
            $k = key($a);
            next($a);
            if (is_array($c)) {
                array_push($stack, $a);
                $p .= ', ' . $k;
                $a = $c;
                reset($a);
            } else {
                yield substr($p . ', ' . $k, 2) => $c;
            }
        }
    }
}

function itOne($n) {
    $cont = ["itOne arg=$n", "one", "zwei" => "two", 9 => ['nine', 'neun']];
    $cx=0;
    outLi("itOne", ++$cx, "begin");
    foreach($cont as $k => $v) {
        if (! is_string($k)) {
            outLi("itOne$n", ++$cx, "foreach vor yield", $v);
            $o = yield $v;
        } else {
            outLi("itOne$n", ++$cx, "foreach vor yield $k =>", $v);
            $o = yield $k => $v;
        }
        outLi("itOne$n", ++$cx, "nach yield got", $o);
        if ($n == 1 and $o != null)
            foreach(itOne(2) as $r => $s) {
                outLi("itOne$n", ++$cx, "subiterator got $r =>", $s, ", yield+");
                yield "$r+" => (is_string($s) ? "$s+" : $s);
            }
    }
    outLi("itOne$n", ++$cx, "end");
}

outH('itRec recursive???');
out('recursive use of generators does not work! they have to pass the yield back throu the whole chain of calls');
outTB();
outTRH('#', 'key', 'current');
$cc = 0;
foreach( itRec([0, 'eins', [20, [210, 'zweihundertelf', [2120, 2121], 'zweihundertdreizehn'], 22], 'drei'
        , [40, [410]], 'fuenfSchluss']) as $k => $v)
    outTRD($cc++, $k, $v);
outTBEnd();
outH('itStack: simulating recursion by a manual stack of course works');
outTB();
outTRH('#', 'key', 'current');
$cc = 0;foreach( itStack([0, 'eins', [20, [210, 'zweihundertelf', [2120, 2121], 'zweihundertdreizehn'], 22], 'drei'
        , [40, [410]], 'fuenfSchluss']) as $k => $v)
    outTRD($cc++, $k, $v);
outTBEnd();

outH('itOne');
outOL();
outLi("main calls itOne(1) =", print_r($it = itOne(1), true));        
outLi("main it->valid()", $it->valid(), ", key()", $it->key(), ", current =", $it->current());
outLi("main it->next()", $it->next(), ", it->valid()", $it->valid(), ", key()", $it->key(), ", current =", $it->current());
outLi("main it->send([so send it])", $it->send(['so', 'send',  'it']), 
        ", it->valid()", $it->valid(), ", key()", $it->key(), ", current =", $it->current());
for ($i=0; $i < 7; $i++)
    outLi("main it->next()", $it->next(), ", it->valid()", $it->valid(), ", key()", $it->key(), ", current =", $it->current());
        
outEnd(__file__);
?>