3 ms·
Typically when an OOP programmer says the word ‘class’ they mean one (or both) of two things, depending on their favourite OOP language: - a factory for object
by Twey 1y ago
Typically when an OOP programmer says the word ‘class’ they mean one (or both) of two things, depending on their favourite OOP language:
- a factory for objects, that hides some internal state of the object;
- a static construct that gives a name to some (‘public’) subset of the behaviour of those objects, and which a type-checker can then use to ensure that the use of the objects adheres to the intended contract.
They're both mechanisms for encapsulation of internal behaviour (that may change at any time) while providing a blessed public API that you promise will stay the same (or at least only change in certain ways, under a strict discipline like semver or ‘we'll tell you on the mailing list’). The difference is that the former is runtime (dynamic) behaviour, while the latter is compile-time (static) behaviour. The former maps to functions (or, with state, closures), not types, in functional languages (see ‘objects are a poor man's closures, and vice versa’ [1]), and the latter… is types :) The same typing concept that ensures correct interaction with objects can also be used to ensure correct interaction with functions or other data types, though since functional languages are easier to type than OO languages strictly-typed functional languages tend to have stronger type systems that capture more properties, like effects.
[1]: https://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg03277.html https://people.csail.mit.edu/gregs/ll1-discuss-archive-html/...
From one perspective, there's a spectrum imperative <-> procedural <-> OOP <-> functional that is about how tightly scoped state changes are. In that view, functional languages are just the natural next step: if the whole point of OOP is to scope state, a functional language is just an OOP language with _even more_ tightly scoped state. The philosophy (uncontrolled state changes are scary and hard to reason about: add language constructs that allow the reader to see at a glance how far they have to look for the knock-on effects of a given state changes) is the same, just the implementation is different.
- labrador 1y agoThanks for the thoughtful response. As you know, I was drawing a parallel between the compile-time contract that a class provides and the role of complex types in functional programming. In many cases, a module that defines data types alongside functions operating on them feels similar to a class that encapsulates both structure and behavior. I realize there are deeper distinctions and advantages on the functional side, but I’m just trying to simplify and compare the basic conceptual building blocks. I also really liked your spectrum from imperative to functional. It's a helpful framing.
- Twey 1y agoNo you're totally right! In fact I think you're even more right than you said in the original post: the analogy you draw isn't just an analogy, they are in fact the exact same thing. A class is (amongst other things) a module, and a closure, and a type. In functional programming these things are (usually!) deconstructed rather than all being facets of the ‘class’ concept, but they're all still there and they all work exactly the same way as in OOP (perhaps modulo mutability, depending on choice of languages — but you can see local mutability as syntax sugar over function calls anyway).