OnceAndOnlyOnce seems to sometimes conflict with black-box independence. Factoring out repetition sometimes results in the need to create global or module-level variables. Examples:
Independent version:
function stuff() {
declare glab, zob;
...
foo(glab, zob, 10, "nog");
foo(glab, zob, 2, "17");
foo(glab, zob, 47, "gloop");
foo(glab, zob, 8, "toog");
foo(glab, zob, 242, "n");
foo(glab, zob, 532, "bork");
...
},
function foo(glab, zob, nork, bling) {
...
x = something(glab, nork);
y = somethingAlso(zob, bling);
...
},
Dependent version:
declare glab, zob; // module-level vars
function stuff() {
foo(10, "nog");
foo(2, "17");
foo(47, "gloop");
foo(8, "toog");
foo(242, "n");
foo(532, "bork");
...
},
function foo(nork, bling) {
...
x = something(glab, nork); // note use of "glab"
y = somethingAlso(zob, bling); // note use of "zob"
...
},
Another variation would be Pascal-like nested routines that can nest scope, but it is fairly close to the second example as far as consequences.
Another possibility is to put the parameters into a structure(s), but that is often over-engineering and many languages don't make such very easy.
I tend to lean toward the second style if there are more than 6 or so calls, especially if the "foo" routine is something specific to the given module rather than intended to be a generic library function. Some suggest that every function should be designed to be generic or reusable. But I lean toward YagNi on that: wait until it is clear that something is going to be reused. Only about one in ten end up reusable anyhow, even with re-work.