<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body text="#000000" bgcolor="#FFFFFF">
<p><br>
</p>
<p>I use DbC occasionally to clarify my thoughts during a
refactoring, and then only in the places that continue to make
mistakes. In general, I am not in a domain that benefits from DbC.
<br>
</p>
<p>Contracts are code: More code means more bugs. Declarative
contracts are succinct, but difficult to debug when wrong; I
believe this because the debugger support for contracts is poor;
There is no way to step through the logic and see the intermediate
reasoning in complex contracts. A contract is an incomplete
duplication of what the code already does: at some level of
complexity I prefer to use a duplicate independent implementation
and compare inputs/outputs.<br>
</p>
Writing contracts cost time and money; and that cost should be
weighed against the number and flexibility of the customers that use
the code. A one-time script, a webapp for you team, an Android app
for your startup, fraud software, and Facebook make different
accounting decisions. I contend most code projects can not justify
DbC.<br>
<br>
<br>
<div class="moz-cite-prefix">On 2018-09-24 03:46, Marko
Ristin-Kaufmann wrote:<br>
</div>
<blockquote type="cite"
cite="mid:CAGu4bVB4=Bou+DhoDzayx=i7eQ2Gr8KDDOFONeaB-Qvt8LZo2A@mail.gmail.com">
<meta http-equiv="content-type" content="text/html; charset=utf-8">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">When you
are documenting a
method you have the
following options:<br>
<div>1) Write
preconditions and
postconditions
formally and include
them automatically
in the documentation
(<i>e.g., </i>by
using icontract
library). <br>
</div>
<div>2) Write
precondtions and
postconditions in
docstring of the
method as human
text.<br>
</div>
<div>3) Write doctests
in the docstring of
the method.<br>
</div>
<div>4) Expect the
user to read the
actual
implementation.<br>
</div>
<div>5) Expect the
user to read the
testing code.<br>
</div>
<div dir="ltr"><br>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<br>
There are other ways to communicate how a method works.<br>
<br>
6) The name of the method<br>
7) How the method is called throughout the codebase <br>
8) observing input and output values during debugging<br>
9) observing input and output values in production<br>
10) relying on convention inside, and outside, the application<br>
11) Don't communicate - Sometimes
<complexity>/<num_customers> is too high; code is not
repaired, only replaced.<br>
<br>
<br>
<blockquote type="cite"
cite="mid:CAGu4bVB4=Bou+DhoDzayx=i7eQ2Gr8KDDOFONeaB-Qvt8LZo2A@mail.gmail.com">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">
<div dir="ltr">This is
again something that
eludes me and I would
be really thankful if
you could clarify.
Please consider for an
example, pypackagery (<a
href="https://pypackagery.readthedocs.io/en/latest/packagery.html"
moz-do-not-send="true">https://pypackagery.readthedocs.io/en/latest/packagery.html</a>)
and the documentation
of its function
resolve_initial_paths:<br>
<div dir="ltr">
<div>
<dl
class="gmail-function">
<dt
id="gmail-packagery.resolve_initial_paths">
<code
class="gmail-descclassname">packagery.</code><code
class="gmail-descname">resolve_initial_paths</code><span
class="gmail-sig-paren">(</span><em>initial_paths</em><span
class="gmail-sig-paren">)</span></dt>
<dd>
<p>Resolve the
initial paths
of the
dependency
graph by
recursively
adding <code
class="gmail-docutils gmail-literal gmail-notranslate"><span
class="gmail-pre">*.py</span></code>
files beneath
given
directories.</p>
<table
class="gmail-docutils
gmail-field-list" frame="void" rules="none">
<colgroup><col
class="gmail-field-name">
<col
class="gmail-field-body">
</colgroup><tbody
valign="top">
<tr
class="gmail-field-odd
gmail-field">
<th
class="gmail-field-name">Parameters:</th>
<td
class="gmail-field-body">
<p
class="gmail-first"><strong>initial_paths</strong>
(<code
class="gmail-xref
gmail-py
gmail-py-class
gmail-docutils
gmail-literal
gmail-notranslate"><span class="gmail-pre">List</span></code>[<code
class="gmail-xref
gmail-py
gmail-py-class
gmail-docutils
gmail-literal
gmail-notranslate"><span class="gmail-pre">Path</span></code>]) –
initial paths
as absolute
paths</p>
</td>
</tr>
<tr
class="gmail-field-even
gmail-field">
<th
class="gmail-field-name">Return
type:</th>
<td
class="gmail-field-body">
<p
class="gmail-first"><code
class="gmail-xref gmail-py gmail-py-class gmail-docutils gmail-literal
gmail-notranslate"><span
class="gmail-pre">List</span></code>[<code class="gmail-xref gmail-py
gmail-py-class
gmail-docutils
gmail-literal
gmail-notranslate"><span class="gmail-pre">Path</span></code>]</p>
</td>
</tr>
<tr
class="gmail-field-odd
gmail-field">
<th
class="gmail-field-name">Returns:</th>
<td
class="gmail-field-body">
<p
class="gmail-first">list
of initial
files (<em>i.e.</em>
no
directories)</p>
</td>
</tr>
<tr
class="gmail-field-even
gmail-field">
<th
class="gmail-field-name">Requires:</th>
<td
class="gmail-field-body">
<ul
class="gmail-first
gmail-simple">
<li><code
class="gmail-code
gmail-docutils
gmail-literal
gmail-notranslate"><span class="gmail-pre">all(pth.is_absolute()</span>
<span
class="gmail-pre">for</span>
<span
class="gmail-pre">pth</span>
<span
class="gmail-pre">in</span>
<span
class="gmail-pre">initial_paths)</span></code></li>
</ul>
</td>
</tr>
<tr
class="gmail-field-odd
gmail-field">
<th
class="gmail-field-name">Ensures:</th>
<td
class="gmail-field-body">
<ul
class="gmail-first
gmail-last
gmail-simple">
<li><code
class="gmail-code
gmail-docutils
gmail-literal
gmail-notranslate"><span class="gmail-pre">len(result)</span> <span
class="gmail-pre">>=</span>
<span
class="gmail-pre">len(initial_paths)</span>
<span
class="gmail-pre">if</span>
<span
class="gmail-pre">initial_paths</span>
<span
class="gmail-pre">else</span>
<span
class="gmail-pre">result</span>
<span
class="gmail-pre">==</span>
<span
class="gmail-pre">[]</span></code></li>
<li><code
class="gmail-code
gmail-docutils
gmail-literal
gmail-notranslate"><span class="gmail-pre">all(pth.is_absolute()</span>
<span
class="gmail-pre">for</span>
<span
class="gmail-pre">pth</span>
<span
class="gmail-pre">in</span>
<span
class="gmail-pre">result)</span></code></li>
<li><code
class="gmail-code
gmail-docutils
gmail-literal
gmail-notranslate"><span class="gmail-pre">all(pth.is_file()</span> <span
class="gmail-pre">for</span> <span class="gmail-pre">pth</span> <span
class="gmail-pre">in</span> <span class="gmail-pre">result)</span></code></li>
</ul>
</td>
</tr>
</tbody>
</table>
</dd>
</dl>
<br>
</div>
<div>How is this
difficult to
read,[...]?<br>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</blockquote>
<br>
This contract does not help me: <br>
<blockquote>Does it work on Windows? <br>
What is_absolute()? is <a class="moz-txt-link-rfc2396E" href="file:///">"file:///"</a> absolute?<br>
How does this code fail? <br>
What does a permission access problem look like? <br>
Can initial_paths can be None? <br>
Can initial_paths be files? directories? <br>
What are the side effects?<br>
<br>
</blockquote>
resolve_initial_path() is a piece code is better understood by
looking at the callers (#7), or not exposing it publicly (#11). You
can also use a different set of abstractions, to make the code
easier to read: <br>
<br>
UNION(file for p in initial_paths for file in p.leaves() if
file.extension=="py") <br>
<br>
At a high level, I can see the allure of DbC: Programming can be a
craft, and a person can derive deep personal satisfaction from
perfecting the code they work on. DbC provides you with more
decoration, more elaboration, more ornamentation, more control.
This is not bad, but I see all your arguments as personal ascetic
sense. DbC is only appealing under certain accounting rules.
Please consider the possibility that "the best code" is: low $$$,
buggy, full of tangles, and mostly gets the job done. :)<br>
</body>
</html>