21

Lately I've been trying to wrap my mind about the following fact.

On one hand, there is a host of coding guidelines and standards for what is considered to be "healthy", "clean", "well-written" and so on code. See the "Clean Code" that appears to be widely discussed here as well. Example rule: 7 line long methods and 1 or 2 levels of indentation. Code that doesn't follow is somehow expected to die of poor maintainability.

On the other hand, I get to work with OpenCV, OpenCascade, VTK, etc. It's scientific code. They have 2 page long methods (sen myself), OpenCascade has a method or a class split into 10 files (no jokes here), VTK is a mess at times, too. Yet these projects prosper, are maintained and widely used!

Where's the catch? Are we allowed to write scientific, math-heavy code in a way that it just works, and we can maintain it? Is thee a separate set of standards for such projects, if any?

Might be a naive question, but I'm in what seems to be a programming void trying to build up set of rules how to do and not to do things, which is the way I've been taught to work at high school. Ever since I graduated, I've had almost no guideline support with the things I've had to do, mainly programming - no-one bothers to teach that.

  • 25
    No, it is not, but most scientists don't have the engineering training to know better. – Steven Burnap Mar 16 '16 at 22:48
  • 4
    In any project that has been around for a while, you will find a ton of code that is poorly written but that seems to work well enough that no one bothers to go back and clean it up. Sometimes that is because standards and patterns evolve over time, sometimes that is because standards weren't enforced uniformly, sometimes that is because it's a lot more fun to add new functionality than to go back and refactor a piece of code that works but is poorly documented. – Justin Cave Mar 16 '16 at 22:59
  • 2
    @JustinCaveL Or: "If it ain't broke, don't fix it." Especially applicable to write-only code. See also plaza.ufl.edu/johnaris/PDFs/ProblemSolvingFlowChart.pdf – Robert Harvey Mar 16 '16 at 23:06
  • You will certainly find my earlier question relevant: programmers.stackexchange.com/q/266388/620 – rwong Mar 16 '16 at 23:50
  • 8
    To fellow answerers: This question refers to the code base of open-source libraries for computationally intensive tasks in one or more scientific domains. This question is not about throwaway code. Please pause for a moment to make sure you grasp every highlighted aspect before writing an answer. Thanks. – rwong Mar 17 '16 at 0:03
28

Is scientific code a different enough realm to ignore common coding standards?

No, it's not.

Research code is often "throw away" and written by people who are not developers by background, however strong their academic credentials. Some of the research code I wrote would make current me cry. But it worked!

One thing to consider is the gatekeepers to projects drive what gets included. If a large project started as an academic/research code project, ends up working, and is now a mess, someone has to take the initiative to refactor it.

It takes a lot of work to refactor existing code that is not causing problems. Especially if it is at all domain specific or does not have tests. You will see that OpenCV has a style guide that is very comprehensive, even if not perfect. Applying this retroactively to all existing code? That is.. not for the faint of heart.

This is even more difficult if all that code works. Because it's not broken. Why fix it?

Yet these projects prosper, are maintained and widely used!

This is the answer, in a sense. Working code is still useful and so it is more likely to be maintained.

It might be a mess, especially initially. Some of these projects probably started as a 1-off project that "would not need to be reusued ever and could be thrown away."

Also consider that if you are implementing a complex algorithm it may make more sense to have larger methods because you (and others familiar with the scientific side) can conceptually understand the algorithm better. My thesis work was related to optimization. Having the main algorithm logic as one method was considerably easier to understand than it would have been trying to break it apart. It certainly violated the "7 lines per method" rule but it also meant that another researcher could look at my code and more quickly understand my modifications to the algorithm.

If this implementation was abstracted away and designed well, this transparency would be lost to non programmers.

To fellow answerers: This question refers to the code base of open-source libraries for computationally intensive tasks in one or more scientific domains. This question is not about throwaway code. Please pause for a moment to make sure you grasp every highlighted aspect before writing an answer.

I think people often have this idea that all open source projects start as, "hey I have a great idea for a library that will be wildly popular and used by thousands/millions of others" and then every project happens like that.

Reality is that many projects are started and die. A ridiculously tiny percentage of projects "make it" to the level of OpenCV or VTK etc.

OpenCV started as a research project from Intel. Wikipedia describes it as being part of a "series of projects." Its first non-beta release was 2006, or seven years after it was first started. I suspect that the goal initially was meaningful beta releases, not perfect code.

Additionally, the "ownership" of OpenCV has changed significantly. This makes standards change, unless all responsible parties adopt the exact same standards and keep them for the duration of the project.

I also should point out that OpenCV was around for several years before the Agile Manifesto that Clean Code derives inspiration from was published (and VTK almost 10). VTK was started 17 years prior to the publishing of Clean Code (OpenCV was "only" 9 years prior).

  • 2
    I have been using OpenCV back in 2004 and it was awful. Willow Garage (new owners) made a great job by converting almost everything into C++. Actually it is one of the few scientific libraries that consist of good code. – nimcap Mar 23 '16 at 18:14
15

Scientists are not developers. Their job is not to write code per se. Their job is to solve problems, and programming is just one of the tools they may use.

Most enterprise code written by—as they would call themselves—professional developers is a mess. Most of this code doesn't use design patterns or misuse them. Most comments are candidates for TheDailyWTF. So since in our own industry, we see such results from people whose work is to write code, what would you expect from people whose job is not to write programs?

Would all practices an actual professional developer learns during her career benefit a scientist? Absolutely. Would it be possible for every scientist to spend five to ten years of her life learning software development? Probably not. Therefore, the code quality is as it is.

Another factor is the culture. If your pairs don't write clean code, why would you? Since nobody cares, you're not really inclined to do the extra effort.

Finally, most scientific code has a relatively short lifespan. You write code for a specific research, and when the research is done, you don't reuse the code. Once you have this habit, it's difficult to make a difference between reusable libraries such as the ones you quote and throw-away code.

  • "Their job is not to write code per se. Their job is to solve problems" -- note that technically a developer's job is not to write code either. His/her job, much like the scientist's, is to solve problems. I'm excluding software factories and code monkeys who are paid to keep chairs warm, but by definition they don't care much about clean code either, so they aren't relevant for this question :) – Andres F. Feb 17 '17 at 19:57
8

Ignore? No. Re-consider and adjust? Sure. A lot of scientific code is math intensive and performance critical. Things like the overhead of function calls can actually become a problem, so you may end up with more deeply nested structures then you see in a typical commercial app. That doesn't mean you should dive head first into a thousand micro-optimizations. You should still focus on choosing the right algorithm, and only make optimizations whose effect you can measure.

Some of the differences are obvious and trivial. Coding guidelines will typically call for choosing meaningful variable names and single letter names will be immediately suspect. A scientific application will still want meaningful variable names, but sometimes the most meaningful name will be a single letter, referring to a variable in a well known equation.

  • 4
    +1 for the variable naming comment. When I was in school I did some freelance coding for various departments, and in the stat and math departments I was "strongly encouraged" to use variable names like Aj and T0 because that's the way the variables were named in the functions I was translating to code. Using something like correlationIndex or startTime would get you grumbled at. – TMN Mar 17 '16 at 11:54
4

All of the existing answers had covered this question comprehensively. However, I would like to point out what is the true antipode between the likes of OpenCV, etc., versus say, code that is developed according to good business practices (Code Complete, Clean Code, SOLID, etc.)

In general, there is a lot of business benefit for source code to be KISS - "keep it simple, stupid." There is also a related YAGNI - "You Aren't Gonna Need It".

Unfortunately, for computationally intensive software in the scientific domains, the source code is seldom simple or lean.


Traditionally, OpenCV had suffered from a lack of generalizations (lots of code duplication to support different options), whereas VTK had suffered from excessive generalizations (templates).

In the early days, certain parts of OpenCV was originally developed in C. Later, OpenCV adopted the C++ API we are familiar today. Some algorithms are rewritten to take advantage of C++ interfaces (abstract base classes) and C++ templates. Other algorithms were simply wrappers for the original C code. Remnants of these code can be found scattered around in the "imgproc" module.

OpenCV contains lots of SIMD programming (vectorization). To this date, SIMD programming in C++ still requires the use of intrinsics (intel.com), (arm.com).

SIMD intrinsics read like assembly language, except that the compiler takes care of register assignment of variables, and the compiler is allowed some liberty to swap the order of instructions for performance gains. Algorithms written to use SIMD intrinsics had a high maintenance cost. This is the reason I mentioned a question I asked earlier - Maintenance cost of SIMD programming code base.

A person who is not doing SIMD programming may be easily led to believe that SIMD can be encapsulated elegantly and that low-level SIMD programming should not be necessary anymore. This is actually quite far from the truth. I would challenge anyone to try implement a useful algorithm in SIMD (not fractals) and see the difficulty-of-use in these proposed encapsulations.


Below is a long list of ideas when I try to analyze why computational software can't be KISS or YAGNI. However, all of these ideas are over-generalizations, and they don't seem to support the above observation.

The main contributing factors are:

  • Software performance
  • The need to support many algorithm options and tradeoffs
  • The need to support many different hardware platforms and compilers
    • This compounds with the software performance issue - performance needs to be good for a lot of hardware platform and compilers.
  • The lack of ongoing code base modernization, due to lack of resources, lack of knowledgeable people who can improve the code quality without compromising the other factors, etc.
    • Open-source projects suffer from tragedy of the commons.
    • Open-source projects that receive grants had to meet specific deliverables - code quality is typically not part of it.
    • In particular, there is even a lack of knowledgeable people who can make or suggest incremental code quality improvements. This is the "missing eyeballs" problem - many people benefit from the code, but few took time to read the code.
  • Historical lack of code quality gates such as code review, unit tests, static analysis, etc.
    • For a large scale project, these code quality gates are not merely manual steps - each would require an infrastructure (a web-based system, a unit test system, a build automation system, etc.)

Several of the above contributing factors are antipodes with business software development:

  • Typically, business software does not need to deal with the same high data throughputs seen in computational software.
  • Business software can be tied to a single operating system and computer architecture.
  • Business software can be frugal in deciding what functions to include. In fact, business software development encourages managers to say no to new features unless there is a good business case.
    • Users of internal business software can be trained to do things differently, avoiding the need to make code changes.
    • If a commercial business software loses one customer due to one missing feature, but gained two new customers due to improved simplicity and ease-of-use (see "The Paradox of Choice"), overall it is a net gain - it is a good thing that this one feature is missing.
  • Business software is supported by a continuous revenue stream, so that it can afford to spend part of it on continuous code base modernization.
  • 1
    You are bringing a lot of points to the table that all seem quite irrelevant to the question. – Martin Maat Feb 18 '17 at 9:10
  • @MartinMaat If you have positive things to add to this question, please write in your own answer. – rwong Feb 18 '17 at 9:43
3

Is scientific code a different enough realm to ignore common coding standards?

It depends on what you call "common coding standards". I would not call the extremes of Agile "common". In particular, deeming a function that is eight lines long to be too long, or that has more than two levels of indentation to be too complex are ridiculous standards in the field of numerical / scientific programming.

A very simple matrix times matrix function is more than seven lines and has three levels of indentation. The function will grow to be considerably more complex than that should one be concerned about efficiency. This is such a common operation that efficiency is important. Breaking it down into pieces is exactly what you don't want to do. A matrix decomposition is going to be even more complex.

  • 2
    "Agile" doesn't have anything to do with coding standards. – Steven Burnap Mar 17 '16 at 0:28
  • @StevenBurnap -- Sure it does. Look at "Clean Code". It has oodles of coding standards in it. – David Hammen Mar 17 '16 at 3:08
  • 1
    Clean code having a lot of coding standards is a bad argument. The Agile manifesto may not have anything to do with coding standards, but Agile does promote flexibility and responding to change and sticking to coding standards or best practices supports that. So - in a very indirect and circumspect way agile may not have anything to do with coding standards, but coding standard do have a lot to do with agile. – Marjan Venema Mar 17 '16 at 7:45
1

I decided to post this as a new answer because it's a completely different perspective.

Let us take a look at a code sample that I consider to be "clean code" in terms of computer vision and image understanding:

https://github.com/opencv/opencv/blob/05b15943d6a42c99e5f921b7dbaa8323f3c042c6/modules/photo/src/seamless_cloning_impl.cpp

For those familiar with MATLAB and scientific computing, the code in C++ is nearly as concise as the cleanest possible MATLAB code.


Now we have to ask, why isn't the entire library code base (OpenCV in this example) written to the same standard as this code sample?


We must stratify a large scientific library's code base into abstraction levels.

At the low level, you are literally re-implementing additions and subtractions. Or, literally re-mapping each operation to the fastest implementations on each platform.

https://github.com/opencv/opencv/blob/master/modules/core/src/hal_replacement.hpp

The mid-level is where we find the "dirtiest" code, within which maybe 80% - 90% of CPU execution time is spent. (Similarly, maybe 80% - 90% of development effort were spent in the mid-level, if we count separately software development efforts from scientific research.)

At the high level, we have the cleanest code, written by researchers.


A strong excellence in source code organization is needed to make sure these levels don't mix. This is beyond coding standards, more has to do with open source stewardship.

For example, sometimes the decision is made to split one open-source project into two. You can't make these things happen by code commits.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.