Archived

This topic is now archived and is closed to further replies.

Feelings on programming dogmata

This topic is 4948 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Recently I''ve become a little disillusioned with the programming world because I see a little too much rigidity in the minds of people. Instead of being open to improving the way we write software, it seems too often like people find a way that they like and attempt to make the world agree. I''ll illustrate this point with 2 examples. The first, is a ''mistake'' I made with my own code recently. I was writing a CGI application in Python, and as I went along, I spotted common elements... generating the HTTP headers, the HTML head, the common parts of each page, and so on. To begin with, I abstracted these out into functions so that they were written just once and called on each page. Then I realised that I was copy-and-pasting this code for each web page, with only a few minor changes in some cases. We''ve all seen people say how copy-and-paste code is bad. When one bit changes, you have to then go and change it all. It''s awkward to maintain. It''s redundant, in terms of needing to be checked/tested/compiled in multiple places, in terms of taking up more disk space, of the repeated times you have to type or paste it, etc. So, I endeavoured to remove this by abstracting the commonality into a standard algorithm, using what is commonly known as the template method. You provide a base class that dictates a standard algorithm and sub-classes override parts of that algorithm as necessary to customise behaviour. No more copy-and-paste, no more redundant code as you only ever override what needs changing, etc. I refactored all my pages and things worked fine. Each page contained a class with 1 to 3 methods for the things it needed to override. Then real life took over, and I had to abandon the project for a couple of months. When I came back and looked at my code, all I saw was a tiny bit of logic buried beneath a mountain of abstraction. No longer could I look at the code for an individual page and see exactly what happens, because half of the the functionality was hidden away in a base class. I had several functions in each file and couldn''t see instantly what order they would be called in without cross-referencing it with the base-class. I couldn''t follow the program flow steadily down the page but instead had to flick between 2 files at a time, adjusting my mental understanding of the program flow in the base class based on the contents of the sub-class''s file. In traditional terms, maintenance of this software had just become harder, not easier. I felt like I was reading a book where I had to memorise the footnotes to make sense of the story. The moral of this story is that I took it too far. A layer of abstraction buys you flexibility but loses you clarity, and in this case the amount of clarity I lost far exceeded the flexibility I received. The second example is one I saw when talking to people about server technologies for the above project. Some people preferred systems that closely resembled ASP or PHP, while others wanted all the logic to go through one ''main()''-style function and be processed from there. Both ways have their merits and the discussion was of little help to me because of this. However the most interesting viewpoint came from those who disliked the ASP/PHP model because they were adamant that they should separate the presentation from the logic. In other words, they considered this sort of code to be bad:
<p>This is a dynamic page.
<?php print "You are visitor number " . $count; ?>
</p> 
Yet their alternatives - typically involving running a function that uses a request or response object with a ''write'' method to send data to the user - produced code like this:
req.write("<p>This is a dynamic page. You are visitor number")
req.write(str(count))
req.write("</p>") 
Apart from the placement of delimiters and the function calls, these 2 snippets are virtually identical. But somehow they had convinced themselves that embedding HTML in programming code was ok but embedding programming code in HTML was totally wrong. Yet the two examples are equivalent. All the real presentation details would be handled by CSS anyway. The problem here was just in their thinking. Isn''t it sad that we make these kinds of mistakes in the search for some ''true'' way to program? Have any of you ever seen or done something like this and then realised the futility of it? [ MSVC Fixes | STL Docs | SDL | Game AI | Sockets | C++ Faq Lite | Boost
Asking Questions | Organising code files | My stuff | Tiny XML | STLPort]

Share this post


Link to post
Share on other sites
quote:
Original post by Kylotan
Recently I''ve become a little disillusioned with the programming world because I see a little too much rigidity in the minds of people. Instead of being open to improving the way we write software, it seems too often like people find a way that they like and attempt to make the world agree.

Weren''t you the one who said you won''t even attempt to *look into* .NET?

Share this post


Link to post
Share on other sites
I have had only one summer''s worth of experience in the "real world", so my opinion is probably worthless. Nevertheless, I completely agree with you Kylotan. Object oriented programming courses avoid the real situations one might encounter in the business. Therefore, students coming out of theses classes have the mindset that most programming problems can be solved using classes + inheritance and the works when in actuality while they may have their uses, traditional programming methodology is often more practical.

It seems to me that my code has finally reached a style that is practical but flexible, a point that is difficult to reach. Then again, five years from now I might be saying the same thing about now.

The Code on the Cob series here at GameDev.Net has strengthened my programming style. Have you ever read the articles?

Share this post


Link to post
Share on other sites
quote:
Original post by CoffeeMug
quote:
Original post by Kylotan
Recently I've become a little disillusioned with the programming world because I see a little too much rigidity in the minds of people. Instead of being open to improving the way we write software, it seems too often like people find a way that they like and attempt to make the world agree.

Weren't you the one who said you won't even attempt to *look into* .NET?


Yep, but I hope you remember that my choice wasn't based on programming reasons. This is a thread about programming. Thanks.

PS. Also, I did not try to dissuade anybody else from looking into or using .NET, and I did in fact ask a question regarding a much-hyped aspect of .NET on an abstract level.


[ MSVC Fixes | STL Docs | SDL | Game AI | Sockets | C++ Faq Lite | Boost
Asking Questions | Organising code files | My stuff | Tiny XML | STLPort]


[edited by - Kylotan on May 31, 2004 8:54:42 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by Kylotan
Isn''t it sad that we make these kinds of mistakes in the search for some ''true'' way to program? Have any of you ever seen or done something like this and then realised the futility of it?



Dear god, yes. You should see some the obfuscated crud I churn out just to satisfy exception safety in C++. (RAII up the wazoo and so on.) Then I think to myself, why didn''t I just use a try/catch block?

I honestly think sometimes I was a more effective programmer when I knew less. It''s not actually true, since I can actually finish large projects now that I couldn''t do say, five years ago, but all the same there''s this feelings of falling backwards.

One thing that''s helped me, at least in the feeling of frustration department, is that I''ve started getting serious about my personal code library in the last year or so. That way, even though I still occassionally get the feeling of over-abstracting my projects, at least the component pieces are familiar.

Share this post


Link to post
Share on other sites
It seems to me that the solution to most modern programming problems is in the IDE (or equivalent). For example, to help with viewing code in a complex class tree, the IDE could show the concrete class code with code from all parent classes shown as well, so you see the whole class when looking over the code.

It could even be taken one step further and the code for the highlighted function/method could be shown. This would really help viewing code where the class has one or two 'main'-type functions that invoke many private member functions. Perhaps it could have a per-method setting that controls how the code is displayed ({inline, 'tooltip' popup on mouseover, seperate window} , {always, only for children with attribute X, only for this class, etc})

In other words, the IDE could allow you to conceptually abstract things without requiring the details to be spewed all over the place, allowing you to easily analize the details when it helps and then forget about them when they aren't.

Both abstraction and the details are helpfull, and such a change to the IDE could help maximize the benefitis of both.

[edited by - Extrarius on May 31, 2004 9:05:38 PM]

Share this post


Link to post
Share on other sites
One of the common arguments against object-oriented programming in general is that abstraction inevitably means that there is no single place of reference. That is, if a class is part of an inheritance hierarchy,in order to fully understand whats going on in the class, you''d have to understand the behavior of each class it inherits from and each class it encapsulates.

This argument is often perfectly valid, take a look at the Unreal SDK that comes with UT2004/2004. Finding out what''s going on can be likened to walking through a forest blindfolded. Of course, the fact that the UnrealEngine is so strongly object-oriented means that it is ridiculously easy to modify behavior _once_ you understand whats going on.

OOP in general sacrifices readability (in that it is often harder for beginners to understand whats going on in an OO-system) for flexibility, and I guess the real decision that needs to be made is whether it is suitable for a project depending on the scope and the importance of flexibility (on a per-project basis).

For large projects where maintainability is critical, OOP is the silver bullet. For simpler programs, functional programming could well be more suitable. Yet sometimes I find myself building hackneyed OO systems simply because Im more comfortable with it (and because its been thumped into my head for a few years now)... luckily at my current job Ive been forced to understand languages and paradigms that I wasn''t comfortable with before, and for that, Im thankful

Share this post


Link to post
Share on other sites
quote:
Original post by Kylotan
Isn't it sad that we make these kinds of mistakes in the search for some 'true' way to program? Have any of you ever seen or done something like this and then realized the futility of it?

Funny, I actually did something like this only yesterday I had written a BSP loader for Quake 3 maps when I realized that since all BSP maps are structured in pretty much the same way (lumps), I could abstract the loader class, and then derive from it for each specific BSP version I want loaded (in case I want to be able to load any BSP map version automatically). Turns out that while there were only minor differences between each format, the obfuscation caused by writing everything in an abstracted manner outweighed the flexibility of knowing exactly what the format was. For example, instead of having a concrete Vertex property in my map object, I had to start writing functions like GetLumpByName in my abstract loader class that returned abstract lump classes that could then be casted by the client, because since I was trying to be as abstract as possible I couldn't assume there was a vertex lump, even though logically all the current BSP file formats would have to store vertex data. It was a mess, and most of the actual map loading code was making sure the derived class worked with the abstract interface I had developed!

Once I had gotten over the harsh reality that I'd just spent hours writing confusing, ultimately useless code, I realized a simple loader class interface was all I needed in the abstraction department. That might be too much even, since I don't have any code right now that requires that level of abstraction, as little as it may be.

Sometimes trying to be as object-oriented as possible gets the best of you. I need to spend more time in the design stage.

Kylotan: I also wanted to add that you always post the most interesting thread topics

[edited by - Zipster on May 31, 2004 9:36:37 PM]

Share this post


Link to post
Share on other sites
I think OOP is overused a bit. It definitely has a place at the architectural level, but when you start getting down to nitty-gritty details, flipping between files becomes not so fun.

I''m writing an IM program, and I naively used OOP when writing the contact list GUI. It was such a mistake because if I want to, say, add an item to a context menu, invariably I load up ContactListWindow.cpp, see that a Node class is being used, then load up the derived Node class, then look for the handler function, then...etc.

Now, I write the code as simply as possible and just add in abstraction when I feel like its becoming unmanageable.

Share this post


Link to post
Share on other sites
quote:
Original post by Kylotan
Recently I've become a little disillusioned with the programming world because I see a little too much rigidity in the minds of people.
People are rigid because they are limited by their tools and/or resources and/or egos.
quote:
Original post by Kylotan
I was writing a CGI application in Python... The moral of this story is that I took it too far.
So, were you too rigid, or not rigid enough? You made a design decision. You choose the best way rather than the easy way. That sounds you were being flexible, not rigid.
quote:
Original post by Kylotan
The second example... Apart from the placement of delimiters and the function calls, these 2 snippets are virtually identical.
No. They are not identical because their designs differ. Are you saying you are being rigid because you can't accept the benefits of their design?
quote:
Original post by Kylotan
Isn't it sad that we make these kinds of mistakes in the search for some 'true' way to program?
No. It certainly is not sad. It is called learning. If you look at code you wrote a few years ago and you aren't amazed at how little you knew back then, then you have learned nothing in those few years. Besides, there is no "true way to program".
quote:
Original post by Kylotan
Have any of you ever seen or done something like this and then realised the futility of it?
It happens a lot. If everything you try is a success, then you aren't trying very hard. If you want to learn snowboarding with the goal of never falling, you will never get very good at it.

John Bolton
Page 44 Studios
Current project: NHL Faceoff 2005 PS2


[edited by - JohnBolton on May 31, 2004 10:16:21 PM]

Share this post


Link to post
Share on other sites
quote:
Original post by JohnBolton
People are rigid because they are limited by their tools and/or resources and/or egos .


Share this post


Link to post
Share on other sites
Guest Anonymous Poster
Programming paradigms and dogma are mostly churned out by ''schools'', whose agenda is less of promoting proper practice and more like a cult that wants to control people''s minds and the market. Microsoft is probably the biggest cult of them all, but Unix people are really just as badly brainwashed.

In effect, there are too many people in the field, and not enough jobs for them all. So to justify there existence, they have to demand of others to conform to their dogma. It''s all smoke and mirrors, it''s more about who you own and who owns you. It''s more of a marketing gimmick to keep the in people in and the out people out.

pWn

Share this post


Link to post
Share on other sites
Here''s my dogma:

1) Does it work the way it''s supposed to?
2) Is it fast?

Satisfy those two conditions* for me, and I don''t care if you use OOP, procedural, cut-n-paste, etc.

*Obviously there are a few other conditions to keep in mind such as memory usage, but those are the two I find to be most important.

Share this post


Link to post
Share on other sites
3) Is it maintainable, should be very, very high on that list. I''d venture to say in some cases it should be #2, and speed should be #3.

And I''d have to agree with JohnBolton on a few points. You chose the best design decision at the time, and it was just unfortunate that you abandoned the project and had a hard time getting back into it when you returned. That doesn''t mean you were in the wrong, it just means that certain design patterns only solve certain problems; and especially when dealing with abstraction, clarity is usually pretty low on the list, if at all. I don''t know how much commenting you do, but maybe just a little more could have salvaged a little more clarity. But even with abundant commenting, it''s the law of diminishing returns.

I''d just settle on the fact that you leaving the project was the worst mistake. Shame on you! j/k

Share this post


Link to post
Share on other sites
quote:
Original post by BitBlt
[...]2) Is it fast?[...]
I think this just demonstrates Kylotan's point. I'd guess that in 90% of the applications used in business, speed is anywhere near the top of the list. The proof of this is in java and old versions of VB (back when it was interpreted) - TONS of business applications are written in the aforementioned language despite the fact that they could be made to run faster if written in C/C++.

Unless you meant "Is it fast to develop in?" in which case you agree with most companies that what is important is getting programs out quickly reguardless of other factors that might make quick cost more.

[edited by - Extrarius on May 31, 2004 11:24:56 PM]

Share this post


Link to post
Share on other sites
Commenting is fine, but a comment is not verified by a compiler, and generally the next guy rewriting doesn''t bother to fix them. Writing clean, "self commenting" code makes more sense. I personally use a very object oriented model, but if it makes sense to just call the function wherever I want, then I make it global and call the function wherever I want. Demanding that you stick with a certain discipline is NOT being ''less rigid''.

Share this post


Link to post
Share on other sites
Just wanted to say, you are 100% right that the HTML with code, or the code with HTML are identical ...

you''re example of your own mistake is also completely correct, and I''ve done similar things many times myself ...

however, I would like to point out a few things that cause me no end of trouble when talking to bosses and other "real world" oriented people.

"Abstraction" or "more abstraction" are never culprits of these bad situations, but instead "bad abstraction" or "false abstraction". Or in your case "badly formatted abstraction".

First, you original program had abstraction in it ... when every page had a Header and Body, the abstraction was there in your code, reguardless of how well or poorly you identified it. If ever page shared many common elements, and you originally used "copy / paste" to duplicate these common areas, then the abstraction was there ... and likely you had even cleaned up the identical sections from the varying sections first, to make copy / paste more efficient.

So then you look and say ... well, I have this abstraction ... and it serves me very well for making new pages ... but it will totally and completely break down for maintaining the pages (if you want to make a change to affect all of the pages) - however don''t also forget that any simple system that is allows easy page by page changes does not allow easy system wide changes, but any system that allows system wide changes requires extra work for page by page differences ... it''s ALWAYS a trade off you must choose based on your domain and expected needs.

Back to the "abstraction" topic. So you took this abstraction and tried to codify it into a certain format - functions / classes, etc. And you decided that the template method was a good choice. But here''s the thing about the template method ... it is very very visible what is going on IF AND ONLY IF you have a complete and total understanding of the template algorithm and it''s implications - and if your algorithm is actually a good and obvious framework for what your doing.

But if your forcing the square pegs into round holes ... it not only gets bigger - it gets uglier, more confusing, less maintainable, and eventually, it dawns on you how silly the whole thing is. But that doesn''t mean "abstraction" is bad. Just THIS PARTICULAR abstraction.

Just look at the millions of string classes, and container libraries, tree classes, math libraries, Widget frameworks .. etc. Its not that any of them screwed up by using abstraction, its that none of them found the PERFECT abstraction. Although some are close. I program with C# at work all day, and I can tell you, the STL is so many times better than any other container framework I''ve used - from any language. Because it gives you 100% of the readability and debuging nature of a strongly typed language, but gets (almost) completely out of your way, and lets nearly any containers, types, and algorithms be combined (well - any that meet certain broad categories and specific rules).

eh, I no longer no how many tangents I''ve followed, or what my original points we''re (or if I''ve even said them yet) ... so I think I''ll call it a post, and come back later

Share this post


Link to post
Share on other sites
I think you''re looking at it the wrong way. By abstracting your design and pushing related code into a base class, you created a sort of a black box. Your black box should have a complete interface, with good function names that should tell you what will happen by calling that function without looking at its innards. When you come to your code months later, when you look at your function calls, you shouldn''t care what happens behind the scenes inside those functions. You should know that, "ok, I called this here and this happens," or you could just look at the postconditions comment (you did write one, right?) Of course, if you don''t have the right interface and crappy function names, you didn''t gain much with OOP.

Share this post


Link to post
Share on other sites
quote:
Original post by temp_ie_cant_thinkof_name
This is exactly why you should never use inheritance and abstraction = obstruction.

I can only hope that was a very poor attempt at sarcasm

Share this post


Link to post
Share on other sites
quote:
Original post by Kylotan
Isn''t it sad that we make these kinds of mistakes in the search for some ''true'' way to program? Have any of you ever seen or done something like this and then realised the futility of it?



Yup! I''m continually re-evaluating how to go about programming various things. The more I consider it, the more I come to the conclusion that there is no "best practice" that can be used in all situations.

Sometimes a small program, or a component of a larger system that''s fairly rigid, can benefit a lot from less abstraction. It makes it easier to update and more straight-forward to follow. However, in a more complex system changing all kinds of explicit calls can become a total nightmare. I''ve seen a number of programs that have parts that rarely get touched simply because it''d be too much work/risk to go in and try to re-factor it into something that fits the desired needs. Or worse, instead of changing what''s there things get "tacked on" to it, making it progressively more and more of an incomprehensible monster. That''s the other end of choosing the wrong approach.

These days I try to factor in things like how long this code will likely be around, which other programs may use it, how it''ll be used, and the general scope of what it is when choosing how to structure it. Alas, this sometimes makes me feel like I spend too much thought on how to do it instead of just doing it

-John

Share this post


Link to post
Share on other sites
Guest Anonymous Poster
I''ll tell you, my two most recent experiences with abstraction/oop were with my hobby 3d-engine and with the embedded robotics project I was on recently. Let me tell you, it was pretty enlightening.

The 3d engine was a good place for abstraction. By making sure I developed it in pieces, I had a working engine at every step of development, where changes in one part of the code didn''t affect anything else. I could stop working for weeks at a time and return and continue on developing quickly.

The project, on the other hand, wasn''t. We used C++, but that probably wasn''t the right choice. Developing systems like that isn''t what oop was intended for - we didn''t need extensibility, or abstraction. What we needed was something reliable and stable. In systems like this, there''s no real debugger. Lab simulations only go so far before you have to take it outside to test. And when you''re outside, 10 pm at night, trying to fix code in the cold with no debugger on a deadline, you better know exactly which line of code failed as soon as you see the software do something stupid. And that was difficult. Planning the next project(similar to the one I was on) I''m going to recommend C99 instead, just because developers on the team were more familiar with it than c++

Share this post


Link to post
Share on other sites
Judge if you need lots of abstraction or not. If you are writing a simple Python script to rename or move a bunch of files, probably not. If you are writing a DB-backed application, you probably need a little in case you have a similar application to write in the future and you want to complete it faster the next time. If you are writing a library, I think you should try and make it as abstract as possible to try and allow every use of the library, even those that you haven''t thought of.

Share this post


Link to post
Share on other sites

"Text Files Considered Dangerous."

The problem with programming today is not the languages or the theories, so much as the development environments. It''s been thirty long and increasingly painful years since the philosophy of using text files for everything was dreamed up. It made sense back then, but times have changed and projects have become vastly more complex since then.

And yet... IDEs today are still fundamentally focused on slapping all the code into arbitrary text files. We''ve had any number of methodologies and languages thrown at us since then, but the text file has formed the basis of development for over thirty years.

My opinion on OOP is that it''s a good concept, let down by a lack of IDEs that are suited to the concept. Objects and data encapsulation are a poor fit for text files. It would make far more sense to use a database-driven development environment, with discrete entities entered as records into a database.

Instead of typing methods into text files, methods would become records in a database. Member variables are defined as fields in the record, with types, initialisers, etc. all clearly defined. Contracts could even be enforced between methods and classes, since the database could even be given acceptable limits to for variables and arguments. In addition, testing and test-harnesses can even be created on-the-fly -- along with compilation of the code itself. (All this can be server-side, client-side or a mix of both.)

Source control would be effectively free with DDD, incidentally. Traditional record locking would take care of the sharing issues on big projects, with far greater granularity too.

But most importantly, the use of a database back-end allows for a far more ''intelligent'' development environment. "Visual" programming could easily be extended way beyond what we''re used to today. We''d finally be able to move towards a form of meta-programming, rather than programming at the relatively low levels we''re used to today.



DISCLAIMER: I''ve been known to talk a lot of shite after drinking lots of tea.

--
Sean Timarco Baggaley

Share this post


Link to post
Share on other sites
For small programs (including most CGI scripts), it overcomplicates things to write OOP. However, for a larger project, OOP makes things much easier, as long as it is properly preplanned. One of the most important principles of OOP is the "black box" theory - that every layer of abstraction is a "black box" - with a certain functionally which should be totally independant of implementation. If your levels of abstraction were written with this in mind, you definitely wouldn''t have to consult the back-end to see "how things are done" because that should be irrelevant.
I definitely agree with the PHP example, though. Sometimes people are obsessed with doing things the "correct" way even when the other way is simpler, more effective, and faster. I''ve always been a fan of the "''Goto considered harmful'' considered harmful" group (though I don''t think I''ve used Goto since QBasic, besides maybe on a TI-83 graphing calculator).

Zorx (a Puzzle Bobble clone)
Discontinuity (an animation system for POV-Ray)

Share this post


Link to post
Share on other sites