Skip to content

Instantly share code, notes, and snippets.

@ClarkeRemy
Created September 4, 2024 07:37
Show Gist options
  • Save ClarkeRemy/75abfdcd02b5fa7847213136f6b67b07 to your computer and use it in GitHub Desktop.
Save ClarkeRemy/75abfdcd02b5fa7847213136f6b67b07 to your computer and use it in GitHub Desktop.
Object oriented code JS manual
const interface_method = (object, _interface)=>(method) => (
object._interface[_interface].hasOwnProperty(method)
&& (typeof object._interface[_interface][method]) == "function"
)
const implInterface = (_interface, invariant, object, impl) => {
if (!object.hasOwnProperty("_interface")) {
object._interface = {};
}
object._interface[_interface] = impl
if (!invariant(object)) {throw `FAILED TO IMPLEMENT \`${_interface}\``}
}
const IPerson = (object) =>{
let method = interface_method(object, "IPerson");
return method("name") && method("age");
}
const implIPerson = (object, impl) => {
implInterface("IPerson", IPerson, object, impl)
}
const ICompany = (object) => {
let method = interface_method(object, "ICompany");
return method("company");
}
const implICompany = (object, impl) => {
implInterface("ICompany", ICompany, object, impl)
}
const IAge = (object) => {
let method = interface_method(object, "IAge");
return method("age");
}
const implIAge = (object, impl) => {
implInterface("IAge", IAge, object, impl)
}
const ClassPerson = (name, age) => {
// method dispatch
return {name : ()=>name, age : ()=>age}
}
const ClassEmployee = (name, age, company) => {
let person = ClassPerson(name, age);
person.company = ()=>company;
return person;
}
const ClassEmployee2 = (person, company) => {
person.company = ()=>company;
return person;
}
const ClassHPEmployee = (person, gender) => {
let still_at_hp = true;
person.company = ()=>{
still_at_hp = !still_at_hp;
if (still_at_hp) { return "HP" }
else {return "IBM" }
};
let old_name = person.name;
person.name = ()=>
`${ (gender === "male" || gender === "Male" )
? "Mr"
: "Ms"
}.${old_name()}`;
implIPerson(
person,
{
name : old_name,
age : person.age
});
implICompany(
person,
{ company : person.company }
)
implIAge(person, {age : person._interface.IPerson.age})
return person;
}
const ClassComputer = (maker, {year, model}) => {
let computer = {model : model, year : year};
implICompany(computer, {company : ()=>maker})
implIAge(computer, {age : ()=>(new Date().getFullYear()) - year})
return computer;
}
const ask_for_age = (obj /* expects IPerson */) => {
obj._interface.IPerson.age
}
// forall O where O : IAge + ICompany =>
const age_and_company = (obj) => {
let obji = obj._interface;
return { company : obji.ICompany.company(),
age: obji.IAge.age()
}
}
const e = ClassHPEmployee(ClassPerson("Bob", 55), "Male");
const c = ClassComputer("Apple", {year : 1977 ,model : "Apple2"});
let name = e.name();
console.log(e._interface.IPerson.name());
console.log(e);
console.log(c);
console.log(age_and_company(e));
console.log(age_and_company(c));
console.log(e.company());
console.log(e.company());
console.log(e.company());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment