Example of this prototype OOP code in FP style

prototype-based programming example
prototype programming
functional programming
object-oriented programming
prototype programming javascript
introduction to object-oriented programming
prototype-based language vs class-based
what is meant by prototype based language

So. I'm reading a lot of articles regarding Functional Programming and I'm finding a lot of related issues with all of them... They are all talk and no play. They all talk about Functional Programming but noone actual shows an example and the ones who do show examples, show completely different examples than that of the OOP they show, so it is hard to relate between the two. The one thing that is hard to grasp is state in functional programming. So, for the sake of it, could someone answer this post and write a functional programming approach to the below OOP style code.

person.json:

{
    "firstname": "Karl",
    "surname": "Morrison"
}

person.js:

// Module code

const fs = require('fs');
const path = require('path');

function Person(filePath) {
    const person = JSON.parse(fs.readFileSync(path.join(__dirname, filePath)));
    this.firstname = person.firstname;
    this.surname = person.surname;
    this.salary = 0;
}

Person.prototype.getPerson = function() {
    return {
        firstname: this.firstname,
        surname: this.surname,
        salary: this.salary
    }
}

Person.prototype.increaseSalary = function(amount) {
    this.salary += amount;
}

Person.prototype.increaseSalary = function(amount) {
    this.salary += amount;
}

Person.prototype.getYearlySalary = function() {
    return this.salary * 12;
}


// Application code

const people = [];

const personOne = new Person('./person_one.json');
console.log(personOne.getPerson()); // { firstname: 'Karl', surname: 'Morrison', salary: 0 }
personOne.increaseSalary(1000);
console.log(personOne.getPerson()); // { firstname: 'Karl', surname: 'Morrison', salary: 1000 }
console.log(personOne.getYearlySalary()); // 12000

people.push(personOne);

const personTwo = new Person('./person_two.json');
console.log(personTwo.getPerson()); // { firstname: 'Eric', surname: 'McDood', salary: 0 }
personTwo.increaseSalary(100);
console.log(personTwo.getPerson()); // { firstname: 'Eric', surname: 'McDood', salary: 100 }
console.log(personTwo.getYearlySalary()); // 1200

people.push(personTwo);

// API endpoint - This would be an example of returning the state of the people to whoever made the request. State needs to be kept.

function APIGetPeopleCallback() {
    return people;
}

function APIAddPersonCallback(filePath) {
    people.push(new Person(filePath));
}

Well, here you go:

 ((people, loadPerson, increaseSalary) => (
     people(it => [...it, increaseSalary(loadPerson('./person_one.json'), 1000))]),
     people(it => [...it, increaseSalary(loadPerson('./person_two.json'), 100))]),
     { getPeople: () => people(), addPerson: (path) => people(it => [...it, loadPerson(path)]) }
 ))(
   (s => e => s = e ? e(s) : s)([]),
   file => JSON.parse(fs.readFileSync(path.join(__dirname, file))),
   (p, amount) => ({ ...p, salary: p.salary + amount })
 )

Takeaways:

"purely functional code" in an asynchronous world is complicated.

Purely functional code in a multiparadigm language is impossible, as all APIs impose different paradigms.

Prototype-based programming, Prototype-based programming is a style of object-oriented programming in which behaviour reuse (known as inheritance) is performed via a process of reusing� In this article we will iteratively implement a simple object system suitable for object-oriented programming (OOP) in a functional programming (FP) style. The goal of this exercise is two-fold

There are two problems with this request

functional programming approach to the below OOP style code

  1. There's absolutely nothing OOP about the code you posted. You could have a module-level object with salary hashed by name or some other thing and expose getters and setters to manipulate it. This is plain procedural code with a very thin coat of OO paint. I get that it's an example and is supposed to be simplified, but it actually gets right to the heart of the problem...

  2. Paradigms when used correctly are not line-by-line (or even module-by-module!) translatable from one to the other. Think about a real OO design for some problem. You can use one of the classics like the parking garage or monopoly or some problem you've actually solved in an app. Most of your classes probably have only the most tenuous connections to physical entities, and instead are related to things like state change invariant enforcement (i.e. validation) and policy. Think about the way the interaction between instances is mediated, with all the layers of indirection and the Law of Demeter and yada. Now imagine someone comes to you with a procedural implementation of a solution and says "how do I translate this to OOP?".

You can't. I mean, sure, you can create an example like the one you posted which is really still procedural, but how would you even begin to explain how to do an actual OO solution? You'd have to start at the very beginning and work your way up from first principles. It's not a different style of coding, it's a completely different way of modeling problems. For another example, think about the difference between how things are modeled in most programming languages vs. say, relational tables in a database.

And that's why the blogs are annoying you, they're trying to explain things (and I realize I'm painting with a broad brush here) from the first principles, the way it has to be done, when you seem want the TL;DR. I freely admit it doesn't help that those explanations are mixed with a sales pitch, but que cirra.

Object Oriented Programming (OOP) & Functional Programming , Objected-Oriented Programming (OOP) and Functional Programming OOP utilizes objects without classes, prototype delegation — aka OLOO (objects linking to other objects). can be viewed as much more verbose than the OOP example. OOP utilizes an imperative style, in which code reads like a� The article seems to be using Functional Programming and the use of functions without distinction, even though they are vastly different things. For example, he is trying to draw a parallel between database interactions and functional programming by saying that we interact with databases like we are using simple functions, when functional programming covers much more area than simple functions.

I'm not sure you're going to get the answer you're looking for. It's kind of like saying, "could somebody please take this classical tune and rewrite it as a blues song, with clear rules that show how to do it." You'd never get to the bottom of it. In fact (as you see already), many would say, "that's not a classical song so your request is misguided."

So if I may, I'd submit this as a better place to start: "please give me a PRACTICAL example."

To that end, three of the most practical things I ever heard when I was going through this was:

"OOP's notions of types are fine grained. Functional's notion of types are course grained."

"OOP is more types with less methods. Functional is less types with more methods."

"OOP creates deeper, more brittle hierarchies. Functional creates shallower, often flat, structures."

None of these are meant to be absolute edicts, they are meant to differentiate the thinking, which IMHO is the most important thing to understand about Functional and OOP (notice I do not say "vs.").

Consider what you've got up there: you create a Person type, and it has some methods that are specific to processing THAT type.

So if you need "BigPerson", what will you do? You'll probably extend Person. Makes sense; hierarchy, reuse, etc. You'll add BigPerson methods, or, you'll have to implement IPerson in both Person and BigPerson so that you can alter the behaviors on a type-by-type basis (or just override the functions in the prototype), or some such. More types, more specific, deeper hierarchy.

Now, consider a list to hold such objects. How would you type it? Person (or IPerson)? Might not be specific enough for BigPerson. So you'd type it as BigPerson (or, create IBigPerson and use that). Many might even create BigPersonList implements IBigPersonList (I see this ALL the time and it drives me nutz...you end up with a different list type for every component that displays a list). And then let's say you want a list as an array, then a list as a Set. IBigPersonArray, IBigPersonSet? Or implement other types and interfaces that abstract List and Set, and implement those in BigPerson (BigPersonList extends PersonList implements IArrayList...)

Don't laugh, I've seen these patterns so many times in the wild anybody saying "no employed professional would do that" is simply wrong. (In fact I might actually say that in my experience, the more academic training a programmer has, the more likely they are to do it.)

A functional programmer might say: I'm not going to go through all that. I need a list; all lists are fundamentally the same, they are a collection of objects. The difference in all that typing and interface business is the behavior to process the types you give it.

So I will create a list, with a function that accepts a function, which tells the list how to process the types; the list itself will not contain anything other than the most rudimentary behavior to stuff objects into an array (in fact, I could actually let the user determine what top-level data structure to use, they can just pass it in along with the function). It'll also have an arg, "type", so that you can ask "what type of list is this." And, if they need to use the same processing logic somewhere else, they can simply grab the function that this "type" of list uses, and do whatever they want with it somewhere else. I can even let them pass in the logic to iterate it.

So one of my own notions of functional and OOP; OOP sets the instructions in stone. If the dev wants different instructions, they extend/override/etc. Functional allows the developer to provide those instructions, so that you don't need another static type.

Taken to the extreme, types disappear. Everything is just dynamically provided instructions to "higher order" functionality. What's important is top-level functionality that accepts instructions on how to extend its capability. A "list" can hold anything. It doesn't need to be typed, and it doesn't need to care about the type it holds, because the developer told it how to handle it (with instructions-as-functions). As long as another developer can inspect enough info about it to understand what it holds and how it holds/provides it (sometimes called "duck typing", if it looks like a duck and acts like a duck, it's practical to assume it's a duck, I don't need the class->order->species of it), you're good.

The strengths and weaknesses come to mind pretty quickly. They are debated endlessly. Personally, I think the best practice is a smart combination of both.

So in your example, I wouldn't rewrite Person. But in more abstract things that would handle things like Person, that's where I may approach more functionally.

Hope that helps. It'll probably cost me some rep.

From OOP to Functional Style (FP) — A JavaScript Pattern , For every programming pattern shown, between OOP and FP, we'll discuss the Extendability: How easy it is to add functionality to the code. One of the most common examples to use when teaching patterns or have to import the whole Circle and then do: Circle.prototype.area.bind({ r: 4 })() Not nice. I had quite a lot of experience of the both approaches when writing an RPG game in Java. Originally I wrote the whole game using class-based OOP, but eventually realised that this was the wrong approach (it was becoming unmaintainable as the class hierarchy expanded). I therefore converted the whole code base to prototype-based code.

How To Do Object Oriented Programming The Right Way, Object Oriented Programming (OOP) is a software design pattern that Consider the following example: Good functional software design practices say we should always write functions that has no side effects, i.e., don't use void functions. Let's write some code to add partition to the Array prototype: Object-oriented programming, or OOP, is THE paradigm for modern application development and is supported by major languages like Java, C# or JavaScript. The Object-Oriented Paradigm From the OOP perspective, an application is a collection of “objects” that communicate with each other.

Intro to Functional Programming: JavaScript Paradigms, Functional programming is a paradigm of building computer programs using Example: String.prototype.slice, Array.protoype.filter, Array.prototype.join. Object-oriented programming (OOP) is a programming paradigm based on the concept of "objects", which can contain data, in the form of fields (often known as attributes or properties), and code, in the form of procedures (often known as methods).

An introduction to Object-Oriented Programming in JavaScript, Since OOP came later in JavaScript's development, you may come across older code that uses prototype or functional programming techniques. Object Oriented Programming (OOP) and Functionnal Programming (FP) are programming paradigms. Roughly speaking, following a programming paradigm is writing code compliant with a specific set of rules. For example, organizing the code into units would be called OOP, avoiding side effects would be called FP.

Comments
  • const increaseSalary = (p, amount) => ({ ...p, salary: p.salary + amount });
  • @JonasWilms You are acting like all the blogs now.
  • @KarlMorrison the flip side of that (and I'm not trying to be flippant) is that your ~50 LoC is an awful lot of boilerplate for what should be a one-liner....
  • person = increaseSalary(person)
  • @JonasWilms This is a very good question. For others: With asynchronous computations the original call stack is lost. So where is the state then? Well, the asynchronous effect is modeled through continuation and the corresponding monad in FP. Continuations are lazily evaluated, that is you build up a huge deferred function call tree when composing them. This tree is evaluated only when you actually run the continuiation. Voilá, there is the call stack again, there is the state.
  • Probably because most bloggers don't know what they are talking about.
  • I couldn't be more in agreeance. I am satisfied with your answer as it will get most people reading this on their merry way.
  • What do you mean by 'there is no such thing as "purely functional code" in an asynchronous world'? Of course there is. You build a pure abstraction of the computation and then run it. For example, IO actions in Haskell are purely functional. It's only when you run the IO actions that they actually produce side effects. It's the difference between console.log("Hello World!"), i.e. a computation, and () => console.log("Hello World!"), i.e. a description of a computation.
  • There is no such thing as "purely functional code" in an asynchronous world. - Even promises would be purely functional if it weren't for the strict evaluation of the promise constructor. You can't make your entire program purely functional, but you can defer impurity to the edge of your program so that large parts remain purely functional.
  • @AaditMShah I can't help but feel this has turned into something of a semantic debate about the meaning of the term "purely functional code" rather than a real point of disagreement. I could be wrong about that.
  • "This is plain procedural code with a very thin coat of OO paint", that is the whole point... Well since you can't abstract it enough (I get the vibe of curse of knowledge from you) I guess you won't be able to answer my question properly. I don't see any FP code, so I will no be accepting this.
  • @KarlMorrison yes, it is the whole point: you can write procedural in any language. But it isn't FP any more that your example is OO. See Jonas Wilm's examples for proof.
  • @KarlMorrison also, you may be right about the curse of knowledge thing. I can think of several examples of things that seemed completely obtuse to me when I didn't understand them (closures, monads, promises in JS), and completely obvious once the lightbulb clicked.