Skip to content

Commit

Permalink
Merge 2c361a0 into a52fafd
Browse files Browse the repository at this point in the history
  • Loading branch information
wentout committed May 20, 2020
2 parents a52fafd + 2c361a0 commit 54aba7f
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 18 deletions.
49 changes: 32 additions & 17 deletions TypeScript.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

## (default) way to go with typings

So, getting from the README.md as a starting point, the main method of the library is `.define`, here is how it works:
So, getting from the README.md as a starting point, the main method of the library is `define`, here is how it works:

```js

Expand All @@ -13,26 +13,42 @@ So, getting from the README.md as a starting point, the main method of the libra
const TypeClass = define('TypeClass', function (opts) {
// any operators here, for example
Object.assign(this, opts);
};
});

const typeClassInstance = new TypeClass();

```

And `.define` it is indeed have to typed. And there is almost no way somebody would be glad reading it's interface if it would. Therefore it just checks that provided constructor function is `:NewableFunction` and provided typename is `:string`. The rest of typing is on your own. You can mark `TypeClass` or `typeClassInstance` with necessary type you wish, and you can pass `this` definition argument to newable function. Combining all three you will get all necessary typings.
And `define` it is indeed have to typed. And there is almost no way somebody would be glad reading it's interface if it would. Therefore it just checks that provided constructor function is `:NewableFunction` and provided typename is `:string`. The rest of typing is on your own. You can mark `TypeClass` or `typeClassInstance` with necessary type you wish, and you can pass `this` definition argument to newable function. Combining all three you will get all necessary typings.


```js

import { define } from 'mnemonica';


type SomeType = {
// some definitions
...
// defined in future
NestedType: NewableFunction
};

type Nesteds = {
define: CallableFunction
};

// TypeClass
const TypeClass = define('TypeClass', function (opts) {
const TypeClass:Nesteds = define('TypeClass', function (this:SomeType, opts) {
// any operators here, for example
Object.assign(this, opts);
};
});

const typeClassInstance = new TypeClass();
const typeClassInstance:SomeType = new TypeClass();

const NestedClass = TypeClass.define('NestedType', function () { /* ... */});

const nestedType:SomeType = new typeClassInstance.NestedType();


```

Expand All @@ -51,6 +67,7 @@ And yes, it works like this for us, if we wish to get reach to the typings right

type SomeTypeInstance = {
someField: string;
// defined in future
SomeSubType: IDEF<SubTypeInstance>;
}

Expand Down Expand Up @@ -81,17 +98,17 @@ And yes, it works like this for us, if we wish to get reach to the typings right

This example is not so easy. As you see we if we go deeper with the purpose of mnemonica, we have to craft a lot of additional tooling per each step.

And seems there is no way to make the other 99% cause of TypeScript limitations. Therefore `.tsdefine` method is extremely hard to passthrough without types. And if you are TypeScript developer, emm... **Please Help Me!**
And seems there is no way to make the other 99% cause of TypeScript limitations. Therefore `tsdefine` method is extremely hard to passthrough without types. And if you are TypeScript developer, emm... **Please Help Me!**

The other way is `.tsdefine` instead of `.define` provides the same typechecks as you can do with **(default)** way. And you would need to annotate a lot of other things instead of annotating the results. There where `.define` is just a way to go as you wish and as you go, `.tsdefine` enforces you to make a lot of hard stuff.
The other way is `tsdefine` instead of `define` provides the same typechecks as you can do with **(default)** way. And you would need to annotate a lot of other things instead of annotating the results. There where `define` is just a way to go as you wish and as you go, `tsdefine` enforces you to make a lot of hard stuff.

Moreover, if the default way would win, the support of `.tsdefine` might be excluded from library, as it would be not so necessary anymore, though we think to leave it for backward compatibility.
Moreover, if the default way would win, the support of `tsdefine` might be excluded from library, as it would be not so necessary anymore, though we think to leave it for backward compatibility.

# The Truth is...

About the plans. Indeed, as we can see from code there Should be no typings at all, it Must be the same as JavaSript code, but with type checker. And the goal is to make the following:

* extract `typeof this` from newable function or class provided to `.define`
* extract `typeof this` from newable function or class provided to `define`
* give `this` as some sort of result for `new TypeClass()`, so the type of `typeClassInstance` magically casts with `typeof this` inside of `TypeClass` constructor
* get `'SomeSubType'` string somehow and add it to the result of `new TypeClass()` as mnemonica does through hidden mechanics, so there is a way to make `new instance.SomeSubType()` with automated typecheck, derived from previous step of consruction trie (from prototype).

Expand All @@ -103,14 +120,12 @@ Chaining with TypeClass provides a lot of features:
* **straight** viable steps of application **lifecycle** via described steps of construction chain for each instance
* the ability to make `.clone` or `.fork` and even re-write or re-initialize the constructor
* powerfull `Error`'s checking with automated ability to get `instanceof FailedConstructor` check which is written above `Error` instance
* testing simplicity because each constructor is a separate clean function, it is easy to write unit tests
* mnemonica collections are is a sort of DI container, you can extract, mock and so on, as you wish
* * chained asynchronous constructors are good also, grep for `await new` of the `./test` folder
* everything is connected, therefore we indeed write much less code
* **testing simplicity** because each constructor is a separate clean function, it is easy to write unit tests
* chained **asynchronous constructors** are good also, grep for `await new` of the `./test` folder

And if this all is not enough, there is overwhelming power of `.registerHook`, which provides the ability to get reach to :

* answer the question where each tiny piece of running code it belongs to... through combination of `auto-bind` and `async_hooks` module.
* answer the question where each tiny piece of running code it belongs to... and it can be even more powerfull in combination with some sort of [`auto-bind`](https://www.npmjs.com/package/auto-bind) package and [AsyncLocalStorage](https://nodejs.org/api/async_hooks.html#async_hooks_class_asynclocalstorage) module.
* easy monitoring of each construction step, written once
* powerful validations based on `'preCreation'` and `'postCreation'` hooks

Expand All @@ -121,7 +136,7 @@ Making the JavaScript part of code better and better and will be able to concent

And TypeScript typings support, emm... if you wish play with types -- it is not my choice, but yours. I gave the ability to describe types and will accept PRs. That is why I'm asking for Help with TypeScript typings...

So, the Truth is... that [Prototype](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain) is Asynchronous [Set](https://en.wikipedia.org/wiki/Set_theory) of [Linearizable](https://en.wikipedia.org/wiki/Linearizability) [Dependent](https://en.wikipedia.org/wiki/Dependent_type) [Refinement](https://en.wikipedia.org/wiki/Refinement_type) of [Bounded quantification](https://en.wikipedia.org/wiki/Bounded_quantification) based on [History monoid](https://en.wikipedia.org/wiki/History_monoid) solving [Expression problem](https://en.wikipedia.org/wiki/Expression_problem) through [Chaining](https://en.wikipedia.org/wiki/Method_chaining) of [Type Classes](https://en.wikipedia.org/wiki/Type_class) through [Multimethods](https://en.wikipedia.org/wiki/Multiple_dispatch)... and might be I missed something else... for example [Trace](https://en.wikipedia.org/wiki/Trace_theory) and [HoTT](https://en.wikipedia.org/wiki/Homotopy_type_theory)...
So, the Truth is... it is time for joke... that [Prototype](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Inheritance_and_the_prototype_chain) is Asynchronous [Set](https://en.wikipedia.org/wiki/Set_theory) of [Linearizable](https://en.wikipedia.org/wiki/Linearizability) [Dependent](https://en.wikipedia.org/wiki/Dependent_type) [Refinement](https://en.wikipedia.org/wiki/Refinement_type) of [Bounded quantification](https://en.wikipedia.org/wiki/Bounded_quantification) based on [History monoid](https://en.wikipedia.org/wiki/History_monoid) solving [Expression problem](https://en.wikipedia.org/wiki/Expression_problem) through [Chaining](https://en.wikipedia.org/wiki/Method_chaining) of [Type Classes](https://en.wikipedia.org/wiki/Type_class) by [Multimethods](https://en.wikipedia.org/wiki/Multiple_dispatch)... and might be I missed something else... for example [Trace](https://en.wikipedia.org/wiki/Trace_theory) and [HoTT](https://en.wikipedia.org/wiki/Homotopy_type_theory)...

# Thank YOU ;^)
## best wishes
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "mnemonica",
"version": "0.9.78",
"version": "0.9.79",
"description": "abstract technique that aids information retention : instance inheritance system",
"type": "commonjs",
"main": "./build/index.js",
Expand Down

0 comments on commit 54aba7f

Please sign in to comment.