🪚 OmniGraph™ Delusional code of the utterly deranged #112
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
In this PR
This is a precursor for even more extensible tooling because the sky is the limit. It is a restricted and mutated version of a basic Monoid and a Semigroup for
Promise
s.The problem
Once a promise is created, there is no way of doing something before it starts. There is also no way of saying oh I want these promises to happen in a certain order which is limiting, in the most tangible case, when asking for user input on the CLI.
On the CLI, you can only ask for one thing at a time. If the user needs to answer a question e.g. for every single
contract
, they need to be asked these questions one by one.At this moment the code relies on strategies such as
Promise.all
which require you to pass in an array of promises (remember, you can't stop a promise). If in any of these promises we need to ask user for some input, this input will be printed out in parallel which is incomprehensible to the CLI and results in broken software (all the questions will be answered at once and will be answered with the first input that the user types in)The solution
The solution is a wrapper around a
Promise
, commonly referred to as aTask
.Task
is a function that generates a promise when required - but it will not start the promise until asked to do so.Tasks are much more flexible than
Promises
since we can prevent them from happening, postpone or arrange them.For now, the only tooling we require for Tasks are so-called Monoids and Semigroups. These are very simple mathematical structures consisting of a type
S
and an operation that transformsS + S → S
(and in case of aMonoid
we also get an empty element).In our case we get rid of the purity a bit and simplify some of the steps when it comes to the mathematics in order to get a better UX. We get a
parallel
andsequence
"monoids" - not truly monoids because instead of operating on two elements they operate on N elements and instead of returning a Task they execute the task for us; and afirst
"semigroups" - again, a bit simplified for the purpose of UX.These structures allow us to control the behavior of functions to our liking - for example in a non-interactive case we might be okay with executing graph transformations in parallel, in an interactive case we might go with sequential execution.
Example
For example, our
Options
together withOptionsBuilder
are a monoid - you can merge two options using the builder and the empty state is0x