Lucas, The Wizard

Lucas, The Wizard

Темы
Неделя
Jul 6, 2020 → Jul 15, 2020

@thewizardlucas week

Monday


Hello, everyone! This week your host will be me, @thewizardlucas ✨ I'm a Brazilian Software Engineer, currently in London. You may know me from my talks at HolyJS especially because of this one: youtube.com/watch?v=rqZuNA… I'm very happy to be your host this week 💖

I'm currently writing a book about JavaScript testing, which you can find at this tweet's link, and I often write at lucasfcosta.com. Unfortunately, I'm not a Russian speaker, so the tweets will be in English. I hope you'll appreciate my insights! manning.com/books/testing-…

100% code coverage does not exist. The only way you can make it impossible for your software not to make certain mistakes is with types, not with tests. Here's why 👇

In his brilliant article named "Why Most Unit Testing is Waste" (rbcs-us.com/documents/Why-…) James O'Coplien explains what he'd consider as 100% coverage, and it's different from what most of us think it is:

"I define 100% coverage as having examined all possible combinations of all possible paths through all methods of a class, having reproduced every possible configuration of data bits accessible to those methods, at every machine language instruction along the paths of execution."

"Anything else is a heuristic about which absolutely no formal claim of correctness can be made."

Tests can't prove that your software doesn't have bugs, they can only prove it has bugs. On the other hand, Types allow you to encode certain properties about your programs in advance, in such a way that they can make incorrect states impossible.

In this talk (one of my favourite talks ever), @rtfeldman explains in more detail how to use types to make impossible states impossible: youtube.com/watch?v=IcgmSR…

🔥Thread (@thewizardlucas)
Contrary to what most people think, Test Driven Development is not about tests. It's about taking small iterative steps towards a solution. TDD is a fear reducing tool, it helps you get feedback earlier in the process of writing code so that you end-up with less rework.

Another misconception that people have is that they should always repeat the TDD cycle (failing, passing, refactor) multiple times, which makes tests slow. Actually, when doing TDD you not always have to do more iterations. Your iterations should be as big as your confidence is.

The more confident you are, the more thorough should be the tests you create, and the bigger should be the chunks of code you write. Writing a difficult piece of code? Reduce speed. Create simpler tests, write less code, take more steps, and refactor as you go until you finish.

Tuesday


One of the things that has made me the most productive in my career was to learn how to properly use a terminal. Today, I use it for amost everything. Last year, I went a post detailing the tools I was using at the time, and it went kinda viral: lucasfcosta.com/2019/02/10/ter…

A few things have changed in my stack since then, but, currently, here are the most important tools I've been using: Kitty (migrated from iTerm) (sw.kovidgoyal.net/kitty/) Tmux (github.com/tmux/tmux/wiki) Neovim (neovim.io) ZSH (zsh.org)

As far as Vim plugins go, I don't use many. The ones I think are the most useful are FZF (github.com/junegunn/fzf.v…) and ConquerOfCompletion (github.com/neoclide/coc.n…). Besides that, I try to keep my configs as vanilla as possible, so that I'm confortable in any environment

You can find my dotfiles with these configs at github.com/lucasfcosta/do…. These files have been wanting my attention for quite a while, and there's still an open PR with the 2020 configs on the repo: github.com/lucasfcosta/do…, which I'm yet to update and merge.

🔥Thread (@thewizardlucas)
The best way to review PRs is to: ⭐ Assume that there is always something that can be improved and that your job is to find it. ⭐ Review with the intention of adding comments. Does something need changing? Say it. Something is good? Give praise. Didn't understand? Ask.

Akin’s Laws of Spacecraft Design (spacecraft.ssl.umd.edu/akins_laws.html) are one of the most useful pieces of wisdom for any engineering discipline, especially software engineering. Here are a few that have been very helpful to me 👇

Engineering is done with numbers. Analysis without numbers is only an opinion.

To design a spacecraft right takes an infinite amount of effort. This is why it's a good idea to design them to operate when some things are wrong .

In nature, the optimum is almost always in the middle somewhere. Distrust assertions that the optimum is at an extreme point.

Not having all the information you need is never a satisfactory excuse for not starting the analysis.

A bad design with a good presentation is doomed eventually. A good design with a bad presentation is doomed immediately.

(Patton's Law of Program Planning) A good plan violently executed now is better than a perfect plan next week.

🔥Thread (@thewizardlucas)

Wednesday


Given that my twitter handle is @thewizardlucas, I couldn't help but love something as magical as streams 💖 Throughout the day today, I'll do a few posts about streams. Here's a quick intro👇

🤔Why I love streams I love streams because I don’t like software. I always try to build less software. Less software means you have to spend less time updating it, less time fixing it, and less time thinking about it. The only thing better than “less software” is no software.

❓How can streams help build less software? Streams help us writing less software because they allow programs to communicate with each other. If programs cannot communicate they must have too many features to satisfy their user’s needs, therefore creating more software.

By enabling inter-process communication, streams encourage software to be smaller and sometimes can even prevent software from being written.

📚What are streams? In the same way that a river has a stream of water, programs have streams of data. Moreover, just like you can use steel pipes to carry water from one place to another, you can use UNIX pipes to carry data from one program to another.

⚙️How do streams work? Streams can be used to pass data into programs and to get data out of them. In UNIX, programs get some streams attached to them by default, both for input and output. We call these standard streams.
notion image

There are three different standard streams: standard input ➡️the stream which feeds your program with data standard output ➡️ the stream to which your program writes its main output standard error ➡️ the stream to which your program writes error messages
notion image

The cat program, for example, uses the stdin to receive input from your keyboard and the stdout to send it out. Data goes in through stdout and stderr and goes out in the other end: your monitor. Similarly, your keyboard input goes through stdin to a program.
notion image

When you know what each stream does, you can connect multiple programs through them.
notion image

🔥Thread (@thewizardlucas)
What if I told you that your terminal is not "really" a terminal❓ If you are not a hardcore time-traveller, what you use is not really a terminal, in fact, it's a terminal emulator. Terminal emulators are software simulations of “real” terminals.

These emulators provide you with an interface to interact with the Linux TTY driver. The TTY driver is responsible for handling the data to and from programs.
notion image

Each TTY has its own stdin, stdout, and stderr streams connected to it. These are the streams provided to programs for them to read from (stdin) and write to (stdout and stderr).
notion image

Like everything in UNIX, the tty is a file. Each instance of a terminal emulator has a different tty file associated with it. Because each emulator reads from and writes to a different file, you don’t see the output of the programs you run in all the windows you have open.

To find out which tty is associated with a terminal window you can use the tty command.
notion image

When you open a new terminal window, its streams will point to the connected TTY.
notion image

🔥Thread (@thewizardlucas)
To complement the two threads about #unix #streams that I've done today, here go a few related links that I'd recommend: linusakesson.net/programming/tt… catonmat.net/bash-one-liner… lucasfcosta.com/2019/04/07/str…

Thursday


Today, a little bit about lambda calculus, to complement one of my favourite talks ever, this one, at HolyJS 2018: youtube.com/watch?v=rqZuNA…

A long time ago, a guy called Leibniz had a dream: he wanted to solve all problems using logic. His dream was to be able to translate all matters into a system of symbols and then have clear rules to manipulate those symbols and get to an answer.
notion image

If you would like to hear straight from Leibniz himself, this is what he said: "If controversies were to arise, there would be no more need of disputation between two philosophers than between two calculators."

"For it would suffice for them to take their pencils in their hands and to sit down at the abacus, and say to each other (and if they so wish also to a friend called to help): Let us calculate."

And for a long time, people have tried to do create formal ways of expressing computation and solving problems. Here you can see computer science at its inception.

Today, most of us already know one way of expressing computations: through the use of Turing Machines. The other way is through Lambda Calculus, introduced by Alonzo Church in the 1930s. Lambda calculus is the very basis for functional programming.

To this day, learning lambda calculus can be very helpful for one to learn functional programming properly. Not at the level of being able to write programs, but at the level of designing good programs, and understanding functional principles. stackoverflow.com/questions/1145…

🔥Thread (@thewizardlucas)

Friday


Continuing the thread about Lambda Calculus from yesterday! In this one, we'll go through the very basics and talk about how it actually works👇

Everything in Lambda Calculus is an expression, which means that everything must evaluate to a value. There are, however, four different forms of expressions. An expression can be either: ID - Identifier λID. E - Abstraction. E E - Application (E) - Grouping

➡️Identifiers are simply that: identifiers. They identify certain values by giving them a “name”, just like our modern programming languages do.

➡️Abstractions are perhaps the most iconic kind of lambda expression, they define what we call functions or, more adequately, lambdas: which are just anonymous functions. a => b => a is equivalent to an abstraction, for example.

The ID in the beginning of that abstraction is called the metavariable. The metavaraible is the variable that is going to be used in the function’s body. In a => a, you have "a" as a metavariable.

➡️ Applications denote function invocation. If you have a function A you can say you’re calling it with B by writing: A B. In JS, that would be something like: (a => b => a)(first)(second)

➡️Grouping exists for the sake of disambiguation. We use these parentheses around the expressions we want to group to make it clear which ones of them we want to apply to each other.

🔥Thread (@thewizardlucas)
Writing software is easier than writing books because you don’t have to build an entire product before you can sell it. Distributing software usually takes a few seconds and costs virtually nothing.

The fact that you can ship software several times a day at zero-cost allows you to make fewer assumptions when building it. You can iterate in smaller steps and test your hypothesis one at a time.

Links