From 214a6587520807e51e828c1371ea69aaf5fc616a Mon Sep 17 00:00:00 2001 From: Mathieu Ledru Date: Tue, 13 Aug 2024 00:26:59 +0200 Subject: [PATCH] :bento: Update yflow example --- README.md | 1 + examples/ampYFlow.php | 60 ------------- examples/flow.php | 1 - examples/yflow.php | 203 +++++++++++------------------------------- 4 files changed, 52 insertions(+), 213 deletions(-) delete mode 100644 examples/ampYFlow.php diff --git a/README.md b/README.md index 61f4b349..db45527c 100644 --- a/README.md +++ b/README.md @@ -64,6 +64,7 @@ $flow($ip); A working script is available in the bundled `examples` directory - Run Flow : `php examples/flow.php` +- Run Y-Combinator Flow : `php examples/yflow.php` - Start Server : `php examples/server.php` Start Client(s) : `php examples/client.php` diff --git a/examples/ampYFlow.php b/examples/ampYFlow.php deleted file mode 100644 index c8efe17e..00000000 --- a/examples/ampYFlow.php +++ /dev/null @@ -1,60 +0,0 @@ - $f($f); -$Y = static fn (Closure $f) => $U(static fn (Closure $x) => $f(static fn ($y) => $U($x)($y))); - -$factorialYJobDeferBefore = static function (YFlowData $data) { - printf("* #%d - Job : Calculating factorial(%d)\n", $data->id, $data->number); - - return new YFlowData($data->id, $data->number, $data->number); -}; - -$asyncFactorialDefer = $Y(static function ($factorial) { - return static function ($args) use ($factorial) { - [$data, $defer] = $args; - - return $defer(static function ($complete, $async) use ($data, $defer, $factorial) { - if ($data->result <= 1) { - $complete([new YFlowData($data->id, $data->number, 1), $defer]); - } else { - $async($factorial([new YFlowData($data->id, $data->number, $data->result - 1), $defer]), static function ($result) use ($data, $complete) { - [$resultData, $defer] = $result; - $complete([new YFlowData($data->id, $data->number, $data->result * $resultData->result), $defer]); - }); - } - }); - }; -}); - -$factorialYJobDeferAfter = static function ($args) { - [$data, $defer] = $args; - - return $defer(static function ($complete) use ($data, $defer) { - printf("* #%d - Job : Result for factorial(%d) = %d\n", $data->id, $data->number, $data->result); - - $complete([new YFlowData($data->id, $data->number), $defer]); - }); -}; - -$driver = new FiberDriver(); - -$flow = (new Flow($factorialYJobDeferBefore, null, null, null, null, $driver)) - ->fn(new Flow($asyncFactorialDefer, null, null, null, new DeferAsyncHandler(), $driver)) - ->fn(new Flow($factorialYJobDeferAfter, null, null, null, new DeferAsyncHandler(), $driver)) -; - -$ip = new Ip(new YFlowData(5, 5, 5)); -$flow($ip); - -$flow->await(); diff --git a/examples/flow.php b/examples/flow.php index 0b53ba14..e697db3d 100644 --- a/examples/flow.php +++ b/examples/flow.php @@ -107,4 +107,3 @@ }; $asyncTask($job1, $job2, $job3, $errorJob1, $errorJob2, $driver); echo "ended - synchronous\n"; -echo 'maths - 4 + 4 = ' . (4 + 4) . "\n"; diff --git a/examples/yflow.php b/examples/yflow.php index 63436e60..4a4a1aea 100644 --- a/examples/yflow.php +++ b/examples/yflow.php @@ -4,7 +4,7 @@ require __DIR__ . '/../vendor/autoload.php'; -use Amp\Future; +use Flow\AsyncHandler\DeferAsyncHandler; use Flow\AsyncHandler\YAsyncHandler; use Flow\Driver\AmpDriver; use Flow\Driver\FiberDriver; @@ -16,61 +16,11 @@ use Flow\Flow\YFlow; use Flow\Ip; -use function Amp\async; - -$U = static fn ($f) => $f($f); -$Y = static fn (callable $f) => $U(static fn (Closure $x) => $f(static fn ($y) => $U($x)($y))); - -$asyncFactorial = $Y(static function ($fact) { - return static function ($n) use ($fact): Future { - return async(static function () use ($n, $fact) { - if ($n <= 1) { - return 1; - } - - $result = yield $fact($n - 1); - - return $n * $result; - }); - }; -}); - -$future = $asyncFactorial(5); - -$future->map(static function ($result) { - echo 'Factorial: ' . $result . PHP_EOL; -}); - -// $driver = new AmpDriver(); -// $driver-> - -/*$factorialYJob = static function ($factorial) { - return static function (YFlowData $data) use ($factorial): YFlowData { - return new YFlowData( - $data->id, - $data->number, - ($data->result <= 1) ? 1 : $data->result * $factorial(new YFlowData($data->id, $data->number, $data->result - 1))->result - ); - }; -}; - -$flow = (new Flow($factorialYJob, null, null, null, new YAsyncHandler(), $driver)) - ->fn(static function (YFlowData $data): YFlowData { - printf("* #%d - Job 4 : Result for factorial(%d) = %d\n", $data->id, $data->number, $data->result); - - return new YFlowData($data->id, $data->number); - }); - -$ip = new Ip(new YFlowData(5, 5, 5)); -$flow($ip); - -$flow->await();*/ - -/*$driver = match (random_int(1, 1)) { +$driver = match (random_int(1, 2)) { 1 => new AmpDriver(), - 2 => new FiberDriver(), - 3 => new ReactDriver(), - 4 => new SwooleDriver(), + 2 => new ReactDriver(), + // 3 => new FiberDriver(), + // 4 => new SwooleDriver(), // 5 => new SpatieDriver(), }; printf("Use %s\n", $driver::class); @@ -116,86 +66,9 @@ function factorialGen(callable $func): Closure function factorialYMemo(int $n): int { return Ymemo('factorialGen')($n); -}*/ - -/* -use Amp\Promise; -use Amp\Deferred; - -function Ywrap(callable $f, callable $wrapperFunc) { - $U = fn($x) => $x($x); - return $U(fn($x) => $f($wrapperFunc(fn($y) => Promise\wait($U($x)($y))))); } -function asyncWrapper(callable $f) { - return function($y) use ($f) { - $deferred = new Deferred(); - $deferred->resolve($f($y)); // Resolve immediately - return $deferred->promise(); - }; -} - -function Ymemo($f) { - return Ywrap($f, 'asyncWrapper'); -} - -function factorialGen(callable $func) { - return function (int $n) use ($func) { - $deferred = new Deferred(); - $result = ($n <= 1) ? 1 : $n * Promise\wait($func($n - 1)); - $deferred->resolve($result); // Resolve immediately - return $deferred->promise(); - }; -} - -function factorialYMemo(int $n) { - return Promise\wait(Ymemo('factorialGen')($n)); -} - -// Usage -Amp\Loop::run(function() { - $result = factorialYMemo(5); - echo $result; // Expected: 120 -}); -*/ - -/* -use Amp\Promise; - -class Flow { - // ... other combinators ... - - public static function Y($f) { - return (function ($x) use ($f) { - return $f(function ($y) use ($x) { - return Promise\wait($x($x)($y)); - }); - })(function ($x) { - return $f(function ($y) use ($x) { - return Promise\wait($x($x)($y)); - }); - }); - } - - // ... rest of the class ... -} - -use Amp\Loop; - -Loop::run(function() { - $factorial = Flow::Y(function ($f) { - return function ($x) use ($f) { - return $x == 0 ? 1 : $x * $f($x - 1); - }; - }); - - echo $factorial(5); // Outputs: 120 -}); -*/ - -// factorialYMemo(6) . ' ' . factorialYMemo(5); - -/*$factorialJob = static function (YFlowData $data): YFlowData { +$factorialJob = static function (YFlowData $data): YFlowData { printf("*... #%d - Job 1 : Calculating factorial(%d)\n", $data->id, $data->number); // raw factorial calculation @@ -207,7 +80,7 @@ public static function Y($f) { }; $factorialYJobBefore = static function (YFlowData $data): YFlowData { - printf(".*.. #%d - Job 2 : Calculating factorial(%d)\n", $data->id, $data->number); + printf(".*.. #%d - Job 2 : Calculating factorialYJob(%d)\n", $data->id, $data->number); return new YFlowData($data->id, $data->number, $data->number); }; @@ -223,7 +96,7 @@ public static function Y($f) { }; $factorialYJobAfter = static function (YFlowData $data): YFlowData { - printf(".*.. #%d - Job 2 : Result for factorial(%d) = %d\n", $data->id, $data->number, $data->result); + printf(".*.. #%d - Job 2 : Result for factorialYJob(%d) = %d\n", $data->id, $data->number, $data->result); return new YFlowData($data->id, $data->number); }; @@ -238,16 +111,41 @@ public static function Y($f) { return new YFlowData($data->id, $data->number); }; -$factorialYAsyncHandlerJobBefore = static function (YFlowData $data): YFlowData { - printf("...* #%d - Job 4 : Calculating factorial(%d)\n", $data->id, $data->number); +// Define the Y-Combinator +$U = static fn (Closure $f) => $f($f); +$Y = static fn (Closure $f) => $U(static fn (Closure $x) => $f(static fn ($y) => $U($x)($y))); + +$factorialYJobDeferBefore = static function (YFlowData $data) { + printf("...* #%d - Job 4 : Calculating factorialYJobDefer(%d)\n", $data->id, $data->number); return new YFlowData($data->id, $data->number, $data->number); }; -$factorialYAsyncHandlerJobAfter = static function (YFlowData $data): YFlowData { - printf("...* #%d - Job 4 : Result for factorial(%d) = %d\n", $data->id, $data->number, $data->result); +$factorialYJobDefer = $Y(static function ($factorial) { + return static function ($args) use ($factorial) { + [$data, $defer] = $args; + + return $defer(static function ($complete, $async) use ($data, $defer, $factorial) { + if ($data->result <= 1) { + $complete([new YFlowData($data->id, $data->number, 1), $defer]); + } else { + $async($factorial([new YFlowData($data->id, $data->number, $data->result - 1), $defer]), static function ($result) use ($data, $complete) { + [$resultData, $defer] = $result; + $complete([new YFlowData($data->id, $data->number, $data->result * $resultData->result), $defer]); + }); + } + }); + }; +}); + +$factorialYJobDeferAfter = static function ($args) { + [$data, $defer] = $args; - return new YFlowData($data->id, $data->number); + return $defer(static function ($complete) use ($data, $defer) { + printf("...* #%d - Job 4 : Result for factorialYJobDefer(%d) = %d\n", $data->id, $data->number, $data->result); + + $complete([new YFlowData($data->id, $data->number), $defer]); + }); }; $flow = Flow::do(static function () use ( @@ -256,22 +154,23 @@ public static function Y($f) { $factorialYJob, $factorialYJobAfter, $factorialYMemoJob, - $factorialYAsyncHandlerJobBefore, - $factorialYAsyncHandlerJobAfter + $factorialYJobDeferBefore, + $factorialYJobDefer, + $factorialYJobDeferAfter ) { - //yield [$factorialJob]; - //yield [$factorialYJobBefore]; - //yield new YFlow($factorialYJob); - //yield [$factorialYJobAfter]; - //yield [$factorialYMemoJob]; - yield [$factorialYAsyncHandlerJobBefore]; - yield [$factorialYJob, null, null, null, new YAsyncHandler()]; - yield [$factorialYAsyncHandlerJobAfter]; + yield [$factorialJob]; + yield [$factorialYJobBefore]; + yield new YFlow($factorialYJob); + yield [$factorialYJobAfter]; + yield [$factorialYMemoJob]; + yield [$factorialYJobDeferBefore]; + yield [$factorialYJobDefer, null, null, null, new DeferAsyncHandler()]; + yield [$factorialYJobDeferAfter, null, null, null, new DeferAsyncHandler()]; }, ['driver' => $driver]); -for ($i = 5; $i <= 5; $i++) { +for ($i = 1; $i <= 5; $i++) { $ip = new Ip(new YFlowData($i, $i)); $flow($ip); } -$flow->await();*/ +$flow->await();