I view at least half the written content I consume via my mobile
phone, which belongs to the class of phones with a slightly smaller
than average screen. In fact, it’s width as reported by the Firefox
and Chrome viewport simulators is 375 pixels wide, small but not
tiny. And yet many websites I visit hinder my mobile viewing
experience because of a rather simple issue: horizontal scrolling.
If you’re building a new app today, it might be worth taking a
closer look at making it cloud-native and using Kubernetes from the
jump. The effort to set up Kubernetes is less than you
think. Certainly, it’s less than the effort it would take to
refactor your app later on to support containerization.
Dependency Injection is a software design pattern in which an object
receives other instances that it depends on. It’s a commonly used
technique that allows reusing code, insert mocked data, and simplify
testing. An example could be initializing a view with the network
provider as a dependency.
The Zip file format is now 32 years old. You'd think being 32 years
old the format would be well documented. Unfortunately it's not.
I have a feeling this is like many file formats. They aren't
designed, rather the developer just makes it up as they go. If it
gets popular other people want to read and/or write them. They
either try to reverse engineer the format OR they ask for
specs. Even if the developer writes specs they often forget all the
assumptions their original program makes. Those are not written down
and hence the spec is incomplete. Zip is such a format.
Putting images on websites is incredibly simple, yes? Actually, yes,
it is. You use and link it to a valid source in the src
attribute and you’re done. Except that there are (counts fingers)
927 things you could (and some you really should) do that often go
In this post, I’ll summarize what I’ve learned from an attempt to
gain a deeper understanding of two important concepts in
continuation. The aim
is not to teach Python or Scheme programming. Rather, what I want to
do is to demonstrate that generators are special cases of a much
more powerful construct - continuations. Continuations allow
programmers to invent new control structures, and it is the
foundation upon which iterators, generators, coroutines, and many
other useful constructs can be built. I have found it very useful to
understand how generators work from the deeper and broader
perspective of continuations.
This weekend I was talking with a friend about how I'd planned and
estimated a huge software project in one of my previous jobs. By
that I mean not something which can be done by a single team in a
sprint or two, but something which requires several teams, across
several quarters of effort, involving many other departments of
non-engineering team members.
A couple of weeks ago I wrote a short thread on
about the undying argument Is this really bad UI, or is it just you
who are averse to change? — I’m publishing these observations here
simply because it will be easier to find them and reference them in
Docker is one of the tools that has simplified and eased the
development of applications amongst teams. The application is being
packaged in a container shipped and run giving the developers a
better experience during development, testing, and deployment. This
container is being created using a Docker image where all the
application’s dependencies and runtime information are required to
In recent years, developers have embraced this approach because they
do not need to worry about installing all dependencies on their
system. What is needed is just Docker on their computer.
This article will detail the steps to follow whenever we want to
Dockerize our application with Node.js. With that, we mean to
achieve the smooth development experience Docker provides. This
article will not focus on explaining what Docker is but we will look
at a few reasons why we would want to Dockerize our application.
Don’t. Worker pools are not a great fit for Rust due to its ownership
model. Instead, embrace functional programming and immutable
data. Rust provides simpler to use and more elegant tools: parallel
Iterators and Streams.
After the disappointment of my X1
Nano and learning that all
future Intel “Evo”-branded laptops would lack S3 suspend, I started
thinking about returning to my M1 MacBook full-time or building an
OpenBSD desktop. I chose the latter, building my first desktop
machine in many years.
I publish Perl stories on this
blog once a week, and it seems every time there’s at least one
response on social media that amounts to, “I hate Perl because of
its weird syntax.” Or, “It looks like line noise.” (Perl seems to
have outlasted that one — when’s the last time you used an acoustic
modem?) Or the quote attributed to Keith
Bostic: “The only language that looks the same
before and after RSA encryption.”
So let’s address, confront, and demystify this hate. What are these
objectionable syntactical, noisy, possibly encrypted bits? And why
does Perl have them?
The best case depth for a search tree is O(logbn),
if b is the arity (or branching) of the tree. Intuitively, we know
that if we increase b, the depth goes down, but is that all there
is to it? And if not, how do we chose the optimal branching b?
Many git tutorials focus on a set of commands and instructions to
“get you up to speed” in git, without addressing the underlying
concept of “how git works”. While the commands are important, I
feel it’s more important for you to understand what’s going on
behind the scenes.
My last post on this topic
caught some attention, so I’m going to continue exploring some of
the systemd features that may be useful to people writing network
services. Here are some more things about socket activation I didn’t
cover in the previous post.
Firstly, it’s not something that needs a binding to a specific
library to work (although systemd does make one available for this
task). It uses conventions that already exist in Unix, and have done
for a long time. The network sockets are presented as file
descriptors, and some information about them as environment
On many Linux systems, systemd-journald runs as a daemon at boot and
collects your logs. You can access them through journalctl but it
turns out journald is a lot more complicated then just sending
something to a text file. I’ll look at two main things here: What
kind of information is included in a journald entry and how these
entries get from programs to journald.
It's often said that the internet has democratized education: the
sum of human knowledge is only a Google search away! And yet, having
access to information is only half of the story; you also need to be
able to convert raw information into usable skills.
Many people have contributed to developing and promoting the use of
regular expressions since they were invented about half a century
ago. Here's a short list of some of the most influential people
behind the technology. I've written this up for two reasons:
For people who've only gotten into the technology recently but
are interested in some of the history and pioneers behind it.
Since I fit the above description, I'm hoping readers will help
fill me in on other people I've forgotten about or otherwise left
Most of the time you can get away with a fairly simple security
posture on NixOS. Don't run services as root, separate each service
into its own systemd units, don't run packages you don't trust the
heritage of and most importantly don't give random people shell
access with passwordless sudo.
Sometimes however, you have good reasons to want to lock everything
down as much as humanly possible. This could happen when you want to
create production servers for something security-critical such as a
bastion host. In this post I'm going to show you a defense-in-depth
model for making a NixOS server that is a bit more paranoid than
usual, as well as explanations of all the moving parts.
I’ve sometimes seen people asking about dependency management,
hooks, tracking bugs and other sort of higher level (to me) things
than git provides. You can see this if you look at stackoverflow
questions about submodules. What’s wrong with submodules? Well,
compared to what exactly? When I do a clone of a project and run
yarn install, it gives me a list of CVEs that match. When I do a
bundle exec it loads my project and has an opportunity (with a very
high level of context) to tell me that I’ve forgotten to run
migrations or run yarn update in a while. You don’t get this with
git. Maybe these examples are too web-tech specific. But I’d like to
suggest that this pattern will probably apply to Go, Rust and
whatever else. Git is below your project and your project is trying
to get better stuff done. So stop trying to solve your problem with
Git and listen to how a few other communities do their thing.