--
[0] - Everything I worked on, from games through embedded to web development, was a poor fit for C++/Java-style OO, but I suspect there are some domains where OO modeling is the best way of looking at things.
I agree though, that having the entire program be a graph of objects is actually usually the worst pattern.
This is what I was primarily thinking about, and this is what is most written about in OOP books. OOP is a big bag that wraps itself around a lot of things, and which appropriated quite a lot of concepts. The concept of gluing together a bunch of data and code in order to treat them as a single entity is indeed useful (at least for imperative code), and while it is the foundation of OOP, I don't think it's really the distinguishing thing about various OOP approaches. For the class-based OOP, it's the composition of data+behaviour, encapsulation, polymorphism and inheritance that together create a particular philosophy - one that I find much less useful than advertised.
The building blocks are no doubt useful - a proper type system is great, but you don't need classes and objects for that. So is polymorphism, and again, you don't need Java-style classes to get method dispatch (see e.g. Common Lisp multimethods for an arguably better way of doing this, and one that doesn't even treat methods as parts of classes!).
I'll concede that OOP approach fits UI libraries unusually well (though you can hit some conceptual roadblocks there too; I'm not sure I've ever seen a good OOP design of tables, nor do I know how to design it well). But then again, I was recently writing some React code in ClojureScript, and it turns out that functions and plain data can handle building stateful UI components well too.
What I mean by saying that OOP appropriated things - I've seen people thinking, and even myself I used to think, that "abstraction" is something that a class creates, and is what you achieve with OOP. I gradually grew out of that belief, and I vividly remembering that reading SICP made it finally click in my head that quite a lot - if not most - of the software engineering practices discussed and attributed to OOP are in fact more general concepts applicable regardless of your programming paradigm.
For Alan Kay it was all about messanging but I dont think most people think about that.
Structs with some kind of dynamic dispatch based on the type would be the most general discription I think.
Common Lisp really opened my eyes here. Initially it felt weird to have methods[0] living completely independently from classes, but over time I realized that where classes and objects implement nouns, generic functions and methods represent verbs, and in a language the verbs are an independent domain from nouns, representing their own generalized concepts that's unrelated to the taxonomy of nouns.
--
[0] - A "method" in CLOS is an individual implementation of a "generic function". So e.g. you could have a generic function `(defgeneric draw (device figure))`, and then specific implementations dispatching on any combination of arguments; e.g. `(defmethod draw ((device printer) figure)` to draw any kind of figure on a specific device, or `(defmethod draw (device plotter) (figure circle))` to draw a specific thing on a specific device, etc.
def method():
this.value = this.value + 1
lisp does something like this? def method(object):
object.data = object.data + 1So you might have.
define generic inspect-vehicle (v :: <vehicle>, i :: <inspector>) => ();
define method inspect-vehicle (v :: <vehicle>, i :: <inspector>) => () look-for-rust(v); end;
define method inspect-vehicle (car :: <car>, i :: <inspector>) => () next-method(); // perform vehicle inspection check-seat-belts(car); end;
define method inspect-vehicle (truck :: <truck>, i :: <inspector>) => () next-method(); // perform vehicle inspection check-cargo-attachments(truck); end;
This is Dylan code, but its the same concept, easier to read compared to CL. See: https://opendylan.org/documentation/intro-dylan/multiple-dis...
Once you start thinking about dispatch in a broader sense the advantage is clear.
Common Lisp gets rid of implicit `this` by making all arguments explicit, and by not restricting polymorphism to the first parameter - in fact, you can do a method dispatch on any of the method parameters, or any combination of them. See https://news.ycombinator.com/item?id=18848384 for an example.
But to be clear: Node and Java (and anything with a managed heap) doesn't have a paradigm for things like RAII or inlined parametrazation or copy-by-value or move semantics because it doesn't have a way to express them. But those are useful tools and important in some regimes.
C++ is very messy, but for the most part you can ignore the messy things.
I feel we should build our programs the same way. Bottom up from a small set of simple primitives. Not top down like C++.
* C++
* Lua
..
.. [a thousand other things]
..
..
* Node
* Javascript
__ bottom of the pile..
The Node/JS ecosystem is such a steaming pile of garbage, I can honestly see with great clarity why people should be running from it back into the arms of C++[11,17] ..
Now, I'm sure some people have an easier time with Makefiles, but I've found it even easier to get up and running in Javascript. Most of the tools in Javascript (create-react-app, Webpack, etc.) are very user friendly, making setup trivial.
It is best not to speak with such authority/certainty that C++ is easier to use than Javascript.
Don't underestimate the pile of garbage JS indeed is! Yes, you can install a package with ease, you'll have to do that with about 100 packages that keep changing all the time with all kinds of breaking changes (not talking about their 1000's of dependencies). I'm also sick and tired of the hipster JS community where every piece of shit can become a hype. With JS you'll be forced to work with things you hate. Almost all codebases I have to work with are horrendous piles of rubbish that often need to be completely rewritten from scratch. Almost everything you write doesn't last. You've spent a year learning Backbone? Just throw it away, now it's Angular you can start all over again. One year later? Stop doing Angular, it's React now, just start all over again! Hey, now we have some hipsters promoting Vue, they say it's the holy grail, just start all over again, it's fun! Flux stores? Fluxxor, Alt, Redux, Redux with Saga's, or just go with Thunk? It doesn't matter that much, it only lasts for 1 or 2 years! I'm completely sick and tired of it, including the fact that I'm only working on stupid e-commerce websites..
Talking about make files, a magnitude easier than trying to setup babel and webpack for a medium sized SSR SPA. I recently had to upgrade from babel 6 to 7, what a fuckin pain that was, so many changes, the deployment server refused to boot etc, etc..
Mind your step going into JS!
Similarly, with C++ there are also many packages to do the same thing. This summer I was using TLS and I found a variety of options, OpenSSL, mbedTLS, wolfSSL, etc. etc.
I do agree that it is tiring to learn some of React's accessories. I have never used Redux and when I do need some form of global state management, I think I will use MobX.
The complaints about code base quality and "stupid e-commerce websites" don't seem to be problems inherent to Javascript, although I suspect the problems Javascript solves are less interesting than the ones C++ solves.
All in all, I feel like C++ (for me) has been more difficult than Javascript due to a lack of standardization and the community being less beginner friendly.
That being said, I was trying to use a relative obscure feature (SGX) in C++, whereas with Javascript I stick to relatively mainstream applications.
https://www.infoq.com/presentations/Simple-Made-Easy
JavaScript is a simple language that can be made extremely complicated via "simple" tooling. You can open the node_modules folder and see how sausages are made. :-)
C++ is dealing with essential complexities, there is no silver bullet:
Unless of course you have 30+ years of experience in the software business, have kept abreast of all the latest and greatest distractions from proper software engineering practices, have built a few hundred examples of such personally, and have no desire to throw more garbage at the fiery pile. As is my personal case. Node/Javascript are the Visual Basic of the 21st Century - this doesn't mean people haven't been productive with them as technologies, just that they've been productive in spite of them.
https://nbviewer.jupyter.org/gist/ontouchstart/1af198f8535eb...