Sign in to follow this  

Why OOP more popular than functional programming?

This topic is 2657 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Why OOP more popular than functional programming? In OOP are many cpp's/headers, everything is more complicated and harder to understand, in functional programming you only need to create a function, and run it in main.cpp, easier to know scope and debug, no complicated stuff, no inheritances, so is OOP faster? Because every open source project is made with OOP.

Share this post


Link to post
Share on other sites
When you treat programming data like objects, it's a bit closer to the real world, and so it becomes a bit easier to understand, as such, when working on Huge projects, (such as video games), OOP tends to be a easier to organize, not always the case, but usually.

Share this post


Link to post
Share on other sites
It depends on the scope of the project, I like working with objects because I find it easier to work out solutions to problems, like I broke down my current project into a large number of different classes and using inheritance I have created a common interface that is easier to understand for example:

All of my classes which contain something to render have a function called Draw which takes a reference to the render window as an argument (using SFML). They then use the render window to draw themselves to the screen and also update the sprite to make sure it is using the current subrect for animation/direction it is facing.

NPC's are inherited from a pure virtual class which defines the core functions (such as Draw, Update), they also have a specific function for interaction with the player which can be called through update. For example currently if the player stands close enough to a friendly NPC that is walking it will stop until the player has left the vicinity and then continue on it's way. If the player stands close enough to a hostile NPC it will leave it's path to chase after the player and if the player is far away enough it will return to it's path.

Thing's like that I don't see how I could have solved as simply using a plethora of functions which would be hard to understand, where is the ability to expand on something with a procedural program? With OOP if I want to add a new Friendly NPC I can create it with two lines of code (one to initiate a smart pointer, the other to push onto the container of smart pointers which could probably be changed down to one line I guess). With procedural I would have to create at least 18 different uniquely named variables for that NPC, and considering about half of those are classes themselves including a few which I defined myself (Waypoints for following a simple path, ImageManager for handing out pointers to images and also containing all of the various subrects to be obtained from a map)...it sort of leads into a predicament.

If you are working on a small project like pong procedural is a viable choice (albeit a little conceited in my opinion as you are creating more than one of objects, albeit with slightly different behaviour, you can still seperate the behaviour from the class by simply calling the move function from your player's input and the AI code which can be a function that makes sense) you also have to realise that depending on the language you are using, you are making use of objects whether you like it or not. "complicated and harder" isn't really a valid argument for not picking a paradigm which could be more suited for the job.

Share this post


Link to post
Share on other sites
Quote:
Original post by Mafioso
Why OOP more popular than functional programming? In OOP are many cpp's/headers, everything is more complicated and harder to understand, in functional programming you only need to create a function, and run it in main.cpp, easier to know scope and debug, no complicated stuff, no inheritances, so is OOP faster? Because every open source project is made with OOP.


As already mentioned, you mean structured programming - functional programming is something entirely different altogether!

The speed differences between OOP and structured approaches is largely negligible. It's more a matter of convenience than anything else.

A game by its very nature, is largely a data driven system - and a lot of that data can be brittle - i.e. set the wrong value, and parts of the game engine explode in a nasty mess.

Therefore if you have the ability to encapsulate data (via private/protected & getters/setters) you can minimise the possibility of those errors from occurring (how successful that is depends on your unit tests really ;)). It is also much easier to expose a public interface from classes than it with C.....

I imagine most experienced devs, if forced to program in C, would still program with an OOP approach (which is entirely possible via the use of your own language constructs). OOP is a natural fit for game objects, so most people will adopt that route.

OOP though, is more often than not, only used at a higher level within a game engine. The closer you get to the low level code, the more it evolves into C-style approaches. Typically you'll sort the data from the higher level objects into arrays, and then process them efficiently in batches without C++ features such as virtual funcs, etc. That's not to say they won't use classes though (which are always a win), but sorting objects and then processing arrays is normally more efficient.... i.e. The following:


class Foo
{
public:
bool someConditionIsTrue() const;
void doSomeStuff();
void doSomeDifferentStuff();

void func()
{
if(someConditionIsTrue())
{
doSomeStuff();
}
else
{
doSomeDifferentStuff();
}
}
};


Will, more often than not, be converted into a more structured approach like so:


class Foo
{
public:
bool someConditionIsTrue() const;
void doSomeStuff();
void doSomeDifferentStuff();
};

void func(std::vector<Foo*>& inputObjects)
{
std::vector<Foo*> someStuff;
std::vector<Foo*> someDifferentStuff;
for(size_t i=0;i<inputObjects.size();++i)
{
if(inputObjects[i]->someConditionIsTrue())
someStuff.push_back(inputObjects[i]);
else
someDifferentStuff.push_back(inputObjects[i]);
}
for(size_t i=0;i<someStuff.size();++i)
{
someStuff[i]->doSomeStuff();
}
for(size_t i=0;i<someDifferentStuff.size();++i)
{
someDifferentStuff[i]->doSomeDifferentStuff();
}
}


You'll note that classes are still used, however the pre-sorting of data in that way usually makes it much easier to process the code efficiently on multi-core systems. So it's rare to find an engine that adopts an entirely OOP approach or structured approach. It's usually a mix of the two (and potentially functional/generic approaches too). There is no right or wrong way, just use whichever approach fits the problem best....

Share this post


Link to post
Share on other sites
I think ExcessNeo has a hard time imagining how a procedural program would be written because he has little experience with them. Procedural programming also uses user-defined data types (struct in C) and is not all that hard to keep clean and understandable.

Quote:
Thing's like that I don't see how I could have solved as simply using a plethora of functions which would be hard to understand

If you had never used objects, you wouldn't see how you could have solved it simply using a plethora of classes which would be hard to understand. You can write clean, elegant solutions in both paradigms, and you can write crap in both.

I don't personally like OOP. Objects are useful, and so are function calls and loops, but I don't orient my programming to a single tool. I mostly program in C++, and I use objects when I am modeling something that fits naturally in that shape (I can give it a good name and the interface makes sense). This is probably around 75% of my code. But my objects don't belong to complicated inheritance hierarchies: I use inheritance about as often as I would use function pointers in C (e.g., when I need polymorphic behavior).

The OP should probably gain some familiarity with objects, at least to be able to understand other people's code. Then he'll probably find himself using objects very frequently.

Share this post


Link to post
Share on other sites
Quote:
Original post by ExcessNeo
NPC's are inherited from a pure virtual class which defines the core functions (such as Draw, Update), they also have a specific function for interaction with the player which can be called through update. For example currently if the player stands close enough to a friendly NPC that is walking it will stop until the player has left the vicinity and then continue on it's way. If the player stands close enough to a hostile NPC it will leave it's path to chase after the player and if the player is far away enough it will return to it's path.

Thing's like that I don't see how I could have solved as simply using a plethora of functions which would be hard to understand, where is the ability to expand on something with a procedural program?


Trivial to do in C with OOP like so:

NPC.h

typedef void (*NPC_update_func)(NPC* _this, float dt);
typedef void (*NPC_interact_func)(NPC* _this, NPC* _otherNPC);
typedef void (*NPC_draw_func)(NPC* _this);

typedef struct
{
NPC_update_func update;
NPC_interact_func interact;
NPC_draw_func draw;
}
NPC_func_table;

typedef struct
{
NPC_func_table vtable;
Vector3 position;
Vector3 velocity;
Quat rotation;
int typeId; // 1 = villager, 2 = stormtrooper etc
} NPC;

#define drawNPC(npc) { assert(npc); assert((npc)->vtable.draw); (npc)->vtable.draw(npc); }

#define updateNPC(npc, dt) { assert(npc); assert((npc)->vtable.draw); (npc)->vtable.update((npc), dt); }

#define interactNPC(npc, other) { assert(npc); assert(other); assert((npc)->vtable.interact); (npc)->vtable.interact((npc), (other)); }

extern NPC* createVillager();
extern NPC* createStormTrooper();

// to prove it works for inheritance....
extern NPC* createVillageMayor();





villager extends NPC

typedef struct
{
NPC npc;

// villager specific params

} NPC_villager;

void Villager_update_func(NPC* _this, float dt)
{
NPC_villager* villager = (NPC_villager*)_this;

// update the villager
}
void Villager_interact_func(NPC* _this, NPC* _otherNPC)
{
NPC_villager* villager = (NPC_villager*)_this;

// handle interaction
}
void Villager_draw_func(NPC* _this)
{
NPC_villager* villager = (NPC_villager*)_this;

// draw the villager
}

NPC* createVillager()
{
NPC_villager* ptr = (NPC_villager*)malloc(sizeof(NPC_villager));
ptr->npc.vtable.update = Villager_update_func;
ptr->npc.vtable.interact = Villager_interact_func;
ptr->npc.vtable.draw = Villager_draw_func;

// init the other params...

return &ptr->npc;
}




stormtrooper extends NPC

typedef struct
{
NPC npc;

// stormtrooper specific params

} NPC_stormtrooper;


void Stormtrooper_update_func(NPC* _this, float dt)
{
NPC_stormtrooper* villager = (NPC_stormtrooper*)_this;

// update the stormtrooper
}
void Stormtrooper_interact_func(NPC* _this, NPC* _otherNPC)
{
NPC_stormtrooper* stormtrooper = (NPC_stormtrooper*)_this;

// handle interaction
}
void Stormtrooper_draw_func(NPC* _this)
{
NPC_stormtrooper* stormtrooper = (NPC_stormtrooper*)_this;

// draw the stormtrooper
}

NPC* createStormTrooper()
{
NPC_stormtrooper* ptr = (NPC_stormtrooper*)malloc(sizeof(NPC_stormtrooper));
ptr->npc.vtable.update = Stormtrooper_update_func;
ptr->npc.vtable.interact = Stormtrooper_interact_func;
ptr->npc.vtable.draw = Stormtrooper_draw_func;

// init the other params...

return &ptr->npc;
}




Village Mayor, extends villager

typedef struct
{
NPC_villager villager;

// villager specific params

} NPC_villageMayor;

void VillageMayor_update_func(NPC* _this, float dt)
{
// call update on base class....
Villager_update_func(_this, dt);

NPC_villageMayor* villager = (NPC_villageMayor*)_this;

// do Mayor specific stuff...
}
void VillageMayor_interact_func(NPC* _this, NPC* _otherNPC)
{
// call interact on base class....
Villager_interact_func(_this, _otherNPC);

NPC_villageMayor* villageMayor = (NPC_villageMayor*)_this;

// handle interaction
}
void VillageMayor_draw_func(NPC* _this)
{
// call draw on base class....
Villager_draw_func(_this);

NPC_villageMayor* villager = (NPC_villageMayor*)_this;

// draw the village mayor
}

NPC* createVillageMayor()
{
NPC_villageMayor* ptr = (NPC_villageMayor*)malloc(sizeof(NPC_villageMayor));
ptr->villager.npc.vtable.update = VillageMayor_update_func;
ptr->villager.npc.vtable.interact = VillageMayor_interact_func;
ptr->villager.npc.vtable.draw = VillageMayor_draw_func;

// init the other params...

return &ptr->villager.npc;
}




It's fair to say that you can implement almost all OOP language features in strict C. Whether or not it is a good idea to do so, is another matter entirely......

Share this post


Link to post
Share on other sites
Quote:
Original post by alvaro
I don't personally like OOP. Objects are useful, and so are function calls and loops, but I don't orient my programming to a single tool. I mostly program in C++, and I use objects when I am modeling something that fits naturally in that shape (I can give it a good name and the interface makes sense). This is probably around 75% of my code. But my objects don't belong to complicated inheritance hierarchies: I use inheritance about as often as I would use function pointers in C (e.g., when I need polymorphic behavior).


+1

Share this post


Link to post
Share on other sites
Quote:
Original post by RobTheBloke
Quote:
Original post by alvaro
I don't personally like OOP. Objects are useful, and so are function calls and loops, but I don't orient my programming to a single tool. I mostly program in C++, and I use objects when I am modeling something that fits naturally in that shape (I can give it a good name and the interface makes sense). This is probably around 75% of my code. But my objects don't belong to complicated inheritance hierarchies: I use inheritance about as often as I would use function pointers in C (e.g., when I need polymorphic behavior).


+1


+2

Share this post


Link to post
Share on other sites
+3

i normally never has a hirarchy deeper than one layer, if i ever have one.

and why stick to c if c++ allows you to code faster? (why in c++ if you could do in c# would be my punchline, others would use "in python" or what ever :))

Share this post


Link to post
Share on other sites
Quote:
Original post by phresnel
Uh oh.


Indead. Looks like a repost of Mafioso's old thread: 'Is OOP better for developing games?'.

So Mafioso, after reviewing that old thread, what exactly is the stumbling point that you aren't quite capturing? Could you post a concrete example of what wasn't explained well in that thread?

Share this post


Link to post
Share on other sites
I like OO simply because it makes variables easier to manage on large projects. That, and because you can modify class functions easier to accommodate unforeseen data requirements.

I certainly agree, however, that not everything function to be made a method.

Note: This is in reference to PHP programming. I'm not familiar with C#/C++.

Share this post


Link to post
Share on other sites
Quote:
Original post by KulSeran
Quote:
Original post by phresnel
Uh oh.


Indead. Looks like a repost of Mafioso's old thread: 'Is OOP better for developing games?'.

So Mafioso, after reviewing that old thread, what exactly is the stumbling point that you aren't quite capturing? Could you post a concrete example of what wasn't explained well in that thread?


I readed that thread, but still can't understand why people making everything complicated with OOP, for me OOP is only many functions with a prefix and code splitted in many cpp's/headers it just makes x100 harder for me, every open project game that I downloaded (about 5) was made in OOP, seems functions doesn't exist at all, I'm not very good at english, maybe I'll try to reread and go into this deeper and sorry for reposting, I spend all day reading that thread [smile] and didn't get why every game is made with OOP, someone said that somewhere need functions somewhere OOP, but why every game is made with OOP? finally decided to learn what is more popular among programmers and I get to this question [smile] , one reason to learn OOP is for this pointer (I don't think it's worth)

Share this post


Link to post
Share on other sites
Quote:
didn't get why every game is made with OOP


Large majority of developers in commodity software industry is <25 years old. Since their tenure will last around 3 years before they burn out from 16+ hour work days, there is no point in training them.

So companies use whatever methodology new hires come with. These days it's Java and design patterns.

It's also a known observation that very few programmers are capable of growing beyond the one and only paradigm they learned, so majority will never be capable of learning anything beyond OOP. Nobody ever investigated why this is so, but last 20 years of observation of industry confirms it.

This year alone over 1 million people will graduate and be certified in OOP. There will be almost no graduates who even heard about functional programming.

In short - race to bottom in commoditized markets. The rest is not a factor.

Share this post


Link to post
Share on other sites
Quote:
Original post by Antheus
Quote:
didn't get why every game is made with OOP


Large majority of developers in commodity software industry is <25 years old. Since their tenure will last around 3 years before they burn out from 16+ hour work days, there is no point in training them.

So companies use whatever methodology new hires come with. These days it's Java and design patterns.

It's also a known observation that very few programmers are capable of growing beyond the one and only paradigm they learned, so majority will never be capable of learning anything beyond OOP. Nobody ever investigated why this is so, but last 20 years of observation of industry confirms it.

This year alone over 1 million people will graduate and be certified in OOP. There will be almost no graduates who even heard about functional programming.

In short - race to bottom in commoditized markets. The rest is not a factor.


+ for you man, I readed and asked and readed again, but in conclusion everything what you know is good, and there is nothing better or worst, every paradigm has this own pliuses and minuses, just need to know them all, if you want to know what is the best for your project.

P.S. Going to reread my old thread about OOP and note pliuses and minuses of paradigms and study them, Thanks for all your reply they helped me a lot [smile] And don't think that OOP is always the best way doing things [lol]

Share this post


Link to post
Share on other sites
I think the long and the short of it is that OOP works just fine for making games, and is well established. Are other paradigms better in certain situations? Sure. Are they universally better? No. Are they better enough in the relevant problem domains that it's worth the trouble of worrying about when OOP resources are plentiful and reliable? The popular answer to that seems, again, to be no (and I would agree).

Share this post


Link to post
Share on other sites
Quote:
Original post by Shinkage
Are they better enough in the relevant problem domains that it's worth the trouble of worrying about when OOP resources are plentiful and reliable? The popular answer to that seems, again, to be no (and I would agree).


The fact its a popular answer is a bad thing; in the case of games the performance gains you can get from going from an text book OOP to something more functional (not pure functional as you'll have side effects of course) are generally more than worth the effort.

Unfortunately very few places invest in new things, fortunately some do and, in the case of games, no ways of thinking about things makes their products shine.

The best example; the move away from OOP back towards something just above assembly for SPU programming has suddenly unleashed a world of power which has been sitting there waiting to be unlocked for some time now.

Share this post


Link to post
Share on other sites
Quote:
Original post by Shinkage
Are other paradigms better in certain situations? Sure. Are they universally better? No.


Are you saying that OOP is universal?

Share this post


Link to post
Share on other sites
Quote:
Original post by Antheus
Large majority of developers in commodity software industry is <25 years old. Since their tenure will last around 3 years before they burn out from 16+ hour work days, there is no point in training them.

So companies use whatever methodology new hires come with. These days it's Java and design patterns.

It's terrible. I remember when I was a teaching assistant at UBC and they switched the main data structures and design 2nd year course from C++ to Java. I ran a tutorial section of the course the last year they did C++, and I attempted to tell people not everything needs to be done with classes and objects, and tried to promote other approaches like generic programming, not as replacements, but as additional tools in the box. When I found out next year they switched to Java, I felt disgusted.

Quote:
It's also a known observation that very few programmers are capable of growing beyond the one and only paradigm they learned, so majority will never be capable of learning anything beyond OOP. Nobody ever investigated why this is so, but last 20 years of observation of industry confirms it.

The problem is insufficient exposure to other approaches in academia. While I fancy neither Lisp nor Prolog, I'm sure glad I had to write code in them in a mathematics and AI courses, correspondingly. I think it was also beneficial that I learned C first and then C++.
To those that see OOP as the hammer for every nail, I suggest you take a look at Elements of Programming and C++Next, as well as experiment with functional languages.

Share this post


Link to post
Share on other sites
Quote:
Original post by Prune
It's terrible. I remember when I was a teaching assistant at UBC and they switched the main data structures and design 2nd year course from C++ to Java. I ran a tutorial section of the course the last year they did C++, and I attempted to tell people not everything needs to be done with classes and objects, and tried to promote other approaches like generic programming, not as replacements, but as additional tools in the box. When I found out next year they switched to Java, I felt disgusted.


(Slightly offtopic)

They've switched back, evidently. I took that course (CPSC221 I think was the course code) just last year and it was in C++. C++ classes weren't even covered. In fact, for the most part our code was very C-like, only with C++'s standard library. I don't remember anyone having any particular difficulty with the lack of objects. Then again, IMO UBC doesn't push OOP very hard in first and second years. Out of the three 2nd year courses that had programming involved, one was in Java, one was in C, and one was in C++. Now that I think about it, I've heard that there's a compiler construction course that uses Scheme. I'm also fairly certain that first-years are now learning Scheme instead of Java, so there's a bit of Lisp experience right there.

Share this post


Link to post
Share on other sites
I think some here are confusing OOP with the "everything must be an object" approach. OOP is object oriented programming. If every single line of code and bit of data in your project is an object, you are likely overdoing things, from a practical and performance perspective, if not a theoretical "elegance" one.

Also, one of the largest benefits of OOP isn't the objects themselves, but simply because it forces a programmer to spend more time "up front" designing the project, rather than jumping right in with writing code. Sitting down and trying to organize every entity into a class structure is usually invaluable ... even if you wind up not using much or even all of those classes.

Share this post


Link to post
Share on other sites
Quote:
Original post by Mafioso
Why OOP more popular than functional procedural programming? In OOP are many cpp's/headers, everything is more complicated and harder to understand, in functional procedural programming you only need to create a function, and run it in main.cpp,
easier to know scope and debug,

I'd argue "OOP" is easier to debug.

With "OOP", private variables can only be accessed by member functions, so it's easier to reason about what could be changing them. In C, where everything is public, any function in your entire program could theoretically be changing the variables in question*, even without memory corruption.

With "OOP", you can create and hold invariants: If you have a std::vector<int> v;, you can assume it has v.size() elements, because std::vector is meant to guarantee this, and to break that guarantee you need to either corrupt memory or intentionally be looking to break it. In C, you might have a structure*: struct int_vector { int* data; size_t size; };, or two seperate variables/parameters -- however, it's very easy to accidentally have a size that doesn't match the number of elements data actually points to, even without memory corruption. This in turn leads to memory corruption via buffer overflows and underflows, resulting in crashes and some of the more severe security holes allowing arbitrary code injection.


* Through various hacks that I won't go into, we can actually emulate C++'s OOP features in C to get many of the same benifits, but at that point you're not just creating functions willy nilly -- you're doing OOP in C.

This isn't to say OOP is a panacea and appropriate for all needs -- but that's why C++ doesn't force you to. Sometimes, a simple function is best.

Share this post


Link to post
Share on other sites

This topic is 2657 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this