Procedural vs. OOP vs. the world
February 20, 2005 1:27 AM Subscribe
Does anyone know of a book (site, magazine, DVD, anything) that, preferrably communicated in a non-specific programming language (e.g. - pseudocode, if possible), illustrates real world pros and cons of procedural vs. OOP coding and vice versa?
I don't want a religous war on why one is better than the other; but rather a (fairly) objective look at both with the who/what/where/when/why/how of any specific reasons for more efficient use of either.
Just to expand upon what Rusty says, he's right, the primary benefits of OOP are in the nature of objects themselves. Inheritance, multiple inheritance, abstraction, interfaces, and all the code reuse, organization, and (arguably) most importantly, encapsulation--the technical term for 'control of access'.
Obviously that can all be somewhat accomplished without using object-oriented syntax, but it makes things much, much easier when you have those specific goals in mind. I find, with my admittedly limited real-world experience, that it's best to mix the two--have the bulk of the code in objects and the actual program flow in procedural terms.
posted by cyrusdogstar at 11:58 AM on February 20, 2005
Obviously that can all be somewhat accomplished without using object-oriented syntax, but it makes things much, much easier when you have those specific goals in mind. I find, with my admittedly limited real-world experience, that it's best to mix the two--have the bulk of the code in objects and the actual program flow in procedural terms.
posted by cyrusdogstar at 11:58 AM on February 20, 2005
I read a pretty interesting book called 'The Object-Oriented Thought Process' by Matt Weisfeld. It's biased in favor of OOP, but does explain the reasoning behind OOP and some of the ways the two schools of thought differ very clearly (to me, a programming novice who just knows some VBA).
posted by bingo at 2:01 PM on February 20, 2005
posted by bingo at 2:01 PM on February 20, 2005
part of the reason you're not getting clear answers is, i think, because the question is rather vague. many different factors "make up" programming languages and "being object oriented" isn't necessarily the most important. for example, both c++ and smalltalk are "oo languages", while c is procedural, yet you could make the case that c and c++ are much more similar than c++ and smalltalk. and if you try to make "oo" more precise the wide variation in "oo languages" means that it's difficult to come up with much more than "inheritance" which, as others have pointed out, isn't really that important in practice.
so what can you do instead if you still want an answer?
i guess you can just face up to the idea that "oo" isn't that big a deal, and instead look at more specific ideas like abstract data types, strong and weak typing, encapsulation, etc.
alternatively, you could try looking at languages that are "multi-paradigm" - that support oo, procedural and/or functional programming - and see how people use them in practice. by looking at when people use the "oo parts" of those languages you can see when they might be useful.
off the top of my head i can think of three languages that might be appropriate. the first two are common lisp and ocaml. the main difference (apart from lisp's syntax, which is a red herring here) between those two languages is that ocaml is statically typed. in fact, they make a good illustration of what i was saying above - they feel very different to use, even though both support oo, functional and procedural programming.
so you might go to the lisp and ocaml communities (which would probably by the comp.lang.lisp usenet group and the ocaml mailing list) and ask when they use the oo parts of their languages, and why. more properly, you should look for faqs first, since presumably these are common questions. the ocaml manual has a description of when the oo parts of that language are useful, but i won't bother linking to it because (1) i'm lazy (2) it's rather technical and (3) i didn't fully understand it myself. for what it's worth, i have a fair amount of oo programming experience and use ocaml, but have never found it necessary to use oo constructs in ocaml.
i mentioned three languages. the third is oz, which can be found here. that language was explicitly designed like an onion, so that you start with a very simple core and "add" features (like variables that can change value) as you need them. the idea is that you use the simplest language necessary to solve the problem at hand.
the oz approach is described in an excellent book and if you read it i think you'd find that your question had been answered. it takes the oz language and shows how the different features make it progressively more powerful (and dangerous) - "objects" being one of those features.
unfortunately, i'm not capable of giving a good, quick summary of what the book says - partly because i've not read it all (it's large!) but mainly because you really need to work through the earlier parts of the book to undestand just how powerful very basic language features can be before you can see clearly what "adding objects" gives you.
posted by andrew cooke at 8:31 PM on February 20, 2005
so what can you do instead if you still want an answer?
i guess you can just face up to the idea that "oo" isn't that big a deal, and instead look at more specific ideas like abstract data types, strong and weak typing, encapsulation, etc.
alternatively, you could try looking at languages that are "multi-paradigm" - that support oo, procedural and/or functional programming - and see how people use them in practice. by looking at when people use the "oo parts" of those languages you can see when they might be useful.
off the top of my head i can think of three languages that might be appropriate. the first two are common lisp and ocaml. the main difference (apart from lisp's syntax, which is a red herring here) between those two languages is that ocaml is statically typed. in fact, they make a good illustration of what i was saying above - they feel very different to use, even though both support oo, functional and procedural programming.
so you might go to the lisp and ocaml communities (which would probably by the comp.lang.lisp usenet group and the ocaml mailing list) and ask when they use the oo parts of their languages, and why. more properly, you should look for faqs first, since presumably these are common questions. the ocaml manual has a description of when the oo parts of that language are useful, but i won't bother linking to it because (1) i'm lazy (2) it's rather technical and (3) i didn't fully understand it myself. for what it's worth, i have a fair amount of oo programming experience and use ocaml, but have never found it necessary to use oo constructs in ocaml.
i mentioned three languages. the third is oz, which can be found here. that language was explicitly designed like an onion, so that you start with a very simple core and "add" features (like variables that can change value) as you need them. the idea is that you use the simplest language necessary to solve the problem at hand.
the oz approach is described in an excellent book and if you read it i think you'd find that your question had been answered. it takes the oz language and shows how the different features make it progressively more powerful (and dangerous) - "objects" being one of those features.
unfortunately, i'm not capable of giving a good, quick summary of what the book says - partly because i've not read it all (it's large!) but mainly because you really need to work through the earlier parts of the book to undestand just how powerful very basic language features can be before you can see clearly what "adding objects" gives you.
posted by andrew cooke at 8:31 PM on February 20, 2005
I can break it down very simply. When you are working in procedural languages, you end up with the style "a struct for everything and everything in its struct". For example, I had written a UI framework which initially started with something like this:
typedef struct t_Window {
t_PlatFormWindow *theWin;
t_WidgetList *itsWidgets;
} t_Window;
Then I'd inevitable write a set of routines like this:
static void WidgetPaintCallback(t_Widget *widget, void *ref)
{
t_Window *win = (t_Window *)ref;
WidgetPaint(win, widget);
}
void PaintWindow(t_Window *win)
{
PlatformPaint(win->theWin);
WidgetForEach(win->itsWidgets, (void *)win);
}
This let me easily loop through a set of widgets in a window and paint each of them. Inevitably, I wanted cutom widgets that could manage their own painting in a special way. To manage this, I defined a widget struct to include a function pointer which when invoked would paint the custom widget. I also included function pointers to handle all the UI functions. With this model, I could define new widgets easily and I could do things like make two widgets that shared almost all the same code by sharing the function pointers. I could also augment the behavior of an existing widget by keeping a copy of, say, it's paint routine around and calling it first, then adding some other things on top of it.
This was all done in plain C and I got an entire UI library in a startingly small amount of code. The only problem was that it was hell to debug.
When I looked at C++ I found that it had just made the techniques I was using on a day-to-day basis easier to implement and far easier to debug and safer in terms of datatypes (actually this isn't strictly true--I had ways of building type information into my structs and could for a debug break if types didn't match). Function pointers were now implemented through virtual member functions in a class. Sharing of code was done through inheritance and by protecting data members with accessor functions, I could easily trap when a particular object was being changed to a particular value (which is one of the hardest things to do without that language feature). What I lost was the ability to change behaviors on the fly easily. I had code that could swap function pointers in and out of structs to temporarily change behaviors, which is a lot harder to do in C++ (but there's usually a better way to solve those particular problems in a OO way).
posted by plinth at 7:11 AM on February 21, 2005
typedef struct t_Window {
t_PlatFormWindow *theWin;
t_WidgetList *itsWidgets;
} t_Window;
Then I'd inevitable write a set of routines like this:
static void WidgetPaintCallback(t_Widget *widget, void *ref)
{
t_Window *win = (t_Window *)ref;
WidgetPaint(win, widget);
}
void PaintWindow(t_Window *win)
{
PlatformPaint(win->theWin);
WidgetForEach(win->itsWidgets, (void *)win);
}
This let me easily loop through a set of widgets in a window and paint each of them. Inevitably, I wanted cutom widgets that could manage their own painting in a special way. To manage this, I defined a widget struct to include a function pointer which when invoked would paint the custom widget. I also included function pointers to handle all the UI functions. With this model, I could define new widgets easily and I could do things like make two widgets that shared almost all the same code by sharing the function pointers. I could also augment the behavior of an existing widget by keeping a copy of, say, it's paint routine around and calling it first, then adding some other things on top of it.
This was all done in plain C and I got an entire UI library in a startingly small amount of code. The only problem was that it was hell to debug.
When I looked at C++ I found that it had just made the techniques I was using on a day-to-day basis easier to implement and far easier to debug and safer in terms of datatypes (actually this isn't strictly true--I had ways of building type information into my structs and could for a debug break if types didn't match). Function pointers were now implemented through virtual member functions in a class. Sharing of code was done through inheritance and by protecting data members with accessor functions, I could easily trap when a particular object was being changed to a particular value (which is one of the hardest things to do without that language feature). What I lost was the ability to change behaviors on the fly easily. I had code that could swap function pointers in and out of structs to temporarily change behaviors, which is a lot harder to do in C++ (but there's usually a better way to solve those particular problems in a OO way).
posted by plinth at 7:11 AM on February 21, 2005
what plinth's describing, as far as i can see, is an abstract data type - some "thing", with associated operations. you can implement abstract data types in different ways in different languages. in ml languages you would use modules, for example. in oo languages you use objects. but basically you are arguing for decent adt support rather than oo features. and c++ wins out compared to c not because it has "objects" but because it has better support for this kind of abstraction.
this is why you really need to look at a language where objects are just one way of doing things, rather than "the" solution you are forced to use for everything. in the end, plinth's argument comes down to "c++ is more powerful than c". which you knew already.
posted by andrew cooke at 7:21 AM on February 21, 2005
this is why you really need to look at a language where objects are just one way of doing things, rather than "the" solution you are forced to use for everything. in the end, plinth's argument comes down to "c++ is more powerful than c". which you knew already.
posted by andrew cooke at 7:21 AM on February 21, 2005
Just to be clear (and this is not a religious argument), I never said nor would I say that C++ is more powerful than C, because that's simply not true.
posted by plinth at 11:18 AM on February 21, 2005
posted by plinth at 11:18 AM on February 21, 2005
maybe i chose my words badly. obviously, both are turing complete. would "more expressive" be better?
posted by andrew cooke at 11:45 AM on February 21, 2005
posted by andrew cooke at 11:45 AM on February 21, 2005
Response by poster: Hmmm... after reading the answers given I'm guessing that my original thoughts on OOP are correct: OOP is unnecessary.
In my estimation, OOP is just another way to get things done, but so many of the developers I know swear by it, while I have really never found any "need" for it versus developing procedurally. I did, however, borrow the book "The Object-Oriented Thought Process" from a fellow co-worker/MeFite, just because he had it handy.
Thanks for all your responses! :)
posted by crankydoodle at 4:39 PM on February 23, 2005
In my estimation, OOP is just another way to get things done, but so many of the developers I know swear by it, while I have really never found any "need" for it versus developing procedurally. I did, however, borrow the book "The Object-Oriented Thought Process" from a fellow co-worker/MeFite, just because he had it handy.
Thanks for all your responses! :)
posted by crankydoodle at 4:39 PM on February 23, 2005
This thread is closed to new comments.
In the end I don't think it really matters much. Given that you can express most functions as either...
myobject.myfunction()
or
myfunction(myobject)
...the main difference between OOP and procedural programming is inheritance, and, to some extent, that control of access to data is built in to most OOP languages. To me these things don't matter too much, inheritance has always struck me as sort of a forced concept.
But, also, I typically work alone or in tightly knit teams. Some folks have expressed to me that object oriented programming lends itself to massive team efforts better.
posted by RustyBrooks at 10:23 AM on February 20, 2005