Plurrrr

week 45, 2022

Stop writing Rust linked list libraries!

Don’t write a Rust linked list library: they are hard to do well, and usually useless.

Use VecDeque, which is great. If you actually need more than VecDeque can do, use one of the handful of libraries that actually offer a significantly more useful API.

If you are writing your own data structure, check if someone has done it already, and consider slotmap or generation_arena, (or maybe Rc/Arc).

Source: Stop writing Rust linked list libraries!.

Army of Thieves (2021)

A prequel, set before the events of Army of the Dead, which focuses on German safecracker Ludwig Dieter leading a group of aspiring thieves on a top secret heist during the early stages of the zombie apocalypse.

In the evening Alice, Esme, and I watched Army of Thieves. I liked the movie and give it a 7.5 out of 10.

The evolution of scalable CSS

In this post, we’ll develop a deeper understanding of CSS by diving into the underlying issues that make it difficult to scale.

We’ll understand the evolution of the various CSS best practices that have emerged and changed over time.

By the end, we’ll have a good grasp on past approaches to scaling CSS on large projects, and how popular tools like Tailwind and a range of others address these issues in counter-intuitive ways.

Source: The evolution of scalable CSS.

How Regexes Work

This isn't an article about how to use regexes; you've probably seen plenty of those already. It's about how you would write a regex package from scratch, in a language like C that doesn't already have regexes.

I'll demonstrate a new module, Regex.pm, which implements regexes from nothing, in Perl. This will give you an idea of how regex matching is possible, although the details differ rather substantially from what Perl actually does.

Source: How Regexes Work, an article by Mark-Jason Dominus.

Adding types to a large Python codebase

Python is one of the world’s beloved programming languages. Dynamic typing makes it easy to learn and fast to build with. Its popularity has led to its use in some of the most advanced AI systems and web applications on the planet.

However, traditional dynamically typed Python code struggles at scale. Specifically:

  • Refactoring is painful. It is challenging to refactor any large dynamically typed codebase. This is because dynamically typed code can’t be processed with the sort of static analysis and refactoring tools widely available in statically typed languages (e.g. Java, C#). These tools support automatic symbol renaming, reference lookup, edit-time type-checking etc.
  • It’s hard to ensure correctness. Dynamically typed Python code is difficult to check for correctness. The best available method is to write comprehensive automated tests, but writing and maintaining a large test suite is expensive. Tests are also often too slow to provide feedback while editing in the same way as static analysis tools, allowing errors to compound for longer.

Source: Adding types to a large Python codebase, an article by Sean Mackesey.

Blessed - An unofficial guide to the Rust ecosystem

Compared to other programming languages such as Python and Go, Rust's standard library is very small, including only core data structures in the standard library with all other functionality farmed out to 3rd party ecosystem crates, and a common complaint from new Rust developers is that they don't know where to start: which crates they ought to use and which crates they ought to trust. This list attempts to answer those questions.

Source: Blessed.

Trie in Python

A post about Haskell vs. Python readability came onto my radar the other day. It compares the implementation of a trie structure, and after looking upon the Python version I wanted to make my own attempt. I didn't make it to necessarily compare or "battle" against the other solutions, it's more of an exercise in the vein of "how would I do it".

Source: Trie in Python, an article by Ivan Sagalaev.

Basics of Haskell

A gentle introduction to Haskell for beginners.

The prerequisite for this series of tutorials is some knowledge of imperative programming, whether C++, Java, Pascal, you name it. If you have some familiarity with functional programming, that's even better.

Source: Basics of Haskell, an article by Bartosz Milewski.

The Hitman's Bodyguard (2017)

One of the world's top bodyguards gets a new client, a world class hitman who must testify at the International Criminal Court. They must put their differences aside and work together to make it to the trial alive and on time.

In the evening Alice and I watched The Hitman's Bodyguard. We had already seen the sequel: Hitman's Wife's Bodyguard, which I didn't like much. But I did like this movie and I give it a 7 out of 10.

Improving the experience of JSON in Haskell

In my last post, I talked about how Haskell newtypes are great tools for modeling JSON data when writing API clients in Haskell, and I included some examples on how to write custom ToJSON and FromJSON methods that incorporated these newtypes. That post generated some discussion on Lobsters, from which I learned about this interesting library called autodocodec. Given the advantages laid out in that discussion, I decided to give that library a try on my project’s codebase, and it worked so well that, so I ended up refactoring basically all of my types to use autodocodec to generate JSON parsers for my types. In fact, I enjoyed the experience of using autodocodec so much that I thought it was worth blogging about.

Source: Improving the experience of JSON in Haskell with autodocodec and bifunctors, an article by Dylan Martin.

Creating a priority queue with a custom sort order

I want to create a personal web crawler. As I download each page, I collect a new list of URLs. To increase the likelihood that I am downloading the most important pages first, I want to keep the list of URLs to visit sorted by length (shorter URLs are more likely to be closer to the front page). That presents a problem though, because I'm also adding URLs.

A naïve list (Vec<T> in Rust), won't be very efficient. After every batch of inserts, I would need to re-sort the list. Wouldn't it be good if there were a data structure that could maintain the sort order itself? Yes! It's called a binary heap.

Source: Creating a priority queue with a custom sort order using a binary heap in Rust, an article by Tim McNamara.

Idiot proof git

I’m an idiot. And git is hard. A lot of places use a rebase-based Git workflow, and I’ve made git less hard with a set of handy aliases. Put these in your ~/.gitconfig and turn git into an actually less painful command line tool to use.

Source: Idiot proof git, an article by Doug Turnbull.

Mocking a JavaScript Class with Jest, two ways to make it easier

Jest is the most popular automated testing framework for JavaScript. It can be used both on the front end and back end with Node.js. Jest is a feature-rich, batteries included testing framework. Amongst other valuable features, the ability to mock dependencies out of the box is a useful one.

In this post, you will learn about the need for mocking in unit testing and the difference between dependency injection and mocking. You will also get acquainted with mocking in Jest. Furthermore, you will see an example script with two classes and mock the dependent class to test the other class with a full code example using module factory and Jest SpyOn. Let’s get rolling!

Source: Mocking a JavaScript Class with Jest, two ways to make it easier, an article by Geshan Manandhar.

Get Started with Rust: Traits

A trait is a basic language concept for defining shared behavior on types. Traits describe an interface that types can implement.

Rust traits are a sibling of Scala traits and Haskell type classes, as well as a cousin of C++ and Java interfaces.

This article will show you how to use traits in Rust. After reading it, you’ll be able to answer these questions:

  • What is a trait?
  • Why do we use traits in Rust?
  • How to implement and define traits in Rust?
  • What does it mean to derive a trait, and when can we do it?

Source: Traits in Rust, an article by Yevhenii Zelenskyi.

Functional programming from sets and functions

Introductions to functional programming are usually targeted at people who are already accustomed to programming, and they typically present the perks of the paradigm by comparing it to imperative or object-oriented programming. This often leaves the reader with the impression that they have to unlearn practices and concepts they already know to adopt this new paradigm.

In this post I would like to try a different approach, not requiring any programming knowledge, but only the most basic intuition. We will build on high school mathematics, in the form of sets and functions, to provide a learning path to understanding functional programming1.

Source: Functional programming from sets and functions, an article by Marco Perone.

The Takeover (2022)

Framed for murder after uncovering a privacy scandal, an ethical hacker must evade the police while trying to track down the criminals blackmailing her.

In the evening Esme and I watched the Dutch movie The Takeover. It suffers a lot from the typical "hacker" nonsense like slow scrolling source code etc. While I liked to see some parts of Rotterdam, where I have lived for a while in the 90's, I didn't like the movie much and give it a 5 out of 10.

Haskell, Python, and Readability

This weekend on /r/programming someone posted a nice introduction to tries using Python. A while ago, I had implemented a mini web server to do completion and correction of words using Ternary Search Tries in Haskell, and since the trie post generated a lot of interest I decided to post mine too.

Then, someone else posted a blog article commenting on the readability of Python and Haskell based on my web server code and the trie example, concluding that the Python version was much more readable.

Source: Haskell, Python, and Readability, an article by Francesco Mazzoli.

Better Python code grepping with pyastgrep

A few weeks ago I released pyastgrep, a tool for grepping Python code at the syntax level (using AST - Abstract Syntax Trees), and today I released some more improvements.

It builds on an earlier tool, astpath which now appears to be abandoned, and also had quite a few bugs. I’ve fixed lots of things and re-written quite a bit internally in backwards incompatible ways, so a fork was the easiest way forward. I’ve also been able to make lots of improvements to default behaviour, inspired by tools like ripgrep. For example, it automatically exclude paths that match discovered .gitignore files, which can make a massive performance improvement in some cases (looking at you, node_modules).

Source: Better Python code grepping with pyastgrep, an article by Luke Plant.

Python List Comprehensions Are More Powerful Than You Might Think

Python's list comprehensions (and generators) are an awesome feature that can greatly simplify your code. Most of the time however, we only use them to write a single for loop, maybe with addition of one if conditional and that's it. If you start poking around a bit though, you will find out that there are many more features of Python's comprehensions that you don't know about, but can learn a lot from...

Source: Python List Comprehensions Are More Powerful Than You Might Think, an article by Martin Heinz.

Is There Too Much CSS Now?

As front-end developers, we’ve wished for a lot of things over the years — ways to center things in CSS, encapsulate styles, set an element’s aspect ratio, get finer-grained control over our colors, select an element based on its children’s properties, manage layers of specificity, allow elements to respond to the width of their parents… the list goes on and on.

And now that we got all we wished for and more, some of us are asking — do we now have too much CSS?

Source: Is There Too Much CSS Now?, an article by Sacha Greif.