views:

347

answers:

11

I'm finding only about 30% of my code actually solves problems, the rest is taken up by logging, tests, parameter checking, exceptions, error handling and so on. Do you find that in your code, and is there an IDE/Editor that allows you to hide code that's not interesting?

OTOH are there languages which make the support code more manageable and smaller in size?

Edit - I think we're all aware of the difference between business logic and other code. I'm not saying that the logging etc is not important. The things is, when I'm coding I'm either implementing business logic, or I'm making sure things don't break. For me that's two different ways of thinking, do others develop like that, and is there an IDE that supports that way of developing?

+1  A: 

If my IDE could hide "not interesting code" I would definitely turn the feature off. You wouldn't want that happening, I bet :)

There are certainly languages that minimise the amount of supporting code, but I don't think you could switch from Java to lets say JavaScript simply because in JavaScript you wouldn't have to declare every exception... I think it's quite necessary to have your supporting code where it is.

Oh, and you could have your program formally specified and mathematically proven, then you wouldn't need to support your code too much ;D

Peter Perháč
The ability to 'turn off' the supporting code would make the business logic far easier to identify and understand. I've found this a real hassle when looking at an existing code base in a domain I'm not familiar with.
MrTelly
if your IDE would hide parameter checking, couldn't you end up looking at code (in a domain you're not familiar with) and not understanding it just because of this feature? Or if throwing an exception would be hidden. Wouldn't you wonder what happens in the code?
Peter Perháč
A: 

I don't try to make all routines foolproof, only those exposed to the outside world.

http://en.wikipedia.org/wiki/Folding_editor

Higher and more dynamic languages are usually less verbose. Weak typing also saves a lot of code. Of course there are trade-offs.

Tobias
folding is a drag... or at least as it is implemented in some IDEs. Like, I have had some grief caused by the way Eclipse folds the code.
Peter Perháč
I agree that weak typing reduces the amount of code, but it's really throwing the baby out with the bathwater - I don't want to lose strong typed benefits for shorter code, I'd like an IDE that acknowlegdes the prob and helps to solve it.
MrTelly
A: 

I use the #region directive in Visual Studio to collapse blocks of code that are not the primary focus, e.g. unit tests. With log4net logging statements are only ever one line. I haven't found any approaches to reduce the parameter checking code although it sounds like C# 4 has some kind of contract framework that will help there.

sipwiz
I used to use #regions, but I now actively discourage their use and remove them from my code. It's just too easy to miss something...
Mitch Wheat
...and after all, code should be made easier to understand rather than hidden!
Mitch Wheat
I've tried using regions, but then you end up with multiple regions/method - that looks just as ugly, and you can't have classifications of regions. How about hide all logging, hide all exceptions, show only business logic ...
MrTelly
It's a style choice. I use regions sparingly but where I do use them find them very handy. Being able to quickly grasp the purpose of a block of code by way of the region title saves me time and I've never had a case where I missed something because of a region.
sipwiz
"How about hide all logging": if you comment accordingly code folding can do that.Or you could 'physically' separate them using a Handle Body Pattern.There also is http://en.wikipedia.org/wiki/Aspect-oriented_programming which I know nothing about.
Tobias
+1  A: 

The real code you are referring to is usually called "Business Logic".

In a good unit testing system, your unit tests should be in their own classes (and probably their own assemblies) so that shouldn't be an issue.

The rest is language based for the most part. The more advanced a language, the better it's ability to avoid writing support code to some degree. Also, a well-targetted development system can help you avoid writing a lot of code (Visual Basic's screen builder, Ruby on Rails, ...) but these abstractions can break down and cause you to write just as much code as anything else if you use it to develop targets outside it's intended types of apps. (VB & Ruby don't help all that much if you're calculating prime numbers)

Beyond the language/platform, you have refactoring--the art of eliminating all the supporting code that you can (as well as redundancies in your business logic) to keep your code-base clean and small.

When practicing advanced refactoring, you'll probably end up writing tools for yourself.

Sometimes abstracting data out of your code and into a structured file of some sort can eliminate huge piles of support code and move the rest into "Business logic" because now parsing that data and setting it up is part of the "business" your program does.

This is a good trade-off because this type of business logic tends to be more readable and easier to factor. The other advantage of this kind of abstraction is that all your "Configuration" is now done in data which tends to make it somebody elses' problem.

As an example of this type of tooling: Rails itself! It takes a lot of the boilerplate of web development and factors it out of the code and into libraries driven by data and simplistic code (Ruby blurs the line between code and data--their data files actually loop back to being specified in Ruby code!)

Bill K
+8  A: 

Supporting code is just as important as the "real code". The quality of your product is determined as much by supporting code as anything else.

Consider an automobile. In terms of just getting from point A to point B, that requires nothing more than a go-cart: a frame, a seat, an engine, a few tires. But modern cars have a lot more than just the basics. Highly efficient engines using electronic engine timing. Automatic transmissions. Bucket seats. Heating and A/C. Rack and pinion steering. Power brakes. Anti-lock brakes. Quiet, comfortable cabins protected from the weather. Air bags. Crumple zones and other advanced safety features. Etc. Etc.

Details and execution are important, even in software. If you find that your "supporting code" tends to look more like kludges and hacks, then it's time to rethink your fundamental approach. But ultimately the fit and finish determines quality of the end product as much as anything else.

Edit: The questions you should ask yourself:

Is your "supporting code":

  • An umbrella duct taped to a pole or a metal and glass cabin frame?
  • A piece of pipe tied to the front of the car or an energy absorbing bumper integrated into a crumple zone?
  • A grappling hook on a rope tied to the frame or 4-wheel anti-lock power brakes?
  • A pair of goggles and a thick coat or a windshield and a heating system?

Answers to these questions will probably affect how much you care about your "supporting code".

Edit: Response to Dave Turvey's comment:

I'd encourage rereading the original question, one of the examples of "support code" listed is "error handling". Consider this for a moment. Imagine it in the context of, say, an automobile, a microwave oven, or even an operating system. Should error handling be relegated to second class citizenship because it serves a "support" function in some abstract sense? In an automobile the safety features are part of the fundamental design of the vehicle and comprise a substantial part of the value of the car. The safety features and "error handling" of a microwave oven (indeed, of the microwave oven's embedded software as well) are an important part of its value as well. A microwave oven that was improperly shielded could cook food just fine, under the right circumstances, but it would pose a hazard to the operator.

The implicit featureset of every tool (software or otherwise) includes this list:

  • Robustness
  • Usability
  • Performance

Everything anyone has ever built or used has had these features. Failure to understand this will translate to failure to execute well on these features which will make for a poor quality product of low value and low commercial interest. There is no such thing as "support code", there is only a misunderstanding of the nature of what it means for a feature to be complete. A "feature" that works in the abstract only under laboratory conditions is an experiment, not a part of a product.

The idea of pure, pristine features floating on a bog of dirty, ugly support code is the wrong image of software development. Instead, think of elegant, superbly-integrated machinery that is well-built, intuitive to use, and powerful.

Wedge
Your examples don't really demonstrate what supporting code is in relation to the "real code". supporting code helps to deliver a quality product but doesn't add features used by the customer. For an automobile this would be more like CAD models of the car, a crash test setup or programming for manufacturing robots.Your examples are all just advanced features. I don't need all the formatting options of Word to write a shopping list but that doesn't make them support code.
Dave Turvey
@Dave I can't quite tell if you get my point or miss it. As I mention in my edit, "support code" is framing the question improperly, there is no such thing, there is only code, all of it contributes to the overall qualities and value of the end product.
Wedge
Your analogy is totally off.
Tim
A: 

I have some coworkers who once, while being chewed out by a client for an overdue and bug-ridden project, bragged to the customer that they had written 5 times as much test code as operational code.

The client was not happy, and by "not happy" I mean their skin turned green, they grew to 5 times their normal size, and their clothes popped off.

MusiGenesis
That seems to be a bit of a common theme around SO as well. A lot of people seem to be into write lots of test code before even thinking about biz logic. Thankfully there's authoritative common sense views http://stackoverflow.com/questions/153234/how-deep-are-your-unit-tests/153565#153565.
sipwiz
Pity your can't +1 a comment
MrTelly
A: 

You could just make a static class in a utilities assembly that checks your parameters and things. For instance in the Spring Framework (which is where I got the idea) it has an Assert class and it makes it really fast to make sure that string params aren't empty or that object params aren't null. It cleans up validation code and reduces duplicate code which is a win win.

Zerodestiny
+3  A: 

The supporting code is important, but you want not to be distracted by it when you don't want to. There are two technologies that can help.

  • A language with first-class functions will help you modularize your code so that logging, timing, and so on can be implemented once and then combined with many other modules. It will also help you write unit tests. Some good ways to learn the techniques are to read the paper Why Functional Programming Matters and to learn about the QuickCheck tool. (No, I am not a shill for John Hughes, but he does do wonderful work.)

  • If you cannot use a programming language with powerful capabilities for modularization and reuse, or if you don't want to, Don Knuth's Literate Programming technique will help you organize your code so that you can split up parts the way you want and pay attention only to what you want, when you want. The Noweb literate-programming tool supports any language that can be written in ASCII, and also combinations of those languages.

Norman Ramsey
+1  A: 

It's like you want to take a trip to the top of Pike's Peak. You can take the Winnebago, you can take your SUV, or a motorcycle, or ride up on your bike.

Some ways are a more or less expensive, faster, etc. Sometimes you end up taking along a lot of stuff the isn't there strictly for accomplishing vertical progress; it's nice to have a beer in the cooler. But it pays to remember that you're responsible for everything that goes with you to the top.

le dorfier
I like your answer, but IMHO a better analogy would be a trip with an SUV, wearing a creah helmet, firesuit, belt, braces, carrying a weeks supply of food, when all you wanted was to take a few photos.
MrTelly
+1  A: 

Aspect Oriented Programming partly addresses this. It allows you to inject code into existing source/bytecode. This way you can make a task such as logging appear in its own module instead of woven into the business logic.

+1  A: 

Work expands to fill it's container. This really sounds like an economics question. (ie. optimizing your outputs- features for users and features for the developer) with expensive inputs (time spent writing features, time spent writing plumbing code.)

You have to include user visible features or you don't have a viable product or job. Once that is done partly done, your remaining budget of time will be split between activities with a visible return on effort and an invisible (but positive!) return on effort, like exception logging, memory management, etc.

What ever language makes it cheaper to implement features will probably increase your features/to plumbing code ratio. Likewise, whatever language makes it cheaper to implement plumbing code will probably increase the feature to plumbing code because you'll have freed up more time to write features.

Like all optimization problems you'd have 2 effects-- the increase in the size of the support code (because say, you're using cheap code generation) and the increase in the size of feature related code (because you have more time left over to write features), so the final ratio might be hard to predict.

I do not begrudge the 90% of my code that is data access plumbing, because it is all testable, code generated and very cheap, compared to the 10% of handwritten of domain specific code.

MatthewMartin