5 ms·
Language support is a bit of a distraction. It's a pattern in languages that have no "official" support for it. Go find some old C code for doing something lik
by nitwit005 6y ago
Language support is a bit of a distraction. It's a pattern in languages that have no "official" support for it.
Go find some old C code for doing something like compressing a file. You'll likely find a set of functions where the first or last parameter is always a pointer to some struct or array with the current state of the compression process. If you converted that code to C++, and made it an object, that pointer would be the "this" pointer. The support for objects is just recognizing the common pattern.
Inheritance is similarly recognizing that a lot of code had structs or arrays with multiple function pointers.
The language support just makes those patterns a bit cleaner and less error prone.
- fierro 6y agoI agree. This gets at the real distinction between one language and another; which patterns have been elevated to the status of a statement, expression, control structure, or keyword. class in Java is a formalization of the OOO pattern, for example. There's nothing you can do with OOO that you can't without it, and vice-versa. At the end of the day all we have are instructions and data.
- ywei3410 6y agoI think this sort of reduction is lazy in terms of design for language semantics; there's a massive difference in expressiveness between languages and to pretend otherwise is to do a disservice to the rich field of PL theory. Even when you elevate a particular construct to be first-class in a language; the expressiveness of languages differs greatly. For example, prior to lambdas, first-order functions existed in Java in the form of static methods - but higher-order functions weren't really possible. Even now, we lack the ability in Java to express certain forms of functions which are possible in more expressive functional languages. Lisp's in general have the same control constructs as many imperative languages, but it's possible to do higher-order abstractions over them through the use of macros and constructs like shift/reset or call/cc and the fact that everything is a s-expression. In this regard, Java and C-like struct pointers are almost first-order OOP languages - the composition via inheritance is quite frankly poor compared to the other paradigms.
- imtringued 6y ago> higher-order functions weren't really possible I see you have never used Swing. The reality is that when you needed a callback there were interfaces with a single method and you created anonymous classes that implemented that callback and its method. It's clunky but it's equivalent to higher order functions.
- ywei3410 6y agoI've used more Java enterprise frameworks than you can shake a stick at; I started with Java 1.4 mostly so I'm certainly aware of those patterns! Whether they are "equivalent" depends on your definition of equivalency. Could Java pre-SAM claim to have first-class functions; I would argue not because there was a separation between methods and classes - even though you could make a case that by having `Callable` or whatever anonymous classes you could use to emulate similar behaviours. Does Haskell have inheritance? No, but you can emulate some parts of it with a mixture of template haskell, record types and lenses.
- deleted 6y ago[deleted]
- nomel 6y agoThe more I used C, the more I ended up using structs as instances and functions that looked like: void mything_somefunction(MyThingStruct *mything, ...args){} The weirdest thing was some of the crusty C guys in my group saying "Eww, is that objects?" No, it's maintainable, and it avoids collisions.
- dnautics 6y agoThat's really strange. In my era I knew a lot of C programmers who specifically advocated this as a "better way to do objects" than C++. Even some who in a pinch implemented their own v-tables, freely admitting that occasionally copping an idea from C++ and turning into an explicit contract is a thing (though this was painful enough that you would rightfully do this rarely). It's even more strange now, that we have distinctly non-OO languages that explicitly use the first-parameter-is-struct pattern, e.g: struct definition: https://github.com/elixir-lang/elixir/blob/v1.10.4/lib/elixir/lib/calendar/date.ex#L54 https://github.com/elixir-lang/elixir/blob/v1.10.4/lib/elixi... and functions: https://hexdocs.pm/elixir/Date.html#functions https://hexdocs.pm/elixir/Date.html#functions
- vbezhenar 6y agoAt this point I don't understand why people don't just use C++ for such a code. Of course bringing all C++ features is another matter. But getting some object-oriented C code and transforming it into C++ code is pure win.
- thu2111 6y agoA lot of it is/was driven by the historical instability of the C++ ABI, itself driven by instability in the language. If you made an object with a C based pattern, you could export a binary compatible interface and use dynamic linking. If you exported the same object as C++, even if it boiled down to the same thing, your users might get crashes because two compilers disagreed on the right way to compile it. That's the origin of COM. It's basically the C mything_mystruct pattern with a lot of additional stuff on top. Actual COM objects were usually implemented in C++ though.
- 6y ago
- wvenable 6y agoEven the Linux kernel, written entirely in C, is filled with object-oriented concepts including vtables because both encapsulation and polymorphism are useful concepts. Some as simple as multiple file systems all implementing a common interface (either local or over a network).
- dehrmann 6y agoData structures fit OO extremely well because of OO's ability to encapsulate state and how it can use inheritance to make different implementations of data structures interchangeable (hash-based maps vs sorted, tree-based maps).
- lmm 6y agoIt's the languages that cause the problems, by codifying the pattern wrongly. C++-style "extends" conflates three different things (composition, polymorphism, and delegation) and encourages programmers to think of them as being the same; in a non-OOP language these three things would naturally emerge as distinct patterns (and thankfully newer languages are finally starting to realise this, and support them as orthogonal things).
- loopz 6y agoThey are also moving away from Objects being natural concepts for communication. Orthogonal design seem to impose structure away from what is easily shared among humans, while inheritance and fat classes are easier to explain.
- jupp0r 6y agoWell, it’s been an anti pattern to share mutable state. C++ just makes this anti pattern the standard way to accomplish anything.