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
    Posts
  • #5784
    usernameqwerty004
    Participant

    Look at this example code from [Amphp](https://amphp.org/):

    try {
    $request = new Request(“https://amphp.org/”);
    $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](https://gist.github.com/kbilsted/abdc017858cad68c3e7926b03646554e)).

    #5785
    Jake_Jeremy
    Guest

    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.

    #5786
    MorphineAdministered
    Guest

    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.

    #5787
    HenkPoley
    Guest

    Tangentially related, maybe you’ll like Phel: https://phel-lang.org/#why-phel

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

    #5788
    __matta
    Guest

    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.