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."
OOP (Score:2, Informative)
Not functional programming... (Score:2, Informative)
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.
Re:Use Functional (Score:5, Informative)
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."
Complex Number Support (Score:2, Informative)
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.
OOP == encapsulation ... (Score:4, Informative)
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
Yes and no (Score:3, Informative)
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.
sure it can but (Score:5, Informative)
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.
Object-oriented programming was invented for this (Score:5, Informative)
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.
OO is better for big stuff (Score:2, Informative)
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. :)
Ptolemy project (Score:2, Informative)
OO is the way to go-o (Score:2, Informative)
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.
Engineering with OOP (Score:2, Informative)
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 [llnl.gov], has Overture [llnl.gov] and SAMRAI [llnl.gov] written in C++.
OOP/Procedural/Functional (Score:5, Informative)
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.
Using Objects (Score:3, Informative)
The first OOP system I ever used was Digitalk's Smalltalk V [phaidros.com], 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 [phaidros.com] 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) [borland.com], and Kylix (Linux) [borland.com]. 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 [borland.com]. I hear its pretty good.
2 books (Score:2, Informative)
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.
C++, efficiency, and OO (Score:5, Informative)
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 [att.com] 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 [oonumerics.org]
Have a nice day
NASA is doing it (Score:2, Informative)
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
Re:Look at the audience.... (Score:2, Informative)
First, OO languages are perfectly capabile of performing iteration. Second if you use languages that support tail recursion, you can avoid growing the stack in recursive invocations.
The important point is that there's nothing about OO languages that require or favor recursive vs. iterative coding.
paradigm shift is hard (Score:3, Informative)
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.
Haskell (Score:2, Informative)
Re:Look at the audience.... (Score:5, Informative)
For the second kind of problem, optimization can be of critical importance. It is inherent in the language that Fortran is more optimizable than C: due to the rules of the language, alias analysis in Fortran is a (relatively simple) polynomial-time problem. At present (though there is effort being put into the C 2X standard to try to change this), alias analysis for C and C++ is a NP-complete problem. And given the current processor trends (deeply pipelined superscalar processors running much faster than their memory interfaces), that gives Fortran a factor of 2 performance edge (at present; this promises to become even more marked in the future...)
That doesn't mean that you can't write object-based software in Fortran; I've been doing that for many years, on large scientific modeling codes. Bertrand Meyer's seminal book (The Construction of Object Oriented Software? -- not sure of the title; I'm snowed in at home and my copy is at the office :-( ) even has a section on writing object based Fortran.
Based on two decades of experience in computer modeling, my advice to ThChalm is:
And frequently this attitude will cause you to re-think the problem, and use far better algorithms than you would have otherwise.When I applied these ideas to various problems in the high-performance environmental modeling problem domain, I wound up with an emissions model that is 600 times faster than its fine-grained OO predecessor, and an atmospheric chemistry/transport model that is 10 times faster than a competing naively-written procedural-style model.
Re:Pardon my ignorance but... (Score:2, Informative)
http://www.cs.nott.ac.uk/~gmh//faq.html#functional -languages [nott.ac.uk]
I worked on one (Score:2, Informative)
our main product "DESS"
is all Object oriented
where we model entire power systems in an oo model
A real OO application to Engineering (Score:1, Informative)
They are called template metaprograms and what they essentially do is completely unroll large mathematical operations at compile time and give you a big blob of machine code that is hardcoded to do your operation. Todd Velhuizen seems to be the patron saint of these constructions, and he claims in the links below that a metaprogrammed FFT runs at 3 times the speed of an optimized regular FFT routine. The caveat seems to be that the larger the operation (like a sort for 100 elements as opposed to 10) the larger the unrolled code generated, and hence the lower the processor cache hit rate and the less that things like function call overhead (which unrolling completely removes) matter. Here are some good links to the subject:
http://www.ddj.com/documents/s=958/ddj9608d/9608d
http://osl.iu.edu/~tveldhui/papers/Template-Metap
Re:any componentized program (Score:1, Informative)
OOP implies polymorphism (also known as ad-hoc polymorphism) through inheritance. Inheritance is one of the strongest possible relations you can express in an OO language. When you express such strong relationships between types (or class if you want to take a more pure approach) you are actually making your components extremely cohesive.
Yes of course, you can always treat objects as "Object", but that doesn't help you much. You still need to know the least common denominator, and in most cases, it is NOT Object (or whatever your favorite root class is named). Thus you have to specialize your code to a specific purpose, or at least adapt to an older concept (by inheriting from a foreign class).
Generic programming promotes something called true polymorphism. Generic polymorphism does not require inheritance. In fact, it does not require anything if you wish. For instance, look at containers. There you don't require anything of the polymorphic types (depending on implementation details of the language. C++ containers may for instance require copy constructable types and such). Of course you can do this with Object as well, just look at java. But you get a bonus here, and it's called "type safety".
Not only do you get true polymorphic types, but you also get true polymorphic functions based on the types it processes. See it as instead of adapting the types (your required inheritance), you make the functions adapt to your types instead. For free. No hassle. No manual overloading required!
Of course, not all things can be made generic, but thats where YOUR ideas come into play. You fill in the blanks. And that my friend, you can use good old fashioned imperative programming, functional programming, OO programming, logic programming, or whatever makes you tick.
I used to be a believer in the saying "OO solves any problem". But then I discovered generic programming, and I changed my mind. OO does not solve all problems.. cleanly and efficiently. I started getting an idea during functional programming class, but then the FP-zealots don't want to hear about anything called generic. "It's functional, not generic!". 2 years later I started to use STL at work when I used C++. Guess what? Jesus [read ANSI C++ committee] reached out and touched me.
STL not only gives you remarkably nice containers, it also gives you algorithms for free, the notion of functors and iterators. Mix these together, you'll never have to write retarded loops again working of your sets of data. They provide 100+ algorithms, tested and bugfree just for you to use. STL also have some real cool things in store: Models and concepts. These are interface descriptions for how components can be interacted with. It's similar to that of javas interfaces. The difference is that it no inheritance is required (java calls it implements, but its just an "pure virtual class being inherited"). A concept may just state something like "the type must be copy constructible and provide a function called size(), where the return value is compatible with the type size_t". If there is no copy constructor or size() function for that type, then the compiler will yell at you. In other words, extremely low cohesion.
Try STL for your problem solving and you will like I, find that most of the boiler plate cruft has already been implemented for you. And the best part is that you don't have to commit yourself to some other class hierarchy.
Those who are interested in STL, I dearly recommend the book "Generic Programming and the STL: Using and Extending the C++ Standard Template Library" by Matt Austern (amazon link [amazon.com]). That one is really great learning STL and how/why it works, but it assumes that you know the basics of templates and C++. Starts out with the concept of iterators (quite a big deal in STL!), goes on with gory C++ details, continues with the different models and concepts STL has to offer, and finally provides a reference for pretty much everything in STL so that you can interpret the components in STL as well as providing your own component which are compatible with STL (in terms of concepts and models). Quite a good read actually, eventhough you don't plan on doing any generic programming.
Another book is "Modern C++ Design: Generic Programming and Design Patterns Applied" by Andrei Alexandrescu (amazon link [amazon.com]). This one is really advanced and can make your brain explode. But nonetheless it's a really good read. Eventhough many of the things in there may be called "too radical" by todays standard, it's a great source of ideas. This guy, Andrei, really pushes C++ to the limits. It's quite a spectacular show!
The best part about Andrei is that he's an open source dude. Perhaps not a GPL-zealot, but nonethless, he likes to contribute code which may be used w/o restrictions by anyone else. His library "Loki" is currently being ported and integrated into the boost library [boost.org]. The boost library is the natural extension of STL, written and maintained by C++ committee members and other excellent engineers. All code that goes into boost must go through a rigorous peer code review as well as document review, thus you can count on the quality!
Ok. This wasn't exactly on-topic, but it's a valid alternative to OO for engineering stuff. The way I see it, GP is most likely well suited for those kinds of applications.
The parent of this post refers to COM objects as the main code reuse strategy in Windows. Guess what serious Windows developers use to write COM objects? Yep, you guess right: STL and ATL (Active Template Library). Infact, these two libraries make it a breeze to implement COM objects in Windows (although, I prefer the UNIX environment. I wish the customers of the firm where I work could see it that way too..)
finite element (Score:1, Informative)
http://www.code-aster.org/
(the doc is in french though !)
an other good place for scientific applications under linux is:
http://sal.KachinaTech.com
check it out
& happy new year
Re:OOP == encapsulation ... (Score:3, Informative)
1) OOP != encapsulation, by definition.
Hint: you missed inheritance and polymorphism
2) Unfortuantely, not every program is combination of OO and procedural code. Sometimes OOP-ness is enforced.
Hint: Java.
3) Unfortunately, OOP is not helping to package code and data togethter. On the contrary, because of the inheritance it's often more difficult to trace what are the properties and methods of an object.
Hint: read "Patterns of Software" by Richard Richard P. Gabriel. He has an exellent chapter on compression and reuse. By compression he means dependency on the context. For OOP it's non-localized dependency, which is usually bad.
4) Your argument about NULL pointer checking is irrelevant. Before calling object methods, you have to make sure is's initialized. No difference with passing the pointer as an argument.
5) There's more than just applying a function to a structure. Here it is: applying a function to two structure of diferent type. Where do you put this function? In OOP, it's a source of many arbitrary decisions on early stage. Projects evolve, but it's difficult to change such a decision once it's done.
Example: LinkPictureToAlbum( Picture, Album ). Is it Album object method or Picture object method?
In practice, another problem is need for multiple dispatch, but that's rather implementation problem. C++ and Java are popular OOP languages and they provide single dipatch only. It's not an inherent OOP problem - see CLOS for an example of successful multiple dispatch in OOP.
6) Templates is non-OO feature of C++!
I agree with your conclusion, though. The OOP is not a panacea, but it's definitely useful.