Can OO Programming Solve Engineering Problems?
"I appreciate the concepts of OOP and see its applicability in managing records, GUIs, and possibly standard function libraries. I cannot, however, convince myself that there is a clean way to use these concepts to solve the type of procedural problems that I have encountered in the past (finite difference solutions to differential equations, finite-volume computational fluid dynamics, iterative solutions to non-linear equations, Monte-Carlo simulation of radiative heat transfer, etc.)
Am I just being close minded to the ideas of OOP or do my problems just require 'procedural' solutions, which are better solved using procedural techniques? I'll even be happy with the answer 'Your problems are two small and specialized to realize any significant advantages of OOP.'
I'd be interested in hearing comments from anyone else who has this problem, anyone who has worked through it, or anyone who can send me an example of an engineering application of C++ and OOP."
Your problems are too small and specialized to realize any significant advantages of OOP.
It's not that you can solve problems in OOP that you can't solve in Procedural (Fortran/C like), it's just that for many problems, OOP is much faster, allowing you to re-use much code to deal with things in a similar way when they can be and use the specifics only when needed.
Most engineers have been taught that FORTRAN is the way to solve problems in engineering. If everyone starts out with that prejudice and is stuck there.
Where I work, there is a project to write an engineering application in VB, and it has seemed to be one problem after another after another. (I know i know, VB is crap). The core library functions are in C, in a DLL, so I guess thats a bit of a start.
FORTRAN has been ingrained into the current working generations of engineers, so they're going to use what they know.
Heck, I've even seen SQLPlus code (from Aspen) written very very very FORTRAN like. Instead of using min(), max(), there was a bunch of select looping and checking variables..... Oy.
In my opinion, OOP is only good in large scale yet generic problems. I've seen many people do C/C++ combonations where they filled in C++ gaps with their own C code.
Maybe another way to look at it is to use what you know. It seems like a good amount of engineering students use fortran or pascel to do their engineering work in. As a computer science guy I hardly ever see fortran or pascel when doing my work (school or job), but it boils down to the fact that it works and thats whats important.
This is a really difficult question to answer. I guess my reply would be that no, pure "OO" programming wouldn't hold any advantage to simple procedural programming in this case. However, you can easily add procedures to objects, so OO language is really just a superset of procedural.
Personally, I like the organizational potential of OO. You can have a Pipe object, and call function like Pipe.calculateFlowrate(12,43,23), then you could have a subclass SquarePipe, and call the function SquarePipe.calculateFlowrate(12,12,43,23).
Essentially, you could have 10 objects each with 10 functions to do 100 different tasks, rather than 100 different functions to do 100 different tasks.
Moderation: Put your hand inside the puppet head!
There are a number of ways to approach this, but I've found the following useful:
It's more a matter of thinking in terms of telling your processes to do stuff than creating a road for them to walk down. If you know what I mean
All your Qaeda are belong to US
OO design has nothing to do with C++ versus C. You can do OO design with any language you like; much of the Linux kernel has elements of OO design, but is implemented in C.
Language is an implementation detail. It does not dictate design.
Twoflower
--
Twoflower
I'm not terribly familier with the problems you have presented (I.E. I know what a monte carlo alogorithm is, but not the radiative heat transfer part...), but it sounds to me like you're trying to fit the problem to the solution and not the other way around. OOP can be useful if you're trying to model something, or replicate the behavior behavior and characteristics of a real world problem, but it's not that great for say, solving a system of equations... I guess you can use whatever language or system you would like, but not many need C++ and the STL to evaluate expressions.
All of the techniques you listed and most other engineering problems are expressed in a procedural format. In order to use OO you would have to transform the problem into an object problem. The things that OO does really well at are things where we already think in object terms. Like GUI widgets. Most engineering problems simply aren't expressed that way. Although most problems could be rephrased that way the algorithms would necessarily not be equivalent (better or worse would require experimentation)
If you're dealing with a problem that can be reduced to a mathematical formula or the like, you're probably better off looking in Numerical Recipes or the NAG libraries, or what have you.
In this case, you're dealing with a well-defined, well-understood problem. You could implement a solution using OO principals, but why bother. I mean, you're not going to be changing it or adapting it all that much.
The power of OO happens at a higher level, and with less-well understoof problems. In this case, you're modeling higher-level entities, with less well-understood properties that are much more liable to change. In this case, the ideas of modularity, pluggable behavious, cohesiveness, etc., become much more important.
I hope that didn't sound too much like a hand-waving explanation.
668: Neighbour of the Beast
Code Reuse and extensibility is (IMHO) the largest advantage of OO. By (trying) to demark a dotted line around the box of code you want to (re)use and separating out your new code, you realize gains in writing and testing. Communicating what code actually does is also much cleaner in a componentized view.
So take a look at many programs writting in Windows these days. Anything written that uses COM. Almost all *ix shell scripting. While they all follow different aspects of "object" reuse, you are benefitting from using a block of solid code without having to retest it. I'm abstracting the definition many people have of "object" as such, but in the end all the goals are similar: Get it done better, faster.
mug
Some of the replies here are a little confused. To paraphrase The Princess Bride, the word does not mean what you think it does.
Functional programs evaluate expressions rather than execute commands to "get stuff done". Scheme (which is derived from Lisp) is one of the more well known functional programming languages.
C is a procedural language, not a functional language. Examples of the latter include LISP, Scheme, and ML.
As to whether an object-oriented approach is suitable for engineering applications, I think it depends on the applications and problems. How important is abstraction and re-use? If you deal with matrices, would you benefit from a matrix object which implements all the properties a matrix has? With differential equations, are there objects suitable for implementation?
As with all general questions I am afraid the answer is "It depends."
I would tend to agree that OOP might be the wrong solution. It seems to me that OOP is designed to generalize code to solve broad problems. Engineering, and other applications which require minute changes depending on multiple factors might be better served by procedural code designed to specifically handle those problems.
An interesting point that is raised is the fact that OOP, while an enormously helpful tool to many programmers and despite its advantages in many other theaters of software design, does not have to be an end all be all for programming as a whole. The tool that works should be the tool that is used.
"Moving through the masses like a fish through water." syrup
...when the jury is still out on whether OOP can even solve computer science problems?
Other than a small handful of examples, I haven't seen where OO helps any way other than the creation of arbitrary data types and convenient grouping of data and functionality which can be done, although less cleanly, in a procedural language as well. The complexities of inheritance and God forbid, polymorphism, usually lead to more problems than they solve, in my opinion.
I agree that OO programming can be more programmer-friendly in some cases, but in general find it more trouble than it's worth. Sometimes it looks to me like most of the things that can be re-used have already been turned into libraries, and the rest is all custom programming.
I confess to learning programming using procedural techniques and using them for a dozen years before picking up OOP, and still finding those techniques easier to apply. But I'm not the only one that questions whether OO is a big red herring to productivity.
OOP doesn't solve engineering problems of the kind you describe. The programs solve the problems.
OOP is a way to think about structuring the program, how you organize data and operations on the data, how you build reusable components which you can apply in some future problem you need to write a program to solve. In other words, OO helps solve software engineering problems. You'll still need to write the program which solves your particular problem.
And before the flames commence, yes, OO isn't the only solution to this class of problems. It's just one.
How do you write a million lines of maintainable code in six months with 5 programmers in Silicon Valley and 50 in Turkey? Hint: You don't do it in C.
OO programming is not just about modeling the problem well, which in and of itself is enough to recommend the approach to an engineer. It also addresses the very difficult task of generating and maintaining a large software project in a form that a human can understand. For many small tasks, the extra overhead involved might not be worth the extra effort required if you are not already comfortable with the OO metaphor.
Take a look at BLITZ++, then tell me OOP is not useful for scientists and engineers. :-)
I think the safest thing to say is that whatever your programming needs, whether you're doing pure matrix/BLAS number crunching or writing complex simulations/models, you should think twice before using FORTRAN. Well-written code in, say, C++ will be more maintainable and accessible to other people you work with (and who have to touch your code in future).
The only thing which keeps people using FORTAN that I've seen is that the optimising compiler support is fantastic compared with the equivalent offerings in C/C++ compilers. But that's not much of an excuse for general day to day problem-solving.
Just my 2p.
These sigs are more interesting tha
Read the following book:
Object-Oriented Implementation of Numerical Methods: An Introduction with Java & Smalltalk
by Didier H. Besset
One of the items I've run into is that FORTRAN natively supports complex numbers. C doesn't support them, and I need to use the Standard template library in C++ to get the support.
After I've used the STL, I then don't have the huge library of old code that I can draw from in FORTRAN.
I much prefer writing in C / C++ to writing in FORTRAN, but there's lots of legacy FORTRAN code out there that'll get reused.
When you get down to it, every application, at some level, is a database of some kind. ie. it will end up storing many records of the same or similar type, usually in memory, and then go and do actions on those records. Weather each 'record' is a data packet, plugins for your application, records from some kind of file, whatever. In the end, it all acts a little like an in-memory database.
....) you would just do mystruct.do_something(...). Which when you think about it, is a more logical solution. Almost every function you write, except for the straight out code-flow, and accessor functions, is some kind of operation on a data record in your 'in-memory database' (however it is represented). OOP's main purpose is to more link the functions doing stuff to the data, and the data itself. Nothing more, nothing less.
.c file, and you know they're all related to that structure because they're in that particular .c file, you instead put all the functions in a class, and you know the funcitons work on that data, because the data, and function, are all part of the same logical unit.
... its just a cleaner way to group together data and functions that work on that data in a more 'binding' fashion, something that had to be done by the coder's memory and by hoping the previous coder's comments were good enough to make it clear what goes with what.
The traditional way to handle this kind of thing is with a linked-list or array of structures. The main thing OOP gives you is not any 'special' solution to old procedural programs -- infact, a good blend of procedural and OOP is always the best solution, because every program is a combination of both. However, what OOP does give you is a nice way to encapsulate all data that is relevent, instead of into a structure, into a complete package.
Instead of calling functions, and passing that object around, and then worrying about lost pointers, NULL's, etc. You take the more logical course of action, and perform the action directly ON the object. ie. instead of doing: do_something(mystruct,
Things like inheritance, templates, polymorphism, etc, are all just fluff to make coding easier, that has been added on top of the OO ideal. Granted, they make life ALOT easier (dont get me wrong, I use all of them all the time, and I'm an OO junkie), but the main purpose of OO is simply to create logical units, including code, and data in one block. So instead of having a bunch of structures, and then all functions to act on that structure in one
So I think you've mistaken the benefit of OO. As I said before, OO is not some kind of magical wand that will solve even the most complex of computing programming problems easily
One example that comes to my mind immeiately is MMTK ( link) (Molecular modeling tool kit) developed in python by Konrad Hinsen.
Not really, but there is an element of truth to that mantra: most engineers traditionally learned to program in Fortran, and there were some damn good Fortran compilers/libraries to handle the types of matrix manipulations commonly encountered.
You don't need the overhead of OO design for your engineering programs. I would stick to C unless you are trying to do some kind of fancy GUI.
While abstract classes will incur the hit of an extra level of indirection in a function call, and exception handling in C++ can be expensive (as can multiple inheritance), these features only cost you if you use them.
Now, to answer the question at hand, I have helped to design and develop commercial speech recognition products using C++. Of course, there was plenty of C and hand-tuned assembler there as well.
A more concrete example would be the VFS in Linux, as well as the classes of network, block, and character device drivers -- while generally coded in C, they represent the notion of abstract base classes unifying a common interface to many different implementations -- there's no reason C++ could not have been used there.
You could've hired me.
First off you're examples Monte Carlo simulations and differential equations aren't "engineering problems". They are math problems that are a component of an engineering problem. Engineers does things. It builds a bridge, drives a car, prints a document. The examples you give are parts of that solution. Every GUI needs to do things like interpolate colors and position, which are the same class of problems -- if orders of magnitude simpler -- as differential equations and Monte Carlo simulations. So it seems to me that you need to figure out what your real problem is and figure out what programming paradigms might help you out with that.
As others have pointed out OOP doesn't let you solve things that are otherwise unsolvable. It is a way of solving problems that may be better in some situations and worse in others. The examples you give of solving equations are all better suited to a functional language than a procedural one like Fortran, so rather than asking "why use OOP" you might want to first ask yourself "why am I using Fortran?" Obviously there are a number of factors that go into how we pick our solutions. Maybe OOP per se isn't a good fit for your problem but you need it to be multiplatform and have a huge amount of available code and standard libraries so you end up going with Java. Or whatever.
The kinds of problems you're talking about don't have a great mapping onto the traditional ways of describing OOP. However, OOP is really just a somewhat formalized kind of way of dealing with abstraction and data encapsulation. You can make a difference equation a class. Maybe it'll only have one method that immediately finds all the finite solutions. But once it is a particular datatype you can also do things like compare whether two user-entered difference equations are identical and just returned the cached solution. You can curry them. You can return partial solutions and then come back later and ask the object for more solutions.
Don't you already have discrete data types for these things? And don't you already have functions that operate on those discrete datatypes? Then you're already doing OOP. Sure you're not using inheritance and multimethods and things like that. But not every OO program does.
OO languages exist at the "high" end of the language-level spectrum. They're geared toward managing code complexity in the face of a problem domain which is conceptually complicated, primarily by encapsulating bits of the problem domain into digestible and self-contained sub-problems. The overhead of all of the OO constructs is worth it if the reduction of your problem domain into smaller chunks is neccessary to solve the problem (or advantageous in terms of directing the efforts of multiple team members in areas where some decoupling is possible).
However, if you problem is "low-level" or conceptually simple (though not neccessarily computationally simple) -- a recipe like "apply transformation x to dataset y, then transform again w/ algorithm z", the OO features simply serve as a distraction from thinking about your actual problem domain and it's solution.
So yes, IMHO, there are problems for which OO techniques are not ideally suited, and most importantly, if the techniques get in *your* way they are not the right tool for *you*. Rememer, languages and tools don't solve problems. People do. If a tool makes you task easier, use it. Otherwise, save yourself the time.
Why not learn Scheme? It is weel suited for implementing recursive algorithms in a straight-forward way. Also, may I suggest learning some logic-based language, like prolog, with a finite domain solver included (as the one in gprolog)? I don't know, since I'm no engineer, but I can imagine a finite domain solver being usefull for engineering tasks (it can be used for e.g. scheduling several tasks to reduce resource usage and the like).
--The knowledge that you are an idiot, is what distinguishes you from one.
For simplicity's sake, let's think about quadratic equations for a second. You can solve them easily, but if you want to use them in a larger program, you could create a QuadEq object in OOP with the following properties:
An OO programmer would then add methods to set, retrieve, and calculate those properties based on what's been entered. And the QuadEq object would be entirely portable and easily amplified for future equations.
I don't think choosing OOP is a matter of being the only tool to solve certain problems. However, it is often the most efficient way to solve large, rapidly-changing problems. But like you said, other problems (like many of the ones I encounter in web development) will be small and uncomplicated enough that the overhead of OOP isn't worth the trouble.
You seem to think that OO is some end all be all of the programing language. It is more on how you structure the code. You can do a hello world program using OO is you wanted. Instead of acting on the logic of the problem you design from the idea that the data is what must be manipulated and therefore is an object to be handeled. All the problems you are listed are easily solved by defining the class that is associated with the data inputs and then perform actions on those objects. It is quite a bit different in thinking over how fortran is programmed.Having programmed in both OO is a much more powerful solution.
Here is an excerpt from www.whatis.com that may explain this better than I can.
" The first step in OOP is to identify all the objects you want to manipulate and how they relate to each other, an exercise often known as data modeling. Once you've identified an object, you generalize it as a class of objects (think of Plato's concept of the "ideal" chair that stands for all chairs) and define the kind of data it contains and any logic sequences that can manipulate it. Each distinct logic sequence is known as a method. A real instance of a class is called (no surprise here) an "object" or, in some environments, an "instance of a class." The object or class instance is what you run in the computer. Its methods provide computer instructions and the class object characteristics provide relevant data. You communicate with objects - and they communicate with each other - with well-defined interfaces called messages.
The concepts and rules used in object-oriented programming provide these important benefits:
The concept of a data class makes it possible to define subclasses of data objects that share some or all of the main class characteristics. Called inheritance, this property of OOP forces a more thorough data analysis, reduces development time, and ensures more accurate coding.
Since a class defines only the data it needs to be concerned with, when an instance of that class (an object) is run, the code will not be able to accidentally access other program data. This characteristic of data hiding provides greater system security and avoids unintended data corruption.
The definition of a class is reuseable not only by the program for which it is initially created but also by other object-oriented programs (and, for this reason, can be more easily distributed for use in networks).
The concept of data classes allows a programmer to create any new data type that is not already defined in the language itself.
One of the first object-oriented computer languages was called Smalltalk. C++ and Java are the most popular object-oriented languages today. The Java programming language is designed especially for use in distributed applications on corporate networks and the Internet."
Papa Legba come and open the gate
I've seen some truly awful procedural code (lots of it was Fortran, BTW). I've seen some truly gorgeous procedural code (lots of it was Fortran, BTW). I've seen some some wonderful, and even more pretty awful, OO code (mostly C++, but with some Java).
Go ahead and study object oriented programming. You'll learn some new ways to do things. But I think it's the act of studying, and the act of learning, that will be the most valuable thing you get out of the process. Too many people never study how to program, how to document, how to design code. They learn one or more languages. Their code shows it.
A few people have a natural tendency to write elegant code. A few more, but still not very many, study and try to learn how to write elegant code.
But don't expect the object-orientedness to make much difference. A dozen or more years ago, a young whippersnapper got hooked on objected-oriented design. He derided all the existing Fortran we had as spaghetti code. To some of us, though, his "object-oriented" code was lasagna code. No overriding structure, code spread out all over the place, a single function scattered over three files. And this was still Fortran; I've seen C++ coders who took six files for a similar, simple function.
I've also surprised myself! when some of my OO C++ code needed four lines to add new functionality. But it was carefully designed, after years of programmer improvement and study.
Go ahead and try it; it can only help.
I think the "answer" to your question is that, yes, your examples are too simple. When you're doing some simulation where the "finite difference solutions to non-linear equations" all interact with each other, and with computed fluid dynamics and heat transfer, etc, you'll immediately see the benefit of separating all these concerns into encapsulating object types.
[
The kinds of problems you're trying to solve aren't problems object oriented designs are good at. While OO is a natural way of dealing with some concepts (for example, GUI concepts), its real power doesn't come from this kind of thing. It tends to be best for designing very large systems that are complex and may change significantly over their life-time. The kinds of problems you mention (finite difference solutions to differential equations, finite-volume computational fluid dynamics, iterative solutions to non-linear equations, Monte-Carlo simulation of radiative heat transfer, etc.) aren't really the kind of software engineering projects that require carefull design. They may be hard problems, but they're also understood and well studied problems.
Take a step away from the scientific problems and consider something like an inventory management system for a pharmacy chain that needs to be solid and accurate, while at the same time collecting data and producing pretty reports for whatever statistic the company directors think is important on that particular day of the week. A slightly different kettle of fish, no?
Another often stated advantage of object oriented programming is component reuse. It seems that most developers don't really try, but for a little bit more effort and thought, object oriented techniques make writing highly reusable software components easy.
For my own personal projects, I have a set of classes that do all sorts of things for me, from a log file manager to a small LALR(1) parser which I have a generic config file parser built using (all in C++, no need for external programs). It's a pain in the ass to write the code originally, but it was all well worth the effort. :)
A lot of engineers have trouble with the problem "Staying employed during a recession." OOP is the cure - every bit of code you create is now unmanagable to your cow workers. As such, you can't be fired.
Moneyed corporations, non-working 'poor' and criminal prisoners are turning productive citizens into tax-slaves.
My personal experience has been that OO is a big win when a problem is subject to factoring. By factoring, I mean that when you take each element involved in the problem, you can find common factors between them. In that case, you get a natural class hierarchy by moving the common elements into parent classes with each individual element being a subclass. The reduction in code size decreases the number of bugs substantially.
One way you can detect this is if you are doing a lot of cutting, pasting and modifying during development. Often this is an indication that a better design would be to have one copy of the base code. All the other elements that had copies would now essentially inherit the base code and then override the parts that need to be changed for that particular element.
If your project is not going to involve a lot of inheritance, then OO is really only useful if you are in a large project, in which case it acts as a useful way of delineating responsabilities. (i.e. all I have to do is implement and test these interfaces and I don't have to worry about stepping on other people's toes.)
This is all a great simplification, but it covers my experience in a nutshell.
If your primary job is engineering and not programming, and you're getting the job done in FORTRAN, then by all means stick with FORTRAN. If on the other hand, you are building software systems from scratch that will need to be maintained over time and have components that might need to be reused then maybe OO is the way to go. In any event, it is good that you are exploring OO because even if you don't use all the techniques explicitly, you are probably picking up some good design ideas through osmosis.
Imagine for a minute that you don't know what problem you want to solve yet. You know that that you want to apply a Galerkin Finite Element Method (for instance, though this particular method isn't required) to a whole class of problems on unstructured grids on a whole class of distributed and shared memory parallel computers. Imagine that you want your user base to be able to specify their equations like they would in LaTeX or some other markup language. Now try imagining that you have only FORTRAN77. Not a pretty picture. We're in the process of completing a rewrite of major sections of our parallel code to do exactly this. Our code started out (7 years ago) as an extremely efficient parallel (3D) C/F77 code for Navier-Stokes + Heat Transfer and is quickly growing into a multi-purpose, multi-physics code written largely in C++.* We extract considerable advantage form C++'s ability to hide implemenations so that as long as interfaces don't change the guts can. We also make good use of the ability to run code before main() in order to register the exisitence of routines (hash tables are your friend). If the routine isn't there you can't call it, but the code still compiles and runs otherwise. We also make use of base class/derived class relationships and polymorphism to allow, for instance, one base mesh class for the rest of the code to interact with, but with two separate derived classes: one to generate meshes internally, and one to read meshes from other programs. Etc., etc. I'm not sure our website can take the /.'ing, but you can look here for some hints.
* I say largely b/c there's a few struct's still left over from the code's C days, but all the F77 is gone. There are still calls to assembly coded (vendor supplied) BLAS routines, though.
Yes...I am a rocket scientist.
Remember that OO code tends to compile into slower and larger executables than structured code. This is not always the case, and optimizing compiliers can do a great deal to mitigate this, but the fact of the matter is that OO code was developed to give coders more power and shorter development times.
Most of the engineering problems that I've ever seen solved in code are math intensive. One such problem was calculating the drag on a certain aircraft wing. If I remember correctly, the coder who was showing me her code indicated that the math involved broke down into a repetitious series of a few hundred cross-section integrations. These equations had to be solved for several hundred thousand cross sections to get a final result and a chart. At the time ('91) there was no 3d model, and the calculations were being conducted on a desktop computer. As you can imagine, it took a very.. very long time. One of the people I was with asked her what she was doing her math in.
C. C++ had too much overhead, she complained, and the C compiler she was using was slightly faster than Pascal or Fortran. She was very seriously considering trying to translate her equations to register-based assembler code to speed up the process.
If you have an engineering problem, and you're happy with the results you get from a funcational language, it's probably not worth your time you'll lose from switching to an OO language.
If you
The next Slashdot story will be ready soon, but subscribers can beat the rush and slashdot the links early!
From your post is sounds like you're solving single solution problems where you write a 'disposable' procedure (probably reusing some code) for each problem. OOP isn't designed for that.
OOP really starts to shine when you actually have objects to work with. If all you're doing is trying to solve a single solution problem a simple 'disposable' procedure is the best route. For larger, evolving, iterative projects OOP is a godsend. In my case, I'm designing a MAV (Micro Air Vehicle).
I'm using Python instead of C++ but the OOP example still holds. Aircraft design is a highly non-linear process, and for myself at least, counter-intuitive. I could write a single procedure to run the analysis but that's not nearly a flexible as an OOP solution.
Basically, I'm using off-the-self components (i.e. motor, batteries, propeller) as a starting point for my design. Each of these components is considered an object. These components are combined in such a way as to make another object: the entire MAV. By using OOP it's rather easy to try different component configurations and design conditions (flight altitude, cruise, loiter, velocity, etc).
If I was really cool (I'm not) I could add in some simulation stuff (Larger aerospace corporations do a lot of this, as it's cheaper and quicker than an experimental approach).
One thing that this sort of OOP approach lends itself towards (especially in my case, is genetic algorithms). Since aircraft deisgn is so non-linear, and counter-intuitive the best solution is not easy to find. So many different designs need to be analysed. OOP and genetic algorithms were born for just this sort of thing.
If you have a single problem that needs to be solved once for one set of conditions, then use a procedure. If you have a larger project that requires the solution of many smaller problems for various conditions (instances to use the OOP term) then OOP is an easier route. Anything in between is a judgment call and really depends a lot on your specific case.
Many people confuse OOP with C++. The two are not the same. C++ contains enhancements that are _supposed_ to help OOP, but often don't.
I've been programming for more than 24 years and have dealt with languages from assembly to FORTRAN. I learned to program in assembly before PC's were even invented. I have always written code as modular and reusable and in a sense in an OO style. I've solved many problems, some large, some small, using OO programming without using C++. In fact, I try to avoid OO C++ for many reasons, though I prefer to use a C++ compiler and a smattering of C++ functions/keywords and style.
I think you will find that many problems have been solved using OOP, but that the definition and composition of OOP is often misunderstood. For a good example of an application that is written using OO techniques, but does NOT use OO C++, see the Quake II source code.
The reasons I avoid using OO C++ is due to inefficient compilers, the tendency to generate hard to find/fix bugs, excessive overhead, and the tendency for other programmers (if I'm working in a team) to overuse/misuse OO C++ features (e.g. - operator overloading). To date I have been able to accomplish the same tasks, with the same OO designs, using straight C, with less hassle and greater efficiency.
- Rohan
I'd recommend that you check out the Ptolemy project (http://ptolemy.eecs.berkeley.edu/). It brings the most powerful features of OO design (encapsulation, polymorphism) into an engineering modeling environment. Applications? Signal processing, simulation of hybrid electronic and mechanical systems, embedded control, etc. Also the basis for many electronic CAD tools.
As part of a project I was on, we needed to do a bunch of simulations of particles moving subject to physics. Unlike what you usually see in games, these needed to be real simulations (reproducable in the lab).
We ended up doing a bunch of OOP so that we could handle many different kinds of particles, and many different PDE solvers, each selected for the particular task. Because of polymorphism, we were able to write the engine once, and plug in what we needed fairly easily. In the end the code ended up being much cleaner, readable, and faster than the Fortran we started with. We have gone on and are using it for a completely different kind of simulation now with minor changes.
This was all in the Chemistry Department, but I certainly think it applies.
I would guess that most engineers use Fortran in part because of the book "Numerical Recipes in Fortran". Although there exist C and C++ versions of the book, they certainly don't take advantage of the languages, and for the most part are direct ports of the fortran. They are very disparaging of the languages in those books, and even spread FUD about C, C++ and the numerical stability of the compilers.
There's an intriguing book called bject-Oriented Implementation of Numerical Methods: An Introduction with Java & Smalltalk which might give some pointers. I haven't read it (just browsed it in a bookstore), so I can't give a personal recommendation one way or the other. It does seem rather intended to address just your question, though.
Don't listen to the guys saying engineering problems are best solved with procedural programming. That's a ludicrous generality.
Both methods (and basically all programming paradigms) can be used to solve your problem. Which you choose depends on factors other than just "which will work". Readability, reuse, maintainability, performance, and ease of design are some of the issues you'll have to weigh do decide whether to use OO or procedural. In my opinion, OO programming beats procedural in all these matters except performance (but C++ ain't too bad, right?).
My company does a great deal of mission-critical engineering software development (satellite command and control, for example), and we approach every large project with OO design and implementation. We find it insturmental in managing complex systems.
If you ever have to show your code to someone else, they'll thank you for having partitioned your project into smaller entities each with their own responsibilites and personalities. This modeling concept is much easier to follow than procedural's interweaving threads of execution.
Pushbutton switches can be on or off, lights likewise (same class, sanity checks to ensure you don't read a light or turn on a pushbutton).
Remember, you are dealing with real world objects which have attributes. Look at them from that perspective, and see how you can model them in software.
Best Slashdot Co
There are many instances where C++ can actually produce faster code.
For a simple example, compare the C qsort with a C++ template Quicksort function. In the C++ version, the comparison operator would likely be compiled inline to the function, meaning that you don't get the overhead of a function call for every comparison. In C the only way you could do this would to be to write quicksort yourself for every data type that needs it. C++ templates allow a lot of work to be done at compile time, rather than at runtime.
Check out http://www.oonumerics.org/blitz/ for fast C++ scientific applications.
cheers,
Tim
The reason for using OO was code maintainability and compartmentalization. It is generally easier to divide work up once you're able to break your application down to classes.
OO also means extendibility. With the right class hierarchy it was easy for us to add a new node to our scengraph to support a new type of data. For example, initially the app supported horizon data only, later on we added support for faults just by extending one of the base classes. OO will help you write any application if your class structure is sane.
Your pizza just the way you ought to have it.
The applicatations that you listed primarily deal with physical systems, so they are very well suited to OO, where an object can be used to represent some real-world thing. Molecules, machine parts, elastic elements, or magnetic domains are all things that have behavior, state and identity, so they are perfect cantidates for objects.
But, the physical simulations are also iterative, so the code will have a loop, and loops feel like procedural code. That is not a conflict -- you are allowed loops in OO code! Your simulations would likely have a loop that iterated over time, space, temperature, or energy, and for each iteration, you would examine the state of each object in the system and call some methods on them to simulate their behavior.
For instance, if you were building a solar system simulator, each planet would be an object, with properties for position in space and mass. Your loop would iterate over time and over each planet. For each planet in a time step, calculate the force on the planet due to other planets, and move the planet in response to the forces. ( More likely you would use an adaptive iterator and use another loop to do several iteration steps per planet per timestep. ) The benefit of OO here is that it makes it easy to organize your code and move simple things like F=Ma, 3d vector manipulations and your Runge-Kutta integrator out of the main algorithm. Plus, your code is easier to read, since you don't nned a lof of comments for things like planet.mass() or planet.move(vector)
OO makes physical simulations much easier because it allows you to organize the program according to the physical structure of the system, and those object remove a lot of basic code from the algorithm, so the algorithm becomes simpler and easier to work with.
I have built simulations for packet networks, simulated anealing, Ising glasses, Newtonian mechanics and finite element analysis in both OO and procedural style, and OO worked so well that I would never consider writing any of them in procedural style again.
Preface: I've been an embedded systems software engineer since 1987. I've been programming in C for almost all of that time, and C++ since '91. I've designed systems with over 250kloc, hard realtime.
The biggest single advantage of OOD is that you can say "This sort of thing will have a function that does something like this, but I won't make the final decision on exactly HOW to implement that function until late, when I have more information on what needs to happen."
Let me give you a concrete example. I had to design the code to reprogram the flash in one of our devices. I faced the following problems:
1) the way the data got to us could either be Xmodem or Ymodem.
2) The file format could be either OMF or raw binary.
3) The types of memory devices could change - they could be Intel type 1 flash, AMD type 1 flash, or Intel type 2 flash (or RAM), all of which have different programming requirements.
3a) In addition, the types of flash could be changed by the production line (based on what was available - most of those parts were "on allocation", meaning "you take the quantities we give you and you like it - you ain't IBM so you don't matter".
3b) The types of flash on a given unit could be mixed - you had to probe at runtime to figure out what you had.
So, here's how I decomposed it:
1) I had two file type objects: OMF and Binary. They each HAD-A Input object, which provided data , and HAD-A Memory object, which would program memory. The OMF object read OMF records from the Input object, parsed the OMF records, extracted the data, and commanded the Memory object to program regions of memory.
2) I had an Xmodem object, which WAS-A Input object. It read data from the serial port, handled the checksum or CRC verification, block counting, and made the data available to the user (the file object).
3) The Memory object HAD-A pointer to a Memory_driver object. When the Memory object was commanded to write to a block of memory, it verified that the write was in the current block, and if so passed the request to the Memory_driver object. If not, the Memory object HAD-A list of Memory_driver_list objects, which each HAD-A pointer to a function that would probe a given memory address and return either NULL or a pointer to a newly created Memory_driver object. The Memory object would iterate through the list, asking each Memory_driver_list object "Can you program this?". When one of them returned a non-null value, the Memory object would delete the old Memory_driver, and use the new Memory_driver.
4) I had Intel_series1, Intel_series2, AMD_series1 and RAM objects, all of which WERE-A Memory_driver. Each class HAD-A static instance of a Memory_driver_list object, which automatically linked itself to the driver list. Each driver HAD-A static member function to probe memory and return a pointer to a newly created driver if needed.
First, this let each routine be focused on what it needed to do - the Xmodem routines didn't worry about OMF format, the OMF didn't do Xmodem handshakeing, the Memory routine didn't care about the specifics of programming memory. I could test each object out in isolation, get it working, and move on. Now, you can do this with proceedural programming techniques too.
Second, when a new type of memory was added, I was able to just write the driver for it, and not touch the OMF object, the Memory object or the file transfer objects. They automatically picked up the new driver. Now, you can do this in a proceedural language like C, but how do you do so? You make each driver have a table of function pointers, and you have the upper level code keep track of a void * that contains your driver information. Guess what - that's OOP! The function table is the same as a C++ vtable, the void * is your this pointer. Except that in C, you have to track all that stuff yourself, in C++ you can let the compiler worry about the BS and you focus on the code design.
In short, OOD helps, but you still have to use it correctly.
www.eFax.com are spammers
However, I have lots of bad experience trying to get engineers to write good OO code. Nothing against y'all, but, conversely if you forced most software engineers (aside from a few savant freaks that I'm sure will chide me) to deal with the engineering problems you mentioned (that I have never heard of or forgot) we would probably die.
What I'm getting at, I guess, is that OO rules. However, it's like linux, or repairing cars, or (ad infinitum). Being an expert rules, but it's not always worth the time to become an expert. You can't just jump in. Reading a few books helps, but I've read a few books, been doing this full-time for two or three years, had a very OO college experience, and most of the stuff I design and code is still crap.
In addition, the code you are writing seems really unlikely to change. Write it procedurally, and write it well, and your grandkids will still be using that code because it would be too much of a pain to rewrite it to OO.
I think you might be looking for an exemption. Here it is : use procedural programming for things that are tough for you to imagine in OO terms. Don't feel guilty. You will still never have as much crap code lying (laying?) around with your name on it as I do, and I do this for a living ;)
Jack Valenti and the MPAA are to technology as the Boston strangler is to the woman home alone
Many engineering programs use a combination of languages. For example, C++ is used for the high level programming and FORTRAN for low level the numeric kernels. Of course, you can write low level numeric kernels in C++ because it supports both OO and procedural programming. Often FORTRAN is used because
My present employer, the Center for Applied Scientific Computing, has Overture and SAMRAI written in C++.
I'm sure that OOP is useful in modelling, but more detail would be nice. Most people don't realise that the engineering problems solved on supercomputers are usually approximations, and increasing efficiency or available resources can improve those approximations. Even a mundane problem like the temperature distribution of someone jogging in wet trousers on a humid sunny day would need serious computing power, and there are a lot of problems more complex than that which can give useful results.
OOP is mainly useful for the design of large systems. Unless your language is being overly intrusive, there won't be anything OO inside the solution of an engineering problem like the ones you describe.
The way OOP would apply to your problems would be when you're looking at the problem from more of a distance. You might have a situation in which some code wants the solution to a problem; the problem is specified by some other code, and it is solved by some other code, but there is a chunk in between that is doing something with the two parts (e.g., graphing them or something). You could make a "problem" interface, with a "solve" method, and various methods for getting information about the data. Then the intermediate code doesn't need to know what procedure to call to get the solution, because the problem object knows that.
As for things like "solve a differential equation" or "solve a set of linear equations", OOP means that you're writing a big method instead of a big procedure. It's not a big deal. The real jump is switching to a functional language, where you write your code without side effects, and the compiler can do optimizations which change when code gets run and do not run the same code with the same data more than once.
I'm sure plenty of people use C++ to kick butt, but I personally never appreciated OOP until I used it in more high level languages.
For something that's much more OOey, and easy to learn, try Python. I don't see any reason for new applications to be written solely in C++ nowadays. And the speed issue is irrelevant since you can rewrite portions of code in C (and quite easily, I was pleased to find).
I haven't looked at NAG, but you're not getting all the source code? Actually, I find it weird that one does rely on closed source in science, when science depends on the full disclosure of all relevant material. Well, the computations done is arguably the most important aspect of most analysis done today, so all source code should be available for public scrutiny.
I would recommend R for many applications. It has some lightweight OO that is very efficient, it's a really beautiful language. It is also very rigorous, you will find the best things in Numerical Recipes there, but there is also a lot of code that has been through formal peer review.
Employee of Inrupt, Project Release Manager and Community Manager for Solid
A lot of people seem to be forgetting that objects can be used to represent algorithms or protocols instead of GUI widgets or physical things, and that subclassing still applies. It's very easy to imagine, for example, a MonteCarlo class or a FiniteElement class with virtual methods for the equations to be applied to each element/unit/whatever. It's much cleaner and more maintainable than explicit dispatch tables and function pointers, and never even mind the cut-and-paste approaches that many scientific code is still based on. Various notational conveniences such as function overloading and default arguments could also be useful.
Sure, the OOP literature tends to give different sorts of examples, but the basic tools are still useful if you just allow yourself to think in terms of relationships between algorithms instead of between actual objects.
Slashdot - News for Herds. Stuff that Splatters.
Now the real question is "should you?" Probably not if you're doing scientific calculations. You're better off optimizing the code and writing detailed documentation than generalizing the structure. Like others have said, "OO is a tool." That's all it is, nothing more, nothing less. Try to think of it as building a house or an office building.
There are reasons why office buildings have large open spaces with cubicles. This allow reconfiguration of the furniture to fit each renter's needs. For the same reasons you wouldn't try to cram 50 person company into a 4 bedroom house, you shouldn't force OOP principles on a problem that doesn't call for it.
From your post, it sounds like you're interested in OOP, so maybe the question really is "should you get a new job that gives you an opportunity to find out first hand what OOP can do for you?"
I have always thought of OOP as fundamentally a procedural programming technique but extended to give you better ability to organise and manage larger projects. C++ is a superset of C - you don't have to use the OOP features but they can help you enormously in the right situation.
:-). In this case, all the code that used the object would remain the same, possibly saving you a load of work.
OOP also encourages good programming practices like producing well-defined interfaces, implementation hiding and code re-use. I actually think these are crucial to the effectiveness of OOP. These are all good things, and I'm sufficienctly lazy that I would never write anything other than a trivial program in purely procedural style.
However, OOP is still best suited to particular domains. Modelling, GUIs, enterprise applications, games etc. are perfect because they all require the manipulation of discrete and readily identifiable "objects" that map onto the OOP model very well.
If you're writing network drivers, you could use OOP, but as other posters have been keen to point out the (very small) overhead of most OOP languages actually becomes a problem for very low-level code. Hence OOP isn't so well suited for OS kernel code, network protocols, hand optimised inner loops and embedded applications.
The difference between procedural and OOP is mainly a trade-off between low level control of the machine and having a semi-automated system to manage the complexity for you. Interestingly, for larger projects, good programmers in procedural langauages often end up having lots of function calls that take the "object to be acted on" as an argument and are therefore effecively emulating method calls. Once they start putting in switch statements in those functions to branch on the type of object encountered, they have effectively emulated virtual methods.
Your case is an interesting one. You are dealing with mathematical/engineering problems that are often tackled in a procedural style.
If you're feeling adventurous, I would actually suggest you head off to look at functional langauges. Reason is that these langauges are ideally suited for representing functions and other mathematical constructs, just as OOP is geared towards representing and manipulating "objects". Haskell would be my no.1 choice if you're looking for elegance and flexibility, O'Caml if you are more concerened about raw performance.
If these seem too radical a departure, then I still think that OOP could make sense for a major project. You probably wouldn't need inheritance, but implementation hiding can be very useful. Let's say you're modelling fluid dynamics, and do it procedural style with a big array. Works fine until you decide that in fact you want to store the data in an octree so that you can get a couple of orders of magnitude better resultion in the particular areas you are interested in. At that point you have to change everything that accesses the data structure, including the 100 or so simulation programs you've been developing. Not fun. If OTOH you had encapsulated it all in an object, you would just change the object's private implementation, keeping all accessor methods the same (e.g. getFluidVelocity(x,y,z), getPressure(x,y,z) or whatever, I'm not an engineer
It's also often useful to have data represented as objects just so you can do useful things like pass the around, build larger data structures etc. Not that you can't do this in procedural style, but OOP takes away all the pain. I've lost track of the number of times I have taken advantage of all the useful features like object serialization in Java, which saves you all the hassle of having to write import/export functions to store your data structures on disk.
Ultimately, use what seems right for your application. But remember that OOP and other techniques such as functional programming aren't just fads, they are ways to solve problems that procedural style just isn't well suited for. If you find yourself spending too much time writing the "glue" to hold a big application together, then it's a good sign that you've actually picked the wrong tool.
Problems of the type you descripe wouldn't benefit much from OOP. I'd solve them myself in C, but that's mainly just because I don't *know* Fortran (fortran is very good at math problems with straightforward methods of solution, and parallelizes easily).
My most recent project, on the other hand, involved simulating a computer system (I won't go into detail; wait until after I've published). This is a perfect scenario for OO - a computer system is built up out of many parts, many with similarities, but with different implementations. If you need a cycle-by-cycle or event-by-event simulation of a computer system, it makes sense to build up models of all of the parts that will be interacting and put them into an OO hierarchy. This lets you avoid copying code, and lets you change things much more easily than in a straight C environment.
In a previous project, I was building the skeleton for a program that would have to be rewritten for many different purposes. Some parts would stay the same between instances, and these were what I was building. I made the mistake of writing it in C, with the idea of upgrading it to C++ later. I ended up faking OO-isms by calling function pointers hither and yon to abstract things. When maintenance of the project was finally turned over to someone else, they started the migration to C++.
In a complex program where you have a lot of abstraction going on between different types of component, an explicitly OO language will almost always make life much easier.
The reason why I learned OOP is pretty much that I had to. I'm at the University of Oslo in Norway, and OOP was invented here and implemented in SIMULA. So they really forced us to use SIMULA and program OO, but in just a couple of basic courses, so I didn't a prolonged forced exposure.
Examples where OO concepts are clear include SIMULA and the S system (my favorite implementation R). SIMULA is a full-blown OOP system (but there are various reasons why it failed), while S has just a few OO features, but the features that have been implemented are easy to understand, they incorporate some essential concepts, and they are very powerful.
Then, you have C++ which is also a full featured language, but where the concepts are not that clear and easy to grasp.
When OO gets muddy is usually when it is built on the top of existing languages. Perl OO is a bit muddy, but not too bad, but if you look at e.g. IDL it gets rather bad IMHO.
Employee of Inrupt, Project Release Manager and Community Manager for Solid
I started out in C, but converted to C++ when it became clear there would be a serious advantage for that particular code.
Looking at the header file, I see that I ended up with a class SampleInfo that contained basic info like the sampling rate and a dozen other items of interest. This basic type was useful as a parameter to constructors and converters throughout the package.
Then there was a class HeaderInfo, which inherited from SampleInfo. It added information such as whether the data was a stream of bytes, complex numbers, or in phase-magnitude form.
Using that starting point, several other classes inherited from HeaderInfo to add still more specialization: VectorHeaderInfo (information about an array of arrays of samples) plus associated implementation classes: ByteVector (just an array of samples of type byte), ComplexVector, ComplexVectorOfVectors, etc.
The class hierarchy and associated inheritance doesn't sound especially impressive, but it immediately cleaned up the code and made it easier to experiment and easier to find certain kinds of conceptual bugs.
Actual transformations were made easy by always returning a pointer to 'this', so a typical usage would look like:
This style of pipelining data through transformation stages makes experimentation a breeze...just insert/delete pipeline stages.
Even design of core algorithms like fft() itself benefited somewhat from reimplementation in C++, although the benefit there was a little smaller.
Basically the added value of OO is small (but non-zero) if you look at converting just one function implementing a single numeric technique, but becomes larger and larger as you implement a family of related techniques, such as matrix arithmetic, multiple transforms, diff eq techniques, etc.
P.S. the biggest optimization advantage for using Fortran is on things like vector processors. And in any case, the right way to optimize is to re-code only inner loops. Thus one could have a package written mostly in C++, but with inner loops recoded in Fortran, if necessary.
Coding whole apps in Fortran is neolithic.
Professional Wild-Eyed Visionary
You wrote:
...
...
... ignore the fact that I used a template ( angle brackets got stripped by the formatter :-( )of course ...
... read: "Design Patterns", Elements of Reuseable Design, Gamma et al., Addison Wesley, 1995.
squarepipe.calculateFlowrate
seems no easier to remember than
squarePipe_CalculateFlowRate()
or
CalculateFlowrate(SQUAREPIPE,...)
Also, if you have generic functions across all classes, you are left with a bizarre model of pipes, bowls, steam generators, and anything else having to be under some umbrella so you can attach a "SurfaceArea" or "Volume" calculator or some other generic routine.
Well and what about this:
// I don't know if you use square pipes
// or round pipes
// or oval pipes
calcTotalFlowRate(Array_of_Pipe* pipe) {
double sum = 0;
for (int i=0; i leth_than pipe.length; i++) {
sum += pipe[i].calculateFlowRate();
}
You wrote:
I've also never been a big believer of the whole "code-reuse" argument.
I say:
Then write my above loop in C
For the problem you are bringing up: adding later a SurfaceArea calculation, OO is exactly THE solution.
And if you are to tired to modify all classes where a calcSurface method would be needed write a Visitor. OOPS, thats a design pattern
Regards,
angel'o'sphere
Cost free eBook I read (by iBook/Kobo/Amazon/ObookO/Gutenberg etc.): "The Green Odyssey" by Philip Jose Farmer.
OOP requires a different organizational view of the problem you're working with. I've seen a tiny few people coming out of college who appear to have been introduced to the necessary concepts in college. For old school programmers or people whose degree program was still geared toward 1970s era, there's going to be a learning curve. Moreover you can't just go off on your own and start programming in C++ or Java willy nilly. You'll just reinforce bad habits while not developing any good ones. A year in a shop with good solid programmers who are willing to mentor you would probably give you a pretty good feel for what works and what doesn't. Assuming you're willing to really study the dicipline.
One of the first things your mentors will probably tell you to do is go out and get a few books. Design Patterns, Antipatterns and Refactoring books make good introductory reading. None of these things are magic bullets either, and you should refrain from viewing them a such. If you don't have Programmer Nature, none of that stuff will help you.
After all that you'll be able to write code that should be easily maintainable and flexible for new problems. Whether or not that will actually solve the problems you want solved is another question entirely.
I'm trying to teach myself to set people on fire with my mind... Is it hot in here?
The first OOP system I ever used was Digitalk's Smalltalk V, a quite successful adaptation of the ur-OO language to DOS, and later to 16-bit Windows. I was impressed by its power and expressiveness -- and frustrated by the difficulty of dealing with the huge mass of new concepts. It would have been much easier if there were a clear distinction between things I needed to know in order to extend the framework, and things I needed to know in order to create applications.
Anyone interested in OOP should download one of the many Smalltalk implementations available just to play with it. But there's a limit to the serious work you can do. There are still Smalltalk developers out there, but most people just don't have the mindset.
Modern OOP systems are mainly extensions of procedural programming languages. This disgusts OOP purists, but makes for a more shallow learning curve, and helps sharpen the distinction between features for designing objects, and features for using them.
C++ is the fanciest of these. But it's extremely complex, and should be approched slowly, if at all. C++ enthusiasts never seem to tire of finding new and obscure idioms to invent.
There are lots of OOP languages out there, but I think two recommend themselves to the newbie -- especially the newbie who wants to actually makes things. There's Java, which no longer seems likely to change the world, but is still a dominant force in some applications.
And there's Object Pascal, which outsiders consider an antiquated curiousity, but which is considered a powerful and highly usable tool by its rabid fans. OP compiles very quickly, which makes it particularly useful for RAD tools.
Which brings me to the commercial: I help document the two big Object Pascal RAD tools, Delphi (Windows), and Kylix (Linux). Both are extremely accessible to the OOP newbie, while having all the power and expressiveness of a serious OOP system. And both have versions you can download for free.
Some people down the hall do a similar tool for Java. I hear its pretty good.
At it's most primitive layer, OOP is a coding thing, a syntactic sugar as so many professors like to say. A way to keep code clean. It's quite nice in that capacity, I don't mind writing "c = a + b;" and under the covers mpz_add is getting called and adding the arbitrary precision number a to the arbitrary precision number b and storing the out put in c. This isn't true OOP, I only include it becuase it's the OOPLs that have made it popularly available.
The next level is encapsulation and reuse. It's pretty damn nice to be able to write "d = {}" in python and create a hashtable dictionary. I do that is literally dozens of python programs. I could easily produce the same thing with list primitives or vectors and what have you and I might even be able to make it better for my particular use but for the most part the dictionary object in python or any of the STL objects are insanely useful, they are easy to use, quick and they are building blocks you can use to build bigger programs. You're already using this kind of code whether you know it or now, the C library is the same thing, it doesn't have the same syntactic sugar though and the things it does are generally more simple where some of these objects are higher level components. I wouldn't call the C library object oriented, per se, but might call a component that does the job of half a dozen C library calls an object.
The final layer of OOP as I see it is modeling. Again it's not well defined outside of a few circles and even then Grady Booch and Bertrand Meyer and the other gurus spend countless hours and books bickering about it. The modeling part is how we break a problem down and implement a solution for it. This I would say is a universal area where OOP has won and will continue to. When programs reach certain sizes, the human mind can really only deal with the complexity by building heirarchies and mapping the problems to solvable isomorphs and then trying to reuse ideas as you move through the heirarchies. If you're trying to multiply a few matrices and then hit them with the Gauss stick to tell if the bridge is going to work, it's probably not a good example of a problem to model that way. A GUI on the other hand is a perfect example where you can have a very clean hierarchy of windows of different types with different functions that behave differently. In my experience, I haven't seen any large scale projects started in the last 15 years that weren't object modeled, even if they were implemented in C or some other non-OOPL, I have seen a fair amount of code from the 1960s and 1970s that was very very complex because it didn't have any real object modeling. The linux kernel has a fair amount of object modeling in it, there are abstract block devices and character devices and they can all be treated the same way, buffering is an abstract concept regardless of the device. Even functionally implemented programs have some degree of object modeling in them.
Now what kind of OOP are you looking for? If you're looking for some kind of advanced object model with reflection and a complex object hierarchy, then maybe it's not being used to solve some engineering problems, it takes a certain size problem before that kind of effort really pays off in the implementation. If you're looking for code reuse then there are numerics packages and probably tons of other packages the will do that.
I have been on projects that insist on OO for there engineering projects. its good for reuse within THAT project, but thats about it.
Very few people can write good OO. but even the good ones often end up with too much indirection, which can seriously hurt a "low level" program.
Each project had specific needs for that chip set, or product, so anything but the most basic needs wasn't reusable without more tweaking.
Compilers are pretty darn good these days, so thing that use to be a selling point for OO aren't anymore.
In my real world experience, there is nothing OO can give you, that good coding practices don't.
The main advantge thats bandied about these days is re-use, but That can be done with a function just as easily.
The Kruger Dunning explains most post on
I've been doing java and C++ programming. Your experience with simula holds true for them too : very rarely do language issues make much of a difference in terms of difficulty of an OO design. (although they surface occasionally) You usually face language limitations in the coding phase (because, if you're like me, you aren't smart enough to recognize them in the design phase). Or in the maintenance phase, when you realize a section of code could be much more elegant with the help of some language feature not present in the current language.
Jack Valenti and the MPAA are to technology as the Boston strangler is to the woman home alone
Object Oriented Software Construction by Bertand Meyer - don't be put off by examples in Eiffel, this book very thoroughly runs down all the standard OO features and demonstrates/explains why the features are useful. Personally I don't know a lick of Eiffel and have no intention of ever learning it, but found it very easy to follow the examples and map them to my language of choice.
Design Patterns by Gamma et al - This book simply runs through a lot of problems and demonstrates at a nice high level how one might use OO design to solve the problems in elegant ways.
If you read these 2 books, you should 'get' OO programming, and understand where you will and will not reap benefits in using OO techniques.
You've described good OO boundaries in some ways. I've seen good OO and bad OO in the engeering field. I've seen good OO where the stats stuff was written once and everybody used it. I've seen bad OO where stats were rewritten all over the place by people of different skill levels.
Stats is just one example of several. We do control systems and have control system base classes that allow us to model the control system by breaking it up into a measurement side and a control side and treating things generically. It works very well.
As you gain a wider experience, you'll find that most systems can be modeled with a good set of abstract concepts. We've found it has helped up tremendously. For example, when we write a new control system, generally all we need to do is to write measurement and control objects for the hardware that we don't already have these objects for and then write some custom plumbing code to tie all the objects together to match the wiring of the actual system (well, more or less, but that gives the right flavor). We don't have to write PID controllers each time, or simple alignment operations or any of the more complex data filtering algorithms we use to keep the control systems stable.
Yes, I know I'm being a little vague, but to fully describe things would take more space than is appropriate for this forum. Then again, the question was kinda vague...
C
if you know C, your learning curve on everything else will be much smaller.
I presume you'll be using some sort of CAD in your work, find out if any of the CAD program support plug-ins, or features you can write your self. that learn the language it supports. Thats a good career move, even if you have to learn basic!
The Kruger Dunning explains most post on
I think the answer to your question is cultural. We all know many OO
weenies who have spent years improving their programming. They have
jobs, and build useful applications sometimes, but I think the thing
that really motivates these people (hey, I'm one of them), is the goal
of becoming a better programmer, and writing ever more beautiful code.
I think that folks working on engineering problems spend similar
amounts of time trying to solve the real-world problem.
From my own educational background, (undergrad, grad school, faculty
member before joining the real world), I observe that the split between
these two approaches to software occurs pretty early. People who focus on the
advanced numeric stuff spend their time on that. People who focus on
the underlying tools seem to have a better chance of becoming object
weenies.
Can OO help out with (non-software) engineering problems? I'd be
surprised if they couldn't. Personally, I don't know enough about that
set of problems to offer an opinion. I think the reason that OO isn't
used more in mechanical engineering (for example) is that there are
many more people like me who specialize in one or the other, and very
few people broad enough to have enough of an understanding of both
worlds to know how they can be combined.
It's an industrial boiler design system in which each meaningful component is modelled as an object.. Then these objects are parts of subsystems of the boiler, and the subsystems all comprise the boiler itself..
I put in a bunch of data files read by the loader object, and used to set the parameters of the internal objects.. Then I simply look at boiler.getEfficiency(), and the necessary computations in all the subjugate objects are done, and there it is..
OOP is more about the architecture of your program and about the way you concieve of the data.. If you think of it as ripping through tables of numbers, you'll at best have a procedural, iterative solution that uses arrays or structs..
If you extend the concept of a struct to be an analogue of a 'thing', and then tell the 'thing' to solve for some attribute of itself based on other internal, and external, factors, you're thinking in OO.
That's all there is to it, in a nutshell.
The REAL jabber has the user id: 13196
What you do today will cost you a day of your life
Think of it this way, a C++ class is basically a C structure on steroids. Functions in the class are like pointers to functions in a structure. Both can do signals and callbacks. The difference is that one was made to make doing OOP easier (C++).
Ada is another option for OOP programming as well as Java.
Do you think that mathcad is all C? I'd imagine that it contains C++ and possibly com objects and it is an engineering program. I'm sure there are others, in fact I remember when I used to read spectrum magazine from IEEE they had adds for many engineering programs and some of the newer ones were in C++.
I think it is your application probably does not call for it.
Only 'flamers' flame!
First of all, for those individuals who refer to C++ as an OO language, please stop. You're wrong. C++ can be used for an OO project, but it is a multi-paradigm language. At least that's what Bjarne Stroustrup calls it. But what does he know about C++?
Second, use of C++'s STL does not equate to OO programming. It is an example of generic programming. Here's a hint: the STL has very little inheritance except for iterators and iostreams -- most evaluation is handled at compile-time. And even iterators and iostreams are just as much generic as OO.
Finally, please dispel the rumor that C is automatically faster than C++ because of C++'s excessive overhead. Need proof? Please read this article about treating C++ as its own language and not a variation of C. Yes, it's a PDF. Get over it.
Think the article is FUD? Prove it! Take the examples from the article and tune them better than he did. Compile them with trusty ol' gcc and g++ on your box. Measure the results. After you do so, can show that C is faster, does not contain any potential buffer-overflow bugs, handles error conditions, and wasn't at least five times more code to do it, then reply back with your results. I have a feeling I won't be getting any replies from people who actually try it.
That said, use whatever language you like best. Studies have shown that people will always perform better in languages they know intimately well than languages in which they have a general familiarity.
But if you want to use OO and C++, check out this numeric library
Have a nice day
- I don't need to go outside, my CRT tan'll do me just fine.
It's called NPSS and it stands for Numerical Propulsion System Simulation. The basic idea behind it is to be able to build a simulation of a jet engine by linking together different objects (fan, compressor, burner, turbine, nozzle, etc) whose properties you can change (fan area, burner temp, fuel flow), in order to theoretically model any engine you want.
I played with it some, and it's very cool. My BS is in Mechanical Engineering, and they didn't start letting engineering students take C/C++ until the year after I started, so I know the FORTRAN woes you suffer.
The thing is that for years engineers have had to use FORTRAN to do stuff it shouldn't really be doing, so they've gotten into habits of trying to think of problems as more complex than they really are, just because the programming language they have to use is unsuited to the problems.
Anyway, NASA has been at it for a few years, and they've done a great job (IMHO) at implementing OO for what they're doing. Using the software to build and simulate an engine is incredibly easy, and you can simulate all kinds of manuevers and engine configurations really fast.
-ristoril
OK folks, how about object-oriented NASTRAN? Anybody out there agreeing yet? This is hardcore structural analysis, and a major pain for years because of its initial programming architecture.
Lockheed-Martin is using a generalized data handling/simulation library called GEMD. It's object-oriented data complemented by an object-oriented, high performance C library. It's powerful enough for F-16 or F-22 simulation, and conveniant for simple one-hour problems. It is a standard for much of the engineering staff.
Are spreadsheets great engineering tools or what? I've done propeller design with a spreadsheet. At the interface, there are lots of objects. I'm sure spreadsheets are best programmed with object principles in mind.
Engineering is a very real-world endeveor. You can argue that engineers use mathematical abstractions in their work, and I would argue that even mathematical abstractions can be regarded as objects in a programming implementation. And I would also argue that most engineers are held to much higher standards of accountability if their software fails. And that goes for accident and incident analysis, too.
Anything that improves production, use, testability, maintenance of software in engineering is well worth learning and using well.
It seems you have convinced yourself that the world should be modeled in terms of procedures. This is typical for people who have programmed using procedural languages. The same happens to people who program OO: they see classes everywhere. Then you have people who like functional languages: suddenly everything seems a function.
The sad part is that all these paradigms have problems where they can be applied very well and none of them can be applied to all problems well.
Now back to OO. What is it good for: it's a good way to structure complex systems. If you have a complex system, you can probably make its structure more explicit by using objects, design patterns and so on.
Mind you, it is no silver bullet and you wouldn't be the first one to build a super complex, flexible OO everything system that doesn't perform well and is impossible to maintain.
Symptoms that indicate you might benefit from OO:
- There's a lot of commonalities between the programs you write: this indicates that you can generalize functionality.
- There's a lot of dependencies between your modules: you need to encapsulate and hide stuff
- You have a lot of complex data structures and lots of functionality around those data structures: hmm objects???
If you are serious about adopting OO you should spent some time with books about OO design such as for example Gammma's excellent book about design patterns.
As for your question regarding engineering problems. I have worked with companies involved in building embedded stuff like fire alarms, haemo dialysis machines (medical machines), mobile phones, digital radio systems and embedded server products. All of them use OO based designs to their advantage so it can be done. And in case you are wondering: all of these systems were very large systems (500 KLOC - 5 MLOC). Using OO is a necessity for these companies since it is the only tool they have to keep complexity under control.
Jilles
I haven't worked _on_ this project but I did work with it a little bit, and tried to write a small analysis routine for a class I took. Check out the OpenSEES Project at Berkeley for a good example of a OOP solution to an engineering problem. Every portion of the analysis, from equation solvers and matrix routines to structural elements and material models are broken into objects. It's an ambitious project but it's moving quickly. And it's even open source!
As many other people have pointed out, it's not so much the type of problem that matters for whether or not you choose OO technologies.
If you are by yourself, writing a small single-purpose, one-shot, low-state program that requires maximum performance, then by all means write in some procedural language.
If you are working with a large, distributed team, writing a large, complex, high-state program where performance takes a back seat to flexibility, evolvability, and maintainability, then choosing the right OO language can help a lot.
And if you're somewhere in between, the choice depends a lot on your circumstances.
But if you do pick an OO language, please take it seriously and really learn how to do OO design well. I saw a team write a million-line procedural program in Java, entirely missing the point of using Java in the first place. They would have been better off using the Visual Basic they knew and loved. Or they would have been better off going whole hog and actually writing OO code in Java. But their Procedurized OOP killed them.
Switching from a procedural style of design to an OO style of design will take you a couple of years before you're as good in OO as you were in your favorite procedural language. To get a good start, rummage around in Ward Cunningham's Wiki. And check out books like Martin Fowler's "Refactoring". Also consider using something like JUnit or CppUnit and the XP-style test-first programming, which will speed your learning considerably.
And regardless of what you pick, good luck!
Some of these will be applicable to managing your algorithyms or making your software more flexible.
Am I just being close minded to the ideas of OOP or do my problems just require 'procedural' solutions, which are better solved using procedural techniques?
It is possible that your key algorythyms will remain lumps of procedural code, OO languages allow this. There is advantage in an application of any size in the judicious use of OO techniques.
My Karma: ran over your Dogma
StrawberryFrog
> I appreciate the concepts of OOP and see its applicability in managing records
2 89482,sid13_tax284872,00.html -- there are also some interesting articles at http://dmoz.org/Computers/Software/Databases/Relat ional/ and subdirectories, including an early version of the Third Manifesto.
Then unfortunately you haven't quite understood neither OOP, nor databases -- and databases are essential to many kinds of programming, including engineering.
Please read http://www.firstsql.com/dbdebunk/, as well as Fabian Pascal's articles at http://searchdatabase.techtarget.com/tipsIndex/0,
Leandro Guimarães Faria Corcete DUTRA
DA, DBA, SysAdmin, Data Modeller
GNU Project, Debian GNU/Lin
Haskell is an often overlooked yet interesting and powerful procedural language. I've used it for some engineering math and also implemented an ARM processor VM with it for a class. Just thought I'd mention it :)
Use the Z-modem protocol between Information Superhighway routers to compress the plaintext. ~LordOfYourPants
While OOP has some advantages in a traditional setting, where it really shines is when you use OOA/D (OO Analysis and Design) as well. If you do a traditional functional analysis and design, then you get a procedurally oriented design. Any OOP benefits you get out of that will be minimal.
However, if you do OOA/D, then you come up with an object-based design, and at that point using OOP really helps a lot.
The question then becomes one of how do you want to perform your requirements analysis. If your requirements are strictly functional, then you don't get much benefit.
On the other hand, even with a functional design, you can still benefit from some features of OOP (the Pipe/SquarePipe/RoundPipe examples above come to mind).
As several people have mentioned, if you can factor your problem and find the commonalities (remembering to distinguish IS-A relationships from HAS-A relationships), you may be able to take some advantage.
Many of the problems you mention (Monte Carlo simulation of XXX, finite difference solutions to DiffEqs, etc...) are at too low a level to use OOP. If you look at them, they're really more a means than an end in and of themselves. The question you need to look at is, "What am I using these low-level 'primitives' to do? What is the big picture?"
For example, you mention radiative heat transfer. Maybe you're designing an engine. You could put the (procedurally oriented) radiative heat transfer routines inside the Radiator object (note, I have no background in engineering -- I'm guessing...), and use it that way in an OO manner.
However, in the end, it all comes down to your analysis and design.
Incidentally, there's one more thing to consider: IF IT AIN'T BROKE, DON'T FIX IT! I know that engineers have tons and tons of debugged, working FORTRAN code. If you use that, you don't have to worry about the typo you made in re-implementing the FFT.... Always a consideration.
Fascism starts when the efficiency of the government becomes more important than the rights of the people.
Question: What programming language will engineers be using in 20 years?
Answer: I don't know, but they will call it Fortran.
(That joke is funnier if you were around when Fortran 8X, er 90, came into being.)
"Rub her feet." -- L.L.
There is an interesting (and rather negative) review about OOP here (OOP Criticism [geocities.com]).
OOP is by no means a magic solution to programming problems.
The criticism page brought up some areas that OOP has alledged weaknesses. Many of these are highly contrived. One of these examples is the issue of mapping OOP to databases, and in particular the widely used relational database model. The problem with this particular analysis is that the mismatch occurs not due to problems in OOP, but rather with the limitations associated with mapping many types of data structures to the RDBMS model. One can hardly criticize OOP becasue it maps poorly with a technology that is far more limited than OOP is. The problem is with the RDBMS model, not OOP.
Other objections, such as data mapping from one OOP language to another are equally contrived. Already we have methodologies gaining widespread acceptance that actually do this.
The idea that OOP will fall out of favor in 15 years or so seems rather outlandish. OOP has been around for a LONG time already (LISP dates back to the mid '50s.). OOP's record of utility is well established. It's very hard to claim with a straight face that something is a fad when it in fact has been gaining acceptance and wider use over a 50 year period, spanning essentially the total time period of the development of the practice of programming.
It is true that OOP is not a magic solution to ALL programming problems. I would not use OOP in coding an FFT algorithm. However not having OOP in your toolbox markedly reduces the number of programming problems that you can map to working code in a clean, logical manner.
Operator overloading is just syntactic sugar, it has nothing to do with object-oriented development. There are a number of non-OO languages that implement this feature. I dislike most uses of operator overloading anyways. Sure, it may "look cleaner" for the above trivial examples, but with multiple overloads and implicit casts, it can be difficult to figure out which function ends up being called. Better to keep things as explicit as you can.
The definitive benefit of object oriented languages is caller-reuse as implemented through polymorphism. In procedural programming, I can reuse called code (a.k.a. functions), but in OO programing I can reuse *caller* code. The shapes example is great to illustrate this: if squares and circles both inheret from a base shape, who implements a "draw" function, I can easily add triangles later, pass them around as references to the base class "shape", and any code that asks a shape to draw it self remains untouched, whereas in procedural programming I have to touch each instance of code that has to do with drawing, and account for the newly added triangle case.
Invisible Agent
This post is a mirror; when a monkey stares in, no hacker gazes out.
I used to write financial software in C++. We has objects for Interest Rates that handled conversions to and from various types (Annualized, Continuous, Bond Equivalent Yield, etc) and could work as normal double floating point values. We had a class hierarchy for option evaluation functions. At the base a parent class had the features common to all options and their evaluation formulas. Children classes then implmented specific evaluation formulas. Sometimes tweaks were needed to those formulas for specific situations and another level of inheritance was used. We found that the OO C++ code was much easier to maintain and add on to then the previous functional C version.
As other posters have said, to really use OO you have to break the problem down into objects. What are the features of these objects? What do they do? How do they interact? Another good idea is to see what certain objects have in common. This allows you push these common features and functions into a parent class that both objects inherit from.
-- soldack
This may be useful in the broader perspective of applying OOP to real life. Their are plenty of papers up on the IBM site that are worthwhile, even if searching for them could be inconvenient.
"It is a greater offense to steal men's labor, than their clothes"
-- ;-)
Kuro5hin.org: where the good times never end.
http://www.cs.nott.ac.uk/~gmh//faq.html#functional -languages
Sorry, but I think that's a bad example. Using an OO design has gained nothing over a simple function or two here, but has probably generated much more clutter as a result.
If I dared propose a more appropriate example in a similar vein, one thing OO is quite good at is providing and working with a representation for complicated and interrelated data items, such as a mathematical expression. Suppose I'm writing a mathematical tool to process these. I will represent an expression as an object of type Expression. Subtypes of that might be ConstantExpression (representing a numeric constant, say 2 or e), AdditionExpression (representing a+b, where a and b are themselves Expressions), etc.
Now I have a clear structure for representing these, I can parse whatever input I have into this format, and work with it. Need to display it using pretty graphics? No problem, add a Display() method to Expression's interface, and provide a suitable implementation for each subtype. Need to evaluate the expression? Eval(), here we come.
So far, so good. You've used OO to provide a nice representation of a problem, at least as clearly as a procedural solution would have done. It's pretty much a draw so far, and a matter of personal preference which style you prefer.
However, the OO framework is much more easily extensible than its procedural counterpart. You can add new subtypes of Expression, and have them immediately fit into your existing framework, without changing any of your existing code (or even having access to it, for that matter). To do this procedurally, you often wind up writing some clever switching logic, but OO does it all for you behind the scenes.
It's also easier for the outside world to work with your code, because you can provide nice, clean interfaces, such that all Expressions look the same to the outside world, however they are composed.
Finally, this approach helps organise your code. If all your types of Expression provide an Eval() interface, the implementation of that interface is in a known place, and probably quite straightforward for each subtype. This maintains a degree of clarity that is easily lost when you don't have the organisational framework an OO design supports.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
I agree with most of what you wrote, but I think bundling C++ templates in as "fluff" is grossly unfair. Templates are responsible for a lot of the good things about C++, and many of those aren't necessarily OO at all. The ability to write generic algorithms, but also specialise them for cases where's it's useful, is a godsend to those writing mathematical functions. The use of expression templates to generate highly optimised code with no programmer effort means C++ programs can now equal or beat the sort of code produced by a decent FORTRAN compiler. And, of course, the use of class templates means you can define generic mathematical structures such as matrices over any type you like, which makes such structures far more useful than vanilla OO designs would allow. Finally, there is the use of templates to provide traits classes, policy classes, and other tools of general use. None of these things is "fluff" if you're trying to develop a serious application!
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
From the web page you referred to:
Functional programming is a style of programming that emphasizes the evaluation of expressions, rather than execution of commands. The expressions in these language are formed by using functions to combine basic values. A functional language is a language that supports and encourages programming in a functional style.
Hmm...
So, given this definition, a functional programming language is one that uses canned or prewritten functions to evaluate expressions on a higher abstraction level than "procedural" languages such as C.
These "functional languages", you mention, appear to have alot in common with spreadsheet style functional representations... I might have to take a closer look at them... Thank You.
Codifex Maximus ~ In search of... a shorter sig.
This actually made Ask Slashdot? Why?
One strength I've seen with OO isn't in the pure programming realm, but more in the business realm. You build objects based on the domain you are working in, whether that's banking, accounting, games, whatever. The terms you use, and how the high level objects fit together and interact can be more closely aligned to the domain you are working with, compared to procedural languages. This allows a developer to more easily verify that what they are developing is actually what is needed (easier to check against the domain), and also allows non-techies to look at the object model and be able to understand what's going on (again, because it's modeled directly to the domain, in the terminology of that domain).
There's lots of other good things about OO (which others have already pointed out), but this one strength is something I've seen work on several projects. Many of these other strengths are in more of the pure technical realm, but the business-oriented strength is one that can be overlooked, but is still important
go to www.dromeydesign.com
our main product "DESS"
is all Object oriented
where we model entire power systems in an oo model
However, if you're looking for flat out performance, even these kinds of simulation systems are still better done in FORTRAN. It's just that unlike fluid dynamics models, the models in most DTS's change over the lifetime of the program (just as the core algorithms don't), so maintainability is more of an issue.
That is all.
If OOP seems like overkill for small and specific engineering problems but you're facing the problem of maintaining and enhancing a large procedural code base, then there's a nice solution.
One of the most efficient ways of tackling this kind of problem is to keep your existing investment in procedural code but wrap it using a scripting language - preferably something like Python. Python has enough classical OO built in to keep your front end clean and maintainable but interfaces easily to programs written in C or C++. There are also tools to do this wrapping automatically for you. Your engineering data and equations will just look like normal Python objects but of course run at the same speed - minus a small amount of call overhead.
Example: after experimenting with Ken Perlin's source code for the 1, 2 and 3d noise which now bears his name, I found that the code was becoming hard to maintain and enhance without changing bits all over the place. Messy. Rewriting it all in Python or C++ would have been a pain because it was optimised C with lots of inline Asm. The solution was to keep the existing code base doing what it did best - calculating perlin noise functions at full speed - and just create a Python wrapper for the interface functions. In the end I got the best of both worlds - Python kept the frontend testbed clean and easy to maintain, the back-end code was unchanged. Time taken to convert the lib - a couple of hours reading the Extending and Embedding part of the Python manual.
Try it - you might like it. I don't know if Python talks to Fortran though.
--- Hot Shot City is particularly good.
One of the most common misconceptions in the industry is that C++ is 'an OOP language.' For that matter, it is similiarly incorrect to label C a procedural language. Paradigms like Object Oriented or Procedural are exactly that
The first C++ compilers were merely front ends for C ones, which took C++ constructs and generated C code, which was then compiled and linked into an executable. It is true that C++ was developed to assist in making OOP constructs with clarity and ease (let's not argue the success or lack therof here, please.) Still, nothing stops one from OOP modelling in Assembly Language and procedural was always openly supported by Bjarne Stroustrup when he invented C++.
You call the problem on the head when you say "I cannot, however, convince myself that there is a clean way to use these concepts to solve the type of procedural problems that I have encountered in the past." When your problems lend themselves to procedural solutions then you want to think about them that way, just as when your problems lend themselves to Object Oriented models, you want to model them that way.
The right tool for the right job. If you want to implemet a Fast Fourier Transform you want to look at it procedurally. If you want to model a Robot, in which thousands of components performing those FFTs interact, you probably want to take your procedural code, wrap it in some Object Oriented code, and get your model.
OOP and Procedural are complementary analytical methods, not competitors. It is an abuse on the part of any software engineer to view or discuss them otherwise!
Guns don't kill people; Physics kills people! - John Lithgow as Dick Solomon on Third Rock From The Sun
"Let's just say you'll have a hard time finding a senior engineer who knows C++, and an equally hard time finding one who doesn't know ForTran. And, often, the senior engineers are among your better resources."
Well-phrased. Yes, older engineers (and scientists) are better versed in FORTRAN. Of course, by "FORTRAN" we really mean that these folks know FORTRAN 77, and you have to ask yourself--do you really want to begin any new coding project in a language as primitive as F77? It's a bit like saying: "we're going to code in BASIC, because that's what the staff knows." Sure, you gain in developer training, but you lose many times more in code management, reuse and maintenance. And what about newer FORTRANs, like F90? Well, if you're going to retrain on that rats-nest of a language, you might as well just stick with the industry-standard rats-nest, and use C++. For an F77 programmer, the learning curve will be the same.
Another funny thing is, most truly senior engineers and scientists aren't the ones writing code anymore. So it becomes even more absurd to suggest that new code should be developed in a language they understand. Indeed, develop in a language the new engineers know, because they're the ones who will be maintaining it well after Dr. Cranky is eating tapioca in the nursing home, babbling on about COMMON blocks, hollerith strings, and how "back in the good old days, all we had was GOTO, and dammit, we LIKED it!"
Let's try not to let fact interfere with our speculation here, OK?
To carry on your car analogy -- yes, OOP is good for modeling the interactions between cars, but first you have to model _one_ car. And this, depending on the level of detail you are looking for, may be simultaneously too simple and too calculation-intensive to fit well into a general purpose OO language. (Simula is a special case -- since it has the required math built-in, it might be competitive.)
To get to something like the problems he was concerned with, let's say you drill down until you need a complete simulation of the air/fuel mixture flow through the intake manifold. "Objects" are irrelevant at this point, all you are concerned with now are many little chunks of gas ("cells"), represented by numbers in a big multi-dimensional array, and related by a massive set of partial differential equations. There are going to be billions or even trillions of floating point operations, taking minutes to hours to complete no matter how efficiently programmed.
You need a language in which you can easily input those equations, and which will very, very quickly go through all the calculations on each cell in that array. FORTRAN excels at this sort of calculation, basically because the language is so unsophisticated that the compiler can do great optimizations. The one issue is that FORTRAN natively understands only basic algebra. The calculus and the process of turning a continuous set of equations into discrete cells of air and steps in time has to be programmed in; there are libraries you can call, but you've got to understand how to pick the right library function and to translate the problem for it.
The second choice is to go to a specialized simulation language like Simula, where the compiler understands discrete integration operations, so you feed in the equations and the geometry and it picks a method of solving it. It might not be the best method, but there's a pretty good chance you'll get usable results without doing a whole lot of work yourself. It's unlikely to run anywhere near as fast as a properly tuned FORTRAN program, but you'll usually get the first-run results much quicker than the FORTRAN could be written. But if you need to try 10,00 different configurations, and FORTRAN runs each one in 2 minutes while other languages take 3 or 4 minutes each...
One way of looking at software engineering divides it into levels of abstraction at which people work. In the traditional view, engineering proceeded by starting at the highest level and proceeding in a orderly manner towards code. We're coming to realise that approach is wrong, but the levels of abstraction still exist. You can use OO at all these levels, by modelling things in terms of classes.
At the highest level, often called analysis, classes, objects and the relationships between them should correspond to concepts in the problem domain. Implementation issues should not come into it. An analysis model should end up representing the system as the user thinks about it.
At the code level, objects are indeed methods combined with data, but while the analysis model won't have captured all, or even most, of the code you end up writing, the concepts in it should still be present in the code.
People still teach that ? I give OO training courses, and we mock that stuff mercilessly. Thats just a (bad) way of doing analysis. If you try to go straight from that to code, you'll end up with a poor, naive implementation, probably with all the "real work" done by one method and all the OO superstructure looking like useless fussiness. Its that kind of thing puts people off OO.
But there's a bit more to it than that. OO is just a way of acheiving well designed software. It has its failings, but its the best I know of. So what does it mean for software to be well designed ? Well (and this goes back much further than OO), it should consist of loosely coupled components, each of which is highly cohesive internally. Each component should hide a small group of closely related design decisions (ideally one) so that the rest of the system can be built independent of its details.
In the end, OO is not about being able to write better algorithms, but about how long your software will last, of how much value it will be to its users, and how much grief it will cause its maintainers. These are principally concerns in commercial environments (where value==price and hassle==cost), but they're relevant everywhere software is written and used more than once.
Now, looking at your problems and your question, here are some random thoughts. I'll be the first to admit to not having the faintest idea what most of those problems are, so some of this is about the peripheral aspects.
Firstly, all OO language in common use are procedural. The opposite of procedural is declarative, but there are very few declarative languages and they are principally of academic interest. In the end, code in OO languages is just like code in C, Pascal or Fortran.
So, thinking about your algorithms: does the algorithm always operate on the same domain ? For instance, do your fluid dynamics always model fluids ? or might it be modelling some complex economic system ? If so, you can split the domain off from the algorithm uding the techniques off OO, by representing it as a set of abstract classes or interfaces. Of course, this is only of interest if the algorithm is part of a larger system with some purpose, and not just an academic toy.
Similarly, are there several algorithms for solving a problem ? or can the algorithm be tuned differently. I know this is the case with some stochastic methods (I used to work on a system that used simulated annealing for place and route - in Smalltalk). In these cases the abstract properties of the algorithm can be encapsulated in an abstract base class, and concrete specialisations used to offer a choise of implementations.
I hope that helps somewhat. Just one thing to bare in mind: beware of C++. Java is unnfortunately inappropriate for heavy numerical lifting, but C++ contains many pitfalls for the unwary. Its worth learning a more rigorously OO language - like Java - and then going back to C++.
Encapsulation is only half the story. To get any benefit from OO, polymorphism is essential. Encapsulation does indeed get you nice organisation by itself, but you don't get any improvement of flexibility. With polymorphism added, you gain the vital ability to operate on objects without having to discover their runtime type. This lets you write, for instance, a catalogue system that can operate on video tapes or books, without having to have any knowledge of what exactly its working on.
Perhaps I can help. A few years ago, I ran a team to write a large scientific visualization program called SciAn, which was all object-oriented. We did stuff like this. Although most of the time the calculation was saved in a file that we read, we also did calculations within it, sometimes using distributed objects.
One problem you may have been having is that nearly all O-O books are crappy and ignore the real power of objects. Here's a heuristic: when a book talks more about "classes" than it does about "objects," throw it away. Vigorously. Anyway, here's how we did it, and you can maybe decide how you could do it.
Take the case of a grid. (Please!) Just to be simple, first let's take 2-D. The points may be connected with edges to form either a non-structured grid or a structured grid. A non-structured grid may be triangular, such a grid may also be a Delauney triangulation. Or it may be a structured grid, in which case it might be a rectilinear grid. You might want to have the grid denser near the boundaries, I called these "separable" grids because I couldn't think of a better word. Or the grid might be curvilinear, wrapped around, say, an airfoil.
Immediately, an object structure emerges, fairly cleanly, like this:
Grid
Structured Grid
Curvilinear Grid
Rectilinear Grid
Separable Grid
Regular Grid
Non-Structured Grid
Triangular Grid
Delauney Triangulation
This probably isn't the hierarchy that I used, exactly, because we had a lot more different kinds. We had multiple grids linked together, data in separate objects linked to the grids, N-dimensional grids with M-dimensional data, time-dependence, etc. But you get the idea.
Would you want to use a bunch of little objects to implement your Navier-Stokes calculations or whatever? No, of course not. Put them as methods within the object.
Once you do this, the objects make sense. You might have a method to initialize the data and a method to calculate one step in the calculation. Another method might be used to switch between, say, a simple projection integration and second-order Runge-Kutta. Call setReynoldsNumber(double x) and see what happens. You might have a method to construct another grid that contains the gradients. You might have a method that resamples any grid as a regular grid. You might have a method that constructs a Delauney triangulation of a point cloud. You might construct an M-1-dimensional slice from an M-dimensional grid, or return a snapshot of a time-dependent data set. Different implementations of these methods may live at different points in the hierarchy.
At our height, we supported about 20 different file formats for the most diverse kinds of data you can imagine: HDF files, protein structure files, EEG recordings, particle traces, for meteorology, chemistry, quantum chemistry, economics, high-energy physics, QCD, you name it, and internally, all the datasets were in the same kind of object and behaved largely the same. As a joke, I deformed an EEG brain by a mountain terrain field. It took about five minutes.
Alas, the research institute went defunct, and now I have to spend my time writing financial and HR reports. On the other hand, I make a lot more money.
Beyond this, you can think in terms of having multiple objects interact. Nearly all of the big stuff that we did involved interactions between grid, dataset, and visualization objects, but there were many others. Want to run your simulation with an isothermal top instead of an adiabatic one? Don't rewrite the equation solver. Slap an isothermal cap on one face of your grid; it knows to clamp the temperatures at each time step. Or whatever: invent your own. Once you start thinking of these things in terms of objects, there's a lot that can be done.
The guy who said that your problems are too small and specialized to benefit from O-O actually had a point. I'm not saying that they are, of course. But if your mindset is that once you have an array of values then you're totally done and eveything's known and you just throw it at a postprocessing package called Graduate Student 3.0, collect your Nobel prize and retire, then there won't be much use for O-O programming. Alas, I've worked with a lot of scientists who thought this way. However, if you work on several problems that are both similar and different, a carefully designed (and redesigned when it doesn't work--don't laugh; it happens) object framework can help you put together something synchronistic that builds up over time and really does save work.
Certainly if you don't try to write a system like that, but just use it to get the idea, then its harmless. I was particularly worried that the original poster mentioned it in the context of being taught Java, though. Unless it was a "your first language" course, in which case he probably should not have attended.
One course I teach is basically "OO for beginners", which is intended for new graduate recruits (not CS grads), and for non-engineerings managers. In that, we get over the brain friction with a role playing exercise that involves people first simulating a business sytem by passing bits of paper around, and then simulating the same system as an OO system, with each person playing an object, by passing messages around. After that, they seem to get the idea of objects, messages and most importantly, classes and polymorphism, quite well.
I doubt OO will help with computational efficiency in the problems you mentioned. Where it could help is in the man-hours department. Creating reusable and extensible OO objects can reduce your coding time on any particular problem a great deal.
For example, I am a contributor to the Scythe Statistical Library which is essentially a big matrix object which supports many common operations. Scythe was initially designed by two professors who do a lot of monte carlo simulation. They still write programs that are essentially procedural to do each simulation, but the library greatly reduces the overall coding effort on each project. Other portions of the library (random number generators, numerical optimizers, etc) are as procedural and stand-alone as a standard c library. But matrices are so important that it makes sense to create an object for them. If needed we could create extending objects like triangular matrices, etc with little effort.
In essence, if you can think of some portion of your coding effort that is object-like (a matrix, a polygon, an engine part) and important enough to many different projects, creating an object for it makes sense. This is especially true if you can think of sub-objects which you might use in the future.
I think we need another compiled language with Python's syntax. I started using Python again after using Perl and C++ for a while, and I found it incredibly clean and easy to use. It's just so clean compared to C++.
I'm just going to add another "Dead on" response.
I'm an OOP fanatic myself. OOP is a wonderful tool for most tasks. The article author's tasks however aren't among those.
A good example of his issues is a Mandelbrot program. If you want code to solve a single problem, like rendering a Mandelbrot set, OOP is not going to give you any advantage. The problem is specific to matching a set of input data (the set boundaries) to its corresponding result (the set). If you wrote this using OO, the meat of the software would be a single Mandelbrot object. Everything else would be necessary fluff for display and handling mouse clicks.
However, if you needed something that would render Mandelbrots, Julias, and Recursive Serpentine something-or-others then OOP would be an appropriate tool. The fractal itself is an object and the higher level managing code doesn't need to know anything about the fractal objects except that they are derivatives of a base fractal class and therefore support an intelligent set of generic methods.
My experience with engineering software written in Fortran has been that the program is tightly coupled to one narrowly scoped problem (like the Mandelbrot example) and doesn't lend itself to an OOP implementation.
Education is a better safeguard of liberty than a standing army.
Edward Everett (1794 - 1865)
However this is a man that writes in Fortran 90. And Fortran 90 does contain pointers (very ugly syntax) and OO stuff if he would ever need to use them. (I would complain about the ugliness of his code too, but I know my shit stunk too when the deadline was coming in)
On the other hand I have met a professor that prefered C++ because he had many projects and they all very large. He wanted maximum code reuse and all self contained pieces.
And also it is obvious that classes are extremely valuable for other types of math than basic arithmetic like linear algebra and some abstract algegras.
I myself prefer C for its speed/simplicity/size and always having a compiler. I generally make very ugly use of inlines, macros, and global variables to cut code size down without having classes. For bad example
int e
#define VECTOR(X) for(e=0;e<3;++e) {X;}
(and then unroll the loops) which applies some statement X component wise, so I could add vectors like VECTOR(a[e]+b[e]). Yes, I know it is ugly, but damnit I have had code that took a month on 9 computers and I just didn't have any extra time for the performance hit of C++.
Sure. Here's the quote from An Interview with A. Stepanov:
STL is not object oriented. I think that object orientedness is almost as much of a hoax as Artificial Intelligence. I have yet to see an interesting piece of code that comes from these OO people... I find OOP technically unsound. It attempts to decompose the world in terms of interfaces that vary on a single type. To deal with the real problems you need multisorted algebras - families of interfaces that span multiple types. I find OOP philosophically unsound. It claims that everything is an object. Even if it is true it is not very interesting - saying that everything is an object is saying nothing at all. I find OOP methodologically wrong. It starts with classes. It is as if mathematicians would start with axioms. You do not start with axioms - you start with proofs. Only when you have found a bunch of related proofs, can you come up with axioms. You end with axioms. The same thing is true in programming: you have to start with interesting algorithms. Only when you understand them well, can you come up with an interface that will let them work.
I am originally a mechanical egngineer and have some expereince with finite element/finite difference work . The short answer is that no OO techniques, don't apply to many engineering tasks. I can remeber not that long ago that entering a bookstore or technical bookstore there would be three of so book cases covering 20-40 languages, now there is one bookcase of C/C++, one of java and half a bookcase of other which seems to mean scripting languages more that anything else like Perl,Tck, Ruby etc... . Those 20-40 languages each had a specialty .....
Fortran for math/engineering
C for systems programming
Prolog for expert systems
LISP for AI
Snobol for text processing
Cobol for business
Pascal for learning
Ada for formal systems
etc
Now the answer is always C/C++/Java, C is realitively general purpose, but C++ is generally 20% slower and larger than a equivalent C application. Java is easier, but I find it strange reasoning that garbage collection is prefered, isn't writing your application correctly a better solution than having the computer clean up after you, kinda like a teenager not putting thier dirty underwear in the hamper becasue Mum will do it eventually. Assembly is always going to be fastest, but the hardest to debug/maintain, the OO languages make life easier, but all the abstraction causes significant speed loss and code bloat. I keep on hearing poeple say that code size and effiency don't matter as thier machine is fast enough and memory is cheap, but Intel is selling faster processors because of inefficient code and people are always adding more memory. C++/Java are fine and are the best solution to some problems, just not all problems. The market is contracting to the point that non C++/Java compilers are rare, and the options will not exist. SW people seem to spend an inordinate amount of time debugging and this is the area that would have the biggest payoff, but heavily typed languages haven't seem much sucess in the market. I spent 6 years, working in Occam a parallel processing language, that have very tight rules and was a formal language, such that there was only one possible solution to given code. We always used to say that in 'C' code, if you got your code to compile you were 20% done, and required the next 80% for debug, while Occam compilation was more painful, getting it to compile you were 80% done, that sort of help makes you more productive than anything else. People hated the compiler complaining about seeming insignificant errors, but the compiler was finding mistakes and helping me rather than hoping that I knew what I was doing. This helped me build 80 processor sonar systems in 11 months, well before any beowolf cluster.
I've always viewed Objects and object oriented desgint to be usefull for structuring programs - that is making moduals simple to glue together.. getting rid of "glue bugs" (problems that occure when intergrating moduals). I don't think that Objects help make a program fast or efficient.. if anything they seem to work against it, making data structures fatter and blocking possible optimisations that could come from tigher integration. This is fine with me, however, since most of my problems come from people not understanding how each others moduals work or making errors that come from simply being un-experienced with someone else's code.
I think you're looking at a tool that can be used to help structure, isolate and make code self sufficient to help with calculations and modeling.
I have implemented Monte Carlo radiation transport algorithms (read Global Illumination Renderers) and it would have taken me three times longer to do it without C++.
:)
:)
What people forget is that every little structure, every little piece of data can be considered an object. You have samples for your Monte Carlo system? Make a class. You have some kind of representation of the environment? Make classes. You have radiation sources? Make classes. You have several sampling techniques that can be chosen at runtime? Make classes.
Why? Haha. Because you get type-safeness, you get reusable code, you get increased readability, you get increased writability (no thinking "what was this int for now?) but *especially* the type-safeness, and it provides a nice framework for you to organize your code into (objects). Did I mention the type-safeness? How it saves yor brane from having to remember your structures?
Is this more code? Sometimes. More lines, yes, but usually much more readable (shorter lines). Is it slower to do it this way? Well, I didn't win the APICS programming competition by not using C++
I use classes for just about everything! People forget that if you program this stuff *well* in C++, it gets compiled away! It's not a "solution to an engineering problem", it's a tool! It gets the compiler to do a lot of things for you that you used to have to keep track of in your head. You can even do OOP in C, for instance, by pretending to do your own namespaces (adding prefixes to all your structs and functions) but why not let the compiler do it for you?
BTW, I strongly believe in the OO/procedural hybrid that is present in languages like C++. Data and functions are organized into objects, but the functions themselves are still procedural on the inside. So OOP is a tool for organizing your code!
That's so important I want us all to say it together: OOP is a tool for organizing your code.
This concludes today's lecture
Music speeds up when you yawn, but does not change pitch.
Not really. You might be doing what some OO guys call "object-based" programming (and other non-OO guys call myriad other things), but it's not really OOP. OOP implies rather more than just using your own data types.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
I'm sorry, but anyone who claims C++ has "too much overhead" over C doesn't know what they're talking about.
There is no reason that this must be the case. C++ strongly adheres to the "zero overhead principle", which says that if you don't use a feature, you shouldn't pay for it. This is directly relevant to things like virtuality (which is optional in C++) and exceptions.
The only major difference between C++ and C code to do the same thing is the quality of the compiler. C compilers used to have a big headstart in the optimisation stakes, but this is no longer the case (at least, not nearly as much).
And before anyone replies and claims that virtual functions, exceptions and such are all horribly slow, just stop and think what you'd have to do to get the same results in C, and tell me how that's going to be faster than a highly optimised, compiler-generated version of the same thing. :-)
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
This is an oft-cited anti-OO article. However, it's clearly written by a very biased author, is hardly objective (no pun intended) and is littered with obvious misunderstandings about OO.
Rather than spend hours dismantling his major arguments and point out all the flaws, I'll just post his "challenge" to the OO community to prove the superiority of OO:
Now tell me, how many people are going to expend the dozens of hours probably required to fulfil this challenge, and then field an arbitrary number of arbitrary questions from the author as a result? Is this a reasonable challenge? Does he seriously expect anyone to take it up in earnest?
Note also the rather gratuitous disclaimer, waaaay down (probably off most people's screens) on the front page of a whole anti-OO site:
'Nuff said, I think.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
Not in some cases. Generic programming in C++ would be heavily limited without it, and some of it is used implicitly.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
...here we are at work, seven years after starting a major project in C++, with about 50 man-years of development on the project behind us, and OO is still working very well indeed. For comparison, we now match the previous incarnation of software (written in C) on almost all features, but that took nearly five times as long to write, and wound up so unmaintainable that we've come in to clean up. Looking at the spaghetti they made out of a complex design, and the number of bugs they never did manage to fix, and comparing it with the nice OO framework we have in place, it's easy to see why, too.
This is an instrument control application, BTW, with a lot of mathematical analysis of data obtained through the instruments and a pretty powerful GUI/macro language on the front end. The use of OO has allowed us to design careful frameworks for the IC, maths and GUI, into which new components plug. One of the major claimed benefits of OO -- the ability to have code you haven't even written yet work with what you're writing now -- has paid off for us big-time.
I agree with some of Stepanov's points; there are indeed some fundamental flaws in a pure OO methodology. However, being pragmatic, they are relatively insignificant and you can work around them. If you choose a mixed-paradigm language such as C++, several of them immediately disappear anyway.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
Yep, some of us are still slogging on, writing our MLOC projects in C++; there's no reason for us not to.
The thing is, we use C++ in a smart way. You keep the low level stuff at low levels, instead of polluting your whole code base with it. That immediately kills most anti-C++ "it's not safe" arguments. You then write mid level building blocks from the low level stuff, and you write high level code using those building blocks. Most of the code we write today uses concepts every bit as high level as most other mainstream languages, often more so, because we use the tools for abstraction that C++ provides appropriately.
IME, the reason many people give up on C++, and switch to "higher level" languages, is that they've never really understood the abstraction tools in C++, and have always just used it as a "better C" with a few objects around in a badly designed hierarchy. Our friends over at MS showed the world how not to do it when they designed (and I use the term loosely) the MFC, which is a thin wrapper around C code, and not a proper OO framework at all.
If a few more programmers went out and learned their craft, instead of trying to use a powerful tool like C++ without learning the ropes first (but it's OK, they program C, so they don't need any more training to know C++) then fewer of them would decide that "C++ sux" and run away.
Of course, the target audience for C++ is, and really always has been, the programmers at the top who are prepared to make the effort to learn to use it. Those who do, reap the rewards, and find many "higher level languages" horribly limited in comparison.
Just MHO, of course, but I've certainly seen it often enough to be sure of that opinion.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
...because you're hurting me. ;-)
I think you just single-handedly proved the value of OO features in the language itself. The difference in readability between the previous C++, and your C implementation is, frankly, striking.
-- Mike Greaves
I'm an old FORTRAN guy who swtiched to objects, so I can relate as to the initial conceptual difficulty of choosing which objects and why. My best advice is to leave your engineering problem X code intact and think about how to encapsulate it to do more than you imagined in the past.
I worked with power grid problems (load flow). Think of it as glorified E=I*R. In the beginning, we could accomplish 0.04 cases per hour. Today's computers run more like 4,000,000 comparable cases per hour. That's more than ample reason to think differently about how to handle a case.
One way to take advantage of the extra computing power is to embed the engineering solver prodedures in optimizing programs. A linear programming engine object can be linked to my load flow encapsulated object. Together they might solve a million what-if cases to produce one optimum result.
A 2nd example. The solver can be encapsulated in objects that make stochastic pertubations of key parameters. Thus your deterministic engineering problem solver could become part of a higher-level solver that gives probability distributions as results.
A 3rd example: Modern load flow solvers are encapsulated in objects so that they can be called by higher level programs. GIS users can sketch out a new housing development and the housing object can create and place the needed poles, tunnels and wires and then turn to the 1960s-vintage procedure to calculate voltages and short-circuit currents then check the anwers against the building code objects. That could not have been achieved wihtout object encapsulation of the solvers.
A lot of the other replies to your post focused on the use of objects at the micro level, linked-lists, wires, resistors, etc as the objects. My advice is to look in the other direction, macro rather than micro. Use them to stretch your thinking about what's possible to do with your engineering algorithms.
Even brand new programs sometimes benefit from cutting off the OO at the lowest levels. Ask yourself why C++ keeps ints, chars and so on as non-object atoms while Smalltalk lets you make objects of everyting down to ints and chars and even bits if I remember correctly. It's lots of fun to play with but the overhead of too many micro level objects is great. All in all, I've gained much more benefit from objects that focus on the macro management of algorithmic solvers rather than the micro details. That's one of the problems I have with MathCAD use; as soon as the CAD programs solve the problem, they become a hindrance to encapsulating the result as an object to be used by higher level programs.
I read it, and gave up partway through the discussion, because most of the comments made were so much ill-informed FUD that it actually made me angry. It's true that C++'s biggest problem is the ignorance of the programming community, but I had hoped for better from the /. community until I read that discussion.
The extra overhead involved in initialising objects in C++ is similar in both purpose and time consumption to the overhead when you first load a C program. It may take marginally longer, but it's measured in milliseconds, and a one-off when you first start up. It's one of the few places where C++ can genuinely be slower than C, and it's still hardly worth mentioning.
I really hope your perspective isn't based on articles like that. It's well-meant, I'm sure, but there was never any debate about whether C++ was slower than C in informed circles, because the answer is obvious: no. Whether you look at the theory of the languages (try reading The Design and Evolution of C++, by Bjarne Stroustrup for some insights) or simply code generated from C++ and the equivalent functionality in C, you find the two comparable on all counts. There is far more variability in quality between compilers of either language than there is between the two languages. In fact, some language features allow C++ to make optimisations C couldn't even dream of, bettering it several fold in performance.
ROFLMAO. I'm sorry, but this is just not carrying any weight with me. Let's look at a few quotes from the first couple of pages, and see how the author demonstrates a lack of consideration on his part, not that of the group behind C++.
No, that is exactly the wrong decision. These are not fundamental features in a language with low level support. Much better to provide a simple language with solid foundations, and build a powerful library on top, than to clutter a language with "powerful" features, but then find the next time you need a new powerful feature, you have to change everything around, or can't add it at all. These features are still available in C++; what difference does it make to the developer whether they are built in or part of a standard library?
And yet, many languages (not just C++) implement MI quite happily, in various ways, with good efficiency and few bugs. Speaking as someone who uses this feature on a regular basis in large application frameworks, I can say with some authority that it's rarely appropriate, but when it is, it's horrible to be without it. Supporting interface inheritance alone is not an adequate solution to replace many useful MI idioms, however much those without MI like to claim otherwise.
And how exactly were you planning to write useful generic algorithms without this? Many critics slam op overloading, and many of the same advocate the introduction of generics into their language of choice. Few have thought it through enough to see the connection. Again, C++ got this one right.
Riiiight. So we're going to improve on C++ by removing the ability to write classes with value semantics, or indeed programmer-definable semantics at all. Further, we're going to be replacing the powerful RAII idiom with the rather underpowered and error-prone try-finally construct. And this is progress?
Unless you're going to provide a smart alternative, you just hit your performance big-time. In doing things like this, you cripple your language for developing truly high performance apps.
OK, let's rule out writing for embedded systems completely as well.
I could go on, and dismantle many of the other myths, personal views that are far from universal and downright misleading claims on the site, but I don't see much point. There are certainly flaws in C++ -- some of which will be addressed in the next revision -- but things like having MI and op overloading are not among them. Putting C++ down on that basis, in the face of informed opposition, just makes you look like you haven't done your homework.
You know, the best bit of that page is the "Who D Is For" bit. I guess I qualify, as do many I have worked with, on about 75% of those counts. Yet the arguments given in the previous "Features To Drop" section would immediately convince me that D wasn't a serious tool.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
Glad to see so many mentions of Python, and i agree. Its a great language, with clear syntax, powerful built in types and many many useful libraries (web server library as standard... what are thinking?)
.)
;)
Python makes excellent glue for bringing in a lot of different parts to make one program. The thing is that for a lot of the time glue is all you need.
When you need more than glue, I recommend some other languages, and some super-glue. If Python can't do something fast enough, Ada can ( I was shocked to see a teeny ada program outperform a teeny C program by a factor of 5, and all it was doing was a simple calculation several million times. The Ada compiler must have done a truly great job
If you think you can express certain parts of the system better in a functional language, such as haskell, then use haskell for those certain parts.
And as for the super-glue? CORBA is an amazing system for getting languages to talk to each other, even with parts being run on other machines ( if you need high MFLOPS in one function, make sure it runs on a mchine with high MFLOPS, makes sense to me
So yes, I would recommend you start by learning Python. If that is ever not enough for a part of a system, use something else that is. I like haskell and Ada, as I think they represent the best there is for their target audiences. I can say the same for CORBA, I think its the best super-glue on the market, and enables many languages to integrate seemlessly.
I don't have to. I'm not setting out to prove anything here. I use OO, procedural, functional and other programming paradigms all the time, and don't find any single one to be universally superior to all others. I'm simply demonstrating that your rules -- the basis for your claim that OO is unproven -- are not fair.
I'll do better than that. I'll pick a few comments you make from your page, and obliterate their arguments completely. I'll try to keep any relevant context; I'm sure you'll reply if you think I've failed to do so.
I posted a counterexample to this from my own work, just the other day. We are currently writing a large (MLOC) instrument-control application, also featuring lots of mathematical analysis of the data collected by the instruments and a pretty powerful GUI/macro language front-end. We are using C++ to do this, and our model is heavily OO based. (Actually, we've pretty much implemented a whole component architecture -- a second, run-time level of OO -- on top of C++.)
The previous effort was written in C, by a team of experts, and took several hundred man-years to write. Our version is around 30 man years so far, and we're close to matching them feature-for-feature, with a much more powerful UI. And so far, we're still happily extending our system (mostly within the frameworks that we designed early on for the IC, analysis and GUI work). The old C-based system fell apart as far as maintainability went, and was still riddled with dozens of serious bugs to the end (which no-one knew how to fix, hence part of the reason for the new version). Their code is the type of spaghetti that is sadly common in real world procedural work, and finding your way around it is very difficult. Ours is systematic and so easier to navigate, as is typical of a decent OO framework in a large-scale app.
Now, this is not looking at what is possible (when coded by the 2% of elite programmers in their field), it is looking at what actually happens (when you have a team of mixed ability). And it's a pretty damn compelling example of OO totally outshining procedural on a large-scale application.
Here you make numerous clear statements about what OOP experts say, and what people think about OOP. And yet, you provide no evidence to support any of it; not a single citation is present in that section. I have never heard anyone I would regard as either an OOP expert or a developer who regularly uses OOP make most of the claims you state.
This is typical of the style of your whole site. You frequently express your personal opinions of OOP, or what you perceive expert opinion to be, as fact, but without citing any references. You drum up some old arguments long since given up as if everyone today still believed them, and then point out where they are flawed as if years of experience with OOP hasn't already demonstrated that. At the same time, you gloss over examples, such as mine above, of projects where OOP and procedural approaches can be directly compared, and the OOP approach has worked much better. (I do not claim by any means that all projects fall into this category; they don't. I merely claim that many examples exist and you have totally failed to mentioned them.)
I find that ironic, given that in the above-mentioned project, we implemented a major part of the system based on a common relational database technology. The database is at the core of our whole application, and the APIs we designed to access it are still standing, with little need for change, even after nearly seven years. I would call that a remarkable success, personally.
WTF? How on earth did you get to that conclusion? You can write data from an OO program out to any format file you like, just as you can with procedural languages, and you can read it back in with any language using any paradigm that provides the necessary facilities. Your statement above seems entirely bogus.
Um... No. Writing a plain OO wrapper for a procedural style API typically takes a few minutes, as anyone who's used C libraries from C++ will be able to testify. Writing a good wrapper, which provides a mapping from your OO system's concepts onto the procedural API, can take much longer, of course, but adds value in the process. It's no different from a smart procedural programmer not calling, say, OS-specific APIs directly from high-level code, but providing an isolation layer to minimise problems with porting to other OSes or libraries at a later date.
Do you know what multiple inheritance is? I used counterexamples to your above claim pretty much every single day I'm at work. Do you know what refactoring is? You can, and should, do it with OOP code as your application develops, just as with procedural, or any other paradigm. Your argument is ill-founded.
And yet, every serious OOP instruction I have ever experienced, in print, at a training course or from senior staff at work, has been quick to stress that inheritance should not be overused. It is a valuable tool where it is appropriate, but that does not mean that it is appropriate everywhere. Your presumption of the important of inheritance in OO designs -- the foundation of your whole argument here -- is totally unrealistic.
Those would be pretty similar to the "ideal" conditions for any programming paradigm. By definition, to use any tool well, you need sufficient training, understanding of your problem, etc. Otherwise, less is sufficient. Any project is better developed with by low turnover team, and with good management. Your points are not related to OOP specifically in any way.
Oh, and I love the graph of productivity vs. a scale of chaos->typical->ideal. Did you actually have any of the metrics you so long for to support it, or was it just more gratuitous and unfounded OOP bashing?
I've got to about halfway down the page now. I could go on, and I'm half tempted to have a go at your final conclusions, but I don't see much point. If my comments above haven't convinced people of your article's misleading and biased nature, I don't think any further discussion will. Your own opinions are obviously quite different to mine, and I accept that you're entitled to them, but I won't accept them marketed as fact without challenging them.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
And again, I repeat that I don't have to. I'm not the one trying to justify my claims about OOP.
On the other hand, if you refuse to accept anecdotes from the many OO developers who use the technology every day in the field, how can you possibly claim to have formed a useful, unbiased opinion? There are many such anecdotes around. In persisting in ignoring them, and attacking what you perceive OO theory to be based on your own theories, you are detaching yourself from reality. The reality is that while not perfect, OOP works very well for a lot of people in a lot of situations.
Hardly. When the procedural code was written, our clients had double figures of experts in the field concerned to help them derive the algorithms and check the details. Now, they have two, whose knowledge doesn't even cover the whole field. Details frequently come to light months or even years after we first support a piece of hardware or analysis, and require fundamental changes to our instrument control or mathematical algorithms. Our need to adapt to changing requirements is way, way higher than that of the original procedural code. This can be objectively demonstrated simply by counting the change requests made over time. And we're succeeding, where they failed.
And you know damn well that any industrial-scale example is going to be both too unwieldy to show you, and certainly the public, and also covered by copyright meaning it can't be shown outside of the companies concerned. Where are your industrial-scale examples of OOP failing? Where are your industrial-scale examples of OOP projects failing? Even given that projects fail, if you're going to have a go at OOP, you need to show convincing evidence that more OOP projects fail than those using other methodologies, and that the cause of that failure was definitely OOP. I don't see even the slightest evidence of such research on your site, and without it, your arguments are purely academic.
Yep, and those of us whose opinions come from real experience using the technology concerned, they have rather more validity in any sensible study than those from people whose arguments are based on theory, not practice.
Sure, just as soon as you issue a similar critique of procedural programming, based on the books written many years ago when it first came out, instead of the current, vastly different state of the art.
You think all programmers should agree about tools and technologies, and there should be no discussion or disagreement? How are we to make progress then?
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
Here is an example entitled Identifying Objects: A Case Study and Class Exercise giving an example of waveform rendering on an oscilloscope (see page 5), appropriately enough based on work done at Tektronix. Is that enough of an "engineering problem" for you?
I accept that it's easier to create new types in an OO system. If you're using a language that is pure OO, then I also accept that it's harder to add operations, if that operation happens to work with multiple types; most OO systems do not support a sufficiently powerful multimethod concept, and this is a genuine flaw in current OO methodology. In languages that do not mandate this, though -- C++ being the most obvious example -- it's no harder to add a function using multiple types than it is in the closest equivalent purely procedural language, C. The solution to the problem -- the aforementioned multimethods -- is widely known as well, but simply not very well researched yet. This is probably because the problem is so small that the research is focused elsewhere.
But you haven't demonstrated that. You haven't even provided any examples. You have just stated it, flat out, without the slightest supporting evidence. This is typical of the arguments throughout your site, and why I refuted your conclusions in my original post.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
Not necessarily, no. As far as I'm aware, I never have. Procedural and OO both have their strengths and weaknesses, and my favourite language, C++, allows me to combine them as I see fit.
What I have done is demonstrate that OO design can be markedly more successful than procedural under some circumstances, based on a large-scale, real world example that allows for direct comparison by meaningful metrics. This is a counterexample to many of the anti-OO claims you make on your web site. Hence your claims are not universally true, which is the impression you are clearly trying to give, in spite of the little disclaimer you keep conveniently inserting.
Really? From your other reply to me on this thread, to which I've just replied:
That sounds pretty darn much like an "objectively better" claim to me.So you keep saying, yet your anonymous and uncited surveys offer vastly different conclusions to my own experience, and clearly that of many others, given the continuing popularity of OO after years of use. Where are these surveys? Can you give an on-line citation or two?
In software development terms? That's ancient history. Much of the OO technique being developed in real applications today come from the current popularity of languages such as Java and C++, and from the current crop of "component" technologies (COM, CORBA, etc.) that are essentially simple OO frameworks. The state of the art in each of these was vastly different five years ago from what it is today. If you need to see how fast things have changed, compare the C++ examples in Design Patterns (1995) -- then a revolutionary book in the OO world -- with the applications of those patterns in Modern C++ Design (2001) -- the closest published work I know of to "state of the art" C++. In 1995, patterns were clever. Today, their use is routine. Their very existence is based, by definition, on the fact that people are discovering OO solutions to recurring problems.
Hardly. There is no single mainstream viewpoint, certainly, because there is more than one way of solving many problems. However, as someone who also lurks around comp.object, I'm well aware that any given expert's proposed solutions are based on reasonable premises, and not the faddish claims of naive management from years ago. The opinions you express, and the claims you make about "expert opinion", are quite opposed to anything I've seen on comp.object recently.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
So what you're saying is pretty much "If you're too dumb to figure out when to use a hammer and when to use a wrench or a screwdriver, then it makes more sense to stick with *only* a hammer for consistency and training's sake.", right?
And every requirement becomes a nail to be beaten into submission. lol:)
p.s. This is a well known usenet troll.
http://groups.google.com/groups?q=%22topmind@te
http://groups.google.com/groups?as_uauthors=top
I obviously can't list the whole thing in detail; that would be around 250,000 lines of code.
The basic idea is that our database is OO, and each type of instrument that we can control, measurement we can take, etc. is modelled as a type. The whole UI and macro language is based on the concept of invoking operations on the objects of those types, and is completely configurable from data files (in the case of the UI) and provided for free by the framework (in the case of the macro language). This works very well, since most of what our application does can be modelled naturally as a signal to an instrument or an action on some resulting data. More complex situations, such as secondary results derived from multiple primary sources, are also modelled naturally in this environment.
A good OO GUI framework will present the rest of the application with general concepts, and map them onto the specifics of the platform in use, freeing the higher levels of platform dependence. As I mentioned before, this is no different to providing an isolation layer in procedural programming, and costs no more.
Basic multiple inheritance typically is indeed used for diverse properties. However, some elegant idioms allow convenient mixing in of overlapping or interfering properties as well. The "decorator" pattern is a good example of this.
It's made it into several of the books I've read. As for the newbie fault, well, they're newbies. I bet they couldn't factor a complex procedural algorithm into elegant subroutines as well as a more experienced programmer, either.
The example I gave before is compelling. In a direct comparison between a procedural approach and an OO one to the same problem, the OO solution has been developed more than 10 times faster (objective fact), in spite of inferior information available (objective fact, based on documentation and human knowledge available then and now) and much more frequent changes in requirements (objective fact, based on formal requirements specs and feature requests).
Obviously, I can't send you all the code to examine, so I have to assume that you trust my information if this is to be a useful conversation. But I have no reason to lie; I do not claim this is a universal truth, just a single example that meets your criteria.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
I fail to see your point. There is no need to use the hierarchy you mention there in an OO model for a computer, and indeed doing so would be an unnecessarily restrictive and poor design.
A less elaborate and much more practical model, for such hypothetical uses such as printing or persisting data, would be a single object consisting of several members, one for each indicator. The type of those could be an enumeration or numeric value in simple cases, or a reference to an object of a type corresponding to each item of data, to allow for more extension for complicated properties. Note that switching from one of these strategies to the other is trivial at any time, and they can be freely interchanged.
One way to model ordering a PC according to your high/mid/low level and business/home use model would be to have a factory arrangement reflecting those hierarchies, perhaps based on multiple inheritance, and generating objects of the "computer" type mentioned above. Now you can have your flexibility and still the convenience of multiple factors, and the design is still clear and simple. WTP?
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
Of course there's no "straight answer". OO is better suited to some sorts of design than others, and individual experience is often the basis on which the decision is made. However, the fact that there are so many "anecdotes", some in favour of OO, others of procedural, makes it quite clear that both can be advantageous when used by the right people in the right way. Of course, I agree that it would be great to find some concrete and well-evidenced guidelines for this, but in the meantime, experience will have to do.
No. Much of the bragging was justified, at least from the point of view of the braggers. However, OO was too much of a buzzword in the mid-90s, too many idiots got involved, and started claiming it was magic, which of course it isn't. Much the same happened for Java a bit after that, and is currently happening for "web services". Time shows each to be a useful technology in the right circumstances, but rarely as fantastic as the most evangelical make out during a period of hype. Mercifully, such idiots seem to have left OO behind for the most part just now, and we can discuss things in a rational and constructive way instead.
OK, here is a simple challenge: look at the patterns in the "gang of four" book (I assume you've read it, since you're expressing an opinion on the subject) and tell me the "trivial" Boolean and/or relational formula to which each corresponds in the non-OO world. There aren't many, and if they really are trivial as you claim, it shouldn't take any longer than it's taking me to write this reply.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
OK, so what were his credentials? Trying to force things like that into a hierarchy is a newbie mistake. It's not fair to compare newbie OO skills with expert p/r skills. No experienced OO designer worth his salt would use a whole hierarchy of classes where one would do. Wasn't that the point I, and several others, were making at the start of this subthread, in response to a suggestion that did exactly that?
It's bad modelling in my book, too. That's why I suggested using multiple inheritance, to combine the two indepedent aspects as necessary. You can combine any others you like as well; your factory classes are independent of your "computer" object's structure, and can produce computers in any useful way, without compromising the basic data type.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
> You could literally have a module for round pipe and a module for rectangular pipe and load them while your program is running.
Please explain what you mean here, I'm not sure that I understand you.
> And you could have a multidimensional vtable if you have complex data types that can't be expressed in a single dimension.
Yuck! Just thinking about it gives me the shivers.
Anyway, why would you want to have this? I can't think of anything that can't be expresses in a single dimension.
It might be more conveient to have something like:
vtbl[0]//math functions
vtbl[1]//UI functions
vtbl[2]//File functions
But that is just being evil for evil's sake. You sort the functions by some order, but it only intreduce another level of indirection, and another level of complexity, where using a staight v-table would be better.
And, anyway, you can do it much more easily on C++ via interfaces. Where this actually makes sense.
--
Two witches watched two watches.
Which witch watched which watch?
You miss my point. All of our instrument control logic, for example, is modelled as operations on the instrument types concerned. That logic is therefore part of the DB interface offered to the UI, macro language, etc., which all use quite general rules to access anything modelled in the database.
The underlying interfaces to access the actual database are all encapsulated in base classes, on which the classes providing the types above are based. They are just based on a DB library (varying, depending on how we're building).
Well, you're entitled to your opinion, of course. However, noting the number of OO GUI toolkits out there, and the fact that so much software is written using them, clearly others do find an OO model for a GUI useful.
The use of MI generally is controversial. Those who program in languages with it think it's great. Those who think Java really "supports" OO programming frequently insult it in religious attempts to defend their language's position. And then they provide absurd and vastly overcomplicated idioms to do what would be trivial with proper MI.
Dunno. Maybe it's because they lack experience, and tend to overuse "flashy" features. This is true of newbies in general, so I see no reason for newbies to OO to be any different.
And as I pointed out before, that's why no-one is taking up your challenge. Most decent examples of this, certainly industrial scale projects, aren't open source. If you genuinely want to get useful information here, don't start by cutting off the vast majority of your possible sources.
And yet, here I have a large-scale, long-term project, where an OO and a procedural approach are directly comparable. I can't show you the whole code, but I have provided objective metrics in terms of time to write it, and the demands placed upon the development.
Your only replies seem to be "It doesn't count if we can't see the code" and "Well, maybe the procedural guys sucked". Those are hardly convincing arguments. The procedural guys sucked so much that it took them ten times longer to write their version, in spite of having fewer demands placed on them and more expert knowledge available? Wow, they must have been really bad. Makes you wonder how they ever got jobs as professional programmers at all, all 20 of them. Either that, or I'm working in a room with 5 Linuses.
You may choose to believe me or assume that for some reason I'm making this up, but here I have at least one example that clearly satisfies your challenge.
Not really. The major benefits don't come from individual features. The strength of the system comes from having a clear overall design, something that deteriorated in its procedural predecessor. Most of the work fits into three "frameworks", one for the instrument control, one for the maths, and one for the UI. These frameworks set out a clear pattern for development, as any good design would, and make explicit the relationships between various aspects.
For example, to change the way something works for all instruments in a particular series, you know immediately that the common functionality will be in the base class for that series, and you also know immediately that changing that base class will affect all instruments that don't specifically override the behaviour (but you still have the latter option if you don't want your change to be made everywhere).
In comparison, the procedural version of the project would have several versions of the algorithm concerned, but each instrument's code must explicitly call the correct algorithm for that instrument, every time. The fact that an instrument always calls the same group of related algorithms has not been modelled, and sure enough, several of the bugs that have come out are because someone called the wrong function. Careless, maybe, but a risk you take with the procedural design.
Using OO lends a helping hand to guide the developer in finding his way around. It also, to an extent, helps to enforce the overall architecture. It's easier to plug in a new bit of code when you already know where it has to go and what essential interfaces it's going to use. You can do any of this in procedural as well, of course, but in my experience it's harder work and more error prone.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
So is Herb Schildt, but look at the various FAQs and web pages dedicated to him, and you'll soon see how the experts view him. When I said "What were his credentials", I meant what real-life projects has he brought home using OO techniques -- as you say, self-standing examples, not puffery. I find it easy to believe that a theoretician could have made the statement you claim, but hard to believe anyone with much time in the trenches would do so.
Well, as noted previously, you can use things like mix-in idioms as well. I've never had any problems modelling dynamic overlap situations with OO techniques so far. Are there particular circumstances you have in mind?
Decorator is no more bloated than having a list of functions to call and iterating through it in a procedural language. I suspect it's unnecessary here, but the pattern itself is sound when used in the right place -- that is, after all, pretty much the definition of a design pattern.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
I didn't indirectly admit it, I said it outright several posts ago. However, my comment quoted above is not in any way evidence to support that, as you seem to be implying. OO has been around for decades and it's still here, so I find any claim about it being a fad to be a little laughable.
I'm still waiting to see a citation so I can go read it. I'm also still waiting to hear any other evidence. Most of your argument so far seems to have been based either on your own subjective views, which I don't share, on this survey of Yourdon's, which you haven't cited that I've seen, or on pure faith. My argument is based on personal experience, both theoretical and practical, which suggests that while some of your criticisms are valid, the big picture is far from as bleak as you make out.
Sure they did. They lost control of their design, and the project failed. That happens frequently in software development. However, given that their project failed and ours didn't, we must ask why. The major differences are in the teams who wrote the code and the technologies used. Given that we know the original team was both bigger and more highly qualified in the domain concerned, we can only conclude that the different technologies and techniques used in development were the deciding factor.
Did it occur to you that your "business applications" domain is only a significant minority of all programming that gets done? The rest of the world is different. If you're going to go around criticising OOP in a limited case, you need to make a prominent disclaimer that your comments apply only to using OOP for writing applications in your domain every time.
I also note that you continuously lump relational programming techniques in as if they were part and parcel of procedural programming. They are not. Few of the languages I would say support procedural programming have built-in support for relational operations, so I claim that the two are separate. It is unfair to claim that OOP does not much improve upon procedural techniques, when you yourself use table-driven methods instead because the simple procedural approach doesn't work for you, either.
Moreover, your table-driven approach is right at home in the database world, but I claim that it is largely or totally irrelevant in many other fields. The instrument control system in my example is not full of separately configurable parts, it's full of things that are clearly and necessarily dependent. OO models this perfectly. A table-based approach to the sort of dispatching we do would only allow for needless errors as a result of invalid or missing data. It is simply the wrong tool for the job, while OO is a suitable one, in this particular case.
There you go again: in your domain. The rest of the world works differently. In the domain of the example I gave earlier, we control a whole family of instruments. Each has some basic properties, such as uniform interfaces to talk to the hardware and GUI. There are several series of instrument, used to measure different types of property, and these do not (and will never) overlap, since it makes no sense in the area of science concerned for them to do so. There are then several instruments in each series, of varying capabilities. We model this using a simple inheritance hierarchy, and it works very well. Each class genuinely is a type of the parent class, which is the only correct use of full inheritance in an OO system. Our whole application rests on several such hierarchies, but because we only use inheritance in appropriate places (containment is a far more common relation between classes in our model), we rarely have problems with this.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
If you have that kind of rule appearing, then clearly Z is not both a type of A and a type of B, and the inheritance model is not appropriate. In any real example, this should have been obvious from the word go. Genuine derived types don't suddenly not become derived types in real cases, even in response to significant changes in requirements. (If the requirements change is severe enough that this does not apply, then the possibility of a complete change of design is indicated anyway. I don't think I've ever seen such a total change in requirements in practice, however.)
The OOP version has several versions of the algorithm, but all instruments of the same type automatically call that type's version of the algorithm, because the code is in the base class that is automatically shared. This is a very frequent requirement in the field I'm working in. In the procedural equivalent, a separate, explicit call to the correct routine is required in each case. This introduces a possibility for errors, and as noted previously, this is not a purely theoretical complaint; such errors frequently happened in practice.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
Then you shouldn't be using decorator. That pattern is most useful when you want to add things at will and the order is significant. Attributes cannot cope with such a situation. You would need some sort of ordered list(s) of functions to iterate to get a straightforward procedural equivalent to decorator, but that equivalent then must have some centralised controlling logic to co-ordinate traversing the list(s) and acting on the contents. That can be a nasty limitation, introducing unwanted dependences on some artificial "central control", which is why we opted to use decorator in the first place on our project.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
Unfortunately, being neither American nor in search of rebirth, I've never read that one. Can you provide a citation here? It sounds like it would make interesting reading.
OK, but since surely the way forward is to allow judicious combination of useful techniques, why must they always be mutually exclusive? I can (and often do) use simple table-based techniques in my application at work, precisely because of the benefits you cite in terms of independent variation of features.
The overall design is broken into hierarchies related by containment, inheritance, etc., but this does not preclude the use of table-based techniques as well for the "little details" where extra classes or method overrides are overkill. In fact, they go together quite nicely, since you can incorporate a suitable table or two into your top level base class, and provide a nice controlled interface to access and update the table should any derived classes need to do so.
We don't, on the current project, use a full-scale relational table system, because that, too, would be overkill for our purposes. I see no reason that it couldn't be incorporated, and just as complementary to the OOP main design, if it were needed, though.
Well, if you're going to have multiple, related tables to model something like this, then you're going to have to impose certain restrictions yourself. Just as with OOP, if the model later changes and moves outside of your initial constraints, you need to do a little reorganising. I really don't see much difference between OOP or a table-based approach here; either is more helpful than a simple procedural approach, and obviously neither is guaranteed to give you the perfect design that never changes. In neither case is it particularly difficult to modify the design when new requirements come in, so I don't see the problem.
I wouldn't dream of it. For a start, Java has an underpowered OO model. It trades off simplicity against power in favour of simplicity. Usually, that works, and the simplicity is probably one reason for Java's popularity. But for serious OO modelling, I find things like the lack of a value/reference distinction and crippled MI mechanism to be very limiting.
My argument is not, and never has been, that OO is universally superior. As I said at the start, I use a mix of paradigms, and draw on them as appropriate. I simply contend that under the right circumstances, OO can and does provide a better basis for a model than procedural, or indeed purely table-driven, programming techniques. Under those circumstances, many of the claims you reject on your web site are actually justified.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
OK, let's look at a concrete example. Suppose I have a model where I need to know some value that is identified by a location in space. I want to establish that value by taking the input co-ordinates and applying various transforms on them to get a new position. I then use a "master function" of some sort to calculate an output value. I may then also want to apply further variations to that, before returning the final value to the caller.
In the decorator pattern, I model this using an interface that takes the co-ordinates as parameters and returns a value. I then provide three classes implementing that interface, one of which does co-ordinate transforms, one of which represents a "master function", and one of which represents the further variations on the value. I also add a second part to the first and last cases, allowing me to chain them on to any other object implementing the main calculation interface, so I can use the decorator pattern. The individual calculation effects are now derived from one of the three specific types, and any data necessary to perform the calculation can be introduced on a case-by-case basis. The result is a simple class hierarchy representing the various transformations to be applied on a one transformation, one class basis, and with any extra data required to define a particular transformation wrapped up with the transformation algorithm in its class.
I can now build a chain of the co-ordinate transforms and variations, ending with a master function to do the main calculation. The only place that knows or cares how to combine the effects is the place that sets up the chain in the first place. There is no connection at all between the three different types of calculation (other than implementing that main interface) and they can be freely interchanged. New calculation classes can be added without any impact on existing code, and just slotted into the chain creation process.
The nearest procedural equivalent without jumping through hoops is to have a list of functions, and to provide both some function to set up the list (which is directly equivalent to setting up the chain in the decorator case), and another master evaluation function to iterate through the functions, calling them in the right order. Life gets more complicated when you then have to provide arbitrarily varying parameters to the different functions, of course. A suitable mechanism for this is not trivial.
OK, that's my problem. It's a real example, the major part of a key subsystem in our current application. The above is the OO model I used to model it, using the decorator pattern. I claim that this use of decorator is a good example, and has proved its worth in a real program. I invite you to suggest a plain procedural and/or relational/table-based solution that is as elegant and adaptable in the face of arbitrary change. I also invite you to point out any weaknesses in the decorator model that make it susceptible to changes in requirements.
If you disagree, post your argument. (-1, Overrated) isn't your personal censorship tool for views you don't like.
My experience with scientific programming has been that while it is quite possible to code in a procedural language (I've done F77 and C), it will eventually start to give out.
That is, there's no question that the inner core algorithms are nicely written in FORTRAN or C or assembler if you please, and these are probably best written in those languages.
It's all the other overlying code that starts to get really ponderous in a procedural language. Things like parsers and managing I/O.
If your underlying code is useful, then you'll inevitably want one more feature to make it easier to use in a slightly different way. This happens constantly. In the end, managing that complexity is more convenient using an OO language.
My own inclination (having wallowed in C++ syntax for a few years) would be to follow an approach like having efficient numerical algorithms in FORTRAN or C and a higher level code in Python, using things like SWIG to connect them together.
Don't dismiss OO programming because of the history of over hype. It really does offer something. It can be misused. But if you take as much care with it as you do with your procedural programming you'll appreciate the dividends it returns.
"Provided by the management for your protection."