Agentic coding

AI has definitely transformed a lot of industries and software development is not spared. While this technology is still young and changing, some standards are now emerging. Agentic code editors Most IDEs now make use of AI models, either directly or via extensions, to provide powerful features and enhance the development experience. VSCode has been the standard for a long time and is still extremely popular, but the rise of AI helped changing the landscape. Cursor is one of those, but to me Zed is the most innovative (several IDEs are VScode forks, this one is built from the ground up).

4 min read

Containerized development on Fedora Silverblue

After some time developing containerized applications, I made a habit of trying to run everything in containers. The ability to sandbox applications allows me to keep control over my system and makes me confident to try and discover new software. In this post I show the tools I use to create disposable development environments and to keep my system tidy. Development Containers Quoting the website, Development Containers “allows you to use a container as a full-featured development environment”, bringing the benefits of containerization to software development. Basically you can start using a development container by adding to your project a .devcontainer.json file as simple as:

4 min read

Advanced flag parsing in standard Go

Over time, a plethora of libraries were developed to build complex CLI applications; spf13/cobra and urfave/cli being probably the most used ones (both have tens of thousands stars on GitHub). While they offer lots of features out of the box, I often found them complex and overkill for my needs. In this post, we will have an overview of how Go’s flag works and see some advanced uses of it. We will then try to implement parsing of complex values such as comma-separated arguments or slices.

4 min read

Making sync package type strict using Go generics

The sync package from Go’s standard library provides primitives (Mutex, WaitGroup, …) to help solving synchronization problems. This is an older package and some of the implementations could be different if the generic features were available then. Indeed, the sync.Pool and sync.Map facilitates concurrent usage for storing and retrieving data in different situations. Those features are pretty elementary and their functionality highly relies on the fact that they can be used with any type, which comes with a few drawbacks. Giving up the type strictness prevents the compiler to detect potential errors or requires type assertion code. The former implies extra attention when writing code and the latter reduces its simplicity and readability.

4 min read

Must pattern in Go and a generics-based generalization

There is a handy code pattern commonly found in Go codebases, known as Must pattern. To put it simply, for a given Do function returning at least an error, the MustDo function then omits returning the error, panicking instead. For instance: // package regexp func Compile(expr string) (*Regexp, error) func MustCompile(expr string) *Regexp // package netip func ParseAddr(s string) (Addr, error) func MustParseAddr(s string) Addr In contexts where errors are unlikely to happen, it is a nice way to still handle them while uncluttering the code. Of course this implies the application of the same good practices as when using panic. Those functions are often used to create constant-like objects, such as regular expressions:

2 min read