Latest Posts (11 found)

Front page

I have not had a huge success with my writing in this blog so far. I don’t collect any analytics 1 , so I am not sure exactly how each post fares, but based on the amount of comments I have received in the various platforms I have shared my posts, the traffic must not be very high. This has not discouraged me from writing. My goal is to share projects that I am developing and to express some of my thoughts when I feel like it. I am glad if someone finds the content interesting and I am even happier to engage anyone who sends a comment my way. In any case, I think that the mere act of sitting down and writing your thoughts is beneficial by itself and it is worth doing, even if the audience is not there. It is true, though, that it feels nice when people accept what you are offering. And two days ago, I finally got my first breakthrough. I shared my last post on Hacker News and it reached the front page . I admit it was satisfying to see that a lot of people approved of the message and wanted to share their own opinions. I spent the next day or so participating in the discussion and digesting all the new information that was available. One of the main themes of the discussion was user interface accessibility. It is a part of software development that is of great interest and importance and I hope to more systematically approach it in my programming and my writing in the near future. The whole experience was positive. I do not claim to be a great writer, nor that my post proclaimed some profound truth, but it was gratifying to see that an extended discussion was started because of something I wrote. As a result, I now am a little braver to share my thoughts with the world. I think they can create bad incentives for content creation.  ↩ I think they can create bad incentives for content creation.  ↩

0 views

GUIs should be fully keyboard-driven

This post has made it to the Hacker News front page. See the discussion . Last week I came across a post on Hacker News that encouraged application developers to stop making terminal user interfaces 1 (a.k.a. TUIs) and instead focus on graphical user interfaces (a.k.a. GUIs). The post reached the HN front page and sparked a lively debate in the comments section. I think there is merit in both sides of the debate. On one hand, I understand the GUI-positive arguments of the post author. In theory, the capabilities of GUI application frameworks are a superset of the capabilities of their TUI counterparts, so they should be preferred. On the other hand, as a heavy terminal user , I also greatly appreciate all TUIs that allow me to “stay” in the terminal and fulfill all my needs. But I want to oppose a recurring argument in favor of TUIs that in my opinion does not have a solid foundation 2 . To paraphrase various commenters: TUIs should be preferred because they are keyboard-driven. While it’s true that if you randomly pick a GUI and a TUI application, the latter is more probable to be fully keyboard-driven, this does not tip the scale in favor of developing TUIs over GUIs 3 . What it does is highlight the inadequacies of keyboard navigation in many GUI applications. There is nothing preventing a GUI from being fully keyboard-driven 4 just like — or even better than — a TUI. In fact, many GUI framework application guidelines explicitly encourage GUI application developers to provide support for keyboard-driven navigation that covers the whole functionality of the application. For example, the GNOME Human Interface Guidelines state that just as it should be possible to perform every action with a pointing device, every action should also be possible with the keyboard and that it should be possible to move around and interact with every part of your user interface using the keyboard . This resonates with me as a user. Being able to intuitively — and predictably — navigate around a GUI application with only my keyboard gives me more incentive to choose it compared to its alternatives. Knowing that, and when wearing my developer hat, I have to make sure that my applications are keyboard-friendly. For my first ever GUI application, Klisi , I invested some time to implement keyboard shortcuts targeting the whole range of available actions. Keyboard navigation is not that hard to achieve in most cases and results in an overall better user experience. It is not a matter of feasibility, but a matter of will on the application developer’s part. The takeaway is simple. Do not compromise on the user experience you provide with your application. Strive to make it as intuitive as possible. To that end, enabling full keyboard navigation should not be ignored. Or alternatively text-based user interfaces .  ↩ The original post author mentions this as well.  ↩ There are other more compelling arguments towards tipping that scale, for example ease of portability.  ↩ Of course, the dexterity achieved via mouse is still preferred — or even required — for some tasks.  ↩ Or alternatively text-based user interfaces .  ↩ The original post author mentions this as well.  ↩ There are other more compelling arguments towards tipping that scale, for example ease of portability.  ↩ Of course, the dexterity achieved via mouse is still preferred — or even required — for some tasks.  ↩

0 views

New font

I saw the iA Writer Quattro font and I liked it. So far, I was not explicitly using a font-family for this website and instead relied on the default sans-serif font provided by the browser. I thought it is time to change that and present a more unified experience for all readers. What do you think?

0 views

Klisi

From Ancient Greek κλῆσις (klêsis), related to καλέω (kaléō, “I call”). After around 3 months of effort, I have finally released the first version of Klisi . Klisi is the result of a desire to fill a small gap in the available application offering for the GNOME desktop environment and a recent interest in the Clojure programming language. I wanted to develop a callgrind profile viewer that better integrates with GNOME and can be used as a simplified alternative to KCacheGrind . Have you heard enough already? Install and try out the application. You can come back for the rest of the write-up and leave a comment with your thoughts. It all started around one year ago. After more than 7 years of using i3 as my window manager — through the end of my university years and the start of my professional career — I decided that it was time to embrace Wayland . The obvious choice would be to continue using another tiling window manager. sway would be the prime candidate. But I was also eyeing a more complete solution. Tiling window managers are great, but they require a lot more manual configuration to have a fully functioning system. I am grateful for what I learned in the process, but I was ready to off-load some of that work to someone else. So, I switched to GNOME. I had always liked the aesthetics of its applications, so having them integrate natively with the whole environment appealed to me. I had also noticed that I could translate my i3 workflow directly to GNOME without any significant changes. I was already using most windows maximized and delegating to tmux for my terminal tiling needs. Scriptability is a little trickier in GNOME than in i3, but GNOME would handle most of my needs now anyway. This was last November. Some time after that — in April — I saw on Hacker News the announcement for the Clojure documentary . People seemed excited about it, so I decided to watch it. Going in, I had zero knowledge about Clojure. I did not know anything about Rich Hickey . I did not know anything about the philosophy of the language. I had only read about it in various post titles, but had never gotten down to study it and use it. The documentary was engaging enough and it piqued my interest. I wanted to try to learn another functional programming language after previous Haskell adventures and this seemed like a nice opportunity. Clojure being a Lisp dialect made the whole premise even more appealing. I started by reading all beginner-friendly documentation on the official website and then went over Clojure for the Brave and True trying to be as hands-on as possible. I was ready for the next step. They say one of the best ways to learn and understand a programming language is to use it in a project. And this is exactly what I did. I set out to combine Clojure and GNOME application development. On the 2nd of May, I made the first commit of Klisi. At the time, I had not yet settled on a name and I was only able to launch an empty GTK window. Today, the application can do a little more. After a long development list, consisting of required features and other ideas that came to my mind while developing, I believe it is good enough to serve other people. This brings us to today and the first release. It was time to share my application with the world. I hope that someone will find it useful and decide to make it a part of their development workflow. In any case, I am very satisfied by the result so far. I have learned a lot and I will continue to do so, while I further explore Clojure, GTK and Flatpak development. There is a long way to go and I believe all the lessons I will learn in the process will be valuable one way or another. This is it from me for now. Try out Klisi and let me know what you think. I will appreciate any well-meaning feedback.

0 views

New address, new adventures

I had been thinking of buying my own domain to host this website for a while. I was always putting it off, since it was not a priority or a strict necessity. But, lately, I reached a tipping point. I have been working on a side project that requires setting an application identifier. From the beginning I knew that I wanted to go with and not share “naming custody” with GitHub. You don’t really need to own a domain to use it as part of an application identifier, but it makes verification with some platforms possible. So, I bit the bullet and moved forward with my plans. is now live . The whole process was quite quick. It took a couple hours reading the required documentation and setting everything up. I registered the domain via porkbun . I verified the new domain for GitHub Pages to avoid any future surprises and added any additional DNS records needed. I created a second static website repository on GitHub and pushed the existing repository to it. As the first order of business (i.e. first commit) I made sure to fix any “stale” links pointing to the old domain to now point to the new one. Finally, I edited the old static site to redirect to the new one automatically and that was all 1 . UPDATE : It turns out I did not read the GitHub Pages documentation carefully enough. Creating the second repository and the manual redirects were not needed. By setting the custom domain in the original repository, GitHub handles the redirects from the default domain (i.e. ), while properly returning the status code in the process. This was my first ever domain purchase and I have to say everything went quite smoothly, so I am satisfied. That’s all for now. Watch this space for my side project update. See you soon. Reading online I got the understanding that a proper redirect emitting the status code would be preferable in order to preserve any search engine ranking that I had. But, honestly, I don’t think that will prove to be much of an issue.  ↩ Reading online I got the understanding that a proper redirect emitting the status code would be preferable in order to preserve any search engine ranking that I had. But, honestly, I don’t think that will prove to be much of an issue.  ↩

0 views

The P in PGP isn’t for pain: encrypting emails in the browser

In my previous post, I described how I implemented an asynchronous, email-based comment system for this blog that runs without a true backend. Every comment is an email sent to a specified address. After each email is processed, all information is stored publicly in a GitHub repository. One of the limitations of such a system is user authentication. Each user needs to send a password alongside each comment that serves to authenticate the user against their email. This is needed because email spoofing is a thing and identity theft is not a joke; even if the stakes are low in the context of blog comments. In that previous post, I acknowledged that sending a password in plain text via email is not best practice and I encouraged the usage of encryption. For this purpose, I provided a public PGP key that can be used to encrypt any email and can only be decrypted by me, the owner of the secret key. The problem with this suggestion is that, even though it’s technically sound and legitimate, it is not straightforward to set up. Many email clients do not even support PGP encryption and, dare I say, even most technical people do not have it set up by default. For non-technical users, configuring everything properly would certainly be a test of computer literacy. This is not good enough, and certainly not welcoming or inclusive. Shortly after I published the first version of the comment system I came up with a question. I already have a public PGP key published and ready to be used. Is there a way to encrypt the comment payload on the browser, including the password and all other data? I wouldn’t be writing this post if the answer was negative. After a quick web search, I came across openPGP.js , a JavaScript library maintained by the Proton team . The goal of the library is to “bypass the PGP installation requirement in every machine” . Just perfect for my use case. I quickly set everything up. I downloaded the JavaScript library files at the root of my website and created a couple of helper functions. The first to load the library on-demand to avoid unnecessary network transactions and the second to produce a PGP encrypted message from a plain text string input. It’s simple. And it works. Note: The comment encryption functionality is not available if JavaScript is disabled on the client. For example, if you were to write a comment for this post using the comment form and provided the following data: the email to be sent would be pre-filled with the following body: Your comment data (username, password, message, etc.) is automatically encrypted without any need for manual intervention. Based on the above proof of concept, I can say that, even without operating a “proper” backend server, it is still possible to guarantee a reasonable level of security. And you can do so without requiring any complicated setup on the user side. To my eyes, this is a win for secure communication when email is used as the medium. Do you agree?

0 views

My comments run on email

Not all blogs support commenting. Initially, I considered doing without them. There are many places where one may share an article or blog post and start a discussion. I frequent Hacker News 1 myself and I really appreciate the breadth of opinions in some of the discussions. Discussion can happen in other spaces as well, like Reddit , LinkedIn 2 and many more. Despite the abundance of such spaces , where discussions can happen, I think it is convenient and fitting — especially for blog posts — when the actual post and the readers’ comments live together. With that in mind, and feeling the urge to hack a little more on my website , during the past weekend I set out to add support for comments in this blog. Doing so in a static blog poses a big challenge . There is no actual server running that can handle requests and process data. That means that you do not have the necessary infrastructure for user accounts. The readers cannot log in and send their comments and there is no straightforward way to take those comments and automatically post them online. Another method is therefore needed to receive the comments and provide them as input to the static site generator, in my case jekyll . One of the most frequently used solutions to this problem is giscus . giscus is utilizing GitHub discussions to store comments for the different blog posts and can be configured to automatically update your website when a new comment is created. This approach is very appealing, but it has one disadvantage in my opinion. The person who wants to comment needs to have a GitHub account. This can be a blocker for non-technical people. I wanted to use a different approach and I also wanted to make commenting accessible to as many people as possible. After some thinking I decided to use the most common technology I could think of. Almost everyone using the internet has an email address. By basing my comment system on email, I can make it accessible to a wide range of people. The fact that every email address is unique allows to implement a kind of primitive authentication setup. I am saying primitive, because email is not secure by default, and by extension neither is any system built on top of it. It goes without saying that this system could never be used in production in security-sensitive environments. That said, crazier things have happened. At this point, it would be useful to go in a little more detail. If you are not interested in the technical aspects of the comment system implementation you can skip this section and go straight to the end . You will miss all the fun, though. So, how does it all work? Before implementing the comment system, I drafted some requirements: The comment system is based on email, so it is logical that you send a comment by sending an email. Every comment email contains all necessary information, so that the comment can be presented correctly. I decided to send the information in the YAML format, since jekyll is YAML -friendly. Additionally, YAML compared to JSON can be more readable for multi-line data, like comments, so it made it more fitting for this use case. Every comment email sends in its body the following information. Sending passwords in plain text is almost always frowned upon. But I believe this situation deserves some leeway. Upon receiving a comment email, some additional information can be obtained: and . Let’s see how we can satisfy the system requirements with these data. All comments should be displayed with a visible name selected by the commenter and the date they were made. For this we use the and information from the actual comment email. A commenter should be able to change their visible name. A malicious actor should not be able to easily assume the identity of a commenter. All information needed to generate this website is publicly stored in a GitHub repository. This means that any personal information needs to be properly stored. For each received comment email a SHA256 message digest ( hash ) is computed using the and a salt 6 . To check name availability, all email hashes that are different from the current one are gathered and their linked name is compared to the requested one. If no matches are found the can be used. An additional message digest is computed for the authentication of the commenter using the , the and the salt . This authentication hash is compared against the authentication hash of one of previous comment emails that share the same email hash 7 . In the event of any error, the commenter is informed with a response email. Sending a comment should be as easy as possible and the comment system should be functional with JavaScript disabled. Commenters with JavaScript enabled can enjoy a streamlined user experience (UX). Clicking on add comment or reply presents them with an HTML form with three input fields: name , password and comment . After filling them and clicking the send button, their preferred email client is launched and the message is pre-filled for them and ready to be sent. Commenters with JavaScript disabled still get a pre-filled email message, but they have to fill the necessary information, while making sure to not break the formatting of the data. Writing a comment using the HTML form with JavaScript enabled has two benefits: Comment replies should be supported and presented in a nested tree structure, which should support collapse and expansion of comment sub-trees. Using the field of the comment email 8 , a tree hierarchy of messages is created. This hierarchy is used to sort the comments properly and to create the necessary logic to collapse and expand the respective sub-trees of comments. We are close to the end, but I have so far failed to mention one basic characteristic of the comment system. And this concerns its responsiveness, or lack thereof. After receiving a comment email, there is, as of now, no automation set up to process the email and post it on the blog. Posting each comment requires manual intervention. This makes the discussion asynchronous. I think that this is not a big issue and does not look out of place considering the static nature of the website. Nevertheless, I leave the door open to automation. Interacting with email is scriptable with programs like msmtp and isync . In the unlikely but welcome scenario that the volume of the received comment emails is too large to handle manually, another weekend hacking project could automate the whole process. Creating a comment system based on email has been a worthwhile experience. I revisited some long-studied concepts and learned new ones. It was a good exercise in balancing trade-offs which I believe is one of the most important aspects of designing a system. The final result leaves me satisfied, while also leaving room for improvements in the future. And after all this work, I can finally say Let me know what you think in the comments. The user interface (UI) of my comments is heavily inspired by HN comments.  ↩ Even if too corporatey most of the time.  ↩ Or nickname .  ↩ Although, you can never be 100% secure.  ↩ Here is the PGP public key .  ↩ Storing message digests of salted data guarantees that, even though all stored data is publicly available, it is not possible to find out which email addresses are stored and what name each email is using.  ↩ If any, the rest of the comments from the same email address have the same authentication hash .  ↩ Root messages, of course, do not set this value.  ↩ All comments should be displayed with a visible name 3 selected by the commenter and the date they were made. A commenter should be able to change their visible name . A malicious actor should not be able 4 to assume the identity of a commenter. Sending a comment should be as easy as possible and the comment system should be functional with JavaScript disabled. Comment replies should be supported and presented in a nested tree structure, which should support collapse and expansion of comment sub-trees. The data transferred is not sensitive and proper care is taken to ensure confidentiality. This is an educational project with no hard security requirements. A password is good to be used as a measure against sender address spoofing . Email can always be hardened by using PGP encryption 5 : Browsers are able to save the name and password fields for the commenter and pre-fill them in the future. The password can be hashed in the email body. This does not improve security, but protects against curious eyes. The user interface (UI) of my comments is heavily inspired by HN comments.  ↩ Even if too corporatey most of the time.  ↩ Or nickname .  ↩ Although, you can never be 100% secure.  ↩ Here is the PGP public key .  ↩ Storing message digests of salted data guarantees that, even though all stored data is publicly available, it is not possible to find out which email addresses are stored and what name each email is using.  ↩ If any, the rest of the comments from the same email address have the same authentication hash .  ↩ Root messages, of course, do not set this value.  ↩

0 views

Techrastination

Have I made up a new word? How do technology and procrastination go together? Hacking with technology and procrastination may seem unrelated, but I believe that in tandem they paint an accurate picture of how lots of people, myself included, interact with technology in their free time. When I am referring to hacking , I intend to convey the original meaning. Wikipedia 1 phrases it quite nicely. The act of engaging in activities (such as programming or other media) in a spirit of playfulness and exploration is termed hacking. However, the defining characteristic of a hacker is not the activities performed themselves (e.g. programming), but how it is done and whether it is exciting and meaningful. The key words in the above segment are: playfulness , exploration , excitement , meaningfulness . I will come back to them shortly. I guess most people are at least vaguely familiar with procrastination . Let’s not mention any definition containing the words laziness or carelessness . I prefer to keep it nice and neutral 2 . The act of procrastinating; putting off or delaying or deferring an action to a later time. And if you are interested in the actual etymology, it can get a little more fun 3 . From Latin prōcrāstinātiō, from prōcrāstinō (“procrastinate”), from prō + crāstinus (“of tomorrow”), from crās (“tomorrow”). What is techrastination then? I will try to give a definition of my own. The act of procrastinating by focusing on the technology associated with an activity rather than focusing on the activity itself. You may have an idea where I am going with this. I am gonna give some examples anyway. The first one is quite relevant. It’s when you spend hours upon hours tinkering with your blog, fixing the theme, checking the fonts, trying to perfect the alignment of CSS elements and the margins of your titles and subtitles, yet you are not working towards creating actual blog posts 4 . It is also when you constantly rework your configuration files and scripts to increase your productivity, when you are not actually working on something that you need to be productive in. Or when you are more interested in the technologies you are using – programming language, stack, tools – and you like to engage in heated arguments with people about them, instead of just focusing on the actual target at hand, whatever that may be. It would be safe to assume that we can think of many more similar examples. I admit I have been guilty of all these to a lesser or greater degree. But, is guilty the right word? Should there be a negative tone when we are describing such activity? Shouldn’t we always try to be as productive as possible? Not really. Let’s go back to the key words of the hacking definition above. Playfulness . Play is not just for kids. Having some amount of play in our lives is beneficial to our well-being . This matches my experience while hacking . When friends or family ask me how I find satisfaction from my computer projects, I usually respond that it feels like playing. Exploration . It is said that repetition is the mother of learning, but I believe that exploration is an equally important part of knowledge acquisition. We don’t have to constantly innovate. But we must test the limits of our knowledge to expand it and savor its benefits in the form of personal and professional growth . Excitement . Who involved with programming and technology in general has not felt immense satisfaction after completing a task? Or even without completing it. Completing the task is not even a requirement. Being in the flow comes with its own set of satisfying emotions. The actual end product does not hold all value. It may not even be that useful, if we were to strictly evaluate it. But this excitement is very important. It encourages further exploration that leads to more play that leads to more excitement. Meaningfulness . Now we are entering tricky territory. So far I have argued that engaging in techrastinating activities can be useful without the need to find an actual meaning. That statement does not have to be betrayed. The actual meaning does not derive from the usefulness of an activity. It comes from the effect it has on the acting individual. If an activity satisfies us, then it is meaningful. All this sounds extremely positive. What about the dark side? I would argue that the dark side is not strictly related to technology activities. Any activity can have a negative impact, when it is exercised without measure and it begins to affect other parts of our life (e.g. relationships or health). A general balance should always be maintained. To sum it all up, hacking with your computer, or actively engaging with technology in general, does not need to have a purpose. The experience itself can be immensely rewarding and there are real benefits to be had, even if not immediately visible to the naked eye. Whether the word sticks or not, if I had to give one piece of advice, it would be the following. Do not worry about the outcome. Techrastinate . See hacker culture .  ↩ You can check out some more definitions here . The basic theme is the same anyway.  ↩ Who says that about etymology? Well, people like me.  ↩ With the post you are currently reading I am resetting once again the procrastination counter. Success .  ↩ See hacker culture .  ↩ You can check out some more definitions here . The basic theme is the same anyway.  ↩ Who says that about etymology? Well, people like me.  ↩ With the post you are currently reading I am resetting once again the procrastination counter. Success .  ↩

0 views

Template files with Nix Home Manager

It’s been a while since my last post and I did not want to leave 2025 behind without making any. During the past year I have been gradually migrating my development and configuration file setup to Nix Home Manager (aka ). This has not been a quick transition, but I am satisfied with the result and I believe it was worth it. I note the following benefits: It enables me to handle all changes (program versions and configuration files) from a single directory. A single source of truth that can be easily tracked by . I am a fan of Nix reproducible environments and builds and I considered using a nice opportunity to familiarize myself with the language. Nix packages enable me to create a predictable development environment across different machines (e.g. home, work, etc.), irrespective of the underlying operating system and the packages that it provides by default. I finally finished the migration last month, so I thought it is a good idea to share the interesting bits of my current setup. Maybe someone will find it useful. I don’t know how many posts I will make about it, but let’s get started. When sharing a configuration between multiple machines, a common scenario is to have a file that needs to be slightly different in each machine. For example, in my configuration, I want to configure the number of async workers that will use when launched by the server. In my laptop which has only 4 cores, I want to use 3 of them. In my work computer that has 20, I want to use more (e.g. 16). How can we utilize to automate this customization? This post does not provide an introduction to . Nevertheless, we need to agree on some necessary baseline knowledge. requires a configuration file that typically lies in the directory. In we can define the files that are generated via by populating the 1 attribute set . Every “key-value” entry in this attribute set corresponds to a file that we want to generate in our directory. For example, if we want to generate the file, we need to add the corresponding entry in the attribute set. The file options attribute set fully configures the generation of each file. This includes the contents, setting the executable bit, any actions to perform when the file changes and more. This post only deals with the contents of the generated files. For this we have two options: We can create a templating layer on top of and programmatically generate files with parametrizable content. How do we do that? We can use a template engine like jinja . For the purposes of my configuration I am using jinja2-cli , because I want to easily invoke from the command line. Let’s take it step by step. 1. Decouple templating layer from the actual attribute set. We create an attribute set that mirrors the structure of the . We do not want to deviate too much from the actual “structure” that expects, so that the configuration and programming logic is simpler. 2. Modify each “key-value” file entry using 2 . Currently the values of the file entries are empty. We need to populate these attribute sets, so that they are valid file entries. As already mentioned, to set the file content, we need to define either the or the attribute. For non-template files the function is simple: You may wonder what this is. In my configuration, I have created a directory inside that mirrors the directory structure of the directory. This allows referring to the source file and the actual generated location with the same relative path and permits using to modify the initial attribute set. For template files we need to provide some more information (i.e. the data). We do so by adding a attribute. Now, we define the function. We can see that we rely on the output of a helper function: . This function in its simplest form 3 takes two paths as arguments: The return value of this function has to be a Nix string that is then used as the value of the attribute. We define the function as follows: How does the function work? The function uses 4 to create a Nix derivation . In our use case we only want to create one single file that we can then read from. 3. Merge simple and template files in one attribute set. We are almost done. We need to map non-template files with the function and template files with the function. The differentiating factor is the presence of the attribute and we use that to create a filter. 4. Assign the resulting attribute set to . That’s it. We have successfully configured to generate files from templates. At the beginning of this post I mentioned how one my use cases for template files is specifying a different number of async workers for in my configuration in . How does this look like based on the described setup? It is that simple 5 . Nix enables extensive configuration, so we could certainly improve on the described setup if we needed to. Here are some ideas: The function in its current form requires two file paths as parameters. We may desire some more flexibility. For example, we may want to pass the template file as a Nix string. Or we may want to pass the in a different format (e.g. as a Nix attribute set, a Nix string, etc.). We should be able to easily achieve that with a few small changes in the function in order to correctly parse and transform parameters of different types. In a previous iteration of my configuration I was generating multiple files from a single template file by iterating over a array. I now have no use for it, so I have not included it in this post, but it is certainly doable with a few changes. See home-file .  ↩ See builtins.mapAttrs .  ↩ See Extensions .  ↩ See pkgs.runCommand .  ↩ The file is automatically generated, but that deserves a post of its own.  ↩ It enables me to handle all changes (program versions and configuration files) from a single directory. A single source of truth that can be easily tracked by . I am a fan of Nix reproducible environments and builds and I considered using a nice opportunity to familiarize myself with the language. Nix packages enable me to create a predictable development environment across different machines (e.g. home, work, etc.), irrespective of the underlying operating system and the packages that it provides by default. the attribute, which is a Nix path to a file whose content will populate the generated file or the attribute, which is a Nix string defining the content of the generated file is the path to the template file. is the path to a file containing data in format. We run on the file using the in format. We write the output to the file ( note: the variable is used internally by Nix and points to the generated derivation file). If anything fails during the call we copy the original template file content to the output file directly. Finally, we read the output file and return its content as a Nix string. The function in its current form requires two file paths as parameters. We may desire some more flexibility. For example, we may want to pass the template file as a Nix string. Or we may want to pass the in a different format (e.g. as a Nix attribute set, a Nix string, etc.). We should be able to easily achieve that with a few small changes in the function in order to correctly parse and transform parameters of different types. In a previous iteration of my configuration I was generating multiple files from a single template file by iterating over a array. I now have no use for it, so I have not included it in this post, but it is certainly doable with a few changes. See home-file .  ↩ See builtins.mapAttrs .  ↩ See Extensions .  ↩ See pkgs.runCommand .  ↩ The file is automatically generated, but that deserves a post of its own.  ↩

0 views

std::cout « “Goodbye Meeting C++. Hello C++ Community.”;

The train journey from Berlin to Brno takes around 7 hours. This gave me some time to reflect on my experience at this year’s Meeting C++ in Berlin and start jotting down these words. I have been working with C++ throughout my still-young software engineering career. Until now, I had not had any in-person contact with the C++ community. That has now changed. During the past three days, and for the first time, I attended a C++ conference. Having no prior reference for such an event, I did not have any outright expectations. I approached the event with an open mind and a curious spirit, diving right in. All conference talks are usually made available online. Attending a conference does not necessarily grant access to exclusive or hidden knowledge. And neither should it. Information should be accessible to all. Both those who can attend such events and those who cannot. Having said that, it is one thing to watch a talk online and another one to experience it in front of you. Observing the subtle behavior of the audience and being close to the interaction between the speaker and the rest of the room elevates the whole experience. Each talk is not just a presentation – it is a live performance. It can make you think, stir your emotions, enlighten you. The possibilities are endless. In that regard, I am grateful to have been present in so many great talks this year. The technical talks were excellent and the information shared from the speakers is highly valuable. The present and future of the language is exciting: modules (at last), contracts, reflection, … – the list goes on and on. But working as a software engineer is not only about designing and writing code. It’s also about interacting with people. It is my strong belief that most problems in any organization are people problems. This is why I especially appreciated the more people-centric talks that were part of this year’s schedule. Special mention goes to Titus Winters and his excellent opening keynote. Titus gave a compelling talk, sharing his experience in reducing fear in tech, and addressing various people-related issues in the workplace. He provided us with valuable actionable advice to improve our day-to-day work with respect to the challenges. He emphasized the importance of setting clear team culture goals related to technology quality, handling internal and external pressure, and team dynamics. He mentioned how expressing gratitude towards our colleagues and embracing the team members’ mistakes can go a long way towards improving the general team morale. Though these ideas sound simple, they are not widely practiced. Yet the potential is clear. They will translate to better results. The audience’s reactions made evident that many in our community resonated with these ideas. One would even say that many probably felt relieved they were not alone in having such sensitivities. So, thank you, Titus, for your talk. I truly believed it paved the way nicely for the success of the whole conference. The most important aspect of any conference is the people. The stories and experiences shared by everyone are invaluable. Glimpsing into different tech sub-worlds through others’ perspectives is incredibly rewarding. I really want to express my gratitude to each and every one of the people who shared some of their precious time talking with me. Your fascinating work and stories left a lasting impression on me. I wish I could have met even more people, but I guess this will have to wait for the next time 1 . Organizing a conference is no easy feat. Such efforts often go unnoticed or underappreciated. People do not tend to make their opinions public about such things. Especially when, as in this case, there are no issues 2 . So, a big thanks has to go to the people that made Meeting C++ 2024 happen and ensured that no visible problems arose. One aspect that could be improved to greatly enhance the whole experience would be the break time between talks. I understand that there were many great talks, and it is not easy to fit everything into the schedule, but I believe 15 minutes is not enough time. The current setting sometimes limits opportunities for meaningful conversations, exchanging opinions, and socializing with fellow attendees. This sentiment was shared by others I spoke to as well, so it would be nice to consider it in future editions of the conference. I thoroughly enjoyed my time at Meeting C++ this year. I am really grateful that my company 3 supported me and provided me with the opportunity to attend. I genuinely believe it was an enriching experience, which has nicely shaped my feelings as I am writing this: Auf Wiedersehen! Or online. If we didn’t meet in person and you would like to talk to me, you can always reach me on LinkedIn or by sending me an email.  ↩ It’s easier for people to complain.  ↩ In Codasip we are doing cool RISC-V and EDA work. Check us out if you are not aware of us.  ↩ I am inspired to improve all aspects of my work environment – culture, technical quality, and actual products. I eagerly look forward to seeing you all again at the next C++ conference I attend. Apparently, I, too, don’t know how to properly operate a coffee safety pot. I quite like my new T-shirt. Or online. If we didn’t meet in person and you would like to talk to me, you can always reach me on LinkedIn or by sending me an email.  ↩ It’s easier for people to complain.  ↩ In Codasip we are doing cool RISC-V and EDA work. Check us out if you are not aware of us.  ↩

0 views

Finding the optional truth

Using a programming language can be an easy task 1 . Understanding it deeply and mastering it, though, is more challenging. Multiple definitions of the word apply here: demanding and stimulating . I have been trying to utilize all available features of C++ as much as possible. One that I particularly like is 2 . I am fond of its semantics. Here is something that may contain a value, or it may as well contain nothing. This nothing is also known as . removes the need of returning raw pointers and relying on comparisons with in order to check if the return value of a function is valid or not. I must say I have not been using extensively, so I am yet to discover all its edges. But recently, I had to interact with it a little more and learned something along the way. Let’s start by writing a small example to describe my thought process. The most explicit way to print the above message is: Of course, in this small example, we could have skipped the check. But in the real world, we always have to ensure that the value is there. Otherwise, an exception – when using – or undefined behavior – when directly dereferencing the – is on the table. Knowing all these, I filled my code with and calls. I knew it was correct, but it was also quite cumbersome. There must have been an easier way to write this. Looking online, I saw some examples that were doing something akin to: This is what I was looking for. Not only is this a lot simpler to write, but it permits you to reuse old code that uses the nullptr-for-no-value pattern, just by changing the type from to in the code. Equipped with my newly found knowledge, I removed all calls to and replaced all calls to with direct dereferencing using . Unfortunately, I was greeted with a compiler error. The code in question was trying to do something like the following: The message was clear. But why did it not work? Converting to a in the condition of the statement is certainly possible. It turns out – as always – this is all by design. To answer my questions, I had to read the available specification on cppreference.com a little more carefully. When an object of type optional<T> is contextually converted to bool 3 , the conversion returns true if the object contains a value and false if it does not contain a value. I was not sure what “contextually” meant, so I followed the link, and I was presented with the following introductory text. Implicit conversions are performed whenever an expression of some type T1 is used in context that does not accept that type, but accepts some other type T2; in particular: It seemed to explain my situation. The last bullet must be what permits the usage of in statements. But wait a minute. The first bullet should cover the function parameter scenario, too. Obviously, this was not the case. I was missing something. The magic word is “implicit” . The class defines the following conversion function to : It is clearly marked as , so implicit conversions do not consider it. I thought to myself: How, then, does the conversion to ‘bool’ take place in the ‘if’ condition? I had to keep reading. Further below was the answer to my question about the meaning of “contextually” . Contextual conversions In the following contexts, the type ‘bool’ is expected and the implicit conversion is performed if the declaration ‘bool t(e)’ is well-formed (that is, an explicit conversion function such as ‘explicit T::operator bool() const’ is considered). Such expression ‘e’ is said to be contextually converted to bool . Since C++11: Since C++20: It turns out that, when a boolean expression is required for defining a condition – one would say, in a conditional context –, explicit conversion functions to are considered as well. I don’t want to focus on the minefield that is modern C++ syntax and rules. People smarter and more knowledgeable than me have expressed, and will continue to express, their opinions on the language. All I want to say is that, as a deeply inquiring mind, I was quite fascinated to discover this little sub-rule, which ultimately expanded my knowledge. Depending on which one you pick, of course.  ↩ See cppreference.com/…/optional .  ↩ See cppreference.com/…/language/implicit_conversion .  ↩ when the expression is used as the argument when calling a function that is declared with T2 as parameter; when the expression is used as an operand with an operator that expects T2; when initializing a new object of type T2, including return statement in a function returning T2; when the expression is used in a switch statement (T2 is integral type); when the expression is used in an if statement or a loop (T2 is bool). the controlling expression of if , while , for the operands of the built-in logical operators ! , && and || the first operand of the conditional operator ?: the predicate in a static_assert declaration the expression in a noexcept specifier the expression in an explicit specifier Depending on which one you pick, of course.  ↩ See cppreference.com/…/optional .  ↩ See cppreference.com/…/language/implicit_conversion .  ↩

0 views