<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="generator" content="pandoc">
  <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=yes">
  <title>P2114R0 &mdash; Minimal Contract Use Cases</title>
  <style type="text/css">code{white-space: pre;}</style>
  <style type="text/css">
a.sourceLine { display: inline-block; line-height: 1.25; }
a.sourceLine { pointer-events: none; color: inherit; text-decoration: inherit; }
a.sourceLine:empty { height: 1.2em; }
.sourceCode { overflow: visible; }
code.sourceCode { white-space: pre; position: relative; }
div.sourceCode { margin: 1em 0; }
pre.sourceCode { margin: 0; }
@media screen {
div.sourceCode { overflow: auto; }
}
@media print {
code.sourceCode { white-space: pre-wrap; }
a.sourceLine { text-indent: -1em; padding-left: 1em; }
}
pre.numberSource a.sourceLine
  { position: relative; left: -4em; }
pre.numberSource a.sourceLine::before
  { content: attr(title);
    position: relative; left: -1em; text-align: right; vertical-align: baseline;
    border: none; pointer-events: all; display: inline-block;
    -webkit-touch-callout: none; -webkit-user-select: none;
    -khtml-user-select: none; -moz-user-select: none;
    -ms-user-select: none; user-select: none;
    padding: 0 4px; width: 4em;
    color: #aaaaaa;
  }
pre.numberSource { margin-left: 3em; border-left: 1px solid #aaaaaa;  padding-left: 4px; }
div.sourceCode
  {  }
@media screen {
a.sourceLine::before { text-decoration: underline; }
}
code span.al { color: #ff0000; font-weight: bold; } /* Alert */
code span.an { color: #60a0b0; font-weight: bold; font-style: italic; } /* Annotation */
code span.at { color: #7d9029; } /* Attribute */
code span.bn { color: #40a070; } /* BaseN */
code span.bu { } /* BuiltIn */
code span.cf { color: #007020; font-weight: bold; } /* ControlFlow */
code span.ch { color: #4070a0; } /* Char */
code span.cn { color: #880000; } /* Constant */
code span.co { color: #60a0b0; font-style: italic; } /* Comment */
code span.cv { color: #60a0b0; font-weight: bold; font-style: italic; } /* CommentVar */
code span.do { color: #ba2121; font-style: italic; } /* Documentation */
code span.dt { color: #902000; } /* DataType */
code span.dv { color: #40a070; } /* DecVal */
code span.er { color: #ff0000; font-weight: bold; } /* Error */
code span.ex { } /* Extension */
code span.fl { color: #40a070; } /* Float */
code span.fu { color: #06287e; } /* Function */
code span.im { } /* Import */
code span.in { color: #60a0b0; font-weight: bold; font-style: italic; } /* Information */
code span.kw { color: #007020; font-weight: bold; } /* Keyword */
code span.op { color: #666666; } /* Operator */
code span.ot { color: #007020; } /* Other */
code span.pp { color: #bc7a00; } /* Preprocessor */
code span.sc { color: #4070a0; } /* SpecialChar */
code span.ss { color: #bb6688; } /* SpecialString */
code span.st { color: #4070a0; } /* String */
code span.va { color: #19177c; } /* Variable */
code span.vs { color: #4070a0; } /* VerbatimString */
code span.wa { color: #60a0b0; font-weight: bold; font-style: italic; } /* Warning */
  </style>
  <link rel="stylesheet" href="github.css">
  <!-- Style for Markdown -->
  <style>
  .md2html-container {
    max-width: 800px;
    margin: 0 auto;
  }
  .md2html-container > h1:first-child {
    margin-top: 0;
  }
  body {
  font-family: Helvetica, arial, sans-serif;
  font-size: 14px;
  line-height: 1.6;
  padding-top: 10px;
  padding-bottom: 10px;
  background-color: white;
  padding: 30px; }

body > *:first-child {
  margin-top: 0 !important; }
body > *:last-child {
  margin-bottom: 0 !important; }

a {
  color: #4183C4; }
a.absent {
  color: #cc0000; }
a.anchor {
  display: block;
  padding-left: 30px;
  margin-left: -30px;
  cursor: pointer;
  position: absolute;
  top: 0;
  left: 0;
  bottom: 0; }

h1, h2, h3, h4, h5, h6 {
  margin: 20px 0 10px;
  padding: 0;
  font-weight: bold;
  -webkit-font-smoothing: antialiased;
  cursor: text;
  position: relative; }

h1:hover a.anchor, h2:hover a.anchor, h3:hover a.anchor, h4:hover a.anchor, h5:hover a.anchor, h6:hover a.anchor {
  background: url("../../images/modules/styleguide/para.png") no-repeat 10px center;
  text-decoration: none; }

h1 tt, h1 code {
  font-size: inherit; }

h2 tt, h2 code {
  font-size: inherit; }

h3 tt, h3 code {
  font-size: inherit; }

h4 tt, h4 code {
  font-size: inherit; }

h5 tt, h5 code {
  font-size: inherit; }

h6 tt, h6 code {
  font-size: inherit; }

h1 {
  font-size: 28px;
  color: black; }

h2 {
  font-size: 24px;
  border-bottom: 1px solid #cccccc;
  color: black; }

h3 {
  font-size: 18px; }

h4 {
  font-size: 16px; }

h5 {
  font-size: 14px; }

h6 {
  color: #777777;
  font-size: 14px; }

p, blockquote, ul, ol, dl, li, table, pre {
  margin: 15px 0; }

hr {
  background: transparent url("../../images/modules/pulls/dirty-shade.png") repeat-x 0 0;
  border: 0 none;
  color: #cccccc;
  height: 4px;
  padding: 0; }

body > h2:first-child {
  margin-top: 0;
  padding-top: 0; }
body > h1:first-child {
  margin-top: 0;
  padding-top: 0; }
  body > h1:first-child + h2 {
    margin-top: 0;
    padding-top: 0; }
body > h3:first-child, body > h4:first-child, body > h5:first-child, body > h6:first-child {
  margin-top: 0;
  padding-top: 0; }

a:first-child h1, a:first-child h2, a:first-child h3, a:first-child h4, a:first-child h5, a:first-child h6 {
  margin-top: 0;
  padding-top: 0; }

h1 p, h2 p, h3 p, h4 p, h5 p, h6 p {
  margin-top: 0; }

li p.first {
  display: inline-block; }

ul, ol {
  padding-left: 30px; }

ul :first-child, ol :first-child {
  margin-top: 0; }

ul :last-child, ol :last-child {
  margin-bottom: 0; }

dl {
  padding: 0; }
  dl dt {
    font-size: 14px;
    font-weight: bold;
    font-style: italic;
    padding: 0;
    margin: 15px 0 5px; }
    dl dt:first-child {
      padding: 0; }
    dl dt > :first-child {
      margin-top: 0; }
    dl dt > :last-child {
      margin-bottom: 0; }
  dl dd {
    margin: 0 0 15px;
    padding: 0 15px; }
    dl dd > :first-child {
      margin-top: 0; }
    dl dd > :last-child {
      margin-bottom: 0; }

blockquote {
  border-left: 4px solid #dddddd;
  padding: 0 15px;
  color: #777777; }
  blockquote > :first-child {
    margin-top: 0; }
  blockquote > :last-child {
    margin-bottom: 0; }

table {
  border-collapse: collapse;
  padding: 0; }
  table tr {
    border-top: 1px solid #cccccc;
    background-color: white;
    margin: 0;
    padding: 0; }
    table tr:nth-child(2n) {
      background-color: #f8f8f8; }
    table tr th {
      font-weight: bold;
      border: 1px solid #cccccc;
      text-align: left;
      margin: 0;
      padding: 6px 13px; }
    table tr td {
      border: 1px solid #cccccc;
      text-align: left;
      margin: 0;
      padding: 6px 13px; }
    table tr th :first-child, table tr td :first-child {
      margin-top: 0; }
    table tr th :last-child, table tr td :last-child {
      margin-bottom: 0; }

img {
  max-width: 100%; }

span.frame {
  display: block;
  overflow: hidden; }
  span.frame > span {
    border: 1px solid #dddddd;
    display: block;
    float: left;
    overflow: hidden;
    margin: 13px 0 0;
    padding: 7px;
    width: auto; }
  span.frame span img {
    display: block;
    float: left; }
  span.frame span span {
    clear: both;
    color: #333333;
    display: block;
    padding: 5px 0 0; }
span.align-center {
  display: block;
  overflow: hidden;
  clear: both; }
  span.align-center > span {
    display: block;
    overflow: hidden;
    margin: 13px auto 0;
    text-align: center; }
  span.align-center span img {
    margin: 0 auto;
    text-align: center; }
span.align-right {
  display: block;
  overflow: hidden;
  clear: both; }
  span.align-right > span {
    display: block;
    overflow: hidden;
    margin: 13px 0 0;
    text-align: right; }
  span.align-right span img {
    margin: 0;
    text-align: right; }
span.float-left {
  display: block;
  margin-right: 13px;
  overflow: hidden;
  float: left; }
  span.float-left span {
    margin: 13px 0 0; }
span.float-right {
  display: block;
  margin-left: 13px;
  overflow: hidden;
  float: right; }
  span.float-right > span {
    display: block;
    overflow: hidden;
    margin: 13px auto 0;
    text-align: right; }

code, tt {
  margin: 0 2px;
  padding: 0 5px;
  white-space: nowrap;
  border: 1px solid #eaeaea;
  background-color: #f8f8f8;
  border-radius: 3px; }

pre code {
  margin: 0;
  padding: 0;
  white-space: pre;
  border: none;
  background: transparent; }

.highlight pre {
  background-color: #f8f8f8;
  border: 1px solid #cccccc;
  font-size: 13px;
  line-height: 19px;
  overflow: auto;
  padding: 6px 10px;
  border-radius: 3px; }

pre {
  background-color: #f8f8f8;
  border: 1px solid #cccccc;
  font-size: 13px;
  line-height: 19px;
  overflow: auto;
  padding: 6px 10px;
  border-radius: 3px; }
  pre code, pre tt {
    background-color: transparent;
    border: none; }
  </style>
  <!--[if lt IE 9]>
    <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/3.7.3/html5shiv-printshiv.min.js"></script>
  <![endif]-->
</head>
<body>

<p>Document no: P2114R0 <br/>
Date: 2020-03-02 <br/>
Authors:
Joshua Berne
Ryan McDougall
Andrzej Krzemieński
<br/>
Reply-to: jberne4@bloomberg.net <br/>
Audience: SG21</p>
<h1>Minimal Contract Use Cases</h1>
<h2>Introduction</h2>
<p>SG21 has been reviewing a large number of potential use cases for contracts.
There are also a number of potential proposals that have previously been put
forward with might be applicapable to those use cases (see <a href="http://wg21.link/P2032R0">P2032</a> ).</p>
<p>We (the authors of this paper, acting inependently)
wish to highlight those use cases that mght be viewed as the true common core
of the proposals so far.  It is our hope to get agreement on this so that the
core of a proposal can be started, and so we can address other features and
satisfying more use cases iteratively on top of that central proposal (instead
of needing to start each proposal from the ground up, and being in a situation
of regularly retreading ground while comparing apples to oranges.)</p>
<p>An additional hope is that, as we get proposals that meet this minimal set of
use cases, a "minimal viable product" emerges that we might be able to provide for
C++23 should a more full-featured proposal not seem to be reachinng consensus in time.
We are not proposing any particular solution here, just a potential guideline for
what use cases a minimal feature needs to satisfy.</p>
<h2>Use Cases</h2>
<p>Here we will list those use cases that we think should be included, with their
original high-level description (see <a href="http://wg21.link/P1995R0">P1995</a> for all
of the use cases).</p>

<table>
  <tr>
    <th>#</th>
    <th>Code</th><th>As A</th><th>In Order To</th><th>I Want To</th>
  </tr>


  
  <tr>
  <td>1</td>
  <td>dev.reason.knowl</td>
  <td>Developer</td>
  <td>Reason explicitly</td>
  <td>Annotate my program anywhere in the code with my current understanding of its
structure or execution</td>
  </tr>

<tr>
  <td colspan="9"> <p>If you could take this out, you still wouldn't be providing anything useful to
users.</p> </td>
</tr>


  <tr>
  <td>2</td>
  <td>dev.reason.behavior</td>
  <td>Developer</td>
  <td>Reason about executions</td>
  <td>Have annotations affect the execution of my program in accordance with my
expectations</td>
  </tr>



  <tr>
  <td>3</td>
  <td>dev.reason.sideeffects</td>
  <td>Developer</td>
  <td>Reason about executions</td>
  <td>Ensure annotations do not substantially change the meaning of my program
whether enabled or disabled</td>
  </tr>

<tr>
  <td colspan="9"> <p>it is important that there is an option to enable contracts and an option to disable contracts that does not include undefined behavior.</p> </td>
</tr>


  <tr>
  <td>4</td>
  <td>dev.readable.syntax</td>
  <td>Developer</td>
  <td>Have readable annotations</td>
  <td>Have annotations with a succinct and elegant syntax</td>
  </tr>



  <tr>
  <td>5</td>
  <td>dev.readable.keywords</td>
  <td>Developer</td>
  <td>Have readable annotations</td>
  <td>Have annotation keywords or names with intuitive, clear, and unambiguous
meanings</td>
  </tr>



  <tr>
  <td>6</td>
  <td>dev.parsable</td>
  <td>Developer</td>
  <td>Interoperate with tools or persons</td>
  <td>A syntax that can both be parsed and can be reasoned about semantically</td>
  </tr>



  <tr>
  <td>7</td>
  <td>dev.tooling</td>
  <td>Developer</td>
  <td>Interoperate with tools or persons</td>
  <td>Expose annotations to tools that might leverage them (eg. code linter, static
analyzer, semantic prover, compiler sanitizer, binary analyzer, code reviewer,
etc.)</td>
  </tr>



  <tr>
  <td>8</td>
  <td>cppdev.syntax.familiar</td>
  <td>C++ Developer</td>
  <td>Get up to speed</td>
  <td>Have annotations use familiar syntax</td>
  </tr>



  <tr>
  <td>9</td>
  <td>cppdev.syntax.cpp</td>
  <td>C++ Developer</td>
  <td>Get up to speed</td>
  <td>Have annotations use C++ syntax</td>
  </tr>



  <tr>
  <td>10</td>
  <td>cppdev.syntax.reuse</td>
  <td>C++ Developer</td>
  <td>Reuse code</td>
  <td>Have annotations use my custom types or functions</td>
  </tr>



  <tr>
  <td>11</td>
  <td>cppdev.location</td>
  <td>C++ Developer</td>
  <td>Have a single source of truth</td>
  <td>Use same source file for both code and annotations</td>
  </tr>



  <tr>
  <td>12</td>
  <td>api.communicate.inputsoutputs</td>
  <td>API Developer</td>
  <td>Communicate my interface to users</td>
  <td>Document the expected inputs and expected outputs on my interface</td>
  </tr>



  <tr>
  <td>13</td>
  <td>api.establish.check</td>
  <td>API Developer</td>
  <td>Establish a contract</td>
  <td>Have validation inform me which output values are unexpected or invalid</td>
  </tr>



  <tr>
  <td>14</td>
  <td>api.establish.values</td>
  <td>API Developer</td>
  <td>Establish a contract</td>
  <td>Have validation inform user which input values are unexpected or invalid</td>
  </tr>



  <tr>
  <td>15</td>
  <td>api.establish.preconditions</td>
  <td>API Developer</td>
  <td>Establish a contract</td>
  <td>Have contracts specify their pre-conditions as logical predicates</td>
  </tr>



  <tr>
  <td>16</td>
  <td>api.establish.postconditions</td>
  <td>API Developer</td>
  <td>Establish a contract</td>
  <td>Have contracts specify their post-conditions as logical predicates</td>
  </tr>



  <tr>
  <td>17</td>
  <td>api.express.values</td>
  <td>API Developer</td>
  <td>Express predicates</td>
  <td>Make reference to either the values of my inputs, or other in-scope identifiers</td>
  </tr>



  <tr>
  <td>18</td>
  <td>api.contract.errorhandling</td>
  <td>API Developer</td>
  <td>Move contract violation out of error handling</td>
  <td>Replace uses of error handling to express contract violation (eg.
<i>operator[](size_t n) noexcept [[pre: n &lt; size()]]</i> instead of
throwing)</td>
  </tr>



  <tr>
  <td>19</td>
  <td>int.conform.violation</td>
  <td>Integration Developer</td>
  <td>Conform to a contract</td>
  <td>Be informed any time an interface's contract is violated</td>
  </tr>



  <tr>
  <td>20</td>
  <td>int.conform.postconditions</td>
  <td>Integration Developer</td>
  <td>Conform to a contract</td>
  <td>Verify results from a call are expected output values</td>
  </tr>



  <tr>
  <td>21</td>
  <td>int.build.headeronly</td>
  <td>Integration Developer</td>
  <td>Build multiple libraries</td>
  <td>Use contract-enabled header-only libraries</td>
  </tr>



  <tr>
  <td>22</td>
  <td>int.build.binaries</td>
  <td>Integration Developer</td>
  <td>Build multiple libraries</td>
  <td>Use contract-enabled binary libraries</td>
  </tr>



  <tr>
  <td>23</td>
  <td>int.violations.information</td>
  <td>Integration Developer</td>
  <td>Correct failed checks</td>
  <td>Be informed what check failed, when, where, and how</td>
  </tr>



  <tr>
  <td>24</td>
  <td>int.violations.common</td>
  <td>Integration Developer</td>
  <td>Unify violation handling</td>
  <td>Be able to override how library violations are handled in the combined software
to point into my handling code</td>
  </tr>



  <tr>
  <td>25</td>
  <td>int.control.build</td>
  <td>Integrated Software Provider</td>
  <td>Ensure the combined software is correct</td>
  <td>At build time, turn on and off what checking happens.</td>
  </tr>



  <tr>
  <td>26</td>
  <td>int.runtime.unchecked</td>
  <td>Integrated Software Provider</td>
  <td>Test final deliverable</td>
  <td>Turn off run time checking to remove checking overhead</td>
  </tr>



  <tr>
  <td>27</td>
  <td>cpplib.headeronly</td>
  <td>C++ Library Developer</td>
  <td>Use templates</td>
  <td>Be able to ship header only library</td>
  </tr>



  <tr>
  <td>28</td>
  <td>arch.nomacros</td>
  <td>Technical Architect</td>
  <td>Maintain quality of code base</td>
  <td>Express assertions in a way that does not rely on C macros (i.e., there is no
valid technical reason for a programmer not to use the new way, including
space, time, tooling, and usability/complexity reasons, compared to C's assert
macro)</td>
  </tr>



  <tr>
  <td>29</td>
  <td>arch.complete</td>
  <td>Technical Architect</td>
  <td>Have a consistent and holistic contracts facility</td>
  <td>Specify preconditions/postconditions/assertions/invariants that express my
expectations about the expected valid state of my program in the form of
compilable boolean expressions, that can be checked statically or dynamically
(as opposed to disjointed state where these features are factored into bits)</td>
  </tr>



  <tr>
  <td>30</td>
  <td>sdev.bestpractices</td>
  <td>Senior Developer</td>
  <td>Set an example</td>
  <td>Demonstrate best practice in defensive programming</td>
  </tr>



  <tr>
  <td>31</td>
  <td>sdev.quality</td>
  <td>Senior Developer</td>
  <td>Enforce code quality</td>
  <td>Discourage reliance on observable out-of-contract behavior by causing check
failure to hard stop program or build</td>
  </tr>



  <tr>
  <td>32</td>
  <td>jdev.understand.contracts</td>
  <td>Junior Developer</td>
  <td>Understand the API</td>
  <td>A uniform, fluent description of expected input values, expected output values,
side effects, and all logical pre and post conditions</td>
  </tr>



  <tr>
  <td>33</td>
  <td>jdev.understand.violations</td>
  <td>Junior Developer</td>
  <td>Understand the API</td>
  <td>Be informed when my usage is out of contract</td>
  </tr>



  <tr>
  <td>34</td>
  <td>jdev.understand.aborting</td>
  <td>Junior Developer</td>
  <td>Understand the program</td>
  <td>Know why my software is aborting</td>
  </tr>



  <tr>
  <td>35</td>
  <td>jdev.understand.buildviolation</td>
  <td>Junior Developer</td>
  <td>Understand the program</td>
  <td>Know that my program or build was halted due to contract violation</td>
  </tr>



  <tr>
  <td>36</td>
  <td>jdev.understand.all</td>
  <td>Junior Developer</td>
  <td>Understand the facility</td>
  <td>Be able to build a program with contracts after reasonably short tutorial</td>
  </tr>



  <tr>
  <td>37</td>
  <td>jdev.understand.keywords</td>
  <td>Junior Developer</td>
  <td>Understand the facility</td>
  <td>Have keywords with precise and unambiguous meanings</td>
  </tr>



  <tr>
  <td>38</td>
  <td>jdev.bestpractices</td>
  <td>Junior Developer</td>
  <td>Improve my code</td>
  <td>Learn about software best practices by example</td>
  </tr>



  <tr>
  <td>39</td>
  <td>adev.fast</td>
  <td>Agile Developer</td>
  <td>Iterate quickly</td>
  <td>Be able to write and modify contracts quickly without heavy boiler plate or up
front cost</td>
  </tr>



  <tr>
  <td>40</td>
  <td>qdev.checkall</td>
  <td>Quality Sensitive Developer</td>
  <td>Enable full checking</td>
  <td>Ensure all checks (pre, post, assert, invariant) are enabled</td>
  </tr>



  <tr>
  <td>41</td>
  <td>teach.bestpractices</td>
  <td>Teacher</td>
  <td>Demonstrate best practice</td>
  <td>Be able to express defensive programming, programming by contract, and test
driven development to introductory students</td>
  </tr>



  <tr>
  <td>42</td>
  <td>teach.standardized</td>
  <td>Teacher</td>
  <td>Demonstrate best practice</td>
  <td>Not rely on custom libraries or proprietary extensions</td>
  </tr>



  <tr>
  <td>43</td>
  <td>teach.portable</td>
  <td>Teacher</td>
  <td>Manage many students</td>
  <td>Have examples compilable by a standard compiler on any system</td>
  </tr>



  <tr>
  <td>44</td>
  <td>teach.teachable</td>
  <td>Teacher</td>
  <td>Build layers of understanding</td>
  <td>Have simple explanation of assertions and their use to support simple
programming tasks, including debugging erroneous programs.</td>
  </tr>



  <tr>
  <td>45</td>
  <td>compiler.best</td>
  <td>Compiler Developer</td>
  <td>Deliver the best implementation</td>
  <td>Have a clear and simple specification that meets clear need</td>
  </tr>




</table>

<br/>

<h2>Conclusion</h2>
<p>This began as an excercise amongst the authors, and we hope that we have identified
something that would be minimally viable to agree on as a group.</p>
<p>We encourage anyone to compare these results with the use cases and convince
themselves this is minimally viable for their own users, or provide feedback on
what else is needed/what is excessive to increase this initial step on the
road to consensus.</p>

</body>
</html>

