Newsletter 18 – 08/2021

Featured

Got game? Secrets of great incident management – Incident management is a critical process in every company, this post brings in a funny way the concept of game days for training incident management.

A great list of computer science papers to read – 13 papers about computer science to read. This list looks interesting and I’ll read! Check it out.

2021 Developer Sourvey – 2021 StackOverflow’s developer sourvey results is available, a lot of interesting insights about tech industry.

How we deal with technical incidents – Let’s talk about incident management, this post written by me talks about how we’re dealing with incident management at Nubank and how blameless culture empowers it.

MISC

Why we killed elixir – It’s always worth to read about different point of views, this post brings an opinion of why a team choose to stop using Elixir to use Go.

Can GitHub Copilot Crack a Facebook Coding Interview? – GitHub has gaining a lot of spotlights recently and this post gained my attention, it explores how Copilot can help you on Facebook coding interview.

Common Anti-Patterns in Go Web Applications – This post brings common anti-patterns to Go web applications but contents like that can be useful for programmers of any language. Check it.

Getting Started with Systems Programming with Rust (Part 1) – Nice tutorial to get started to system programming in Rust (It already have a part 2). If you’re interested in system programming, this post is for you.

Clojure Journey X – Namespaces

Now that we know how to create our functions we need to understand how Clojure organizes and accesses it, this way is called namespaces.

Every good wizard has a lot of books on his bookshelf, with different magics to use in a lot of situations. Imagine a Clojure namespace as being one of your books, and each function or variable (defined with def) is written on it, when you need to use your function, you just search for it in this book and use it!

Your book (namespace) of functions to deal with strings

If you enter in your REPL, you’ll be in a “default” namespace called user, everything that you define here, we’ll be associated with this namespace.

user => (def author-name "otavio")
#'user/author-name

You may have already noticed that when we defined author-name it returned #'user/author-name, it means that you defined an author-name in the user namespace.

To create a new namespace and switch to it, you only need to type ns and a name to it, it will create (if not exists), and you can’t access values defined in other namespace directly anymore. Just like a blank book, waiting to be written.

user => (ns my-new-ns)
nil
my-new-ns => author-name
Syntax error compiling at (REPL:1:1).
Unable to resolve symbol: author-name in this context
Let’s start writing our namespaces

If you want, you can access any variable or function defined in other namespace, just typing its “full address” namespace + name.

my-new-ns => user/author-name
"otavio"

Switch between namespaces is easy, just use in-ns and pass the namespace name preceded by quote. After it, you can access the defined values of this namespace directly again.

any-ns=> (in-ns 'user)
#object[clojure.lang.Namespace 0x56317ffa "user"]
user=> author-name
"otavio"

You can always see in which namespace are you, just typing *ns* (but you can just see in your REPL too.)

Reading other books

Sometimes you as a wizard will want to read books written by other wizards, to not lose your precious time reinventing the wheel creating already existent magics.

Most languages are shipped with a lot of code that you must need, things like string operations, basic http logic, and much more. All this code is available for you, in the form of namespaces, and to use it is simple!

Famous Clojure Libs, just waiting to be used!

Every time that you create a new namespace using ns in your REPL, it will be automatically loaded on it, and you can just start using it, but this is not true while trying to access namespaces packaged in files (which will be important in the future when we start to work with multiple files in large projects).

Let’s use as an example the namespace clojure.string which contains functions to deal with common string operations, we want to use capitalize function from it! The first step is to make our REPL aware of the namespace that you want to use using the require function, passing as an argument the namespace that we want to load in our REPL, after this all functions and symbols globally defined in this namespace are available to us, just use them using its ‘full address’ namespace + name.

user => (require 'clojure.string)
nil
user => (clojure.string/capitalize "hello clojure")
"Hello lojure"

But write clojure.string every time isn’t productive, so we can use the :as keyword to create an alias to use this namespace.

user => (require '[clojure.string :as str])
nil
user => (str/capitalize "hello clojure")
"Hello clojure"

This required namespace will be available only on current namespace, if you change to other namespace, it will no longer be available.

Better now, ya? This is the Clojurist way of using external namespaces from other namespace (including libraries as we’ll see in the future).

If you want, you can also enter in the string namespaces and use functions directly, but I really don’t know why you may want to do it:

user => (require 'clojure.string)
nil
user => (in-ns 'clojure.string)
nil
clojure.string => (capitalize "hello clojure")
"Hello clojure"

Conclusions

Learn how to use namespaces is important! We did not learn how to pack namespace in files yet, but we will in the future! This knowledge is important, it will help while developing using our REPL, and in the future post talking about files.

Next steps

On the next post of this series, we’ll still talking about functions, with just a short trick to make our functions better and readable!

Final thought

If you have any questions that I can help you with, please ask! Send an email (otaviopvaladares at gmail.com), pm me on my Twitter, or comment on this post!

Clojure Journey IX – Destructuring

While creating your beautiful functions you probably will face many times your function receiving a sequential-like structure and needing to decompose its values and bind it to names to use later. For example:

=> (def numbers [42 1 2 3 4])
#'user/numbers
=> (def my-func [any-vector]
     (println (first any-vector) (second any-vector)))
#'user/my-func
=> (my-func numbers)
42 1

You as a critical wizard, may think that’s awful, right? Would be nice if Clojure provides a way of do this process in a beautiful and magic way like in other features right?

This is so awful, we need a way to change it.

Fortunately clojure already provides a way to do it, and its called Destructuring,its the process of bind names to data structure’s values in a readable way.

Many languages have destructuring support like Javascript, Clojure as no exception, has it as feature and don’t require any third party libraries to do so.

A common point of confusion is to think that destructuring is pattern matching, but it’s not, it’s different. To achieve pattern matching in Clojure you can use core.match lib, but it’s topic for another post.

The basics

The most common example as we saw, is to extract things from vectors, imagine that inside your function, you need to bind names to each record of a size 2 vector, you probably will write something like that:

=> (defn print-values [vector]
     (println (first vector) (second vector)))
#'user/print-values
=> (print-values [1 2])
1 2

But you can use destructuring to do it in a less verbose and beautiful way, and it will work just as the first example.

=> (defn print-values [[first second]]
     (println first second))
#'user/print-values
=> (print-values [1 2])
1 2
List destructuring

Please, note that you don’t need to match the full vector, you can match only the first item if you want:

=> (defn print-values [[first-value]]
     (println first-value))
#'user/print-values
=> (print-values [1 2 3 4 5])
1

As in many languages you can use _ to ignore values, in destructuring you can use it to ignore values in the process:

=> (defn print-values [[first-value _ third-value]]
     (println first-value third-value))
#'user/print-values
=> (print-values [1 2 3])
1 3

You can use & to bind the remaining itens of the vector who are not bindend to any name.

=> (defn print-rest [[_ _ _ & rest-itens]]
     (println rest-itens))
#'user/print-rest
=> (print-rest [1 2 3 4 5 6 7])
(4 5 6 7)

Probably you’re thinking that may think that destructuring doesn’t make any sense, but when dealing with nested vectors, its beautiful (and will be much more beautiful when dealing with maps):

=> (defn print-nested [[_ _  [first-nested-value second-nested-value]]]
     (println first-nested-value second-nested-value))
#'user/print-nested
=> (print-nested [1 2 [3 4]])
3 4

Using the bind :as in the last thing of your destructuring you can bind all the struct to a name, just like this:

=> (defn entire-vector [[vec :as entire-vector]]
     (println entire-vector))
#'user/entire-vector
=> (entire-vector [1 2 3 4 5 6 7])
[1 2 3 4 5 6 7]

The beautiful way of dealing with maps

Most of Clojure developers works with web applications, and probably are working with JSON file format, meaning that most of them are working with maps. If you already worked if this kind of application you know that most of your time you’ll be dealing with this hash maps structures, getting data from it.

This brings us to a nice spot, where we can use what we learned from destructuring to extract what we want from a map, representing some received JSON. Let’s take as example, a map that represents a person:

=> (def people {:name "Otavio", 
                :last-name "Valadares",
                :contact {:phone "+550000000000",
                          :email "xpto@xpto.com"}, 
                :address {:country :brazil,
                          :state :sp,
                          :street "Xpto Street",
                          :number "42"}})
#'user/people

If we want, we can just access the number using techniques that we already learned in this post just changing to map, the recipe is to use the syntax {first-symbol :key, second-symbol :second-key}:

=> (defn address-number [{{number :number} :address}]
     (println number))
#'user/address-number
=> (address-number people)
42

But following this syntax of always specifying the symbol and key can be “ugly”, why not use a more beautiful and stylish way? Fortunately, the first Clojure wizards has built a shortcut for us, we only need to use :keys key can be used to only write each key once.

=> (defn address-number [{{:keys [number]} :address}]
     (println number))
#'user/address-number
=> (address-number people)
42

It’s important to note that both lists and maps will be bound nil when the value to destruct doesn’t exist, so, pay attention to it. But a good wizard always has a defense prepared against nil, and when dealing with destructuring, we can use :or keywords to define a default value to some bind. Just put the keyword followed by a map containing the not found key and the default value.

=> (defn get-doc [{:keys [doc] :or {doc"xxx"}}]
     (println doc))
#'user/get-document
=> (get-doc people)
xxx
Lets do some magic to have keywords!

Everything that we can use with lists, we can use with maps too, like :as or & keywords and much more.

Conclusions

Destructuring have many other tricks too, that you can study here. But with this text you already know enough to make your functions looks beautiful, it will look specially useful when we start dealing with JSON data with a lot of nested data.

Next steps

On the next post of this series, we’ll still talking about functions, with just a short trick to our functions.

Final thought

If you have any questions that I can help you with, please ask! Send an email (otaviopvaladares at gmail.com), pm me on my Twitter, or comment on this post!

Follow my blog to get notified every new post:

Newsletter 17 – 07/2021

Featured

Write a time-series database engine from scratch – This post is gold! If you work with any time-series database or loves to know how databases work, this post is for you! A lot of good references too.

Software Architecture Books – A curated list of software architecture books with rantings. It can be especially useful to choose your next book.

Alien Dreams: An Emerging Art Scene – There is an emerging art scene, generative art using deep learning models is growing and this post explains all that you need to know. I already played and created some art, it’s amazing!

Contributing the Go Compiler: Adding New Tilde (~) Operator – A very long post (43 minutes) but fantastic. It covers all that you need to know to start contributing to the Go compiler, this post walk through all the process to add a new operator to the language (A tilde operator), explaining some compiler aspects and giving you a north to begin.

Dropbox Engineering Career Framework – Dropbox has opened its engineering career framework, not only of software engineering, but also eng managers, QA, and much more.

Python behind the scenes #11: how the Python import system works – Python import system is complex and people usually don’t understand how it works. This post explains how it works behind the scenes, and it’s awesome like all posts from this series (that I already shared in previous issues).

Mind the platform execution gap – Build a horizontal platform team is a challenge for many companies around the world. This post gives a nice introduction to it, and if you work if a platform team or want to build one, it’s worth reading.

MISC

How to Create Your Very Own Chip-8 Emulator – Chip-8 emulation is the hello world of emulation, if you want a great tutorial to get introduced to this subject, here’s a great one.

Go read list – A lot of interesting things to read and learn about Go.

HTTP server in Ruby 3 – Fibers & Ractors – The author teach how to build four different HTTP servers in Ruby 3 using different concurrency models, and in the final benchmark it to see the differences. Very interesting!

Crafting Interpreters – Crafting Interpreters in my opinion is one of the best books to get started on languages implementations, it helped me a lot when I was studying it. Finally, it got its print versions, but it’ll keep available to read for free online!

What is a GenServer? – When coding Elixir probably you will face GenServers a powerful Elixir tool that can help you solve a lot of kinds of problems. This short guide gives you an introduction to it.

My Prometheus is Overwhelmed! Help! – Many engineers usually only install Prometheus, start to using it and one day… It starts to crash & get slow. This post gives you a nice list with the most well known problems that your prometheus can have.