proj-oot-ootOopThoughts

in Oot, OOP should for the most part be encouraged only when you are (a) encapsulating the representation of a data type, or (b) grouping together and encapsulating mutable state. For an example of (b), you have a number; you know that you can do arithmetic with it but you want to encapsulate whether it's an integer, fixed point, floating point, whether it uses two's complement representation, etc. For an example of (b), you have a key-value store; you know that it can do CRUD but you want to encapsulate whether it's a hash table, an SQL database, a noSQL database, etc.

What does this exclude that is typically OOP'd? We discourage putting utility functions for operating upon the object as methods of the object itself; these should be freestanding functions in a module, instead. For example, if you want to sort a list, typically that doesn't belong as a method on List; rather that goes in an interface (typeclass) that then has an implementation for List. An exception to this rule is when the operation can make use of an optimized platform primitive; eg if your list actually might be stored in a remote database and you can ask the server to sort it faster than you can sort it at the client, then the implementation of the sort must break encapsulation and so should be a method. Of course when designing List you can imagine that maybe someone might someday want to do this, so do you put .sort() in there? No, keep List small, someone can always make a subclass ListSortable? later with an .sort() method.

This probably isnt different from current best practice in other languages, but it does seem to be different from actual practice, where you sometimes see huge classes with lots of methods, instead of modules with lots of freestanding functions and small classes.

---

" Single inheritance is convenient, because it simplifies many aspects of the implementation. Objects can be extended just by appending fields; a cast to the supertype just involves ignoring the end, and a cast to a subtype just involves a checkā€”the pointer values remain the same. Downcasting in C++ requires a complex search of the inheritance graph in the run-time type information via a runtime library function. " -- [1]

---