Quintessence of OOP

You can talk about almost anything that you want to on this board.

Moderator: Moderators

Post Reply
User avatar
aa-dav
Posts: 154
Joined: Tue Apr 14, 2020 9:45 pm
Location: Russia

Quintessence of OOP

Post by aa-dav » Sat Dec 12, 2020 9:20 am

A lot of a lot was said and written about OOP as paradigm, as way of thinking, as trinity of sacred postulates... but a lot time ago I think I saw quintessence of it in it's the only essential core. And this can be described easily without tons of books and articles.
Primary enemy in understanding OOP is all this noise which quite often leads to labelling as OOP things which are not OOP in any sense.

First of all let's take look at procedural programming. Take a look at wiki: https://en.wikipedia.org/wiki/Procedural_programming
The focus of procedural programming is to break down a programming task into a collection of variables, data structures, and subroutines...
Indeed!...
...whereas in object-oriented programming it is to break down a programming task into objects that expose behavior (methods) and data (members or attributes) using interfaces. The most important distinction is that while procedural programming uses procedures to operate on data structures, object-oriented programming bundles the two together, so an "object", which is an instance of a class, operates on its "own" data structure.
Seems legit, but no, this is usual 'blah-blah-blah' without correct accent.

So, take a look at practical programming.
For example: typical procedural and modular C library: FILE stdio.h

Code: Select all

FILE *f = fopen(...);
fwrite( ..., f )
fclose( f );
What do we have here? We have structure FILE which inner details must not be our interest. And we have bunch of functions which has parameter of pointer to that structure/data.
This is what is known as 'incapsulation' - very good technique which traditionally described as invention of OOP. But this is false: incapsulation is good and productive technique known before.
Now if we want to change inner structure of FILE - we may edit functions from stdio module only (modularity on the march) and everything will be ok.
So: we have object, we have incapsulation, we have strongly dedicated functions which cannot be applied to other objects due to types control: so isn't it OOP really?
LOOKS LEGIT...
But no. Some could say what we lack of inheritence and this is why it's not OOP? Not really.

Let's express main idea of procedural programming: 'Write code (procedures) which works with known objects'.
There is a lot of procedural code. Examples could be: complex numbers library (and it's not important if it is 'std::complex' or java.math.Complex), string library (and also it's not important if it's final public String - it's not OOP!) and so on.

So where OOP begins? It's very simple, lets hear Alan Kay, inventor of Smalltalk - one of the earlies OOP-languages:
...the early work of Doug Ross at MIT (AED and earlier) in
which he advocated embedding procedure pointers in data structures,
Sketchpad (which had full polymorphism -- where e.g. the same offset
in its data structure meant "display" and there would be a pointer to
the appropriate routine for the type of object that structure
represented, etc.
And that's it: polymorphism is the nature of OOP.
Now, let's define main idea of OOP and compare it with procedural one: 'Write code which works with UNknown objects'.
Difference is 'known' vs 'unknown'. OOP objects in contrast with procedural objects have some layer of indirection to code which handes them and hiddens somehow exact data which they contain.
It's called polymorphism.
In strongly typed languages primary technique to implement polymorphism with type-checking is inheritance. That is why it is included in 'sacred trinity of OOP'.
But it's not true what inheritance is required as such. In non-typed languages polymorphism can be implemented without it. It's known as 'duck typing'.
In general it's not important how to implement it: you write OOP code then objects which it works with could have different internal structure and could react in different ways to the same 'messages' in runtime.
For example: HWND with PostMessage in WinAPI is OOP. It's not procedural, but OOP library. (For sure: if you write GUI you either end up with OOP or with extreme shit).
All these 'fruits' and 'apples' is just about 'write code which works with unknown (in runtime) objects'.

So, that's all and simple.
Last edited by aa-dav on Sat Dec 12, 2020 9:52 am, edited 7 times in total.

User avatar
aa-dav
Posts: 154
Joined: Tue Apr 14, 2020 9:45 pm
Location: Russia

Re: Quintessence of OOP

Post by aa-dav » Sat Dec 12, 2020 9:24 am

So, I think that if you put pointer to procedure 'handler' in the array of monsters - you may end up in OOP. :)

coto
Posts: 55
Joined: Wed Mar 06, 2019 6:00 pm
Location: Chile

Re: Quintessence of OOP

Post by coto » Sat Dec 12, 2020 10:53 am

To me, at least. An OOP object is a generic object (polymorphic). And as such has a lot of nice things like you focus on the task and not how the task is built. Another would be, a task is built around orders, recipes then the actual procedure of cooking. You can have as many orders, as many recipes, and these would order largely the main procedure, ensuring the order, recipes, ingredients, and the cooking itself taking its own process without affecting the other.

And then, if in the middle of the development, you want to update the main procedure, it'd affect only the recipes and the behaviour of specific objects, not all of them. This is critical if, say, you maintain a game codebase, or a SDK and want to add features without breaking compatibility, while retaining unit tests, and of course, a stable codebase.

User avatar
aa-dav
Posts: 154
Joined: Tue Apr 14, 2020 9:45 pm
Location: Russia

Re: Quintessence of OOP

Post by aa-dav » Sat Dec 12, 2020 7:12 pm

coto wrote:
Sat Dec 12, 2020 10:53 am
And then, if in the middle of the development, you want to update the main procedure, it'd affect only the recipes and the behaviour of specific objects, not all of them. This is critical if, say, you maintain a game codebase, or a SDK and want to add features without breaking compatibility, while retaining unit tests, and of course, a stable codebase.
Main consequence of 'write code which works with UNknown objects' is that core of program written to work with 'fruits' do not requre any changes then you add new 'banana'. That is why OOP is flexible and extensible. Procedural programming can easily _modify_ KNOWN objects, but cannot add or delete them easily. But OOP can add and modify UNKNOWN objects which implies addition and/or deletetion.
Core of program written to work with any fruit do not requires modifications while new fruits are added/removed. And it's powerful invention which encloses modification of program in small amount of program parts which is one of the main goal of programmers: to make it easier to control and modify.
But if we want to add new behaviour to all fruits it is not working anymore and modifications to many different places are required, so upgrading base class with new virtual methods/behaviours is the main enemy of OOP.

Garth
Posts: 207
Joined: Wed Nov 30, 2016 4:45 pm
Location: Southern California
Contact:

Re: Quintessence of OOP

Post by Garth » Sun Dec 13, 2020 6:22 pm

It seems like I really should learn OOP. I read and read about it, watch videos, and I understand a little and say, "Oh, I've done that in Forth. I didn't realize it was OOP." But then I don't understand the OOP explanations well enough to regurgitate them. Apparently OOP's greatest value is in GUIs and teams of programmers. I've brought a lot of products to market with microcontrollers and two with the 65c02, and automated test equipment on an industrial computer bus with a 65c02 CPU, projects up to 10,000 lines of code, but I've never worked in a team, always alone. It was interesting to see two professional programmers on the 6502.org forum arguing about OOP, both with loads of languages under their belt, both with tons of experience with OOP, but one arguing that it's stupid and no one thinks in terms of objects, and the other one arguing exactly the opposite. I've gotten explanations for all the terms: objects, inheritance, binding, type, class, base class, aggregation, method, Sather, IDL compiler, object proxies and skeletons, domain optimization, polymorphism, etc.; but the explanations are Greek to me too. You can tell by my website that I'm no neophyte (and there's lots more material I want to add, but it all takes so much time), yet OOP seems to be beyond my ability to ever understand it. As such, I have mixed feelings about its true value in computer science. All the tools should make projects more manageable and understandable, not less.
http://WilsonMinesCo.com/ lots of 6502 resources

User avatar
aa-dav
Posts: 154
Joined: Tue Apr 14, 2020 9:45 pm
Location: Russia

Re: Quintessence of OOP

Post by aa-dav » Sun Dec 13, 2020 7:20 pm

Let's take another example: suppose we write cross-platform program which requires graphic output.
And we decide to write graphic output library to video screen.
To cover all platforms we make some object (I will use very abstract syntax):

Code: Select all

struct screen ...
and bunch of functions to it:

Code: Select all

put_pixel ( scr, x, y, color );
draw_line( scr, x1, y1, x2, y2, color );
where scr is required to be screen context on any platform and functions hide details from user code.
This is old good procedural programming library and then you hide implementation behind interface of library you make porting, testing, using and modification of library and code which use it easy and so on.

Well, time passes and some day you are required to add to program ability to print graphics it is drawing on printer.
Well, well... A bunch of routines inside your program draw something on the screen already, but if...
And you upgrade 'screen' structure to 'graphic_context' and rewrite procedures like 'put_pixel' so actual drawing procedures are hidden in this 'graphic_context' (for example as pointers to actual drawing functions) and functions like 'put_pixel' is just a way to run functions inside context passed as parameter.
So your program gets ability to pass different kinds of graphic context (at runtime!) to old drawing procedures and draw to screen, printer, PDF, network communication protocol and so on, and so on. If you want to draw on something new - you just create new type of context hidden behind the same 'graphic_context interface' and pass it to old routinues. And they just work! This is 'code for unknown objects' where object is graphic context.
And this program (or this part of it) became OOP!

Let's look at differences yet another time:
- procedural programming knows objects it works with in runtime. However interface of library makes it easy to modify objects before compilation
- OOP code doesn't need to know actual object it works with evern in rutime - the interface is the only question. This is polymorphism and this is primary characteristic of OOP systems. OOP is very strong in collections of different objects we work with. Good example is collection of GUI elements which is iterated and each element gets command 'draw yourself'. And they do it and we do not need to know how. But even single interactions are useful.

So, all other things (support of programming languages and exact implementations of plymorphic behaviour) are important, but make a giant quantity of noise which fogs the essence of things.

calima
Posts: 1307
Joined: Tue Oct 06, 2015 10:16 am

Re: Quintessence of OOP

Post by calima » Mon Dec 14, 2020 2:39 am

Procedural

Code: Select all

fwrite(f, ...);
OOP

Code: Select all

f->write(...);
That be it. :lol:

User avatar
aa-dav
Posts: 154
Joined: Tue Apr 14, 2020 9:45 pm
Location: Russia

Re: Quintessence of OOP

Post by aa-dav » Mon Dec 14, 2020 3:23 am

calima wrote:
Mon Dec 14, 2020 2:39 am
Procedural

Code: Select all

fwrite(f, ...);
OOP

Code: Select all

f->write(...);
That be it. :lol:
And this is real: chaos with understanding and explaining of OOP do really leads to such misinpretations (I belive you make a joke of it).
They say: 'Decompose task to objects and methods and (tada!) OOP appears.'. But objects and actions are such ambiguous abstractions that you can adjust anything to them. So they say 'if you write "struct" - it's procedural, if you write "class" - it's OOP'. Ans so on.
They who are more experienced understand importance of polymorphism, but very often are unable to detach it from incapsulation and inheritance.
This was a great mess then writers of OOP books were mainly C++ and Java users, so we still have such things in wiki: https://en.wikipedia.org/wiki/Object-based_language
Object-based languages need not support inheritance or subtyping, but those that do are also said to be "object-oriented". Object-based languages that do not support inheritance or subtyping are usually not considered to be true object-oriented languages.
...
Examples of a language that is object-based, but not object-oriented are .. JavaScript ... These languages all support the definition of an object as a data structure, but lack polymorphism and inheritance.
But this is total BS - JavaScript can easily implement polymorphic objects and easily can imitate inheritance through very simple trick as it just need no syntaxic sugar in form of 'inherit' keyword.

turboxray
Posts: 147
Joined: Thu Oct 31, 2019 12:56 am

Re: Quintessence of OOP

Post by turboxray » Mon Dec 21, 2020 6:45 pm

aa-dav wrote:
Sat Dec 12, 2020 7:12 pm
But OOP can add and modify UNKNOWN objects
I don't know what language you're programming with, but all objects are known. Whether you reference them through some base class in the chain or the exact derived class - it's known. It has to know what methods are available to call, and which data structures are available to access.

I'm not sure what you're original post is trying to say, but if you're trying to distill the exact essence of OOP, then you're in for an argument. There are many mechanisms in OOP paradigm, but it's going to be an academic argument about what is necessary/primary or what isn't. It doesn't really matter what the 'father' of OOP (before it was even OOP) says; the paradigms have matured quite a bit since then. Rather than getting caught up in if something qualifies OOP, because if you really have to question if it fits the definition, then it's probably not OOP. Just describe it as having OOP like design.

FYI - quite a bit of people program C with principles taken from OOP. You can easily emulate a full object with a struct that has function pointers. Can design for 'interface' type model in C as well And in a more complex systems, I think it's pretty beneficial for its design. As an academic exercise, I wrote an OOP-ish design for a GUI framework completely in C (no custom pre-processor). Right down to the instantiation, inheritance, composition, etc. It was fun, but also messy - you have to pass 'itself' to its own methods inside the very object.. that is itself. That's more of a language syntax thing, because under the hood that's how its down in OOP languages anyway - it's just exposed in C (in my design).

Also, you can easily do OOP in assembly as well. I done it recently for a game engine on the PCE. It has a class, an instantiation macro, etc. It did require a little more thought and work than my C experiment, but it worked.

Anyway, I see OOP in languages like python and C++, the way I see 'function programming' in python and javascript; they're not really functional languages even if they have some aspects of functional design. Though for javascripts credit, I've definitely seen people design their code in a more functional manner. In the eyes of a purely function language, OOP is still a 'procedural' language with some syntactical dressing.

tepples
Posts: 22288
Joined: Sun Sep 19, 2004 11:12 pm
Location: NE Indiana, USA (NTSC)
Contact:

Re: Quintessence of OOP

Post by tepples » Mon Dec 21, 2020 9:15 pm

If a program applies the strategy pattern to process a record based on a property of that record that selects a strategy, it's object-oriented. Something like Super Mario Bros. is object-oriented in this sense.

One can identify object-oriented patterns fairly easily in a lot of assembly programs. Have a spawn_enemy that takes an enemy type as an argument? That's a factory. Have a list of spawn_enemy calls that failed because the main object pool is full? That's a queue of commands. Using a special do-nothing strategy value to denote an unused element of an object pool? That's a null object.

User avatar
aa-dav
Posts: 154
Joined: Tue Apr 14, 2020 9:45 pm
Location: Russia

Re: Quintessence of OOP

Post by aa-dav » Mon Dec 21, 2020 10:03 pm

turboxray wrote:
Mon Dec 21, 2020 6:45 pm
aa-dav wrote:
Sat Dec 12, 2020 7:12 pm
But OOP can add and modify UNKNOWN objects
I don't know what language you're programming with, but all objects are known. Whether you reference them through some base class in the chain or the exact derived class - it's known.
No, object is unknown in essential sense. You know it's class only. Not object itself. You work with fruit, but you don't know is it apple or lime - so true nature of fruit is unknown. In contrast procedure-oriented Complex Numbers Library can accept Complex Number as input, but is unable to work with anything else except strictly described structure of Complex Number.

When C++ was raised in popularity it became leader of OOP paradigm and almost everyone copied it's OOP support system. And it requires inheritance from base class/interface to make polymorphism with stict typing possible. It's good and robust metodology, but tons of books ignored that alternatives are possible.
For example there can be OOP-systems which can send to unknown objects messages they don't support and this will not lead to runtime error. So these systems need not inheritance and base classes as interface protocol at all.
So inheritance is not really important, but current 'mainstream understanding of OOP' is very much 'OOP in C++/Java style'. And this leads to a lot of misunderstandings.
FYI - quite a bit of people program C with principles taken from OOP. You can easily emulate a full object with a struct that has function pointers.
And this is how I decouple OOP-bullshit from OOP-essentianls. :) Just looking in the details of implementation and comparing it with syntax sugar of OOP-languages.
And yes - we must not mix up OOP-languages and OOP-programs/systems. John Carmack also wrote OOP-GUI system in Quake in pure C.
OOP-language gives instruments, but even without them we could implement OOP-program.
And this is why we must reject idea of 'C++-syle OOP is the only true OOP'. Inheritance is detail of specific implementations, incapsulation is just good practice (not specific to OOP at all). So polymorphism is the only true essential core and heart of 'write code which works with objects which are even not written yet'.

User avatar
aa-dav
Posts: 154
Joined: Tue Apr 14, 2020 9:45 pm
Location: Russia

Re: Quintessence of OOP

Post by aa-dav » Wed Dec 23, 2020 12:31 am

tepples wrote:
Mon Dec 21, 2020 9:15 pm
If a program applies the strategy pattern to process a record based on a property of that record that selects a strategy, it's object-oriented.
Typical C++ polymorphism is based on the single (hidden from programmer) field of object - pointer to array of virtual functions pointers (VTBL).
That is C++ do really make choices about code it calls based on single property of record (I'm not going to multiple inheritance stuff here).
But not all choice strategies are equal.
I would call 'true' dynamic polymorphic code such code whose caller can accept new types of objects without rebuilding/recompiling.
That is, for example, DLL of plugin manager which can accept new plugins DLLs without recompilation.
However I think we can ease this requirement in environments like 8-bit console games to 'adding of new object type requires single local and easily controllable change in existing code'. That is - if we have array of function pointers of different objects in the same memory page - we can't do true dynamic polymorphism, but we still could write code which works with "unknown objects" easily.

Post Reply