indi
v0.1.136
Published
allows to use traits to construct individuums (indi's) based on declarative compositions (compo's) rather than inheritance for presice cross-member dependency injections (onix's) and/or causation patterns (causa's and sue's); plus interface management wit
Downloads
420
Readme
Indi
Hello programmer. Are you looking for new ways to write programs which feel a little bit more fun? What about a more powerful and robust composition pattern that allows to avoid inheritance while giving better design freedoms?
Say hello to Indi! He is the main character in the virtual programming environment world called Monism, who identifies as an individuum. He is, an object in the virtual object-world called the runtime. He begins his existence when caused by the developer, or other individuums via Causas (defined on Compos).
He is the twin-brother of Indika who also behave in the similar way because they are siblings. They perform similar functions by operating in the environment such as Ronald McDonald.
Compo
Unlike other individuums, only he himself can see his internal structure, or composition, also known as his Compo. The goal of the developer is to fulfil the individual's contract known as an Idea, using method implementations that reference the inner links to other structures. The main rule there is no inheritance, but only composition.
Indi and Compo live in the real-world, the meta-verse known as Extension. But because their slice of dimension is particularly rich in Nitrogen-Fosphate, the duality of their world is more promiment: just as they enjoy existance in the realm of Extension, so do are the Ideas from the realm of Thought.
Department of Thought
Only interfaces and universals belong to the realm of thought. Because of dualism, for every body in the real-world Extensia, there is an idea, however some principles are not exposed in thought-realm such as structures and constructors - it is up to indis to implement those things in their "existentias".
Cogi
Cogi is a really smart guy who puts multiple Common Notions together to simulate multiple inheritance in the realm of ideas (interfaces for dev). Pure ideas don't have causes which means they don't have constructors which are only used in the realm of Extension of which only Indies and Compos are.
The rest such as standard ideas (classes) belong to the realm of thought where they exist as compositions of properties. Because there is no multiple inheritance in JS natively, Cogi allows to simulate it by passing Juni Universals which end up as fields on the final idea.
import { UAP } from "./AP.mjs"
import { UBP } from "./BP.mjs"
/*Interface = Idea*/
export class ICP extends
/*Multiple inheritance*/
Cogi(UAP,UBP),
// ^ ^
// Cogi accepts Junis Universalies
// The result has .ap & .bp fields
){}After ideas are produced by Cogis, they become Thouts (i.e., thoughts) and are
handed out by the Department to the clientelle. They serve as abstracts API
contracts allowing to program to interface (idea) and not implementation.
Thouts' unviersal form records the interface, as can be confirmed with letter
first capital letter I - meaning Idea (or Interface).
All Compos always receives a universal as the first argument in order to create a composition. This implies that an indi will always have an idea behind him – his aim is to strive via his existentia, i.e., conglamerate a set of methods together to meet the outside idea of him, but some parts can be private if recorded on structre by Compo.
Juni Universalia
This is Indi's secretary - all communication is done through her reference. Cogis accept Junis Universalias to compose complex ideas. Some ideas are simple such as boolean (true/false), numbers or strings.
/**
Whether cherishability applies
* @abstract
*/
export class BCherishable
extends Boolean {}The Universalia is then
export var UCherishable=Juni({
cherishable:BCherishable,
})Those are immutable.
There is a second usage, for complex types as well. In that case a link on the structural stem is also created as a field referencing the dependency.
export class IDs extends
Cogi(ULand,BCherisable) {
/**A method in Ds.
* @param {string} s
*/
methodDs(s) {return ''}
methodDs0(s) {return ''}
}
export var UDs=Juni({ds:IDs})Fig 3: Juni Universalia creates Universals (or Universalias or Universalea) and serves as link between the idea and structures in extensia when created by Compo. When combined with Cogi, that defines simple notions on the self.
// ULand somehow needs to be implemented,
// and not via connection?
export class _Ds extends Compo(UDs,
CLand,CherishableS, // causes + self-causes
) {}
export default class Ds extends Indi(_Ds,({testFs})=>({
testFs:testFs
}),{
methodDs(s) {
var{methodDs0}=this
return methodDs0(s)
},
})Fig 4: Indis supply implementation to the structure and are the default export, allowing them to be used as classes (mainly via Causes).
Other Characters
Together with Indis and Compos, there are Sue and Causa in the realm of Extention. Sue allows to store information on the distributed hard-drive known as Akashic records because she's got psychic powers. Causa is a gangster whose job is to ensure that all other indis that the main Indi relies on, will be brought into existance (caused) - unless folded from the outside by the developer.
Sue
Sue is energetic and shows the initiative to remembers facts which are
passed to her at the time of initialisation of objects. With the following way,
the declaration of possible inputs (determinants, or deto-s for short) is
defined using JavaScript alone. When Compo receives a trait created by
Sue, he will schedule a constructor that with attempt to automatically
extract the field from the determinants if they match the signature of
Universalia declared.
Advanced JsDoc syntax is used to generate in-IDE documentation. By writing inline comments it's possible to declare the shape of detos without having to document it in a separate place.
import { Juni, Sue } from "indi"
/**@abstract*/class BCherishable
extends Boolean {}
export var UCherishable=Juni({
cherishable:BCherishable})
/*Sue creates self-cause that reads
from deto (first arg to constructor)*/
export var CherishableS=Sue(
/**@param{Object}deto
@param{string}[deto.cherishable] activate cherisable. */
({cherishable})=>UCherishable)Causa
Causa is a like a member of Cosa Nostra - if he needs to make sure an individuum is there to perform his tasks - he will find him and cause into existance. When a new Indi is created, the causas that were defined on its strurcture by Compo, will all ensure the peers providing services are there for indi's methods to run.
The Causa necessarily has the single key which is used to access it within a
structure in Compo. Causes are subject to folder from higher-order
Compositions which allow a fine-grained control over subsumption (called
folding).
export class // A BP indi
BP extends Indi(Compo(UBP,CAP))
// ^
// uses CAP causa to start AP
{}
// provide causes for others
export var CBP=Causa({bp:BP})The key advantage of Indi is that it solves the diamond problem using precise declarative dependency injection.
Causal Folding
Folding is fine-tuning the compositional structure to be able to reuse dependencies which could be caused from the individuum itself, i.e., to prevent new dependency initialisation from inside the dependency by declaring in code that it should take the reference from the indi's own initialised dep.
// 📀 IAP.mjs
export class IAP {}
export var UAP=
Juni({ap:IAP})
// 📀 AP.mjs
export class _AP extends
Compo(UAP){}
export class AP extends
Indi(_AP){}
export var CAP=
Causa({ap:AP})// 🧠 - thought realm
// Simple idea
// universal ap
// 🦾 - extension realm
// structure ap
// indi ap
// causes ap in indis// dependency bp - thought
export class IBP extends Cogi(UAP){}
export var UBP=Juni({bp:IBP})
// dependency bp - extensia
export class _BP extends Compo(UBP,CAP){}
export class BP extends Indi(_BP){}
export var CBP=Causa({bp:BP})export class ICP extends
Cogi(UAP,UBP){}
export var UCP=Juni({cp:ICP})//
// complex idea made of unis
// needed for _CP structureexport class _CP extends
Compo(UCP,
CAP,//⇠-↓----------↓
[CBP,({ap})=>({ap:ap})]
) {}
export class _CP1 extends
Compo(UCP,
[CBP,({ap})=>({ap:ap})],
CAP,//⇠-↑----------↑
) {}// Structure 1:
//
//
// FOLDED CBP CAUSA
//
//
// Structure 2:
//
// FOLDED CBP CAUSA but
// order doesn't matter
//Universal Folding
On occasion, folding causes is not enough, and for convenience purposes the structure might want to expore direct access to one of the caused indies from inner indies. In that case, the following needs to be used.
On the other hand, it should also be possible for the individuum to fold a certain dependency on the self by wiring its reference to the caused dep of a child individuum.
VIP
😯 What does it do?
It lets you compose design (interfaces, shared traits, conceptual contracts) and runtime (class implementations) seamlessly using mixins, while honoring both as modes of a unified structure.
It's an alternative to TypeScript in pure JavaScript, but even better in the following ways:
- like typescript, maintains interface-code duality, but in pure js substance, hence no need for a transpilation step - can work with any ES6 engine.
- high-precision declarative composition principles that allow to solve diamon-problem of multiple inhertiance with additional dev control.
- supports traits unlike TypeScript, which only supports them on the type-level, but not at runtime, enabling declarative composition of common fields.
- constructor-composition like in solidity, for traits, allowing multiple constructors to execute in order and spawn required dependencies.
- automatic binding of methods to the individuum object so that they are readily
accessible via destructuring without lossing
thisbinding. - functional-first outlook on what methods are by expanding unidomensional
thisinto a multi-dimensional, hybrid component envrionment.
