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
- main calls itOne(1) = Generator Object
(
)
- itOne 1 begin
- itOne1 2 foreach vor yield itOne arg=1
- main it->valid() true , key() 0 , current = itOne arg=1
- itOne1 3 nach yield got null
- itOne1 4 foreach vor yield one
- main it->next() null , it->valid() true , key() 1 , current = one
- itOne1 5 nach yield got [so, send, it]
- itOne 1 begin
- itOne2 2 foreach vor yield itOne arg=2
- itOne1 6 subiterator got 0 => itOne arg=2 , yield+
- main it->send([so send it]) itOne arg=2+ , it->valid() true , key() 0+ , current = itOne arg=2+
- itOne2 3 nach yield got null
- itOne2 4 foreach vor yield one
- itOne1 7 subiterator got 1 => one , yield+
- main it->next() null , it->valid() true , key() 1+ , current = one+
- itOne2 5 nach yield got null
- itOne2 6 foreach vor yield zwei => two
- itOne1 8 subiterator got zwei => two , yield+
- main it->next() null , it->valid() true , key() zwei+ , current = two+
- itOne2 7 nach yield got null
- itOne2 8 foreach vor yield [nine, neun]
- itOne1 9 subiterator got 2 => [nine, neun] , yield+
- main it->next() null , it->valid() true , key() 2+ , current = [nine, neun]
- itOne2 9 nach yield got null
- itOne2 10 end
- itOne1 10 foreach vor yield zwei => two
- main it->next() null , it->valid() true , key() zwei , current = two
- itOne1 11 nach yield got null
- itOne1 12 foreach vor yield [nine, neun]
- main it->next() null , it->valid() true , key() 2 , current = [nine, neun]
- itOne1 13 nach yield got null
- itOne1 14 end
- main it->next() null , it->valid() false , key() null , current = null
- 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__);
?>