User:Average/TightCoupling

From HackerspaceWiki
Jump to: navigation, search

Tight coupling: Data, Code, Docs. These get out of sync and the divergence worsens to incomprehensibility or broken code. Enterprise programmers will know what I mean.


Keep your mallocs near your memory usage and be sure to deallocate all your memory, where your done using it. You do it just like using a stack: first memory allocated is the last memory de-allocated. That lets others know that you're being responsible. Leave comments at that point explaining the amount of memory allocated and when you can deallocate it. STUB This page need rewritten ... Hence, contract-driven programming, where they keep the contracts for input and output close to the code. This is a refinement on C declarations, because it tells you the range of correct values.


This can be a fun part of the ally. You get to start with coding how the program should behave and then code it until it passes the tests, ensuring that it is correct.

#!/usr/bin/python
def Factorial(n): """Computes the nth Factorial number. Takes non-negative integer, returns integer. >>> Factorial(0) #math's documented base case, a bit specious but we conform. 1 >>> Factorial(20) #returns arbitrarily-sized ints. 2432902008176640000 """ if n==0: return 1 else: return n * Factorial(n-1)

See how the language has provided a means to keep documentation right at the code? That's called a DocString. Since it's defined in the language itself, other third-party apps could auto-convert this to printed documentation, to document all your functions.

And see how the DocString examples show testable run-time behavior, including possibly confusing edge cases which could easily get missed if the code were to change? Tools like DocTests (included with Python) make this effortless. Even better tight coupling is to allow context-aware DocTests: At module level, a DocString could define variables for each Class that the module is designed for and must have, and then the DocTests within the Class could use those as pre-defined variables. In other words, SetUp code right where it should be, illuminating the module/class`s purpose.

Lastly, the example shown gives a result with high-information density: it's probability of showing up randomly from an incorrect calculation is extremely low. Result: Sweet! Rewrite your code as much as you want, worry-free. Tightly-coupled: documentation <==> code <==> tests. Elegant.

A perfect DocTest case covers:

  • edge-case documentation,
  • common use-cases for correct use,
  • limited to testing designed-for behaviors, and
  • possibly what exceptions are thrown (only documented fail-cases).

These tests can and should be combined if you use a little effort (Compactness). The fail-case scenario requires some mastery of another crucible (w/SeparabilityOfDomains) as you don't put error-handling code where it isn't relevant and tightly-coupled to your function. For example, if you pass a "string" value to the factorial function above you will get an error just as you want (type error), but that error is coupled to your multiplication function -- not yours. And that, friend, is handled and documented by your interpreter.

But what about contracts? The Vigil programming enhancement to Python gave some good ideas. Two new keywords implore and swear offering guarantees on input and output, respectively. When code doesn't conform to the contracts, offending code can be put in a global "purgatory" where someone on the net can nurse it back into compliance and be re-released to the wild (i.e. users).

Left to it`s own, TightCoupling in the service of only correctness would lead to code bloat, so remember it`s companion.