What do you think of LazyPromise as a lightweight alternative to Effect?
3 points by ivan7237d
3 points by ivan7237d
Could you provide some actual examples that contrast LazyPromise with Effect?
Sure, here goes:
Wrapping a callback:
// Effect
const wait = Effect.async<void>((resume) => {
const id = setTimeout(() => resume(Effect.void), 1000);
return Effect.sync(() => clearTimeout(id));
});
// LazyPromise
const wait = new LazyPromise<void>((sink) => {
const id = setTimeout(() => sink.resolve(), 1000);
return () => clearTimeout(id);
});
Running and cancelling:
// Effect
const fiber = Effect.runFork(program);
Fiber.interrupt(fiber);
// LazyPromise
const subscription = result.subscribe({ resolve, reject });
subscription.dispose();
Generator syntax:
// Effect
const program = Effect.gen(function* () {
const user = yield* fetchUser;
return user.name;
});
// LazyPromise
const result = fromGen(function* () {
const user = yield* fetchUser;
return user.name;
});
Typed errors:
// Effect: a separate channel Effect<A, E, R>
const findUser = (id: string): Effect.Effect<User, NotFoundError> =>
Effect.fail(new NotFoundError());
findUser(id).pipe(Effect.catchTag("NotFoundError", () => ...));
// LazyPromise: typed errors are ordinary resolve values in a box
// (see "Why not a separate channel for typed errors?" in the Q&A
// section of the README)
const findUser = (id: string): LazyPromise<User | ErrorBox<"notFound">> => ...;
findUser(id).catchBoxed((error /* "notFound" */) => ...);
Dependency injection:
// Effect
class Random extends Context.Tag("Random")<Random, { next: () => number }>() {}
const program = Effect.gen(function* () {
const random = yield* Random;
return random.next();
});
Effect.runPromise(program.pipe(Effect.provideService(Random, { next: Math.random })));
// LazyPromise
const randomSymbol = Symbol("random");
interface RandomDep { [randomSymbol]: () => number }
const result = fromGen(function* (dep: RandomDep) {
return dep[randomSymbol]();
});
result.subscribe(consumer, { [randomSymbol]: Math.random });
It started out as as a rethink of Observable/Promise in a world with Signals, but has recently added support for generator syntax and dependency injection.
What is this Effect you speak of? I don’t see any JavaScript API of that name when I search MDN, and when I search for “JavaScript effect library”, I just get some animation libraries that mention the general concept of animation effects. LazyPromise’s README doesn’t contain any link in the section that mentions Effect, either.
Yeah, Effect must be having a lot of trouble with the name they chose. It's https://www.effect.website/
I think this is similar to how Aff works in purescript (which is implemented as () => new Promise(...) when you construct it, iirc)
Oh, interesting, it seems like there's indeed a lot in common. If ChatGPT is right (https://chatgpt.com/share/6a81ab9e-bb3c-83ea-b7e5-7497644c4063), one difference is that LazyPromise doesn't have sharing/caching baked in. I talk about that in the 5th question in the Q&A section.