There’s isn’t a universal answer to the best way to balance
development velocity against technical debt. Thinking of debt as
something taken on intentionally by a team to increase their
short-term velocity at the expense of future work is an easy to
apply strategy that has many benefits to engineering teams while
also simplifying the concept for less technical individuals. By
measuring accrued debt against long-term baselines and ceilings,
engineering managers can get a feel for how much this debt is
impacting their teams, and this data can be used to aid in
prioritization decisions and high-level discussions with
stakeholders.
If your goal to to increase your teams' overall development velocity
in the long term, remember that you may want to slow down so that
you can move fast.
After growing frustrated by various fuzzy finders not being as
accurate as I expected, I designed a new fuzzy finder called
zf. I have mentioned zf in
passing many times, but until now I haven’t taken the time to write
about it in detail. In short, zf is a new terminal fuzzy finder with
a ranking algorithm designed specifically for filtering
filepaths. It has been rewarding to develop and use, and perhaps
you will enjoy it too!
Even with all the great tools we have, getting a macOS application
written in Python all the way to a production-ready build suitable
for end users can involve a lot of esoteric trivia.
Supply chain Layers for Software Artifacts
(SLSA) is a framework of tools to generate and verify provenance for
software artifacts. In the Python ecosystem there are two main types
of software artifacts: wheels and source distributions.
How can we use the SLSA framework to generate and verify the
provenance of Python artifacts?
Structured logging involves producing log records in a well-defined
format (usually JSON), which adds a level of organization and
consistency to application logs, making them easier to process. Such
log records are composed of key-value pairs that capture relevant
contextual information about the event being logged, such as the
severity level, timestamp, source code location, user ID, or any
other relevant metadata.
This article will delve deep into the world of structured logging in
Go, with a specific focus on recently accepted slog
proposal which aims to
bring high performance structured logging with levels to the
standard library.
The other day I was pondering on the prevalence of single-method
interfaces (SMI) in Go, and what makes them so effective and
useful. SMIs have proven to be a very successful software modeling
tool for Go programmers, and you find them all over Go code-bases.
I tried to think about the fundamentals, which brought me to some of
the earliest roots of our trade: functional programming and
higher-order functions (HOF). I discussed some examples of applying
higher-order functions in Go
recently.
This post will describe how SMIs are a more general and powerful
technique than HOFs. It makes the following claims:
If ever there were two programming languages said to be at odds with
one another, it might be Haskell and C. But this is not so true as
it seems; they can play quite nicely with one another. Haskell’s
foreign function interface lets us write Haskell code that uses
libraries of other languages — notably, C.
As a brief introduction to how Haskell FFI works, I’ll be talking
about my memfd package,
which is available on Hackage.
Rust’s rules on temporary lifetimes often work well but have some
sharp edges. The 2024 edition offers us a chance to adjust these
rules. Since those adjustments change the times when destructors
run, they must be done over an edition.
A functor between two categories (let’s call them A and B)
consists of two mappings - a mapping that maps each object in A
to an object in B and a mapping that maps each morphism between
any objects in A to a morphism between objects in B, in a way
that preserves the structure of the category.
I’ve had the pleasure of having had to analyse multi-gigabyte JSON
dumps in a project context
recently. JSON itself is
actually a rather pleasant format to consume, as it’s human-readable
and there is a lot of tooling available for
it. JQ allows expressing
sophisticated processing steps in a single command line, and
Jupyter with Python and
Pandas allow easy interactive analysis
to quickly find what you’re looking for.
Daniel Lemire's recent post "runtime asserts are not
free"
looks at the run-time cost of assert statements in C and shows
that a simple assert in a frequently executed loop can cause
significant overhead.
My own opinion on assertions has shifted over the years, from "I
don't see the point" to "use them sparingly" to "use them as much as
possible". That last shift is largely due to Rust having two kinds
of "assert" statement – assert and debug_assert – which has
allowed me to accurately express two different kinds of assertions,
largely freeing me from performance worries. If you come from a
language that only has one kind of assert statement, this
distinction can seem pointless, so in this post I want to briefly
explain why it helped shift my thinking.
Very often during development, it is useful to run your code in a
scenario that is as near to a final deployment as possible, but not
in some cloud environment where it’s hard to change specific parts
without going through the full CI/CD chain. I find it very useful to
quickly build, run, iterate, rebuild, and rerun VMs with NixOS Linux
on my development machines. This week I demonstrate this aspect of
my workflow with NixOS.
I recently read an excellent post by Manu Moreale titled A rant on
web font
licenses. I
highly recommend you give it a read (it's relatively short) since
Manu makes a solid argument against existing font licenses. After
reading, I found myself thinking about it throughout the rest of the
day.
I was trying to understand how we ended up in a situation where
web/UI designers (myself included) have started to insist on using
proprietary, custom web fonts. Do any users actively benefit from
custom web fonts? Are there any useful and measurable goals
achieved by including them? Do end-users actually care about a
website's typeface?
For the most part, I believe the answer to all those questions is:
not really.
There’s a cold familiarity to them; you know what they’re good for
and what they’re not, and despite their age, they remain largely the
same as how you left them. In software, there aren’t a lot of
tools that are allowed to get old. I feel like the default state
is just a drop-off into obscurity.
But Django got old! Its twentieth birthday is almost here. I
suppose that means Django has entered adulthood now, though 20ish
years in software probably puts it more toward seniorhood than
anything. When I stare at a CRUD-style use case, Django remains my
default impulse. With the rise of stripped-down JS frameworks like
HTMX, I thought it’d be exciting to pull out the crusty knives,
sprinkle in some new JS goodness and explore the landscape. What
follows in this article are my thoughts and lessons along the
way. Enjoy!
It is a truth universally acknowledged that the Python packaging
ecosystem is in need of a good dependency checker.
In the least, it’s our hope to convince you that Tweag’s new
dependency checker, FawltyDeps, can help you maintain an environment
that is minimal and reproducible for your Python project, by
ensuring that required dependencies are explicitly declared and
detecting unused dependencies.
If you work with Python, and care about keeping your projects lean
and repeatable, then this is for you.
In this post, we will discuss recent results from Immunant and
Galois in extending C2Rust to emit memory-safe Rust in certain
cases. With this work we aim to shift a meaningful part of the
translation burden from the human to the machine. Up until now,
C2Rust has only been able to translate C to unsafe Rust that is no
safer than the original input C code. Although this provides a
starting point for manual refactoring into idiomatic and safe Rust,
this work had to be done by the human. By using a combination of
static and dynamic analysis, the current in-development version of
C2Rust can now perform some of the lifting to safe Rust
automatically. This post describes how this analysis works and how
we are using it to make it easier to translate unsafe C programs
into memory-safe Rust.
When we talk about a web service, we, more often than not, mean
deployed code which listens on a certain IP address and port and
responds to HTTP messages. There are many steps involved for two
parties to be able to communicate with each other. Application
developers are mainly confronted with two pieces of this process:
TCP and HTTP.
Ah util, the ubiquitous fixture of practically every project since
the invention of code.
I spent my early years programming expecting a util package in
every project, oftentimes being the one to create it myself. It
wasn’t until my third job out of school that I ran into someone who
had an allergic reaction to the addition of one and argued strongly
against it.
The kingdoms of Belleger and Amika had been fighting for
generations. But then they learned of a terrible threat moving
through them to destroy the Last Repository, an immense hidden
library. To face this greater enemy, King Bifalt of Belleger and
Queen Estie of Amika allied their lands and prepared for war.
They are at the door.
Now the time of preparation is over. Black ships and sorcery test
the cannon that defend the Bay of Lights. Treachery and betrayal
threaten the kingdoms. The priests of the Great God Rile sow
dissent. And Estie rides for the Last Repository, desperate to
enlist the help of their Magisters-and to understand the nature of
her own magical gift.
They are here.
Bifalt hates sorcery as much as he loves Estie, and the discovery
that she could become a Magister shatters him. But he must rally and
fight. Belleger and Amika are all that stand between the Great God's
forces and his ultimate goal: the destruction of the Last Repository
and its treasure of knowledge.
In the evening I started in The Killing
God,
the 3rd book in The Great God's War trilogy by Stephen Donaldson.