Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Shouldn't IO::bind be lazy? #27

Open
OlexandrPopov opened this issue Jun 29, 2020 · 3 comments
Open

Shouldn't IO::bind be lazy? #27

OlexandrPopov opened this issue Jun 29, 2020 · 3 comments
Labels

Comments

@OlexandrPopov
Copy link

Consider the following code:

use Chemem\Bingo\Functional\Functors\Monads\IO;

$io = IO::of(function () {
    echo 'LOG 1', PHP_EOL;
})
->bind(function () {
    return IO::of(function () {
        echo 'LOG 2', PHP_EOL;
    });
});

It prints LOG 1 even $io->exec() is not called.

@ace411
Copy link
Owner

ace411 commented Jul 2, 2020

Hello, Mr. Popov. IO::bind should not be lazy as it is a faculty for forward function chaining: it acts on the result of the value encapsulated inside the impure operation that exists in the monad's jurisdiction.

In your example, the function prints "LOG 1" because the function supplied to bind acts on a value of null - the return value of the unsafe operation in the monad's context.

@ace411 ace411 added the question label Jul 3, 2020
@OlexandrPopov
Copy link
Author

Hello, Mr. Popov. IO::bind should not be lazy as it is a faculty for forward function chaining: it acts on the result of the value encapsulated inside the impure operation that exists in the monad's jurisdiction.

Isn't the whole point of IO is to postpone the impure operation (side effect)?

In your example, the function prints "LOG 1" because the function supplied to bind acts on a value of null - the return value of the unsafe operation in the monad's context.

I'm not sure I fully understand what you mean.

@OlexandrPopov
Copy link
Author

I just started to learn and use all these functional things but the samples I've seen in js and typescript libraries are definitely lazy and I thought that they work in the same way no matter what language you use.
Here is an example based on the IO implementation from the Mostly Adequate Guide book: https://jsfiddle.net/alexanderpopov/m4kq2oaw/24/
In the example both console.log will be performed only when io.unsafePerformIO() is called. If you comment the io.unsafePerformIO(); line, console.log('LOG 1') won't be executed.

Here is another example based on fp-ts library:

import { pipe } from 'fp-ts/lib/pipeable';
import { IO, chain } from 'fp-ts/lib/IO';

const log1 = (): IO<void> => () => console.log('LOG1');
const run = pipe(
  log1(),
  chain(() => () => console.log('LOG2')),
);

run();

It's different from the implementation above but it works in the same way, console.log will be executed only when run() is called.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants