Earlier quoted context omitted.
> I know of no ECS languages. Any language with mixins and reflection can do ECS. e.g. Use mixins (components) and reflection to check which mixins an object (entity) has, then executing a code path (system) based upon that answer. Many dynamic languages, like Ruby, support this combination of features. I think the issue is many game developers work in C++ which lacks them. There is a school of thought that design pa…
ECS is commonly implemented without reflection. What are these implementations missing?
The Repeated Deaths of OOP (2015)
141–150 of 220 posts
Re: The Repeated Deaths of OOP (2015)
#142ECS is often implemented in an OOP language. I know of no ECS languages. You have objects that you iterate over and apply changes to the struct or object's fields like x and y coordinates in a game tick for the "next state" Essentially you end up with lots of global functions and very large API space that has no ordering. There's inherent ordering to global function application to produce the correct result. So it pr…
Shouldn't Unity's DOTS/Burst subset of C# count? It gets optimization from alias analysis that you can't get with an ECS in C++ or unrestricted C#.
https://docs.unity3d.com/Packages/com.unity.burst@1.3/manual...
Re: The Repeated Deaths of OOP (2015)
#143Classes were never definitional for OO, so prototypes, as originated in Self and adopted in JS, are not a violation of it. Function calls and messages are, fundamentally, isomorphic. Messages were never definitional. The notion of "purity", everything is an object, was never definitional. That was a Smalltalk conceit. Alan Kay named the idea, but stole it. So he doesn't get to impose his religion. What is definitiona…
I think Billy Idol sings about that in 1983 or so in White Wedding: "there's nothing pure in this world; there's nothing sure in this world..."
Re: The Repeated Deaths of OOP (2015)
#144Earlier quoted context omitted.
Sorry, it’s my pet peeve, but referential transparency doesn’t mean what many think it does — what you mean is simply side-effect freeness. See the top answer here: https://stackoverflow.com/questions/210835/what-is-referenti...
That answer is so informative and yet it completely misses the point. The problem is even called out in the answer itself: > For example, our example "Edinburgh has been the capital of Scotland since 1999" signifies the fact that "capital of Scotland" depends on the time at which it is being considered. Such context-dependence is a reality, both in natural languages and programming languages. "Therein lies the rub."…
The latter is (quoting pron’s older comment: https://elarib.com/item?id=22141647 ): “an expression e is referentially transparent if any sub-term in it can be replaced with any other having the same reference (aka denotation) without changing e's reference”. Perhaps I should have linked this comment over the stackoverflow answer, as it also mentions how eg. template haskell or LISPs are actually NOT necessarily referentially transparent due to macros. So while in Java replacing the constant 2 with a variable having value 2 is always equivalent (in reference, not necessarily effect!), the same may not be true with a given macro applied.
Re: The Repeated Deaths of OOP (2015)
#145Earlier quoted context omitted.
Isn't every existing programming language eventually based on (or at least traceable to) lambda calculus? OOP is just another way to organize code. Human language is unsuitable for " glass clear ", unambiguous definitions, just because of its inherent fuzziness (which is nota bene an essential property for efficient communication).
> Isn't every existing programming language eventually based on (or at least traceable to) lambda calculus? No. Prolog et. al. is based on Horn Clause representation and evaluated using something called SLD resolution. "Concatinative" languages (like Joy) are based on function composition (not application.) (FWIW, the Turing machine is not based on Lambda calculus. Not that TMs are a programming language.)
Re: The Repeated Deaths of OOP (2015)
#146Earlier quoted context omitted.
> Once you start arguing "OOP" vs xyz or "FP" vs xyz, you've missed the point. I think if we were intellectually honest in our arguments this would be fine—we could manage that OOP is poorly defined. Instead almost every debate about OOP takes this form: someone criticizes things which are exclusive to OOP (e.g., inheritance) or very common in OOP (kingdom of nouns, everything having references to everything else i.e…
> We could have a more interesting, robust debate, but poorly defined terms + bad faith means we get the same no true Scotsman rhetoric over and over, and it’s hopelessly dull. If you want a healthy and robust debate, dismissing defenders of the most popular paradigm as always acting in bad faith is not how you get there. This would also be a good way for you to learn more about the field. For example, is “just bad c…
(1) I'm not dismissing, I'm criticizing. (2) I'm very clearly not arguing that all OOP proponents are always acting in bad faith.
> This would also be a good way for you to learn more about the field. For example, is “just bad code” actually more prevalent due to OOP or because it’s the default paradigm for the most popular languages (Java, C#, Python, even JavaScript although that’s messy) and especially those used by the legions of lower-skilled developers cranking out business logic?
This is begging the question. The whole point is there's a semantic argument: is OOP defined by the features and design patterns (including the "bad code" design patterns) that are unique to OOP, or is OOP defined differently and this is the same kind of "bad code" that exists in other ecosystems?
But in whatever case, the debate rarely advances this far because we get mired in semantics, which is my broader point.
> I think FP is a useful technique but, like any tool, it is not perfect and a good developer should have enough experience to be flexible based on the problems and resources.
To be clear, I'm not an FP purist. I actually don't like very many FP languages, and indeed there are some values of "OOP" for which I could be called an OOP enthusiast (to the extent that one would be willing to call idiomatic Go or Rust, "OOP").
Re: The Repeated Deaths of OOP (2015)
#147Earlier quoted context omitted.
While they do have statements as well, they usually also have expressions, which are referentially transparent (and yeah I know it’s not the usage most people use, but it is the correct one: https://stackoverflow.com/questions/210835/what-is-referenti... ). (They don’t employ currying though)
I never quite understood Uday's objection. Any language can be referentially transparent if you consider it's denotation to be just its syntax. Then you can always replace equals with equals, but the only thing equal to an expression is the exact same sequence of characters! The whole point is to be referentially transparent with respect to as coarse a semantics as possible. Haskell gets some of the way there, yet ev…
So taking eg. Template Haskell, you actually loose referential transparency since then even the syntax itself matters and you can’t just replace it to an equivalent expression. I have no experience with Template Haskell itself so bare with me, but eg. having a macro m that converts the constant 2 to the string “two” while others to empty string will fail to be referentially transparent since `m 2` will not be the same as `let a = 2 in m a`.
Re: The Repeated Deaths of OOP (2015)
#148Earlier quoted context omitted.
> Though wouldn’t using arrays of structs kill the performance the same way as array of objects do (stack-allocated ones)? Not really. Components are long-lived so they're not allocated on the stack. And contiguous arrays of structs/objects is the best case for cache locality, that's the entire performance case of ECS.
A simple struct/object having in order an int, a string pointer and another int having 3 different things happening to them can in some case be worse than having all the ints next to each other, etc. ISIISI… vs III…SSS…III.. So for cache locality the latter is the best option.
This is also where ECS as a pattern falls down (from the simplistic ideas about them being performant) because keeping components in packed arrays is only one part of making them efficient. The biggest issue is making sure your entity data is best organised for the most common data access patterns. For example you can’t actually store data in big blocks of single component type but need to consider the shapes/archetypes (common sets of components) that make up an Entity. For each archetype we can store the components packed in arrays so that they can be iterated contiguously. That way Systems can visit all of the archetypes that contain the components they care about and iterate straight through them whilst minimising cache misses. This approach obviously falls down the more heterogeneous your Entities are. It also incurs a cost when a component is added or removed from an Entity so makes some common ECS patterns more expensive. There are other approaches with different trade offs.
But this is also pretty academic for most games which don’t have the entity count or gameplay complexity to actually require this level of performance anxiety.
Re: The Repeated Deaths of OOP (2015)
#149Earlier quoted context omitted.
Why do critics think looping over an array is somehow incomprehensible in OO and must be replaced with inheritance or something? Most ECS implementations are in OO languages. In Unity/C#, those systems are objects those arrays holding component information are even objects! Its really not a stretch for OOP. Its just a design pattern.
Being written in an object-oriented language doesn't make code object-oriented. I could write Java using classes as (namespaces for stateless functions) XOR (structs with no methods), and while it'd still technically all be objects and methods, in practice it wouldn't embody the spirit of OOP at all. It is in keeping with the spirit of OOP to wrap up different entities' data in separate objects and have them interact…
Re: The Repeated Deaths of OOP (2015)
#150Earlier quoted context omitted.
> We could have a more interesting, robust debate, but poorly defined terms + bad faith means we get the same no true Scotsman rhetoric over and over, and it’s hopelessly dull. If you want a healthy and robust debate, dismissing defenders of the most popular paradigm as always acting in bad faith is not how you get there. This would also be a good way for you to learn more about the field. For example, is “just bad c…
> If you want a healthy and robust debate, dismissing defenders of the most popular paradigm as always acting in bad faith is not how you get there. (1) I'm not dismissing, I'm criticizing. (2) I'm very clearly not arguing that all OOP proponents are always acting in bad faith. > This would also be a good way for you to learn more about the field. For example, is “just bad code” actually more prevalent due to OOP or…
You made sweeping unqualified assertions which are hard to reconcile with that claim:
“OOP proponents reliably turn the debate toward semantics rather than engaging with the substantial criticism”
“We could have a more interesting, robust debate, but poorly defined terms + bad faith means we get the same no true Scotsman rhetoric over and over, and it’s hopelessly dull.”
If that’s what you believe going in, it’s unsurprising you’re not finding better quality outcomes.