microsoft / TypeScript

TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
https://www.typescriptlang.org
Apache License 2.0
100.76k stars 12.46k forks source link

Suggestion: Inflections #21424

Closed aronallen closed 3 years ago

aronallen commented 6 years ago

JavaScript is riddled with a mix of synchronous and asynchronous operations. We need a Inflected type to cast entities not only with their inner value, but with their timings and certainties. particularly when working with Observables, Promises, Generators, Async Generators, Iterables.

As I am most familiar with Observables, I will provide examples below on how we can utilize Inflections specifically with Observables, though I believe their use may extend to other constructs mentioned above.

We could leverage categorization terminology from linguistics, casting entities with their correct: number, person, voice, tense, mood, aspect.

Consider a$ to be an Observable of the value 1, that immediately emits and completes upon subscription. Consider b$ to be an Observable of nothing. That never emits nor completes upon subscription.

const a$: Observable<number> = now(1);
const b$: Observable<number> = never();

const c$: Observable<number> = combine((a, b) => a + b, a$, b$);
const d$: Observable<number> = merge(a$, b$);

We define the combine operator to take the latest value of each Observable, and emit the product when both values are defined and when both values are know to emit when one value changes.

We define the merge operator to forward the input of any Observable to the resulting Observable.

With our current type-system TypeScript will fail to recognize that the combine operator will return an Observable that will never yield a number, nor complete, yet it will comply with the current type contract.

With grammatical types we could inflect the Observables.

const a$: Inflect<Observable<number>, Present, Indicative, Active, Singular, First>   = now(1); 
const b$: Inflect<Observable<number>, Infinitive, Indicative, Active, Nil, First> = never();

const c$: Inflect<Observable<number>, Infinitive, Indicative, Active, Nil, First>  = combine((a, b) => a + b, a$, b$)
const d$: Inflect<Observable<number>, Infinitive, Indicative, Active, Singular, First> = merge(a$, b$);

The arguments to Inflect are given in the following order:

Inflect<E: Entity, T: Tense, M: Mood, V: Voice, Q: Quantity, O: Order>

I will now take some time to expound upon the terminology. Present indicates that something will immediately emit and complete, Infinitive indicates that something will never terminate. Active indicates that the events are actively produced and not a consequence of side-effects (such as the passing of time, server responses, or mouse clicks). Singular and Nil indicate the quantity of expected events. And First indicates that this is a first order Observable (read up on higher-order Observables).

Grammar offers us many options for each category of inflection, I do not imagine we need to implement all of them, but we should at least consider all of them, as they have all occurred naturally in human language at some point in time, thus it must have sprung from a need to express an action in a very particular way, real or unreal.

Particularly within Mood we find many interesting categories, such as opative, subjunctive, conditional, which could help us know why something in our code is or isn't happening.

Would it be possible to build an inflection system with TypeScript as-is, or do we need some language extensions to enable the advantages of inflection detailed above. The desired result would be that the type system would be able to infer the resulting inflection of any operation. It would of course be the duty of a library vendor to properly annotate inflections and determine resulting inflections.

DanielRosenwasser commented 6 years ago

Pinging our linguistics experts @sandersn and @JsonFreeman. 😄

atennapel commented 6 years ago

Maybe try to wrap an observable library and see how far you get. You'll have to define a flatMap that combines all these grammatical categories somehow.

RyanCavanaugh commented 3 years ago

Declining due to lack of interest or apparent problems that this would solve.