> Those who speak of “self-documenting code” are missing something big: the purpose of documentation is not just to describe how the system works today, but also how it will work in the future and across many versions. And so it’s equally important what’s not documented. Documentation also (can) tell you why the code is a certain way. The code itself can only answer "what" and "how" questions. The simplest case to sh…
> Some might claim unit tests will solve this Yes. Tests will solve this. Your point is perfect for tests. If another experienced coder cannot comprehend from the tests why something is wrong, then improve the tests. Use any mix of literate programming, semantic names, domain driven design, test doubles, custom matchers, dependency injections, and the like. If you can point to a specific example of your statement, i.…
The Design of Software is a Thing Apart
51–60 of 124 posts
Re: The Design of Software is a Thing Apart
#52Earlier quoted context omitted.
return x >= "A"; // ascii A Gets the whole message across in one line, as does using 65 with the comment.
(Ignoring the typo "A" != 'A') return x >= 'A'; already and only means ascii A. Is there a C compiler anywhere where or likely in future where 'A' in C is NOT ascii A? The comment is redundant if correct, and could be wrong after an edit, so it has no value.
See, here's where you are wrong.
ASCII_A = "A"
alphas = ["Α", "А", "Ꭺ", "ᗅ", "ꓮ", "A", "𐊠", "A", "𝐀", "𝖠", "𝙰", "𝚨", "𝝖"]
for c in alphas:
print c == ASCII_A
Output? False
False
False
False
False
False
False
True
False
False
False
False
False
Several of the numerous possible utf-8 alphas. Those are not A in different fonts -- they are different unicode characters that look like A. And depending on your font they could look absolutely the same as plain ascii a (of which only one towards the middle of the list is). And depending on your locale and keyboard language settings, one of them could be as easy to click as the regular english A in ASCII.Re: The Design of Software is a Thing Apart
#53Earlier quoted context omitted.
How do you know that it's the "E" that is wrong, and not the ASCII_A? Maybe it should be ASCII_E. (If you say it's because it's written twice, well, that's only a valid clue if ASCII_E doesn't happen to be defined too.)
> How do you know that it's the "E" that is wrong, and not the ASCII_A? Maybe it should be ASCII_E. Ultimately you don't, but ASCII_A requires double the intentional actions to name it and have it also be 'A', whereas 'A' vs 'E' or whatever else is a much easier typo. It's the whole idea behind NOT having magic values in your code. That is, that: if (temp > 212) tells us much less than: if (temp > WATER_BOILING_TEMP)…
Or 275°C at around 60 bar.
Re: The Design of Software is a Thing Apart
#54Earlier quoted context omitted.
> Some might claim unit tests will solve this Yes. Tests will solve this. Your point is perfect for tests. If another experienced coder cannot comprehend from the tests why something is wrong, then improve the tests. Use any mix of literate programming, semantic names, domain driven design, test doubles, custom matchers, dependency injections, and the like. If you can point to a specific example of your statement, i.…
Here I'd distinguish between system/integration and unit tests. Unit tests as a whole tend to amount to a mirror of the code base. If a given function f returns '17' and a test validates that fact, all we've done is double check our work -- which has some value, but doesn't protect against the case in which f is _supposed_ to return 18 and both the code and the test are wrong. OTOH, system tests provide a realm where…
So for a lexer, you'd create a dummy program with the output of each token on a newline, and then test that the tokenizer's output matches what you expect from the input. But you shouldn't test whether the functions themselves are correct. The tests cases should be designed to throw up any bugs in any of the internal functions, and the system should catch it as defined.
Otherwise you end up documenting what the system currently is, rather than that the goal of the system is met.
Re: The Design of Software is a Thing Apart
#55> Those who speak of “self-documenting code” are missing something big: the purpose of documentation is not just to describe how the system works today, but also how it will work in the future and across many versions. And so it’s equally important what’s not documented. Documentation also (can) tell you why the code is a certain way. The code itself can only answer "what" and "how" questions. The simplest case to sh…
> Some might claim unit tests will solve this Yes. Tests will solve this. Your point is perfect for tests. If another experienced coder cannot comprehend from the tests why something is wrong, then improve the tests. Use any mix of literate programming, semantic names, domain driven design, test doubles, custom matchers, dependency injections, and the like. If you can point to a specific example of your statement, i.…
Sometimes you just have to pick the right tool for the job, and sometimes that tool is prose. I think if you get too stuck on using one tool (e.g. unit tests), you sometimes get to the point where you start thinking that anything that can't be done with that tool isn't worth doing, which is also wrong.
Re: The Design of Software is a Thing Apart
#56> Those who speak of “self-documenting code” are missing something big: the purpose of documentation is not just to describe how the system works today, but also how it will work in the future and across many versions. And so it’s equally important what’s not documented. Documentation also (can) tell you why the code is a certain way. The code itself can only answer "what" and "how" questions. The simplest case to sh…
> Some might claim unit tests will solve this Yes. Tests will solve this. Your point is perfect for tests. If another experienced coder cannot comprehend from the tests why something is wrong, then improve the tests. Use any mix of literate programming, semantic names, domain driven design, test doubles, custom matchers, dependency injections, and the like. If you can point to a specific example of your statement, i.…
float FastInvSqrt(float x) {
float xhalf = 0.5f * x;
int i = *(int*)&x; // evil floating point bit level hacking
i = 0x5f3759df - (i >> 1); // what the fuck?
x = *(float*)&i;
x = x*(1.5f-(xhalf*x*x));
return x;
}
I can't think of a way to write a test that sufficiently explains "gets within a certain error margin of the correct answer yet is much much faster than the naive way."The only way to test an expected input/output pair is to run the input through that function. If you test that, you're just testing that the function never changes. What if the magic number changed several times during development, do you recalculate all the tests?
You could create the tests to be within a certain tolerance of the number. Well how do you stop a programmer from replacing it with
return 1.0/sqrt(x);
And then complaining when the game now runs at less than 1 frame per second?Here's a commented version of the same function from betterexplained.com.
float InvSqrt(float x){
float xhalf = 0.5f * x;
int i = *(int*)&x; // store floating-point bits in integer
i = 0x5f3759df - (i >> 1); // initial guess for Newton's method
x = *(float*)&i; // convert new bits into float
x = x*(1.5f - xhalf*x*x); // One round of Newton's method
return x;
}
It's still very magic looking to me, but now I get vaguely that it's based on Newton's method and what each line is doing if I needed to modify them.I actually just found this article [0] where someone is trying to find the original author of that function, and no one on the Quake 3 team can remember who wrote it, or why it was slightly different than other versions of the FastInvSqrt they had written.
> which actually is doing a floating point computation in integer - it took a long time to figure out how and why this works, and I can't remember the details anymore
This made me chuckle. The person eventually tracked down as closest to having written the original thing had to rederive how the function works the first time, and can't remember exactly how it works now.
I think the answer is both tests and documentation. Sometimes you do need both. Sometimes you don't, but the person after you will.
Re: The Design of Software is a Thing Apart
#57"So you update the code, a test fails, and you think “'Oh. One of the details changed.'"
Some of the concerns they raise about writing tests are covered by Uncle Bob here: http://blog.cleancoder.com/uncle-bob/2017/10/03/TestContrava... and here: http://blog.cleancoder.com/uncle-bob/2016/03/19/GivingUpOnTD...
Re: The Design of Software is a Thing Apart
#58return x >= ‘A’; Would be better than return x >= ASCII_A; surely. ASCII_A could be set incorrectly, or have a dumb type, and is more verbose anyway. By using the character directly, the code speaks its purpose.
> ASCII_A (usually spelled just 'A')
Of course, they are not the same thing. In the last 6 months I've worked on a very old system that uses not-quite-ASCII. 'A' was 65 but '#' wasn't 35.
Re: The Design of Software is a Thing Apart
#59Peter Naur's "Programming as Theory Building" also addresses this topic of a "theory" which is built in tandem with a piece of software, in the minds of the programmers building it, without actually being a part of the software itself. Definitely worth a read: http://pages.cs.wisc.edu/~remzi/Naur.pdf
Sometimes it gets worse still: you can have different theories according to (a) scientists doing basic research into physics or human perception/cognition, (b) computer science researchers inventing publishable papers/demos, (c) product managers or others making executive product decisions about what to implement, (d) low-level programmers doing the implementation, (e) user interface designers, (f) instructors and documentation authors, (h) marketers, (h) users of the software, and finally (i) the code itself.
Unless a critical proportion of the people in various stages of the process have a reasonable cross-disciplinary understanding and effective communication skills, models tend to diverge and software and its use go to shit.
Re: The Design of Software is a Thing Apart
#60> Those who speak of “self-documenting code” are missing something big: the purpose of documentation is not just to describe how the system works today, but also how it will work in the future and across many versions. And so it’s equally important what’s not documented. Documentation also (can) tell you why the code is a certain way. The code itself can only answer "what" and "how" questions. The simplest case to sh…
> Some might claim unit tests will solve this Yes. Tests will solve this. Your point is perfect for tests. If another experienced coder cannot comprehend from the tests why something is wrong, then improve the tests. Use any mix of literate programming, semantic names, domain driven design, test doubles, custom matchers, dependency injections, and the like. If you can point to a specific example of your statement, i.…