Achieving “functional core, imperative shell” using generators and promises

  • This topic has 4 replies, 1 voice, and was last updated 1 week, 1 day ago by __matta.
Viewing 5 posts - 1 through 5 (of 5 total)
  • Author
  • #5784

    Look at this example code from [Amphp](

    try {
    $request = new Request(“”);
    $response = yield $http->request($request); // Yield a promise

    if ($response->getStatus() !== 200) {
    throw new HttpException;
    } catch (HttpException $e) {
    // handle error

    This code-snippet is pure, no IO is happening. If the request call had been written as

    $response = $http->request($request);

    it would have been effectful, not pure; we’d have to mock the $http object when testing it. Using `yield`, we don’t. Does this mean we can remove the need for mocks if we use generators and wrap all side-effects in promises, as Amphp does? Discuss in small groups. 🙂

    The “imperative shell” in this scenario is the event loop resolving the promises. All other code can be pure.

    A bonus is that we also get non-blocking IO (concurrency) this way.

    (Resources about functional core, imperative shell can be found [here](


    I don’t get why this for you means that you wouldn’t have to mock `$http` during testing, or why this isn’t a side effect in your eyes.


    I’m not sure what IO testing you have in mind. This code fragment doesn’t contain any IO, and the fact that it uses generator has nothing to do with it – it just doesn’t.

    To test “no-yield” version of this code you would pass `$http` stub that returns `$fakeResponse` you want to test your code with, and here you need to pass fake `$http` (that yields some `Promise` dummy) and then send `$fakeResponse` to generator – that’s the only difference.


    Tangentially related, maybe you’ll like Phel:

    But from a cursory look, there are many other attempts.


    I get that you can send data into generators instead of yielding their value, and that you could use that to send in a test response, but I’m not sure how you would get a handle on the generator in your test to call send.

    Are you counting on the global event loop to provide a way for you to get the promise?

Viewing 5 posts - 1 through 5 (of 5 total)
  • You must be logged in to reply to this topic.