Can OO Programming Solve Engineering Problems? 621
"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."
Use Functional (Score:1, Interesting)
Look at the audience.... (Score:4, Interesting)
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.
OOP (Score:2, Interesting)
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.
Complex Question... (Score:5, Interesting)
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.
Re:OOP (Score:2, Interesting)
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.
OOP tends to produce very bloated machine code though. In some mission critical real time systems, or on embedded systems in which there are siginificant resource limits, this may not be a good programming tactic. Yes, it reduces development time, but it tends to increase execution time.
But its sure saved my ass on numerous occaisions! Because of OOP, many of my non-trivial programs "practically write themselves!"
Different solutions to different problems (Score:5, Interesting)
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
Here's a problem (Score:3, Interesting)
Good reference (Score:2, Interesting)
Object-Oriented Implementation of Numerical Methods: An Introduction with Java & Smalltalk
by Didier H. Besset
An example (Score:1, Interesting)
http://www.oonumerics.org/blitz/ (Blitz++)
Re:Round peg, Square Hole... (Score:2, Interesting)
Computational complexity vs Conceptual Complexity (Score:5, Interesting)
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.
Math objects are objects, too (Score:5, Interesting)
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.
We do it! (Score:5, Interesting)
Re:Look at the audience.... (Score:3, Interesting)
Engineering problems are generally solved by iterating through a set of equations (sometimes hundreds of them). Iteration is the only way known to solve these problems. While you could rewrite your iteration into recursion, you would probably be filling up massive amounts of memory uselessly.
Actually, you should take a look at the compilers that are out there. If you write some code in FORTRAN with any decent compiler then the compiler will generally do some very nice things for you (like automatic parallelization). Engineering code is often very parallelizable. And when you compare the wall clock time for a FORTRAN engineering program and a C engineering program generally the FORTRAN will work better because the compiler knows very well how to handle the FORmula TRANslation in FORTRAN.
In summary, it is not a "prejudice," it is a knowledge of the best tool for the job. Your broad statement of "VB is crap" may generally be true, but you should remember that it is an available tool and that for some things (needing a hack that can solve a small windows problem quickly) it is the best tool for the job.
Engineers' goals are generally to use the best tool at their disposal for the task at hand.
I speak from experience working with Molecular Modeling as a Chemical Engineer. On my most recent project, I used FORTRAN, Perl, and Matlab (yes that is a programming language not just a program). Each tool is the best at what it does for its purpose.
Design Analysis, not Problem Solving (Score:3, Interesting)
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.
OOP vs. C++ (Score:2, Interesting)
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
Re:OOP == encapsulation ... (Score:3, Interesting)
Recovery of the "this" pointer means that any function will magically have a pointer to the object it is working on available. Now normally this doesn't matter much because you can just have the function take itself as an argument (or a magically cast-to-void "handle" if you want to be opaque about it). But when you start to have inheritance, it can be tricky for the calling function to figure out what pointer to use. The OO language will do this for you.
Late binding means you can link at runtime, not compile time. C++ offers this recovery but not late binding. Java and COM offer both.
The rest is mostly OO hype. The big argument about how you can encapsulate everything inside a function is bogus because then you just convert it into a documentation issue, of knowing what exact random thing the designer of the function has decided it is appropriate to do. This is no different in OO or non-OO.
The best, really the only successful realization of the OO dream of small interconnectable pieces so far is the Unix command line tools with pipes between them. Sure the data exchange format is trivial and limited, but the system actually works, and users can easily join together small reusable pieces of code to accomplish (most of) what they desire. The fact that this system is 30 years old and has not been improved upon just shows that <insert cliche here>.
- adam
Use OO for the Objects, Procedures for the loop (Score:2, Interesting)
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.
Flowrate: Re:Complex Question... (Score:2, Interesting)
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
Re:Yes and no (Score:3, Interesting)
The thing about an OO design is that object instances can have state (internal per-instance variables) that is implicitly available to member functions (this in C++). That's a big plus.
In your case, if you want a purely functional object, you can have that too! In C++ you'd declare and define a member function operator()(). This would pay off big if you had an object that represented a function with several parameters, some of which you'd want to hold fixed, while you varied the others. You'd use "set" member functions to set the fixed parameters, and the () operator to call the function with the remaining variable ones. This is a slam-dunk if you always want to fix the same parameters.
I can see you thinking, "Yeah, but I can use globals for that, or hard-coded constants." True enough, but then the nature of the function object is polluted by how you want to use it at this particular point in time. There is a price to be paid, of course, to reference the constants within the function proper by dereferencing this, but that's tantamount to deciding "Do I want to do this at compile time or run time?"
Now, C++ templates let you do some neat compile-time hackery to pick the pre-optimized version of a function object class with known parameters as compile time constants or global fixed parameters (static members so as to not pollute the global namespace). And, unfortunately, I don't have time to go into a discussion about type traits and functors, but you can represent functions as objects in C++, and it is espescially elegant syntactically, when those functions have fixed-paramters states.
As for the speech recognition work, the OO methodology came in handy when it came to phonemic graphs and quotient graphs of them divided by particular equivalence relations used for forward estimation functions driving an A* search (the forward estimate obtained by a full Viterbi search over the much smaller quotient graph) -- I could just tell the quotient graph, in it's current state, to digest the next acoustic input frame. Later, I'd ask it for a forward score from a given node at a particular point in time (which it would cache for me).
OOP in structural engineering (Score:3, Interesting)
Re:OOP Myths (Score:4, Interesting)
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.
Bad example? (Score:4, Interesting)
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.
OO is not a silver bullet (Score:1, Interesting)
That's why you've never seen a good, useful, large-scale, general-purpose application written in a language that forces OO on everything (like Java). It just falls on its face for a small, but noticable subset of the CS problems out there.
For engineering and scientific work, nothing beats a functional language like Scheme, if you have the time to get over the learning curve. If not, traditional structured programming does well (Fortran, C, Basic, Pascal, etc.)
Right tool for the job. (Score:2, Interesting)
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 still write in C++ :-) (Score:3, Interesting)
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.