diff --git a/content/books/things-i-learnt/_index.md b/content/books/things-i-learnt/_index.md index 63333e7..69ec7a2 100644 --- a/content/books/things-i-learnt/_index.md +++ b/content/books/things-i-learnt/_index.md @@ -14,6 +14,7 @@ template = "section-contentless.html" * [Gherkin Is Your Friend to Understand Expectations](gherkin) * [Design Patters Are Used to Name Solution, Not Find Them](patterns-not-solutions) * [Thinking Data Flow Beats Patterns](data-flow) + * [The Magic Number Seven, Plus Or Minus Two](magical-number-seven) * Testing Software * [Unit Tests Are Good, Integration Tests Are Gooder](integration-tests) * [Testing Every Function Creates Dead Code](tests-dead-code) diff --git a/content/books/things-i-learnt/data-flow/index.md b/content/books/things-i-learnt/data-flow/index.md index 9126dcf..6032428 100644 --- a/content/books/things-i-learnt/data-flow/index.md +++ b/content/books/things-i-learnt/data-flow/index.md @@ -32,4 +32,4 @@ In a way, this way of thinking gets things more clear 'cause you have a list of steps of transformations you need to do, so you can write them one after another, which prevents a lot of bad code in the future. -{{ chapters(prev_chapter_link="/books/things-i-learnt/patterns-not-solutions", prev_chapter_title="Design Patters Are Used to Name Solution, Not Find Them", next_chapter_link="/books/things-i-learnt/integration-tests", next_chapter_title="Unit Tests Are Good, Integration Tests Are Gooder") }} +{{ chapters(prev_chapter_link="/books/things-i-learnt/patterns-not-solutions", prev_chapter_title="Design Patters Are Used to Name Solution, Not Find Them", next_chapter_link="/books/things-i-learnt/magical-number-seven", next_chapter_title="The Magic Number Seven, Plus Or Minus Two") }} diff --git a/content/books/things-i-learnt/integration-tests/index.md b/content/books/things-i-learnt/integration-tests/index.md index 68b6b8f..c5c9aa3 100644 --- a/content/books/things-i-learnt/integration-tests/index.md +++ b/content/books/things-i-learnt/integration-tests/index.md @@ -66,4 +66,4 @@ parts. [^1]: There is no "unit" in "unit tests". "Unit test" means the test _is_ a unit, indivisible and dependent only on itself. -{{ chapters(prev_chapter_link="/books/things-i-learnt/data-flow", prev_chapter_title="Thinking Data Flow Beats Patterns", next_chapter_title="Testing Every Function Creates Dead Code", next_chapter_link="/books/things-i-learnt/tests-dead-code") }} +{{ chapters(prev_chapter_link="/books/things-i-learnt/magical-number-seven", prev_chapter_title="The Magic Number Seven, Plus Or Minus Two", next_chapter_title="Testing Every Function Creates Dead Code", next_chapter_link="/books/things-i-learnt/tests-dead-code") }} diff --git a/content/books/things-i-learnt/magical-number-seven/index.md b/content/books/things-i-learnt/magical-number-seven/index.md new file mode 100644 index 0000000..021cf09 --- /dev/null +++ b/content/books/things-i-learnt/magical-number-seven/index.md @@ -0,0 +1,86 @@ ++++ +title = "Things I Learnt The Hard Way - The Magical Number Seven, Plus Or Minus Two" +date = 2019-06-26 + +[taxonomies] +tags = ["en-au", "books", "things i learnt", "complexity"] ++++ + +"[The magical number](https://en.wikipedia.org/wiki/The_Magical_Number_Seven,_Plus_or_Minus_Two)" +is a psychology article about the number of things one can keep in their mind +at the same time. + + + +I've seen twice this weird construction on where a function would do some +processing, but its return value was the return of a second function and +some bit of processing. Nothing major. But the second function would also do +some processing and call a third function. And the third function would call a +fourth. And the fourth a fifth. And the fifth, a sixth function. + +Something like this + +``` +func_1 + +-- func_2 + +-- func_3 + +-- func_4 + +-- func_5 + +-- func6 +``` + +Now, when you're trying to understand this kind of code to find a problem, +you'll have to keep in mind what the first, second, third, fourth, fifth and +sixth functions do, 'cause they are all calling each other (inside them). + +This causes some serious mental overflow that shouldn't be necessary. + +Not only that, but imagine that you put a log before and after `func_1`: The +log before points the data that's being send to func_1, and the log after its +result. + +So you'd end up with the impression that `func_1` does a lot of stuff, when it +actually is passing the transformation along. + +(I got a weird experience with a function called `expand`, which logging +before the call would show some raw, compressed data, but the after was not +the expanded data, but actually a list of already processed data from the +compressed data.) + +What would be a better solution, you may ask? + +Well, if instead of making `func_1` call `func_2`, you can make it return the +result (which may not be the final result, anyway) and _then_ call `func_2` +with that result. + +Something like: + +``` +result1 = func_1 +result2 = func_2(result1) +result3 = func_3(result2) +result4 = func_4(result3) +result5 = func_5(result4) +result6 = func_6(result5) +result7 = func_7(result6) +``` + +Now you can see _exactly_ how the data is being transfomed -- and, obviously, +the functions would have better names, like `expand`, `break_lines`, +`name_fields` and so on, so you can see that that compressed data I mentioned +before is actually being decompressed, the content is being broke line by +line, the lines are getting names in its fields and so on (and one could even +claim that it would make things clear if there was a function after +`break_lines` which would just `break_fields`, which would make `name_fields` +more obvious -- and in a construction like this it would be almost trivial to +add this additional step). + +"But that isn't performant!" someone may cry. Well, maybe it's just a bit less +performant than the original chained-calls ('cause it wouldn't create and +destroy frames in the stack, it would just pile them up and then unstack them +all in the end), but heck, optimization is for compilers, not people. Your job +is to make the code _readable_ and _understandable_. If you need performance, +you can think of a better sequence of steps, not some "let's make this a mess +to read" solution. + +{{ chapters(prev_chapter_link="/books/things-i-learnt/data-flow", prev_chapter_title="The Magic Number Seven, Plus Or Minus Two", next_chapter_link="/books/things-i-learnt/integration-tests", next_chapter_title="Unit Tests Are Good, Integration Tests Are Gooder") }}