Skip to content

Instantly share code, notes, and snippets.

@cowboyd
Last active July 10, 2020 19:18
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save cowboyd/10d326c5f9ff2b612cf61858c6c3970e to your computer and use it in GitHub Desktop.
Save cowboyd/10d326c5f9ff2b612cf61858c6c3970e to your computer and use it in GitHub Desktop.
Proposed Effection operations that are non-ambiguous
// Operation is an un-ambiguous union.
export type Operation<T = unknown> = Promise<T> | OperationIterator<T> | OperationConstructor<T> | AtomicOperation<T>;
// Any generator, any iterator that produces operations can be used.
export type OperationIterator<T> = Iterator<Operation<unknown>, T, any>;
// used anywhere we currently have to use a control function.
// the evaluator never yields control when evaluating this one, so operation
// is guaranteed to be executed in the same tick of the runloop as its caller
interface AtomicOperation<T> {
perform(): T
}
// this is just a function that takes a pojo through which operations can share information
// and returns an operation. This is how the current mechanism of using a `GeneratorFunction`
// as an operation would work since a `GeneratorFunction` is a function that returns a generator
// which is an operation. But it is more general, since it could be a function that returns an `AtomicOperation`,
// even an async function, because an async function is a function that returns a promise, and a promise is an operation.
type OperationConstructor<T> = (context: object) => Operation<T>;
// The ambiguity is removed because if the evaluator sees a function, it can assume that it is an operation constructor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment