newsletter
-
I configured different note types to show in different colors. Zettelkasten has a few different kinds of notes, and quickly being able to see, by color, which it is, has been helpful.
-
I added the ability to change the order of notes. This was needed to be able to create structure notes with links in specific order.
-
I added the ability to give links a text description. This is what allowed me to experiment with articulating how two ideas relate to each other. I wrote more about the evolution of this feature in Linking (and how it has evolved) in Smart Notes.
-
I documented how I did a redirect to my old archived site for pages that I have not yet migrated to the new blog in Poor man’s redirect in a static site.
-
I started a “photo blog” documenting my runs and how my life improves from them.
-
Micro.blog makes it easy to create a website that feels like a home.
I can share and develop my interests. I can structure content with categories and pages. Others can come have a look. Comment if they wish. And you can see conversations that I’ve had with visitors.
-
It makes blogging fun. It is easy to publish and you can get comments from the community on your posts.
Newsletter November 2024: A New Project
Compared to last month, this month I did some programming in my spare time. I had fewer commitments, and my mind started thinking about various programming projects. We also got the first snowfall of the season and I got to enjoy a run in it:
A New Code Editor
The programming project that I started working on is code editor that is a mix of a text editor and a structured editor. It is all text, but parsers and pretty printers allow you to work with a tree structure and not think too much about syntax. The code is available on GitHub, and here is what it looks like when editing a JSON document:
I got the idea for this project when trying out Black. Black automatically formats Python code for you so that you don’t have to think about it. I’ve been interested in structured editors for some time, but my feeling is that they are not user friendly because they limit what you can type. Then I came up with this idea of an editor that constantly parses what you type. If the parse is successful, it pretty prints it for you and provides you with edit operations on the AST. But it is all still just text, so you can type whatever. In the worst case, the parse fails and you have to fix it manually.
So far, it looks quite promising. And most importantly, I’m having fun experimenting. The most likely scenario is that the project will not be a success, but I will learn something and have fun doing so. But you never know. One day, one of these projects just might turn into something that is invaluable.
TDD
This month I also watched a presentation by Kent Beck called TDD: Theme & Variations. For me, it was a nice refresher on the origins of TDD.
One thing that I appreciate with TDD, that I partially had forgotten, is how it reduces anxiety. Kent reminded me of it in the presentation. When all tests are passing and you can’t think of any more tests to write, you are done, and you know that it works. That reduces anxiety a lot.
Newsletter October 2024: Primitive Obsession?
Normally I do something related to programming in my spare time every month. I read something that I find interesting and want to share. Or I have some thought related to programming that I want to share. This is the first month since I started these monthly updates in June 2019 that I’ve got nothing of that. I’ve been occupied with other things, and I’ve also done quite a bit of programming at work. Perhaps that has satisfied my interest for programming.
One thing that I’ve done a lot at work this month is wrapping simple data structures in classes. Instead of passing around lists and dictionaries, I’ve created classes holding that data and only serialized it at the edges of the application. Every time I have done this, I wish I had done it sooner. It’s so good. And in nine times out of ten, those classes have attracted some functionality that fits perfectly. They have provided one place to put functionality instead of scattering it throughout the codebase.
What am I talking about? Let me give an example.
Imagine that we talk to a user service that has an API something like this:
service.get_all_users() -> ["user1", "user2"]
service.set_users_in_group("group1", ["user1", "user2"]) -> OK
The API works with users represented as list of strings. Now we want to write a function that applies some domain logic to assign users to groups. It is so easy and tempting to write something like this:
def update_r_users(service)
r_users = []
for user in service.get_all_users():
if "r" in user:
r_users.append(user)
service.set_users_in_group("users_with_r_in_name", r_users)
One problem with this code is that it mixes calls to the user service with domain logic, so is is difficult to test domain logic without invoking the service. It’s also more difficult to reason about.
What if we instead did this:
def update_r_users(service)
service.set_users_in_group(
"users_with_r_in_name",
Users.from_service(service.get_all_users()).filter_name("r").serialize()
)
class Users:
@classmethod
def from_service(cls, users):
return cls(users)
def __init__(self, users):
self.users = users
def filter_name(self, text):
return Users([
user
for user in self.users
if text in user
])
def serialize(self):
return self.users
This is what I mean by wrapping simple data structures in classes. Why is this better?
First of all, I think update_r_users
now reads a lot better. The filtering
logic is no longer mixed with the calls to the service.
This comes at the cost of writing the Users
class which is quite long
for the relative functionality that it provides. In the beginning, I often find
it hard to motivate myself to write these classes. It feels like a lots of
boilerplate code for not much benefit. However, I often find that these
sort of classes attract functionality, at which point they start to become
more useful.
Another thing that they do is encapsulate the data format from the user service. Say that the API of the service changes. There is now more information about users:
service.get_all_users() -> [{"name": "user1", "age": 21}, {"name": "user2", "age": 43}]
service.set_users_in_group("group1", ["user1", "user2"]) -> OK
We can update the User
class accordingly:
class Users:
@classmethod
def from_service(cls, users):
return cls(users)
def __init__(self, users):
self.users = users
def filter_name(self, text):
return Users([
user
for user in self.users
if text in user["name"]
])
def serialize(self):
return [user["name"] for user in self.users]
The update_r_users
stays the same. We control the API of Users
. Our
application can safely depend on it. And we can change the internals.
I couldn’t find a name for this sort of pattern. My first though was that it was a way to avoid primitive obsession. And it is. But it feels like more than that. Bill suggested that it might be just “good old encapsulation”. Dan said that it depends on the context and that it could be an anti-corruption layer in DDD terms. What would you call it?
Anyway, I’ve been doing this sort of thing a lot this month, and I thought it was worth sharing.
Newsletter September 2024: Bash Redirects and Reading
This month I read How to Use a Zettelkasten to Write Stories Packed with Emotion. It inspired me to write something using that technique. The topic that came to mind was Bash redirects. It resulted in the blog post Bash Redirects Explained.
I also started reading How Children Learn by John Holt. He says that children are naturally interested in exploring the world. I started thinking about what environments kill exploration. I though that fear of doing something wrong will discourage exploration. Then I made a parallel to a common practice in software development: pull requests. I thought that pull requests discourage experiments because changes can only propagate after approval, and the idea behind pull requests is to only approve “good” changes. First of all, the learning opportunities of mistakes are gone. Second of all, you might loose interest in experimenting because you are afraid of making a mistake. You build a culture of discouraging making mistakes. I though that a better approach is to focus on making the cost of mistakes small so that we can do lots of them and learn from them.
I also read Debugging Teams by Ben Collins-Sussman and Brian Fitzpatrick. They talk about the myth of the genius programmer and that all great things are built by teams. I believe that is true, but sometimes I have a hard time to acknowledge it because I also enjoy working by myself.
Newsletter August 2024: Smart Notes and Blogging
In August I had my last week of summer vacation. I read a book that made me want to improve my note taking tool, I did some programming on hobby projects, and I migrated my blog to a new platform. All while doing many runs.
A System for Writing
I read A System for Writing by Bob Doto. This review is what made me buy the book:
When I first tried to get my head around Zettelkasten, I consulted Sönke Ahrens’ extremely useful book How to Take Smart Notes. This was—and still is—seen as the book to read on the subject. I predict A System for Writing will replace it.
I liked Sönke’s book, and I was curious to learn more about this topic from a source that seemed credible.
I got some new insights about the Zettelkasten method. In particular the idea that it is important to articulate how two ideas relate. I’ve previously mostly connected ideas without context. The connection was obvious when I made it, but most likely less obvious when I come back to it.
I tried to research this a bit more and found the article Backlinking Is Not Very Useful – Often Even Harmful:
A good link context explains what you can expect if you follow the link. But it can also explain the nature of the relationship between both notes.
I wanted to try this out.
Smart Notes
I use my Smart Notes app to take notes using the Zettelkasten method. When I studied the method more, I got some new ideas that I implemented:
One-File Programs
I continued to work on One-File Programs.
I worked on an engine app that can automatically reload other apps when they change. This gives faster feedback, especially when working on graphical applications. It is similar to an approach I’ve written about previously in How to get fast feedback on graphical code?
I also worked on the no scrollbars app. I wanted to see if we can get rid of scrollbars in some GUI elements. The idea is to make items larger around the area of the mouse so that they can more easily get selected. Here is one screenshot:
I want do continue work with this repo, but the rest of the time this month, I spent on my blog.
Micro.blog
I found out about Micro.blog and moved my blog to it.
Some reflections on Micro.blog:
Newsletter July 2024: Note Making Re-Visited
This post has not yet been imported to my new blog.
In the meantime, you can read it here: http://archive.rickardlindberg.me/writing/newsletter/july-2024/.
Newsletter June 2024: Quines and Smalltalk
This post has not yet been imported to my new blog.
In the meantime, you can read it here: http://archive.rickardlindberg.me/writing/newsletter/june-2024/.
May 2024 Update
This post has not yet been imported to my new blog.
In the meantime, you can read it here: http://archive.rickardlindberg.me/writing/newsletter/may-2024/.
April 2024 Update
This post has not yet been imported to my new blog.
In the meantime, you can read it here: http://archive.rickardlindberg.me/writing/newsletter/april-2024/.
March 2024 Update
This post has not yet been imported to my new blog.
In the meantime, you can read it here: http://archive.rickardlindberg.me/writing/newsletter/march-2024/.
February 2024 Update
This post has not yet been imported to my new blog.
In the meantime, you can read it here: http://archive.rickardlindberg.me/writing/newsletter/february-2024/.
January 2024 Update
This post has not yet been imported to my new blog.
In the meantime, you can read it here: http://archive.rickardlindberg.me/writing/newsletter/january-2024/.
December 2023 Update
This post has not yet been imported to my new blog.
In the meantime, you can read it here: http://archive.rickardlindberg.me/writing/newsletter/december-2023/.
November 2023 Update
This post has not yet been imported to my new blog.
In the meantime, you can read it here: http://archive.rickardlindberg.me/writing/newsletter/november-2023/.
October 2023 Update
This post has not yet been imported to my new blog.
In the meantime, you can read it here: http://archive.rickardlindberg.me/writing/newsletter/october-2023/.
September 2023 Update
This post has not yet been imported to my new blog.
In the meantime, you can read it here: http://archive.rickardlindberg.me/writing/newsletter/september-2023/.
August 2023 Update
This post has not yet been imported to my new blog.
In the meantime, you can read it here: http://archive.rickardlindberg.me/writing/newsletter/august-2023/.
July 2023 Update
This post has not yet been imported to my new blog.
In the meantime, you can read it here: http://archive.rickardlindberg.me/writing/newsletter/july-2023/.
June 2023 Update
This post has not yet been imported to my new blog.
In the meantime, you can read it here: http://archive.rickardlindberg.me/writing/newsletter/june-2023/.
May 2023 Update
This post has not yet been imported to my new blog.
In the meantime, you can read it here: http://archive.rickardlindberg.me/writing/newsletter/may-2023/.
April 2023 Update
This post has not yet been imported to my new blog.
In the meantime, you can read it here: http://archive.rickardlindberg.me/writing/newsletter/april-2023/.