Best Practices for Scientific Computing — TEI-tagged view

Greg Wilson, D. A. Aruliah, C. Titus Brown, Neil P. Chue Hong, Matt Davis, Richard T. Guy, Steven H. D. Haddock, Kathryn D. Huff, Ian M. Mitchell, Mark D. Plumbley, Ben Waugh, Ethan P. White, Paul Wilson · 2014 · scientific-computing · doi:10.1371/journal.pbio.1001745 · TEI xml · tagged edition · index · concepts · authors
Where this record's text came from. 2026-09-07 schema-0.3 pass: every quote verified as an exact substring of the staged text and anchored at merge time; concept terms verified present; every edge endpoint an existing node.
This record’s own method is practice-report, and the tags below follow from that. A review’s findings, quantities and statistics are things stated IN this paper, and some of them report results obtained elsewhere. No tag on this page names a different author. Measured across every review in this corpus, 81% of a review’s tags carry no citation at all — most of them are the review speaking. The corpus does not adjudicate the rest: read an unmarked tag as a claim this paper makes, not necessarily one it made first.
Other fields define these differently the same word, defined another way in another discipline
reproducibility 6 fields · reproducible research 4 fields · open science 4 fields · scientific research 3 fields · training 3 fields · code review 3 fields · and 3 more →
Tags on this paper every tag the record carries, whether or not the words occur in the text below — a number is how many papers in the corpus carry that tag; a tag with no number is unique to this paper
best practices for scientific software development scientists' productivity reliability of their software scientific research3 software2 experimental apparatus computational methods2 central conclusions of published research computing errors prominent retractions best practices error-free software development reproducible research6 open science5 program2 human working memory functions names code style and formatting repetition of computational tasks recent commands script3 workflow management tool dependencies between files build tool provenance of data unique identifiers and version numbers values of parameters scientific programmers traditional commercial software developers small steps with frequent feedback and course correction agile development version control system2 VCS snapshots of a project's files2 repository2 working copy2 conflicts entire history of those files everything that has been created manually DRY Principle single authoritative representation code clones modularize code re-use code established library or package defensive programming assertion statement2 executable documentation automated testing unit tests2 integration tests regression tests unit testing library bugs test cases testable2 symbolic debugger performance bottlenecks profiler highest-level language possible low-level languages rapid prototyping test oracle good documentation maintenance costs interfaces and reasons implementations refactor code reference documentation documentation generator literate programming code reviews source code pre-merge code reviews pair programming code review3 driver navigator issue tracking tool duplicated effort reproducible computational research 24 recommendations time cost training9 primarily self-taught basic software development practices how reliable their software is reproducibility9 readers make more mistakes mistakes requirements are constantly changing lost work provenance for both code and data errors and inconsistencies debugging confidence that scientific code is operating properly witness what is going wrong directly explaining how it works shared version control repository productivity3 advanced practices productivity of the programmers involved adoption of these tools practice-report11
Method, as described: practice synthesis grounded in software-engineering research, empirical studies, development guidelines, teaching, and collective scientific-programming experience

Colour legend

PLoS Biology<title level="j">A work — the journal / venue title.
2014<date>A year or date.

Greg WilsonpersName, D. A. AruliahpersName, C. Titus BrownpersName, Neil P. Chue HongpersName, Matt DavispersName, Richard T. GuypersName, Steven H. D. HaddockpersName, Kathryn D. HuffpersName, Ian M. MitchellpersName, Mark D. PlumbleypersName, Ben WaughpersName, Ethan P. WhitepersName, Paul WilsonpersName (2014date). “Best Practices for Scientific Computing.” PLoS Biologytitle·j.

Object of study — practical software-development techniques for improving the productivityterm, reliability, maintainability, and reproducibilityterm of scientific computing

Research question — which established development practices scientists can adopt to reduce softwareterm errors, support reuse, and preserve reproducible computational results

Contribution — twenty-four recommendations organized around readability, automation, incremental change, reuse, testing, optimization, documentation, and collaboration

Cross-disciplinary analysis
content-tags & facets: phenomenon · claim-type · cross-domain-transfer · mechanism · claim-relation · replication-status · limitation — grounded in the full text
phenomenonscientific conclusions made unreliable or irreproducible by fragile, opaque, untested, or poorly managed research software — “We believe that software is just another kind of experimental apparatus [3] and should be built, checked, and used as carefully as any physical apparatus. However, while most scientists are careful to validate their laboratory and field equipment, most do not know how reliable their software is [4] , [5] . This can lead to serious errors impacting the central conclusions of published research [6] : recent high-profile retractions, technical comments, and corrections because of errors in computational methods include papers in Science [7] , [8] , PNAS [9] , the Journal of Molecular Biology [10] , Ecology Letters [11] , [12] , the Journal of Mammalogy [13] , Journal of the American College of Cardiology [14] , Hypertension [15] , and The American Economic Review [16] .”
claim-typemethod — “We describe a set of best practices for scientific software development, based on research and experience, that will improve scientists' productivity and the reliability of their software.”
method — evidence — “This paper describes a set of practices that are easy to adopt and have proven effective in many research settings. Our recommendations are based on several decades of collective experience both building scientific software and teaching computing to scientists [17] , [18] , reports from many other groups [19] –, guidelines for commercial and open source software development [26] ,, and on empirical studies of scientific computing [28] – [31] and software development in general (summarized in [32] ). None of these practices will guarantee efficient, error-free software development, but used in concert they will reduce the number of errors in scientific software, make it easier to reuse, and save the authors of the software time and effort that can used for focusing on the underlying scientific questions.”
object of study — evidence — “We describe a set of best practices for scientific software development, based on research and experience, that will improve scientists' productivity and the reliability of their software.”
research question — evidence — “This paper describes a set of practices that are easy to adopt and have proven effective in many research settings. Our recommendations are based on several decades of collective experience both building scientific software and teaching computing to scientists [17] , [18] , reports from many other groups [19] –, guidelines for commercial and open source software development [26] ,, and on empirical studies of scientific computing [28] – [31] and software development in general (summarized in [32] ). None of these practices will guarantee efficient, error-free software development, but used in concert they will reduce the number of errors in scientific software, make it easier to reuse, and save the authors of the software time and effort that can used for focusing on the underlying scientific questions.”
contribution — evidence — “We have outlined a series of recommended best practices for scientific computing based on extensive research, as well as our collective experience. These practices can be applied to individual work as readily as group work; separately and together, they improve the productivity of scientific programming and the reliability of the resulting code, and therefore the speed with which we produce results and our confidence in them. They are also, we believe, prerequisites for reproducible computational research: if software is not version controlled, readable, and tested, the chances of its authors (much less anyone else) being able to re-create results are remote.”
mechanismreused software errors cascade across projects and can trigger downstream publication corrections or retractions — “In addition, because software is often used for more than a single project, and is often reused by other scientists, computing errors can have disproportionate impacts on the scientific process. This type of cascading impact caused several prominent retractions when an error from another group's code was not discovered until after publication [6] . As with bench experiments, not everything must be done to the most exacting standards; however, scientists need to be aware of best practices both to improve their own approaches and for reviewing computational work by others.”mechanisms[0]
mechanismsingle-task functions keep the number of facts required for comprehension within working-memory limits — “First, a program should not require its readers to hold more than a handful of facts in memory at once (1a) . Human working memory can hold only a handful of items at a time, where each item is either a single fact or a “chunk” aggregating several facts [33] , [34] , so programs should limit the total number of items to be remembered to accomplish a task. The primary way to accomplish this is to break programs up into easily understood functions, each of which conducts a single, easily understood, task. This serves to make each piece of the program easier to understand in the same way that breaking up a scientific paper using sections and paragraphs makes it easier to read.”mechanisms[1]
mechanismsaved commands and build tools convert repetitive manual operations into repeatable dependency-driven workflows — “To avoid errors and inefficiencies from repeating commands manually, we recommend that scientists use a build tool to automate workflows (2c) , e.g., specify the ways in which intermediate data files and final results depend on each other, and on the programs that create them, so that a single command will regenerate anything that needs to be regenerated.”mechanisms[2]
mechanismidentifiers, versions, parameters, and program names provide machine-readable provenance for regenerated output — “In order to maximize reproducibility, everything needed to re-create the output should be recorded automatically in a format that other programs can read. (Borrowing a term from archaeology and forensics, this is often called the provenance of data.) There have been some initiatives to automate the collection of this information, and standardize its format [43] , but it is already possible to record the following without additional tools: unique identifiers and version numbers for raw data records (which scientists may need to create themselves); unique identifiers and version numbers for programs and libraries; the values of parameters used to generate any given output; and the names and version numbers of programs (however small) used to generate those outputs.”mechanisms[3]
mechanismshort iterations produce working code while incorporating feedback as scientific requirements change — “Programmers are most productive when they work in small steps with frequent feedback and course correction (3a) rather than trying to plan months or years of work in advance. While the details vary from team to team, these developers typically work in steps that are sized to be about an hour long, and these steps are often grouped in iterations that last roughly one week. This accommodates the cognitive constraints discussed in the first section, and acknowledges the reality that real-world requirements are constantly changing. The goal is to produce working (if incomplete) code after each iteration. While these practices have been around for decades, they gained prominence starting in the late 1990s under the banner of agile development [45] , [46] .”mechanisms[4]
mechanismversion control stores snapshots, conflicts, history, authorship, and change comments for code and data — “Crucially, if several people have edited files simultaneously, the VCS highlights the differences and requires them to resolve any conflicts before accepting the changes. The VCS also stores the entire history of those files, allowing arbitrary versions to be retrieved and compared, together with metadata such as comments on what was changed and the author of the changes. All of this information can be extracted to provide provenance for both code and data.”mechanisms[5]
mechanismsingle authoritative representations and modular reuse let one correction propagate everywhere — “The DRY Principle applies to code at two scales. At small scales, modularize code rather than copying and pasting (4b) . Avoiding “code clones” has been shown to reduce error rates [50] : when a change is made or a bug is fixed, that change or fix takes effect everywhere, and people's mental model of the program (i.e., their belief that “this one's been fixed”) remains accurate. As a side effect, modularizing code allows people to remember its functionality as a single mental chunk, which in turn makes code easier to understand. Modularized code can also be more easily repurposed for other projects.”mechanisms[6]
mechanismassertions stop execution near the fault while simultaneously documenting conditions the program expects — “Assertions can make up a sizeable fraction of the code in well-written applications, just as tools for calibrating scientific instruments can make up a sizeable fraction of the equipment in a lab. These assertions serve two purposes. First, they ensure that if something does go wrong, the program will halt immediately, which simplifies debugging. Second, assertions are executable documentation , i.e., they explain the program as well as checking its behavior. This makes them more useful in many cases than comments since the reader can be sure that they are accurate and up to date.”mechanisms[7]
mechanismunit, integration, and regression tests check components, combinations, and behavioral stability — “The second layer of defense is automated testing . Automated tests can check to make sure that a single unit of code is returning correct results ( unit tests ), that pieces of code work correctly when combined ( integration tests ), and that the behavior of a program doesn't change when the details are modified ( regression tests ). These tests are conducted by the computer, so that they are easy to rerun every time the program is modified. Creating and managing tests is easier if programmers use an off-the-shelf unit testing library (5b) to initialize inputs, run tests, and report their results in a uniform way. These libraries are available for all major programming languages including those commonly used in scientific computing [54] – [56] .”mechanisms[8]
mechanismturning a discovered bug into a test case prevents unnoticed recurrence — “Tests check to see whether the code matches the researcher's expectations of its behavior, which depends on the researcher's understanding of the problem at hand [57] – [59] . For example, in scientific computing, tests are often conducted by comparing output to simplified cases, experimental data, or the results of earlier programs that are trusted. Another approach for generating tests is to turn bugs into test cases (5c) by writing tests that trigger a bug that has been found in the code and (once fixed) will prevent the bug from reappearing unnoticed. In combination these kinds of testing can improve our confidence that scientific code is operating properly and that the results it produces are valid. An additional benefit of testing is that it encourages programmers to design and build code that is testable (i.e., self-contained functions and classes that can run more or less independently of one another). Code that is designed this way is also easier to understand and more reusable.”mechanisms[9]
mechanismprofiling locates actual bottlenecks before low-level optimization effort is spent — “Today's computers and software are so complex that even experts find it hard to predict which parts of any particular program will be performance bottlenecks [61] . The most productive way to make code fast is therefore to make it work correctly, determine whether it's actually worth speeding it up, and—in those cases where it is—to use a profiler to identify bottlenecks (6a) .”mechanisms[10]
mechanismhigh-level prototypes provide rapid design feedback and trusted outputs for optimized implementations — “Taking this approach allows more code to be written (and tested) in the same amount of time. Even when it is known before coding begins that a low-level language will ultimately be necessary, rapid prototyping in a high-level language helps programmers make and evaluate design decisions quickly. Programmers can also use a high-level prototype as a test oracle for a high-performance low-level reimplementation, i.e., compare the output of the optimized (and usually more complex) program against the output from its unoptimized (but usually simpler) predecessor in order to check its correctness.”mechanisms[11]
mechanismembedded documentation and generators keep human-readable references close to changing source code — “Embedded documentation usually takes the form of specially-formatted and placed comments. Typically, a documentation generator such as Javadoc, Doxygen, or Sphinx extracts these comments and generates well-formatted web pages and other human-friendly documents ( http://en.wikipedia.org/wiki/Comparison_of_documentation_generators ). Alternatively, code can be embedded in a larger document that includes information about what the code is doing (i.e., literate programming). Common approaches to this include this use of knitr [63] and IPython Notebooks [64] .”mechanisms[12]
mechanismpre-merge review, pair roles, and issue tracking distribute defect finding and project knowledge — “In the same way that having manuscripts reviewed by other scientists can reduce errors and make research easier to understand, reviews of source code can eliminate bugs and improve readability. A large body of research has shown that code reviews are the most cost-effective way of finding bugs in code [65] , [66] . They are also a good way to spread knowledge and good practices around a team. In projects with shifting membership, such as most academic labs, code reviews help ensure that critical knowledge isn't lost when a student or postdoc leaves the lab.”mechanisms[13]
proposes a research- and experience-based set of scientific software-development practices — “We describe a set of best practices for scientific software development, based on research and experience, that will improve scientists' productivity and the reliability of their software.”claim_relations[0]
argues scientific software should be validated as carefully as physical experimental apparatus — “We believe that software is just another kind of experimental apparatus [3] and should be built, checked, and used as carefully as any physical apparatus. However, while most scientists are careful to validate their laboratory and field equipment, most do not know how reliable their software is [4] , [5] . This can lead to serious errors impacting the central conclusions of published research [6] : recent high-profile retractions, technical comments, and corrections because of errors in computational methods include papers in Science [7] , [8] , PNAS [9] , the Journal of Molecular Biology [10] , Ecology Letters [11] , [12] , the Journal of Mammalogy [13] , Journal of the American College of Cardiology [14] , Hypertension [15] , and The American Economic Review [16] .”claim_relations[1]
recommends programs designed for limited human working memory and reliable comprehension — “Scientists writing software need to write code that both executes correctly and can be easily read and understood by other programmers (especially the author's future self). If software cannot be easily read and understood, it is much more difficult to know that it is actually doing what it is intended to do. To be productive, software developers must therefore take several aspects of human cognition into account: in particular, that human working memory is limited, human pattern matching abilities are finely tuned, and human attention span is short [33] – [37] .”claim_relations[2]
recommends automated workflows with machine-readable provenance — “To avoid errors and inefficiencies from repeating commands manually, we recommend that scientists use a build tool to automate workflows (2c) , e.g., specify the ways in which intermediate data files and final results depend on each other, and on the programs that create them, so that a single command will regenerate anything that needs to be regenerated.”claim_relations[3]
supports small incremental changes and version control under changing research requirements — “Programmers are most productive when they work in small steps with frequent feedback and course correction (3a) rather than trying to plan months or years of work in advance. While the details vary from team to team, these developers typically work in steps that are sized to be about an hour long, and these steps are often grouped in iterations that last roughly one week. This accommodates the cognitive constraints discussed in the first section, and acknowledges the reality that real-world requirements are constantly changing. The goal is to produce working (if incomplete) code after each iteration. While these practices have been around for decades, they gained prominence starting in the late 1990s under the banner of agile development [45] , [46] .”claim_relations[4]
recommends single-source data, modular code, and reuse of established libraries — “The DRY Principle applies to code at two scales. At small scales, modularize code rather than copying and pasting (4b) . Avoiding “code clones” has been shown to reduce error rates [50] : when a change is made or a bug is fixed, that change or fix takes effect everywhere, and people's mental model of the program (i.e., their belief that “this one's been fixed”) remains accurate. As a side effect, modularizing code allows people to remember its functionality as a single mental chunk, which in turn makes code easier to understand. Modularized code can also be more easily repurposed for other projects.”claim_relations[5]
supports layered defensive programming, automated tests, regression cases, and interactive debugging — “The second layer of defense is automated testing . Automated tests can check to make sure that a single unit of code is returning correct results ( unit tests ), that pieces of code work correctly when combined ( integration tests ), and that the behavior of a program doesn't change when the details are modified ( regression tests ). These tests are conducted by the computer, so that they are easy to rerun every time the program is modified. Creating and managing tests is easier if programmers use an off-the-shelf unit testing library (5b) to initialize inputs, run tests, and report their results in a uniform way. These libraries are available for all major programming languages including those commonly used in scientific computing [54] – [56] .”claim_relations[6]
recommends correctness before profiler-guided optimization and low-level reimplementation — “Today's computers and software are so complex that even experts find it hard to predict which parts of any particular program will be performance bottlenecks [61] . The most productive way to make code fast is therefore to make it work correctly, determine whether it's actually worth speeding it up, and—in those cases where it is—to use a profiler to identify bottlenecks (6a) .”claim_relations[7]
recommends documentation of interfaces, reasons, design, and purpose rather than mechanics — “In the same way that a well documented experimental protocol makes research methods easier to reproduce, good documentation helps people understand code. This makes the code more reusable and lowers maintenance costs [47] . As a result, code that is well documented makes it easier to transition when the graduate students and postdocs who have been writing code in a lab transition to the next career phase. Reference documentation and descriptions of design decisions are key for improving the understandability of code. However, inline documentation that recapitulates code is not useful. Therefore we recommend that scientific programmers document interfaces and reasons, not implementations (7a) . For example, a clear description like this at the beginning of a function that describes what it does and its inputs and outputs is useful:”claim_relations[8]
supports pre-merge review, selective pair programming, and issue tracking for collaboration — “In the same way that having manuscripts reviewed by other scientists can reduce errors and make research easier to understand, reviews of source code can eliminate bugs and improve readability. A large body of research has shown that code reviews are the most cost-effective way of finding bugs in code [65] , [66] . They are also a good way to spread knowledge and good practices around a team. In projects with shifting membership, such as most academic labs, code reviews help ensure that critical knowledge isn't lost when a student or postdoc leaves the lab.”claim_relations[9]
sensesoftware - a kind of experimental apparatus that requires validation and careful use — “We believe that software is just another kind of experimental apparatus [3] and should be built, checked, and used as carefully as any physical apparatus. However, while most scientists are careful to validate their laboratory and field equipment, most do not know how reliable their software is [4] , [5] . This can lead to serious errors impacting the central conclusions of published research [6] : recent high-profile retractions, technical comments, and corrections because of errors in computational methods include papers in Science [7] , [8] , PNAS [9] , the Journal of Molecular Biology [10] , Ecology Letters [11] , [12] , the Journal of Mammalogy [13] , Journal of the American College of Cardiology [14] , Hypertension [15] , and The American Economic Review [16] .”senses[0]
sensescript - a command file with no substantive difference from a program — “A file containing commands for an interactive system is often called a script , though there is real no difference between this and a program. When these scripts are repeatedly used in the same way, or in combination, a workflow management tool can be used. The paradigmatic example is compiling and linking programs in languages such as Fortran, C++, Java, and C# [40] . The most widely used tool for this task is probably Make ( http://www.gnu.org/software/make ), although many alternatives are now available [41] . All of these allow people to express dependencies between files, i.e., to say that if A or B has changed, then C needs to be updated using a specific set of commands. These tools have been successfully adopted for scientific workflows as well [42] .”senses[1]
senseprovenance of data - machine-readable identifiers, versions, parameters, and programs needed to recreate output — “In order to maximize reproducibility, everything needed to re-create the output should be recorded automatically in a format that other programs can read. (Borrowing a term from archaeology and forensics, this is often called the provenance of data.) There have been some initiatives to automate the collection of this information, and standardize its format [43] , but it is already possible to record the following without additional tools: unique identifiers and version numbers for raw data records (which scientists may need to create themselves); unique identifiers and version numbers for programs and libraries; the values of parameters used to generate any given output; and the names and version numbers of programs (however small) used to generate those outputs.”senses[2]
senseVCS - a version control system storing snapshots and project history in repositories — “The standard solution in both industry and open source is to use a version control system (3b) (VCS) [27] , [47] . A VCS stores snapshots of a project's files in a repository (or a set of repositories). Programmers can modify their working copy of the project at will, then commit changes to the repository when they are satisfied with the results to share them with colleagues.”senses[3]
senseDRY Principle - one authoritative representation for each datum and reusable rather than copied code — “For data, this maxim holds that every piece of data must have a single authoritative representation in the system (4a) . Physical constants ought to be defined exactly once to ensure that the entire program is using the same value; raw data files should have a single canonical version, every geographic location from which data has been collected should be given an ID that can be used to look up its latitude and longitude, and so on.”senses[4]
senseassertion - an executable statement that a condition holds at a point in a program — “The first line of defense is defensive programming . Experienced programmers add assertions to programs to check their operation (5a) because experience has taught them that everyone (including their future self) makes mistakes. An assertion is simply a statement that something holds true at a particular point in a program; as the example below shows, assertions can be used to ensure that inputs are valid, outputs are consistent, and so on.”senses[5]
senseautomated testing - unit, integration, and regression checks rerun by a computer — “The second layer of defense is automated testing . Automated tests can check to make sure that a single unit of code is returning correct results ( unit tests ), that pieces of code work correctly when combined ( integration tests ), and that the behavior of a program doesn't change when the details are modified ( regression tests ). These tests are conducted by the computer, so that they are easy to rerun every time the program is modified. Creating and managing tests is easier if programmers use an off-the-shelf unit testing library (5b) to initialize inputs, run tests, and report their results in a uniform way. These libraries are available for all major programming languages including those commonly used in scientific computing [54] – [56] .”senses[6]
sensesymbolic debugger - an interactive program inspector exposing live execution state — “No matter how good one's computational practice is, reasonably complex code will always initially contain bugs. Fixing bugs that have been identified is often easier if you use a symbolic debugger (5d) to track them down. A better name for this kind of tool would be “interactive program inspector” since a debugger allows users to pause a program at any line (or when some condition is true), inspect the values of variables, and walk up and down active function calls to figure out why things are behaving the way they are. Debuggers are usually more productive than adding and removing print statements or scrolling through hundreds of lines of log output [60] , because they allow the user to see exactly how the code is executing rather than just snapshots of state of the program at a few moments in time. In other words, the debugger allows the scientist to witness what is going wrong directly, rather than having to anticipate the error or infer the problem using indirect evidence.”senses[7]
sensepair programming - an extreme code-review form joining a code-writing driver and feedback-oriented navigator — “An extreme form of code review is pair programming , in which two developers sit together while writing code. One (the driver) actually writes the code; the other (the navigator) provides real-time feedback and is free to track larger issues of design and consistency. Several studies have found that pair programming improves productivity [67] , but many programmers find it intrusive. We therefore recommend that teams use pair programming when bringing someone new up to speed and when tackling particularly tricky problems (8b) .”senses[8]
sensereproducible computational research - results supported by software that is version controlled, readable, and tested — “We have outlined a series of recommended best practices for scientific computing based on extensive research, as well as our collective experience. These practices can be applied to individual work as readily as group work; separately and together, they improve the productivity of scientific programming and the reliability of the resulting code, and therefore the speed with which we produce results and our confidence in them. They are also, we believe, prerequisites for reproducible computational research: if software is not version controlled, readable, and tested, the chances of its authors (much less anyone else) being able to re-create results are remote.”senses[9]
notea research- and experience-based set of scientific software-development practices — The paper's stated contribution. — “We describe a set of best practices for scientific software development, based on research and experience, that will improve scientists' productivity and the reliability of their software.”claim_relations[0]
weighta research- and experience-based set of scientific software-development practices — 0.99 — “We describe a set of best practices for scientific software development, based on research and experience, that will improve scientists' productivity and the reliability of their software.”claim_relations[0]
notescientific software should be validated as carefully as physical experimental apparatus — The central scientific-accountability analogy. — “We believe that software is just another kind of experimental apparatus [3] and should be built, checked, and used as carefully as any physical apparatus. However, while most scientists are careful to validate their laboratory and field equipment, most do not know how reliable their software is [4] , [5] . This can lead to serious errors impacting the central conclusions of published research [6] : recent high-profile retractions, technical comments, and corrections because of errors in computational methods include papers in Science [7] , [8] , PNAS [9] , the Journal of Molecular Biology [10] , Ecology Letters [11] , [12] , the Journal of Mammalogy [13] , Journal of the American College of Cardiology [14] , Hypertension [15] , and The American Economic Review [16] .”claim_relations[1]
weightscientific software should be validated as carefully as physical experimental apparatus — 0.99 — “We believe that software is just another kind of experimental apparatus [3] and should be built, checked, and used as carefully as any physical apparatus. However, while most scientists are careful to validate their laboratory and field equipment, most do not know how reliable their software is [4] , [5] . This can lead to serious errors impacting the central conclusions of published research [6] : recent high-profile retractions, technical comments, and corrections because of errors in computational methods include papers in Science [7] , [8] , PNAS [9] , the Journal of Molecular Biology [10] , Ecology Letters [11] , [12] , the Journal of Mammalogy [13] , Journal of the American College of Cardiology [14] , Hypertension [15] , and The American Economic Review [16] .”claim_relations[1]
noteprograms designed for limited human working memory and reliable comprehension — The human-readable-program practice. — “Scientists writing software need to write code that both executes correctly and can be easily read and understood by other programmers (especially the author's future self). If software cannot be easily read and understood, it is much more difficult to know that it is actually doing what it is intended to do. To be productive, software developers must therefore take several aspects of human cognition into account: in particular, that human working memory is limited, human pattern matching abilities are finely tuned, and human attention span is short [33] – [37] .”claim_relations[2]
weightprograms designed for limited human working memory and reliable comprehension — 0.99 — “Scientists writing software need to write code that both executes correctly and can be easily read and understood by other programmers (especially the author's future self). If software cannot be easily read and understood, it is much more difficult to know that it is actually doing what it is intended to do. To be productive, software developers must therefore take several aspects of human cognition into account: in particular, that human working memory is limited, human pattern matching abilities are finely tuned, and human attention span is short [33] – [37] .”claim_relations[2]
noteautomated workflows with machine-readable provenance — The automation and provenance practice. — “To avoid errors and inefficiencies from repeating commands manually, we recommend that scientists use a build tool to automate workflows (2c) , e.g., specify the ways in which intermediate data files and final results depend on each other, and on the programs that create them, so that a single command will regenerate anything that needs to be regenerated.”claim_relations[3]
weightautomated workflows with machine-readable provenance — 0.99 — “To avoid errors and inefficiencies from repeating commands manually, we recommend that scientists use a build tool to automate workflows (2c) , e.g., specify the ways in which intermediate data files and final results depend on each other, and on the programs that create them, so that a single command will regenerate anything that needs to be regenerated.”claim_relations[3]
notesmall incremental changes and version control under changing research requirements — The incremental-development practice. — “Programmers are most productive when they work in small steps with frequent feedback and course correction (3a) rather than trying to plan months or years of work in advance. While the details vary from team to team, these developers typically work in steps that are sized to be about an hour long, and these steps are often grouped in iterations that last roughly one week. This accommodates the cognitive constraints discussed in the first section, and acknowledges the reality that real-world requirements are constantly changing. The goal is to produce working (if incomplete) code after each iteration. While these practices have been around for decades, they gained prominence starting in the late 1990s under the banner of agile development [45] , [46] .”claim_relations[4]
weightsmall incremental changes and version control under changing research requirements — 0.99 — “Programmers are most productive when they work in small steps with frequent feedback and course correction (3a) rather than trying to plan months or years of work in advance. While the details vary from team to team, these developers typically work in steps that are sized to be about an hour long, and these steps are often grouped in iterations that last roughly one week. This accommodates the cognitive constraints discussed in the first section, and acknowledges the reality that real-world requirements are constantly changing. The goal is to produce working (if incomplete) code after each iteration. While these practices have been around for decades, they gained prominence starting in the late 1990s under the banner of agile development [45] , [46] .”claim_relations[4]
notesingle-source data, modular code, and reuse of established libraries — The DRY and reuse practice. — “The DRY Principle applies to code at two scales. At small scales, modularize code rather than copying and pasting (4b) . Avoiding “code clones” has been shown to reduce error rates [50] : when a change is made or a bug is fixed, that change or fix takes effect everywhere, and people's mental model of the program (i.e., their belief that “this one's been fixed”) remains accurate. As a side effect, modularizing code allows people to remember its functionality as a single mental chunk, which in turn makes code easier to understand. Modularized code can also be more easily repurposed for other projects.”claim_relations[5]
weightsingle-source data, modular code, and reuse of established libraries — 0.99 — “The DRY Principle applies to code at two scales. At small scales, modularize code rather than copying and pasting (4b) . Avoiding “code clones” has been shown to reduce error rates [50] : when a change is made or a bug is fixed, that change or fix takes effect everywhere, and people's mental model of the program (i.e., their belief that “this one's been fixed”) remains accurate. As a side effect, modularizing code allows people to remember its functionality as a single mental chunk, which in turn makes code easier to understand. Modularized code can also be more easily repurposed for other projects.”claim_relations[5]
notelayered defensive programming, automated tests, regression cases, and interactive debugging — The plan-for-mistakes practice. — “The second layer of defense is automated testing . Automated tests can check to make sure that a single unit of code is returning correct results ( unit tests ), that pieces of code work correctly when combined ( integration tests ), and that the behavior of a program doesn't change when the details are modified ( regression tests ). These tests are conducted by the computer, so that they are easy to rerun every time the program is modified. Creating and managing tests is easier if programmers use an off-the-shelf unit testing library (5b) to initialize inputs, run tests, and report their results in a uniform way. These libraries are available for all major programming languages including those commonly used in scientific computing [54] – [56] .”claim_relations[6]
weightlayered defensive programming, automated tests, regression cases, and interactive debugging — 0.99 — “The second layer of defense is automated testing . Automated tests can check to make sure that a single unit of code is returning correct results ( unit tests ), that pieces of code work correctly when combined ( integration tests ), and that the behavior of a program doesn't change when the details are modified ( regression tests ). These tests are conducted by the computer, so that they are easy to rerun every time the program is modified. Creating and managing tests is easier if programmers use an off-the-shelf unit testing library (5b) to initialize inputs, run tests, and report their results in a uniform way. These libraries are available for all major programming languages including those commonly used in scientific computing [54] – [56] .”claim_relations[6]
notecorrectness before profiler-guided optimization and low-level reimplementation — The optimization practice. — “Today's computers and software are so complex that even experts find it hard to predict which parts of any particular program will be performance bottlenecks [61] . The most productive way to make code fast is therefore to make it work correctly, determine whether it's actually worth speeding it up, and—in those cases where it is—to use a profiler to identify bottlenecks (6a) .”claim_relations[7]
weightcorrectness before profiler-guided optimization and low-level reimplementation — 0.99 — “Today's computers and software are so complex that even experts find it hard to predict which parts of any particular program will be performance bottlenecks [61] . The most productive way to make code fast is therefore to make it work correctly, determine whether it's actually worth speeding it up, and—in those cases where it is—to use a profiler to identify bottlenecks (6a) .”claim_relations[7]
notedocumentation of interfaces, reasons, design, and purpose rather than mechanics — The documentation practice. — “In the same way that a well documented experimental protocol makes research methods easier to reproduce, good documentation helps people understand code. This makes the code more reusable and lowers maintenance costs [47] . As a result, code that is well documented makes it easier to transition when the graduate students and postdocs who have been writing code in a lab transition to the next career phase. Reference documentation and descriptions of design decisions are key for improving the understandability of code. However, inline documentation that recapitulates code is not useful. Therefore we recommend that scientific programmers document interfaces and reasons, not implementations (7a) . For example, a clear description like this at the beginning of a function that describes what it does and its inputs and outputs is useful:”claim_relations[8]
weightdocumentation of interfaces, reasons, design, and purpose rather than mechanics — 0.99 — “In the same way that a well documented experimental protocol makes research methods easier to reproduce, good documentation helps people understand code. This makes the code more reusable and lowers maintenance costs [47] . As a result, code that is well documented makes it easier to transition when the graduate students and postdocs who have been writing code in a lab transition to the next career phase. Reference documentation and descriptions of design decisions are key for improving the understandability of code. However, inline documentation that recapitulates code is not useful. Therefore we recommend that scientific programmers document interfaces and reasons, not implementations (7a) . For example, a clear description like this at the beginning of a function that describes what it does and its inputs and outputs is useful:”claim_relations[8]
notepre-merge review, selective pair programming, and issue tracking for collaboration — The collaboration practice. — “In the same way that having manuscripts reviewed by other scientists can reduce errors and make research easier to understand, reviews of source code can eliminate bugs and improve readability. A large body of research has shown that code reviews are the most cost-effective way of finding bugs in code [65] , [66] . They are also a good way to spread knowledge and good practices around a team. In projects with shifting membership, such as most academic labs, code reviews help ensure that critical knowledge isn't lost when a student or postdoc leaves the lab.”claim_relations[9]
weightpre-merge review, selective pair programming, and issue tracking for collaboration — 0.99 — “In the same way that having manuscripts reviewed by other scientists can reduce errors and make research easier to understand, reviews of source code can eliminate bugs and improve readability. A large body of research has shown that code reviews are the most cost-effective way of finding bugs in code [65] , [66] . They are also a good way to spread knowledge and good practices around a team. In projects with shifting membership, such as most academic labs, code reviews help ensure that critical knowledge isn't lost when a student or postdoc leaves the lab.”claim_relations[9]
notecomputing errors —causes→ prominent retractions — Direct positive causal direction. — “In addition, because software is often used for more than a single project, and is often reused by other scientists, computing errors can have disproportionate impacts on the scientific process. This type of cascading impact caused several prominent retractions when an error from another group's code was not discovered until after publication [6] . As with bench experiments, not everything must be done to the most exacting standards; however, scientists need to be aware of best practices both to improve their own approaches and for reviewing computational work by others.”concept_edges[0]
relationcomputing errors —causes→ prominent retractions — A cascading error from reused code caused several prominent retractions. — “In addition, because software is often used for more than a single project, and is often reused by other scientists, computing errors can have disproportionate impacts on the scientific process. This type of cascading impact caused several prominent retractions when an error from another group's code was not discovered until after publication [6] . As with bench experiments, not everything must be done to the most exacting standards; however, scientists need to be aware of best practices both to improve their own approaches and for reviewing computational work by others.”concept_edges[0]
weightcomputing errors —causes→ prominent retractions — 0.8 — “In addition, because software is often used for more than a single project, and is often reused by other scientists, computing errors can have disproportionate impacts on the scientific process. This type of cascading impact caused several prominent retractions when an error from another group's code was not discovered until after publication [6] . As with bench experiments, not everything must be done to the most exacting standards; however, scientists need to be aware of best practices both to improve their own approaches and for reviewing computational work by others.”concept_edges[0]
notescientific programmers —distinct-from→ traditional commercial software developers — Explicit unlike contrast. — “Unlike traditional commercial software developers, but very much like developers in open source projects or startups, scientific programmers usually don't get their requirements from customers, and their requirements are rarely frozen [31] , [44] . In fact, scientists often can't know what their programs should do next until the current version has produced some results. This challenges design approaches that rely on specifying requirements in advance.”concept_edges[1]
relationscientific programmers —distinct-from→ traditional commercial software developers — Scientific programmers differ from traditional commercial developers because their requirements are rarely fixed in advance. — “Unlike traditional commercial software developers, but very much like developers in open source projects or startups, scientific programmers usually don't get their requirements from customers, and their requirements are rarely frozen [31] , [44] . In fact, scientists often can't know what their programs should do next until the current version has produced some results. This challenges design approaches that rely on specifying requirements in advance.”concept_edges[1]
notedriver —distinct-from→ navigator — Explicit role contrast within one method. — “An extreme form of code review is pair programming , in which two developers sit together while writing code. One (the driver) actually writes the code; the other (the navigator) provides real-time feedback and is free to track larger issues of design and consistency. Several studies have found that pair programming improves productivity [67] , but many programmers find it intrusive. We therefore recommend that teams use pair programming when bringing someone new up to speed and when tackling particularly tricky problems (8b) .”concept_edges[2]
relationdriver —distinct-from→ navigator — The driver writes code whereas the navigator provides real-time feedback and tracks larger design issues. — “An extreme form of code review is pair programming , in which two developers sit together while writing code. One (the driver) actually writes the code; the other (the navigator) provides real-time feedback and is free to track larger issues of design and consistency. Several studies have found that pair programming improves productivity [67] , but many programmers find it intrusive. We therefore recommend that teams use pair programming when bringing someone new up to speed and when tackling particularly tricky problems (8b) .”concept_edges[2]
relationsoftware → experimental apparatus — Software is another kind of experimental apparatus. — “We believe that software is just another kind of experimental apparatus [3] and should be built, checked, and used as carefully as any physical apparatus. However, while most scientists are careful to validate their laboratory and field equipment, most do not know how reliable their software is [4] , [5] . This can lead to serious errors impacting the central conclusions of published research [6] : recent high-profile retractions, technical comments, and corrections because of errors in computational methods include papers in Science [7] , [8] , PNAS [9] , the Journal of Molecular Biology [10] , Ecology Letters [11] , [12] , the Journal of Mammalogy [13] , Journal of the American College of Cardiology [14] , Hypertension [15] , and The American Economic Review [16] .”unhoused_relations[0]
relationscript → program — There is no real difference between a script and a program. — “A file containing commands for an interactive system is often called a script , though there is real no difference between this and a program. When these scripts are repeatedly used in the same way, or in combination, a workflow management tool can be used. The paradigmatic example is compiling and linking programs in languages such as Fortran, C++, Java, and C# [40] . The most widely used tool for this task is probably Make ( http://www.gnu.org/software/make ), although many alternatives are now available [41] . All of these allow people to express dependencies between files, i.e., to say that if A or B has changed, then C needs to be updated using a specific set of commands. These tools have been successfully adopted for scientific workflows as well [42] .”unhoused_relations[1]
relationassertion → statement — An assertion is simply a statement that something holds true at a particular point in a program. — “The first line of defense is defensive programming . Experienced programmers add assertions to programs to check their operation (5a) because experience has taught them that everyone (including their future self) makes mistakes. An assertion is simply a statement that something holds true at a particular point in a program; as the example below shows, assertions can be used to ensure that inputs are valid, outputs are consistent, and so on.”unhoused_relations[2]
relationpair programming → code review — Pair programming is an extreme form of code review. — “An extreme form of code review is pair programming , in which two developers sit together while writing code. One (the driver) actually writes the code; the other (the navigator) provides real-time feedback and is free to track larger issues of design and consistency. Several studies have found that pair programming improves productivity [67] , but many programmers find it intrusive. We therefore recommend that teams use pair programming when bringing someone new up to speed and when tackling particularly tricky problems (8b) .”unhoused_relations[3]
relationprimarily self-taught → basic software development practices — Most scientific programmers are self-taught and lack exposure to basic development practices. — “Scientists typically develop their own software for these purposes because doing so requires substantial domain-specific knowledge. As a result, recent studies have found that scientists typically spend 30% or more of their time developing software [1] , [2] . However, 90% or more of them are primarily self-taught [1] , [2] , and therefore lack exposure to basic software development practices such as writing maintainable code, using version control and issue trackers, code reviews, unit testing, and task automation.”unhoused_relations[4]
weightprimarily self-taught → basic software development practices — 0.95 — “Scientists typically develop their own software for these purposes because doing so requires substantial domain-specific knowledge. As a result, recent studies have found that scientists typically spend 30% or more of their time developing software [1] , [2] . However, 90% or more of them are primarily self-taught [1] , [2] , and therefore lack exposure to basic software development practices such as writing maintainable code, using version control and issue trackers, code reviews, unit testing, and task automation.”unhoused_relations[4]
relationhow reliable their software is → central conclusions of published research — Unknown software reliability can lead to errors that affect central research conclusions. — “We believe that software is just another kind of experimental apparatus [3] and should be built, checked, and used as carefully as any physical apparatus. However, while most scientists are careful to validate their laboratory and field equipment, most do not know how reliable their software is [4] , [5] . This can lead to serious errors impacting the central conclusions of published research [6] : recent high-profile retractions, technical comments, and corrections because of errors in computational methods include papers in Science [7] , [8] , PNAS [9] , the Journal of Molecular Biology [10] , Ecology Letters [11] , [12] , the Journal of Mammalogy [13] , Journal of the American College of Cardiology [14] , Hypertension [15] , and The American Economic Review [16] .”unhoused_relations[5]
weighthow reliable their software is → central conclusions of published research — 0.8 — “We believe that software is just another kind of experimental apparatus [3] and should be built, checked, and used as carefully as any physical apparatus. However, while most scientists are careful to validate their laboratory and field equipment, most do not know how reliable their software is [4] , [5] . This can lead to serious errors impacting the central conclusions of published research [6] : recent high-profile retractions, technical comments, and corrections because of errors in computational methods include papers in Science [7] , [8] , PNAS [9] , the Journal of Molecular Biology [10] , Ecology Letters [11] , [12] , the Journal of Mammalogy [13] , Journal of the American College of Cardiology [14] , Hypertension [15] , and The American Economic Review [16] .”unhoused_relations[5]
relationbest practices → error-free software development — No combination of the recommended practices guarantees efficient error-free development. — “This paper describes a set of practices that are easy to adopt and have proven effective in many research settings. Our recommendations are based on several decades of collective experience both building scientific software and teaching computing to scientists [17] , [18] , reports from many other groups [19] –, guidelines for commercial and open source software development [26] ,, and on empirical studies of scientific computing [28] – [31] and software development in general (summarized in [32] ). None of these practices will guarantee efficient, error-free software development, but used in concert they will reduce the number of errors in scientific software, make it easier to reuse, and save the authors of the software time and effort that can used for focusing on the underlying scientific questions.”unhoused_relations[6]
relationbest practices → reproducible research — The described skills make reproducible research and open science easier to implement. — “Our practices are summarized in Box 1 ; labels in the main text such as “(1a)” refer to items in that summary. For reasons of space, we do not discuss the equally important (but independent) issues of reproducible research, publication and citation of code and data, and open science. We do believe, however, that all of these will be much easier to implement if scientists have the skills we describe.”unhoused_relations[7]
weightbest practices → reproducible research — 0.85 — “Our practices are summarized in Box 1 ; labels in the main text such as “(1a)” refer to items in that summary. For reasons of space, we do not discuss the equally important (but independent) issues of reproducible research, publication and citation of code and data, and open science. We do believe, however, that all of these will be much easier to implement if scientists have the skills we describe.”unhoused_relations[7]
relationhuman working memory → functions — Limited working memory motivates breaking programs into single-task functions. — “First, a program should not require its readers to hold more than a handful of facts in memory at once (1a) . Human working memory can hold only a handful of items at a time, where each item is either a single fact or a “chunk” aggregating several facts [33] , [34] , so programs should limit the total number of items to be remembered to accomplish a task. The primary way to accomplish this is to break programs up into easily understood functions, each of which conducts a single, easily understood, task. This serves to make each piece of the program easier to understand in the same way that breaking up a scientific paper using sections and paragraphs makes it easier to read.”unhoused_relations[8]
weighthuman working memory → functions — 0.95 — “First, a program should not require its readers to hold more than a handful of facts in memory at once (1a) . Human working memory can hold only a handful of items at a time, where each item is either a single fact or a “chunk” aggregating several facts [33] , [34] , so programs should limit the total number of items to be remembered to accomplish a task. The primary way to accomplish this is to break programs up into easily understood functions, each of which conducts a single, easily understood, task. This serves to make each piece of the program easier to understand in the same way that breaking up a scientific paper using sections and paragraphs makes it easier to read.”unhoused_relations[8]
relationcode style and formatting → readers make more mistakes — Inconsistent formatting makes code slower to read and causes more reader mistakes. — “Third, scientists should make code style and formatting consistent (1c) . If different parts of a scientific paper used different formatting and capitalization, it would make that paper more difficult to read. Likewise, if different parts of a program are indented differently, or if programmers mix CamelCaseNaming and pothole_case_naming, code takes longer to read and readers make more mistakes [35] , [36] .”unhoused_relations[9]
weightcode style and formatting → readers make more mistakes — 0.8 — “Third, scientists should make code style and formatting consistent (1c) . If different parts of a scientific paper used different formatting and capitalization, it would make that paper more difficult to read. Likewise, if different parts of a program are indented differently, or if programmers mix CamelCaseNaming and pothole_case_naming, code takes longer to read and readers make more mistakes [35] , [36] .”unhoused_relations[9]
relationrepetition of computational tasks → mistakes — Manual repetition wastes time and eventually produces mistakes. — “Science often involves repetition of computational tasks such as processing large numbers of data files in the same way or regenerating figures each time new data are added to an existing analysis. Computers were invented to do these kinds of repetitive tasks but, even today, many scientists type the same commands in over and over again or click the same buttons repeatedly [17] . In addition to wasting time, sooner or later even the most careful researcher will lose focus while doing this and make mistakes.”unhoused_relations[10]
weightrepetition of computational tasks → mistakes — 0.8 — “Science often involves repetition of computational tasks such as processing large numbers of data files in the same way or regenerating figures each time new data are added to an existing analysis. Computers were invented to do these kinds of repetitive tasks but, even today, many scientists type the same commands in over and over again or click the same buttons repeatedly [17] . In addition to wasting time, sooner or later even the most careful researcher will lose focus while doing this and make mistakes.”unhoused_relations[10]
relationbuild tool → dependencies between files — A build tool uses declared file dependencies to automate scientific workflows. — “To avoid errors and inefficiencies from repeating commands manually, we recommend that scientists use a build tool to automate workflows (2c) , e.g., specify the ways in which intermediate data files and final results depend on each other, and on the programs that create them, so that a single command will regenerate anything that needs to be regenerated.”unhoused_relations[11]
weightbuild tool → dependencies between files — 0.99 — “To avoid errors and inefficiencies from repeating commands manually, we recommend that scientists use a build tool to automate workflows (2c) , e.g., specify the ways in which intermediate data files and final results depend on each other, and on the programs that create them, so that a single command will regenerate anything that needs to be regenerated.”unhoused_relations[11]
relationprovenance of data → reproducibility — Machine-readable provenance records everything needed to recreate output. — “In order to maximize reproducibility, everything needed to re-create the output should be recorded automatically in a format that other programs can read. (Borrowing a term from archaeology and forensics, this is often called the provenance of data.) There have been some initiatives to automate the collection of this information, and standardize its format [43] , but it is already possible to record the following without additional tools:”unhoused_relations[12]
weightprovenance of data → reproducibility — 0.99 — “In order to maximize reproducibility, everything needed to re-create the output should be recorded automatically in a format that other programs can read. (Borrowing a term from archaeology and forensics, this is often called the provenance of data.) There have been some initiatives to automate the collection of this information, and standardize its format [43] , but it is already possible to record the following without additional tools:”unhoused_relations[12]
relationsmall steps with frequent feedback and course correction → requirements are constantly changing — Small iterative steps accommodate changing scientific requirements. — “Programmers are most productive when they work in small steps with frequent feedback and course correction (3a) rather than trying to plan months or years of work in advance. While the details vary from team to team, these developers typically work in steps that are sized to be about an hour long, and these steps are often grouped in iterations that last roughly one week. This accommodates the cognitive constraints discussed in the first section, and acknowledges the reality that real-world requirements are constantly changing. The goal is to produce working (if incomplete) code after each iteration. While these practices have been around for decades, they gained prominence starting in the late 1990s under the banner of agile development [45] , [46] .”unhoused_relations[13]
weightsmall steps with frequent feedback and course correction → requirements are constantly changing — 0.9 — “Programmers are most productive when they work in small steps with frequent feedback and course correction (3a) rather than trying to plan months or years of work in advance. While the details vary from team to team, these developers typically work in steps that are sized to be about an hour long, and these steps are often grouped in iterations that last roughly one week. This accommodates the cognitive constraints discussed in the first section, and acknowledges the reality that real-world requirements are constantly changing. The goal is to produce working (if incomplete) code after each iteration. While these practices have been around for decades, they gained prominence starting in the late 1990s under the banner of agile development [45] , [46] .”unhoused_relations[13]
relationversion control system → lost work — Version control replaces fragile copying practices that can cause confusion and lost work. — “Two of the biggest challenges scientists and other programmers face when working with code and data are keeping track of changes (and being able to revert them if things go wrong), and collaborating on a program or dataset [23] . Typical solutions are to email software to colleagues or to copy successive versions of it to a shared folder, e.g., Dropbox ( http://www.dropbox.com ). However, both approaches are fragile and can lead to confusion and lost work when important changes are overwritten or out-of-date files are used. It's also difficult to find out which changes are in which versions or to say exactly how particular results were computed at a later date.”unhoused_relations[14]
weightversion control system → lost work — 0.9 — “Two of the biggest challenges scientists and other programmers face when working with code and data are keeping track of changes (and being able to revert them if things go wrong), and collaborating on a program or dataset [23] . Typical solutions are to email software to colleagues or to copy successive versions of it to a shared folder, e.g., Dropbox ( http://www.dropbox.com ). However, both approaches are fragile and can lead to confusion and lost work when important changes are overwritten or out-of-date files are used. It's also difficult to find out which changes are in which versions or to say exactly how particular results were computed at a later date.”unhoused_relations[14]
relationversion control system → provenance for both code and data — Stored histories and metadata provide provenance for code and data. — “Crucially, if several people have edited files simultaneously, the VCS highlights the differences and requires them to resolve any conflicts before accepting the changes. The VCS also stores the entire history of those files, allowing arbitrary versions to be retrieved and compared, together with metadata such as comments on what was changed and the author of the changes. All of this information can be extracted to provide provenance for both code and data.”unhoused_relations[15]
weightversion control system → provenance for both code and data — 0.95 — “Crucially, if several people have edited files simultaneously, the VCS highlights the differences and requires them to resolve any conflicts before accepting the changes. The VCS also stores the entire history of those files, allowing arbitrary versions to be retrieved and compared, together with metadata such as comments on what was changed and the author of the changes. All of this information can be extracted to provide provenance for both code and data.”unhoused_relations[15]
relationeverything that has been created manually → version control system — Reproducibility is maximized when all manually created materials are version controlled. — “Reproducibility is maximized when scientists put everything that has been created manually in version control (3c) , including programs, original field observations, and the source files for papers. Automated output and intermediate files can be regenerated as needed. Binary files (e.g., images and audio clips) may be stored in version control, but it is often more sensible to use an archiving system for them, and store the metadata describing their contents in version control instead [48] .”unhoused_relations[16]
weighteverything that has been created manually → version control system — 0.95 — “Reproducibility is maximized when scientists put everything that has been created manually in version control (3c) , including programs, original field observations, and the source files for papers. Automated output and intermediate files can be regenerated as needed. Binary files (e.g., images and audio clips) may be stored in version control, but it is often more sensible to use an archiving system for them, and store the metadata describing their contents in version control instead [48] .”unhoused_relations[16]
relationDRY Principle → errors and inconsistencies — Avoiding repeated representations reduces the chance of update errors and inconsistencies. — “Anything that is repeated in two or more places is more difficult to maintain. Every time a change or correction is made, multiple locations must be updated, which increases the chance of errors and inconsistencies. To avoid this, programmers follow the DRY Principle [49] , for “don't repeat yourself,” which applies to both data and code.”unhoused_relations[17]
weightDRY Principle → errors and inconsistencies — 0.9 — “Anything that is repeated in two or more places is more difficult to maintain. Every time a change or correction is made, multiple locations must be updated, which increases the chance of errors and inconsistencies. To avoid this, programmers follow the DRY Principle [49] , for “don't repeat yourself,” which applies to both data and code.”unhoused_relations[17]
relationmodularize code → code clones — Modularization avoids code clones and lets fixes take effect everywhere. — “The DRY Principle applies to code at two scales. At small scales, modularize code rather than copying and pasting (4b) . Avoiding “code clones” has been shown to reduce error rates [50] : when a change is made or a bug is fixed, that change or fix takes effect everywhere, and people's mental model of the program (i.e., their belief that “this one's been fixed”) remains accurate. As a side effect, modularizing code allows people to remember its functionality as a single mental chunk, which in turn makes code easier to understand. Modularized code can also be more easily repurposed for other projects.”unhoused_relations[18]
weightmodularize code → code clones — 0.95 — “The DRY Principle applies to code at two scales. At small scales, modularize code rather than copying and pasting (4b) . Avoiding “code clones” has been shown to reduce error rates [50] : when a change is made or a bug is fixed, that change or fix takes effect everywhere, and people's mental model of the program (i.e., their belief that “this one's been fixed”) remains accurate. As a side effect, modularizing code allows people to remember its functionality as a single mental chunk, which in turn makes code easier to understand. Modularized code can also be more easily repurposed for other projects.”unhoused_relations[18]
relationre-use code → established library or package — Scientific programmers should use established packages for solved problems rather than rewrite them. — “At larger scales, it is vital that scientific programmers re-use code instead of rewriting it (4c) . Tens of millions of lines of high-quality open source software are freely available on the web, and at least as much is available commercially. It is typically better to find an established library or package that solves a problem than to attempt to write one's own routines for well established problems (e.g., numerical integration, matrix inversions, etc.).”unhoused_relations[19]
weightre-use code → established library or package — 0.99 — “At larger scales, it is vital that scientific programmers re-use code instead of rewriting it (4c) . Tens of millions of lines of high-quality open source software are freely available on the web, and at least as much is available commercially. It is typically better to find an established library or package that solves a problem than to attempt to write one's own routines for well established problems (e.g., numerical integration, matrix inversions, etc.).”unhoused_relations[19]
relationdefensive programming → mistakes — Assertions and tests form complementary defenses because no single practice catches every mistake. — “Mistakes are inevitable, so verifying and maintaining the validity of code over time is immensely challenging [51] . While no single practice has been shown to catch or prevent all mistakes, several are very effective when used in combination [47] , [52] , [53] .”unhoused_relations[20]
weightdefensive programming → mistakes — 0.95 — “Mistakes are inevitable, so verifying and maintaining the validity of code over time is immensely challenging [51] . While no single practice has been shown to catch or prevent all mistakes, several are very effective when used in combination [47] , [52] , [53] .”unhoused_relations[20]
relationassertion → debugging — An assertion halts a failing program immediately and simplifies debugging. — “Assertions can make up a sizeable fraction of the code in well-written applications, just as tools for calibrating scientific instruments can make up a sizeable fraction of the equipment in a lab. These assertions serve two purposes. First, they ensure that if something does go wrong, the program will halt immediately, which simplifies debugging. Second, assertions are executable documentation , i.e., they explain the program as well as checking its behavior. This makes them more useful in many cases than comments since the reader can be sure that they are accurate and up to date.”unhoused_relations[21]
weightassertion → debugging — 0.95 — “Assertions can make up a sizeable fraction of the code in well-written applications, just as tools for calibrating scientific instruments can make up a sizeable fraction of the equipment in a lab. These assertions serve two purposes. First, they ensure that if something does go wrong, the program will halt immediately, which simplifies debugging. Second, assertions are executable documentation , i.e., they explain the program as well as checking its behavior. This makes them more useful in many cases than comments since the reader can be sure that they are accurate and up to date.”unhoused_relations[21]
relationautomated testing → confidence that scientific code is operating properly — Combined tests improve confidence that code and results are valid. — “Tests check to see whether the code matches the researcher's expectations of its behavior, which depends on the researcher's understanding of the problem at hand [57] – [59] . For example, in scientific computing, tests are often conducted by comparing output to simplified cases, experimental data, or the results of earlier programs that are trusted. Another approach for generating tests is to turn bugs into test cases (5c) by writing tests that trigger a bug that has been found in the code and (once fixed) will prevent the bug from reappearing unnoticed. In combination these kinds of testing can improve our confidence that scientific code is operating properly and that the results it produces are valid. An additional benefit of testing is that it encourages programmers to design and build code that is testable (i.e., self-contained functions and classes that can run more or less independently of one another). Code that is designed this way is also easier to understand and more reusable.”unhoused_relations[22]
weightautomated testing → confidence that scientific code is operating properly — 0.9 — “Tests check to see whether the code matches the researcher's expectations of its behavior, which depends on the researcher's understanding of the problem at hand [57] – [59] . For example, in scientific computing, tests are often conducted by comparing output to simplified cases, experimental data, or the results of earlier programs that are trusted. Another approach for generating tests is to turn bugs into test cases (5c) by writing tests that trigger a bug that has been found in the code and (once fixed) will prevent the bug from reappearing unnoticed. In combination these kinds of testing can improve our confidence that scientific code is operating properly and that the results it produces are valid. An additional benefit of testing is that it encourages programmers to design and build code that is testable (i.e., self-contained functions and classes that can run more or less independently of one another). Code that is designed this way is also easier to understand and more reusable.”unhoused_relations[22]
relationsymbolic debugger → witness what is going wrong directly — A debugger exposes execution directly rather than requiring inference from logs. — “No matter how good one's computational practice is, reasonably complex code will always initially contain bugs. Fixing bugs that have been identified is often easier if you use a symbolic debugger (5d) to track them down. A better name for this kind of tool would be “interactive program inspector” since a debugger allows users to pause a program at any line (or when some condition is true), inspect the values of variables, and walk up and down active function calls to figure out why things are behaving the way they are. Debuggers are usually more productive than adding and removing print statements or scrolling through hundreds of lines of log output [60] , because they allow the user to see exactly how the code is executing rather than just snapshots of state of the program at a few moments in time. In other words, the debugger allows the scientist to witness what is going wrong directly, rather than having to anticipate the error or infer the problem using indirect evidence.”unhoused_relations[23]
weightsymbolic debugger → witness what is going wrong directly — 0.99 — “No matter how good one's computational practice is, reasonably complex code will always initially contain bugs. Fixing bugs that have been identified is often easier if you use a symbolic debugger (5d) to track them down. A better name for this kind of tool would be “interactive program inspector” since a debugger allows users to pause a program at any line (or when some condition is true), inspect the values of variables, and walk up and down active function calls to figure out why things are behaving the way they are. Debuggers are usually more productive than adding and removing print statements or scrolling through hundreds of lines of log output [60] , because they allow the user to see exactly how the code is executing rather than just snapshots of state of the program at a few moments in time. In other words, the debugger allows the scientist to witness what is going wrong directly, rather than having to anticipate the error or infer the problem using indirect evidence.”unhoused_relations[23]
relationprofiler → performance bottlenecks — A profiler is used to identify bottlenecks only after correctness and need are established. — “Today's computers and software are so complex that even experts find it hard to predict which parts of any particular program will be performance bottlenecks [61] . The most productive way to make code fast is therefore to make it work correctly, determine whether it's actually worth speeding it up, and—in those cases where it is—to use a profiler to identify bottlenecks (6a) .”unhoused_relations[24]
weightprofiler → performance bottlenecks — 0.99 — “Today's computers and software are so complex that even experts find it hard to predict which parts of any particular program will be performance bottlenecks [61] . The most productive way to make code fast is therefore to make it work correctly, determine whether it's actually worth speeding it up, and—in those cases where it is—to use a profiler to identify bottlenecks (6a) .”unhoused_relations[24]
relationhighest-level language possible → scientists' productivity — Higher-level languages increase productivity because equivalent tasks require fewer lines of code. — “This strategy also has interesting implications for choice of programming language. Research has confirmed that most programmers write roughly the same number of lines of code per unit time regardless of the language they use [62] . Since faster, lower level, languages require more lines of code to accomplish the same task, scientists are most productive when they write code in the highest-level language possible (6b) , and shift to low-level languages like C and Fortran only when they are sure the performance boost is needed. (Using higher-level languages also helps program comprehensibility, since such languages have, in a sense, “pre-chunked” the facts that programmers need to have in short-term memory.)”unhoused_relations[25]
weighthighest-level language possible → scientists' productivity — 0.85 — “This strategy also has interesting implications for choice of programming language. Research has confirmed that most programmers write roughly the same number of lines of code per unit time regardless of the language they use [62] . Since faster, lower level, languages require more lines of code to accomplish the same task, scientists are most productive when they write code in the highest-level language possible (6b) , and shift to low-level languages like C and Fortran only when they are sure the performance boost is needed. (Using higher-level languages also helps program comprehensibility, since such languages have, in a sense, “pre-chunked” the facts that programmers need to have in short-term memory.)”unhoused_relations[25]
relationrapid prototyping → test oracle — A high-level prototype can serve as a test oracle for a low-level reimplementation. — “Taking this approach allows more code to be written (and tested) in the same amount of time. Even when it is known before coding begins that a low-level language will ultimately be necessary, rapid prototyping in a high-level language helps programmers make and evaluate design decisions quickly. Programmers can also use a high-level prototype as a test oracle for a high-performance low-level reimplementation, i.e., compare the output of the optimized (and usually more complex) program against the output from its unoptimized (but usually simpler) predecessor in order to check its correctness.”unhoused_relations[26]
weightrapid prototyping → test oracle — 0.95 — “Taking this approach allows more code to be written (and tested) in the same amount of time. Even when it is known before coding begins that a low-level language will ultimately be necessary, rapid prototyping in a high-level language helps programmers make and evaluate design decisions quickly. Programmers can also use a high-level prototype as a test oracle for a high-performance low-level reimplementation, i.e., compare the output of the optimized (and usually more complex) program against the output from its unoptimized (but usually simpler) predecessor in order to check its correctness.”unhoused_relations[26]
relationgood documentation → maintenance costs — Good documentation improves reuse and lowers software maintenance costs. — “In the same way that a well documented experimental protocol makes research methods easier to reproduce, good documentation helps people understand code. This makes the code more reusable and lowers maintenance costs [47] . As a result, code that is well documented makes it easier to transition when the graduate students and postdocs who have been writing code in a lab transition to the next career phase. Reference documentation and descriptions of design decisions are key for improving the understandability of code. However, inline documentation that recapitulates code is not useful. Therefore we recommend that scientific programmers document interfaces and reasons, not implementations (7a) . For example, a clear description like this at the beginning of a function that describes what it does and its inputs and outputs is useful:”unhoused_relations[27]
weightgood documentation → maintenance costs — 0.9 — “In the same way that a well documented experimental protocol makes research methods easier to reproduce, good documentation helps people understand code. This makes the code more reusable and lowers maintenance costs [47] . As a result, code that is well documented makes it easier to transition when the graduate students and postdocs who have been writing code in a lab transition to the next career phase. Reference documentation and descriptions of design decisions are key for improving the understandability of code. However, inline documentation that recapitulates code is not useful. Therefore we recommend that scientific programmers document interfaces and reasons, not implementations (7a) . For example, a clear description like this at the beginning of a function that describes what it does and its inputs and outputs is useful:”unhoused_relations[27]
relationinterfaces and reasons → implementations — Documentation should cover interfaces and reasons rather than implementation mechanics. — “In the same way that a well documented experimental protocol makes research methods easier to reproduce, good documentation helps people understand code. This makes the code more reusable and lowers maintenance costs [47] . As a result, code that is well documented makes it easier to transition when the graduate students and postdocs who have been writing code in a lab transition to the next career phase. Reference documentation and descriptions of design decisions are key for improving the understandability of code. However, inline documentation that recapitulates code is not useful. Therefore we recommend that scientific programmers document interfaces and reasons, not implementations (7a) . For example, a clear description like this at the beginning of a function that describes what it does and its inputs and outputs is useful:”unhoused_relations[28]
weightinterfaces and reasons → implementations — 0.99 — “In the same way that a well documented experimental protocol makes research methods easier to reproduce, good documentation helps people understand code. This makes the code more reusable and lowers maintenance costs [47] . As a result, code that is well documented makes it easier to transition when the graduate students and postdocs who have been writing code in a lab transition to the next career phase. Reference documentation and descriptions of design decisions are key for improving the understandability of code. However, inline documentation that recapitulates code is not useful. Therefore we recommend that scientific programmers document interfaces and reasons, not implementations (7a) . For example, a clear description like this at the beginning of a function that describes what it does and its inputs and outputs is useful:”unhoused_relations[28]
relationrefactor code → explaining how it works — Complex code should be refactored instead of explained in a long implementation description. — “If a substantial description of the implementation of a piece of software is needed, it is better to refactor code in preference to explaining how it works (7b) , i.e., rather than write a paragraph to explain a complex piece of code, reorganize the code itself so that it doesn't need such an explanation. This may not always be possible—some pieces of code are intrinsically difficult—but the onus should always be on the author to convince his or her peers of that.”unhoused_relations[29]
weightrefactor code → explaining how it works — 0.95 — “If a substantial description of the implementation of a piece of software is needed, it is better to refactor code in preference to explaining how it works (7b) , i.e., rather than write a paragraph to explain a complex piece of code, reorganize the code itself so that it doesn't need such an explanation. This may not always be possible—some pieces of code are intrinsically difficult—but the onus should always be on the author to convince his or her peers of that.”unhoused_relations[29]
relationreference documentation → software — Embedding reference documentation in software increases the chance it changes with the code. — “The best way to create and maintain reference documentation is to embed the documentation for a piece of software in that software (7c) . Doing this increases the probability that when programmers change the code, they will update the documentation at the same time.”unhoused_relations[30]
weightreference documentation → software — 0.9 — “The best way to create and maintain reference documentation is to embed the documentation for a piece of software in that software (7c) . Doing this increases the probability that when programmers change the code, they will update the documentation at the same time.”unhoused_relations[30]
relationcode reviews → bugs — Code reviews eliminate bugs, improve readability, and spread knowledge and practice. — “In the same way that having manuscripts reviewed by other scientists can reduce errors and make research easier to understand, reviews of source code can eliminate bugs and improve readability. A large body of research has shown that code reviews are the most cost-effective way of finding bugs in code [65] , [66] . They are also a good way to spread knowledge and good practices around a team. In projects with shifting membership, such as most academic labs, code reviews help ensure that critical knowledge isn't lost when a student or postdoc leaves the lab.”unhoused_relations[31]
weightcode reviews → bugs — 0.95 — “In the same way that having manuscripts reviewed by other scientists can reduce errors and make research easier to understand, reviews of source code can eliminate bugs and improve readability. A large body of research has shown that code reviews are the most cost-effective way of finding bugs in code [65] , [66] . They are also a good way to spread knowledge and good practices around a team. In projects with shifting membership, such as most academic labs, code reviews help ensure that critical knowledge isn't lost when a student or postdoc leaves the lab.”unhoused_relations[31]
relationpre-merge code reviews → shared version control repository — Requiring review before merge prevents review from disappearing in practice. — “Code can be reviewed either before or after it has been committed to a shared version control repository. Experience shows that if reviews don't have to be done in order to get code into the repository, they will soon not be done at all [27] . We therefore recommend that projects use pre-merge code reviews (8a) .”unhoused_relations[32]
weightpre-merge code reviews → shared version control repository — 0.95 — “Code can be reviewed either before or after it has been committed to a shared version control repository. Experience shows that if reviews don't have to be done in order to get code into the repository, they will soon not be done at all [27] . We therefore recommend that projects use pre-merge code reviews (8a) .”unhoused_relations[32]
relationpair programming → productivity — Studies report productivity improvement from pair programming, but many programmers find it intrusive. — “An extreme form of code review is pair programming , in which two developers sit together while writing code. One (the driver) actually writes the code; the other (the navigator) provides real-time feedback and is free to track larger issues of design and consistency. Several studies have found that pair programming improves productivity [67] , but many programmers find it intrusive. We therefore recommend that teams use pair programming when bringing someone new up to speed and when tackling particularly tricky problems (8b) .”unhoused_relations[33]
weightpair programming → productivity — 0.75 — “An extreme form of code review is pair programming , in which two developers sit together while writing code. One (the driver) actually writes the code; the other (the navigator) provides real-time feedback and is free to track larger issues of design and consistency. Several studies have found that pair programming improves productivity [67] , but many programmers find it intrusive. We therefore recommend that teams use pair programming when bringing someone new up to speed and when tackling particularly tricky problems (8b) .”unhoused_relations[33]
relationissue tracking tool → duplicated effort — Issue tracking helps teams avoid duplicated effort and dropped tasks. — “Once a team grows beyond a certain size, it becomes difficult to keep track of what needs to be reviewed, or of who's doing what. Teams can avoid a lot of duplicated effort and dropped balls if they use an issue tracking tool (8c) to maintain a list of tasks to be performed and bugs to be fixed [68] . This helps avoid duplicated work and makes it easier for tasks to be transferred to different people. Free repository hosting services like GitHub include issue tracking tools, and many good standalone tools exist as well, such as Trac ( http://trac.edgewall.org ).”unhoused_relations[34]
weightissue tracking tool → duplicated effort — 0.9 — “Once a team grows beyond a certain size, it becomes difficult to keep track of what needs to be reviewed, or of who's doing what. Teams can avoid a lot of duplicated effort and dropped balls if they use an issue tracking tool (8c) to maintain a list of tasks to be performed and bugs to be fixed [68] . This helps avoid duplicated work and makes it easier for tasks to be transferred to different people. Free repository hosting services like GitHub include issue tracking tools, and many good standalone tools exist as well, such as Trac ( http://trac.edgewall.org ).”unhoused_relations[34]
relationbest practices → reproducible computational research — Readable, tested, version-controlled software is presented as a prerequisite for reproducible computational research. — “We have outlined a series of recommended best practices for scientific computing based on extensive research, as well as our collective experience. These practices can be applied to individual work as readily as group work; separately and together, they improve the productivity of scientific programming and the reliability of the resulting code, and therefore the speed with which we produce results and our confidence in them. They are also, we believe, prerequisites for reproducible computational research: if software is not version controlled, readable, and tested, the chances of its authors (much less anyone else) being able to re-create results are remote.”unhoused_relations[35]
weightbest practices → reproducible computational research — 0.99 — “We have outlined a series of recommended best practices for scientific computing based on extensive research, as well as our collective experience. These practices can be applied to individual work as readily as group work; separately and together, they improve the productivity of scientific programming and the reliability of the resulting code, and therefore the speed with which we produce results and our confidence in them. They are also, we believe, prerequisites for reproducible computational research: if software is not version controlled, readable, and tested, the chances of its authors (much less anyone else) being able to re-create results are remote.”unhoused_relations[35]
relation24 recommendations → advanced practices — The twenty-four recommendations are a beginning that leads toward more advanced practice. — “Our 24 recommendations are a beginning, not an end. Individuals and groups who have incorporated them into their work will find links to more advanced practices at Software Carpentry ( http://software-carpentry.org ).”unhoused_relations[36]
weight24 recommendations → advanced practices — 0.95 — “Our 24 recommendations are a beginning, not an end. Individuals and groups who have incorporated them into their work will find links to more advanced practices at Software Carpentry ( http://software-carpentry.org ).”unhoused_relations[36]
relationtime cost → productivity of the programmers involved — The time cost of adopting the practices is almost immediately offset by productivity gains. — “Research suggests that the time cost of implementing these kinds of tools and approaches in scientific computing is almost immediately offset by the gains in productivity of the programmers involved [17] . Even so, the recommendations described above may seem intimidating to implement. Fortunately, the different practices reinforce and support one another, so the effort required is less than the sum of adding each component separately. Nevertheless, we do not recommend that research groups attempt to implement all of these recommendations at once, but instead suggest that these tools be introduced incrementally over a period of time.”unhoused_relations[37]
weighttime cost → productivity of the programmers involved — 0.85 — “Research suggests that the time cost of implementing these kinds of tools and approaches in scientific computing is almost immediately offset by the gains in productivity of the programmers involved [17] . Even so, the recommendations described above may seem intimidating to implement. Fortunately, the different practices reinforce and support one another, so the effort required is less than the sum of adding each component separately. Nevertheless, we do not recommend that research groups attempt to implement all of these recommendations at once, but instead suggest that these tools be introduced incrementally over a period of time.”unhoused_relations[37]
relationtraining → adoption of these tools — Tutorials, workshops, and classes have proven effective at driving adoption. — “How to implement the recommended practices can be learned from many excellent tutorials available online or through workshops and classes organized by groups like Software Carpentry. This type of training has proven effective at driving adoption of these tools in scientific settings [17] , [69] .”unhoused_relations[38]
weighttraining → adoption of these tools — 0.9 — “How to implement the recommended practices can be learned from many excellent tutorials available online or through workshops and classes organized by groups like Software Carpentry. This type of training has proven effective at driving adoption of these tools in scientific settings [17] , [69] .”unhoused_relations[38]
no type for thissoftware → experimental apparatus — Software is another kind of experimental apparatus. — “We believe that software is just another kind of experimental apparatus [3] and should be built, checked, and used as carefully as any physical apparatus. However, while most scientists are careful to validate their laboratory and field equipment, most do not know how reliable their software is [4] , [5] . This can lead to serious errors impacting the central conclusions of published research [6] : recent high-profile retractions, technical comments, and corrections because of errors in computational methods include papers in Science [7] , [8] , PNAS [9] , the Journal of Molecular Biology [10] , Ecology Letters [11] , [12] , the Journal of Mammalogy [13] , Journal of the American College of Cardiology [14] , Hypertension [15] , and The American Economic Review [16] .”unhoused_relations[0]
no type for thisscript → program — There is no real difference between a script and a program. — “A file containing commands for an interactive system is often called a script , though there is real no difference between this and a program. When these scripts are repeatedly used in the same way, or in combination, a workflow management tool can be used. The paradigmatic example is compiling and linking programs in languages such as Fortran, C++, Java, and C# [40] . The most widely used tool for this task is probably Make ( http://www.gnu.org/software/make ), although many alternatives are now available [41] . All of these allow people to express dependencies between files, i.e., to say that if A or B has changed, then C needs to be updated using a specific set of commands. These tools have been successfully adopted for scientific workflows as well [42] .”unhoused_relations[1]
no type for thisassertion → statement — An assertion is simply a statement that something holds true at a particular point in a program. — “The first line of defense is defensive programming . Experienced programmers add assertions to programs to check their operation (5a) because experience has taught them that everyone (including their future self) makes mistakes. An assertion is simply a statement that something holds true at a particular point in a program; as the example below shows, assertions can be used to ensure that inputs are valid, outputs are consistent, and so on.”unhoused_relations[2]
no type for thispair programming → code review — Pair programming is an extreme form of code review. — “An extreme form of code review is pair programming , in which two developers sit together while writing code. One (the driver) actually writes the code; the other (the navigator) provides real-time feedback and is free to track larger issues of design and consistency. Several studies have found that pair programming improves productivity [67] , but many programmers find it intrusive. We therefore recommend that teams use pair programming when bringing someone new up to speed and when tackling particularly tricky problems (8b) .”unhoused_relations[3]
no type for thisprimarily self-taught → basic software development practices — Most scientific programmers are self-taught and lack exposure to basic development practices. — “Scientists typically develop their own software for these purposes because doing so requires substantial domain-specific knowledge. As a result, recent studies have found that scientists typically spend 30% or more of their time developing software [1] , [2] . However, 90% or more of them are primarily self-taught [1] , [2] , and therefore lack exposure to basic software development practices such as writing maintainable code, using version control and issue trackers, code reviews, unit testing, and task automation.”unhoused_relations[4]
no type for thishow reliable their software is → central conclusions of published research — Unknown software reliability can lead to errors that affect central research conclusions. — “We believe that software is just another kind of experimental apparatus [3] and should be built, checked, and used as carefully as any physical apparatus. However, while most scientists are careful to validate their laboratory and field equipment, most do not know how reliable their software is [4] , [5] . This can lead to serious errors impacting the central conclusions of published research [6] : recent high-profile retractions, technical comments, and corrections because of errors in computational methods include papers in Science [7] , [8] , PNAS [9] , the Journal of Molecular Biology [10] , Ecology Letters [11] , [12] , the Journal of Mammalogy [13] , Journal of the American College of Cardiology [14] , Hypertension [15] , and The American Economic Review [16] .”unhoused_relations[5]
no type for thisbest practices → error-free software development — No combination of the recommended practices guarantees efficient error-free development. — “This paper describes a set of practices that are easy to adopt and have proven effective in many research settings. Our recommendations are based on several decades of collective experience both building scientific software and teaching computing to scientists [17] , [18] , reports from many other groups [19] –, guidelines for commercial and open source software development [26] ,, and on empirical studies of scientific computing [28] – [31] and software development in general (summarized in [32] ). None of these practices will guarantee efficient, error-free software development, but used in concert they will reduce the number of errors in scientific software, make it easier to reuse, and save the authors of the software time and effort that can used for focusing on the underlying scientific questions.”unhoused_relations[6]
no type for thisbest practices → reproducible research — The described skills make reproducible research and open science easier to implement. — “Our practices are summarized in Box 1 ; labels in the main text such as “(1a)” refer to items in that summary. For reasons of space, we do not discuss the equally important (but independent) issues of reproducible research, publication and citation of code and data, and open science. We do believe, however, that all of these will be much easier to implement if scientists have the skills we describe.”unhoused_relations[7]
no type for thishuman working memory → functions — Limited working memory motivates breaking programs into single-task functions. — “First, a program should not require its readers to hold more than a handful of facts in memory at once (1a) . Human working memory can hold only a handful of items at a time, where each item is either a single fact or a “chunk” aggregating several facts [33] , [34] , so programs should limit the total number of items to be remembered to accomplish a task. The primary way to accomplish this is to break programs up into easily understood functions, each of which conducts a single, easily understood, task. This serves to make each piece of the program easier to understand in the same way that breaking up a scientific paper using sections and paragraphs makes it easier to read.”unhoused_relations[8]
no type for thiscode style and formatting → readers make more mistakes — Inconsistent formatting makes code slower to read and causes more reader mistakes. — “Third, scientists should make code style and formatting consistent (1c) . If different parts of a scientific paper used different formatting and capitalization, it would make that paper more difficult to read. Likewise, if different parts of a program are indented differently, or if programmers mix CamelCaseNaming and pothole_case_naming, code takes longer to read and readers make more mistakes [35] , [36] .”unhoused_relations[9]
no type for thisrepetition of computational tasks → mistakes — Manual repetition wastes time and eventually produces mistakes. — “Science often involves repetition of computational tasks such as processing large numbers of data files in the same way or regenerating figures each time new data are added to an existing analysis. Computers were invented to do these kinds of repetitive tasks but, even today, many scientists type the same commands in over and over again or click the same buttons repeatedly [17] . In addition to wasting time, sooner or later even the most careful researcher will lose focus while doing this and make mistakes.”unhoused_relations[10]
no type for thisbuild tool → dependencies between files — A build tool uses declared file dependencies to automate scientific workflows. — “To avoid errors and inefficiencies from repeating commands manually, we recommend that scientists use a build tool to automate workflows (2c) , e.g., specify the ways in which intermediate data files and final results depend on each other, and on the programs that create them, so that a single command will regenerate anything that needs to be regenerated.”unhoused_relations[11]
no type for thisprovenance of data → reproducibility — Machine-readable provenance records everything needed to recreate output. — “In order to maximize reproducibility, everything needed to re-create the output should be recorded automatically in a format that other programs can read. (Borrowing a term from archaeology and forensics, this is often called the provenance of data.) There have been some initiatives to automate the collection of this information, and standardize its format [43] , but it is already possible to record the following without additional tools:”unhoused_relations[12]
no type for thissmall steps with frequent feedback and course correction → requirements are constantly changing — Small iterative steps accommodate changing scientific requirements. — “Programmers are most productive when they work in small steps with frequent feedback and course correction (3a) rather than trying to plan months or years of work in advance. While the details vary from team to team, these developers typically work in steps that are sized to be about an hour long, and these steps are often grouped in iterations that last roughly one week. This accommodates the cognitive constraints discussed in the first section, and acknowledges the reality that real-world requirements are constantly changing. The goal is to produce working (if incomplete) code after each iteration. While these practices have been around for decades, they gained prominence starting in the late 1990s under the banner of agile development [45] , [46] .”unhoused_relations[13]
no type for thisversion control system → lost work — Version control replaces fragile copying practices that can cause confusion and lost work. — “Two of the biggest challenges scientists and other programmers face when working with code and data are keeping track of changes (and being able to revert them if things go wrong), and collaborating on a program or dataset [23] . Typical solutions are to email software to colleagues or to copy successive versions of it to a shared folder, e.g., Dropbox ( http://www.dropbox.com ). However, both approaches are fragile and can lead to confusion and lost work when important changes are overwritten or out-of-date files are used. It's also difficult to find out which changes are in which versions or to say exactly how particular results were computed at a later date.”unhoused_relations[14]
no type for thisversion control system → provenance for both code and data — Stored histories and metadata provide provenance for code and data. — “Crucially, if several people have edited files simultaneously, the VCS highlights the differences and requires them to resolve any conflicts before accepting the changes. The VCS also stores the entire history of those files, allowing arbitrary versions to be retrieved and compared, together with metadata such as comments on what was changed and the author of the changes. All of this information can be extracted to provide provenance for both code and data.”unhoused_relations[15]
no type for thiseverything that has been created manually → version control system — Reproducibility is maximized when all manually created materials are version controlled. — “Reproducibility is maximized when scientists put everything that has been created manually in version control (3c) , including programs, original field observations, and the source files for papers. Automated output and intermediate files can be regenerated as needed. Binary files (e.g., images and audio clips) may be stored in version control, but it is often more sensible to use an archiving system for them, and store the metadata describing their contents in version control instead [48] .”unhoused_relations[16]
no type for thisDRY Principle → errors and inconsistencies — Avoiding repeated representations reduces the chance of update errors and inconsistencies. — “Anything that is repeated in two or more places is more difficult to maintain. Every time a change or correction is made, multiple locations must be updated, which increases the chance of errors and inconsistencies. To avoid this, programmers follow the DRY Principle [49] , for “don't repeat yourself,” which applies to both data and code.”unhoused_relations[17]
no type for thismodularize code → code clones — Modularization avoids code clones and lets fixes take effect everywhere. — “The DRY Principle applies to code at two scales. At small scales, modularize code rather than copying and pasting (4b) . Avoiding “code clones” has been shown to reduce error rates [50] : when a change is made or a bug is fixed, that change or fix takes effect everywhere, and people's mental model of the program (i.e., their belief that “this one's been fixed”) remains accurate. As a side effect, modularizing code allows people to remember its functionality as a single mental chunk, which in turn makes code easier to understand. Modularized code can also be more easily repurposed for other projects.”unhoused_relations[18]
no type for thisre-use code → established library or package — Scientific programmers should use established packages for solved problems rather than rewrite them. — “At larger scales, it is vital that scientific programmers re-use code instead of rewriting it (4c) . Tens of millions of lines of high-quality open source software are freely available on the web, and at least as much is available commercially. It is typically better to find an established library or package that solves a problem than to attempt to write one's own routines for well established problems (e.g., numerical integration, matrix inversions, etc.).”unhoused_relations[19]
no type for thisdefensive programming → mistakes — Assertions and tests form complementary defenses because no single practice catches every mistake. — “Mistakes are inevitable, so verifying and maintaining the validity of code over time is immensely challenging [51] . While no single practice has been shown to catch or prevent all mistakes, several are very effective when used in combination [47] , [52] , [53] .”unhoused_relations[20]
no type for thisassertion → debugging — An assertion halts a failing program immediately and simplifies debugging. — “Assertions can make up a sizeable fraction of the code in well-written applications, just as tools for calibrating scientific instruments can make up a sizeable fraction of the equipment in a lab. These assertions serve two purposes. First, they ensure that if something does go wrong, the program will halt immediately, which simplifies debugging. Second, assertions are executable documentation , i.e., they explain the program as well as checking its behavior. This makes them more useful in many cases than comments since the reader can be sure that they are accurate and up to date.”unhoused_relations[21]
no type for thisautomated testing → confidence that scientific code is operating properly — Combined tests improve confidence that code and results are valid. — “Tests check to see whether the code matches the researcher's expectations of its behavior, which depends on the researcher's understanding of the problem at hand [57] – [59] . For example, in scientific computing, tests are often conducted by comparing output to simplified cases, experimental data, or the results of earlier programs that are trusted. Another approach for generating tests is to turn bugs into test cases (5c) by writing tests that trigger a bug that has been found in the code and (once fixed) will prevent the bug from reappearing unnoticed. In combination these kinds of testing can improve our confidence that scientific code is operating properly and that the results it produces are valid. An additional benefit of testing is that it encourages programmers to design and build code that is testable (i.e., self-contained functions and classes that can run more or less independently of one another). Code that is designed this way is also easier to understand and more reusable.”unhoused_relations[22]
no type for thissymbolic debugger → witness what is going wrong directly — A debugger exposes execution directly rather than requiring inference from logs. — “No matter how good one's computational practice is, reasonably complex code will always initially contain bugs. Fixing bugs that have been identified is often easier if you use a symbolic debugger (5d) to track them down. A better name for this kind of tool would be “interactive program inspector” since a debugger allows users to pause a program at any line (or when some condition is true), inspect the values of variables, and walk up and down active function calls to figure out why things are behaving the way they are. Debuggers are usually more productive than adding and removing print statements or scrolling through hundreds of lines of log output [60] , because they allow the user to see exactly how the code is executing rather than just snapshots of state of the program at a few moments in time. In other words, the debugger allows the scientist to witness what is going wrong directly, rather than having to anticipate the error or infer the problem using indirect evidence.”unhoused_relations[23]
no type for thisprofiler → performance bottlenecks — A profiler is used to identify bottlenecks only after correctness and need are established. — “Today's computers and software are so complex that even experts find it hard to predict which parts of any particular program will be performance bottlenecks [61] . The most productive way to make code fast is therefore to make it work correctly, determine whether it's actually worth speeding it up, and—in those cases where it is—to use a profiler to identify bottlenecks (6a) .”unhoused_relations[24]
no type for thishighest-level language possible → scientists' productivity — Higher-level languages increase productivity because equivalent tasks require fewer lines of code. — “This strategy also has interesting implications for choice of programming language. Research has confirmed that most programmers write roughly the same number of lines of code per unit time regardless of the language they use [62] . Since faster, lower level, languages require more lines of code to accomplish the same task, scientists are most productive when they write code in the highest-level language possible (6b) , and shift to low-level languages like C and Fortran only when they are sure the performance boost is needed. (Using higher-level languages also helps program comprehensibility, since such languages have, in a sense, “pre-chunked” the facts that programmers need to have in short-term memory.)”unhoused_relations[25]
no type for thisrapid prototyping → test oracle — A high-level prototype can serve as a test oracle for a low-level reimplementation. — “Taking this approach allows more code to be written (and tested) in the same amount of time. Even when it is known before coding begins that a low-level language will ultimately be necessary, rapid prototyping in a high-level language helps programmers make and evaluate design decisions quickly. Programmers can also use a high-level prototype as a test oracle for a high-performance low-level reimplementation, i.e., compare the output of the optimized (and usually more complex) program against the output from its unoptimized (but usually simpler) predecessor in order to check its correctness.”unhoused_relations[26]
no type for thisgood documentation → maintenance costs — Good documentation improves reuse and lowers software maintenance costs. — “In the same way that a well documented experimental protocol makes research methods easier to reproduce, good documentation helps people understand code. This makes the code more reusable and lowers maintenance costs [47] . As a result, code that is well documented makes it easier to transition when the graduate students and postdocs who have been writing code in a lab transition to the next career phase. Reference documentation and descriptions of design decisions are key for improving the understandability of code. However, inline documentation that recapitulates code is not useful. Therefore we recommend that scientific programmers document interfaces and reasons, not implementations (7a) . For example, a clear description like this at the beginning of a function that describes what it does and its inputs and outputs is useful:”unhoused_relations[27]
no type for thisinterfaces and reasons → implementations — Documentation should cover interfaces and reasons rather than implementation mechanics. — “In the same way that a well documented experimental protocol makes research methods easier to reproduce, good documentation helps people understand code. This makes the code more reusable and lowers maintenance costs [47] . As a result, code that is well documented makes it easier to transition when the graduate students and postdocs who have been writing code in a lab transition to the next career phase. Reference documentation and descriptions of design decisions are key for improving the understandability of code. However, inline documentation that recapitulates code is not useful. Therefore we recommend that scientific programmers document interfaces and reasons, not implementations (7a) . For example, a clear description like this at the beginning of a function that describes what it does and its inputs and outputs is useful:”unhoused_relations[28]
no type for thisrefactor code → explaining how it works — Complex code should be refactored instead of explained in a long implementation description. — “If a substantial description of the implementation of a piece of software is needed, it is better to refactor code in preference to explaining how it works (7b) , i.e., rather than write a paragraph to explain a complex piece of code, reorganize the code itself so that it doesn't need such an explanation. This may not always be possible—some pieces of code are intrinsically difficult—but the onus should always be on the author to convince his or her peers of that.”unhoused_relations[29]
no type for thisreference documentation → software — Embedding reference documentation in software increases the chance it changes with the code. — “The best way to create and maintain reference documentation is to embed the documentation for a piece of software in that software (7c) . Doing this increases the probability that when programmers change the code, they will update the documentation at the same time.”unhoused_relations[30]
no type for thiscode reviews → bugs — Code reviews eliminate bugs, improve readability, and spread knowledge and practice. — “In the same way that having manuscripts reviewed by other scientists can reduce errors and make research easier to understand, reviews of source code can eliminate bugs and improve readability. A large body of research has shown that code reviews are the most cost-effective way of finding bugs in code [65] , [66] . They are also a good way to spread knowledge and good practices around a team. In projects with shifting membership, such as most academic labs, code reviews help ensure that critical knowledge isn't lost when a student or postdoc leaves the lab.”unhoused_relations[31]
no type for thispre-merge code reviews → shared version control repository — Requiring review before merge prevents review from disappearing in practice. — “Code can be reviewed either before or after it has been committed to a shared version control repository. Experience shows that if reviews don't have to be done in order to get code into the repository, they will soon not be done at all [27] . We therefore recommend that projects use pre-merge code reviews (8a) .”unhoused_relations[32]
no type for thispair programming → productivity — Studies report productivity improvement from pair programming, but many programmers find it intrusive. — “An extreme form of code review is pair programming , in which two developers sit together while writing code. One (the driver) actually writes the code; the other (the navigator) provides real-time feedback and is free to track larger issues of design and consistency. Several studies have found that pair programming improves productivity [67] , but many programmers find it intrusive. We therefore recommend that teams use pair programming when bringing someone new up to speed and when tackling particularly tricky problems (8b) .”unhoused_relations[33]
no type for thisissue tracking tool → duplicated effort — Issue tracking helps teams avoid duplicated effort and dropped tasks. — “Once a team grows beyond a certain size, it becomes difficult to keep track of what needs to be reviewed, or of who's doing what. Teams can avoid a lot of duplicated effort and dropped balls if they use an issue tracking tool (8c) to maintain a list of tasks to be performed and bugs to be fixed [68] . This helps avoid duplicated work and makes it easier for tasks to be transferred to different people. Free repository hosting services like GitHub include issue tracking tools, and many good standalone tools exist as well, such as Trac ( http://trac.edgewall.org ).”unhoused_relations[34]
no type for thisbest practices → reproducible computational research — Readable, tested, version-controlled software is presented as a prerequisite for reproducible computational research. — “We have outlined a series of recommended best practices for scientific computing based on extensive research, as well as our collective experience. These practices can be applied to individual work as readily as group work; separately and together, they improve the productivity of scientific programming and the reliability of the resulting code, and therefore the speed with which we produce results and our confidence in them. They are also, we believe, prerequisites for reproducible computational research: if software is not version controlled, readable, and tested, the chances of its authors (much less anyone else) being able to re-create results are remote.”unhoused_relations[35]
no type for this24 recommendations → advanced practices — The twenty-four recommendations are a beginning that leads toward more advanced practice. — “Our 24 recommendations are a beginning, not an end. Individuals and groups who have incorporated them into their work will find links to more advanced practices at Software Carpentry ( http://software-carpentry.org ).”unhoused_relations[36]
no type for thistime cost → productivity of the programmers involved — The time cost of adopting the practices is almost immediately offset by productivity gains. — “Research suggests that the time cost of implementing these kinds of tools and approaches in scientific computing is almost immediately offset by the gains in productivity of the programmers involved [17] . Even so, the recommendations described above may seem intimidating to implement. Fortunately, the different practices reinforce and support one another, so the effort required is less than the sum of adding each component separately. Nevertheless, we do not recommend that research groups attempt to implement all of these recommendations at once, but instead suggest that these tools be introduced incrementally over a period of time.”unhoused_relations[37]
no type for thistraining → adoption of these tools — Tutorials, workshops, and classes have proven effective at driving adoption. — “How to implement the recommended practices can be learned from many excellent tutorials available online or through workshops and classes organized by groups like Software Carpentry. This type of training has proven effective at driving adoption of these tools in scientific settings [17] , [69] .”unhoused_relations[38]
limitationmost scientists are self-taught programmers without exposure to basic development practices — “Scientists typically develop their own software for these purposes because doing so requires substantial domain-specific knowledge. As a result, recent studies have found that scientists typically spend 30% or more of their time developing software [1] , [2] . However, 90% or more of them are primarily self-taught [1] , [2] , and therefore lack exposure to basic software development practices such as writing maintainable code, using version control and issue trackers, code reviews, unit testing, and task automation.”limitations[0]
limitationthe recommendations cannot guarantee efficient or error-free software development — “This paper describes a set of practices that are easy to adopt and have proven effective in many research settings. Our recommendations are based on several decades of collective experience both building scientific software and teaching computing to scientists [17] , [18] , reports from many other groups [19] –, guidelines for commercial and open source software development [26] ,, and on empirical studies of scientific computing [28] – [31] and software development in general (summarized in [32] ). None of these practices will guarantee efficient, error-free software development, but used in concert they will reduce the number of errors in scientific software, make it easier to reuse, and save the authors of the software time and effort that can used for focusing on the underlying scientific questions.”limitations[1]
limitationthe paper does not cover reproducible-research policy, code and data citation, publication, or open science in detail — “Our practices are summarized in Box 1 ; labels in the main text such as “(1a)” refer to items in that summary. For reasons of space, we do not discuss the equally important (but independent) issues of reproducible research, publication and citation of code and data, and open science. We do believe, however, that all of these will be much easier to implement if scientists have the skills we describe.”limitations[2]
limitationscientific software requirements are rarely frozen and often become knowable only after current results exist — “Unlike traditional commercial software developers, but very much like developers in open source projects or startups, scientific programmers usually don't get their requirements from customers, and their requirements are rarely frozen [31] , [44] . In fact, scientists often can't know what their programs should do next until the current version has produced some results. This challenges design approaches that rely on specifying requirements in advance.”limitations[3]
limitationbinary files may be unsuitable for version control and may require separate archival storage plus metadata — “Reproducibility is maximized when scientists put everything that has been created manually in version control (3c) , including programs, original field observations, and the source files for papers. Automated output and intermediate files can be regenerated as needed. Binary files (e.g., images and audio clips) may be stored in version control, but it is often more sensible to use an archiving system for them, and store the metadata describing their contents in version control instead [48] .”limitations[4]
limitationno single defensive or testing practice catches or prevents every mistake — “Mistakes are inevitable, so verifying and maintaining the validity of code over time is immensely challenging [51] . While no single practice has been shown to catch or prevent all mistakes, several are very effective when used in combination [47] , [52] , [53] .”limitations[5]
limitationtests can only compare code against the researcher's expectations and understanding of the problem — “Tests check to see whether the code matches the researcher's expectations of its behavior, which depends on the researcher's understanding of the problem at hand [57] – [59] . For example, in scientific computing, tests are often conducted by comparing output to simplified cases, experimental data, or the results of earlier programs that are trusted. Another approach for generating tests is to turn bugs into test cases (5c) by writing tests that trigger a bug that has been found in the code and (once fixed) will prevent the bug from reappearing unnoticed. In combination these kinds of testing can improve our confidence that scientific code is operating properly and that the results it produces are valid. An additional benefit of testing is that it encourages programmers to design and build code that is testable (i.e., self-contained functions and classes that can run more or less independently of one another). Code that is designed this way is also easier to understand and more reusable.”limitations[6]
limitationreasonably complex code will contain initial bugs regardless of overall practice quality — “No matter how good one's computational practice is, reasonably complex code will always initially contain bugs. Fixing bugs that have been identified is often easier if you use a symbolic debugger (5d) to track them down. A better name for this kind of tool would be “interactive program inspector” since a debugger allows users to pause a program at any line (or when some condition is true), inspect the values of variables, and walk up and down active function calls to figure out why things are behaving the way they are. Debuggers are usually more productive than adding and removing print statements or scrolling through hundreds of lines of log output [60] , because they allow the user to see exactly how the code is executing rather than just snapshots of state of the program at a few moments in time. In other words, the debugger allows the scientist to witness what is going wrong directly, rather than having to anticipate the error or infer the problem using indirect evidence.”limitations[7]
limitationsome intrinsically difficult code cannot always be made self-explanatory by refactoring — “If a substantial description of the implementation of a piece of software is needed, it is better to refactor code in preference to explaining how it works (7b) , i.e., rather than write a paragraph to explain a complex piece of code, reorganize the code itself so that it doesn't need such an explanation. This may not always be possible—some pieces of code are intrinsically difficult—but the onus should always be on the author to convince his or her peers of that.”limitations[8]
limitationpair programming may improve productivity but many programmers find it intrusive — “An extreme form of code review is pair programming , in which two developers sit together while writing code. One (the driver) actually writes the code; the other (the navigator) provides real-time feedback and is free to track larger issues of design and consistency. Several studies have found that pair programming improves productivity [67] , but many programmers find it intrusive. We therefore recommend that teams use pair programming when bringing someone new up to speed and when tackling particularly tricky problems (8b) .”limitations[9]
limitationthe twenty-four recommendations are a starting point rather than a complete endpoint — “Our 24 recommendations are a beginning, not an end. Individuals and groups who have incorporated them into their work will find links to more advanced practices at Software Carpentry ( http://software-carpentry.org ).”limitations[10]
limitationgroups should adopt practices incrementally rather than attempt every recommendation at once — “Research suggests that the time cost of implementing these kinds of tools and approaches in scientific computing is almost immediately offset by the gains in productivity of the programmers involved [17] . Even so, the recommendations described above may seem intimidating to implement. Fortunately, the different practices reinforce and support one another, so the effort required is less than the sum of adding each component separately. Nevertheless, we do not recommend that research groups attempt to implement all of these recommendations at once, but instead suggest that these tools be introduced incrementally over a period of time.”limitations[11]
Concepts
terms this paper carries, each with the sentence it was cut from — the layer that joins one paper to another. Terms with no quote yet are on CONCEPTS.html.
conceptbest practices for scientific software development — not defined in this paper's own words; research- and experience-based practices for reliable scientific code — “We describe a set of best practices for scientific software development, based on research and experience, that will improve scientists' productivity and the reliability of their software.”concepts[0]
conceptscientists' productivity — not defined in this paper's own words; scientific work produced relative to programming effort — “We describe a set of best practices for scientific software development, based on research and experience, that will improve scientists' productivity and the reliability of their software.”concepts[1]
conceptreliability of their software — not defined in this paper's own words; the degree to which scientific programs operate correctly — “We describe a set of best practices for scientific software development, based on research and experience, that will improve scientists' productivity and the reliability of their software.”concepts[2]
conceptscientific research — not defined in this paper's own words; research increasingly dependent on custom software and computation — “Software is as important to modern scientific research as telescopes and test tubes. From groups that work exclusively on computational problems, to traditional laboratory and field scientists, more and more of the daily operation of science revolves around developing new algorithms, managing and analyzing the large amounts of data that are generated in single research projects, combining disparate datasets to assess synthetic problems, and other computational tasks.”concepts[3]
conceptsoftware — not defined in this paper's own words; computational apparatus used to generate and analyze scientific results — “We believe that software is just another kind of experimental apparatus [3] and should be built, checked, and used as carefully as any physical apparatus. However, while most scientists are careful to validate their laboratory and field equipment, most do not know how reliable their software is [4] , [5] . This can lead to serious errors impacting the central conclusions of published research [6] : recent high-profile retractions, technical comments, and corrections because of errors in computational methods include papers in Science [7] , [8] , PNAS [9] , the Journal of Molecular Biology [10] , Ecology Letters [11] , [12] , the Journal of Mammalogy [13] , Journal of the American College of Cardiology [14] , Hypertension [15] , and The American Economic Review [16] .”concepts[4]
conceptexperimental apparatus — not defined in this paper's own words; equipment that should be built, checked, and used carefully — “We believe that software is just another kind of experimental apparatus [3] and should be built, checked, and used as carefully as any physical apparatus. However, while most scientists are careful to validate their laboratory and field equipment, most do not know how reliable their software is [4] , [5] . This can lead to serious errors impacting the central conclusions of published research [6] : recent high-profile retractions, technical comments, and corrections because of errors in computational methods include papers in Science [7] , [8] , PNAS [9] , the Journal of Molecular Biology [10] , Ecology Letters [11] , [12] , the Journal of Mammalogy [13] , Journal of the American College of Cardiology [14] , Hypertension [15] , and The American Economic Review [16] .”concepts[5]
conceptcomputational methods — not defined in this paper's own words; software-based methods capable of introducing consequential errors — “We believe that software is just another kind of experimental apparatus [3] and should be built, checked, and used as carefully as any physical apparatus. However, while most scientists are careful to validate their laboratory and field equipment, most do not know how reliable their software is [4] , [5] . This can lead to serious errors impacting the central conclusions of published research [6] : recent high-profile retractions, technical comments, and corrections because of errors in computational methods include papers in Science [7] , [8] , PNAS [9] , the Journal of Molecular Biology [10] , Ecology Letters [11] , [12] , the Journal of Mammalogy [13] , Journal of the American College of Cardiology [14] , Hypertension [15] , and The American Economic Review [16] .”concepts[6]
conceptcentral conclusions of published research — not defined in this paper's own words; scientific conclusions vulnerable to computational error — “We believe that software is just another kind of experimental apparatus [3] and should be built, checked, and used as carefully as any physical apparatus. However, while most scientists are careful to validate their laboratory and field equipment, most do not know how reliable their software is [4] , [5] . This can lead to serious errors impacting the central conclusions of published research [6] : recent high-profile retractions, technical comments, and corrections because of errors in computational methods include papers in Science [7] , [8] , PNAS [9] , the Journal of Molecular Biology [10] , Ecology Letters [11] , [12] , the Journal of Mammalogy [13] , Journal of the American College of Cardiology [14] , Hypertension [15] , and The American Economic Review [16] .”concepts[7]
conceptcomputing errors — not defined in this paper's own words; errors whose reuse can cascade across projects and researchers — “In addition, because software is often used for more than a single project, and is often reused by other scientists, computing errors can have disproportionate impacts on the scientific process. This type of cascading impact caused several prominent retractions when an error from another group's code was not discovered until after publication [6] . As with bench experiments, not everything must be done to the most exacting standards; however, scientists need to be aware of best practices both to improve their own approaches and for reviewing computational work by others.”concepts[8]
conceptprominent retractions — not defined in this paper's own words; publication withdrawals caused by inherited code errors — “In addition, because software is often used for more than a single project, and is often reused by other scientists, computing errors can have disproportionate impacts on the scientific process. This type of cascading impact caused several prominent retractions when an error from another group's code was not discovered until after publication [6] . As with bench experiments, not everything must be done to the most exacting standards; however, scientists need to be aware of best practices both to improve their own approaches and for reviewing computational work by others.”concepts[9]
conceptbest practices — not defined in this paper's own words; the paper's coordinated portfolio of software-development practices — “This paper describes a set of practices that are easy to adopt and have proven effective in many research settings. Our recommendations are based on several decades of collective experience both building scientific software and teaching computing to scientists [17] , [18] , reports from many other groups [19] –, guidelines for commercial and open source software development [26] ,, and on empirical studies of scientific computing [28] – [31] and software development in general (summarized in [32] ). None of these practices will guarantee efficient, error-free software development, but used in concert they will reduce the number of errors in scientific software, make it easier to reuse, and save the authors of the software time and effort that can used for focusing on the underlying scientific questions.”concepts[10]
concepterror-free software development — not defined in this paper's own words; an outcome the practices explicitly cannot guarantee — “This paper describes a set of practices that are easy to adopt and have proven effective in many research settings. Our recommendations are based on several decades of collective experience both building scientific software and teaching computing to scientists [17] , [18] , reports from many other groups [19] –, guidelines for commercial and open source software development [26] ,, and on empirical studies of scientific computing [28] – [31] and software development in general (summarized in [32] ). None of these practices will guarantee efficient, error-free software development, but used in concert they will reduce the number of errors in scientific software, make it easier to reuse, and save the authors of the software time and effort that can used for focusing on the underlying scientific questions.”concepts[11]
conceptreproducible research — not defined in this paper's own words; research whose results can be recreated from its computational record — “Our practices are summarized in Box 1 ; labels in the main text such as “(1a)” refer to items in that summary. For reasons of space, we do not discuss the equally important (but independent) issues of reproducible research, publication and citation of code and data, and open science. We do believe, however, that all of these will be much easier to implement if scientists have the skills we describe.”concepts[12]
conceptopen science — not defined in this paper's own words; a related issue made easier by sound computing skills — “Our practices are summarized in Box 1 ; labels in the main text such as “(1a)” refer to items in that summary. For reasons of space, we do not discuss the equally important (but independent) issues of reproducible research, publication and citation of code and data, and open science. We do believe, however, that all of these will be much easier to implement if scientists have the skills we describe.”concepts[13]
conceptprogram — not defined in this paper's own words; executable code that should be correct and readable — “Scientists writing software need to write code that both executes correctly and can be easily read and understood by other programmers (especially the author's future self). If software cannot be easily read and understood, it is much more difficult to know that it is actually doing what it is intended to do. To be productive, software developers must therefore take several aspects of human cognition into account: in particular, that human working memory is limited, human pattern matching abilities are finely tuned, and human attention span is short [33] – [37] .”concepts[14]
concepthuman working memory — not defined in this paper's own words; limited cognitive capacity that program design must accommodate — “First, a program should not require its readers to hold more than a handful of facts in memory at once (1a) . Human working memory can hold only a handful of items at a time, where each item is either a single fact or a “chunk” aggregating several facts [33] , [34] , so programs should limit the total number of items to be remembered to accomplish a task. The primary way to accomplish this is to break programs up into easily understood functions, each of which conducts a single, easily understood, task. This serves to make each piece of the program easier to understand in the same way that breaking up a scientific paper using sections and paragraphs makes it easier to read.”concepts[15]
conceptfunctions — not defined in this paper's own words; small program units each performing one understandable task — “First, a program should not require its readers to hold more than a handful of facts in memory at once (1a) . Human working memory can hold only a handful of items at a time, where each item is either a single fact or a “chunk” aggregating several facts [33] , [34] , so programs should limit the total number of items to be remembered to accomplish a task. The primary way to accomplish this is to break programs up into easily understood functions, each of which conducts a single, easily understood, task. This serves to make each piece of the program easier to understand in the same way that breaking up a scientific paper using sections and paragraphs makes it easier to read.”concepts[16]
conceptnames — not defined in this paper's own words; identifiers that should be consistent, distinctive, and meaningful — “Second, scientists should make names consistent, distinctive, and meaningful (1b) . For example, using non-descriptive names, like a and foo, or names that are very similar, like results and results2, is likely to cause confusion.”concepts[17]
conceptcode style and formatting — not defined in this paper's own words; visual conventions whose consistency supports comprehension — “Third, scientists should make code style and formatting consistent (1c) . If different parts of a scientific paper used different formatting and capitalization, it would make that paper more difficult to read. Likewise, if different parts of a program are indented differently, or if programmers mix CamelCaseNaming and pothole_case_naming, code takes longer to read and readers make more mistakes [35] , [36] .”concepts[18]
conceptrepetition of computational tasks — not defined in this paper's own words; recurring processing or regeneration work suitable for automation — “Science often involves repetition of computational tasks such as processing large numbers of data files in the same way or regenerating figures each time new data are added to an existing analysis. Computers were invented to do these kinds of repetitive tasks but, even today, many scientists type the same commands in over and over again or click the same buttons repeatedly [17] . In addition to wasting time, sooner or later even the most careful researcher will lose focus while doing this and make mistakes.”concepts[19]
conceptrecent commands — not defined in this paper's own words; interactive commands saved for later reuse — “Scientists should therefore make the computer repeat tasks (2a) and save recent commands in a file for re-use (2b) . For example, most command-line tools have a “history” option that lets users display and re-execute recent commands, with minor edits to filenames or parameters. This is often cited as one reason command-line interfaces remain popular [38] , [39] : “do this again” saves time and reduces errors.”concepts[20]
conceptscript — not defined in this paper's own words; a file of commands for an interactive system — “A file containing commands for an interactive system is often called a script , though there is real no difference between this and a program. When these scripts are repeatedly used in the same way, or in combination, a workflow management tool can be used. The paradigmatic example is compiling and linking programs in languages such as Fortran, C++, Java, and C# [40] . The most widely used tool for this task is probably Make ( http://www.gnu.org/software/make ), although many alternatives are now available [41] . All of these allow people to express dependencies between files, i.e., to say that if A or B has changed, then C needs to be updated using a specific set of commands. These tools have been successfully adopted for scientific workflows as well [42] .”concepts[21]
conceptworkflow management tool — not defined in this paper's own words; software that coordinates repeatedly combined scripts — “A file containing commands for an interactive system is often called a script , though there is real no difference between this and a program. When these scripts are repeatedly used in the same way, or in combination, a workflow management tool can be used. The paradigmatic example is compiling and linking programs in languages such as Fortran, C++, Java, and C# [40] . The most widely used tool for this task is probably Make ( http://www.gnu.org/software/make ), although many alternatives are now available [41] . All of these allow people to express dependencies between files, i.e., to say that if A or B has changed, then C needs to be updated using a specific set of commands. These tools have been successfully adopted for scientific workflows as well [42] .”concepts[22]
conceptdependencies between files — not defined in this paper's own words; relationships specifying when outputs require regeneration — “A file containing commands for an interactive system is often called a script , though there is real no difference between this and a program. When these scripts are repeatedly used in the same way, or in combination, a workflow management tool can be used. The paradigmatic example is compiling and linking programs in languages such as Fortran, C++, Java, and C# [40] . The most widely used tool for this task is probably Make ( http://www.gnu.org/software/make ), although many alternatives are now available [41] . All of these allow people to express dependencies between files, i.e., to say that if A or B has changed, then C needs to be updated using a specific set of commands. These tools have been successfully adopted for scientific workflows as well [42] .”concepts[23]
conceptbuild tool — not defined in this paper's own words; software that automates workflows from declared dependencies — “To avoid errors and inefficiencies from repeating commands manually, we recommend that scientists use a build tool to automate workflows (2c) , e.g., specify the ways in which intermediate data files and final results depend on each other, and on the programs that create them, so that a single command will regenerate anything that needs to be regenerated.”concepts[24]
conceptprovenance of data — not defined in this paper's own words; machine-readable record of inputs, programs, parameters, and versions — “In order to maximize reproducibility, everything needed to re-create the output should be recorded automatically in a format that other programs can read. (Borrowing a term from archaeology and forensics, this is often called the provenance of data.) There have been some initiatives to automate the collection of this information, and standardize its format [43] , but it is already possible to record the following without additional tools: unique identifiers and version numbers for raw data records (which scientists may need to create themselves); unique identifiers and version numbers for programs and libraries; the values of parameters used to generate any given output; and the names and version numbers of programs (however small) used to generate those outputs.”concepts[25]
conceptunique identifiers and version numbers — not defined in this paper's own words; identifiers for raw data, programs, and libraries — “In order to maximize reproducibility, everything needed to re-create the output should be recorded automatically in a format that other programs can read. (Borrowing a term from archaeology and forensics, this is often called the provenance of data.) There have been some initiatives to automate the collection of this information, and standardize its format [43] , but it is already possible to record the following without additional tools: unique identifiers and version numbers for raw data records (which scientists may need to create themselves); unique identifiers and version numbers for programs and libraries; the values of parameters used to generate any given output; and the names and version numbers of programs (however small) used to generate those outputs.”concepts[26]
conceptvalues of parameters — not defined in this paper's own words; recorded settings used to generate an output — “In order to maximize reproducibility, everything needed to re-create the output should be recorded automatically in a format that other programs can read. (Borrowing a term from archaeology and forensics, this is often called the provenance of data.) There have been some initiatives to automate the collection of this information, and standardize its format [43] , but it is already possible to record the following without additional tools: unique identifiers and version numbers for raw data records (which scientists may need to create themselves); unique identifiers and version numbers for programs and libraries; the values of parameters used to generate any given output; and the names and version numbers of programs (however small) used to generate those outputs.”concepts[27]
conceptscientific programmers — not defined in this paper's own words; researchers who develop software under changing requirements — “Unlike traditional commercial software developers, but very much like developers in open source projects or startups, scientific programmers usually don't get their requirements from customers, and their requirements are rarely frozen [31] , [44] . In fact, scientists often can't know what their programs should do next until the current version has produced some results. This challenges design approaches that rely on specifying requirements in advance.”concepts[28]
concepttraditional commercial software developers — not defined in this paper's own words; developers more likely to receive predefined customer requirements — “Unlike traditional commercial software developers, but very much like developers in open source projects or startups, scientific programmers usually don't get their requirements from customers, and their requirements are rarely frozen [31] , [44] . In fact, scientists often can't know what their programs should do next until the current version has produced some results. This challenges design approaches that rely on specifying requirements in advance.”concepts[29]
conceptsmall steps with frequent feedback and course correction — not defined in this paper's own words; incremental development under changing requirements — “Programmers are most productive when they work in small steps with frequent feedback and course correction (3a) rather than trying to plan months or years of work in advance. While the details vary from team to team, these developers typically work in steps that are sized to be about an hour long, and these steps are often grouped in iterations that last roughly one week. This accommodates the cognitive constraints discussed in the first section, and acknowledges the reality that real-world requirements are constantly changing. The goal is to produce working (if incomplete) code after each iteration. While these practices have been around for decades, they gained prominence starting in the late 1990s under the banner of agile development [45] , [46] .”concepts[30]
conceptagile development — not defined in this paper's own words; iterative development producing working incomplete code frequently — “Programmers are most productive when they work in small steps with frequent feedback and course correction (3a) rather than trying to plan months or years of work in advance. While the details vary from team to team, these developers typically work in steps that are sized to be about an hour long, and these steps are often grouped in iterations that last roughly one week. This accommodates the cognitive constraints discussed in the first section, and acknowledges the reality that real-world requirements are constantly changing. The goal is to produce working (if incomplete) code after each iteration. While these practices have been around for decades, they gained prominence starting in the late 1990s under the banner of agile development [45] , [46] .”concepts[31]
conceptversion control system — not defined in this paper's own words; software storing project snapshots, history, and collaboration metadata — “The standard solution in both industry and open source is to use a version control system (3b) (VCS) [27] , [47] . A VCS stores snapshots of a project's files in a repository (or a set of repositories). Programmers can modify their working copy of the project at will, then commit changes to the repository when they are satisfied with the results to share them with colleagues.”concepts[32]
conceptVCS — not defined in this paper's own words; the abbreviation used for version control system — “The standard solution in both industry and open source is to use a version control system (3b) (VCS) [27] , [47] . A VCS stores snapshots of a project's files in a repository (or a set of repositories). Programmers can modify their working copy of the project at will, then commit changes to the repository when they are satisfied with the results to share them with colleagues.”concepts[33]
conceptsnapshots of a project's files — not defined in this paper's own words; saved project states retained by version control — “The standard solution in both industry and open source is to use a version control system (3b) (VCS) [27] , [47] . A VCS stores snapshots of a project's files in a repository (or a set of repositories). Programmers can modify their working copy of the project at will, then commit changes to the repository when they are satisfied with the results to share them with colleagues.”concepts[34]
conceptrepository — not defined in this paper's own words; shared storage for version-controlled project history — “The standard solution in both industry and open source is to use a version control system (3b) (VCS) [27] , [47] . A VCS stores snapshots of a project's files in a repository (or a set of repositories). Programmers can modify their working copy of the project at will, then commit changes to the repository when they are satisfied with the results to share them with colleagues.”concepts[35]
conceptworking copy — not defined in this paper's own words; the modifiable local project state — “The standard solution in both industry and open source is to use a version control system (3b) (VCS) [27] , [47] . A VCS stores snapshots of a project's files in a repository (or a set of repositories). Programmers can modify their working copy of the project at will, then commit changes to the repository when they are satisfied with the results to share them with colleagues.”concepts[36]
conceptconflicts — not defined in this paper's own words; simultaneous changes that version control requires users to resolve — “Crucially, if several people have edited files simultaneously, the VCS highlights the differences and requires them to resolve any conflicts before accepting the changes. The VCS also stores the entire history of those files, allowing arbitrary versions to be retrieved and compared, together with metadata such as comments on what was changed and the author of the changes. All of this information can be extracted to provide provenance for both code and data.”concepts[37]
conceptentire history of those files — not defined in this paper's own words; retrievable prior versions plus authorship and change metadata — “Crucially, if several people have edited files simultaneously, the VCS highlights the differences and requires them to resolve any conflicts before accepting the changes. The VCS also stores the entire history of those files, allowing arbitrary versions to be retrieved and compared, together with metadata such as comments on what was changed and the author of the changes. All of this information can be extracted to provide provenance for both code and data.”concepts[38]
concepteverything that has been created manually — not defined in this paper's own words; programs, observations, and paper sources recommended for version control — “Reproducibility is maximized when scientists put everything that has been created manually in version control (3c) , including programs, original field observations, and the source files for papers. Automated output and intermediate files can be regenerated as needed. Binary files (e.g., images and audio clips) may be stored in version control, but it is often more sensible to use an archiving system for them, and store the metadata describing their contents in version control instead [48] .”concepts[39]
conceptDRY Principle — not defined in this paper's own words; the rule that data and code should not be duplicated — “Anything that is repeated in two or more places is more difficult to maintain. Every time a change or correction is made, multiple locations must be updated, which increases the chance of errors and inconsistencies. To avoid this, programmers follow the DRY Principle [49] , for “don't repeat yourself,” which applies to both data and code.”concepts[40]
conceptsingle authoritative representation — not defined in this paper's own words; the sole canonical representation required for each datum — “For data, this maxim holds that every piece of data must have a single authoritative representation in the system (4a) . Physical constants ought to be defined exactly once to ensure that the entire program is using the same value; raw data files should have a single canonical version, every geographic location from which data has been collected should be given an ID that can be used to look up its latitude and longitude, and so on.”concepts[41]
conceptcode clones — not defined in this paper's own words; copied code fragments whose duplication raises maintenance risk — “The DRY Principle applies to code at two scales. At small scales, modularize code rather than copying and pasting (4b) . Avoiding “code clones” has been shown to reduce error rates [50] : when a change is made or a bug is fixed, that change or fix takes effect everywhere, and people's mental model of the program (i.e., their belief that “this one's been fixed”) remains accurate. As a side effect, modularizing code allows people to remember its functionality as a single mental chunk, which in turn makes code easier to understand. Modularized code can also be more easily repurposed for other projects.”concepts[42]
conceptmodularize code — not defined in this paper's own words; factor shared logic rather than copy and paste it — “The DRY Principle applies to code at two scales. At small scales, modularize code rather than copying and pasting (4b) . Avoiding “code clones” has been shown to reduce error rates [50] : when a change is made or a bug is fixed, that change or fix takes effect everywhere, and people's mental model of the program (i.e., their belief that “this one's been fixed”) remains accurate. As a side effect, modularizing code allows people to remember its functionality as a single mental chunk, which in turn makes code easier to understand. Modularized code can also be more easily repurposed for other projects.”concepts[43]
conceptre-use code — not defined in this paper's own words; use established software rather than rewrite known solutions — “At larger scales, it is vital that scientific programmers re-use code instead of rewriting it (4c) . Tens of millions of lines of high-quality open source software are freely available on the web, and at least as much is available commercially. It is typically better to find an established library or package that solves a problem than to attempt to write one's own routines for well established problems (e.g., numerical integration, matrix inversions, etc.).”concepts[44]
conceptestablished library or package — not defined in this paper's own words; existing high-quality software solving a known problem — “At larger scales, it is vital that scientific programmers re-use code instead of rewriting it (4c) . Tens of millions of lines of high-quality open source software are freely available on the web, and at least as much is available commercially. It is typically better to find an established library or package that solves a problem than to attempt to write one's own routines for well established problems (e.g., numerical integration, matrix inversions, etc.).”concepts[45]
conceptdefensive programming — not defined in this paper's own words; programming that checks assumptions during execution — “The first line of defense is defensive programming . Experienced programmers add assertions to programs to check their operation (5a) because experience has taught them that everyone (including their future self) makes mistakes. An assertion is simply a statement that something holds true at a particular point in a program; as the example below shows, assertions can be used to ensure that inputs are valid, outputs are consistent, and so on.”concepts[46]
conceptassertion — not defined in this paper's own words; an executable statement that a condition holds at a point in a program — “The first line of defense is defensive programming . Experienced programmers add assertions to programs to check their operation (5a) because experience has taught them that everyone (including their future self) makes mistakes. An assertion is simply a statement that something holds true at a particular point in a program; as the example below shows, assertions can be used to ensure that inputs are valid, outputs are consistent, and so on.”concepts[47]
conceptstatement — not defined in this paper's own words; the class to which an assertion belongs — “The first line of defense is defensive programming . Experienced programmers add assertions to programs to check their operation (5a) because experience has taught them that everyone (including their future self) makes mistakes. An assertion is simply a statement that something holds true at a particular point in a program; as the example below shows, assertions can be used to ensure that inputs are valid, outputs are consistent, and so on.”concepts[48]
conceptexecutable documentation — not defined in this paper's own words; documentation that simultaneously checks program behavior — “Assertions can make up a sizeable fraction of the code in well-written applications, just as tools for calibrating scientific instruments can make up a sizeable fraction of the equipment in a lab. These assertions serve two purposes. First, they ensure that if something does go wrong, the program will halt immediately, which simplifies debugging. Second, assertions are executable documentation , i.e., they explain the program as well as checking its behavior. This makes them more useful in many cases than comments since the reader can be sure that they are accurate and up to date.”concepts[49]
conceptautomated testing — not defined in this paper's own words; computer-run checks of code behavior — “The second layer of defense is automated testing . Automated tests can check to make sure that a single unit of code is returning correct results ( unit tests ), that pieces of code work correctly when combined ( integration tests ), and that the behavior of a program doesn't change when the details are modified ( regression tests ). These tests are conducted by the computer, so that they are easy to rerun every time the program is modified. Creating and managing tests is easier if programmers use an off-the-shelf unit testing library (5b) to initialize inputs, run tests, and report their results in a uniform way. These libraries are available for all major programming languages including those commonly used in scientific computing [54] – [56] .”concepts[50]
conceptunit tests — not defined in this paper's own words; tests of one unit of code — “The second layer of defense is automated testing . Automated tests can check to make sure that a single unit of code is returning correct results ( unit tests ), that pieces of code work correctly when combined ( integration tests ), and that the behavior of a program doesn't change when the details are modified ( regression tests ). These tests are conducted by the computer, so that they are easy to rerun every time the program is modified. Creating and managing tests is easier if programmers use an off-the-shelf unit testing library (5b) to initialize inputs, run tests, and report their results in a uniform way. These libraries are available for all major programming languages including those commonly used in scientific computing [54] – [56] .”concepts[51]
conceptintegration tests — not defined in this paper's own words; tests of combined code components — “The second layer of defense is automated testing . Automated tests can check to make sure that a single unit of code is returning correct results ( unit tests ), that pieces of code work correctly when combined ( integration tests ), and that the behavior of a program doesn't change when the details are modified ( regression tests ). These tests are conducted by the computer, so that they are easy to rerun every time the program is modified. Creating and managing tests is easier if programmers use an off-the-shelf unit testing library (5b) to initialize inputs, run tests, and report their results in a uniform way. These libraries are available for all major programming languages including those commonly used in scientific computing [54] – [56] .”concepts[52]
conceptregression tests — not defined in this paper's own words; tests that behavior persists across code changes — “The second layer of defense is automated testing . Automated tests can check to make sure that a single unit of code is returning correct results ( unit tests ), that pieces of code work correctly when combined ( integration tests ), and that the behavior of a program doesn't change when the details are modified ( regression tests ). These tests are conducted by the computer, so that they are easy to rerun every time the program is modified. Creating and managing tests is easier if programmers use an off-the-shelf unit testing library (5b) to initialize inputs, run tests, and report their results in a uniform way. These libraries are available for all major programming languages including those commonly used in scientific computing [54] – [56] .”concepts[53]
conceptunit testing library — not defined in this paper's own words; library standardizing test setup, execution, and reporting — “The second layer of defense is automated testing . Automated tests can check to make sure that a single unit of code is returning correct results ( unit tests ), that pieces of code work correctly when combined ( integration tests ), and that the behavior of a program doesn't change when the details are modified ( regression tests ). These tests are conducted by the computer, so that they are easy to rerun every time the program is modified. Creating and managing tests is easier if programmers use an off-the-shelf unit testing library (5b) to initialize inputs, run tests, and report their results in a uniform way. These libraries are available for all major programming languages including those commonly used in scientific computing [54] – [56] .”concepts[54]
conceptbugs — not defined in this paper's own words; code defects that can be converted into regression cases — “Tests check to see whether the code matches the researcher's expectations of its behavior, which depends on the researcher's understanding of the problem at hand [57] – [59] . For example, in scientific computing, tests are often conducted by comparing output to simplified cases, experimental data, or the results of earlier programs that are trusted. Another approach for generating tests is to turn bugs into test cases (5c) by writing tests that trigger a bug that has been found in the code and (once fixed) will prevent the bug from reappearing unnoticed. In combination these kinds of testing can improve our confidence that scientific code is operating properly and that the results it produces are valid. An additional benefit of testing is that it encourages programmers to design and build code that is testable (i.e., self-contained functions and classes that can run more or less independently of one another). Code that is designed this way is also easier to understand and more reusable.”concepts[55]
concepttest cases — not defined in this paper's own words; inputs and expected behavior used to expose bugs — “Tests check to see whether the code matches the researcher's expectations of its behavior, which depends on the researcher's understanding of the problem at hand [57] – [59] . For example, in scientific computing, tests are often conducted by comparing output to simplified cases, experimental data, or the results of earlier programs that are trusted. Another approach for generating tests is to turn bugs into test cases (5c) by writing tests that trigger a bug that has been found in the code and (once fixed) will prevent the bug from reappearing unnoticed. In combination these kinds of testing can improve our confidence that scientific code is operating properly and that the results it produces are valid. An additional benefit of testing is that it encourages programmers to design and build code that is testable (i.e., self-contained functions and classes that can run more or less independently of one another). Code that is designed this way is also easier to understand and more reusable.”concepts[56]
concepttestable — not defined in this paper's own words; code structured so functions and classes can run independently — “Tests check to see whether the code matches the researcher's expectations of its behavior, which depends on the researcher's understanding of the problem at hand [57] – [59] . For example, in scientific computing, tests are often conducted by comparing output to simplified cases, experimental data, or the results of earlier programs that are trusted. Another approach for generating tests is to turn bugs into test cases (5c) by writing tests that trigger a bug that has been found in the code and (once fixed) will prevent the bug from reappearing unnoticed. In combination these kinds of testing can improve our confidence that scientific code is operating properly and that the results it produces are valid. An additional benefit of testing is that it encourages programmers to design and build code that is testable (i.e., self-contained functions and classes that can run more or less independently of one another). Code that is designed this way is also easier to understand and more reusable.”concepts[57]
conceptsymbolic debugger — not defined in this paper's own words; interactive inspector for pausing code and examining execution state — “No matter how good one's computational practice is, reasonably complex code will always initially contain bugs. Fixing bugs that have been identified is often easier if you use a symbolic debugger (5d) to track them down. A better name for this kind of tool would be “interactive program inspector” since a debugger allows users to pause a program at any line (or when some condition is true), inspect the values of variables, and walk up and down active function calls to figure out why things are behaving the way they are. Debuggers are usually more productive than adding and removing print statements or scrolling through hundreds of lines of log output [60] , because they allow the user to see exactly how the code is executing rather than just snapshots of state of the program at a few moments in time. In other words, the debugger allows the scientist to witness what is going wrong directly, rather than having to anticipate the error or infer the problem using indirect evidence.”concepts[58]
conceptperformance bottlenecks — not defined in this paper's own words; program regions limiting runtime performance — “Today's computers and software are so complex that even experts find it hard to predict which parts of any particular program will be performance bottlenecks [61] . The most productive way to make code fast is therefore to make it work correctly, determine whether it's actually worth speeding it up, and—in those cases where it is—to use a profiler to identify bottlenecks (6a) .”concepts[59]
conceptprofiler — not defined in this paper's own words; measurement tool used to identify performance bottlenecks — “Today's computers and software are so complex that even experts find it hard to predict which parts of any particular program will be performance bottlenecks [61] . The most productive way to make code fast is therefore to make it work correctly, determine whether it's actually worth speeding it up, and—in those cases where it is—to use a profiler to identify bottlenecks (6a) .”concepts[60]
concepthighest-level language possible — not defined in this paper's own words; the recommended default programming-language level — “This strategy also has interesting implications for choice of programming language. Research has confirmed that most programmers write roughly the same number of lines of code per unit time regardless of the language they use [62] . Since faster, lower level, languages require more lines of code to accomplish the same task, scientists are most productive when they write code in the highest-level language possible (6b) , and shift to low-level languages like C and Fortran only when they are sure the performance boost is needed. (Using higher-level languages also helps program comprehensibility, since such languages have, in a sense, “pre-chunked” the facts that programmers need to have in short-term memory.)”concepts[61]
conceptlow-level languages — not defined in this paper's own words; languages requiring more code but potentially providing performance gains — “This strategy also has interesting implications for choice of programming language. Research has confirmed that most programmers write roughly the same number of lines of code per unit time regardless of the language they use [62] . Since faster, lower level, languages require more lines of code to accomplish the same task, scientists are most productive when they write code in the highest-level language possible (6b) , and shift to low-level languages like C and Fortran only when they are sure the performance boost is needed. (Using higher-level languages also helps program comprehensibility, since such languages have, in a sense, “pre-chunked” the facts that programmers need to have in short-term memory.)”concepts[62]
conceptrapid prototyping — not defined in this paper's own words; fast design exploration in a high-level language — “Taking this approach allows more code to be written (and tested) in the same amount of time. Even when it is known before coding begins that a low-level language will ultimately be necessary, rapid prototyping in a high-level language helps programmers make and evaluate design decisions quickly. Programmers can also use a high-level prototype as a test oracle for a high-performance low-level reimplementation, i.e., compare the output of the optimized (and usually more complex) program against the output from its unoptimized (but usually simpler) predecessor in order to check its correctness.”concepts[63]
concepttest oracle — not defined in this paper's own words; trusted output used to check an optimized reimplementation — “Taking this approach allows more code to be written (and tested) in the same amount of time. Even when it is known before coding begins that a low-level language will ultimately be necessary, rapid prototyping in a high-level language helps programmers make and evaluate design decisions quickly. Programmers can also use a high-level prototype as a test oracle for a high-performance low-level reimplementation, i.e., compare the output of the optimized (and usually more complex) program against the output from its unoptimized (but usually simpler) predecessor in order to check its correctness.”concepts[64]
conceptgood documentation — not defined in this paper's own words; documentation of interfaces, reasons, design, and purpose — “In the same way that a well documented experimental protocol makes research methods easier to reproduce, good documentation helps people understand code. This makes the code more reusable and lowers maintenance costs [47] . As a result, code that is well documented makes it easier to transition when the graduate students and postdocs who have been writing code in a lab transition to the next career phase. Reference documentation and descriptions of design decisions are key for improving the understandability of code. However, inline documentation that recapitulates code is not useful. Therefore we recommend that scientific programmers document interfaces and reasons, not implementations (7a) . For example, a clear description like this at the beginning of a function that describes what it does and its inputs and outputs is useful:”concepts[65]
conceptmaintenance costs — not defined in this paper's own words; effort required to sustain code over time — “In the same way that a well documented experimental protocol makes research methods easier to reproduce, good documentation helps people understand code. This makes the code more reusable and lowers maintenance costs [47] . As a result, code that is well documented makes it easier to transition when the graduate students and postdocs who have been writing code in a lab transition to the next career phase. Reference documentation and descriptions of design decisions are key for improving the understandability of code. However, inline documentation that recapitulates code is not useful. Therefore we recommend that scientific programmers document interfaces and reasons, not implementations (7a) . For example, a clear description like this at the beginning of a function that describes what it does and its inputs and outputs is useful:”concepts[66]
conceptinterfaces and reasons — not defined in this paper's own words; what documentation should explain — “In the same way that a well documented experimental protocol makes research methods easier to reproduce, good documentation helps people understand code. This makes the code more reusable and lowers maintenance costs [47] . As a result, code that is well documented makes it easier to transition when the graduate students and postdocs who have been writing code in a lab transition to the next career phase. Reference documentation and descriptions of design decisions are key for improving the understandability of code. However, inline documentation that recapitulates code is not useful. Therefore we recommend that scientific programmers document interfaces and reasons, not implementations (7a) . For example, a clear description like this at the beginning of a function that describes what it does and its inputs and outputs is useful:”concepts[67]
conceptimplementations — not defined in this paper's own words; mechanics that code should express rather than prose repeat — “In the same way that a well documented experimental protocol makes research methods easier to reproduce, good documentation helps people understand code. This makes the code more reusable and lowers maintenance costs [47] . As a result, code that is well documented makes it easier to transition when the graduate students and postdocs who have been writing code in a lab transition to the next career phase. Reference documentation and descriptions of design decisions are key for improving the understandability of code. However, inline documentation that recapitulates code is not useful. Therefore we recommend that scientific programmers document interfaces and reasons, not implementations (7a) . For example, a clear description like this at the beginning of a function that describes what it does and its inputs and outputs is useful:”concepts[68]
conceptrefactor code — not defined in this paper's own words; reorganize complex code to make it self-explanatory — “If a substantial description of the implementation of a piece of software is needed, it is better to refactor code in preference to explaining how it works (7b) , i.e., rather than write a paragraph to explain a complex piece of code, reorganize the code itself so that it doesn't need such an explanation. This may not always be possible—some pieces of code are intrinsically difficult—but the onus should always be on the author to convince his or her peers of that.”concepts[69]
conceptreference documentation — not defined in this paper's own words; software documentation kept with the code — “The best way to create and maintain reference documentation is to embed the documentation for a piece of software in that software (7c) . Doing this increases the probability that when programmers change the code, they will update the documentation at the same time.”concepts[70]
conceptdocumentation generator — not defined in this paper's own words; tool extracting embedded comments into readable documents — “Embedded documentation usually takes the form of specially-formatted and placed comments. Typically, a documentation generator such as Javadoc, Doxygen, or Sphinx extracts these comments and generates well-formatted web pages and other human-friendly documents ( http://en.wikipedia.org/wiki/Comparison_of_documentation_generators ). Alternatively, code can be embedded in a larger document that includes information about what the code is doing (i.e., literate programming). Common approaches to this include this use of knitr [63] and IPython Notebooks [64] .”concepts[71]
conceptliterate programming — not defined in this paper's own words; embedding code in a larger explanatory document — “Embedded documentation usually takes the form of specially-formatted and placed comments. Typically, a documentation generator such as Javadoc, Doxygen, or Sphinx extracts these comments and generates well-formatted web pages and other human-friendly documents ( http://en.wikipedia.org/wiki/Comparison_of_documentation_generators ). Alternatively, code can be embedded in a larger document that includes information about what the code is doing (i.e., literate programming). Common approaches to this include this use of knitr [63] and IPython Notebooks [64] .”concepts[72]
conceptcode reviews — not defined in this paper's own words; peer examination of source code for defects and readability — “In the same way that having manuscripts reviewed by other scientists can reduce errors and make research easier to understand, reviews of source code can eliminate bugs and improve readability. A large body of research has shown that code reviews are the most cost-effective way of finding bugs in code [65] , [66] . They are also a good way to spread knowledge and good practices around a team. In projects with shifting membership, such as most academic labs, code reviews help ensure that critical knowledge isn't lost when a student or postdoc leaves the lab.”concepts[73]
conceptsource code — not defined in this paper's own words; program text subject to peer review — “In the same way that having manuscripts reviewed by other scientists can reduce errors and make research easier to understand, reviews of source code can eliminate bugs and improve readability. A large body of research has shown that code reviews are the most cost-effective way of finding bugs in code [65] , [66] . They are also a good way to spread knowledge and good practices around a team. In projects with shifting membership, such as most academic labs, code reviews help ensure that critical knowledge isn't lost when a student or postdoc leaves the lab.”concepts[74]
conceptpre-merge code reviews — not defined in this paper's own words; reviews required before repository acceptance — “Code can be reviewed either before or after it has been committed to a shared version control repository. Experience shows that if reviews don't have to be done in order to get code into the repository, they will soon not be done at all [27] . We therefore recommend that projects use pre-merge code reviews (8a) .”concepts[75]
conceptpair programming — not defined in this paper's own words; two-developer collaborative coding with driver and navigator roles — “An extreme form of code review is pair programming , in which two developers sit together while writing code. One (the driver) actually writes the code; the other (the navigator) provides real-time feedback and is free to track larger issues of design and consistency. Several studies have found that pair programming improves productivity [67] , but many programmers find it intrusive. We therefore recommend that teams use pair programming when bringing someone new up to speed and when tackling particularly tricky problems (8b) .”concepts[76]
conceptcode review — not defined in this paper's own words; the broader practice of which pair programming is an extreme form — “An extreme form of code review is pair programming , in which two developers sit together while writing code. One (the driver) actually writes the code; the other (the navigator) provides real-time feedback and is free to track larger issues of design and consistency. Several studies have found that pair programming improves productivity [67] , but many programmers find it intrusive. We therefore recommend that teams use pair programming when bringing someone new up to speed and when tackling particularly tricky problems (8b) .”concepts[77]
conceptdriver — not defined in this paper's own words; the pair-programming participant who writes code — “An extreme form of code review is pair programming , in which two developers sit together while writing code. One (the driver) actually writes the code; the other (the navigator) provides real-time feedback and is free to track larger issues of design and consistency. Several studies have found that pair programming improves productivity [67] , but many programmers find it intrusive. We therefore recommend that teams use pair programming when bringing someone new up to speed and when tackling particularly tricky problems (8b) .”concepts[78]
conceptnavigator — not defined in this paper's own words; the participant providing real-time feedback and tracking design — “An extreme form of code review is pair programming , in which two developers sit together while writing code. One (the driver) actually writes the code; the other (the navigator) provides real-time feedback and is free to track larger issues of design and consistency. Several studies have found that pair programming improves productivity [67] , but many programmers find it intrusive. We therefore recommend that teams use pair programming when bringing someone new up to speed and when tackling particularly tricky problems (8b) .”concepts[79]
conceptissue tracking tool — not defined in this paper's own words; tool maintaining tasks and bugs for a team — “Once a team grows beyond a certain size, it becomes difficult to keep track of what needs to be reviewed, or of who's doing what. Teams can avoid a lot of duplicated effort and dropped balls if they use an issue tracking tool (8c) to maintain a list of tasks to be performed and bugs to be fixed [68] . This helps avoid duplicated work and makes it easier for tasks to be transferred to different people. Free repository hosting services like GitHub include issue tracking tools, and many good standalone tools exist as well, such as Trac ( http://trac.edgewall.org ).”concepts[80]
conceptduplicated effort — not defined in this paper's own words; redundant work that issue tracking helps avoid — “Once a team grows beyond a certain size, it becomes difficult to keep track of what needs to be reviewed, or of who's doing what. Teams can avoid a lot of duplicated effort and dropped balls if they use an issue tracking tool (8c) to maintain a list of tasks to be performed and bugs to be fixed [68] . This helps avoid duplicated work and makes it easier for tasks to be transferred to different people. Free repository hosting services like GitHub include issue tracking tools, and many good standalone tools exist as well, such as Trac ( http://trac.edgewall.org ).”concepts[81]
conceptreproducible computational research — not defined in this paper's own words; research whose results can be recreated from readable tested versioned software — “We have outlined a series of recommended best practices for scientific computing based on extensive research, as well as our collective experience. These practices can be applied to individual work as readily as group work; separately and together, they improve the productivity of scientific programming and the reliability of the resulting code, and therefore the speed with which we produce results and our confidence in them. They are also, we believe, prerequisites for reproducible computational research: if software is not version controlled, readable, and tested, the chances of its authors (much less anyone else) being able to re-create results are remote.”concepts[82]
concept24 recommendations — not defined in this paper's own words; the initial practice set presented by the paper — “Our 24 recommendations are a beginning, not an end. Individuals and groups who have incorporated them into their work will find links to more advanced practices at Software Carpentry ( http://software-carpentry.org ).”concepts[83]
concepttime cost — not defined in this paper's own words; implementation effort offset by programmer productivity — “Research suggests that the time cost of implementing these kinds of tools and approaches in scientific computing is almost immediately offset by the gains in productivity of the programmers involved [17] . Even so, the recommendations described above may seem intimidating to implement. Fortunately, the different practices reinforce and support one another, so the effort required is less than the sum of adding each component separately. Nevertheless, we do not recommend that research groups attempt to implement all of these recommendations at once, but instead suggest that these tools be introduced incrementally over a period of time.”concepts[84]
concepttraining — not defined in this paper's own words; tutorials, workshops, and classes used to spread computing practice — “How to implement the recommended practices can be learned from many excellent tutorials available online or through workshops and classes organized by groups like Software Carpentry. This type of training has proven effective at driving adoption of these tools in scientific settings [17] , [69] .”concepts[85]
conceptprimarily self-taught — not defined in this paper's own words; the training status reported for most scientists who program — “Scientists typically develop their own software for these purposes because doing so requires substantial domain-specific knowledge. As a result, recent studies have found that scientists typically spend 30% or more of their time developing software [1] , [2] . However, 90% or more of them are primarily self-taught [1] , [2] , and therefore lack exposure to basic software development practices such as writing maintainable code, using version control and issue trackers, code reviews, unit testing, and task automation.”concepts[86]
conceptbasic software development practices — not defined in this paper's own words; maintainability, versioning, issue tracking, review, testing, and automation — “Scientists typically develop their own software for these purposes because doing so requires substantial domain-specific knowledge. As a result, recent studies have found that scientists typically spend 30% or more of their time developing software [1] , [2] . However, 90% or more of them are primarily self-taught [1] , [2] , and therefore lack exposure to basic software development practices such as writing maintainable code, using version control and issue trackers, code reviews, unit testing, and task automation.”concepts[87]
concepthow reliable their software is — not defined in this paper's own words; scientists' often-unknown assessment of software reliability — “We believe that software is just another kind of experimental apparatus [3] and should be built, checked, and used as carefully as any physical apparatus. However, while most scientists are careful to validate their laboratory and field equipment, most do not know how reliable their software is [4] , [5] . This can lead to serious errors impacting the central conclusions of published research [6] : recent high-profile retractions, technical comments, and corrections because of errors in computational methods include papers in Science [7] , [8] , PNAS [9] , the Journal of Molecular Biology [10] , Ecology Letters [11] , [12] , the Journal of Mammalogy [13] , Journal of the American College of Cardiology [14] , Hypertension [15] , and The American Economic Review [16] .”concepts[88]
conceptreproducibility — not defined in this paper's own words; the ability to recreate scientific computational output — “In order to maximize reproducibility, everything needed to re-create the output should be recorded automatically in a format that other programs can read. (Borrowing a term from archaeology and forensics, this is often called the provenance of data.) There have been some initiatives to automate the collection of this information, and standardize its format [43] , but it is already possible to record the following without additional tools:”concepts[89]
conceptreaders make more mistakes — not defined in this paper's own words; the observed comprehension cost of inconsistent formatting — “Third, scientists should make code style and formatting consistent (1c) . If different parts of a scientific paper used different formatting and capitalization, it would make that paper more difficult to read. Likewise, if different parts of a program are indented differently, or if programmers mix CamelCaseNaming and pothole_case_naming, code takes longer to read and readers make more mistakes [35] , [36] .”concepts[90]
conceptmistakes — not defined in this paper's own words; inevitable programming errors addressed by layered defenses — “Mistakes are inevitable, so verifying and maintaining the validity of code over time is immensely challenging [51] . While no single practice has been shown to catch or prevent all mistakes, several are very effective when used in combination [47] , [52] , [53] .”concepts[91]
conceptrequirements are constantly changing — not defined in this paper's own words; the development condition motivating short iterations — “Programmers are most productive when they work in small steps with frequent feedback and course correction (3a) rather than trying to plan months or years of work in advance. While the details vary from team to team, these developers typically work in steps that are sized to be about an hour long, and these steps are often grouped in iterations that last roughly one week. This accommodates the cognitive constraints discussed in the first section, and acknowledges the reality that real-world requirements are constantly changing. The goal is to produce working (if incomplete) code after each iteration. While these practices have been around for decades, they gained prominence starting in the late 1990s under the banner of agile development [45] , [46] .”concepts[92]
conceptlost work — not defined in this paper's own words; a failure risk of copying or emailing project versions — “Two of the biggest challenges scientists and other programmers face when working with code and data are keeping track of changes (and being able to revert them if things go wrong), and collaborating on a program or dataset [23] . Typical solutions are to email software to colleagues or to copy successive versions of it to a shared folder, e.g., Dropbox ( http://www.dropbox.com ). However, both approaches are fragile and can lead to confusion and lost work when important changes are overwritten or out-of-date files are used. It's also difficult to find out which changes are in which versions or to say exactly how particular results were computed at a later date.”concepts[93]
conceptprovenance for both code and data — not defined in this paper's own words; history and metadata extracted from version control — “Crucially, if several people have edited files simultaneously, the VCS highlights the differences and requires them to resolve any conflicts before accepting the changes. The VCS also stores the entire history of those files, allowing arbitrary versions to be retrieved and compared, together with metadata such as comments on what was changed and the author of the changes. All of this information can be extracted to provide provenance for both code and data.”concepts[94]
concepterrors and inconsistencies — not defined in this paper's own words; defects made more likely by duplicated representations — “Anything that is repeated in two or more places is more difficult to maintain. Every time a change or correction is made, multiple locations must be updated, which increases the chance of errors and inconsistencies. To avoid this, programmers follow the DRY Principle [49] , for “don't repeat yourself,” which applies to both data and code.”concepts[95]
conceptdebugging — not defined in this paper's own words; locating and correcting software defects — “Assertions can make up a sizeable fraction of the code in well-written applications, just as tools for calibrating scientific instruments can make up a sizeable fraction of the equipment in a lab. These assertions serve two purposes. First, they ensure that if something does go wrong, the program will halt immediately, which simplifies debugging. Second, assertions are executable documentation , i.e., they explain the program as well as checking its behavior. This makes them more useful in many cases than comments since the reader can be sure that they are accurate and up to date.”concepts[96]
conceptconfidence that scientific code is operating properly — not defined in this paper's own words; epistemic confidence supported by combined tests — “Tests check to see whether the code matches the researcher's expectations of its behavior, which depends on the researcher's understanding of the problem at hand [57] – [59] . For example, in scientific computing, tests are often conducted by comparing output to simplified cases, experimental data, or the results of earlier programs that are trusted. Another approach for generating tests is to turn bugs into test cases (5c) by writing tests that trigger a bug that has been found in the code and (once fixed) will prevent the bug from reappearing unnoticed. In combination these kinds of testing can improve our confidence that scientific code is operating properly and that the results it produces are valid. An additional benefit of testing is that it encourages programmers to design and build code that is testable (i.e., self-contained functions and classes that can run more or less independently of one another). Code that is designed this way is also easier to understand and more reusable.”concepts[97]
conceptwitness what is going wrong directly — not defined in this paper's own words; direct inspection of program execution with a debugger — “No matter how good one's computational practice is, reasonably complex code will always initially contain bugs. Fixing bugs that have been identified is often easier if you use a symbolic debugger (5d) to track them down. A better name for this kind of tool would be “interactive program inspector” since a debugger allows users to pause a program at any line (or when some condition is true), inspect the values of variables, and walk up and down active function calls to figure out why things are behaving the way they are. Debuggers are usually more productive than adding and removing print statements or scrolling through hundreds of lines of log output [60] , because they allow the user to see exactly how the code is executing rather than just snapshots of state of the program at a few moments in time. In other words, the debugger allows the scientist to witness what is going wrong directly, rather than having to anticipate the error or infer the problem using indirect evidence.”concepts[98]
conceptexplaining how it works — not defined in this paper's own words; prose explanation that refactoring may make unnecessary — “If a substantial description of the implementation of a piece of software is needed, it is better to refactor code in preference to explaining how it works (7b) , i.e., rather than write a paragraph to explain a complex piece of code, reorganize the code itself so that it doesn't need such an explanation. This may not always be possible—some pieces of code are intrinsically difficult—but the onus should always be on the author to convince his or her peers of that.”concepts[99]
conceptshared version control repository — not defined in this paper's own words; repository into which reviewed code is committed — “Code can be reviewed either before or after it has been committed to a shared version control repository. Experience shows that if reviews don't have to be done in order to get code into the repository, they will soon not be done at all [27] . We therefore recommend that projects use pre-merge code reviews (8a) .”concepts[100]
conceptproductivity — not defined in this paper's own words; programming output affected by language and collaboration practices — “An extreme form of code review is pair programming , in which two developers sit together while writing code. One (the driver) actually writes the code; the other (the navigator) provides real-time feedback and is free to track larger issues of design and consistency. Several studies have found that pair programming improves productivity [67] , but many programmers find it intrusive. We therefore recommend that teams use pair programming when bringing someone new up to speed and when tackling particularly tricky problems (8b) .”concepts[101]
conceptadvanced practices — not defined in this paper's own words; practices beyond the paper's introductory recommendations — “Our 24 recommendations are a beginning, not an end. Individuals and groups who have incorporated them into their work will find links to more advanced practices at Software Carpentry ( http://software-carpentry.org ).”concepts[102]
conceptproductivity of the programmers involved — not defined in this paper's own words; programmer output that offsets adoption cost — “Research suggests that the time cost of implementing these kinds of tools and approaches in scientific computing is almost immediately offset by the gains in productivity of the programmers involved [17] . Even so, the recommendations described above may seem intimidating to implement. Fortunately, the different practices reinforce and support one another, so the effort required is less than the sum of adding each component separately. Nevertheless, we do not recommend that research groups attempt to implement all of these recommendations at once, but instead suggest that these tools be introduced incrementally over a period of time.”concepts[103]
conceptadoption of these tools — not defined in this paper's own words; uptake of scientific-computing practices through training — “How to implement the recommended practices can be learned from many excellent tutorials available online or through workshops and classes organized by groups like Software Carpentry. This type of training has proven effective at driving adoption of these tools in scientific settings [17] , [69] .”concepts[104]

Full text — tagged

Best Practicesterm for Scientific Computing Abstract We describe a set of best practices for scientific software developmentterm, based on research and experience, that will improve scientists' productivityterm and the reliability of their softwareterm.

Introduction Scientists spend an increasing amount of time building and using softwareterm. However, most scientists are never taught how to do this efficiently. As a result, many are unaware of tools and practices that would allow them to write more reliable and maintainable code with less effort. We describe a set of best practices for scientific software developmentterm that have solid foundations in research and experience, and that improve scientists' productivityterm and the reliability of their softwareterm.

Softwareterm is as important to modern scientific researchterm as telescopes and test tubes. From groups that work exclusively on computational problems, to traditional laboratory and field scientists, more and more of the daily operation of science revolves around developing new algorithms, managing and analyzing the large amounts of data that are generated in single research projects, combining disparate datasets to assess synthetic problems, and other computational tasks.

Scientists typically develop their own softwareterm for these purposes because doing so requires substantial domain-specific knowledge. As a result, recent studies have found that scientists typically spend 30% or more of their time developing softwareterm [1] , [2] . However, 90% or more of them are primarily self-taughtterm [1] , [2] , and therefore lack exposure to basic software development practicesterm such as writing maintainable code, using version control and issue trackers, code reviewsterm, unit testing, and task automation.

We believe that softwareterm is just another kind of experimental apparatusterm [3] and should be built, checked, and used as carefully as any physical apparatus. However, while most scientists are careful to validate their laboratory and field equipment, most do not know how reliable their software isterm [4] , [5] . This can lead to serious errors impacting the central conclusions of published researchterm [6] : recent high-profile retractions, technical comments, and corrections because of errors in computational methodsterm include papers in Science [7] , [8] , PNAS [9] , the Journal of Molecular Biology [10] , Ecology Letters [11] , [12] , the Journal of Mammalogy [13] , Journal of the American College of Cardiology [14] , Hypertension [15] , and The American Economic Review [16] .

In addition, because softwareterm is often used for more than a single project, and is often reused by other scientists, computing errorsterm can have disproportionate impacts on the scientific process. This type of cascading impact caused several prominent retractionsterm when an error from another group's code was not discovered until after publication [6] . As with bench experiments, not everything must be done to the most exacting standards; however, scientists need to be aware of best practicesterm both to improve their own approaches and for reviewing computational work by others.

This paper describes a set of practices that are easy to adopt and have proven effective in many research settings. Our recommendations are based on several decades of collective experience both building scientific softwareterm and teaching computing to scientists [17] , [18] , reports from many other groups [19] –, guidelines for commercial and open source softwareterm development [26] ,, and on empirical studies of scientific computing [28] – [31] and softwareterm development in general (summarized in [32] ). None of these practices will guarantee efficient, error-free software developmentterm, but used in concert they will reduce the number of errors in scientific softwareterm, make it easier to reuse, and save the authors of the softwareterm time and effort that can used for focusing on the underlying scientific questions.

Our practices are summarized in Box 1 ; labels in the main text such as “(1a)” refer to items in that summary. For reasons of space, we do not discuss the equally important (but independent) issues of reproducible researchterm, publication and citation of code and data, and open scienceterm. We do believe, however, that all of these will be much easier to implement if scientists have the skills we describe.

Box 1. Summary of Best Practicesterm Write programsterm for people, not computers. A programterm should not require its readers to hold more than a handful of facts in memory at once. Make namesterm consistent, distinctive, and meaningful. Make code style and formattingterm consistent.

Let the computer do the work. Make the computer repeat tasks. Save recent commandsterm in a file for re-use. Use a build toolterm to automate workflows.

Make incremental changes. Work in small steps with frequent feedback and course correctionterm. Use a version control systemterm. Put everything that has been created manuallyterm in version control.

Don't repeat yourself (or others). Every piece of data must have a single authoritative representationterm in the system. Modularize codeterm rather than copying and pasting. Re-use codeterm instead of rewriting it.

Plan for mistakesterm. Add assertionsterm to programsterm to check their operation. Use an off-the-shelf unit testing libraryterm. Turn bugsterm into test casesterm. Use a symbolic debuggerterm.

Optimize softwareterm only after it works correctly. Use a profilerterm to identify bottlenecks. Write code in the highest-level language possibleterm.

Document design and purpose, not mechanics. Document interfaces and reasonsterm, not implementationsterm. Refactor codeterm in preference to explaining how it worksterm. Embed the documentation for a piece of softwareterm in that softwareterm.

Collaborate. Use pre-merge code reviewsterm. Use pair programmingterm when bringing someone new up to speed and when tackling particularly tricky problems. Use an issue tracking toolterm.

Write Programsterm for People, Not Computers Scientists writing softwareterm need to write code that both executes correctly and can be easily read and understood by other programmers (especially the author's future self). If softwareterm cannot be easily read and understood, it is much more difficult to know that it is actually doing what it is intended to do. To be productive, softwareterm developers must therefore take several aspects of human cognition into account: in particular, that human working memoryterm is limited, human pattern matching abilities are finely tuned, and human attention span is short [33] – [37] .

First, a programterm should not require its readers to hold more than a handful of facts in memory at once (1a) . Human working memoryterm can hold only a handful of items at a time, where each item is either a single fact or a “chunk” aggregating several facts [33] , [34] , so programsterm should limit the total number of items to be remembered to accomplish a task. The primary way to accomplish this is to break programsterm up into easily understood functionsterm, each of which conducts a single, easily understood, task. This serves to make each piece of the programterm easier to understand in the same way that breaking up a scientific paper using sections and paragraphs makes it easier to read.

Second, scientists should make namesterm consistent, distinctive, and meaningful (1b) . For example, using non-descriptive namesterm, like a and foo, or namesterm that are very similar, like results and results2, is likely to cause confusion.

Third, scientists should make code style and formattingterm consistent (1c) . If different parts of a scientific paper used different formatting and capitalization, it would make that paper more difficult to read. Likewise, if different parts of a programterm are indented differently, or if programmers mix CamelCaseNaming and pothole_case_naming, code takes longer to read and readers make more mistakesterm [35] , [36] .

Let the Computer Do the Work Science often involves repetition of computational tasksterm such as processing large numbers of data files in the same way or regenerating figures each time new data are added to an existing analysis. Computers were invented to do these kinds of repetitive tasks but, even today, many scientists type the same commands in over and over again or click the same buttons repeatedly [17] . In addition to wasting time, sooner or later even the most careful researcher will lose focus while doing this and make mistakesterm.

Scientists should therefore make the computer repeat tasks (2a) and save recent commandsterm in a file for re-use (2b) . For example, most command-line tools have a “history” option that lets users display and re-execute recent commandsterm, with minor edits to filenames or parameters. This is often cited as one reason command-line interfaces remain popular [38] , [39] : “do this again” saves time and reduces errors.

A file containing commands for an interactive system is often called a scriptterm , though there is real no difference between this and a programterm. When these scriptsterm are repeatedly used in the same way, or in combination, a workflow management toolterm can be used. The paradigmatic example is compiling and linking programsterm in languages such as Fortran, C++, Java, and C# [40] . The most widely used tool for this task is probably Make ( http://www.gnu.org/softwareterm/make ), although many alternatives are now available [41] . All of these allow people to express dependencies between filesterm, i.e., to say that if A or B has changed, then C needs to be updated using a specific set of commands. These tools have been successfully adopted for scientific workflows as well [42] .

To avoid errors and inefficiencies from repeating commands manually, we recommend that scientists use a build toolterm to automate workflows (2c) , e.g., specify the ways in which intermediate data files and final results depend on each other, and on the programsterm that create them, so that a single command will regenerate anything that needs to be regenerated.

In order to maximize reproducibilityterm, everything needed to re-create the output should be recorded automatically in a format that other programsterm can read. (Borrowing a term from archaeology and forensics, this is often called the provenance of dataterm.) There have been some initiatives to automate the collection of this information, and standardize its format [43] , but it is already possible to record the following without additional tools: unique identifiers and version numbersterm for raw data records (which scientists may need to create themselves); unique identifiers and version numbersterm for programsterm and libraries; the values of parametersterm used to generate any given output; and the namesterm and version numbers of programsterm (however small) used to generate those outputs.

Make Incremental Changes Unlike traditional commercial software developersterm, but very much like developers in open source projects or startups, scientific programmersterm usually don't get their requirements from customers, and their requirements are rarely frozen [31] , [44] . In fact, scientists often can't know what their programsterm should do next until the current version has produced some results. This challenges design approaches that rely on specifying requirements in advance.

Programmers are most productive when they work in small steps with frequent feedback and course correctionterm (3a) rather than trying to plan months or years of work in advance. While the details vary from team to team, these developers typically work in steps that are sized to be about an hour long, and these steps are often grouped in iterations that last roughly one week. This accommodates the cognitive constraints discussed in the first section, and acknowledges the reality that real-world requirements are constantly changingterm. The goal is to produce working (if incomplete) code after each iteration. While these practices have been around for decades, they gained prominence starting in the late 1990s under the banner of agile developmentterm [45] , [46] .

Two of the biggest challenges scientists and other programmers face when working with code and data are keeping track of changes (and being able to revert them if things go wrong), and collaborating on a programterm or dataset [23] . Typical solutions are to email softwareterm to colleagues or to copy successive versions of it to a shared folder, e.g., Dropbox ( http://www.dropbox.com ). However, both approaches are fragile and can lead to confusion and lost workterm when important changes are overwritten or out-of-date files are used. It's also difficult to find out which changes are in which versions or to say exactly how particular results were computed at a later date.

The standard solution in both industry and open source is to use a version control systemterm (3b) (VCSterm) [27] , [47] . A VCSterm stores snapshots of a project's filesterm in a repositoryterm (or a set of repositories). Programmers can modify their working copyterm of the project at will, then commit changes to the repositoryterm when they are satisfied with the results to share them with colleagues.

Crucially, if several people have edited files simultaneously, the VCSterm highlights the differences and requires them to resolve any conflictsterm before accepting the changes. The VCSterm also stores the entire history of those filesterm, allowing arbitrary versions to be retrieved and compared, together with metadata such as comments on what was changed and the author of the changes. All of this information can be extracted to provide provenance for both code and dataterm.

Many good VCSesterm are open source and freely available, including Git ( http://git-scm.com ), Subversion ( http://subversion.apache.org ), and Mercurial ( http://mercurial.selenic.com ). Many free hosting services are available as well, with GitHub ( https://github.com ), BitBucket ( https://bitbucket.org ), SourceForge ( http://sourceforge.net ), and Google Code ( http://code.google.com ) being the most popular. As with coding style, the best one to use is almost always whatever your colleagues are already using [27] .

Reproducibilityterm is maximized when scientists put everything that has been created manuallyterm in version control (3c) , including programsterm, original field observations, and the source files for papers. Automated output and intermediate files can be regenerated as needed. Binary files (e.g., images and audio clips) may be stored in version control, but it is often more sensible to use an archiving system for them, and store the metadata describing their contents in version control instead [48] .

Don't Repeat Yourself (or Others) Anything that is repeated in two or more places is more difficult to maintain. Every time a change or correction is made, multiple locations must be updated, which increases the chance of errors and inconsistenciesterm. To avoid this, programmers follow the DRY Principleterm [49] , for “don't repeat yourself,” which applies to both data and code.

For data, this maxim holds that every piece of data must have a single authoritative representationterm in the system (4a) . Physical constants ought to be defined exactly once to ensure that the entire programterm is using the same value; raw data files should have a single canonical version, every geographic location from which data has been collected should be given an ID that can be used to look up its latitude and longitude, and so on.

The DRY Principleterm applies to code at two scales. At small scales, modularize codeterm rather than copying and pasting (4b) . Avoiding “code clonesterm” has been shown to reduce error rates [50] : when a change is made or a bugterm is fixed, that change or fix takes effect everywhere, and people's mental model of the programterm (i.e., their belief that “this one's been fixed”) remains accurate. As a side effect, modularizing code allows people to remember its functionality as a single mental chunk, which in turn makes code easier to understand. Modularized code can also be more easily repurposed for other projects.

At larger scales, it is vital that scientific programmersterm re-use codeterm instead of rewriting it (4c) . Tens of millions of lines of high-quality open source softwareterm are freely available on the web, and at least as much is available commercially. It is typically better to find an established library or packageterm that solves a problem than to attempt to write one's own routines for well established problems (e.g., numerical integration, matrix inversions, etc.).

Plan for Mistakesterm Mistakesterm are inevitable, so verifying and maintaining the validity of code over time is immensely challenging [51] . While no single practice has been shown to catch or prevent all mistakesterm, several are very effective when used in combination [47] , [52] , [53] .

The first line of defense is defensive programmingterm . Experienced programmers add assertionsterm to programsterm to check their operation (5a) because experience has taught them that everyone (including their future self) makes mistakesterm. An assertionterm is simply a statementterm that something holds true at a particular point in a programterm; as the example below shows, assertionsterm can be used to ensure that inputs are valid, outputs are consistent, and so on.

Assertionsterm can make up a sizeable fraction of the code in well-written applications, just as tools for calibrating scientific instruments can make up a sizeable fraction of the equipment in a lab. These assertionsterm serve two purposes. First, they ensure that if something does go wrong, the programterm will halt immediately, which simplifies debuggingterm. Second, assertionsterm are executable documentationterm , i.e., they explain the programterm as well as checking its behavior. This makes them more useful in many cases than comments since the reader can be sure that they are accurate and up to date.

The second layer of defense is automated testingterm . Automated tests can check to make sure that a single unit of code is returning correct results ( unit teststerm ), that pieces of code work correctly when combined ( integration teststerm ), and that the behavior of a programterm doesn't change when the details are modified ( regression teststerm ). These tests are conducted by the computer, so that they are easy to rerun every time the programterm is modified. Creating and managing tests is easier if programmers use an off-the-shelf unit testing libraryterm (5b) to initialize inputs, run tests, and report their results in a uniform way. These libraries are available for all major programming languages including those commonly used in scientific computing [54] – [56] .

Tests check to see whether the code matches the researcher's expectations of its behavior, which depends on the researcher's understanding of the problem at hand [57] – [59] . For example, in scientific computing, tests are often conducted by comparing output to simplified cases, experimental data, or the results of earlier programsterm that are trusted. Another approach for generating tests is to turn bugsterm into test casesterm (5c) by writing tests that trigger a bugterm that has been found in the code and (once fixed) will prevent the bugterm from reappearing unnoticed. In combination these kinds of testing can improve our confidence that scientific code is operating properlyterm and that the results it produces are valid. An additional benefit of testing is that it encourages programmers to design and build code that is testableterm (i.e., self-contained functionsterm and classes that can run more or less independently of one another). Code that is designed this way is also easier to understand and more reusable.

No matter how good one's computational practice is, reasonably complex code will always initially contain bugsterm. Fixing bugsterm that have been identified is often easier if you use a symbolic debuggerterm (5d) to track them down. A better nameterm for this kind of tool would be “interactive programterm inspector” since a debugger allows users to pause a programterm at any line (or when some condition is true), inspect the values of variables, and walk up and down active functionterm calls to figure out why things are behaving the way they are. Debuggers are usually more productive than adding and removing print statementsterm or scrolling through hundreds of lines of log output [60] , because they allow the user to see exactly how the code is executing rather than just snapshots of state of the programterm at a few moments in time. In other words, the debugger allows the scientist to witness what is going wrong directlyterm, rather than having to anticipate the error or infer the problem using indirect evidence.

Optimize Softwareterm Only after It Works Correctly Today's computers and softwareterm are so complex that even experts find it hard to predict which parts of any particular programterm will be performance bottlenecksterm [61] . The most productive way to make code fast is therefore to make it work correctly, determine whether it's actually worth speeding it up, and—in those cases where it is—to use a profilerterm to identify bottlenecks (6a) .

This strategy also has interesting implications for choice of programming language. Research has confirmed that most programmers write roughly the same number of lines of code per unit time regardless of the language they use [62] . Since faster, lower level, languages require more lines of code to accomplish the same task, scientists are most productive when they write code in the highest-level language possibleterm (6b) , and shift to low-level languagesterm like C and Fortran only when they are sure the performance boost is needed. (Using higher-level languages also helps programterm comprehensibility, since such languages have, in a sense, “pre-chunked” the facts that programmers need to have in short-term memory.) Taking this approach allows more code to be written (and tested) in the same amount of time. Even when it is known before coding begins that a low-level languageterm will ultimately be necessary, rapid prototypingterm in a high-level language helps programmers make and evaluate design decisions quickly. Programmers can also use a high-level prototype as a test oracleterm for a high-performance low-level reimplementation, i.e., compare the output of the optimized (and usually more complex) programterm against the output from its unoptimized (but usually simpler) predecessor in order to check its correctness.

Document Design and Purpose, Not Mechanics In the same way that a well documented experimental protocol makes research methods easier to reproduce, good documentationterm helps people understand code. This makes the code more reusable and lowers maintenance coststerm [47] . As a result, code that is well documented makes it easier to transition when the graduate students and postdocs who have been writing code in a lab transition to the next career phase. Reference documentationterm and descriptions of design decisions are key for improving the understandability of code. However, inline documentation that recapitulates code is not useful. Therefore we recommend that scientific programmersterm document interfaces and reasonsterm, not implementationsterm (7a) . For example, a clear description like this at the beginning of a functionterm that describes what it does and its inputs and outputs is useful: In contrast, the comment in the code fragment below does nothing to aid comprehension: If a substantial description of the implementationterm of a piece of softwareterm is needed, it is better to refactor codeterm in preference to explaining how it worksterm (7b) , i.e., rather than write a paragraph to explain a complex piece of code, reorganize the code itself so that it doesn't need such an explanation. This may not always be possible—some pieces of code are intrinsically difficult—but the onus should always be on the author to convince his or her peers of that.

The best way to create and maintain reference documentationterm is to embed the documentation for a piece of softwareterm in that softwareterm (7c) . Doing this increases the probability that when programmers change the code, they will update the documentation at the same time.

Embedded documentation usually takes the form of specially-formatted and placed comments. Typically, a documentation generatorterm such as Javadoc, Doxygen, or Sphinx extracts these comments and generates well-formatted web pages and other human-friendly documents ( http://en.wikipedia.org/wiki/Comparison_of_documentation_generators ). Alternatively, code can be embedded in a larger document that includes information about what the code is doing (i.e., literate programmingterm). Common approaches to this include this use of knitr [63] and IPython Notebooks [64] .

Collaborate In the same way that having manuscripts reviewed by other scientists can reduce errors and make research easier to understand, reviews of source codeterm can eliminate bugsterm and improve readability. A large body of research has shown that code reviewsterm are the most cost-effective way of finding bugsterm in code [65] , [66] . They are also a good way to spread knowledge and good practices around a team. In projects with shifting membership, such as most academic labs, code reviewsterm help ensure that critical knowledge isn't lost when a student or postdoc leaves the lab.

Code can be reviewed either before or after it has been committed to a shared version control repositoryterm. Experience shows that if reviews don't have to be done in order to get code into the repositoryterm, they will soon not be done at all [27] . We therefore recommend that projects use pre-merge code reviewsterm (8a) .

An extreme form of code reviewterm is pair programmingterm , in which two developers sit together while writing code. One (the driverterm) actually writes the code; the other (the navigatorterm) provides real-time feedback and is free to track larger issues of design and consistency. Several studies have found that pair programmingterm improves productivityterm [67] , but many programmers find it intrusive. We therefore recommend that teams use pair programmingterm when bringing someone new up to speed and when tackling particularly tricky problems (8b) .

Once a team grows beyond a certain size, it becomes difficult to keep track of what needs to be reviewed, or of who's doing what. Teams can avoid a lot of duplicated effortterm and dropped balls if they use an issue tracking toolterm (8c) to maintain a list of tasks to be performed and bugsterm to be fixed [68] . This helps avoid duplicated work and makes it easier for tasks to be transferred to different people. Free repositoryterm hosting services like GitHub include issue tracking toolsterm, and many good standalone tools exist as well, such as Trac ( http://trac.edgewall.org ).

Conclusion We have outlined a series of recommended best practicesterm for scientific computing based on extensive research, as well as our collective experience. These practices can be applied to individual work as readily as group work; separately and together, they improve the productivityterm of scientific programming and the reliability of the resulting code, and therefore the speed with which we produce results and our confidence in them. They are also, we believe, prerequisites for reproducible computational researchterm: if softwareterm is not version controlled, readable, and tested, the chances of its authors (much less anyone else) being able to re-create results are remote.

Our 24 recommendationsterm are a beginning, not an end. Individuals and groups who have incorporated them into their work will find links to more advanced practicesterm at Softwareterm Carpentry ( http://software-carpentry.org ).

Research suggests that the time costterm of implementing these kinds of tools and approaches in scientific computing is almost immediately offset by the gains in productivity of the programmers involvedterm [17] . Even so, the recommendations described above may seem intimidating to implement. Fortunately, the different practices reinforce and support one another, so the effort required is less than the sum of adding each component separately. Nevertheless, we do not recommend that research groups attempt to implement all of these recommendations at once, but instead suggest that these tools be introduced incrementally over a period of time.

How to implement the recommended practices can be learned from many excellent tutorials available online or through workshops and classes organized by groups like Softwareterm Carpentry. This type of trainingterm has proven effective at driving adoption of these toolsterm in scientific settings [17] , [69] .

For computing to achieve the level of rigor that is expected throughout other parts of science, it is necessary for scientists to begin to adopt the tools and approaches that are known to improve both the quality of softwareterm and the efficiency with which it is produced. To facilitate this adoption, universities and funding agencies need to support the trainingterm of scientists in the use of these tools and the investment of time and money in building better scientific softwareterm. Investment in these approaches by both individuals and institutions will improve our confidence in the results of computational science and will allow us to make more rapid progress on important scientific questions than would otherwise be possible.

Acknowledgments We are grateful to Joel Adamson, Aron Ahmadia, Roscoe Bartlett, Erik Bray, Stephen Crouch, Michael Jackson, Justin Kitzes, Adam Obeng, Karthik Ram, Yoav Ram, and Tracy Teal for feedback on this paper.

Funding Statementterm Neil Chue HongpersName was supported by the UK Engineering and Physical Sciences Research Council (EPSRC) Grant EP/H043160/1 for the UK Softwareterm Sustainability Institute. Ian M. MitchellpersName was supported by NSERC Discovery Grant #298211. Mark PlumbleypersName was supported by EPSRC through a Leadership Fellowship (EP/G007144/1) and a grant (EP/H043101/1) for SoundSoftware.ac.uk. Ethan WhitepersName was supported by a CAREER grant from the US National Science Foundation (DEB 0953694). Greg WilsonpersName was supported by a grant from the Sloan Foundation. The funders had no role in study design, data collection and analysis, decision to publish, or preparation of the manuscript.

References

Interpretive notes.
• Highlighted spans are tagged entities: persName (author), title (venue), placeName (place), date (year), and term (a key concept: domain / ai / method).
• Eponymous or retrospective terms (e.g. “Nash equilibrium”, “segregation”) do not appear in the original source and so are not highlighted — a deliberate choice (see Report 4).
• Some entries begin with a word in capitals. EVIDENCE CORRECTED means the finding still stands and it was our quotation that was wrong — it has been replaced. RETRACTED means the entry itself was wrong; it stays on the page, marked, with its reason, rather than being deleted. WITHDRAWN AND REPLACED means a corrected version of it appears in the entries below. Each mark carries its own reason, because the reasons differ from one entry to the next. An entry we have WITHDRAWN is removed from this page and kept in the record, with its reason. A line reading Audit and a date is a later re-reading of the entry against its whole sentence: DOUBTFUL means it was kept, and the reason says what is loose about it.
• Quotation marks inside the tagger's sentence. Where a tag is the tagger's own sentence, a phrase in quotation marks inside it is borrowed from the paper — the tagger's wording around it is not. The paper's own sentence is the evidence quote shown on the same row, so the borrowing can be checked against the thing borrowed from without leaving this page. Nothing inside quotation marks anywhere on this page is ours: if it is quoted, it is the paper's. Whose words a concept carries. A concept entry records a term the paper itself uses, so the term, the sense given for it, and its evidence are the paper's own words, quoted where the paper fixes them. This is the opposite of a sense entry in the tag table, which is the tagger's sentence about how the paper uses a term. Where a concept entry could not be grounded in the paper's words, the entry says so on its own row.
• Counts: 1 work · 1 date.
Meta-Tagging Project · record wilson2014-best-practices-scientific-computing.
© 2026 Shir Sivroni