cujojs / most

Ultra-high performance reactive programming
MIT License
3.49k stars 231 forks source link

Proposal: Grammatical Typology to Enable Advanced Tooling #516

Closed aronallen closed 6 years ago

aronallen commented 6 years ago

Observables are one of the most general abstractions we have available in Computer Science. They provide a common interface to operate on singular or plural and synchronous or asynchronous items.

But programming with Observables is a path riddled with traps, partly due to its novelty, but also that our tooling mostly is built around synchronous imperative code, and not asynchronous functional code.

Typing can get us really far in removing common errors when piping Observables through our code, but our types are not going to help us with the problem of time.

I have spent some days philosophizing whether we need a temporal-type to decorate our Observables, to get a better immediate idea of the consequences when merging, combining, delaying, debouncing, skipping, etc...

At first I set out to categories Observables in my own made-up categories, but then I realized we already have a quite extensive and rigid categorization of temporal events, this system is known as Grammar more properly conjugation, and it provides us with an opportunity to type our Observables not just with their expected value, but when that value might arrive.

In Latin conjugation we can operate with four dimensions, mood, voice, tense, and person. These four dimensions map well to what we need to properly time-categorize Streams.

Grammatical Mood

Grammatical mood helps us know the certainty of an event. Moods can be divided into Realis and Irrealis, things that are certain, and things that are uncurtain. Indicative is a Realis mood, the rest are Irrealis.

They may not all be applicable for Observables

enum Mood {
  Indicative, // realis certain
  Subjunctive, // it might
  Conditional, // if
  Optative, // hope
  Imperative, // command
  Jussive, // command to non-present
  Potential, // it could
  Hypothetical, // it is unlikely
  Inferential, // tree falling in forest without observer
  Interrogative // asking (probably better for a pull based thing)
}

Grammatical Voice

Voice indicates whether something is doing something, or something is happening to something. In observables it could indicate whether the Observable producer has all it's futures defined, or whether it awaits input from the outside (such as passing of time, mouse clicks). Most Observables would be Passive, with the exception of Observables created from arrays or constants.


enum Voice {
  Acitve,
  Passive
}

Grammatical Tense

Grammatical tense indicates when something may happen, or when something did happen, we might want to add a Never, or Never may simply be an undefined Tense.

enum Tense {
  Present, // now
  Imperfect, // past and ongoing
  Perfect, //past and complete
  Future, // soon
  Pluperfect, // happened before something else in the past
  FuturePerfect // will happen at this time
};

Gramatical Person

Finally we have grammatical persons, that indicates who is doing what. We could use the person to indicate singular and plural events of a stream, and the degree of stream (higher-order-streams)

enum Person {
  FirstPersonSingular, // a stream of one thing
  FirstPersonPlural, // a stream of many things
  SecondPersonSinglar, // a stream of one stream of one thing
  SecondPersonPlural, // a stream of streams of things.
  ThirdPersonSingular, // a stream of one stream of one stream of one thing
  ThirdPersonPlural // a stream of streams of streams of things
}

Once our Observable producers are properly decorated with grammatical metadata. We can proceed to ensure that our operators determine what the conjugation of the resulting stream would be.

Practical Applications

Imagine you are combining stream a$ and b$, they are both Stream<number> but a$ is defined far away from where you are currently working, a$ happens to be never() while b$ is just(3) but you are unaware and spend some time trying to find the culprit. With gramatical typings you could get a warning, indicating you are trying to combine something b$ (Present, FirstPersonSingular, Active, Indicative) with a$ (Never), you would get a hint as to where something is amiss.

I would welcome some input on the ideas above, is it useful?

aronallen commented 6 years ago

As a replacement for Grammatical Person, we could divide it into two dimensions. Quantity, and Order, Order indicates the depth to the first non-stream value, and Quantity could indicate how many events are expected (if known) could be 0, 1, 3, Infinity.

Frikki commented 6 years ago

I like the idea.

briancavalier commented 6 years ago

Hey @aronallen, thanks for posting these ideas. I'm very much in favor of finding ways for the type system to help users, and I'd love to discuss this over in @most/core, since it represents the future direction of most.js. Would you mind opening an issue there with the same info (literally you can just paste it into a new issue, that'd be fine!)? Thanks!