I have so much to say about all of this, but the indentation on this comment thread is getting extreme. Everything you said is correct in some general sense of understanding software engineering, and yet ... somehow too fence-sitting. Static Typing vs. Dynamic Typing is not some 50/50 argument: evidence and the experience of people who use both is strongly in favor of Static Typing being close to "strictly better" for most teams. SQL vs. NoSQL is less clear, but you can extrapolate known "good practices" to show that the relational model is "strictly better" for the kinds of applications that most people actually want to build.

There's No Free Lunch, sure, but that's defined over all problems, which is an unbelievably vast set of things that we mostly never care about. The problems that human beings ever actually care about rounds to 0.000% of "all problems", and you could keep going with 100 more 0s after that. When you look at the industry and the problems people are actually trying to solve, sometimes "strictly better" starts looking like the right term to use for some of these tradeoffs; or at least "almost always better".

Ultimately Software Engineering is still a juvenile discipline compared to other kinds of Engineering, and I think we can look to our big siblings for some insights. It's obviously true that in Aeronautical Engineering, everything is a tradeoff and nothing is "strictly better", yet we don't see many biplanes flying around anymore. It is possible for basically the whole field to advance. (Although old ideas have a way of resurrecting, too -- maybe biplanes will suddenly become very useful for certain drones, or in the Martian atmosphere or something!)

> dynamically typed Clojure is also a great language

I'm sure it is! And I'm also sure that statically typed Clojure, with a sufficiently strong type system to represent the kind of code you want to write with it, would be an even better language. Although perhaps "sufficiently strong" is not yet achievable.

> I also think down the line people will realize [ECS] has similar / the same short-comings as NoSQL and will re-adopt relational for its benefits.

Entity-Component is more relational than standard table-per-noun architecture (at least the way I do it), but I understand why this isn't obvious and that it's something I'd need to prove.

> Note though that they also called out the trade-off of "normal" ECS and how you lose mode enforced / constraint checking.

I encourage you to sit down and think through all of the constraints on your domain logic, and then see how many are enforced at the database level. Let's look at the old classic https://wiki.c2.com/?WhyIsPayrollHard -- how many of these constraints are enforced with ACID guarantees at the database level? Something like this:

> After being sick for 3 days (when your pay comes from your normal account), you go on disability, where your pay continues but comes from another account. After N days you only get 60% of your pay, unless you come back and go out on a different disability.

This is a complex domain-logic rule that you could never implement in the database (unless you're using T-SQL as your application development language, in which case your Triggers are simply your application and you're still doing this in the application layer). All foreign key constraints can be phrased in terms of (often volatile) business validation rules -- there is nothing special about them, except the fact that they happen to be easy to enforce by the database. Look at that list of Payroll requirements and then ask again: how do you prevent invalid data states? There's no reason to single out database-enforced foreign key constraints as the only data validation check that you absolutely must enforce at the database layer. It's completely fine to drop foreign key constraints if you have other ways to validate your model -- and you must! (Yes, at the dreaded "application layer"! That's exactly what your application layer is!)

> any entity can take on any behavior with minimal changes;

Unfortunately we haven't even started talking about how behavior and domain logic works its way in here. It's not really like mixins -- mixins is like trying to add the concept of addition onto the number 7. 7 is just a number, and addition exists outside of it. Think more of the "Arithmetic System" as defining a set of operations that make sense to do on (collections of) numbers, and checking/enforcing constraints on that (no division by 0). (Obviously this doesn't explicitly exist since programming languages and databases already give us arithemetic for free.) Then the "Unit Conversion" system relies on the Arithmetic System to do its jobs, defining more complex aggregate data types, further narrowing the scope of valid operations, further enforcing checks. Then the "Chemical Reaction" system relies on the Unit Conversion System (and others), defines larger, stricter aggregates, further narrows the scope of valid operations on those aggregates, etc. It's built in successively strict layers working on successively more complicated "aggregate components" -- not really anything like mixins.

Thanks for the links. SpaceTimeDB is not really what I'm talking about but it's sorta close-ish.