7 ms·
"Classes would still exist, but as implicit patterns." Classes are not a design inevitability, but just one way of managing state. Languages that mostly avoid
by weavejester 5y ago
"Classes would still exist, but as implicit patterns."
Classes are not a design inevitability, but just one way of managing state. Languages that mostly avoid mutable state don't tend to have object systems, for instance.
- jakobnissen 5y agoRight, that's true. I think structs are inevitable, and classes is the way to get structs in Python. But yes, the entire OOP-classes with namspaced methods and "self", that's not inevitable
- pjmlp 5y agoIn a very simplified way, classes are extensible modules. That has always been in trend in most languages, first one gets modularity, then eventually they outgrown now being able to have generic modules, and eventually they land into something that is for all pratical purposes OOP (there are many ways to skin a cat).
- weavejester 5y agoI'm not even sure structs are inevitable. You could write a language around open sets of key/value pairs, for example.
- pjmlp 5y agoType classes and ML functors are also a way to do polymorphism and dynamic dispatch on data structures. So which languages are left without object systems?
- cttet 5y agoTo be more concise classes != object systems != polymorphism and dynamic dispatch on data structures The difference between them are important to some people. And that's why they will argue for that.
- pjmlp 5y agoOne thing that is common to many people arguing is that they actually never bothered to read SIGPLAN, or CS type systems. So they argue with knowledge based on Internet facts instead of actual CS literature.
- cttet 5y agoThe natural language is evolved by people saying what they what and the majority became the language. Not defined by some elites or some authority. Classes binds data and functions together, and object systems supports inheritance. These are some of the things that some people don't really like, but you may not care. People sometimes care about syntax as well, writing "Class" is also part of the experience of using the language. We have different words in the language for a purpose, that's my opinion.
- pjmlp 5y agoModules also bind data and functions together. Not all object systems use inheritance, and even those that do, we can speak about delegation, interface/trait/protocols/type classes inheritance, regular classes inheritance, or some weird stuff like object patterns from BETA. That is why we have CS literature, to put the right words in place.
- cttet 5y ago| Modules also bind data and functions together. Yep, but a module is still not a Class. My example was referring to you mixing concepts of Classes and Polymorphism and dynamic dispatch in your original reply. As you said, there are a lot of object systems that are different, and the difference matters. Having inheritance or not matters. I was just making examples to show that things are different. We all know that C++ concepts != go/typescript interfaces != Java/c# interfaces != Haskell type classes (c# concepts) != rust/scala traits. Try to explain that using "CS literature", maybe a lot of language designs don't have a word yet made for that. Yep there are Subtyping, Bounded quantification, Ad hoc polymorphism, Row polymorphism, but still not enough to tell all of them from each other. But to anyone in the community, people all know that they are all not Classes and what make them special is important. It is quite clear, but why don't you get that? The concepts CS literature are quite trivial and people can spend a few weekends to learn, or maybe another few for type rule syntax or a few others for basic category theory to understand them in a more intuitive way. But the real problem of making a good language for some applications is still there and much more complex and difficult. And maybe current literature are not enough for that. The elites will never dictate the words, the people will pick up whatever they want to express their knowledge anyway, as we know of what happened in history.
- GrumpySloth 5y agoType classes are a way to do polymorphism, but... dynamic dispatch? I don't think so; which function is called, is determined statically. As for ML functors: they're neither polymorphism, nor dynamic dispatch. First: functions for different types can't share names (unless we're talking about shadowing of names with lexical scope), the names are either qualified with the name of the struct they come from or they're not qualified at all. In all cases there is exactly one implementation for every name. And again: no dynamic dispatch. MLton even defunctorizes all code at compile-time. The only polymorphism in SML is the one that's used in some built-ins (like +), but it's not available to users of the language. SML has something called "polymorphic functions", but it has nothing to do with writing multiple implementations of one function under one name and letting the compiler select which one is called; which is what is usually meant by "polymorphism".
- pjmlp 5y agoThere are many ways to skin a cat how those declarations are written. If I have time later I might post an example, apparently we are only right with code.
- weavejester 5y agoPolymorphism and dynamic dispatch don't equate to an object system in and of themselves. At minimum, I'd say an object system needs some form of messaging and state hiding. That is, an object holds hidden state, and responds to external messages.
- pjmlp 5y agoSome would say that starting from lambda calculus it would be enough to reach there. I advise some reading "The Art of the Metaobject Protocol", or similar literature.
- weavejester 5y agoObviously any Turing complete language can implement an object system, but that's clearly different from the language having an object system built in.
- pjmlp 5y agoWe can start discussing semantics then, when a language supports a feature, it is only when it is hardcoded on the compiler, or the language offers enough lego blocks to do it via a library.
- weavejester 5y agoIt's when it's part of the core language, as any Turing complete language can implement any feature of any other Turing complete language. It's not a useful statement to say all languages support all features.
- pjmlp 5y agoSo I guess Common Lisp, Raket, Scheme, C++, C#, F#,... just lost a couple of features.
- 5y ago
- Supermancho 5y ago> Classes are not a design inevitability, but just one way of managing state What "Classes" are is a tragedy of things. Classes are closures, with a syntactic form that allows for nested composition. This is a particularly brittle form and these qualities are found in all languages with Classes. Language maintainers, as they currently exist, have failed to concede that this is a bad idea, because "it works good enough for lots of cases". This has hurt the industry by creating a culture that can only support the view that "all code is ugly". Given the choices, the variability in how code evolves randomly to deal with choices made under these conditions, is unsurprising. Why? Because Classes are a good feature that has been misrepresented as a compositional tool instead of a syntactical shortcut and nobody is dealing with the gravity of that...given the amount of history, industry, effort, et al based around supporting their faux necessity, who could be blamed for not raising a stink? And why is there a "new" keyword in 2022? Python gets this right. Almost every language ends up heaping additional syntax for behavior that is either compiler added (eg php/rust traits, ruby aspects) a meta-language (eg Java aspects, php attributes, various C++ impls, ES6 javascript classes), or a straight mixin syntax (Python decorator). This alone, is obvious that the support for composition is a major problem that has both been neglected, then mishandled by heaping on the same mistakes. Interfaces, were a particularly laughable solution, which has made the problem worse by tying that limited form of composition with reflection. > Languages that mostly avoid mutable state don't tend to have object systems, for instance. They do, in the form of closures. How infrequently composition-by-nesting is used in functional languages is telling (basically the inverse of nonFP languages).
- tsimionescu 5y agoClasses are closures just as much as closures are classes (as Java showed). What classes are at their most core is bundles of behavior, possibly with encapsulated state, and usually some way to decide at runtime which of a family of classes' behavior to use. Closures are naturally tied to 1 single behavior (though of course you can invent ad-hoc methods of extending that, such as a "methodName" parameter, but no one ever does this in practice). This is the reason why classes and interfaces actually exist in some form or another in all useful languages today. For example, Go has structs with methods + interfaces, Rust has structs + traits, OCaml has modules + module types (well, it also has classes, but I understand those are less popular), Haskell has data types and type classes, and on and on, JavaScript has objects + dynamic name resolution. The one idea from classic OOP that has turned out to mostly be a dead-end is implementation inheritance + subtyping. This is basically the only class feature you'll only find in specific OO concepts, and basically all modern guides tell you to avoid it.