Fog Creek Software
Discussion Board




OO benefits - a counterexample.

In light of a recent discussion of OO benefits on this board, I would like to give a counterexample:

There's a good  introduction by Thomas Niemann to Operator Precedence Parsing; This is a technique to parse arithmetic constructs with precedence rules, e.g., to properly parse  x^2+y^2 as  (x^2)+(y^2) rather than, say,  (x^(2+y))^2.

The introduction includes code in C, C++, VB and K. The C++ is "standard" in how it uses OO. Yet, it is significantly longer than the C code (almost twice as long), and gives no advantage as far as I can tell. Personally, I find the C code easier to read, and I suspect that it also runs faster (but I won't be placing any bets on that).

This is more or less my real world experience - that, with few exceptions (GUIs being the most notable), procedural code with a hint of OO is shorter, easier to read, easier to maintain and simpler than code based on "industrry standard" OO practices.

Do you guys and gals have real world examples that demonstrate OO benefits outside of GUI? By demonstrate, I do not mean "yep, this system is OO and it works and it was easy to write", which is anecdotal at best and from which nothing can be generalized. Rather, I mean two systems, using essentially the same inner workings as far as bit moving is concerned (i.e., same algorithms, comparable data structures etc.), written around the same time, one using a procedural language (e.g. C) and the other using an OO-heavy implementation in an OO language (e.g. C++)  -- and in which the OO system is arguably better in some sense?

And please try to compare oranges to oranges; Comparing C to Python is NOT ok; Comparing OO python to procedural python, is good.

Ori Berger
Friday, June 06, 2003

Forgot the link:

[ http://epaperpress.com/oper/ ]

Silly me.

Ori Berger
Friday, June 06, 2003

As I've mentioned in the past, I have a document processing engine running that parses xml invoices into sql server and display those invoices as a pdf. It also has webforms to allow the user to generate an invoice, which puts it in sql server and submits an xml document to a VAN.

I did the webforms first, and they're almost completely procedural. As I did the xml parsing I went with an OO approach (mostly because I wrote an xml schema -> C# Class generator). So I've got fairly similar implementations in procedural and oo code.

Observations:
1) The OO code is much, much easier to maintain. I can implement changes and find bugs in about 1/4 the time I can in teh procedural code. In addition, I *introduce* new bugs in the OO code about 1/4 as much as in the procedural code, due to the increased isolation of functions.

2) I have to change stuff 2-3 times for each change, since I've duplicated code. If the entire back end was OO, then changes to the invoice would be made in one place.

Bottom line: when we move to 2.0 I'll be moving to a 100% OO implementation.

Philo

Philo
Friday, June 06, 2003

Hi Ori,

thats a lot of things Im not allowed to say about OO programming :)

"Yet, it is significantly longer than the C code (almost twice as long),"

Ive just had a pleasant read, the c++ code is certainly longer than the c version.
<g> personally I think maybe the author got carried away with creating objects, but I think I can muster a defence of c++ based on the code you have provided.


To me a big part of the art of programming is about focus, in the same way that military people talk about bringing overwhelming power to bear on a particularly point, I think about bringing overwhelming understanding tobear on the code you are looking at.
A counter example example of this is the slightly sick feeling I get when I am staring blankly at a function 3 pages long written by some imbecile (possibly myself) 2 years ago.
....thats a case of me bringing an overwhelming _lack_ of understanding to the code...

To deal with this programmers have developed various guidelines...in both c and c++ for instance its generally considered good practice to keep the length of functions pretty short wherever possibly.

But to me thats also the greatest strength of c++ over c, c++ makes this a lot easier by providing me with a design framework that lets me look at the specific code I am interested in, exactly where I would logically expect to find it.

Thats it :)  thats my defence.

I am not arguing that this same thing cannot be achieved with c, it can. 
I _am_ arguing that I find that c++ makes arranging code in this fashion a lot easier, _because it is specifically designed to do so_.


I believe that the particular example code you have given us simply proves something I have always known,  that c++ doesn't actually come into its own until you are building bigger projects.
As you have noticed the added overhead in lines of code (which is basically made up entirely of class declarations & definitions) means that for smaller projects you do end up with more code for less apparent payoff.
My belief is that c++ pays off in the larger more complex projects because you are more easily able to locate and understand the code, bringing your understanding to bear where it is most needed.

FullNameRequired
Friday, June 06, 2003

As the last post mentions, OO adds value when your code gets sufficiently large. I'd put the threshold at around 1000 lines of code. And the advantages become pronounced when you reach 10,000 lines.

You C example includes only 7 functions, which you can easily keep track of. If you had 100 functions, however, it would be a lot easier to create and maintain 10 classes with 10 methods apiece. It wouldn't be difficult to remember what each class did, and when working on a particular class just have to deal with its methods. Encapsulation is your friend on large projects.

It would take a while to create a sufficiently large multiple-language example, analogous to yours, that demonstrates the benefits of OO.

Julian
Friday, June 06, 2003

Have you considered that the C++ version actually does more.

For example:
- the stack in C is 50 fixed limit, in C++ it's variable. 
- I only took a quick look, but I didn't spot some C++ bits in the C, for example in C++ version there is a function that outputs all the operators.
- I'm not so sure about the number of different classes the C++ version has being a good idea especially if that's all there is, rather than aiming to be a basic framework for a larger program. In other words I think that's why the programmer structured the C++ the way he did ((for expandability at the cost of increased code now).  I don't see this goal being that blatantly obvious in the same way in the C version.

Personally I didn't find either the C or C++ examples particularly readable or great code. I'd give them a B-.

One last point C++ programs in general do not need to use classes, and definitely not for every single darn thing - that would simply be OO fanaticism, not well considered programming!  Anyway it'd be interesting to compare the C code, to a C++ version of the same thing (i.e. using C++ as a better C), which took advantage of library classes (string, vector, etc) without going crazy on the program specific classes.  I think a  well written C++ example would win that comparison (on readability and robustness - no potential string overflows or stack overflows) by a country mile.

S. Tanna
Friday, June 06, 2003

Julian, you're talking about modular structure of the code. But there's nothing in procedural languages that prevents you from doing the same thing: just split your code by modules, organize the module interfaces, descibing data structures and related functions. OO languages don't have any advantage here.

C just doesn't have any support fo modularization, but take Perl or Python for example -- you can write in pure procedural style, but make your code highly modular. I personally maintained 100kloc system in Perl and it was not bad at all.

Frosya
Friday, June 06, 2003

OO is about behaviour. You aren't actually doing anything
in the code but parse. Now doing something with
what you've parsed. You might find the advanatages
more then.  OO is magik dust that makes everything
better. For just parsing the C code is clearer. The C++
code will when when you start doing things.

valraven
Saturday, June 07, 2003

OO is about behaviour. You aren't actually doing anything
in the code but parse. Now do something with
what you've parsed. You might find the advanatages
more then.  OO is not magik dust that makes everything
better. For just parsing the C code is clearer. The C++
code will win when you start doing things.

valraven
Saturday, June 07, 2003

Right tool for the right job. OO has plenty of damned good uses. GUIs, as mentioned earlier, and others.

One that pops into my head now is Java's I/O stream system: you can plug together a bunch of (relatively) unrelated objects, and very easily get output over a file or network or whatever taht is compressed/encrypted/checksummed/whatever. I think it'd be hard to set up something as seamless in C.

OTOH, mplayer, an open source media player, just rewrote one of its codecs in pure C (instead of OOed C++), and said they experienced a great speed up.

Have good tools, know how to use them, and know *when* to use them. After all, programming is the art of finding the right wrench with which to pound in the right screw ;) Don't try to retrofit things where they don't belong: not everything is a procedure, and not everything is an object.

Mike Swieton
Saturday, June 07, 2003

I have seen the opposite case - where C++ would be/is much shorter than C.

(example is a library for Voice over IP protocols (they are very similar to HTTP).

They have a library that is very much object based - instead of classes you have structures.

(you have to do that, because the library is large and every piece of data is really an independent entity - and each struct can be accessed independently)

Instead constructors you have Create something.

- instead of virtual functions you have a structure with typedefs to function pointers.

You can't say that this is shorter then code written in C++.
They just have to stick to C because of portability.

Michael Moser
Saturday, June 07, 2003

Boy, those operators just scream to be turned into generics, don't they?

Danil
Saturday, June 07, 2003

I'm not sure if it proves the superiority of OO versus procedural but testing both C and C++ versions with the first expression that came to mind: 45+98*(4+6), the C version answered 45 while the C++ one answered 1025 which is obviously the correct answer :)

Laurent
Sunday, June 08, 2003

Its been my experience that, when organizations set out to design OO frameworks and are actually serious about it, they'll hire the architecture astronauts of the world.  These people will then create the most abstract, super-generalized framework known to man (even with its own "Object" base class), with n-levels deep of composition and inheritance, and force it down the throats of developers.  They'll then implement it according to the proscribed orthodoxy, and that's life.

The result is often a system that is both very extensible, and very hard to understand.  I recall a saying to the effect of, "OO is a neat way to create spaghetti code."  It really is--when every object in a system is generated by some factory or dispatch interface or another, it becomes very hard to figure out in a reasonable amount of time what a given piece of code actually does.

I know this sounds very 1980-ish, but I really like to be able to understand a program's flow within a reasonable amount of time.  Dijikstra didn't rag on "goto" because he hated the specific words "go" and "to" in combination, but because it creates code that is difficult to understand and maintain. 

There has to be a balance between OO orthodoxy, and ease of understanding.  Design patterns are a good example--they're wonderfully extensible, but frankly, the book sells so well because most people wouldn't think of modelling a system that way.

OO should be taken in moderation.  One compelling reason is that not all code needs the extensibility OO provides, and the extra framework baggage is a waste of time.  But more important, IMO, is that it increases readability (a concept that seems remarkably out of vogue these days) and maintainability, especially when there's staff turnover.

smkr4
Sunday, June 08, 2003

"Its been my experience that, when organizations set out to design OO frameworks and are actually serious about it..."

You just described the problem right there.  They *should* be setting out to solve business problems, not to design frameworks.  ;)

You then describe the second problem - a consequence of the first - the hiring of architecture astronauts, who can make *anything* overkill, no matter what kind of abstraction is being used.

Phillip J. Eby
Monday, June 09, 2003

I think that it's a little misleading to call the C++ example "standard OOP practice."  I mean, it's got objects and it uses the STL and everything, but in this particular example it seems that the objects are only incidental to the program.  They kind of obfuscate what's going on and beyond that they offer little benefit beyond the variable-length stack that somebody already mentioned (you can make the argument that it's easier to add operators with the C++ version, but it's a trivial addition and there no practical benefit to that since you probably won't ever add that many operators).

Several years ago (in my naive youth) I chanced upon a VC++ book by Ivor Horton.  One of the example programs that he described was actually something very much like this.  However, one small detail about how he defined this little parser/calculator impressed me (and I think gave me a good idea of why people would want to write OO code over strictly procedural code in the first place).

He defined a "Calculator" class with a "Calculate" method that took as input an expression similar to the form described in the linked site (though from the outset it wasn't planned to allow RPN) and would output a floating point value representing the result of the calculation.  Inside there was a simple sort of FSM that also defined an order of operations like that defined in the linked site, but when it encountered a group (ie: a set of calculations in parentheses) it started off a new Calculator object on it (and then used the result of Calculate like it would have used any other value it encountered).  It seemed like a very nice and clear way to solve the problem.

I think that's what language features (or frameworks you build for yourself within a language) should do.  If you write two versions of the same program in language A and language B, where A's features are effectively a subset of B's, and the version in A is clearer (even if it's slightly less functional -- eg: fixed size buffers and whatnot) then I think that means that you've done something wrong.

I think that an important guiding principle here was best stated by Hal Abelson (or maybe it was Gerry Sussman, I can never remember) when he said, "Programs are meant to be read by humans and only incidentally for computers to execute."

Just my 2 cents.

K
Monday, June 09, 2003

I disagree with the assertion that OO makes code less readable.  Yes, maybe the architecture astronauts around us produce frameworks that are hard to use.  But the same thing can be done in C.  C code with lots of function pointers and macro code are just as hard to read as the type of OO programs you describe.  The problem is not the language, it is the people.  If you strive to never reuse a line of code, your program is going to be an unreadable mess no matter what language you use.

Personally I find the majority of OO code I've seen to be more straightforward and easier to read than a lot of procedural code I've seen.  I also didn't find the C++ version of the parser to be particularly well written, but that is just my opinion.  In fact the most readable C code I have seen usually emulates OO style

Also note when using this page as an example: what was written is not really a parser so much as an evaluator.  The C++ version could pretty easily be turned into a real parser that creates a syntax tree, while the C version would need much more work to accomplish that.  The two are not really comparable pieces of code, regardless of how well you think they are written.

Mike McNertney
Monday, June 09, 2003

I meant to say "if you never strive to *repeat* a line of code"

Mike McNertney
Monday, June 09, 2003

grr... what I really meant is "if you strive to never repeat a line of code"

Man my brain must be on vacation today

Mike McNertney
Monday, June 09, 2003

*  Recent Topics

*  Fog Creek Home