> The pattern is called Functional Reactive Programming.

Worked with that in .NET a bit, specifically this one: https://github.com/reactiveui/ReactiveUI Not a big fan. For example, when I wanted to fix a bug, put a breakpoint to the code that failed, and reproduced, there was no way to tell who or why sent that event, the original context was already lost. For this reason I prefer simpler ways with interfaces or lambdas. Not sure if that’s a problem of the approach or the implementation I used. But generally speaking marshalling contexts is complicated and is a common source of bugs, YMMV.

> in web development performance is not the priority. Useability is.

I can see how it can be the case on servers (one reason is economy, for many companies it makes more sense to rent more EC2 instances instead of writing better software), but I’m not sure same applies to client. In the browser, you have the same 16.6ms performance budget for optimal usability. The fact that JavaScript is generally slower than compiled languages makes things worse.

> literally the addOne method cannot be reused without creating a banana, a gorilla, and a jungle.

Every design pattern can be abused, and none of them is a silver bullet. If you want to reuse that code, make it a global function, all OO languages have them or equivalents (static classes in C#). But other times, the feature if very useful. See the example linked in my previous comment (I hope C# is readable enough even for non-users), the iReadStream object returned from setupConnection can potentially hold quite a lot of referenced things, GZIP compressor, AES implementation, yet for the user of that object it’s just a trivially simple interface with a single read() method.

> If you want to restrict your function to operate on certain data types you do this by restricting the input parameters.

Due to polymorphism, OOP allows to write functions operating on data types unknown to either compiler or the programmer writing that code, as long as the types implement the expected functionality.

Microsoft replaces both data types and code of their IOutputStream.WriteAsync method with windows updates. Their changes don’t break my code, they don’t even require me to recompile it.

For that particular OS kernel API, you might say we aren’t re-implementing it on our side, and you would be correct. Still, that level of flexibility is very useful for making software. At least once the software complexity grows past some threshold: for simpler stuff it often does more harm than good.

> This is 100x better than the explicit use of "private."

These things are orthogonal. No one forces you to return half-initialized objects, you can throw an exception instead.

> Combining functions to form other functions hands down beats combining objects to form other objects.

Not every object can be expressed as a function. That C# example I linked above can, because iReadStream interface only has a single method, but if we want to do the same for writing, we now need 2 methods, write() and flush().

> You're not really doing OOP without an internal mutable var.

1. Why not? We have objects, they have methods which mutate their internal state. Looks OOP enough in my book?

2. If I would have actually implemented these objects instead of writing // TODO comments, these implementations all would have a fair bit of internal mutable vars, due to buffering, AES blocks, and other shenanigans.