From cad33c58bde04f216f177580bdbbcc3cd4682af1 Mon Sep 17 00:00:00 2001 From: Julio Biason Date: Tue, 25 Jun 2019 14:14:39 -0300 Subject: [PATCH 01/12] New Chapter: right tool for the job --- content/books/things-i-learnt/_index.md | 1 + .../books/things-i-learnt/cargo-cult/index.md | 2 +- .../right-tool-agenda/index.md | 24 +++++++++++++++++++ 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 content/books/things-i-learnt/right-tool-agenda/index.md diff --git a/content/books/things-i-learnt/_index.md b/content/books/things-i-learnt/_index.md index ea8d8eb..05c71ef 100644 --- a/content/books/things-i-learnt/_index.md +++ b/content/books/things-i-learnt/_index.md @@ -35,3 +35,4 @@ template = "section-contentless.html" * Community/Teams * [A Language Is Much More Than A Language](languages-are-more) * [Understand And Stay Away From Cargo Cult](cargo-cult) + * ["Right Tool For The Job" Is Just To Push An Agenda](right-tool-agenda) diff --git a/content/books/things-i-learnt/cargo-cult/index.md b/content/books/things-i-learnt/cargo-cult/index.md index d03ee7d..38b0056 100644 --- a/content/books/things-i-learnt/cargo-cult/index.md +++ b/content/books/things-i-learnt/cargo-cult/index.md @@ -38,4 +38,4 @@ ProductX good, or even if it fits your solution. And there is much more [behind a product](/books/things-i-learnt/languages-are-more) than just its development. -{{ chapters(prev_chapter_link="/books/things-i-learnt/languages-are-more", prev_chapter_title="A Language Is Much More Than A Language") }} +{{ chapters(prev_chapter_link="/books/things-i-learnt/languages-are-more", prev_chapter_title="A Language Is Much More Than A Language", next_chapter_link="/books/things-i-learnt/right-tool-agenda", next_chapter_title="Right Tool For The Job Is Just To Push An Agenda") }} diff --git a/content/books/things-i-learnt/right-tool-agenda/index.md b/content/books/things-i-learnt/right-tool-agenda/index.md new file mode 100644 index 0000000..430a941 --- /dev/null +++ b/content/books/things-i-learnt/right-tool-agenda/index.md @@ -0,0 +1,24 @@ ++++ +title = "Things I Learnt The Hard Way - \"Right Tool For The Job\" Is Just To Push An Agenda " +date = 2019-06-25 + +[taxonomies] +tags = ["en-au", "books", "things i learnt", "right tool", "agenda"] ++++ + +A lot of times I heard "We should use the right tool for the job!" Most of +those times it was just a way to push an agenda. + + + +When someone claims we should use the "right tool", the sentence mean there is +a right tool and a wrong tool to do something -- e.g., using a certain +language/framework instead of the current language/framework. + +But sadly, none of those times it was really the "right tool". Most of the +time, the person saying we should use the "right tool" was trying to push +their own favourite language/framework, either because they disliked the +current language/framework or because they don't want to push the "hero +project". + +{{ chapters(prev_chapter_link="/books/things-i-learnt/cargo-cult", prev_chapter_title="Understand And Stay Away From Cargo Cult") }} From a06643b08a95949a6ce4f999cf4e7085c715cf14 Mon Sep 17 00:00:00 2001 From: Julio Biason Date: Tue, 25 Jun 2019 14:27:27 -0300 Subject: [PATCH 02/12] New Chapter: Right tool is obvious --- content/books/things-i-learnt/_index.md | 1 + .../right-tool-agenda/index.md | 2 +- .../right-tool-obvious/index.md | 29 +++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 content/books/things-i-learnt/right-tool-obvious/index.md diff --git a/content/books/things-i-learnt/_index.md b/content/books/things-i-learnt/_index.md index 05c71ef..75fc820 100644 --- a/content/books/things-i-learnt/_index.md +++ b/content/books/things-i-learnt/_index.md @@ -36,3 +36,4 @@ template = "section-contentless.html" * [A Language Is Much More Than A Language](languages-are-more) * [Understand And Stay Away From Cargo Cult](cargo-cult) * ["Right Tool For The Job" Is Just To Push An Agenda](right-tool-agenda) + * [The Right Tool Is More Obvious Than You Think](right-tool-obvious) diff --git a/content/books/things-i-learnt/right-tool-agenda/index.md b/content/books/things-i-learnt/right-tool-agenda/index.md index 430a941..d69c9ea 100644 --- a/content/books/things-i-learnt/right-tool-agenda/index.md +++ b/content/books/things-i-learnt/right-tool-agenda/index.md @@ -21,4 +21,4 @@ their own favourite language/framework, either because they disliked the current language/framework or because they don't want to push the "hero project". -{{ chapters(prev_chapter_link="/books/things-i-learnt/cargo-cult", prev_chapter_title="Understand And Stay Away From Cargo Cult") }} +{{ chapters(prev_chapter_link="/books/things-i-learnt/cargo-cult", prev_chapter_title="Understand And Stay Away From Cargo Cult", next_chapter_link="/books/things-i-learnt/right-tool-obvious", next_chapter_title="The Right Tool Is More Obvious Than You Think") }} diff --git a/content/books/things-i-learnt/right-tool-obvious/index.md b/content/books/things-i-learnt/right-tool-obvious/index.md new file mode 100644 index 0000000..f72d22d --- /dev/null +++ b/content/books/things-i-learnt/right-tool-obvious/index.md @@ -0,0 +1,29 @@ ++++ +title = "Things I Learnt The Hard Way - The Right Tool Is More Obvious Than You Think" +date = 2019-06-25 + +[taxonomies] +tags = ["en-au", "books", "things i learnt", "right tool"] ++++ + +Maybe you're in a project that needs to process some text. Maybe you're +tempted to say "Let's use Perl" 'cause you know that Perl is very strong in +processing text. + +But that may still be not the right tool. + + + +Although Perl is an amazing tool to process files, providing every single +switch and option you'll ever need, you're missing something: You're working +on a C shop. Everybody knows C, not Perl. + +Sure, if it is a small, "on the corner" kind of project, it's fine to be in +Perl; if it is important for the company, it's better that if it is a C +project. + +One of the reason your hero project may fail is because of this: You may even +prove that what you thought it was a better solution is actually a better +solution, but it can't be applied 'cause nobody else can maintain it. + +{{ chapters(prev_chapter_link="/books/things-i-learnt/right-tool-agenda", prev_chapter_title="Right Tool For The Job Is Just To Push An Agenda") }} From 6069876b08a2e0c160e4f7279676b12e9b267431 Mon Sep 17 00:00:00 2001 From: Julio Biason Date: Tue, 25 Jun 2019 18:16:09 -0300 Subject: [PATCH 03/12] New chapter: dont mess with things outside the project --- content/books/things-i-learnt/_index.md | 1 + .../languages-are-more/index.md | 2 +- .../things-i-learnt/outside-project/index.md | 35 +++++++++++++++++++ .../things-i-learnt/use-structures/index.md | 16 ++++++++- 4 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 content/books/things-i-learnt/outside-project/index.md diff --git a/content/books/things-i-learnt/_index.md b/content/books/things-i-learnt/_index.md index 75fc820..155d0b2 100644 --- a/content/books/things-i-learnt/_index.md +++ b/content/books/things-i-learnt/_index.md @@ -32,6 +32,7 @@ template = "section-contentless.html" * [If You Know How To Handle It, Handle It](handle-it) * [Types Say What Your Data Is](data-types) * [If Your Data Has a Schema, Use a Structure](use-structures) + * [Don't Mess With Things Outside Your Project](outside-project) * Community/Teams * [A Language Is Much More Than A Language](languages-are-more) * [Understand And Stay Away From Cargo Cult](cargo-cult) diff --git a/content/books/things-i-learnt/languages-are-more/index.md b/content/books/things-i-learnt/languages-are-more/index.md index 6133ade..0e3c90a 100644 --- a/content/books/things-i-learnt/languages-are-more/index.md +++ b/content/books/things-i-learnt/languages-are-more/index.md @@ -39,4 +39,4 @@ surface of what the whole of a language encapsulates and if you ignore the other elements in it, you may find yourself with a cute language in a community that is always fighting and never going forward. -{{ chapters(prev_chapter_link="/books/things-i-learnt/use-structures", prev_chapter_title="If Your Data Has a Schema, Use a Structure", next_chapter_link="/books/things-i-learnt/cargo-cult", next_chapter_title="Understand And Stay Away From Cargo Cult") }} +{{ chapters(prev_chapter_link="/books/things-i-learnt/use-structures", prev_chapter_title="If Your Data Has a Schema, Use a Structure", next_chapter_link="/books/things-i-learnt/outside-project", next_chapter_title="Don't Mess With Things Outside Your Project") }} diff --git a/content/books/things-i-learnt/outside-project/index.md b/content/books/things-i-learnt/outside-project/index.md new file mode 100644 index 0000000..7adfddb --- /dev/null +++ b/content/books/things-i-learnt/outside-project/index.md @@ -0,0 +1,35 @@ ++++ +title = "Things I Learnt The Hard Way - Don't Mess With Things Outside Your Project" +date = 2019-06-25 + +[taxonomies] +tags = ["en-au", "books", "things i learnt", "frameworks"] ++++ + +Simple rule: Is the code yours or from your team? Good, go break it. Does it +come from outside? DON'T. TOUCH. IT. + + + +Sometimes people are tempted to, instead of using the proper extension tools, +change external libraries/frameworks -- for example, making changes directly +into WordPress or Django. Believe me, I've seen my fair share of this kind of +stuff going around. + +This is an easy way to make the project -- the team project, that is -- +a huge security problem. As soon as a new version is released, you'll -- or, +better yet, someone who was not the person who decided to mess with outside +code -- have to keep up your changes in sync with the main project and, pretty +soon, you'll find that the changes don't apply anymore and you'll leave the +external project in an old version, full of security bugs. + +Not only you'd end up with something that may very soon put at risk your whole +infrastructure, you won't take any benefits from things in the new versions, +'cause hey, you're stuck in the broken version! + +Sometimes doing it so is faster and cheaper, and if you would do the same +thing using extensions or actually coding around the problem, even duplicating +the framework functions, would probably take longer and make you write more +code, but in the long run, it's worth the time. + +{{ chapters(prev_chapter_link="/books/things-i-learnt/use-structures", prev_chapter_title="If Your Data Has a Schema, Use a Structure", next_chapter_link="/books/things-i-learnt/languages-are-more", next_chapter_title="A Language Is Much More Than A Language") }} diff --git a/content/books/things-i-learnt/use-structures/index.md b/content/books/things-i-learnt/use-structures/index.md index 5883d21..c0ed963 100644 --- a/content/books/things-i-learnt/use-structures/index.md +++ b/content/books/things-i-learnt/use-structures/index.md @@ -55,4 +55,18 @@ every time. So: You data has a schema? Use a Data Class or Class or Struct. Only if it is schemaless, then you can use a tuple. -{{ chapters(prev_chapter_link="/books/things-i-learnt/data-types", prev_chapter_title="Types Say What Your Data Is", next_chapter_link="/books/things-i-learnt/languages-are-more", next_chapter_title="A Language Is Much More Than A Language") }} +I've seen this used at least once. Sure, at the very start of the project, it +may seem easier to just store the data as a tuple and destructure it and build +it again when needed. There was even a whole module designed to receiving +tuples, destructure them and rebuild new ones (for example, a function that +would receive two tuples and compute the sum of the "value" field of each, +building a new tuple as a result). But because of this design, to add just a +new field, I had to change 14 files and do 168 changes around -- 'cause, sure, +there was a function to add two tuples, but there were points where you need +just one field, and there wasn't a function for it. + +It would be easier to use if there were functions to extract each field, and +add two tuples, and what else was needed for managing the tuples, but then you +have to ask yourself: Why not use a class for that? + +{{ chapters(prev_chapter_link="/books/things-i-learnt/data-types", prev_chapter_title="Types Say What Your Data Is", next_chapter_link="/books/things-i-learnt/outside-project", next_chapter_title="Don't Mess With Things Outside Your Project") }} From cbb95a8c641be3959a1d32a0140e0a3b81383cc9 Mon Sep 17 00:00:00 2001 From: Julio Biason Date: Tue, 25 Jun 2019 18:28:01 -0300 Subject: [PATCH 04/12] New chapter: design patterns --- content/books/things-i-learnt/_index.md | 1 + .../books/things-i-learnt/gherkin/index.md | 2 +- .../integration-tests/index.md | 2 +- .../patterns-not-solution/index.md | 38 +++++++++++++++++++ 4 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 content/books/things-i-learnt/patterns-not-solution/index.md diff --git a/content/books/things-i-learnt/_index.md b/content/books/things-i-learnt/_index.md index 155d0b2..e320525 100644 --- a/content/books/things-i-learnt/_index.md +++ b/content/books/things-i-learnt/_index.md @@ -12,6 +12,7 @@ template = "section-contentless.html" * [Spec First, Then Code](spec-first) * [Write Steps as Comments](steps-as-comments) * [Gherkin Is Your Friend to Understand Expectations](gherkin) + * [Design Patters Are Used to Name Solution, Not Find Them](patterns-not-solutions) * 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/gherkin/index.md b/content/books/things-i-learnt/gherkin/index.md index 4e8ae9b..c22b871 100644 --- a/content/books/things-i-learnt/gherkin/index.md +++ b/content/books/things-i-learnt/gherkin/index.md @@ -51,4 +51,4 @@ system, you can get a better picture of the whole. Also, you may not like to write specs. That's alright, you can replace them with Gherkin anyway. -{{ chapters(prev_chapter_link="/books/things-i-learnt/steps-as-comments", prev_chapter_title="Write Steps as Comments", 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/steps-as-comments", prev_chapter_title="Write Steps as Comments", next_chapter_link="/books/things-i-learnt/patterns-not-solutions", next_chapter_title="Design Patters Are Used to Name Solution, Not Find Them") }} diff --git a/content/books/things-i-learnt/integration-tests/index.md b/content/books/things-i-learnt/integration-tests/index.md index b62f80c..61e4618 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/gherkin", prev_chapter_title="Gherkin Is Your Friend to Understand Expectations", 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/patterns-not-solutions", prev_chapter_title="Design Patters Are Used to Name Solution, Not Find Them", 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/patterns-not-solution/index.md b/content/books/things-i-learnt/patterns-not-solution/index.md new file mode 100644 index 0000000..e35dd1b --- /dev/null +++ b/content/books/things-i-learnt/patterns-not-solution/index.md @@ -0,0 +1,38 @@ ++++ +title = "Things I Learnt The Hard Way - Design Patters Are Used to Name Solution, Not Find Them" +date = 2019-06-25 + +[taxonomies] +tags = ["en-au", "books", "things i learnt", "design patterns"] ++++ + +Most of the times I saw design patterns being applied, they were applied as a +way to find a solution, so you end up twisting a solution -- and, sometimes, +the problem it self -- to fit the pattern. + + + +My guess is that the heavy use of "let's apply _this_ design pattern" before +even understanding the problem -- or even trying to solve it -- comes as a +form of [cargo cult](/books/things-i-learnt/cargo-cult): I heard people used +this pattern and solved their problem, so let's use it too and it will solve +our problem. Or, worse: Design pattern is described by _Famous Person_, so we +must use it. + +Here is the thing: Design pattern should _not_ be used as a way to find +solution to any problems. You may use some of them as base for your solution, +but you must focus on the _problem_, not the _pattern_. + +"Do a visitor pattern will solve this?" is the wrong question. "What should we +do to solve our problem?" is the real question. Once you went there and solved +the problem you may look and see if it is a visitor pattern -- or whatever +pattern. If it doesn't, that's alright, 'cause you _solved the problem_. If it +did... well, congratulations, you now know how to name your solution. + +I've seen this happening a lot: People have a problem; people decided to use a +pattern; the pattern doesn't actually solve the problem (not in the 100% mark, +but above 50%); what happens then is that people start twisting the problem to +fit the pattern or, worse, add new layers to transform the problem into the +pattern. + +{{ chapters(prev_chapter_link="/books/things-i-learnt/gherkin", prev_chapter_title="Gherkin Is Your Friend to Understand Expectations", next_chapter_link="/books/things-i-learnt/integration-tests", next_chapter_title="Unit Tests Are Good, Integration Tests Are Gooder") }} From ca04d42e01a2ca4b5227b8d4e945c9cbb53a59f7 Mon Sep 17 00:00:00 2001 From: Julio Biason Date: Tue, 25 Jun 2019 18:31:12 -0300 Subject: [PATCH 05/12] Renamed --- .../{patterns-not-solution => patterns-not-solutions}/index.md | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename content/books/things-i-learnt/{patterns-not-solution => patterns-not-solutions}/index.md (100%) diff --git a/content/books/things-i-learnt/patterns-not-solution/index.md b/content/books/things-i-learnt/patterns-not-solutions/index.md similarity index 100% rename from content/books/things-i-learnt/patterns-not-solution/index.md rename to content/books/things-i-learnt/patterns-not-solutions/index.md From af02b815e96b0133c903a64a781c5c63de060262 Mon Sep 17 00:00:00 2001 From: Julio Biason Date: Wed, 26 Jun 2019 12:29:39 -0300 Subject: [PATCH 06/12] New chapter: data flows --- content/books/things-i-learnt/_index.md | 1 + .../books/things-i-learnt/data-flow/index.md | 35 +++++++++++++++++++ .../integration-tests/index.md | 2 +- .../patterns-not-solutions/index.md | 2 +- 4 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 content/books/things-i-learnt/data-flow/index.md diff --git a/content/books/things-i-learnt/_index.md b/content/books/things-i-learnt/_index.md index e320525..63333e7 100644 --- a/content/books/things-i-learnt/_index.md +++ b/content/books/things-i-learnt/_index.md @@ -13,6 +13,7 @@ template = "section-contentless.html" * [Write Steps as Comments](steps-as-comments) * [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) * 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 new file mode 100644 index 0000000..9126dcf --- /dev/null +++ b/content/books/things-i-learnt/data-flow/index.md @@ -0,0 +1,35 @@ ++++ +title = "Things I Learnt The Hard Way - Thinking Data Flow Beats Patterns" +date = 2019-06-26 + +[taxonomies] +tags = ["en-au", "books", "things i learnt", "data flow", "design patterns"] ++++ + +When you're trying to find a solution to your problem, think on the way the +data will flow through your code. + + + +Instead of focusing on design patterns, a better way is to think the way the +data will flow -- and be transformed -- on your code. + +For example, the user will input a number. You'll get this number and find the +respective record on the database. This is a transformation -- no, it's not +"I'll get the number and receive a complete different thing based upon it", +you're actually transforming the number into a record, using the database as a +transformation. + +(Yes, I know, it's not that clear at the first glance, but you have to think +that they are the same data with different representations.) + +Most of the time I did that, I managed to come with more clear design for my +applications. I didn't even think about how many functions/classes it would be +needed to do these kind of transformations, that was something I came up +_after_ I could see the data flow. + +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") }} diff --git a/content/books/things-i-learnt/integration-tests/index.md b/content/books/things-i-learnt/integration-tests/index.md index 61e4618..68b6b8f 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/patterns-not-solutions", prev_chapter_title="Design Patters Are Used to Name Solution, Not Find Them", 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/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") }} diff --git a/content/books/things-i-learnt/patterns-not-solutions/index.md b/content/books/things-i-learnt/patterns-not-solutions/index.md index e35dd1b..be7565f 100644 --- a/content/books/things-i-learnt/patterns-not-solutions/index.md +++ b/content/books/things-i-learnt/patterns-not-solutions/index.md @@ -35,4 +35,4 @@ but above 50%); what happens then is that people start twisting the problem to fit the pattern or, worse, add new layers to transform the problem into the pattern. -{{ chapters(prev_chapter_link="/books/things-i-learnt/gherkin", prev_chapter_title="Gherkin Is Your Friend to Understand Expectations", 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/gherkin", prev_chapter_title="Gherkin Is Your Friend to Understand Expectations", next_chapter_link="/books/things-i-learnt/data-flow", next_chapter_title="Thinking Data Flow Beats Patterns") }} From 24b06878f6242109f24926f63931271c036beeac Mon Sep 17 00:00:00 2001 From: Julio Biason Date: Wed, 26 Jun 2019 17:27:13 -0300 Subject: [PATCH 07/12] New chapter: magical number seven --- content/books/things-i-learnt/_index.md | 1 + .../books/things-i-learnt/data-flow/index.md | 2 +- .../integration-tests/index.md | 2 +- .../magical-number-seven/index.md | 86 +++++++++++++++++++ 4 files changed, 89 insertions(+), 2 deletions(-) create mode 100644 content/books/things-i-learnt/magical-number-seven/index.md 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") }} From 01f422e37547a49ab76265e053b21cb4536973a2 Mon Sep 17 00:00:00 2001 From: Julio Biason Date: Wed, 26 Jun 2019 19:04:43 -0300 Subject: [PATCH 08/12] New chapter: functional programming --- content/books/things-i-learnt/_index.md | 1 + .../functional-programming/index.md | 68 +++++++++++++++++++ .../integration-tests/index.md | 2 +- .../magical-number-seven/index.md | 8 ++- 4 files changed, 77 insertions(+), 2 deletions(-) create mode 100644 content/books/things-i-learnt/functional-programming/index.md diff --git a/content/books/things-i-learnt/_index.md b/content/books/things-i-learnt/_index.md index 69ec7a2..a666c93 100644 --- a/content/books/things-i-learnt/_index.md +++ b/content/books/things-i-learnt/_index.md @@ -15,6 +15,7 @@ template = "section-contentless.html" * [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) + * [Learn The Basics of Functional Programming](functional-programming) * 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/functional-programming/index.md b/content/books/things-i-learnt/functional-programming/index.md new file mode 100644 index 0000000..2e9ec08 --- /dev/null +++ b/content/books/things-i-learnt/functional-programming/index.md @@ -0,0 +1,68 @@ ++++ +title = "Things I Learnt The Hard Way - Learn The Basics of Functional Programming" +date = 2019-06-26 + +[taxonomies] +tags = ["en-au", "books", "things i learnt", "functional programming"] ++++ + +At this point, you should at least have hard about how cool functional +programming is. There are a lot of concepts here, but at least the very basic +ones you should keep in mind. + + + +A lot of talks about functional programming come with weird words like +"functors" and "monads". It doesn't hurt to know what they really mean +(disclaimer: I still don't). But some other stuff coming from functional +programming is actually easy to understand and grasp. + +For example, immutability. This means that all your data can't change once +it's created. You have a record with user information and the user changed +this password? No, do not change the password field, create a new user record +with the updated password and discard the old one. Sure, it creates a lot of +create and destroy sequences which makes absolutely no sense (why would you +allocate memory for a new user, copy everything from the old one to the new +one, update one field, and deallocate the memory from the old one? It makes no +sense!) but, in the long run, it would prevent weird results, specially when +you understand and start use threads. + +(Basically, you're avoiding a shared state -- the memory -- between parts of +your code.) + +Another useful concept is pure functions. Pure functions are functions that, +called with the same parameters, always return the same result, no matter how +many times you call them. One example of a _non_ pure function is `random()`: +each time you call `random()`, you get a different number[^1]. An example of a +pure function would be something like this in Python: + +```python +def mult(x): + return x * 4 +``` + +No matter how many times you call `mult(2)`, it will always return 8. Another +example could be our immutable password change above: You could easily write a +function that receives a user record and returns a new user record with the +password changed. You could call with the same record over and over again and +it will always return the same resulting record. + +Pure functions are useful 'cause they are, first most, easy to test. + +Second, they are easy to chain, specially in a [data +flow](/books/things-i-learnt/data-flow) design: Because they don't have an +internal state (which is the real reason they are called pure functions), you +can easily call one after the other and no matter how many times you pass +things around, they still produce the same result. And because each function, +given the same input, produce the same result, chaining them all _also_ +produces the same result given the same inputs. + +Just those two concepts can make code longer (again, you're creating a new +user record instead of simply changing one field), but the final result is a +more robust code. + +[^1]: Except in Haskell, but it does require sending the seed every time, so + you end up with random values based on the seed, so even there it is a pure + function. + +{{ chapters(prev_chapter_link="/books/things-i-learnt/magical-number-seven", 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") }} diff --git a/content/books/things-i-learnt/integration-tests/index.md b/content/books/things-i-learnt/integration-tests/index.md index c5c9aa3..fd7980b 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/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") }} +{{ chapters(prev_chapter_link="/books/things-i-learnt/functional-programming", prev_chapter_title="Learn The Basics of Functional Programming", 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 index 021cf09..21fdbb1 100644 --- a/content/books/things-i-learnt/magical-number-seven/index.md +++ b/content/books/things-i-learnt/magical-number-seven/index.md @@ -83,4 +83,10 @@ 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") }} +Just a quick note: Although the famous paper mentions that the number is +around 7, new research is actually pointing that the number is way lower than +that, at 4. So simply making `func_1` call `func_2`, which would call +`func_3`, which would call `func_4` may be enough to overload someone and make +them lose the track of what the code does. + +{{ 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/functional-programming", next_chapter_title="Learn The Basics of Functional Programming") }} From 88a27dd156fd1cf612e974ba86267aff0d194e8e Mon Sep 17 00:00:00 2001 From: Julio Biason Date: Wed, 26 Jun 2019 19:53:26 -0300 Subject: [PATCH 09/12] New chapter: cognitive load --- content/books/things-i-learnt/_index.md | 1 + .../things-i-learnt/cognitive-cost/index.md | 57 +++++++++++++++++++ .../functional-programming/index.md | 2 +- .../magical-number-seven/index.md | 2 +- 4 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 content/books/things-i-learnt/cognitive-cost/index.md diff --git a/content/books/things-i-learnt/_index.md b/content/books/things-i-learnt/_index.md index a666c93..d60cbe6 100644 --- a/content/books/things-i-learnt/_index.md +++ b/content/books/things-i-learnt/_index.md @@ -15,6 +15,7 @@ template = "section-contentless.html" * [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) + * [Cognitive Cost Is The Readability Killer](cognitive-cost) * [Learn The Basics of Functional Programming](functional-programming) * Testing Software * [Unit Tests Are Good, Integration Tests Are Gooder](integration-tests) diff --git a/content/books/things-i-learnt/cognitive-cost/index.md b/content/books/things-i-learnt/cognitive-cost/index.md new file mode 100644 index 0000000..893cd4c --- /dev/null +++ b/content/books/things-i-learnt/cognitive-cost/index.md @@ -0,0 +1,57 @@ ++++ +title = "Things I Learnt The Hard Way - Cognitive Cost Is The Readability Killer" +date = 2019-06-26 + +[taxonomies] +tags = ["en-au", "books", "things i learnt", "cognitive dissonance", "cognitive cost"] ++++ + +"[Cognitive dissonance](https://en.wikipedia.org/wiki/Cognitive_dissonance)" +is a fancy way of saying "I need to remember two (or more) different and +contradicting things at the same time to understand this." Keeping those +different things in your head creates a cost and it keeps accumulating the +more indirect the things are ('cause you'll have to keep all those in your +head). + + + +(Disclaimer: I like to use the expression "cognitive dissonance" to make me +sound smarter. I usually explain what it means, though.) + +To give you an example of a (very mild) cognitive cost, I'll show you this: + +* You have a function called `sum()`. It does the sum of the numbers of a + list. +* You have another function, called `is_pred()`. It gets a value and, if it + fits the predicate -- a test, basically -- returns True; otherwise, + returns False. + +So, pretty simple, right? One function sums numbers and another returns a +boolean. + +Now, what would you say if I shown you this, in Python: + +```python +sum(is_pred(x) for x in my_list) +``` + +Wait, didn't I say that `sum()` sums numbers? And that `is_pred()` returns a +boolean? How can I sum booleans? What's the expected result of True + True + +False? + +Sadly, this works. Because someone, long time ago, didn't think booleans were +worth a thing and used an integer instead. And everyone else since then did +the same stupid mistake. + +But, for you, you'll now read a line that says "summing a boolean list returns +a number". And that's two different, disparate things that you suddenly have +to keep in mind when reading that line. + +That's why [types are important](/books/things-i-learnt/data-types) are +important. Also, this may sound a bit like [the magical number +seven](/books/things-i-learnt/magical-number-seven), 'cause you have to keep +two things at your mind at the same thing but, although that's not near seven, +they are not the same, with opposite (for weird meanings of "opposite", in this +case) meanings. + +{{ chapters(prev_chapter_link="/books/things-i-learnt/magical-number-seven", prev_chapter_title="The Magic Number Seven, Plus Or Minus Two", next_chapter_link="/books/things-i-learnt/functional-programming", next_chapter_title="Learn The Basics of Functional Programming") }} diff --git a/content/books/things-i-learnt/functional-programming/index.md b/content/books/things-i-learnt/functional-programming/index.md index 2e9ec08..928e557 100644 --- a/content/books/things-i-learnt/functional-programming/index.md +++ b/content/books/things-i-learnt/functional-programming/index.md @@ -65,4 +65,4 @@ more robust code. you end up with random values based on the seed, so even there it is a pure function. -{{ chapters(prev_chapter_link="/books/things-i-learnt/magical-number-seven", 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") }} +{{ chapters(prev_chapter_link="/books/things-i-learnt/cognitive-cost", prev_chapter_title="Cognitive Cost Is The Readability Killer", next_chapter_link="/books/things-i-learnt/integration-tests", next_chapter_title="Unit Tests Are Good, Integration Tests Are Gooder") }} diff --git a/content/books/things-i-learnt/magical-number-seven/index.md b/content/books/things-i-learnt/magical-number-seven/index.md index 21fdbb1..c422789 100644 --- a/content/books/things-i-learnt/magical-number-seven/index.md +++ b/content/books/things-i-learnt/magical-number-seven/index.md @@ -89,4 +89,4 @@ that, at 4. So simply making `func_1` call `func_2`, which would call `func_3`, which would call `func_4` may be enough to overload someone and make them lose the track of what the code does. -{{ 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/functional-programming", next_chapter_title="Learn The Basics of Functional Programming") }} +{{ 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/cognitive-cost", next_chapter_title="Cognitive Cost Is The Readability Killer") }} From 1f9f55da905a3261e9b4fa9427e0ccf797212a1b Mon Sep 17 00:00:00 2001 From: Julio Biason Date: Mon, 1 Jul 2019 12:46:35 -0300 Subject: [PATCH 10/12] New chapter: Resist Easy --- content/books/things-i-learnt/_index.md | 1 + .../languages-are-more/index.md | 2 +- .../things-i-learnt/outside-project/index.md | 2 +- .../things-i-learnt/resist-easy/index.md | 31 +++++++++++++++++++ 4 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 content/books/things-i-learnt/resist-easy/index.md diff --git a/content/books/things-i-learnt/_index.md b/content/books/things-i-learnt/_index.md index d60cbe6..682e859 100644 --- a/content/books/things-i-learnt/_index.md +++ b/content/books/things-i-learnt/_index.md @@ -38,6 +38,7 @@ template = "section-contentless.html" * [Types Say What Your Data Is](data-types) * [If Your Data Has a Schema, Use a Structure](use-structures) * [Don't Mess With Things Outside Your Project](outside-project) + * [Resist The Temptation Of Easy](resist-easy) * Community/Teams * [A Language Is Much More Than A Language](languages-are-more) * [Understand And Stay Away From Cargo Cult](cargo-cult) diff --git a/content/books/things-i-learnt/languages-are-more/index.md b/content/books/things-i-learnt/languages-are-more/index.md index 0e3c90a..0943de6 100644 --- a/content/books/things-i-learnt/languages-are-more/index.md +++ b/content/books/things-i-learnt/languages-are-more/index.md @@ -39,4 +39,4 @@ surface of what the whole of a language encapsulates and if you ignore the other elements in it, you may find yourself with a cute language in a community that is always fighting and never going forward. -{{ chapters(prev_chapter_link="/books/things-i-learnt/use-structures", prev_chapter_title="If Your Data Has a Schema, Use a Structure", next_chapter_link="/books/things-i-learnt/outside-project", next_chapter_title="Don't Mess With Things Outside Your Project") }} +{{ chapters(prev_chapter_link="/books/things-i-learnt/resist-easy", prev_chapter_title="Resist The Temptation Of Easy", next_chapter_link="/books/things-i-learnt/outside-project", next_chapter_title="Don't Mess With Things Outside Your Project") }} diff --git a/content/books/things-i-learnt/outside-project/index.md b/content/books/things-i-learnt/outside-project/index.md index 7adfddb..fced03d 100644 --- a/content/books/things-i-learnt/outside-project/index.md +++ b/content/books/things-i-learnt/outside-project/index.md @@ -32,4 +32,4 @@ thing using extensions or actually coding around the problem, even duplicating the framework functions, would probably take longer and make you write more code, but in the long run, it's worth the time. -{{ chapters(prev_chapter_link="/books/things-i-learnt/use-structures", prev_chapter_title="If Your Data Has a Schema, Use a Structure", next_chapter_link="/books/things-i-learnt/languages-are-more", next_chapter_title="A Language Is Much More Than A Language") }} +{{ chapters(prev_chapter_link="/books/things-i-learnt/use-structures", prev_chapter_title="If Your Data Has a Schema, Use a Structure", next_chapter_link="/books/things-i-learnt/resist-easy", next_chapter_title="Resist The Temptation Of Easy") }} diff --git a/content/books/things-i-learnt/resist-easy/index.md b/content/books/things-i-learnt/resist-easy/index.md new file mode 100644 index 0000000..f033a72 --- /dev/null +++ b/content/books/things-i-learnt/resist-easy/index.md @@ -0,0 +1,31 @@ ++++ +title = "Things I Learnt The Hard Way - Resist The Temptation Of Easy" +date = 2019-07-01 + +[taxonomies] +tags = ["en-au", "books", "things i learnt", "ides"] ++++ + +Sure that IDE will help you with a ton of autocomplete stuff and let you +easily build your project, but do you understand what's going on? + + + +I'm not denying the fact that IDEs make things easier. The fact is, you should +not rely heavily on their features. + +I mentioned before that you should at least know how to [run tests on the +command line](/books/things-i-learnt/tests-in-the-command-line) and the same +applies to everything in IDEs: how to build, how to run, how to run tests and, +let's be honest here, how to find proper names for your variables and +functions. 'Cause, sure, it's nice that the IDE can complete all the names of +the functions, but if the autocomplete feature was off, would you know which +function you need? In other words, have you thought at least 10 seconds about +a good name for your function so you _won't_ need to use autocomplete to +remember its name? + +These days, IDEs can autocomplete almost everything, from function names to +even how to name your variables. But using the autocomplete is not always a +good solution. Finding better names is. + +{{ chapters(prev_chapter_link="/books/things-i-learnt/outside-project", prev_chapter_title="Don't Mess With Things Outside Your Project", next_chapter_link="/books/things-i-learnt/languages-are-more", next_chapter_title="A Language Is Much More Than A Language") }} From 23951d6c0e37aee62fc14ef5a37dbed6b0340cdb Mon Sep 17 00:00:00 2001 From: Julio Biason Date: Mon, 1 Jul 2019 13:06:46 -0300 Subject: [PATCH 11/12] New Chapter: Timezones --- content/books/things-i-learnt/_index.md | 1 + .../languages-are-more/index.md | 2 +- .../things-i-learnt/resist-easy/index.md | 2 +- .../things-i-learnt/use-timezones/index.md | 35 +++++++++++++++++++ 4 files changed, 38 insertions(+), 2 deletions(-) create mode 100644 content/books/things-i-learnt/use-timezones/index.md diff --git a/content/books/things-i-learnt/_index.md b/content/books/things-i-learnt/_index.md index 682e859..8e15213 100644 --- a/content/books/things-i-learnt/_index.md +++ b/content/books/things-i-learnt/_index.md @@ -39,6 +39,7 @@ template = "section-contentless.html" * [If Your Data Has a Schema, Use a Structure](use-structures) * [Don't Mess With Things Outside Your Project](outside-project) * [Resist The Temptation Of Easy](resist-easy) + * [Always Use Timezones With Your Dates](use-timezones) * Community/Teams * [A Language Is Much More Than A Language](languages-are-more) * [Understand And Stay Away From Cargo Cult](cargo-cult) diff --git a/content/books/things-i-learnt/languages-are-more/index.md b/content/books/things-i-learnt/languages-are-more/index.md index 0943de6..f53fa5f 100644 --- a/content/books/things-i-learnt/languages-are-more/index.md +++ b/content/books/things-i-learnt/languages-are-more/index.md @@ -39,4 +39,4 @@ surface of what the whole of a language encapsulates and if you ignore the other elements in it, you may find yourself with a cute language in a community that is always fighting and never going forward. -{{ chapters(prev_chapter_link="/books/things-i-learnt/resist-easy", prev_chapter_title="Resist The Temptation Of Easy", next_chapter_link="/books/things-i-learnt/outside-project", next_chapter_title="Don't Mess With Things Outside Your Project") }} +{{ chapters(prev_chapter_link="/books/things-i-learnt/use-timezones", prev_chapter_title="Always Use Timezones With Your Dates", next_chapter_link="/books/things-i-learnt/outside-project", next_chapter_title="Don't Mess With Things Outside Your Project") }} diff --git a/content/books/things-i-learnt/resist-easy/index.md b/content/books/things-i-learnt/resist-easy/index.md index f033a72..dc9212d 100644 --- a/content/books/things-i-learnt/resist-easy/index.md +++ b/content/books/things-i-learnt/resist-easy/index.md @@ -28,4 +28,4 @@ These days, IDEs can autocomplete almost everything, from function names to even how to name your variables. But using the autocomplete is not always a good solution. Finding better names is. -{{ chapters(prev_chapter_link="/books/things-i-learnt/outside-project", prev_chapter_title="Don't Mess With Things Outside Your Project", next_chapter_link="/books/things-i-learnt/languages-are-more", next_chapter_title="A Language Is Much More Than A Language") }} +{{ chapters(prev_chapter_link="/books/things-i-learnt/outside-project", prev_chapter_title="Don't Mess With Things Outside Your Project", next_chapter_link="/books/things-i-learnt/use-timezones", next_chapter_title="Always Use Timezones With Your Dates") }} diff --git a/content/books/things-i-learnt/use-timezones/index.md b/content/books/things-i-learnt/use-timezones/index.md new file mode 100644 index 0000000..976fc33 --- /dev/null +++ b/content/books/things-i-learnt/use-timezones/index.md @@ -0,0 +1,35 @@ ++++ +title = "Things I Learnt The Hard Way - Always Use Timezones With Your Dates" +date = 2019-07-01 + +[taxonomies] +tags = ["en-au", "books", "things i learnt", "dates", "timezones"] ++++ + +No matter if the date you're receiving is in your local timezone and you'll +display it in your timezone. Sooner or later, the fact that you ignored there +was a timezone behind that date will hurt you. + + + +(Note: Most of this post when I say "date" you can think of "date and time", +although the date should also be timezone aware.) + +At some point of my professional life, ignoring timezones was easy: You just +pick the date, throw in the database, then read it back and everybody was +happy. + +But things are not like this anymore. People will access your site from far +away locations, the source of the date may not be in the same timezone of your +system, your system may be running in a completely different timezone of your +dev machine (it's pretty common to run things in our machines in the local +timezone but the production system will run in UTC), the display may be a +complete different timezone than your production and dev machine and so on. + +So always carry the timezone with the data. Find modules/classes that support +dates with timezones (a.k.a. make things _timezone aware_), capture the +timezone as soon as possible and carry it around in all operations. +Modules/classes that don't support timezones for dates/times should, as soon +as possible, removed from the system. + +{{ chapters(prev_chapter_link="/books/things-i-learnt/use-timezones", prev_chapter_title="Always Use Timezones With Your Dates", next_chapter_link="/books/things-i-learnt/languages-are-more", next_chapter_title="A Language Is Much More Than A Language") }} From a94980d60ece94554939e392008074e385ea435e Mon Sep 17 00:00:00 2001 From: Julio Biason Date: Mon, 1 Jul 2019 17:29:40 -0300 Subject: [PATCH 12/12] New Chapter: Use UTF8 --- content/books/things-i-learnt/_index.md | 1 + .../languages-are-more/index.md | 2 +- .../things-i-learnt/use-timezones/index.md | 7 ++- .../books/things-i-learnt/use-utf8/index.md | 55 +++++++++++++++++++ 4 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 content/books/things-i-learnt/use-utf8/index.md diff --git a/content/books/things-i-learnt/_index.md b/content/books/things-i-learnt/_index.md index 8e15213..bda025c 100644 --- a/content/books/things-i-learnt/_index.md +++ b/content/books/things-i-learnt/_index.md @@ -40,6 +40,7 @@ template = "section-contentless.html" * [Don't Mess With Things Outside Your Project](outside-project) * [Resist The Temptation Of Easy](resist-easy) * [Always Use Timezones With Your Dates](use-timezones) + * [Always Use UTF-8 For Your Strings](use-utf8) * Community/Teams * [A Language Is Much More Than A Language](languages-are-more) * [Understand And Stay Away From Cargo Cult](cargo-cult) diff --git a/content/books/things-i-learnt/languages-are-more/index.md b/content/books/things-i-learnt/languages-are-more/index.md index f53fa5f..c0ac487 100644 --- a/content/books/things-i-learnt/languages-are-more/index.md +++ b/content/books/things-i-learnt/languages-are-more/index.md @@ -39,4 +39,4 @@ surface of what the whole of a language encapsulates and if you ignore the other elements in it, you may find yourself with a cute language in a community that is always fighting and never going forward. -{{ chapters(prev_chapter_link="/books/things-i-learnt/use-timezones", prev_chapter_title="Always Use Timezones With Your Dates", next_chapter_link="/books/things-i-learnt/outside-project", next_chapter_title="Don't Mess With Things Outside Your Project") }} +{{ chapters(prev_chapter_link="/books/things-i-learnt/use-utf8", prev_chapter_title="Always Use UTF-8 For Your Strings", next_chapter_link="/books/things-i-learnt/outside-project", next_chapter_title="Don't Mess With Things Outside Your Project") }} diff --git a/content/books/things-i-learnt/use-timezones/index.md b/content/books/things-i-learnt/use-timezones/index.md index 976fc33..89e4a91 100644 --- a/content/books/things-i-learnt/use-timezones/index.md +++ b/content/books/things-i-learnt/use-timezones/index.md @@ -32,4 +32,9 @@ timezone as soon as possible and carry it around in all operations. Modules/classes that don't support timezones for dates/times should, as soon as possible, removed from the system. -{{ chapters(prev_chapter_link="/books/things-i-learnt/use-timezones", prev_chapter_title="Always Use Timezones With Your Dates", next_chapter_link="/books/things-i-learnt/languages-are-more", next_chapter_title="A Language Is Much More Than A Language") }} +Developers a bit more seasoned -- and by "seasoned" I meant "Had to deal with +times before" -- will probably claim "Hey, this is _obvious_!" And I'd have to +agree. But it's annoying how many times I got bitten by some stupid bug 'cause +we decided that "well, everything is in the same timezone, so it's all good". + +{{ chapters(prev_chapter_link="/books/things-i-learnt/resist-easy", prev_chapter_title="Resist The Temptation Of Easy", next_chapter_link="/books/things-i-learnt/utf-utf8", next_chapter_title="Always Use UTF-8 For Your Strings") }} diff --git a/content/books/things-i-learnt/use-utf8/index.md b/content/books/things-i-learnt/use-utf8/index.md new file mode 100644 index 0000000..ef47acc --- /dev/null +++ b/content/books/things-i-learnt/use-utf8/index.md @@ -0,0 +1,55 @@ ++++ +title = "Things I Learnt The Hard Way - Always Use UTF-8 For Your Strings" +date = 2019-07-01 + +[taxonomies] +tags = ["en-au", "books", "things i learnt", "utf-8"] ++++ + +Long gone are the days where [ASCII](https://en.wikipedia.org/wiki/ASCII) was +enough for everyone. Long gone are the days where you can deal with strings +with no "weird" or "funny" characters. + + + +I was born in a time when the only encoding we had was ASCII. You could encode +all strings in sequences of bytes, 'cause all characters you could use where +encoded from 1 to 255 (well, from 32 [space] to 93 [close brackets] and you +still have a few latin-accented characters in some higher positions, although +not all accents where there). + +Today, accepting characters beyond that is not the exception, but the norm. To +cope with all that, we have things like +[Unicode](https://en.wikipedia.org/wiki/Unicode) and +[uTF-8](https://en.wikipedia.org/wiki/UTF-8) for encoding that in reasonable +memory space (UTF-16 is also a good option here, but that would depend on your +language). + +So, as much as you to make your system simple, you will have to keep the +internal representation of your strings in UTF-8/UTF-16. Surely, you may not +receive the data as UTF-8/UTF-16, but you'll have to encode it and keep +transmitting it around as UTF-8/UTF-16 till you have to display it, at which +point you'll convert from UTF-8/UTF-16 to whatever your display supports +(maybe it even supports displaying in UTF-8/UTF-16, so you're good already). + +At this point, I believe most languages do support UTF-8, which is great. You +may still have problems with inputs coming from other systems that are not +UTF-8 (old Windows versions, for example), but that's fairly easy to convert +-- the hard part is figuring out the input _encoding_, though. Also, most +developers tend to ignore this and only accept ASCII characters, or ignore +UTF-8/whatever-encoding and get a bunch of weird characters on their printing, +'cause they completely ignored the conversion on the output point. That's why +I'm repeating the mantra of UTF-8: To remind you to always capture your input, +encode it in UTF-8 and _then_ convert in the output. + +One thing to keep in mind is that UTF-8 is not a "cost free" encoding as +ASCII: While in ASCII to move to the 10th character, you'd just jump 10 bytes +from the start of the string, with UTF-8 you can't, due some characters being +encoded as two or more bytes (you should read the Wikipedia page; the encoding +is pretty simple and makes a lot of sense) and, due this, you can't simply +jump 10 characters 'cause you may end up in second byte that represents a +single character. Walking through the whole string would require traversing +the string character by character, instead of simply jumping straight to the +proper position. But that's a price worth paying, in the long run. + +{{ chapters(prev_chapter_link="/books/things-i-learnt/use-timezones", prev_chapter_title="Always Use Timezones With Your Dates", next_chapter_link="/books/things-i-learnt/languages-are-more", next_chapter_title="A Language Is Much More Than A Language") }}