<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Tomas Vik</title>
    <link>https://blog.viktomas.com/</link>
    <description>Recent content on Tomas Vik</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en</language>
    <managingEditor>me@viktomas.com (Tomas Vik)</managingEditor>
    <webMaster>me@viktomas.com (Tomas Vik)</webMaster>
    <lastBuildDate>Sun, 30 Mar 2025 00:00:00 +0000</lastBuildDate><atom:link href="https://blog.viktomas.com/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Neovim native, built-in, LSP autocomplete</title>
      <link>https://blog.viktomas.com/graph/neovim-native-built-in-lsp-autocomplete/</link>
      <pubDate>Sun, 30 Mar 2025 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/neovim-native-built-in-lsp-autocomplete/</guid>
      <description>&lt;p&gt;You don&amp;rsquo;t need &lt;code&gt;nvim-cmp&lt;/code&gt;, &lt;code&gt;coq_nvim&lt;/code&gt;, &lt;code&gt;blink.cmp&lt;/code&gt;, or any of the other autocomplete plugins. Neovim supports LSP autocompletion without extra plugins, and this short post will show you how.&lt;/p&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/2025-03-30-nvim-lsp-completion.gif&#34;
    alt=&#34;screencast&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;If you are only looking for the standard autocompletion offered by your Language Server, you can leverage the built-in &lt;a href=&#34;https://neovim.io/doc/user/lsp.html#lsp-completion&#34;&gt;&lt;code&gt;lsp-completion&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;three-easy-steps&#34;&gt;Three easy steps&lt;/h2&gt;
&lt;h3 id=&#34;step-1-set-completeopthttpsneovimiodocuseroptionshtmlcompleteopt&#34;&gt;Step 1: set &lt;a href=&#34;https://neovim.io/doc/user/options.html#&#39;completeopt&#39;&#34;&gt;&lt;code&gt;completeopt&lt;/code&gt;&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Set the complete option to make the menu feel like the auto completion plugins.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;-- prevent the built-in vim.lsp.completion autotrigger from selecting the first item&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;vim.opt.completeopt = { &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;menuone&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;noselect&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;popup&amp;#34;&lt;/span&gt; } 
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Explanation of the options taken from the docs:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;menuone&lt;/code&gt; - Use the popup menu also when there is only one match. Useful when there is additional information about the match, e.g., what file it comes from.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;noselect&lt;/code&gt; - Same as &amp;ldquo;noinsert&amp;rdquo;, except that no menu item is pre-selected. If both &amp;ldquo;noinsert&amp;rdquo; and &amp;ldquo;noselect&amp;rdquo; are present, &amp;ldquo;noselect&amp;rdquo; has precedence.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;popup&lt;/code&gt; - Show extra information about the currently selected completion in a popup window. Only works in combination with &amp;ldquo;menu&amp;rdquo; or &amp;ldquo;menuone&amp;rdquo;. Overrides &amp;ldquo;preview&amp;rdquo;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;step-2-enable-completion-on-lsp-client-attach&#34;&gt;Step 2: enable completion on LSP client attach&lt;/h3&gt;
&lt;p&gt;I assume you already have &lt;a href=&#34;https://github.com/neovim/nvim-lspconfig&#34;&gt;nvim-lspconfig&lt;/a&gt; set up. If you do, you can pass in an &lt;code&gt;on_attach&lt;/code&gt; callback when setting up each of the Language Servers.&lt;/p&gt;
&lt;p&gt;See the following example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;require(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;lspconfig&amp;#34;&lt;/span&gt;)[&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;gopls&amp;#34;&lt;/span&gt;].setup({
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	on_attach = &lt;span style=&#34;color:#00f&#34;&gt;function&lt;/span&gt;(client, bufnr)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      vim.lsp.completion.enable(&lt;span style=&#34;color:#00f&#34;&gt;true&lt;/span&gt;, client.id, bufnr, {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		autotrigger = &lt;span style=&#34;color:#00f&#34;&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		convert = &lt;span style=&#34;color:#00f&#34;&gt;function&lt;/span&gt;(item)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#00f&#34;&gt;return&lt;/span&gt; { abbr = item.label:gsub(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;%b()&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;) }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#00f&#34;&gt;end&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      })
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      vim.keymap.set(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;i&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;&amp;lt;C-space&amp;gt;&amp;#34;&lt;/span&gt;, vim.lsp.completion.get, { desc = &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;trigger autocompletion&amp;#34;&lt;/span&gt; })
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The key part is the call to &lt;code&gt;vim.lsp.completion.enable&lt;/code&gt; that will enable the completion. Using &lt;code&gt;autotrigger&lt;/code&gt; makes the trigger characters automatically start completion.&lt;/p&gt;
&lt;p&gt;I also mapped &lt;code&gt;CTRL+SPACE&lt;/code&gt; to trigger the autocompletion. You can instead use &lt;a href=&#34;https://neovim.io/doc/user/insert.html#omnicompletion&#34;&gt;omnicompletion&lt;/a&gt; with &lt;code&gt;CTRL-X CTRL-O&lt;/code&gt; if you want to be a purist (omnicompletion is used under the hood).&lt;/p&gt;
&lt;p&gt;In my dotfiles, I define &lt;code&gt;on_attach&lt;/code&gt; once and reuse it for all &lt;code&gt;setup()&lt;/code&gt; functions.&lt;/p&gt;
&lt;h3 id=&#34;step-3-use-it&#34;&gt;Step 3: Use it&lt;/h3&gt;
&lt;p&gt;Once the language client attaches, the autocompletion triggers on trigger characters like &lt;code&gt;.&lt;/code&gt; and you can invoke it manually with &lt;code&gt;CTRL+SPACE&lt;/code&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;I&amp;rsquo;m excited to replace a plugin, but time will tell if this simplified version of autocompletion will be enough for me. I&amp;rsquo;m not sure how much I&amp;rsquo;ll miss the lack of snippets and documentation for each symbol.&lt;/p&gt;
&lt;h2 id=&#34;resources&#34;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;PR that introduced the feature: &lt;a href=&#34;https://github.com/neovim/neovim/pull/27339&#34;&gt;feat(lsp): completion side effects by MariaSolOs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Nvim docs &lt;a href=&#34;https://neovim.io/doc/user/lsp.html#lsp-completion&#34;&gt;&lt;code&gt;lsp-completion&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>The books I did not finish in 2024</title>
      <link>https://blog.viktomas.com/graph/2024-unfinished-books/</link>
      <pubDate>Wed, 12 Feb 2025 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/2024-unfinished-books/</guid>
      <description>&lt;p&gt;I like to finish books that I start, but it&amp;rsquo;s not always possible. In this post, I share a few books I started reading but didn&amp;rsquo;t finish last year.&lt;/p&gt;
&lt;p&gt;Some of them just weren&amp;rsquo;t good, others did not match my expectations. A good tell that the book is not good for me is that I stop reading in the evenings and instead do something else like watch TV or play games. When that goes on for too long, the book ends up on this list.&lt;/p&gt;
&lt;h2 id=&#34;an-elegant-puzzle---will-larson&#34;&gt;An Elegant Puzzle - Will Larson&lt;/h2&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/will-larson--elgant-puzzle.jpg&#34;
    alt=&#34;An Elegant Puzzle - Will Larson&#34;
    loading=&#34;lazy&#34;
    
/&gt;
☠️ April 2024&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.goodreads.com/book/show/45303387-an-elegant-puzzle&#34;&gt;Goodreads&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This book was published by Stripe Press. Those were all the credentials I needed to pick it up. But it is not as useful or insightful for me as many other &lt;a href=&#34;https://press.stripe.com/&#34;&gt;Stripe Press books&lt;/a&gt;. The content is aimed at managers and it&amp;rsquo;s mostly based on anecdotal evidence.&lt;/p&gt;
&lt;h2 id=&#34;start-small-stay-small---rob-walling&#34;&gt;Start small, stay small - Rob Walling&lt;/h2&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/rob-walling--start-small-stay-small.jpg&#34;
    alt=&#34;Start small, stay small - Rob Walling&#34;
    loading=&#34;lazy&#34;
    
/&gt;
☠️ August 2024&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.goodreads.com/book/show/9167158-start-small-stay-small&#34;&gt;Goodreads&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I enjoyed Walling&amp;rsquo;s guide on how to create a small, sustainable company. However, the book is 15 years old so about half of the practical advice no longer applies. Also, I realised mid-way through the book that I&amp;rsquo;m not going to start a business on top of having a day job and a toddler. So I stopped reading.&lt;/p&gt;
&lt;h2 id=&#34;mike-robbins---be-yourself-everyone-else-is-already-taken&#34;&gt;Mike Robbins - Be Yourself, Everyone Else is Already Taken&lt;/h2&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/mike-robbins--be-yourself.jpg&#34;
    alt=&#34;&#34;
    loading=&#34;lazy&#34;
    
/&gt;
☠️ November 2024&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.goodreads.com/book/show/6380353-be-yourself-everyone-else-is-already-taken&#34;&gt;Goodreads&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Robbins&amp;rsquo; self-help book is an enjoyable read but the timing was not right.&lt;/p&gt;
&lt;p&gt;When I picked it up, I was already learning how to practice Stoicism.&lt;/p&gt;
&lt;p&gt;I also started doing Jordan Peterson&amp;rsquo;s Self-Authoring course in October and there was significant overlap between the exercises in Robbin&amp;rsquo;s book and Peterson&amp;rsquo;s course.&lt;/p&gt;
&lt;p&gt;I made it through half of this book before deciding that it didn&amp;rsquo;t bring enough value compared to all the other self-help/philosophy materials I was working with.&lt;/p&gt;
&lt;h2 id=&#34;nelson-mandela---long-walk-to-freedom&#34;&gt;Nelson Mandela - Long Walk to Freedom&lt;/h2&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/nelson-mandela--long-walk-to-freedom.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;
☠️ November 2024&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.goodreads.com/book/show/318431.Long_Walk_to_Freedom&#34;&gt;Goodreads&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Mandela&amp;rsquo;s autobiography gives you an insight into the racial struggle in South Africa throughout the last 100 years and more. I tried both reading and listening to this book but stopped after the first third- as one review on Goodreads says: &amp;ldquo;It&amp;rsquo;s a long, long, long, long, long walk to Freedom&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;The issue is that Mandela goes to extreme detail about every political meeting and campaign and I just couldn&amp;rsquo;t find time to listen to 30 hours of audio.&lt;/p&gt;
&lt;p&gt;I think he deserves the praise for freedom fighting, but not for brevity.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;sigh&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Sharing this post lifted a boulder off my shoulders. I prefer finishing books but even when I don&amp;rsquo;t, I think a brief mention is OK. Maybe it will even help you avoid/read them.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Ray Dalio - Principles: Life and Work</title>
      <link>https://blog.viktomas.com/graph/ray-dalio--principles/</link>
      <pubDate>Wed, 05 Feb 2025 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/ray-dalio--principles/</guid>
      <description>&lt;ul&gt;
&lt;li&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/ray-dalio--principles.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;
&lt;a href=&#34;https://www.goodreads.com/book/show/34536488-principles&#34;&gt;Goodreads&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My rating: ★★★★☆ (85%)&lt;/p&gt;
&lt;p&gt;Ray Dalio is a successful investor who wrote a book about how should you live your life. I&amp;rsquo;ve only read the personal life section of the book which amounts to roughly a third. I skipped Dalio&amp;rsquo;s autobiography and principles for work since those seemed geared more toward founders/owners of a business.&lt;/p&gt;
&lt;p&gt;These are four ideas that seemed the most interesting to me:&lt;/p&gt;
&lt;h2 id=&#34;1-reflect-on-pain&#34;&gt;1. Reflect on pain&lt;/h2&gt;
&lt;p&gt;When something is painful or unpleasant for you, note it down and take time to reflect on why that is. Often it’s painful because you are not good at handling the situation and by reflecting on the pain you can get better.&lt;/p&gt;
&lt;p&gt;Key insight: &lt;strong&gt;If you don&amp;rsquo;t have enough awareness to recognise when you are in emotional pain, you won&amp;rsquo;t reflect on and fix the issue and it will repeat itself.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;2-blind-spots&#34;&gt;2. Blind spots&lt;/h2&gt;
&lt;p&gt;You don’t know what you don’t know and your view of reality seems to be the right one for you. But you have blind posts that you can’t uncover. You need to interact with transparent people who share their criticism of you to find your blind spots. This is why you should never get defensive when you receive feedback. You want people to criticise you openly.&lt;/p&gt;
&lt;h2 id=&#34;3-nobody-is-perfect&#34;&gt;3. Nobody is perfect&lt;/h2&gt;
&lt;p&gt;Learn what are your weaknesses and learn to work around them. You are not perfect and even though neuroplasticity is real, maybe you should focus on improving your strengths and learn to work around your weaknesses (e.g. delegating to other people who are better).&lt;/p&gt;
&lt;p&gt;If you don’t understand your weaknesses and think you are good at the task, you will run into the same problem again and again.&lt;/p&gt;
&lt;h2 id=&#34;4-you-are-a-manager-and-a-worker&#34;&gt;4. You are a manager and a worker&lt;/h2&gt;
&lt;p&gt;Dalio says you have to know yourself. Know your weaknesses. And perceive your involvement in life through two separate lenses: Manager and Worker.&lt;/p&gt;
&lt;p&gt;The manager is responsible for designing and organising the work and the worker is responsible for executing it.&lt;/p&gt;
&lt;p&gt;Key insight: It’s possible to be a bad worker in some areas and still succeed. The manager needs to fire the worker and find a workaround/hire someone.&lt;/p&gt;
&lt;h2 id=&#34;personal-impact&#34;&gt;Personal impact&lt;/h2&gt;
&lt;p&gt;Overall, the ideas in the book don&amp;rsquo;t sound groundbreaking, but Dalio describes them clearly and applicably.&lt;/p&gt;
&lt;p&gt;I started keeping a pain journal and I&amp;rsquo;m adding roughly one new &amp;ldquo;pain&amp;rdquo; entry each week.&lt;/p&gt;
&lt;p&gt;I also got motivated to define my life goals after reading this book. I&amp;rsquo;ll write about the 45-hour journaling session in another post.&lt;/p&gt;
&lt;p&gt;I recommend reading the &amp;ldquo;personal principles&amp;rdquo; section of the book. It has a high signal/noise ratio.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Frederick Douglass - Narrative of the Life of Frederick Douglass</title>
      <link>https://blog.viktomas.com/graph/frederick-douglass--narrative-of-the-life-of-frederick-douglass/</link>
      <pubDate>Wed, 25 Dec 2024 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/frederick-douglass--narrative-of-the-life-of-frederick-douglass/</guid>
      <description>&lt;ul&gt;
&lt;li&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/frederick-douglass--narrative-of-the-life-of-frederick-douglass.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.goodreads.com/book/show/36529.Narrative_of_the_Life_of_Frederick_Douglass&#34;&gt;Goodreads&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;frederick-douglass--narrative-of-the-life-of-frederick-douglass&#34;&gt;Download&lt;/a&gt; (It&amp;rsquo;s in the public domain)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My rating: ★★★★☆ (80%)&lt;/p&gt;
&lt;p&gt;Frederick Douglass shares his life story. He was born as a slave and managed to escape slavery.&lt;/p&gt;
&lt;p&gt;This is a short book but very touching. Douglass experienced unimaginable hardships but wrote about them with calmness and eloquence. He escaped at age twenty and was twenty-seven when he published the narrative.&lt;/p&gt;
&lt;p&gt;This is the first account of slavery (not counting movies) and the issue gets more gravity when written by an ex-slave. It&amp;rsquo;s puzzling that people back then accepted slavery as something compatible with virtue and good morals&lt;/p&gt;
&lt;p&gt;Skip the two preface chapters written by other people. They are written in the early 1800s style,  where the authors ate a dictionary. Douglass himself writes in simple language and to the point.&lt;/p&gt;
&lt;p&gt;The book is a three-hour read. Have fun reading.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>William B. Irvine - A Guide to the Good Life</title>
      <link>https://blog.viktomas.com/graph/william-b-irvine--a-guide-to-the-good-life/</link>
      <pubDate>Wed, 20 Nov 2024 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/william-b-irvine--a-guide-to-the-good-life/</guid>
      <description>&lt;ul&gt;
&lt;li&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/william-b-irvine--a-guide-to-the-good-life.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;
&lt;a href=&#34;https://www.goodreads.com/book/show/5617966-a-guide-to-the-good-life&#34;&gt;Goodreads&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My rating: ★★★☆☆ (60%)&lt;/p&gt;
&lt;p&gt;Irvine takes the Stoic teachings and transforms them into an accessible self-help book. The book&amp;rsquo;s greatest strength is how it distils the teachings into several practical exercises. Here are three key exercises that, when practised daily, can make you more joyful:&lt;/p&gt;
&lt;h2 id=&#34;exercise-1-negative-visualization&#34;&gt;Exercise 1: Negative Visualization&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s human nature to always want more. We rarely stay satisfied for long when we get what we&amp;rsquo;ve been striving for, be it money, a romantic partner, or other possessions.&lt;/p&gt;
&lt;p&gt;The key insight is this:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;If we can learn to appreciate what we already have, we can be content with our current lives.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;How do we achieve this? By imagining that we&amp;rsquo;ve lost what we already have. &lt;strong&gt;This can be a bit dark.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Do you have a nice family but feel like you don&amp;rsquo;t have enough time for yourself? Imagine they all died in a car crash and see how much you mind the lack of me-time after that.&lt;/li&gt;
&lt;li&gt;Do you wish for a larger house? Imagine your current one burned down and you weren&amp;rsquo;t insured.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This exercise works for me.&lt;/p&gt;
&lt;p&gt;Do you think that someone who imagines the death of their loved ones can&amp;rsquo;t enjoy life as much as someone who doesn&amp;rsquo;t? Give it a try and see for yourself. I bet you&amp;rsquo;ll be more present and grateful if you practice negative visualization.&lt;/p&gt;
&lt;h2 id=&#34;exercise-2-focus-on-what-you-can-control&#34;&gt;Exercise 2: Focus on What You Can Control&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Some things are up to us and some are not up to us&lt;/p&gt;
&lt;p&gt;Epictetus&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A key Stoic principle is recognizing that we don&amp;rsquo;t have control over many things. According to the Stoics, we can only truly control our impressions (thoughts and senses) and how we react to them. &lt;strong&gt;We can&amp;rsquo;t control anything else.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This concept is similar to Buddhist philosophy, which teaches us that our thoughts and sensations are not us and that we don&amp;rsquo;t have to react to them.&lt;/p&gt;
&lt;p&gt;Here Irvine introduces a third category of &amp;ldquo;things that are mostly but not completely in our control&amp;rdquo;. This is where I started noticing Irvine&amp;rsquo;s interpretation diverging from how I understand the original Stoic works and started leaning more towards the self-help genre. This aspect of the book is the reason for my average rating.&lt;/p&gt;
&lt;p&gt;But the original idea is still powerful: &lt;strong&gt;Once you assign value and crave or try to avoid things that are &lt;em&gt;outside&lt;/em&gt; of your control, you&amp;rsquo;ll suffer.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;When you notice you want or don&amp;rsquo;t want something, consider whether that thing is in your control or not. If it&amp;rsquo;s not, realize that you can&amp;rsquo;t keep it or avoid it forever.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You want a great job? You can&amp;rsquo;t control that, and even if you get it, you might get fired or you might stop enjoying it.&lt;/li&gt;
&lt;li&gt;You want children that love you and care about you? You can&amp;rsquo;t control that; you can only control what kind of parent you are.&lt;/li&gt;
&lt;li&gt;You want a specific man/woman to love you? &amp;hellip; You get the idea.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For things you can control (your reaction to thoughts, sensations, emotions), ensure you act virtuously. For things you can&amp;rsquo;t control, let them go and don&amp;rsquo;t worry about them. Why worry about something you can&amp;rsquo;t control?&lt;/p&gt;
&lt;h2 id=&#34;exercise-3-live-down-a-little&#34;&gt;Exercise 3: Live Down a Little&lt;/h2&gt;
&lt;p&gt;As opposed to &lt;em&gt;living it up&lt;/em&gt;. Get it? &lt;a href=&#34;https://www.youtube.com/watch?v=ona-RhLfRfc&#34;&gt;Nudge, nudge, wink, wink&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This exercise takes negative visualization a step further by temporarily living without some of life&amp;rsquo;s comforts. Try to occasionally live without the things you enjoy. That way, you&amp;rsquo;ll find that living a life of a poor person is not that bad.&lt;/p&gt;
&lt;p&gt;Try to underdress for cold weather, take cold showers, eat only bread or fast for a day. Give up coffee for a while. In other words, make your life a bit less comfortable.&lt;/p&gt;
&lt;p&gt;This will have two effects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;It will make you appreciate warm clothes, hot showers, good food, and coffee.&lt;/li&gt;
&lt;li&gt;It will show you that a simpler life is not that bad in case you might have to adopt it in the future.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;in-closing&#34;&gt;In Closing&lt;/h2&gt;
&lt;p&gt;Irvine&amp;rsquo;s book is a solid introduction to Stoicism. Its best quality is that it&amp;rsquo;s actionable. These exercises, plus a few more, will help you deal with everyday situations. If you practice them regularly, they have the potential to make your life more joyful.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Rob Fitzpatrick - The Mom Test</title>
      <link>https://blog.viktomas.com/graph/rob-fitzpatrick--the-mom-test/</link>
      <pubDate>Tue, 01 Oct 2024 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/rob-fitzpatrick--the-mom-test/</guid>
      <description>&lt;ul&gt;
&lt;li&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/rob-fitzpatrick--the-mom-test.png&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;
&lt;a href=&#34;https://www.goodreads.com/book/show/52283963-the-mom-test&#34;&gt;Goodreads&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My rating: ★★★★★ (95%)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TL;DR: Read &amp;ldquo;The Mom Test&amp;rdquo; if you&amp;rsquo;re creating a product and need to talk to customers or if you want to get better at getting unbiased facts from people.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&amp;ldquo;The Mom Test&amp;rdquo; is a concise guide on how to talk to potential customers and discover if your product solves their needs.&lt;/p&gt;
&lt;h2 id=&#34;key-idea-dont-discuss-your-idea-talk-about-their-problems&#34;&gt;Key idea: Don&amp;rsquo;t discuss your idea. Talk about their problems&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;you aren&amp;rsquo;t allowed to tell them what their problem is, and in return, they aren&amp;rsquo;t allowed to tell you what to build&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;If you just avoid mentioning your idea, you automatically start asking better questions. Doing this is the easiest (and biggest) improvement you can make&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The book is called &amp;ldquo;The Mom Test&amp;rdquo; because by applying this idea, even your Mom can&amp;rsquo;t lie to you about loving your idea/product (because you won&amp;rsquo;t share it).&lt;/p&gt;
&lt;h2 id=&#34;digging-deeper-ask-for-specific-examples&#34;&gt;Digging Deeper: Ask for Specific Examples&lt;/h2&gt;
&lt;p&gt;Ask for specific examples to get beyond vague opinions and general statements. When they say &amp;ldquo;I do that all the time,&amp;rdquo; ask &amp;ldquo;When was the last time?&amp;rdquo; If they claim &amp;ldquo;I would buy that,&amp;rdquo; ask &amp;ldquo;How much time have you spent searching for a solution?&amp;rdquo; Equipped with these facts, you can form your own conclusion about whether there&amp;rsquo;s a problem worth solving.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The measure of usefulness of an early customer conversation is whether it gives us concrete facts about our customers&amp;rsquo; lives and world views.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;broadly-applicable-principles&#34;&gt;Broadly applicable principles&lt;/h2&gt;
&lt;p&gt;I was surprised that the Mom Test principles also apply to designing engineering surveys at my workplace. This week, I created a survey about problems engineers face in our codebase. Before reading this book, I would have made several mistakes with leading questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Before: Rank these three problems by importance to you.
&lt;ul&gt;
&lt;li&gt;This shares my preconceived notions with a predefined list.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;After: Please list the three most serious issues you&amp;rsquo;ve encountered in the codebase over the past two months (include examples).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;key-points-summary&#34;&gt;Key Points Summary&lt;/h2&gt;
&lt;p&gt;While not discussing your idea is the main takeaway, there&amp;rsquo;s more to consider:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Clearly define your target market segment and invest time in researching their workflows and challenges.&lt;/li&gt;
&lt;li&gt;Prepare 3 pressing questions you need answered, focusing on experiences and facts rather than opinions.&lt;/li&gt;
&lt;li&gt;Ideally, don&amp;rsquo;t reveal your idea, but if you must, deflect compliments and keep the focus on the customer&amp;rsquo;s problem.&lt;/li&gt;
&lt;li&gt;When appropriate, ask for commitment. That can be time (another meeting), reputation (introductions to others), or money.&lt;/li&gt;
&lt;li&gt;Continue customer conversations until you stop hearing new information. If you still hear new information after ten meetings, narrow your market segment.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;An interesting side note from the book, not necessarily related to product development, suggests that when facing an unpleasant task, imagine you&amp;rsquo;re delegating it to someone else and write instructions for them, then follow those instructions yourself.&lt;/p&gt;
&lt;p&gt;Overall, I found the book enjoyable and highly valuable. While talking to customers can be daunting, this compact book provides a complete framework and plenty of examples on how to do it.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Atul Gawande - The Checklist Manifesto</title>
      <link>https://blog.viktomas.com/graph/atul-gawande--the-checklist-manifesto/</link>
      <pubDate>Fri, 20 Sep 2024 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/atul-gawande--the-checklist-manifesto/</guid>
      <description>&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/atul-gawande--the-checklist-manifesto.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;
&lt;a href=&#34;https://www.goodreads.com/book/show/6667514-the-checklist-manifesto&#34;&gt;Goodreads&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My rating: ★★★★☆ (75%)&lt;/p&gt;
&lt;p&gt;This book answers the age-old question: Can you write a whole book about something as trivial as checklists?&lt;/p&gt;
&lt;p&gt;As it turns out, you can, and to my surprise, it was a fun read.&lt;/p&gt;
&lt;p&gt;I got this book recommendation from a YouTube video &lt;a href=&#34;https://www.youtube.com/watch?v=LzjbSXC6COE&#34;&gt;Find Business Ideas Customers ACTUALLY Want 💡 Josh Kaufman&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I use checklists extensively and I&amp;rsquo;ve read about them in &lt;a href=&#34;https://blog.viktomas.com/graph/munger-kaufman--poor-charlies-almanack&#34;&gt;Charles T. Munger, Peter D. Kaufman - Poor Charlie&amp;rsquo;s Almanack&lt;/a&gt;. So I was eager to find out if there&amp;rsquo;s anything I can add to my checklists to make them more useful.&lt;/p&gt;
&lt;h2 id=&#34;the-story&#34;&gt;The story&lt;/h2&gt;
&lt;p&gt;The book describes how planes in the 30s became so complex to fly that pilots had to introduce checklists to prevent crashes. Gawande argues that all industries have reached this level of complexity, necessitating the use of checklists to manage intricate processes and prevent errors.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Multiple fields, in other words, have become too much airplane for one person to fly.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The main storyline follows Gawande and his colleagues as they successfully introduce a checklist to be used before and after surgeries. This significantly reduces preventable mistakes, such as forgetting to administer antibiotics to patients. An interesting insight is the widespread resistance of professionals to follow a checklist, despite its proven benefits.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;But we believe our jobs are too complicated to reduce to a checklist.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;the-useful-info&#34;&gt;The useful info&lt;/h2&gt;
&lt;p&gt;Checklists for planes can be of two kinds: &lt;strong&gt;do-read and read-do&lt;/strong&gt;. For a quick double-check after performing an action, you would use do-read. For example, after completing a pre-flight inspection, pilots might use a do-read checklist to ensure they haven&amp;rsquo;t missed any critical steps. When you want to follow a more complex process (e.g., emergency water landing), you will use read-do to ensure you do all the steps in the right order. This type of checklist guides the user through each step of the process as they perform it.&lt;/p&gt;
&lt;p&gt;Most of the checklists in the book capture important steps in a complex process (e.g., surgery) that repeat very often. However, there are exceptions like checks for plane emergencies that pilots almost never use in real life. The difference between these &amp;ldquo;probably never needed&amp;rdquo; checklists and the common checklists is that aviation companies have whole departments dedicated to crafting and testing checklists.&lt;/p&gt;
&lt;p&gt;When designing a checklist, you can have multiple pause points. For example: before the taxi, before takeoff, and after takeoff.&lt;/p&gt;
&lt;p&gt;Read chapter 2 if you plan on introducing checklists to your company and you have team leads that should follow them (e.g., surgeons).&lt;/p&gt;
&lt;h2 id=&#34;designing-a-good-checklist&#34;&gt;Designing a good checklist&lt;/h2&gt;
&lt;p&gt;To create an effective checklist, consider the following guidelines:&lt;/p&gt;
&lt;p&gt;Content:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Include only steps you might forget to do; if you do the step every time without fail, don&amp;rsquo;t put it in the checklist.&lt;/li&gt;
&lt;li&gt;Assume domain knowledge and don&amp;rsquo;t explain terms/processes everybody knows.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Length and timing:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The author recommends that you time your checklist and make sure that each pause-point takes only 60 seconds. (This may vary depending on the context)&lt;/li&gt;
&lt;li&gt;The checklist should have between five and nine items. (This guideline may also vary based on the complexity of the task)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Practicality:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Good checklists, on the other hand, are precise. They are efficient, to the point, and easy to use even in the most difficult situations. They do not try to spell out everything—a checklist cannot fly a plane. Instead, they provide reminders of only the most critical and important steps—the ones that even the highly skilled professionals using them could miss. Good checklists are, above all, practical.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;meta-checklist&#34;&gt;Meta checklist&lt;/h2&gt;
&lt;p&gt;I devised this checklist after reading the book. Apply it to your checklists:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Contains tasks that I would often forget, not the tasks I do every time&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; The checklist feels like a net-benefit, not net-loss - it regularly catches mistakes/omissions I&amp;rsquo;d make&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; There are no items that are significantly less important than the others&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Can be completed in a reasonable timeframe for the context (e.g. 60 seconds for quick checks, longer for complex decisions)&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Addresses common failure points or recurrent mistakes in the process&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; Is visually clear and easy to read quickly&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;meta-sidenote&#34;&gt;Meta (sidenote)&lt;/h2&gt;
&lt;p&gt;At one point in the book, the author works for the World Health Organization (WHO) to develop a program for surgeons worldwide to reduce surgery complications. The author goes on to do something clever:&lt;/p&gt;
&lt;p&gt;He studies previous successful WHO health projects to see what they had in common. This is something that&amp;rsquo;s hard to do but has massive ROI, &lt;strong&gt;take a step back and inspect your task on a meta level&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&#34;applications-in-different-fields&#34;&gt;Applications in different fields&lt;/h2&gt;
&lt;p&gt;Throughout the book, Gawande explores the use of checklists in various industries:&lt;/p&gt;
&lt;h3 id=&#34;aviation&#34;&gt;Aviation&lt;/h3&gt;
&lt;p&gt;The aviation industry pioneered the use of checklists, developing both routine and emergency checklists to ensure safety.&lt;/p&gt;
&lt;h3 id=&#34;medicine&#34;&gt;Medicine&lt;/h3&gt;
&lt;p&gt;Gawande&amp;rsquo;s work in implementing surgical checklists led to significant reductions in complications and deaths. The World Health Organization (WHO) adopted a similar approach for a global surgery safety program.&lt;/p&gt;
&lt;h3 id=&#34;construction&#34;&gt;Construction&lt;/h3&gt;
&lt;p&gt;The author draws parallels between the complexity of modern construction projects and the need for effective communication and coordination, which can be facilitated by checklists.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;The biggest cause of serious error in [construction] is a failure of communication,&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;investing&#34;&gt;Investing&lt;/h3&gt;
&lt;p&gt;Gawande mentions how investors use checklists to ensure they consider all critical factors before making investment decisions. For example, ensuring that board members are not selling their stock too much.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Checklists, when designed and implemented correctly, can be powerful tools for managing complexity, reducing errors, and improving performance. As our world becomes increasingly complex, checklists can help manage some of the complexity.&lt;/p&gt;
&lt;p&gt;I personally use checklists every day in my notes. My &amp;ldquo;pause points&amp;rdquo; are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;starting a project&lt;/li&gt;
&lt;li&gt;finishing a project&lt;/li&gt;
&lt;li&gt;encountering a difficult task&lt;/li&gt;
&lt;li&gt;implementing new feature&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When reading the book, I felt a bit envious of more mature engineering disciplines like civil engineering. The level of coordination and communication that happens during construction seems miles ahead of what I experience daily as a software engineer.&lt;/p&gt;
&lt;p&gt;The book is repetitive and basic at times, but it&amp;rsquo;s enjoyable to read thanks to Gawande&amp;rsquo;s healthcare stories.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Circular Dependencies in JavaScript Explained</title>
      <link>https://blog.viktomas.com/graph/circular-dependencies-in-javascript-explained/</link>
      <pubDate>Sun, 21 Jul 2024 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/circular-dependencies-in-javascript-explained/</guid>
      <description>&lt;p&gt;Wide-eyed, I stared at &lt;code&gt;undefined&lt;/code&gt;. It shouldn&amp;rsquo;t have been there. It was meant to be a string, defined as &lt;code&gt;export const val = &#39;abc&#39;&lt;/code&gt; and imported as &lt;code&gt;import {val} from &#39;./my-module&#39;&lt;/code&gt;. Yet, it was &lt;code&gt;undefined&lt;/code&gt;. No amount of deleting &lt;code&gt;node_modules&lt;/code&gt;, restarting my computer, or logging could fix it. &lt;code&gt;val&lt;/code&gt; remained stubbornly &lt;code&gt;undefined&lt;/code&gt;. But why?&lt;/p&gt;
&lt;p&gt;Sometimes you enjoy the flexibility of JavaScript/TypeScript, and other times, it kicks you in the crotch. A proper swing with a run-up. This post is about the crotch-kicking quality of JavaScript.&lt;/p&gt;
&lt;h2 id=&#34;tldr&#34;&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ll explain circular dependency types in JavaScript and how to avoid them with the &lt;a href=&#34;https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-cycle.md&#34;&gt;&lt;code&gt;import/no-cycle&lt;/code&gt; ESLint rule&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;circular-dependency-explained&#34;&gt;Circular Dependency Explained&lt;/h2&gt;
&lt;p&gt;The simplest circular dependency is when module A references module B, and module B references module A.&lt;/p&gt;

&lt;div class=&#34;mermaid&#34; align=&#34;center&#34;&gt;graph TD
a --&gt; b
b --&gt; a&lt;/div&gt;
&lt;p&gt;However, in JavaScript, there are two circular dependency types, one more harmful than the other.&lt;/p&gt;
&lt;h2 id=&#34;immediate-circular-dependency&#34;&gt;Immediate Circular Dependency&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s called &lt;em&gt;immediate&lt;/em&gt; (or &amp;ldquo;static&amp;rdquo;) because the dependency is realized (immediately) when the modules load, before any non-import code runs.&lt;/p&gt;
&lt;p&gt;This is the hardcore nasty type. With some node module implementations, it will break your app completely, while with others, it will manifest as the tricky &lt;code&gt;undefined&lt;/code&gt; bug I teased in the introduction.&lt;/p&gt;
&lt;p&gt;The &lt;em&gt;immediate&lt;/em&gt; circular dependency can&amp;rsquo;t be initialized correctly.&lt;/p&gt;
&lt;p&gt;This is the simplest example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;// a.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;import&lt;/span&gt; { b } from &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;./b.js&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;const&lt;/span&gt; a = &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;aloha&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;console.log(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;from a&amp;#34;&lt;/span&gt;, b);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;// b.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;import&lt;/span&gt; { a } from &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;./a.js&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;const&lt;/span&gt; b = &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;bye&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;console.log(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;from b&amp;#34;&lt;/span&gt;, a);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;// index.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;import&lt;/span&gt; { a } from &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;./a.js&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;console.log(a);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As in the diagram, module &lt;code&gt;a&lt;/code&gt; needs module &lt;code&gt;b&lt;/code&gt; and vice versa.&lt;/p&gt;
&lt;p&gt;When you run &lt;code&gt;node index.js&lt;/code&gt;, most of the code runs as a result of the &lt;code&gt;import { a } from &amp;quot;./a.js&amp;quot;&lt;/code&gt; import statement, before the &amp;ldquo;production code&amp;rdquo; &lt;code&gt;console.log(a)&lt;/code&gt; runs.&lt;/p&gt;
&lt;p&gt;It happens like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;node index.js&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;We start importing &lt;code&gt;a&lt;/code&gt; to &lt;code&gt;index&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;When loading &lt;code&gt;a&lt;/code&gt;, we need to import &lt;code&gt;b&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;b&lt;/code&gt; tries to import &lt;code&gt;a&lt;/code&gt;, causing a bug because &lt;code&gt;a&lt;/code&gt; has already been loaded and still isn&amp;rsquo;t initialized. It waits for &lt;code&gt;b&lt;/code&gt; initialization.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This same code produces 3 different results based on how you run it:&lt;/p&gt;
&lt;h3 id=&#34;ecmascript-modules&#34;&gt;ECMAScript Modules&lt;/h3&gt;
&lt;p&gt;When using &lt;a href=&#34;https://nodejs.org/api/esm.html&#34;&gt;ECMAScript modules&lt;/a&gt;, running the script fails:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;file:///circular/init-circular-esm/b.js:5
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;console.log(&amp;#34;from b&amp;#34;, a);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;                      ^
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;ReferenceError: Cannot access &amp;#39;a&amp;#39; before initialization
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    at file:///circular/init-circular-esm/b.js:5:23
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    at ModuleJob.run (node:internal/modules/esm/module_job:222:25)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    at async ModuleLoader.import (node:internal/modules/esm/loader:323:24)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    at async loadESM (node:internal/process/esm_loader:28:7)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    at async handleMainPromise (node:internal/modules/run_main:120:12)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Node.js v21.7.3
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is fantastic. So if you use ESM and Node, you don&amp;rsquo;t have to worry about &lt;em&gt;immediate&lt;/em&gt; circular dependencies.&lt;/p&gt;
&lt;h3 id=&#34;commonjs-modules&#34;&gt;CommonJS Modules&lt;/h3&gt;
&lt;p&gt;To use &lt;a href=&#34;https://nodejs.org/api/modules.html&#34;&gt;CommonJS modules&lt;/a&gt;, we need to change the example slightly:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;// a.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;const&lt;/span&gt; b = require(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;./b.js&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;module.exports = &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;aloha&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;console.log(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;from a&amp;#34;&lt;/span&gt;, b);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;// b.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;const&lt;/span&gt; a = require(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;./a.js&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;module.exports = &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;bye&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;console.log(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;from b&amp;#34;&lt;/span&gt;, a);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;// index.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;const&lt;/span&gt; a = require(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;./a.js&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;console.log(a);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Running &lt;code&gt;node index.js&lt;/code&gt; results in:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;from b {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;from a bye
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;aloha
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But you also get a warning:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(node:90636) Warning: Accessing non-existent property &amp;#39;Symbol(nodejs.util.inspect.custom)&amp;#39; of module exports inside circular dependency
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(Use `node --trace-warnings ...` to show where the warning was created)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(node:90636) Warning: Accessing non-existent property &amp;#39;constructor&amp;#39; of module exports inside circular dependency
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(node:90636) Warning: Accessing non-existent property &amp;#39;Symbol(Symbol.toStringTag)&amp;#39; of module exports inside circular dependency
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That&amp;rsquo;s nice. Node doesn&amp;rsquo;t clearly tell you where the issue is (even if you run it with &lt;code&gt;--trace-warnings&lt;/code&gt;), but at least you know you have an issue.&lt;/p&gt;
&lt;h3 id=&#34;esbuild&#34;&gt;&lt;code&gt;esbuild&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;I left the best for last. Our example bundled by &lt;a href=&#34;https://esbuild.github.io/&#34;&gt;&lt;code&gt;esbuild&lt;/code&gt;&lt;/a&gt; results in:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;from b undefined
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;from a bye
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;aloha
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;No error, no warning, just the &lt;code&gt;undefined&lt;/code&gt; I alluded to at the start of this post.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;esbuild&lt;/code&gt; makes a &lt;a href=&#34;https://github.com/evanw/esbuild/issues/3808#issuecomment-2184055328&#34;&gt;performance optimization&lt;/a&gt; and &lt;a href=&#34;https://esbuild.github.io/faq/#top-level-var&#34;&gt;replaces all top-level &lt;code&gt;const&lt;/code&gt; with &lt;code&gt;var&lt;/code&gt; in the bundled code&lt;/a&gt;. This means you can access any module top-level variable even before the module initializes, but it will be &lt;code&gt;undefined&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;For completeness, this is the bundled code produced by &lt;code&gt;esbuild&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;// b.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;var&lt;/span&gt; b = &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;bye&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;console.log(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;from b&amp;#34;&lt;/span&gt;, a);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;// a.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;var&lt;/span&gt; a = &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;aloha&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;console.log(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;from a&amp;#34;&lt;/span&gt;, b);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;// index.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;console.log(a);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;delayed-circular-dependency&#34;&gt;Delayed Circular Dependency&lt;/h2&gt;
&lt;p&gt;Sometimes called &lt;em&gt;dynamic&lt;/em&gt;, &lt;em&gt;delayed&lt;/em&gt; circular dependency is more benign than its &lt;em&gt;immediate&lt;/em&gt; cousin because the modules can still initialize correctly.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Delayed&lt;/em&gt; circular dependency happens when the module&amp;rsquo;s top-level code doesn&amp;rsquo;t have circular dependencies, but the functions/methods invoked at runtime do. The dependencies are realized at runtime &lt;em&gt;after&lt;/em&gt; the code is initialized, hence the &lt;em&gt;delayed&lt;/em&gt; name.&lt;/p&gt;
&lt;p&gt;This is the simplest example:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;// a.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;import&lt;/span&gt; { b } from &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;./b.js&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;const&lt;/span&gt; a = &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;aloha&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;const&lt;/span&gt; sayA = () =&amp;gt; console.log(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;from a&amp;#34;&lt;/span&gt;, b);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;// b.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;import&lt;/span&gt; { a } from &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;./a.js&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;const&lt;/span&gt; b = &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;bye&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;const&lt;/span&gt; sayB = () =&amp;gt; console.log(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;from b&amp;#34;&lt;/span&gt;, a);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;// index.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;import&lt;/span&gt; { sayA } from &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;./a.js&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;import&lt;/span&gt; { sayB } from &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;./b.js&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sayA();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sayB();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Which results in the correct:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;from a bye
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;from b aloha
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Even though &lt;code&gt;a&lt;/code&gt; depends on &lt;code&gt;b&lt;/code&gt; and vice versa, this is not a bug because the modules don&amp;rsquo;t need each other&amp;rsquo;s top-level code to initialize.&lt;/p&gt;
&lt;p&gt;The easiest way to understand this is to look at how &lt;code&gt;esbuild&lt;/code&gt; bundles the code (the CommonJS modules and ESM work similarly).&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;// b.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;var&lt;/span&gt; b = &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;bye&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;var&lt;/span&gt; sayB = () =&amp;gt; console.log(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;from b&amp;#34;&lt;/span&gt;, a);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;// a.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;var&lt;/span&gt; a = &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;aloha&amp;#34;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;var&lt;/span&gt; sayA = () =&amp;gt; console.log(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;from a&amp;#34;&lt;/span&gt;, b);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;// index.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;sayA();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;sayB();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You see that by the time we &lt;em&gt;define&lt;/em&gt; &lt;code&gt;sayB&lt;/code&gt;, the &lt;code&gt;a&lt;/code&gt; variable is &lt;code&gt;undefined&lt;/code&gt;, but that&amp;rsquo;s not a problem because &lt;strong&gt;by the time we &lt;em&gt;run&lt;/em&gt; &lt;code&gt;sayB&lt;/code&gt;, the &lt;code&gt;a&lt;/code&gt; variable is already defined.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;prevention-is-the-best-cure&#34;&gt;Prevention Is the Best Cure&lt;/h2&gt;
&lt;p&gt;Now you understand how circular dependencies work in JavaScript, and if you don&amp;rsquo;t use &lt;code&gt;esbuild&lt;/code&gt;, maybe you&amp;rsquo;ll even get some errors/warnings when you run the code. However, these warnings are only for &lt;em&gt;immediate&lt;/em&gt; circular dependencies.&lt;/p&gt;
&lt;p&gt;But even &lt;em&gt;delayed&lt;/em&gt; circular dependencies are a code smell, making the code harder to reason about. Imagine thinking about &lt;a href=&#34;https://en.wikipedia.org/wiki/Internet_protocol_suite&#34;&gt;TCP/IP protocol layers&lt;/a&gt;, but the network (lowest) layer would have a circular dependency on the application (highest) layer, say SSH.&lt;/p&gt;
&lt;p&gt;And in production code, the circular dependency virtually always involves more than two modules (e.g., &lt;strong&gt;&lt;code&gt;a&lt;/code&gt;&lt;/strong&gt; -&amp;gt; &lt;code&gt;b&lt;/code&gt; -&amp;gt; &lt;code&gt;c&lt;/code&gt; -&amp;gt; &lt;code&gt;d&lt;/code&gt; -&amp;gt; &lt;strong&gt;&lt;code&gt;a&lt;/code&gt;&lt;/strong&gt;), so you won&amp;rsquo;t spot it during development or code review.&lt;/p&gt;
&lt;p&gt;But cyclic dependencies can be found by static analysis. And that&amp;rsquo;s exactly what the &lt;a href=&#34;https://github.com/import-js/eslint-plugin-import/blob/main/docs/rules/no-cycle.md&#34;&gt;&lt;code&gt;import/no-cycle&lt;/code&gt; &lt;code&gt;eslint&lt;/code&gt; rule&lt;/a&gt; does. I strongly recommend installing the &lt;code&gt;eslint-plugin-import&lt;/code&gt; node module to your ESLint and using the &lt;code&gt;import/no-cycle&lt;/code&gt; rule to prevent both &lt;em&gt;immediate&lt;/em&gt; and &lt;em&gt;delayed&lt;/em&gt; circular dependencies.&lt;/p&gt;
&lt;p&gt;You can find all the code from this post in my &lt;a href=&#34;https://gitlab.com/viktomas/circular-dependencies-showcase&#34;&gt;viktomas/circular-dependencies-showcase&lt;/a&gt; project.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Jornad Mechner - The Making of Prince of Persia</title>
      <link>https://blog.viktomas.com/graph/jordan-mechner--making-of-prince-of-persia/</link>
      <pubDate>Thu, 11 Jul 2024 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/jordan-mechner--making-of-prince-of-persia/</guid>
      <description>&lt;ul&gt;
&lt;li&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/jordan-mechner--making-of-prince-of-persia.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;
&lt;a href=&#34;https://www.goodreads.com/book/show/52824295-the-making-of-prince-of-persia&#34;&gt;Goodreads&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;My rating: ★★★☆☆ (60%)&lt;/p&gt;
&lt;p&gt;Jordan deserves kudos for publishing an unfiltered journal from his early twenties without censoring it. It&amp;rsquo;s a brave move.&lt;/p&gt;
&lt;h2 id=&#34;the-engaging-nature-of-jordans-writing-style&#34;&gt;The engaging nature of Jordan&amp;rsquo;s writing style&lt;/h2&gt;
&lt;p&gt;Jordan&amp;rsquo;s writing impressed me and I&amp;rsquo;ll adjust my journaling style after reading this book. That&amp;rsquo;s the main reason you should read the book: &lt;strong&gt;To see how engaging a journal can be if you write it like normal prose: adding suspense, jokes, and a lot of emotion.&lt;/strong&gt; Sometimes he mentioned important world events as a background for his journal.&lt;/p&gt;
&lt;h2 id=&#34;what-the-book-doesnt-cover&#34;&gt;What the book doesn&amp;rsquo;t cover&lt;/h2&gt;
&lt;p&gt;If you want to know technical details about making games in the 80s and 90s, this book won&amp;rsquo;t help you. The book didn&amp;rsquo;t describe the process of making the game itself in detail, so it didn&amp;rsquo;t satisfy my curiosity as a software engineer. It reads more like a soap opera about Jordan&amp;rsquo;s relationships and emotions as he made PoP.&lt;/p&gt;
&lt;p&gt;I learned several interesting things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Making a game back then was often a one-person job&lt;/li&gt;
&lt;li&gt;The lead programmer could expect roughly a 10% royalty&lt;/li&gt;
&lt;li&gt;Jordan had a very entrepreneurial mind, thinking about how to earn more money at every step&lt;/li&gt;
&lt;li&gt;Jordan showed more interest in filmmaking than game-making&lt;/li&gt;
&lt;li&gt;When making PoP, Jordan believed that the computer game market might be ending&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;jordans-analysis-of-successful-80s-games&#34;&gt;Jordan&amp;rsquo;s analysis of successful 80s games&lt;/h2&gt;
&lt;p&gt;Jordan provided an interesting analysis of the characteristics of successful 80s games:&lt;/p&gt;
&lt;blockquote&gt;
&lt;ol&gt;
&lt;li&gt;You can tell at any moment, by glancing at the screen, how close you are to finishing, how much is left.&lt;/li&gt;
&lt;li&gt;There are setbacks and successes on the road to ultimate success. You get a smaller version of the “Whew! Did it!” when, say, you clear a difficult area (Pac-Man), or drive a guard back with a series of blows (Karateka), or retrieve a hard-to-get sack (Lode Runner). Conversely, you get the “Oh, shit…” reaction when you accidentally split up a bunch of bigger asteroids into more smaller, faster ones; or when you finish a pattern and see that you’ve missed one dot; etc. Some setbacks are fatal, some are just irritating. But when they happen, you feel they’re your own fault.&lt;/li&gt;
&lt;li&gt;You can hold off on the next task, waiting for the right moment, before saying “OK… Now” and going for it… plunging into a period of higher tension, higher chance of either a setback or success.&lt;/li&gt;
&lt;/ol&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Overall, I would not read the whole book again; I recommend skimming through it. The first third is, in my opinion, the most interesting.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>James Gleick - Isaac Newton</title>
      <link>https://blog.viktomas.com/graph/james-gleick--isaac-newton/</link>
      <pubDate>Tue, 25 Jun 2024 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/james-gleick--isaac-newton/</guid>
      <description>&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/james-gleick--isaac-newton.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;
&lt;a href=&#34;https://www.goodreads.com/book/show/17098.Isaac_Newton&#34;&gt;Goodreads&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My rating: ★★☆☆☆ (40%)&lt;/p&gt;
&lt;p&gt;I wanted to read Newton&amp;rsquo;s biography because I&amp;rsquo;ve listened to a lecture about him and realized I know little about how Newton made his scientific discoveries.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;h2 id=&#34;its-a-hard-read&#34;&gt;It&amp;rsquo;s a hard read&lt;/h2&gt;
&lt;p&gt;This book helped me, but it was disappointing how hard it was to read it. It tried to be poetic with a &lt;em&gt;heavy citation of resources&lt;/em&gt; from Newton&amp;rsquo;s age. This gave the book an aura of authenticity and authority, but it also made it hard to understand.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2 id=&#34;interesting-facts-i-learned&#34;&gt;Interesting facts I learned&lt;/h2&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;newtons-life&#34;&gt;Newton&amp;rsquo;s life&lt;/h3&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Newton was super introverted and antisocial.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Newton was petty and never forgot a grudge.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;From the book, I got a sense that he remained celibate not because of choice but because of social skills.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;newtons-discoveries&#34;&gt;Newton&amp;rsquo;s discoveries&lt;/h3&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;He found out about white light being made out of different colors by using a prism and trying to split the already-split colors.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;He discovered calculus thanks to his interest in infinitely small numbers.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;There existed no good concept of mass in his time, &lt;strong&gt;he had to define that term&lt;/strong&gt;. This impressed me more than anything. He discovered concepts that his language didn&amp;rsquo;t support.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;His most important book is &amp;ldquo;Philosophiæ Naturalis Principia Mathematica&amp;rdquo;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This introduced his 3 laws&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I wouldn&amp;rsquo;t recommend this book as the first Newton biography to read.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2 id=&#34;private&#34;&gt;private&lt;/h2&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h2 id=&#34;highlights&#34;&gt;Highlights&lt;/h2&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;1-what-imployment-is-he-fit-for&#34;&gt;1. What Imployment Is He Fit For?&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Barnabas Smith, a wealthy man twice her age. Smith wanted a wife, not a stepson; under the negotiated terms of their marriage Hannah abandoned Isaac in the Woolsthorpe house, leaving him to his grandmother’s care.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;The triumphant Puritans rejected absolutism and denied the divine right of the monarchy. In 1649, soon after Isaac turned six, Charles Stuart, the king, was beheaded at the wall of his palace.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Nevertheless, in the fall of 1659, when Isaac was sixteen years old, his mother summoned him home to be a farmer.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;2-some-philosophical-questions&#34;&gt;2. Some Philosophical Questions&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;subsizars, who earned their keep by menial service to other students, running errands, waiting on them at meals, and eating their leftovers&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;The widowed Hannah Smith was wealthy now, by the standards of the countryside, but chose to provide her son little money; he entered Trinity College as a subsizar.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;“Everything that is in motion must be moved by something,” Aristotle asserted (and proved, by knotted logic).&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Gunners understood that a cannonball, once in flight, was no longer moved by anything but a ghostly memory of the explosion inside the iron barrel; and they were learning, roughly, to compute the trajectories of their projectiles. Pendulums, in clockwork, however crude, demanded a mathematical view of motion. And in turn the clockwork made measurement possible—&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Although the library of Trinity College had more than three thousand books, students could enter only in the company of a fellow. Still, Newton found his way to new ideas and polemics: from the French philosopher René Descartes, and the Italian astronomer Galileo Galilei, who had died in the year of Newton’s birth. Descartes proposed a geometrical and mechanical philosophy. He imagined a universe filled throughout with invisible substance, forming great vortices that sweep the planets and stars forward. Galileo, meanwhile, applied geometrical thinking to the problem of motion. Both men defied Aristotle explicitly—&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Galileo created a concept of uniform acceleration. He considered motion as a state rather than a process. Without ever using a word such as inertia, he nonetheless conceived that bodies have a tendency to remain in motion or to remain motionless. The next step demanded experiment and measure. He measured time with a water-clock. He rolled balls down ramps and concluded, wrongly, that their speed varied in proportion to the distance they rolled.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Newton began to absorb this, at second or third hand; Galileo had written mostly in Italian, a language few in England could read.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;But light itself played a delicate part in the Cartesian scheme, and Newton, attempting to take Descartes literally, already sensed contradictions. Pressure does not restrict itself to straight lines; vortices whirl around corners. “Light cannot be by pression,” Newton asserted, “for then wee should see in the night a[s] wel or better than in the day we should se[e] a bright light above us becaus we are pressed downewards.…” Eclipses should never darken the sky.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Another elusive word, gravity, began to appear in the Questiones. Its meanings darted here and there. It served as half of a linked pair: Gravity &amp;amp; Levity. It represented the tendency of a body to descend, ever downward. But how could this happen? “The matter causing gravity must pass through all the pores of a body. It must ascend againe, for else the bowells of the earth must have had large cavitys &amp;amp; inanitys to containe it in.…”19 It must be crowded in that unimaginable place, the center of the earth—all the world’s streams coming home. “When the streames meet on all sides in the midst of the Earth they must needs be coarcted into a narrow roome &amp;amp; closely press together.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;he sketched a balance scale. He speculated about “rays of gravity.” Then, gravity could also refer to a body’s tendency to move, not downward, but in any direction;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Violent motion is made continued either by the aire or by motion force imprest or by the natural gravity in the body moved.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Yet how could the cannonball be helped along by the air? He noted that the air crowds more upon the front of a projectile than on the rear, “&amp;amp; must therefore rather hinder it.” So the continuing motion must come from some natural tendency in the object. But—gravity?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;3-to-resolve-problems-by-motion&#34;&gt;3. To Resolve Problems by Motion&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;wollstrup may the 6. 16654
The colleges of Cambridge began shutting down. Fellows and students dispersed into the countryside&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;As Newton learned Latin and Greek, he experimented with shorthand alphabets and phonetic writing, and when he entered Trinity College he wrote down a scheme for a “universal” language, based on philosophical principles, to unite the nations of humanity. “The Dialects of each Language being soe divers &amp;amp; arbitrary,” he declared, “a generall Language cannot bee so fitly deduced from them as from the natures of things themselves.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;symbols came equations: relations between quantities, and changeable relations at that. This was new territory, and Descartes exploited it. He treated one unknown as a spatial dimension, a line; two unknowns thus define a plane. Line segments could now be added and even multiplied. Equations generated curves; curves embodied equations&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;He taught himself to find real and complex roots of equations and to factor expressions of many terms—polynomials. When the infinite number of points in a curve correspond to the infinite solutions of its equation, then all the solutions can be seen at once, as a unity. Then equations have not just solutions but other properties: maxima and minima, tangents and areas. These were visualized, and they were named.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Newton’s patience was limitless. Truth, he said much later, was “the offspring of silence and meditation.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;On one page he drew a hyperbola and set about calculating the area under it—“squaring” it. He stepped past the algebra Descartes knew. He would not confine himself to expressions of a few (or many) terms; instead he constructed infinite series: expressions that continue forever.17 An infinite series need not sum to infinity; rather, because the terms could grow smaller and smaller, they could close in on a goal or limit. He conceived such a series to square the hyperbola—
—and carried out the calculation to fifty-five decimal places:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Mathematicians had a glimmering notion of how to raise the sum of two quantities, a + b, to some power. Through infinite series, Newton discovered in the winter of 1664 how to expand such sums to any power, integer or not: the general binomial expansion.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;special aspect of infinity troubled Newton; he returned to it again and again, turning it over, restating it with new definitions and symbols. It was the problem of the infinitesimal—the quantity, impossible and fantastic, smaller than any finite quantity, yet not so small as zero&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;could not escape it, so he pressed it into service, employing a private symbol—a little o—for this quantity that was and was not zero. In some of his diagrams, two lengths differed “but infinitely little,” while two other lengths had “no difference at all.” It was essential to preserve this uncanny distinction. It enabled him to find areas by infinitely partitioning curves and infinitely adding the partitions. He created “a Method whereby to square those crooked lines which may bee squared”26—to integrate (in the later language of the calculus&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;paradox of Achilles and the tortoise. The tortoise has a head start. Achilles can run faster but can never catch up, because each time he reaches the tortoise’s last position, the tortoise has managed to crawl a bit farther ahead. By this logic Zeno proved that no moving body could ever reach any given place&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;culture lacking technologies of time and speed also lacked basic concepts that a mathematician needed to quantify motion. The English language was just beginning to adapt its first unit of velocity: the term knot, based on the sailor’s only speed-measuring device, the log line heaved into the sea. The science most eager to understand the motion of earthly objects, ballistics, measured the angles of gun barrels and the distances their balls traveled, but scarcely conceived of velocity; even when they could define this quantity, as a ratio of distance and time, they could not measure it&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;geometrical task matched a kinetic task: to measure curvature was to find a rate of change. Rate of change was itself an abstraction of an abstraction; what velocity was to position, acceleration was to velocity. It was differentiation (in the later language of the calculus&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Repeatedly he started a new page—in November 1665, in May 1666, and in October 1666—in order to essay a system of propositions needed “to resolve Problems by motion.”34 On his last attempt he produced a tract of twenty-four pages, on eight sheets of paper folded and stitched together.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;In creating this mathematics Newton embraced a paradox. He believed in a discrete universe. He believed in atoms, small but ultimately indivisible—not infinitesimal. Yet he built a mathematical framework that was not discrete but continuous, based on a geometry of lines and smoothly changing curves. “All is flux, nothing stays still,” Heraclitus had said two millennia before. “Nothing endures but change.” But this state of being—in flow, in change—defied mathematics then and afterward.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;The new king, Charles II—having survived his father’s beheading and his own fugitive years, and having outlasted the Lord Protector, Cromwell—fled London with his court.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;4-two-great-orbs&#34;&gt;4. Two Great Orbs&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;1543, just before his death, Nicolaus Copernicus, Polish astronomer, astrologer, and mathematician, published the great book De Revolutionibus Orbium Coelestium (“On the Revolutions of the Heavenly Spheres”). In it he gave order to the planets’ paths, resolving them into perfect circles; he set the earth in motion and placed an immobile sun at the center of the universe.4&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Johannes Kepler, looking for more order in a growing thicket of data, thousands of painstakingly recorded observations, declared that the planets could not be moving in circles. He suspected the special curves known to the ancients as ellipses.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Galileo Galilei took spy-glasses—made by inserting spectacle makers’ lenses into a hollow tube—and pointed them upward toward the night sky. What he saw both inspired and disturbed him: moons orbiting Jupiter;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Newton knew how big the moon was and how far away. By virtue of a coincidence, the moon’s apparent size was almost exactly the same as the sun’s, about one-half degree of arc, the coincidence that makes a solar eclipse such a perfect spectacle.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Newton could see other globes, dangling from their stems. A two-inch apple at a distance of twenty feet subtended the same half-degree in the sky. These ratios were second nature now, the congruent Euclidean triangles inscribed in his mind’s eye.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;An apple was no sphere, but he understood it to be flying through space along with the rest of the earth’s contents, spinning across 25,000 miles each day. Why, then, did it hang gently downward, instead of being flung outward like a stone whirled around on a string? The same question applied to the moon: what pushed it or pulled it away from a straight path?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Many years later Newton told at least four people that he had been inspired by an apple in his Woolsthorpe garden—perhaps an apple actually falling from a tree, perhaps not.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;I began to think of gravity extending to the orb of the Moon …&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;computed the force requisite to keep the Moon in her Orb with the force of gravity at the surface of the earth … &amp;amp; found them answer pretty nearly. All this was in the two plague years of 1665–1666. For in those days I was in the prime of my age for invention &amp;amp; minded Mathematicks and Philosophy more than at any time since.17&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Nor did Newton comprehend universal gravitation in a flash of insight. In 1666 he was barely beginning to understand. What he suspected about gravity he kept private for decades to come.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;He took the mile to be 5,000 feet.20 He set one degree of the earth’s latitude at the equator equal to sixty miles, an error of about 15 percent. Some units were English, some antique Latin, others Italian: mile, passus, brace, pedes. He came up with a datum for the speed of the revolving earth: 16,500,000 cubits in six hours.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Yet, with the data he had, he could not quite make the numbers work. He still found it necessary to attribute some of the moon’s motion to the vortices of Descartes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;If a quantity once move it will never rest unlesse hindered by some externall caus.
2. A quantity will always move on in the same streight line (not changing the determination nor celerity of its motion) unless some externall cause divert it.26&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;He continued through dozens more axioms, comprising a logical whole, but a tangled one. He was hampered by the chaos of language—words still vaguely defined and words not quite existing.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;twenty-four, Newton believed he could marshal a complete science of motion, if only he could find the appropriate lexicon, if only he could set words in the correct order&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;5-bodys--senses&#34;&gt;5. Bodys &amp;amp; Senses&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;With this paradox in mind, Newton, experimental philosopher, slid a bodkin into his eye socket between eyeball and bone. He pressed with the tip until he saw “severall white darke &amp;amp; coloured circles.…&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;6-the-oddest-if-not-the-most-considerable-detection&#34;&gt;6. The Oddest If Not the Most Considerable Detection&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Barrow showed him a new book from London, Logarithmotechnia, by Nicholas Mercator, a mathematics tutor and member of the Royal Society. It presented a method of calculating logarithms from infinite series and thus gave Newton a shock: his own discoveries, rediscovered.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;infinite series he had worked out at Woolsthorpe. Provoked, he revealed to Barrow a bit more of what he knew. He drafted a paper in Latin, “On Analysis by Infinite Series.” He also let Barrow post this to another Royal Society colleague, a mathematician, John Collins,4 but he insisted on anonymity. Only after Collins responded enthusiastically did he let Barrow identify him: “I am glad my friends paper giveth you so much satisfaction. his name is Mr Newton; a fellow of our College, &amp;amp; very young … but of an extraordinary genius and proficiency in these things.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Yet Newton knew what Barrow did not: that the whole project wanted correction.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Anyway, Barrow had ambitions elsewhere. He was a favorite of the king, hoped for advancement, and thought of himself more as a theologian than a mathematician. Before the end of the year, he resigned his post as Lucasian professor, yielding it to Newton, twenty-seven years old.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;7-reluctancy-and-reaction&#34;&gt;7. Reluctancy and Reaction&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;The crucial idea was to isolate a beam of colored light and send that through a prism. For this he needed a pair of prisms and a pair of boards pierced with holes&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Most persuasive, though, was that the second prism never created new colors or altered the colors shining from the first prism.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;“And so the true cause of the length of that Image was detected,” Newton declared triumphantly—“that Light consists of Rays differently refrangible.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Above all: white light is a heterogeneous mixture.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Fifteen months after his election to the Royal Society, Newton announced that he wished to withdraw—and not just from the society but from all correspondence&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Oldenburg did not hear from him again for more than two years&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;had discovered a great truth of nature. He had proved it and been disputed. He had tried to show how science is grounded in concrete practice rather than grand theories. In chasing a shadow, he felt, he had sacrificed his tranquillity&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;8-in-the-midst-of-a-whirlwind&#34;&gt;8. In the Midst of a Whirlwind&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Hooke grew irate. In evenings that followed he met with friends in coffee-houses and told them that Newton had commandeered his pulse theory. After all, Newton was talking about color in terms of “vibrations of unequal bignesses.” Large vibrations are red—or, as he said more carefully, cause the sensation of red. Short vibrations produce violet. The only difference between colors was this: a slight, quantifiable divergence in the magnitude of vibration. Newton did not speak of waves. Nor for that matter had Hooke: waves were still a phenomenon of the sea. A lack of vocabulary hindered both men;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;9-all-things-are-corruptible&#34;&gt;9. All Things Are Corruptible&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;He feared disease—plague and pox—and treated himself preemptively by drinking a self-made elixir of turpentine, rosewater, olive oil, beeswax, and sack. In fact he was poisoning himself, slowly, by handling mercury&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;the Newtonian world of formal, institutionalized science, it became disreputable.
But Newton belonged to the pre-Newtonian world&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Over time, mercury builds up in the body, causing neurological damage: tremors, sleeplessness, and sometimes paranoid delusions.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;The virtuosi of the Royal Society wished to remove themselves from charlatans, to build all explanations from reason and not miracles. But magic persisted. Astronomers still doubled as astrologers; Kepler and Galileo had trafficked in horoscopes.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;There were forces in nature that he would not be able to understand mechanically, in terms of colliding billiard balls or swirling vortices. They were vital, vegetable, sexual forces—invisible forces of spirit and attraction. Later, it had been Newton, more than any other philosopher, who effectively purged science of the need to resort to such mystical qualities. For now, he needed them.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;When he was not stoking his furnaces and stirring his crucibles, he was scrutinizing his growing hoard of alchemical literature. By the century’s end, he had created a private Index chemicus, a manuscript of more than a hundred pages, comprising more than five thousand individual references to writings on alchemy spanning centuries. This, along with his own alchemical writing, remained hidden long after his death.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;10-heresy-blasphemy-idolatry&#34;&gt;10. Heresy, Blasphemy, Idolatry&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;But in the seventh year of his fellowship, 1675, a further step would be required: he would take holy orders and be ordained to the Anglican clergy, or he would face expulsion. As the time approached, he realized that he could no longer affirm his orthodoxy. He would not be able to take a false oath. He prepared to resign.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;The very existence of the Bible in English—long opposed by the church establishment and finally authorized only a generation before Newton’s birth—had inspired the Puritan cause.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;At the last moment, in 1675, Newton’s precarious position at Cambridge was rescued. The king granted his request for a dispensation, an act that released the Lucasian professorship, in perpetuity, from the obligation to take holy orders.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;He would not even label years as AD, preferring AC: Christ, but not the Lord. Jesus was more than a man but less than God. He was God’s son, a mediator between God and humanity,&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;11-first-principles&#34;&gt;11. First Principles&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Whatever comets were, omens or freaks, their singularity was taken for granted: each glowing visitor arrived, crossed the sky in a straight path, and departed, never to be seen again. Kepler had said this authoritatively, and what else could a culture of short collective memory believe?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Instead he suggested that the comet could have gone all the way around the sun and then returned.10 He diagrammed this alternative, too. And he conceded a crucial point to Flamsteed’s intuition: “I can easily allow an attractive power in the whereby the Planets are kept in their courses about him from going away in tangent lines.”
He had never before said this so plainly.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Hooke’s essay offered a “System of the World.”13 It paralleled much of Newton’s undisclosed thinking about gravity and orbits in 1666, though Hooke’s system lacked a mathematical foundation. All celestial bodies, Hooke supposed, have “an attraction or gravitating power towards their own centers.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Hooke pounced. Having promised days earlier to keep their correspondence private, he now read Newton’s letter aloud to the Royal Society and publicly contradicted it&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Both men were thinking in terms of a celestial attractive force, binding planets to the sun and moons to the planets.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Hooke and Newton had both jettisoned the Cartesian notion of vortices. They were explaining the planet’s motion with no resort to ethereal pressure (or, for that matter, resistance). They had both come to believe in a body’s inherent force—its tendency to remain at rest or in motion—a concept for which they had no name.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Hooke finally did put this to Newton: “My supposition is that the Attraction always is in a duplicate proportion to the Distance from the Center Reciprocall”—that is, inversely as the square of distance.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;now remaines to know the proprietys of a curve Line … made by a centrall attractive power … in a Duplicate proportion to the Distances reciprocally taken&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Hooke had finally formulated the problem exactly. He acknowledged Newton’s superior powers. He set forth a procedure: find the mathematical curve, suggest a physical reason. But he never received a reply.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Hooke asserted that he could show how to base all celestial motion on the inverse-square law and that he was keeping the details secret for now, until more people had tried and failed; only then would they appreciate his work.22 Halley doubted that Hooke knew as much as he claimed.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;He wrote only in Latin now, the words less sullied by everyday use. &lt;strong&gt;Quantitas materiæ—quantity of matter. What did this mean exactly? He tried: “that which arises from its density and bulk conjointly.” Twice the density and twice the space would mean four times the amount of matter. Like weight, but weight would not do&lt;/strong&gt;; he could see ahead to traps of circular reasoning. Weight would depend on gravity, and gravity could not be presupposed. So, quantity of matter: “This quantity I designate under the name of body or mass.”23 Then, quantity of motion: the product of velocity and mass. And force—innate, or impressed, or “centripetal”—a coinage, to mean action toward a center.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;For the reasoning to come, he needed a foundation of words that did not exist in any language.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;A fever possessed him, like none since the plague years. He ate mainly in his room, a few bites standing up. He wrote standing at his desk. When he did venture outside, he would seem lost,&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;specially understood and owned by the virtuosi—the scientists.
Absolute, true, and mathematical time, in and of itself, and of its own nature, without reference to anything external, flows uniformly.…&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;12-every-body-perseveres&#34;&gt;12. Every Body Perseveres&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;After much discussion the council members did vote to order the Principia printed—but by Halley, at his own expense. They offered him leftover copies of History of Fishes in place of his salary. No matter. The young Halley was a believer&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Without further ado, having defined his terms, Newton announced the laws of motion.
Law 1. Every body perseveres in its state of being at rest or of moving uniformly straight forward, except insofar as it is compelled to change its state by forces impressed. A cannonball would fly in a straight line forever, were it not for air resistance and the downward force of gravity. The first law stated, without naming, the principle of inertia, Galileo’s principle, refined. Two states—being at rest and moving uniformly—are to be treated as the same. If a flying cannonball embodies a force, so does the cannonball at rest.
Law 2. A change in motion is proportional to the motive force impressed and takes place along the straight line in which that force is impressed. Force generates motion, and these are quantities, to be added and multiplied according to mathematical rules.
Law 3. To any action there is always an opposite and equal reaction; in other words, the actions of two bodies upon each other are always equal and always opposite in direction. If a finger presses a stone, the stone presses back against the finger. If a horse pulls a stone, the stone pulls the horse. Actions are interactions—no preference of vantage point to be assigned. If the earth tugs at the moon, the moon tugs back.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Newton formed his argument in classic Greek geometrical style: axioms, lemmas, corollaries; Q.E.D. As the best model available for perfection in knowledge, it gave his physical program the stamp of certainty. He proved facts about triangles and tangents, chords and parallelograms, and from there, by a long chain of argument, proved facts about the moon and the tides.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;He had to create a dynamics for velocities changing from moment to moment, both in magnitude and in direction, in three dimensions. No philosopher had ever conceived such a thing, much less produced it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;The force points toward the centers of bodies, not because of anything special in the centers, but as a mathematical consequence of this final claim: that every particle of matter in the universe attracts every other particle. From this generalization all the rest followed. Gravity is universal.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;He explained the slow precession of the earth’s rotation axis, the third and most mysterious of its known motions. Like a top slightly off balance, the earth changes the orientation of its axis against the background of the stars, by about one degree every seventy-two years. No one had even guessed at a reason before. Newton computed the precession as the complex result of the gravitational pull of the sun and moon on the earth’s equatorial bulge.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;but the pattern of two high tides per twenty-five hours was clear and global. Newton marshaled the data and made his theoretical claim. The moon and sun both pull the seas; their combined gravity creates the tides by raising a symmetrical pair of bulges on opposite sides of the earth.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;But the mechanical philosophy already had rules, and Newton was flouting one of them in spectacular fashion. Physical causes were supposed to be direct: matter striking or pressing on matter,&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;It could not be denied, even if its essence could not be understood&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;13-is-he-like-other-men&#34;&gt;13. Is He Like Other Men?&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Halley heralded the Principia in 1687 with the announcement that its author had “at length been prevailed upon to appear in Publick.”2 Indeed, Newton, in his forty-fifth year, became a public man. Willy-nilly he began to develop into the eighteenth-century icon of later legend.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;The King asserted his authority over this bastion of Protestantism by issuing royal mandates, placing Catholics as fellows and college officers. Tensions rose—the abhorrence of popery was written into Cambridge’s statutes as well as its culture.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Newton abandoned his Cambridge cloister for good in 1696. His smoldering ambition for royal preferment was fulfilled. Trinity had been his home for thirty-five years, but he departed quickly and left no friends behind.35 As he emphatically told Flamsteed, he was now occupied by the King’s business. He had taken charge of the nation’s coin.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;14-no-man-is-a-witness-in-his-own-cause&#34;&gt;14. No Man Is a Witness in His Own Cause&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;Newton grew rich himself, as Warden and then, from 1700 onward, Master. (From his first months he complained to the Treasury about his remuneration,9 but as Master he received not only a salary of £500 but also a percentage of every pound coined, and these sums were far greater.)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Newton often opposed such pardons. Counterfeiting was difficult to prove; he had himself made a Justice of the Peace and oversaw prosecutions himself, all the way to the gallows. William Chaloner not only coined his own guineas but tried to cover his tracks by accusing the Mint of making its own false money. Newton, managing a network of agents and prison informers, ensured that he was hanged&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;For the coronation of Queen Anne, in 1702, he manufactured medals of gold and silver, for which he billed the Treasury, twice, precisely £2,485 18s. 3½d.18 It was three years later, by Her Majesty’s Special Grace, that he was knighted.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;His return to the Royal Society had waited, all these years, for Hooke’s exit. Hooke died in March 1703; within months Newton was chosen president.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;He presented it to the Royal Society with an “Advertisement” in which he explained why he had suppressed this work since 1675. The reason: “To avoid being engaged in Disputes.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;He was charging his heirs and followers with a mission, the perfection of natural philosophy. He left them a task of further study, “the Investigation of difficult Things by the Method of Analysis.”28 They need only follow the signs and the method&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Newton declared not only that he had made his discoveries by 1666 but also that he had described them to Leibniz. He released the correspondence, anagrams and all.39 Soon an anonymous counterattack appeared in Acta Eruditorum suggesting that Newton had employed Leibniz’s methods, though calling them “fluxions” instead of “Leibnizian differences.” This anonymous reviewer was Leibniz.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;The principals joined the fray openly in 1711. A furious letter from Leibniz arrived at the Royal Society, where it was read aloud and “deliver’d to the President to consider the contents thereof.”41 The society named a committee to investigate “old letters and papers.”42 Newton provided these. Early correspondence with John Collins came to light; Leibniz had seen some of it, all those years before. The committee produced a document without precedent: a detailed, analytical history of mathematical discovery.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;vindicated Newton with eloquence and passion, and no wonder: Newton was its secret author&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Newton understood the truth full well: that he and Leibniz had created the calculus independently. Leibniz had not been altogether candid about what he had learned from Newton—in fragments, and through proxies—but the essence of the invention was his.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;In a young and suddenly fertile field like the mathematics of the seventeenth century, discoveries had lain waiting to be found again and again by different people in different places.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;“Grown men, brilliant and powerful, betrayed their friends, lied shamelessly to their enemies, uttered hateful chauvinistic slurs, and impugned each others’ characters.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Watching over the minting of a nation’s coin, catching a few counterfeiters, increasing an already respectably sized personal fortune, being a political figure, even dictating to one’s fellow scientists: it should all seem a crass and empty ambition once you have written a Principia.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;15-the-marble-index-of-a-mind&#34;&gt;15. The Marble Index of a Mind&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;The Principia marked a fork in the road: thenceforth science and philosophy went separate ways. Newton had removed from the realm of metaphysics many questions about the nature of things—about what exists—and assigned them to a new realm, physics. “This preparation being made,” he declared, “we argue more safely.”26 And less safely, too: by mathematizing science, he made it possible for its facts and claims to be proved wrong.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;This vulnerability was its strength. By the early nineteenth century Georges Cuvier was asking enviously, “Should not natural history also one day have its Newton&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;The observer whom Einstein and his followers returned to science scarcely resembled the observer whom Newton had removed. That medieval observer had been careless and vague; time was an accumulation of yesterdays and tomorrows, slow and fast, nothing to be measured or relied upon. Time and space had first to be rescued—made absolute, true, and mathematical&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;“Newton was not the first of the age of reason,” Keynes told a few students and fellows in a shadowed room at Trinity College. “He was the last of the magicians, the last of the Babylonians and Sumerians, the last great mind which looked out on the visible and intellectual world with the same eyes as those who began to build our intellectual inheritance rather less than 10,000 years ago.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;On his deathbed he refused the sacrament of the church. Nor could a pair of doctors ease his pain. He died early Sunday morning, March 19, 1727. On Thursday the Royal Society recorded in its Journal Book, “The Chair being Vacant by the death of Sir Isaac Newton there was no Meeting this Day.”&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;In eighty-four years he had amassed a fortune:&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>TypeScript Dependency Injection using ES Decorators</title>
      <link>https://blog.viktomas.com/graph/typescript-di-es-decorators/</link>
      <pubDate>Sat, 15 Jun 2024 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/typescript-di-es-decorators/</guid>
      <description>&lt;p&gt;This post shows how to create a dependency injection (DI) mini-framework using the new &lt;a href=&#34;https://github.com/tc39/proposal-decorators&#34;&gt;ES decorators&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Most TypeScript DI frameworks use the legacy TypeScript experimental decorators. This feature likely won&amp;rsquo;t leave the experimental stage. TypeScript now uses the ES decorator standard by default.&lt;/p&gt;
&lt;p&gt;Now is the time to use the new standard. &lt;code&gt;esbuild&lt;/code&gt; recently added decorator support, so if your project uses &lt;code&gt;esbuild&lt;/code&gt; for bundling, you can use decorators.&lt;/p&gt;
&lt;h2 id=&#34;what-are-decorators&#34;&gt;What are decorators?&lt;/h2&gt;
&lt;p&gt;A decorator is a &lt;code&gt;@&lt;/code&gt; prefixed function call that can enhance classes.&lt;/p&gt;
&lt;p&gt;This is the first example in &lt;a href=&#34;https://github.com/tc39/proposal-decorators&#34;&gt;the specification&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;&#34;&gt;@&lt;/span&gt;defineElement(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;my-class&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;class&lt;/span&gt; C &lt;span style=&#34;color:#00f&#34;&gt;extends&lt;/span&gt; HTMLElement {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;&#34;&gt;@&lt;/span&gt;reactive accessor clicked = &lt;span style=&#34;color:#00f&#34;&gt;false&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The key thing is that decorators are plain functions called by the runtime with arguments based on what part of the class they decorate.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;defineElement&lt;/code&gt; from above is a function that returns a function with this signature:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;type&lt;/span&gt; ClassDecorator = (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  value: &lt;span style=&#34;color:#2b91af&#34;&gt;Function&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  context: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    kind: &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#39;class&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    name: &lt;span style=&#34;color:#2b91af&#34;&gt;string&lt;/span&gt; | &lt;span style=&#34;color:#00f&#34;&gt;undefined&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    addInitializer(initializer: () =&amp;gt; &lt;span style=&#34;color:#00f&#34;&gt;void&lt;/span&gt;): &lt;span style=&#34;color:#00f&#34;&gt;void&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;) =&amp;gt; Function | &lt;span style=&#34;color:#00f&#34;&gt;void&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The implementation could look like:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;const&lt;/span&gt; defineElement = (name) =&amp;gt; (value, context) =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    console.log(&lt;span style=&#34;color:#a31515&#34;&gt;`I decorated class &lt;/span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;${&lt;/span&gt;context.name&lt;span style=&#34;color:#a31515&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#a31515&#34;&gt; with &lt;/span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;${&lt;/span&gt;name&lt;span style=&#34;color:#a31515&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;`&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And at runtime, you&amp;rsquo;d see the &lt;code&gt;I decorated class C with my-class&lt;/code&gt; log message.&lt;/p&gt;
&lt;p&gt;To play with decorators locally, you can &lt;a href=&#34;https://esbuild.github.io/getting-started/&#34;&gt;install &lt;code&gt;esbuild&lt;/code&gt;&lt;/a&gt; or check out this &lt;a href=&#34;https://gitlab.com/viktomas/di&#34;&gt;setup project&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;See the &lt;a href=&#34;#references&#34;&gt;References&lt;/a&gt; section for more resources to understand the standard better.&lt;/p&gt;
&lt;h2 id=&#34;designing-the-injectable-decorator&#34;&gt;Designing the &lt;code&gt;@Injectable&lt;/code&gt; decorator&lt;/h2&gt;
&lt;p&gt;Now that we covered decorators, we can design the DI mini-framework. Our requirements are:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;We should be able to &lt;strong&gt;decorate any class&lt;/strong&gt; without changing it.&lt;/li&gt;
&lt;li&gt;The decorator captures the &lt;strong&gt;class&amp;rsquo; interface and dependencies&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;The decorator must be &lt;strong&gt;type-safe&lt;/strong&gt;. If the decorator types don&amp;rsquo;t match the class types, the compiler must fail.&lt;/li&gt;
&lt;li&gt;The DI container initializes the decorated classes so the class&amp;rsquo; dependencies are initialized first.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The trickiest requirement is type-safety. That will need some TypeScript type sorcery.&lt;/p&gt;
&lt;h3 id=&#34;branding-types&#34;&gt;Branding types&lt;/h3&gt;
&lt;p&gt;TypeScript removes all type information and produces plain JavaScript. &lt;code&gt;esbuild&lt;/code&gt; does the same. So we need a way to preserve the type information past compilation. A commonly used mechanism is called branded types.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s start with an example interface.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;interface&lt;/span&gt; A {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  field: &lt;span style=&#34;color:#2b91af&#34;&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;code&gt;A&lt;/code&gt; interface is only used for type-checking and is removed at runtime.&lt;/p&gt;
&lt;p&gt;But we want to use it at runtime like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;@Injectable&lt;/span&gt;(A)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;class&lt;/span&gt; AImpl &lt;span style=&#34;color:#00f&#34;&gt;implements&lt;/span&gt; A {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  field = &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#39;value&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;and&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;const&lt;/span&gt; a = container.&lt;span style=&#34;color:#00f&#34;&gt;get&lt;/span&gt;(A);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;How do we keep &lt;code&gt;A&lt;/code&gt; at runtime? We&amp;rsquo;ll brand it.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;type&lt;/span&gt; InterfaceId&amp;lt;T&amp;gt; = &lt;span style=&#34;color:#2b91af&#34;&gt;string&lt;/span&gt; &amp;amp; { __type: &lt;span style=&#34;color:#2b91af&#34;&gt;T&lt;/span&gt; };
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;TypeScript sorcery exhibit A: Branding&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The union with &lt;code&gt;{ __type: T}&lt;/code&gt; is an arbitrary way to &lt;em&gt;use&lt;/em&gt; the type; otherwise, the compiler would fail.&lt;/p&gt;
&lt;p&gt;The good news is we don&amp;rsquo;t have to add &lt;code&gt;__type&lt;/code&gt; to every interface ID; we can use type assertion:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;const&lt;/span&gt; A = &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#39;A&amp;#39;&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;as&lt;/span&gt; InterfaceId&amp;lt;A&amp;gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Or we can make a helper for it:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;const&lt;/span&gt; createInterfaceId = &amp;lt;T&amp;gt;(id: &lt;span style=&#34;color:#2b91af&#34;&gt;string&lt;/span&gt;): InterfaceId&amp;lt;T&amp;gt; =&amp;gt; id &lt;span style=&#34;color:#00f&#34;&gt;as&lt;/span&gt; InterfaceId&amp;lt;T&amp;gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we can create the &lt;code&gt;A&lt;/code&gt; branded type, and the previous examples of decorating the class and getting the instance from the container will work.&lt;/p&gt;
&lt;h3 id=&#34;decorating-a-class-with-its-interface&#34;&gt;Decorating a class with its interface&lt;/h3&gt;
&lt;p&gt;The decorator standard lets us decorate 4 class elements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Class itself&lt;/li&gt;
&lt;li&gt;Methods&lt;/li&gt;
&lt;li&gt;Fields&lt;/li&gt;
&lt;li&gt;Accessors&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Looking at requirement 2:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The decorator captures the &lt;strong&gt;class&amp;rsquo; interface and dependencies&lt;/strong&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We need a way to add this information. The DI framework needs to know the class implements an interface (remember, type information is removed at compile time), and we need to express that the class needs dependencies to initialize.&lt;/p&gt;
&lt;p&gt;We also must decide how the dependencies will get to the class. I think there&amp;rsquo;s only one option: pass them to the constructor. In TypeScript, you can define that a class property is mandatory only if you initialize it in the constructor. Also, any other solution would clash with our first requirement:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We should be able to &lt;strong&gt;decorate any class&lt;/strong&gt; without changing it.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Looking at existing frameworks like &lt;a href=&#34;https://github.com/microsoft/tsyringe&#34;&gt;&lt;code&gt;tsyringe&lt;/code&gt;&lt;/a&gt; (virtually all use the TS experimental decorators), they would decorate a class like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;@Injectable&lt;/span&gt;(ConfigService)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;class&lt;/span&gt; DefaultConfigService &lt;span style=&#34;color:#00f&#34;&gt;implements&lt;/span&gt; ConfigService {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;constructor&lt;/span&gt;(&lt;span style=&#34;color:#00f&#34;&gt;@Inject&lt;/span&gt;(DbService) dbService: &lt;span style=&#34;color:#2b91af&#34;&gt;DbService&lt;/span&gt;){}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is elegant, and the decorators are in the right place, close to the affected code.&lt;/p&gt;
&lt;p&gt;However, the &lt;strong&gt;ES decorator standard doesn&amp;rsquo;t support constructor or method parameter decorators&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;So the only place left is the class decorator. It will have to capture both the class&amp;rsquo; interface and its dependencies.&lt;/p&gt;
&lt;p&gt;I ended up with this API:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;@Injectable&lt;/span&gt;(B, [A])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;class&lt;/span&gt; BImpl &lt;span style=&#34;color:#00f&#34;&gt;implements&lt;/span&gt; B {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#00f&#34;&gt;constructor&lt;/span&gt;(a: &lt;span style=&#34;color:#2b91af&#34;&gt;A&lt;/span&gt;) {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We use a single &lt;code&gt;@Injectable&lt;/code&gt; decorator and give it two arguments: the implemented interface and all dependencies.&lt;/p&gt;
&lt;p&gt;Now the hard part: how to make &lt;code&gt;@Injectable&lt;/code&gt; type-safe?&lt;/p&gt;
&lt;h3 id=&#34;making-injectable-type-safe&#34;&gt;Making &lt;code&gt;@Injectable&lt;/code&gt; type-safe&lt;/h3&gt;
&lt;h4 id=&#34;type-safe-interface&#34;&gt;Type-safe interface&lt;/h4&gt;
&lt;p&gt;Let&amp;rsquo;s start with the easier part. Remember that a class decorator is a function that accepts the decorated class as a parameter. And thanks to the type system, we can define a decorator that will only accept a class implementing some interface.&lt;/p&gt;
&lt;p&gt;The simplest way would be:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;interface&lt;/span&gt; Dog {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    bark(): &lt;span style=&#34;color:#2b91af&#34;&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;const&lt;/span&gt; Dog = createInterfaceId&amp;lt;Dog&amp;gt;(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;Dog&amp;#34;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;function&lt;/span&gt; dogDecorator&amp;lt;T extends { new &lt;span style=&#34;&#34;&gt;(&lt;/span&gt;...args&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; any&lt;span style=&#34;&#34;&gt;):&lt;/span&gt; Dog }&amp;gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;constructor&lt;/span&gt;: T,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    { kind }: ClassDecoratorContext,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ) {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;@dogDecorator&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;class&lt;/span&gt; Corgi &lt;span style=&#34;color:#00f&#34;&gt;implements&lt;/span&gt; Dog {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    bark = () =&amp;gt; &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#39;woof&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To understand the decorator, first see what the class type is:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;type&lt;/span&gt; Class = { &lt;span style=&#34;color:#00f&#34;&gt;new&lt;/span&gt; (...args: &lt;span style=&#34;color:#2b91af&#34;&gt;any&lt;/span&gt;[]): &lt;span style=&#34;color:#2b91af&#34;&gt;any&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;TypeScript sorcery exhibit B: Class type&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Since classes in JS are constructor functions, that&amp;rsquo;s what the type says: a class is a constructor function that takes arguments and makes an instance.&lt;/p&gt;
&lt;p&gt;Knowing about the constructor type, you can read the &lt;code&gt;dogDecorator&lt;/code&gt; function signature better:&lt;/p&gt;
&lt;p&gt;We reduce the type set that can be decorated with &lt;code&gt;dogDecorator&lt;/code&gt; to classes whose instances implement the &lt;code&gt;Dog&lt;/code&gt; interface.&lt;/p&gt;
&lt;p&gt;If we generalize this, we get the first building block of the &lt;code&gt;@Injectable&lt;/code&gt; interface:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;function&lt;/span&gt; Injectable&amp;lt;I&amp;gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  id: &lt;span style=&#34;color:#2b91af&#34;&gt;InterfaceId&lt;/span&gt;&amp;lt;I&amp;gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#00f&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;function&lt;/span&gt; &amp;lt;T extends { new &lt;span style=&#34;&#34;&gt;(&lt;/span&gt;...args&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; any&lt;span style=&#34;&#34;&gt;):&lt;/span&gt; I }&amp;gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;constructor&lt;/span&gt;: T,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    { kind }: ClassDecoratorContext,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#008000&#34;&gt;// the business logic goes here
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;  };
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we can decorate a class with an interface in a type-safe way:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;@Injectable&lt;/span&gt;(A) &lt;span style=&#34;color:#008000&#34;&gt;// compiler fails if AImpl doesn&amp;#39;t implement A
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;class&lt;/span&gt; AImpl &lt;span style=&#34;color:#00f&#34;&gt;implements&lt;/span&gt; A {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  field = &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#39;value&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h4 id=&#34;type-safe-dependencies&#34;&gt;Type-safe dependencies&lt;/h4&gt;
&lt;p&gt;This section is the hardest to grasp but also the most important part of the framework we&amp;rsquo;re building.&lt;/p&gt;
&lt;p&gt;We need to ensure that the second argument to &lt;code&gt;@Injectable&lt;/code&gt; has identical types and order as the class constructor.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;@Injectable&lt;/span&gt;(A, [X, Y, Z])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;class&lt;/span&gt; AImpl &lt;span style=&#34;color:#00f&#34;&gt;implements&lt;/span&gt; A {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#00f&#34;&gt;constructor&lt;/span&gt;(x: &lt;span style=&#34;color:#2b91af&#34;&gt;X&lt;/span&gt;, y: &lt;span style=&#34;color:#2b91af&#34;&gt;Y&lt;/span&gt;, z: &lt;span style=&#34;color:#2b91af&#34;&gt;Z&lt;/span&gt;) {}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the example above, we have two types:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the &lt;code&gt;@Injectable&lt;/code&gt; second parameter has type &lt;code&gt;[InterfaceId&amp;lt;X&amp;gt;, InterfaceId&amp;lt;Y&amp;gt;, InterfaceId&amp;lt;Z&amp;gt;]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;the constructor parameters: &lt;code&gt;...[X, Y, Z]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;How do we verify that the InterfaceIds are wrapping the same types and have the same order as constructor parameters?&lt;/p&gt;
&lt;h5 id=&#34;infer-to-the-rescue&#34;&gt;&lt;code&gt;infer&lt;/code&gt; to the rescue&lt;/h5&gt;
&lt;p&gt;The &lt;a href=&#34;https://www.typescriptlang.org/docs/handbook/2/conditional-types.html#inferring-within-conditional-types&#34;&gt;Inferring Within Conditional Types&lt;/a&gt; part of the TypeScript documentation is an interesting read that I recommend.&lt;/p&gt;
&lt;p&gt;The TL;DR is that with &lt;code&gt;infer&lt;/code&gt;, you can introduce a new generic type in the middle of a type declaration, and based on the inference, you branch the type. You can use &lt;code&gt;infer&lt;/code&gt; only in a conditional type.&lt;/p&gt;
&lt;p&gt;This is how we unwrap the array of &lt;code&gt;InterfaceId&lt;/code&gt;s:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;type&lt;/span&gt; UnwrapInterfaceIds&amp;lt;T extends InterfaceId&lt;span style=&#34;&#34;&gt;&amp;lt;&lt;/span&gt;unknown&amp;gt;[]&amp;gt; = {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  [K &lt;span style=&#34;color:#00f&#34;&gt;in&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;keyof&lt;/span&gt; T]: T[K] &lt;span style=&#34;color:#00f&#34;&gt;extends&lt;/span&gt; InterfaceId&amp;lt;infer U&amp;gt; ? U : &lt;span style=&#34;color:#2b91af&#34;&gt;never&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;TypeScript sorcery exhibit B: using &lt;code&gt;infer&lt;/code&gt; in conditional types&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;We say:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Our type accepts generic parameter &lt;code&gt;T&lt;/code&gt;, which is an array of &lt;code&gt;InterfaceId&lt;/code&gt;s.&lt;/li&gt;
&lt;li&gt;For all keys (indexes in this context), we try to infer the inner type &lt;code&gt;U&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;If we don&amp;rsquo;t succeed, we return the &lt;a href=&#34;https://www.typescriptlang.org/docs/handbook/2/functions.html#never&#34;&gt;&lt;code&gt;never&lt;/code&gt; type&lt;/a&gt;. In other words, this branch doesn&amp;rsquo;t happen.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5 id=&#34;putting-it-together&#34;&gt;Putting it together&lt;/h5&gt;
&lt;p&gt;Now, with &lt;code&gt;UnwrapInterfaceIds&lt;/code&gt;, we can define the final type of the &lt;code&gt;@Injectable&lt;/code&gt; decorator:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;function&lt;/span&gt; Injectable&amp;lt;I&lt;span style=&#34;&#34;&gt;,&lt;/span&gt; TDependencies extends InterfaceId&lt;span style=&#34;&#34;&gt;&amp;lt;&lt;/span&gt;unknown&amp;gt;[]&amp;gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  id: &lt;span style=&#34;color:#2b91af&#34;&gt;InterfaceId&lt;/span&gt;&amp;lt;I&amp;gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  dependencies: [...TDependencies],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#00f&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;function&lt;/span&gt; &amp;lt;T extends { new &lt;span style=&#34;&#34;&gt;(&lt;/span&gt;...args&lt;span style=&#34;&#34;&gt;:&lt;/span&gt; UnwrapInterfaceIds&lt;span style=&#34;&#34;&gt;&amp;lt;&lt;/span&gt;TDependencies&amp;gt;): I }&amp;gt;(
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;constructor&lt;/span&gt;: T,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    { kind }: ClassDecoratorContext,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#008000&#34;&gt;// the business logic goes here
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;  };
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The key addition is adding the &lt;code&gt;TDependencies&lt;/code&gt; generic and ensuring that the decorated function has a constructor with parameters with order and type equal to unwrapped &lt;code&gt;TDependencies&lt;/code&gt; using &lt;code&gt;...args: UnwrapInterfaceIds&amp;lt;TDependencies&amp;gt;&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This means that our &lt;code&gt;@Injectable&lt;/code&gt; decorator will only work on classes that implement the interface and have all the constructor parameters typed as the defined dependencies. Yay 🎉&lt;/p&gt;
&lt;p&gt;Congratulations, you read through the hardest part. I hope I wrote it clearly; if not, chuck the snippets with my explanation to your favourite chatbot and let it rephrase it.&lt;/p&gt;
&lt;h2 id=&#34;initializing-container&#34;&gt;Initializing &lt;code&gt;Container&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;The types are done. Now we just need to write the &amp;ldquo;business logic&amp;rdquo; as I called it before.&lt;/p&gt;
&lt;p&gt;This is the easy part.&lt;/p&gt;
&lt;p&gt;Our logic has three steps:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Decoration
&lt;ul&gt;
&lt;li&gt;We need to tell our DI that a class implements an interface and needs some dependencies&lt;/li&gt;
&lt;li&gt;&lt;code&gt;@Injectable&lt;/code&gt; implementation does this&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Initialization
&lt;ul&gt;
&lt;li&gt;Once we know about all classes and dependencies, we need to initialize them in the right order&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Container.init&lt;/code&gt; will do this&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Retrieval
&lt;ul&gt;
&lt;li&gt;We need access to initialized instances in the container&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Container.get&lt;/code&gt; will do this&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;What is this &lt;code&gt;Container&lt;/code&gt; you ask? It&amp;rsquo;s a class we make responsible for managing the classes and their instances.&lt;/p&gt;
&lt;h3 id=&#34;decoration&#34;&gt;Decoration&lt;/h3&gt;
&lt;p&gt;We need &lt;code&gt;@Injectable&lt;/code&gt; to do something. More concretely, we need it to pass the interface ID and list of dependencies (I call those &lt;em&gt;metadata&lt;/em&gt; from now on) to the &lt;code&gt;Container&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;But how?&lt;/p&gt;
&lt;p&gt;Originally, my idea was to add the metadata as &amp;ldquo;private attributes&amp;rdquo; on the class (prototype). Something like this:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;// omitting all the types for brevity
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;function&lt;/span&gt; Injectable(id, dependencies) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   &lt;span style=&#34;color:#00f&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;function&lt;/span&gt;(&lt;span style=&#34;color:#00f&#34;&gt;constructor&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#00f&#34;&gt;constructor&lt;/span&gt;.__id = id;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     &lt;span style=&#34;color:#00f&#34;&gt;constructor&lt;/span&gt;.__dependencies = dependencies;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   };
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This worked, but it changes the class, which is not great. My colleague Paul suggested a better way:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;interface&lt;/span&gt; Metadata {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  id: &lt;span style=&#34;color:#2b91af&#34;&gt;string&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  dependencies: &lt;span style=&#34;color:#2b91af&#34;&gt;string&lt;/span&gt;[];
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;const&lt;/span&gt; injectableMetadata = &lt;span style=&#34;color:#00f&#34;&gt;new&lt;/span&gt; WeakMap&amp;lt;object&lt;span style=&#34;&#34;&gt;,&lt;/span&gt; Metadata&amp;gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;// omitting all the types for brevity
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;function&lt;/span&gt; Injectable(id, dependencies) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;function&lt;/span&gt;(&lt;span style=&#34;color:#00f&#34;&gt;constructor&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      injectableMetadata.&lt;span style=&#34;color:#00f&#34;&gt;set&lt;/span&gt;(&lt;span style=&#34;color:#00f&#34;&gt;constructor&lt;/span&gt;, {id, dependencies});
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    };
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We create a global &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/WeakMap&#34;&gt;&lt;code&gt;WeakMap&lt;/code&gt;&lt;/a&gt; and store the metadata for each class in that map. Now we are ready to start initializing the classes.&lt;/p&gt;
&lt;h3 id=&#34;initialization&#34;&gt;Initialization&lt;/h3&gt;
&lt;p&gt;To initialize the container, we need to know two things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;All classes that should be initialized&lt;/li&gt;
&lt;li&gt;Metadata for all these classes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The list of classes will be an argument to the &lt;code&gt;Container.init&lt;/code&gt; function. The metadata should all be in the &lt;code&gt;injectableMetadata&lt;/code&gt; weak map.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;type&lt;/span&gt; ClassWithDependencies = { cls: &lt;span style=&#34;color:#2b91af&#34;&gt;Class&lt;/span&gt;; id: &lt;span style=&#34;color:#2b91af&#34;&gt;string&lt;/span&gt;; dependencies: &lt;span style=&#34;color:#2b91af&#34;&gt;string&lt;/span&gt;[] };
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;class&lt;/span&gt; Container {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;&#34;&gt;#&lt;/span&gt;instances = &lt;span style=&#34;color:#00f&#34;&gt;new&lt;/span&gt; Map&amp;lt;string&lt;span style=&#34;&#34;&gt;,&lt;/span&gt; unknown&amp;gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  init(...classes: &lt;span style=&#34;color:#2b91af&#34;&gt;Class&lt;/span&gt;[]) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#008000&#34;&gt;// validate classes
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#008000&#34;&gt;// Create instances in topological order
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;for&lt;/span&gt; (&lt;span style=&#34;color:#00f&#34;&gt;const&lt;/span&gt; cwd &lt;span style=&#34;color:#00f&#34;&gt;of&lt;/span&gt; sortDependencies(classes)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#00f&#34;&gt;const&lt;/span&gt; args = cwd.dependencies.map((dependencyId) =&amp;gt; &lt;span style=&#34;color:#00f&#34;&gt;this&lt;/span&gt;.&lt;span style=&#34;&#34;&gt;#&lt;/span&gt;instances.&lt;span style=&#34;color:#00f&#34;&gt;get&lt;/span&gt;(dependencyId));
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#00f&#34;&gt;const&lt;/span&gt; instance = &lt;span style=&#34;color:#00f&#34;&gt;new&lt;/span&gt; cwd.cls(...args);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#00f&#34;&gt;this&lt;/span&gt;.&lt;span style=&#34;&#34;&gt;#&lt;/span&gt;instances.&lt;span style=&#34;color:#00f&#34;&gt;set&lt;/span&gt;(cwd.id, instance);
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the code above, you see that we pass a list of classes to &lt;code&gt;Container.init&lt;/code&gt;, we ensure that we can initialize the classes, and then we sort them. When we have them sorted, we start initializing them in order from least to most dependent.&lt;/p&gt;
&lt;p&gt;I skipped over the sort; see the &lt;a href=&#34;#exercises-left-to-the-reader&#34;&gt;Exercises left to the reader&lt;/a&gt; for an implementation link.&lt;/p&gt;
&lt;h3 id=&#34;retrieval&#34;&gt;Retrieval&lt;/h3&gt;
&lt;p&gt;Once we initialized the &lt;code&gt;Container&lt;/code&gt;, we might have to retrieve instances from it. We implement a simple &lt;code&gt;Container.get&lt;/code&gt; method:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-ts&#34; data-lang=&#34;ts&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;export&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;class&lt;/span&gt; Container {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;&#34;&gt;#&lt;/span&gt;instances = &lt;span style=&#34;color:#00f&#34;&gt;new&lt;/span&gt; Map&amp;lt;string&lt;span style=&#34;&#34;&gt;,&lt;/span&gt; unknown&amp;gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#00f&#34;&gt;get&lt;/span&gt;&amp;lt;T&amp;gt;(id: &lt;span style=&#34;color:#2b91af&#34;&gt;InterfaceId&lt;/span&gt;&amp;lt;T&amp;gt;): T {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;if&lt;/span&gt; (!&lt;span style=&#34;color:#00f&#34;&gt;this&lt;/span&gt;.&lt;span style=&#34;&#34;&gt;#&lt;/span&gt;instances.has(id)) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#00f&#34;&gt;throw&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;new&lt;/span&gt; Error();
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;this&lt;/span&gt;.&lt;span style=&#34;&#34;&gt;#&lt;/span&gt;instances.&lt;span style=&#34;color:#00f&#34;&gt;get&lt;/span&gt;(id) &lt;span style=&#34;color:#00f&#34;&gt;as&lt;/span&gt; T;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And with this, we explained all concepts needed for a fully functional, type-safe dependency injection mini-framework 🚀.&lt;/p&gt;
&lt;h2 id=&#34;exercises-left-to-the-reader&#34;&gt;Exercises left to the reader&lt;/h2&gt;
&lt;p&gt;If you add up the code above, it won&amp;rsquo;t compile or run. There were several things I omitted because I didn&amp;rsquo;t consider them too complex and wanted to keep this post reasonably long. You can check the full implementation &lt;a href=&#34;https://gitlab.com/viktomas/needle/-/blob/main/src/dependency.ts&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This is a list of things that I didn&amp;rsquo;t explain:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Adding pre-initialized instances
&lt;ul&gt;
&lt;li&gt;In addition to calling &lt;code&gt;Container.init&lt;/code&gt;, you might want to add a method that will add existing instances to the container. Adding pre-initialized instances is useful if the instances have constructor parameters that the framework can&amp;rsquo;t provide (e.g., database connection).&lt;/li&gt;
&lt;li&gt;See the &lt;a href=&#34;https://gitlab.com/viktomas/needle/-/blob/a203e8f2b88eaaea44466ac8a4a06ec822a613e4/src/dependency.ts#L207-222&#34;&gt;&lt;code&gt;Container.addInstance()&lt;/code&gt; implementation&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Topological sort
&lt;ul&gt;
&lt;li&gt;When classes depend on each other, you have to initialize them in such an order that all dependencies of a class are created before we call the class constructor.&lt;/li&gt;
&lt;li&gt;See the code &lt;a href=&#34;https://gitlab.com/viktomas/di/-/blob/a203e8f2b88eaaea44466ac8a4a06ec822a613e4/src/dependency.ts#L151-176&#34;&gt;here&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Runtime validation - the type system can&amp;rsquo;t ensure the container is initialized correctly, so we need to implement these runtime validations:
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/viktomas/di/-/blob/a203e8f2b88eaaea44466ac8a4a06ec822a613e4/src/dependency.ts#L230-233&#34;&gt;All classes are decorated with &lt;code&gt;@Injectable&lt;/code&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/viktomas/di/-/blob/a203e8f2b88eaaea44466ac8a4a06ec822a613e4/src/dependency.ts#L110-145&#34;&gt;There are no circular dependencies&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/viktomas/di/-/blob/a203e8f2b88eaaea44466ac8a4a06ec822a613e4/src/dependency.ts#L76-87&#34;&gt;Each interface has only one implementation in the container&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/viktomas/di/-/blob/a203e8f2b88eaaea44466ac8a4a06ec822a613e4/src/dependency.ts#L96-107&#34;&gt;All dependencies are present in the container&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;m happy that I learned more about decorators. They used to seem like magic, and now I (and hopefully you) understand that they are functions that can mutate the decorated parts of the class. I would still use them with caution since they might seem magical to other developers (don&amp;rsquo;t go and decorate everything in your code), but you see how far one decorator (&lt;code&gt;@Injectable&lt;/code&gt;) took us.&lt;/p&gt;
&lt;h2 id=&#34;references&#34;&gt;References&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/viktomas/needle&#34;&gt;viktomas / needle · GitLab&lt;/a&gt; - Implementation of the framework from this post.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/tc39/proposal-decorators&#34;&gt;tc39/proposal-decorators: Decorators for ES6 classes&lt;/a&gt; - The latest stage three proposal.&lt;/li&gt;
&lt;li&gt;The recently added decorator support in &lt;code&gt;esbuild&lt;/code&gt; &lt;a href=&#34;https://github.com/evanw/esbuild/issues/104&#34;&gt;Feature request: Decorators support · Issue #104 · evanw/esbuild&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;The de-facto reference documentation: &lt;a href=&#34;https://2ality.com/2022/10/javascript-decorators.html&#34;&gt;JavaScript metaprogramming with the 2022-03 decorators API&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/microsoft/TypeScript/pull/50820&#34;&gt;Overview of TypeScript decorator types&lt;/a&gt; (this link is the PR that added ES decorator support to TS).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;acknowledgments&#34;&gt;Acknowledgments&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Thank you, Paul Slaughter, for not settling for an Interface-based DI and nudging me towards learning decorators. Also, thank you, Paul, for suggesting the &lt;code&gt;WeakMap&lt;/code&gt; improvement.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Example of whitespace-sensitive TreeSitter grammar</title>
      <link>https://blog.viktomas.com/graph/whitespace-sensitive-treesitter-grammar/</link>
      <pubDate>Mon, 06 May 2024 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/whitespace-sensitive-treesitter-grammar/</guid>
      <description>&lt;p&gt;In this short post, I&amp;rsquo;ll explain how to parse nested single-line markdown blocks into an AST using TreeSitter. The whole grammar is 18 lines of JavaScript and 127 lines of C.&lt;/p&gt;
&lt;p&gt;The final grammar will be able to parse this text:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;-&lt;/span&gt; one
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#00f&#34;&gt;-&lt;/span&gt; two
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#00f&#34;&gt;-&lt;/span&gt; three
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#00f&#34;&gt;-&lt;/span&gt; four
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;-&lt;/span&gt; five
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;into this AST:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lisp&#34; data-lang=&#34;lisp&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(document
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#00f&#34;&gt;block&lt;/span&gt; (block_start) (block_content)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#00f&#34;&gt;block&lt;/span&gt; (block_start) (block_content)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    (&lt;span style=&#34;color:#00f&#34;&gt;block&lt;/span&gt; (block_start) (block_content)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  (&lt;span style=&#34;color:#00f&#34;&gt;block&lt;/span&gt; (block_start) (block_content)))
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;(&lt;span style=&#34;color:#00f&#34;&gt;block&lt;/span&gt; (block_start) (block_content)))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This post expects that you know how to &lt;a href=&#34;https://tree-sitter.github.io/tree-sitter/creating-parsers#project-setup&#34;&gt;set up a TreeSitter project&lt;/a&gt; and you are familiar with &lt;a href=&#34;https://tree-sitter.github.io/tree-sitter/creating-parsers#the-first-few-rules&#34;&gt;basic grammar syntax&lt;/a&gt;. I don&amp;rsquo;t try to explain the basic concepts in too much detail here. For that, I can recommend Jonas Hietala&amp;rsquo;s &lt;a href=&#34;https://www.jonashietala.se/blog/2024/03/19/lets_create_a_tree-sitter_grammar/&#34;&gt;Let&amp;rsquo;s create a Tree-sitter grammar&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Sidenote: I&amp;rsquo;m not an expert on programming language grammar or C. I wrote this summary mainly on the off chance that future me ever decides to pick up the grammar and extend it. Sorry if it&amp;rsquo;s too terse. My original goal was to write a grammar for &lt;a href=&#34;https://logseq.com/&#34;&gt;Logseq&lt;/a&gt; files, but it was too much effort for the value. I spent eight hours writing this basic grammar and that&amp;rsquo;s only 10% of the effort needed for a full grammar.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;why-are-whitespace-sensitive-grammars-special&#34;&gt;Why are whitespace-sensitive grammars special?&lt;/h2&gt;
&lt;p&gt;The key difference between free-form grammar like C and whitespace-sensitive grammar like Markdown or Python is that:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;free-form grammar - &lt;strong&gt;characters can be directly mapped to tokens&lt;/strong&gt; (parentheses, semicolon,..), and whitespace is generally ignored apart from being used to separate tokens.&lt;/li&gt;
&lt;li&gt;Whitespace-sensitive grammar — some tokens are the result of the absence of characters. In our example, when we don&amp;rsquo;t see a tab, we close a block. This complicates the lexer (scanner), which needs to keep a state with information about indentation.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;simple-example&#34;&gt;Simple example&lt;/h2&gt;
&lt;p&gt;Without nested blocks, our text structure is very simple:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;-&lt;/span&gt; one
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;-&lt;/span&gt; two
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;-&lt;/span&gt; three
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;These blocks can be parsed by this grammar:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;module.exports = grammar({
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  name: &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;simple&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#008000&#34;&gt;// ignores carriage return (\r\n turns to \n)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;  extras: (_) =&amp;gt; [&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;\r&amp;#34;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  rules: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  document: ($) =&amp;gt; repeat($.block),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  block: ($) =&amp;gt; seq($.block_start, $.block_content, $._block_end),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  block_start: ($) =&amp;gt; /- &lt;span style=&#34;&#34;&gt;/,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  block_content: ($) =&amp;gt; /[^&lt;span style=&#34;&#34;&gt;\&lt;/span&gt;n]+&lt;span style=&#34;&#34;&gt;/,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  _block_end: ($) =&amp;gt; choice(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;, $._eof),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  _eof: ($) =&amp;gt; &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;\0&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The document is made up of blocks (lines). Each block starts with &lt;code&gt;- &lt;/code&gt;, and then all characters on the line count as content. The block ends with a new line or the end of the file. Underscored rules won&amp;rsquo;t be included in the final AST.&lt;/p&gt;
&lt;h2 id=&#34;nesting&#34;&gt;Nesting&lt;/h2&gt;
&lt;p&gt;Now let&amp;rsquo;s introduce nesting. Remember the example from the start of the post:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;-&lt;/span&gt; one
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#00f&#34;&gt;-&lt;/span&gt; two
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		&lt;span style=&#34;color:#00f&#34;&gt;-&lt;/span&gt; three
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#00f&#34;&gt;-&lt;/span&gt; four
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;-&lt;/span&gt; five
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;For parsing this, we need to delegate the &lt;code&gt;block_start&lt;/code&gt; and &lt;code&gt;block_end&lt;/code&gt; tokens to a separate lexer logic. TreeSitter calls this lexer logic &lt;a href=&#34;https://tree-sitter.github.io/tree-sitter/creating-parsers#external-scanners&#34;&gt;an external &lt;code&gt;scanner.c&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This scanner will keep track of the number of open blocks and then emit &lt;code&gt;block_end&lt;/code&gt; tokens based on the indentation of the next block.&lt;/p&gt;
&lt;p&gt;The above example will be treated like this:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;line 1: we parsed block &lt;code&gt;one&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;line 2:  has a leading tab, that means we nest block &lt;code&gt;two&lt;/code&gt; under &lt;code&gt;one&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;line 3: has two leading tabs, we&amp;rsquo;ll nest &lt;code&gt;three&lt;/code&gt; under &lt;code&gt;one&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;line 4: has one leading tab, we will close blocks &lt;code&gt;three&lt;/code&gt; and &lt;code&gt;two&lt;/code&gt; and create block &lt;code&gt;four&lt;/code&gt; (sibling of &lt;code&gt;two&lt;/code&gt;, nested under &lt;code&gt;one&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;line 5: doesn&amp;rsquo;t have any leading tabs, we&amp;rsquo;ll close &lt;code&gt;four&lt;/code&gt; and &lt;code&gt;one&lt;/code&gt; and create &lt;code&gt;five&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;end of file, we&amp;rsquo;ll close &lt;code&gt;five&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Now that you see how the scanner detects the end of a block, let&amp;rsquo;s make the above process a bit more exact by capturing it in pseudocode.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;var level = 0
var blocksToClose = 0
scanToken() {
  if (isValidSymbol(BLOCK_END)){
     if (blocksToClose &amp;gt; 0) {
       blocksToClose--
       return BLOCK_END
     }
     if(nextChar == \n){
       tabs = countTabsAfterNewLine()
       if (tabs &amp;lt; level) {
          blocksToClose = level - tabs;
          blocksToClose--
          level--
          return BLOCK_END
        }
      } else if (eof) {
        blocksToClose = level
        blocksToClose--
        level--
        return BLOCK_END
      }
  }

  if (isValidSymbol(BLOCK_START)){
    if(nextTwoChars == &amp;#34;- &amp;#34;){
      level++
      return BLOCK_START
    }
  }
  return nil
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The key points to follow in the pseudocode:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;code&gt;level&lt;/code&gt; global state represents the number of open blocks we have at the moment we scan this token.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;blocksToClose&lt;/code&gt; is a workaround because &lt;code&gt;scanToken()&lt;/code&gt; can only return one token at a time, but we might have to close multiple blocks.
We close a block if the number of leading tabs on the new line is less than the number of open blocks. Look at the example, see that all &lt;code&gt;- &lt;/code&gt; increase level, and apply this close rule to understand how tabs are used by this code.&lt;/li&gt;
&lt;li&gt;We close all open blocks if we hit the end of the file.&lt;/li&gt;
&lt;li&gt;The &lt;code&gt;isValidSymbol&lt;/code&gt; check prevents us from running our code at places where we can&amp;rsquo;t emit &lt;code&gt;BLOCK_START&lt;/code&gt; or &lt;code&gt;BLOCK_END&lt;/code&gt; (e.g. when we are parsing the block content).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;em&gt;Limitation: Representing the state by two integers is a simplification. You probably want to implement a stack of open blocks for real-world grammar. This stack will allow you to close different type of blocks at once. For example, you might want to close a quote block, then a paragraph, and then the list item.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;grammar.js&lt;/code&gt; is even simpler because it &amp;ldquo;outsources&amp;rdquo; two rules. The only added complexity is that we allowed nested blocks (block rule references itself):&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-js&#34; data-lang=&#34;js&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;module.exports = grammar({
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    name: &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;simple&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    extras: (_) =&amp;gt; [&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;\r&amp;#34;&lt;/span&gt;],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    externals: ($) =&amp;gt; [$.block_start, $._block_end],
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    rules: {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    document: ($) =&amp;gt; seq(&lt;span style=&#34;color:#a31515&#34;&gt;/\s*/&lt;/span&gt;, repeat($.block)),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    block: ($) =&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      seq($.block_start, $.block_content, repeat($.block), $._block_end),
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    block_content: ($) =&amp;gt; /[^&lt;span style=&#34;&#34;&gt;\&lt;/span&gt;n]+&lt;span style=&#34;&#34;&gt;/,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The &lt;a href=&#34;https://gitlab.com/viktomas/tree-sitter-logseq/-/blob/5ab1cac03f2ab572f586f5d59ae7818aa78219c1/src/scanner.c&#34;&gt;scanner code is a bit more complex&lt;/a&gt;. It follows the pseudocode closely but it&amp;rsquo;s too long for me to paste it here verbatim. You can follow the link to my GitLab. The &lt;a href=&#34;https://tree-sitter.github.io/tree-sitter/creating-parsers#external-scanners&#34;&gt;TreeSitter external scanner documentation&lt;/a&gt; gives a good overview of the file structure and interface.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Limitation: I don&amp;rsquo;t understand error handling and highlighting in TreeSitter well and I don&amp;rsquo;t know if the grammar from this post has good error handling and highlighting support.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;p&gt;I showed you how to create a simple grammar representing Markdown lists. First, we looked at non-nested lists, which can be handled with the default scanner. Then, we introduced nested list items, which needed an external scanner.&lt;/p&gt;
&lt;p&gt;From here, I recommend reading Jonas Hietala&amp;rsquo;s &lt;a href=&#34;https://www.jonashietala.se/blog/2024/03/19/lets_create_a_tree-sitter_grammar/&#34;&gt;Let&amp;rsquo;s create a Tree-sitter grammar&lt;/a&gt;, which introduces a much more complex grammar.&lt;/p&gt;
&lt;p&gt;Good luck!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Tiago Forte - Building a Second Brain</title>
      <link>https://blog.viktomas.com/graph/tiago-forte--building-second-brain/</link>
      <pubDate>Thu, 25 Apr 2024 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/tiago-forte--building-second-brain/</guid>
      <description>&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/tiago-forte--building-second-brain.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.goodreads.com/book/show/59616977-building-a-second-brain&#34;&gt;Goodreads&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My rating: ★★★★☆ (90%)&lt;/p&gt;
&lt;p&gt;This book changed the way I think about note-taking. I can&amp;rsquo;t recommend it enough. In this review, I&amp;rsquo;ll explain the book&amp;rsquo;s main two ideas.&lt;/p&gt;
&lt;h3 id=&#34;tldr&#34;&gt;TL;DR&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Zettlekasten makes you spend too much energy upfront when consuming content. The second brain method lets you spend that energy later and only if needed. Putting verbatim highlights in your notes is fine.&lt;/li&gt;
&lt;li&gt;Organise your notes into a structure that reflects how useful the note is to you now (PARA).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;the-zettelkasten-method-perfectionism-and-upfront-effort&#34;&gt;The Zettelkasten Method: Perfectionism and Upfront Effort&lt;/h2&gt;
&lt;p&gt;In software, there is a concept of iteration, which delays all decisions until later and works only at the absolute minimum to deliver value. In other words, don&amp;rsquo;t do the work before it&amp;rsquo;s necessary.&lt;/p&gt;
&lt;p&gt;I use this approach when writing software all day, every day. However, somehow, I didn&amp;rsquo;t do that when taking notes. I encountered the &lt;a href=&#34;https://blog.viktomas.com/tags/zettelkasten/&#34;&gt;zettelkasten school of thought&lt;/a&gt; first, and since then, I have spent obscene amounts of time juicing out all the information from every book I&amp;rsquo;ve read.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Since I started with Slip-box, I felt that it takes too much time to write good notes. It takes me roughly half an hour to produce one permanent note (including the time for reading). For example, when I read Software Engineering at Google it took me three hours to read a chapter and make five permanent notes. I’m comforting myself that now that I put effort to extract the knowledge and linking it with my existing notes, I’ll always have it readily available. But was it worth three hours of my time?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;My quote from &lt;a href=&#34;https://blog.viktomas.com/posts/slip-box-after-a-year/&#34;&gt;Zettelkasten note-taking after one year&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I thought note-taking should take a long time. Watching &lt;a href=&#34;https://www.youtube.com/playlist?list=PLHwtkAtdkx1IZoI7FZf1X50qyzRnmw_Vy&#34;&gt;videos of &amp;ldquo;professional&amp;rdquo; zettelkasten note-takers&lt;/a&gt;, I saw that it&amp;rsquo;s normal.&lt;/p&gt;
&lt;h2 id=&#34;the-second-brain-method-deferring-effort-and-organizing-with-para&#34;&gt;The Second Brain Method: Deferring Effort and Organizing with PARA&lt;/h2&gt;
&lt;p&gt;After reading Tiago&amp;rsquo;s book, I realised I was doing it wrong. &lt;strong&gt;My perspective on note-taking was turned on its head for four years.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The following table sums up the difference:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;&lt;/th&gt;
          &lt;th&gt;zettlekasten&lt;/th&gt;
          &lt;th&gt;second brain&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Note quality&lt;/td&gt;
          &lt;td&gt;Each note is a well-described idea linked to the network of other ideas. If this idea conflicts with a pre-existing idea, the conflict must be resolved&lt;/td&gt;
          &lt;td&gt;The note can be anything, a set of highlights, a paragraph, or a picture. You can copy-paste interesting parts of an article and not post-process it 🤯&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;notes organisation&lt;/td&gt;
          &lt;td&gt;network of interlinked notes (think Wikipedia)&lt;/td&gt;
          &lt;td&gt;folder structure based on your work and interests&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;most of the work happens&lt;/td&gt;
          &lt;td&gt;when you create the note&lt;/td&gt;
          &lt;td&gt;when you need to use the note&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The Zettlekasten method always seemed perfectionist to me, but the only alternative I knew of was to write the notes as I used to before, write notes as I read a book, and never return to them again. Also, the idea of perfected notes (almost like small blog posts) that are little atoms of knowledge was very seductive.&lt;/p&gt;
&lt;p&gt;However, putting that much effort into note-taking is not worth it for most topics. Maybe when I read a well-written, short book about the exact topic that&amp;rsquo;s key for my current project, I can process it in that much detail, but when I casually read &lt;a href=&#34;https://www.goodreads.com/book/show/11468377-thinking-fast-and-slow&#34;&gt;Thinking Fast and Slow&lt;/a&gt;, I shouldn&amp;rsquo;t put in that much effort because I&amp;rsquo;m not sure I&amp;rsquo;ll need that information.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s when Tiago&amp;rsquo;s second brain comes in. You defer polishing/organising the notes until you need them. You take raw notes with any interesting information, and you organise them using the &lt;strong&gt;PARA method&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;The PARA method lets you organise your notes by &amp;ldquo;how useful they are to you&amp;rdquo;. The more useful they are, the more prominent they get in your note structure.&lt;/p&gt;
&lt;p&gt;PARA stands for:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Projects: This is a folder with all your current initiatives, both work and life. (Examples: Renovate kitchen, write a blog post about mountain bikes)&lt;/li&gt;
&lt;li&gt;Areas: Your areas of responsibility. Projects usually last for a short while, while Areas last much longer. (Examples: parenting, leadership, health)&lt;/li&gt;
&lt;li&gt;Resources: These are any other useful notes that don&amp;rsquo;t belong to the previous two.&lt;/li&gt;
&lt;li&gt;Archive: Everything you stop being interested in, you move to the archive.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can google &amp;ldquo;PARA method&amp;rdquo; for a more detailed explanation.&lt;/p&gt;
&lt;h2 id=&#34;personal-experience-enjoying-reading-more-with-the-second-brain-method&#34;&gt;Personal Experience: Enjoying Reading More with the Second Brain Method&lt;/h2&gt;
&lt;p&gt;Since I implemented this method, I&amp;rsquo;ve enjoyed reading much more. Since I&amp;rsquo;m now &amp;ldquo;allowed&amp;rdquo; to copy and paste my highlights and be done with the note, I started using &lt;a href=&#34;https://omnivore.app&#34;&gt;Omnivore&lt;/a&gt; as a read-later app, and I&amp;rsquo;m making more careful highlights in my &lt;a href=&#34;https://koreader.rocks/&#34;&gt;KOReader&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I now read at different levels of attentiveness. I can pretty much guess which PARA folder the note will go into, and based on that, I either read for leisure (when I know it will go to &amp;ldquo;Resources&amp;rdquo;) or read carefully (if the content applies to one of my projects).&lt;/p&gt;
&lt;p&gt;At work, the PARA method helps me have a clear overview of my current responsibilities. Recently, I had to go on sick leave, and I could take a snapshot of my work project notes and use that as a clear status update for my colleagues.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s been only a month since I read the book so portion of my sentiment can be attributed to &amp;ldquo;new and shiny&amp;rdquo; factor, however I&amp;rsquo;m quite optimistic about this drastic shift in my note-taking.&lt;/p&gt;
&lt;h2 id=&#34;summary&#34;&gt;Summary&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Zettlekasten method requires a large amount of work when reading new material. In my opinion, it&amp;rsquo;s a method designed for academics to read papers in their field.&lt;/li&gt;
&lt;li&gt;Second brain provides two ideas (delayed effort, PARA) to make taking notes easy and delaying all the work to when you use the notes&lt;/li&gt;
&lt;li&gt;My personal experience makes me think that a Second brain is much better for non-academics.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>How will you sell the thing you just bought: A strategy for smarter shopping</title>
      <link>https://blog.viktomas.com/graph/mindset-when-buying-things/</link>
      <pubDate>Mon, 15 Apr 2024 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/mindset-when-buying-things/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve bought a Samsung LCD ultra-wide monitor &amp;ldquo;34&amp;rdquo; Samsung Ultra-Wide monitor C34H890, for roughly $350. I was super happy with the choice and the screen&amp;rsquo;s look.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/image_1692178700448_0.png&#34;
    alt=&#34;image.png&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I found a new screen still for sale for double the price so I messaged the guy, but I wasn&amp;rsquo;t lowballing too much. By then, I already saw myself having the screen in my study.&lt;/p&gt;
&lt;p&gt;The guy accepted my $15 less offer and I drove to nearby town to pick it up. So far so good.&lt;/p&gt;
&lt;p&gt;The screen looked great but I made a mistake. I didn&amp;rsquo;t even want to see the screen on. I just took the guy&amp;rsquo;s word for it, gave him the money, loaded the screen into my car and headed home. I was still thinking I was getting an amazing deal.&lt;/p&gt;
&lt;p&gt;To be fair, I had a great experience buying second-hand electronics recently, which made me feel like buying second-hand stuff is a risk-free activity.&lt;/p&gt;
&lt;p&gt;When I connected the screen at home to my M1 Max 16&amp;quot; Mac, the text was blurry. Blurry!&lt;/p&gt;
&lt;p&gt;I thought it had to be the cable, so I ordered five different cables (display port, USB-C 4, thunderbolt, HDMI) to try them. The next day, I tried them one by one and found that the &lt;a href=&#34;https://discussions.apple.com/thread/252217807&#34;&gt;issue was in MacOS&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I tried to return the screen to the guy, but he stopped taking my calls.&lt;/p&gt;
&lt;p&gt;Shortly after, I found that a brand-new model could be bought only for a few dollars more. That lowered the price I could re-sell the screen for.&lt;/p&gt;
&lt;p&gt;When I realised I had become a seller instead of a buyer, my mindset changed. And &lt;strong&gt;this mindset is something I want to remember and talk about&lt;/strong&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;When I&amp;rsquo;m about to buy something new, I&amp;rsquo;m excited. I see myself using the thing and I&amp;rsquo;m in a state of mind where the thing is the missing piece to my happiness and once I get it, my life will be amazing. This is never the case but I feel that way.&lt;/p&gt;
&lt;p&gt;I buy the thing, excitedly unpack it, play with it for a while and then it starts gathering dust. The dust gathering is especially strong if it didn&amp;rsquo;t replace an item I use daily (e.g. laptop, phone, or watch).&lt;/p&gt;
&lt;p&gt;If I use it seldom enough, I&amp;rsquo;ll try to sell it and the difference between how I feel when I&amp;rsquo;m selling it couldn&amp;rsquo;t be bigger.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;&lt;/th&gt;
          &lt;th&gt;buying&lt;/th&gt;
          &lt;th&gt;selling&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;price&lt;/td&gt;
          &lt;td&gt;The price is a bargain&lt;/td&gt;
          &lt;td&gt;I&amp;rsquo;ll sell it for much less to get it off my hands&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;utility&lt;/td&gt;
          &lt;td&gt;I need it so much&lt;/td&gt;
          &lt;td&gt;I&amp;rsquo;m not using it. It has a low value&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;value to others&lt;/td&gt;
          &lt;td&gt;everyone needs one&lt;/td&gt;
          &lt;td&gt;nobody will probably want this&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;There is a new behaviour that I&amp;rsquo;d like to try. &lt;strong&gt;Imagine that I already have the thing and try to sell it before I buy it.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Go to Craigslist and see what the selling &amp;ldquo;competition&amp;rdquo; is. How much lower I&amp;rsquo;ll have to go with the price?&lt;/li&gt;
&lt;li&gt;Imagine dealing with people who are lowballing me + all the spam that&amp;rsquo;s  happening on the FB marketplace&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;what-helps-with-taming-the-buy-beast&#34;&gt;What helps with taming the buy beast&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Buy things second-hand (when I&amp;rsquo;m inevitably selling, the value won&amp;rsquo;t drop as much as for a new thing)&lt;/li&gt;
&lt;li&gt;Buy common items with a large customer base (they are easy to sell quickly). I still remember buying a niche Ergodox EZ keyboard for $450 and then trying to sell it in the small Czech market.&lt;/li&gt;
&lt;li&gt;Try to mainly replace existing items (laptop, headphones, phone, watch..). That way, you know you&amp;rsquo;ll be using the thing.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Skip GitLab CI jobs in forks</title>
      <link>https://blog.viktomas.com/graph/gitlab-ci-skip-jobs-in-forks/</link>
      <pubDate>Sun, 14 Apr 2024 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/gitlab-ci-skip-jobs-in-forks/</guid>
      <description>&lt;p&gt;In this post, you will learn one approach to disabling jobs on forked projects. &lt;strong&gt;This approach only works on GitLab Premium or Ultimate.&lt;/strong&gt; If you are in a rush,  check the &amp;ldquo;Final Condition&amp;rdquo; section.&lt;/p&gt;
&lt;p&gt;Recently, I had to solve an issue at work: we have E2E tests running in our CI pipeline. These jobs need secrets. The secrets are stored in our CI/CD config as environmental variables. All merge requests from fork projects had these tests failing because the forked project was missing these secrets.&lt;/p&gt;
&lt;p&gt;We had two options:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ask all forked projects to create a test account. However, the account would have to have several paid subscriptions for our tests to pass&lt;/li&gt;
&lt;li&gt;Not run E2E tests on forks and only run them once when a maintainer tries to merge the MR&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The E2E tests are very basic, and there is a good chance that some unit test will catch the failure first, so we opted for the second option, only running E2E tests on merge.&lt;/p&gt;
&lt;h3 id=&#34;ci-settings-explained&#34;&gt;CI settings explained&lt;/h3&gt;
&lt;p&gt;We use &lt;a href=&#34;https://docs.gitlab.com/ee/ci/pipelines/merge_trains.html&#34;&gt;merge trains&lt;/a&gt; and &lt;a href=&#34;https://docs.gitlab.com/ee/ci/pipelines/merged_results_pipelines.html&#34;&gt;merge result pipelines&lt;/a&gt;. Because this approach relies on merge trains, it won&amp;rsquo;t work on Free GitLab&lt;/p&gt;
&lt;h3 id=&#34;naive-attempt&#34;&gt;Naive attempt&lt;/h3&gt;
&lt;p&gt;I thought that I could use existing environment variables to figure out where the pipeline runs. My first attempt was the condition:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rules:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    - if: $CI_PROJECT_ID == &amp;#34;46519181&amp;#34; || $GITLAB_TEST_TOKEN != &amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The condition says to run the tests if the project is the main (forked) project or if the fork added the token to the CI config&lt;/p&gt;
&lt;p&gt;As the heading suggests, this didn&amp;rsquo;t work because since the MR is targeting the main project, the &lt;code&gt;$CI_PROJECT_ID&lt;/code&gt; environmental variable is always set to the main project ID&lt;/p&gt;
&lt;h3 id=&#34;investigation&#34;&gt;Investigation&lt;/h3&gt;
&lt;p&gt;I created a test project in my &lt;code&gt;viktomas&lt;/code&gt; namespace and forked it. I set CI to use merge trains and run a simple job&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;test:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  script:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    - printenv
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then, I run two pipelines&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;one when the MR was created&lt;/li&gt;
&lt;li&gt;one when the MR was merged&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I noticed that the only useful difference between the two printouts was the &lt;code&gt;$CI_MERGE_REQUEST_EVENT_TYPE&lt;/code&gt; variable&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;MR created - the variable had &lt;code&gt;detached&lt;/code&gt; value&lt;/li&gt;
&lt;li&gt;MR merged - the variable had &lt;code&gt;merge_train&lt;/code&gt; value&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;extra-confusion&#34;&gt;Extra confusion&lt;/h4&gt;
&lt;p&gt;I didn&amp;rsquo;t realise that even if I create the MR from fork, if I have developer access to the main project, the CI variables from the main project are accessible to the pipeline. That complicated my investigation because I had to use a separate user with lower privileges to create the MR from fork.&lt;/p&gt;
&lt;h3 id=&#34;final-condition&#34;&gt;Final condition&lt;/h3&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;rules:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;- if: $GITLAB_TEST_TOKEN || $CI_MERGE_REQUEST_EVENT_TYPE == &amp;#34;merge_train&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This condition says: run the pipeline if the token is present, or if the job runs in a pipeline that tries to merge the MR.&lt;/p&gt;
&lt;p&gt;This condition takes advantage of two things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When you run merge train (i.e. a maintainer of the project started merging the MR), the &lt;code&gt;$CI_MERGE_REQUEST_EVENT_TYPE&lt;/code&gt; is se to &lt;code&gt;merge_train&lt;/code&gt;. So there is no way for the MR to get merged without at least one successful pipeline that has &lt;code&gt;$CI_MERGE_REQUEST_EVENT_TYPE == &amp;quot;merge_train&amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;When a user with developer or higher privileges in the main project runs the pipeline, it will have access to the main project&amp;rsquo;s CI/CD variables (here &lt;code&gt;$GITLAB_TEST_TOKEN&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These two facts combined mean that the condition achieves exactly what we set out to do at the beginning. Community contributors with forks don&amp;rsquo;t have to set up their CI with extra variables and their pipeline can still pass. However, once a maintainer in the main project runs merge train to merge the MR, the E2E tests will run with the needed variables, ensuring the MR didn&amp;rsquo;t break E2E tests.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Martin Gurri - The Revolt of the Public</title>
      <link>https://blog.viktomas.com/graph/martin-gurri--revolt-of-the-public/</link>
      <pubDate>Mon, 01 Apr 2024 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/martin-gurri--revolt-of-the-public/</guid>
      <description>&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/martin-gurri--revolt-of-the-public.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.goodreads.com/book/show/42286006-the-revolt-of-the-public-and-the-crisis-of-authority-in-the-new-millenni&#34;&gt;Goodreads&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My rating: ★☆☆☆☆ (10%)&lt;/p&gt;
&lt;p&gt;This book disappointed me. I&amp;rsquo;ve read only about a quarter, and I stopped. Martin&amp;rsquo;s writing is what I&amp;rsquo;d call &amp;ldquo;Trying to impress my English teacher&amp;rdquo; style. The ideas conveyed in this book were as hard to understand as the language.&lt;/p&gt;
&lt;h2 id=&#34;tldr&#34;&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;Once the elite (government, rich people) lost the monopoly on how the information is shared, people started fractioning into small groups based on opinions, and since scandals and failures of character are now easily exposed, people lost trust in the government institutions.&lt;/p&gt;
&lt;p&gt;One interesting insight: People are not happy with the government, but from how they interact, they only oppose things and can&amp;rsquo;t govern themselves. Opposed government and no alternatives leaves democracy in a pickle.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>J. Storrs Hall - Where Is My Flying Car?: A Memoir of Future Past</title>
      <link>https://blog.viktomas.com/graph/j-storrs-hall--where-is-my-flying-car/</link>
      <pubDate>Sun, 03 Mar 2024 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/j-storrs-hall--where-is-my-flying-car/</guid>
      <description>&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/j-storrs-hall--where-is-my-flying-car.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://openlibrary.org/books/OL33567985M/Where_Is_My_Flying_Car&#34;&gt;OpenLibrary&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My rating: ★★★★★ (95%)&lt;/p&gt;
&lt;p&gt;Interesting review: &lt;a href=&#34;https://bayesianinvestor.com/blog/index.php/2018/10/14/where-is-my-flying-car/#2&#34;&gt;Where Is My Flying Car? | Bayesian Investor Blog&lt;/a&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;tldr&#34;&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;This is one of the most eye opening books I&amp;rsquo;ve read (the other that comes to mind is Harari&amp;rsquo;s Sapiens).&lt;/p&gt;
&lt;p&gt;You need to take many parts with a heavy nugget of salt. When there is an ambiguous topic (e.g. radiation impact on cancer) Josh takes an authoritative stance to one extreme.&lt;/p&gt;
&lt;p&gt;See the &amp;ldquo;Thoughts&amp;rdquo; at the end of this post for the kind of takeaways you&amp;rsquo;ll have from this book.&lt;/p&gt;
&lt;p&gt;Key takeaways&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Nuclear energy is over regulated, material-wise it&amp;rsquo;s so cheap that we could have no CO2 emissions and energy too cheap to measure.&lt;/li&gt;
&lt;li&gt;Regulation and other centralised government factors (e.g. government funded research) stifle innovation, but it&amp;rsquo;s an opportunity cost that is hard to see (i.e. our rate of progress is 2% rather than 7% a year but it still seems like we make progress)&lt;/li&gt;
&lt;li&gt;We need to understand radiation effect on people much better. It will be necessary for spaceflight anyway and it might give us cheep nuclear energy.&lt;/li&gt;
&lt;li&gt;Nanotechnology is a concept that has a potential that I haven&amp;rsquo;t understood before. It could completely change how our civilisation works.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;unsorted-thoughts&#34;&gt;Unsorted thoughts&lt;/h2&gt;
&lt;p&gt;The author mapped 1960s predictions about technologies and shown that only the ones that don&amp;rsquo;t require high energy came true.&lt;/p&gt;
&lt;p&gt;The energy output of the US started to stagnate around 1972, since then there weren&amp;rsquo;t any improvements in flight, space travel and so on&lt;/p&gt;
&lt;p&gt;Nanotechnology has the potential to rebuild the whole US infrastructure (buildings, factories, roads railways) in 2 weeks&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Typical factory will pay for itself in 25-35 years of being built, nanofactory could do that in weeks&lt;/li&gt;
&lt;li&gt;Moors law would apply, there would be more efficient nanofactories built by previous generation. The software (design) would be the bottleneck.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Machiavelli Effect&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The established ruling party is fighting change because it would affect their well being. They never identify this as the reason, they think they are doing the world the service (it&amp;rsquo;s again the incentives and self-interest that Munger is talking about)&lt;/li&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;Science advances funeral by funeral&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://duckduckgo.com/?q=what+if+it%27s+all+been+a+big+fat+lie&amp;amp;t=ffab&amp;amp;ia=web&#34;&gt;https://duckduckgo.com/?q=what+if+it%27s+all+been+a+big+fat+lie&amp;amp;t=ffab&amp;amp;ia=web&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;I discovered, to my amazement, that all through history there had been resistance— and bitter, exaggerated, last-ditch resistance— to every significant technological change that had taken place on earth. Usually the resistance came from those groups who stood to lose influence, status, money as a result of the change. Although they never advanced this as their reason for resisting it. It was always the good of humanity that rested upon their hearts.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;—Isaac Asimov&lt;/li&gt;
&lt;li&gt;Cold fusion
&lt;ul&gt;
&lt;li&gt;Cold fusion experiments got heavily criticised by high power nuclear physicists. Hall argues that it&amp;rsquo;s because they were afraid about loosing funding/power.&lt;/li&gt;
&lt;li&gt;The physicists were actively sabotaging attempts to reproduce the original experiement.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;public-research-funding-is-bad-for-science&#34;&gt;Public research funding is bad for science&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Hall argues that public research funding is, if anything, hindering science because bureaucrats can dictate what is important for science and what isn&amp;rsquo;t.
&lt;ul&gt;
&lt;li&gt;All important improvements of life came before 1960s when the public research funding skyrocketed in US
&lt;ul&gt;
&lt;li&gt;transistors, vacuum tubes, indoor plumbing, refrigirators, cards, airplanes, electric lights&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Failures to understand new science is now not causing only mispredictions, but actively work against it as the bureaucrats decide what research gets funding.&lt;/li&gt;
&lt;li&gt;France had a massive public research funding in 1800s, but industrial revolution came from England&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The number of PhDs also doesn&amp;rsquo;t correlate with quality of life imporovements.&lt;/p&gt;
&lt;h3 id=&#34;flying-cars&#34;&gt;Flying cars&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Hill asks us to imagine the progress that could have been caused by flying cars. Similarly to what the normal car caused
&lt;ul&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;You didn&amp;rsquo;t just take the trips that you would have walked, but faster; you took trips you never would have made at all.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;This is really interesting thought exercise, the invention of automobile allowed for new businesses, new way of working (commute to the city), new experiences&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;The car and the network of interstate freeways in US is attributed to 30% of the economic growth in the 50&amp;rsquo;s&lt;/li&gt;
&lt;li&gt;The interstate system contributed to the solid 4.1% growth up to the great stagnation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Hill describes how chevrolet corvair was cancelled because somebody wrote an article about how terrible its handling is&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Again an interesting idea about how minor bad event can stere public opinion to cancel a thing&lt;/em&gt; Hall says that if the flying cards flew, few people would crash and die and it would cause public to turn against them. The same will be the case with autonomous cars these days.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;regulation&#34;&gt;Regulation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The regulation sky-rocketed in 1970s&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://sci-hub.hkvisa.net/10.1007/s10887-013-9088-y&#34;&gt;Federal regulation and aggregate economic growth&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;2013 Study that says that the median US household income is $53,000 and if US maintained the amount of regulation that it had in 1949, it would be $185,000&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;FDA got power over all drugs in 1938 after a disaster when a drug killed 100 people.
&lt;ul&gt;
&lt;li&gt;Since then all drugs have to get regulatory approval.&lt;/li&gt;
&lt;li&gt;One such drug was Sulfapyridine that could have saved 10-20k lives the winter that it was in review by FDA instead of in hospitals.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;The direct cost of regulation in 2008 was $15k+ per household&lt;/li&gt;
&lt;li&gt;Certified airplane parts are 10times more expensive than if they are not for airplane&lt;/li&gt;
&lt;li&gt;There was some de-regulation of air traffic controls that increased the number of flights and hence saved lives by taking people off highways (this is a [[second order effect]])&lt;/li&gt;
&lt;li&gt;Regulators are not elected. Regulation is not introduced as law is. US introduces around 20 times more new regulations than law. regulatory administrative courts handle 10 times more cases than federal courts&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Regulation is triggered by small disasters where relatively small amount of people dies and it stops progress and sometimes it causes more deaths&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;I was always thinking how regulation brought good and improved people&amp;rsquo;s lives, but what I didn&amp;rsquo;t realise is that there was a huge improvement in people&amp;rsquo;s lives &lt;strong&gt;before&lt;/strong&gt; regulation.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;The only way for industry to start is to make a huge progress before regulation kiks in
&lt;ul&gt;
&lt;li&gt;Software&lt;/li&gt;
&lt;li&gt;Normal cars&lt;/li&gt;
&lt;li&gt;Hobby drones&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;product-liability&#34;&gt;Product liability&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;in 70s, lot of accidents were judged as caused by products and the companies had to pay
&lt;ul&gt;
&lt;li&gt;This completely destroyed the small airplane industry&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;in 70s and later many people studied law and lots of talent was wasted on court battles&lt;/li&gt;
&lt;li&gt;imagine Ford getting sued every time model T crashed, there would be no cars&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Author names hypothetical obstacles to flying cars&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;insurance company won&amp;rsquo;t insure new thing&lt;/li&gt;
&lt;li&gt;neighbours will complain about nose and propeller close to children&lt;/li&gt;
&lt;li&gt;city council worrying about property prices&lt;/li&gt;
&lt;li&gt;TV reporters creating drama and scaring everyone&lt;/li&gt;
&lt;li&gt;Tax assesor who will classify your lawn as airport&lt;/li&gt;
&lt;li&gt;mayor who will use this for his governor campaign&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;mallows-hierarchy&#34;&gt;Mallow&amp;rsquo;s Hierarchy&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Hall argues that around the end of 60s, the basic physical human needs in US were satisfied and people needed the fulfilment and belonging. It&amp;rsquo;s hard to give something important to work on to everyone and people started coming up with silly unproductive virtue signalling things.
&lt;ul&gt;
&lt;li&gt;Hall says that we can make ourselves believe almost anything, most people would believe that they do something important and help the world.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Reaching of higher Mallow level is possible explanation why so many different social movements happened at the same time. Cvil rights, feminism, anti-war, sexual revolution, conservationism (nature), socialism
&lt;ul&gt;
&lt;li&gt;virtue signalling became more important than real-world results&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Hall uses the term &lt;em&gt;Eloi&lt;/em&gt; for people who have their physical needs taken care of enough that they can concern themselves with love, esteem, and self-actualization.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;war-as-a-tool-for-efficiency&#34;&gt;War as a tool for efficiency&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Hall argues that historically, people couldn&amp;rsquo;t spend too much time on virtue signalling and activities disconnected from reality. Since the invention of atomic bomb, if a nation becomes ineffective, it can&amp;rsquo;t be defeated and taken over by another nation.
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;I&amp;rsquo;m not sure about this argument because middle-ages were ripe with war and the efficiency wasn&amp;rsquo;t too great&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;At any rate, there is a pattern that we see recurring throughout history, when a successful empire expands its borders so far that it becomes the biggest kid on the block. When survival is no longer at stake, selfish elites and other special interest groups capture the political agenda. The spirit that “we are all in the same boat” disappears and is replaced by a “winner take all” mentality.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;em&gt;This makes sense. The less immediate danger there is, the more can people concern themselves with bullshit.&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;after WW2, the cooperative spirit fuelled the large national corporations GE, GM, &amp;hellip;&lt;/li&gt;
&lt;li&gt;However as the next generation didn&amp;rsquo;t have to fight for survival, the mentality of let&amp;rsquo;s all work for single goal broke down&lt;/li&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;it is ease and plenty, the lack of danger and struggle rather than their presence, that appears to engender moral and intellectual decay.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;media-misinformation&#34;&gt;Media misinformation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;The more you are disconnected from the event/situation, the more you are likely to believe media scare messages
&lt;ul&gt;
&lt;li&gt;Cancer from cell-phones - everybody has one, nobody has cancer - you don&amp;rsquo;t believe them&lt;/li&gt;
&lt;li&gt;Dangers of nuclear power - I don&amp;rsquo;t live next to a power plant - I believe them&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;climate-change&#34;&gt;Climate change&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The intergovernmental panel for climate change&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The author mentions study from 2007 that says that the impact of climate change will be small&lt;/li&gt;
&lt;li&gt;I read &lt;img
    src=&#34;./assets/IPCC_AR6_SYR_SPM.pdf&#34;
    alt=&#34;2023 summary&#34;
    loading=&#34;lazy&#34;
    
/&gt; and the 2023 prognosis is not that good
&lt;ul&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;Climate change is a threat to human well-being and planetary health (very high confidence). There is a rapidly closing window of opportunity to secure a liveable and sustainable future for all (very high confidence)&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The author found some report that says that worst-case-scenario, climate change will cost US 2.5% GDP in 2100&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;This sounds like no longer being true&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;If you think your belief is based upon reason, you will support it by argument rather than by persecution, and will abandon it if the argument goes against you. But if your belief is based upon faith, you will realize that argument is useless, and will therefore resort to force either in the form of persecution or by stunting or distorting the minds of the young in what is called “education.”&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;—Bertrand Russell&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Author makes argument that all products are becoming worse thanks to energy savings (dishwashers that don&amp;rsquo;t wash dishes, showers that drizzle)&lt;/p&gt;
&lt;p&gt;Author describes Xhosa African nation that believed a girl &amp;ldquo;prophet&amp;rdquo; who said they should slaughter all their animals and not saw new crops. 40 000 people starved to death. &lt;a href=&#34;https://en.wikipedia.org/wiki/History_of_the_Cape_Colony_from_1806_to_1870#Xhosa_cattle-killing_movement_and_famine_(1854-1858)&#34;&gt;Wiki source&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;In modern democratic society, the outcome of a plague meme is lack of growth, not a decline. People would notice deteriorating living conditions, but they don&amp;rsquo;t notice the lost opportunities [[Opportunity cost]]&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The susceptibility to horror stories is what creates regulation and what created glass ceiling on our energy generation.&lt;/p&gt;
&lt;p&gt;All predictions from the turn of 20th century missed a car. They were predicting how the public spaces will be great, how public transport will be great, but they didn&amp;rsquo;t anticipate the &lt;strong&gt;productivity increase&lt;/strong&gt; introduced by Ford that let everyone have a car.&lt;/p&gt;
&lt;p&gt;Author says that if we had the current cultural and regulatory environment in 1910, we &lt;em&gt;would not have cars&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;When US was all frontier, and people were competing with nature rather than with each other, there was low value in virtue-signalling.&lt;/p&gt;
&lt;h3 id=&#34;aviation&#34;&gt;Aviation&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;most of the private planes in US are home-made or 40 years old and this is thanks to the &lt;em&gt;safety&lt;/em&gt; regulations&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Jevon&amp;rsquo;s paradox - the more energy-efficient your appliance gets, the more total energy you use&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Named after William Stanley Jevons&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s explained on an example with a selling tomatoes by driving to a market. If you can only go 20km with one batch of tomatoes, you will do less trips (less customers) than if you can go 40km with a batch of tomatoes for the same price&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;nuclear-energy&#34;&gt;Nuclear energy&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;747-400 flight US-AU will tak 194 tons of Jet-A fuel (2.1 GWh), that&amp;rsquo;s on average 100tons of cargo that the plane is taking. It costs $343k to buy that fuel. Uranium with the same amount of energy (100g) would cost under $10&lt;/li&gt;
&lt;li&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Fuel&lt;/th&gt;
          &lt;th&gt;Unit Price&lt;/th&gt;
          &lt;th&gt;Amount/TJ&lt;/th&gt;
          &lt;th&gt;$/TJ&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;gasoline&lt;/td&gt;
          &lt;td&gt;$3.37/gal&lt;/td&gt;
          &lt;td&gt;7,780 gal&lt;/td&gt;
          &lt;td&gt;26,000.00&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;electricity&lt;/td&gt;
          &lt;td&gt;$0.12/kWh&lt;/td&gt;
          &lt;td&gt;278,000 kWh&lt;/td&gt;
          &lt;td&gt;33,000.00&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;natural gas&lt;/td&gt;
          &lt;td&gt;$12.50/mcf&lt;/td&gt;
          &lt;td&gt;948 mcf&lt;/td&gt;
          &lt;td&gt;11,850.00&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;coal (anthracite)&lt;/td&gt;
          &lt;td&gt;$170/ton&lt;/td&gt;
          &lt;td&gt;91,600 lbs&lt;/td&gt;
          &lt;td&gt;7,786.00&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;tritium&lt;/td&gt;
          &lt;td&gt;$30,000/g&lt;/td&gt;
          &lt;td&gt;3.77 lbs&lt;/td&gt;
          &lt;td&gt;51 million&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;uranium (as U2O8)&lt;/td&gt;
          &lt;td&gt;$58.24/lb&lt;/td&gt;
          &lt;td&gt;0.028 lbs&lt;/td&gt;
          &lt;td&gt;1.40&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;uranium (enriched)&lt;/td&gt;
          &lt;td&gt;$1.63/gram&lt;/td&gt;
          &lt;td&gt;12.58 g&lt;/td&gt;
          &lt;td&gt;20.00&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;thorium (oxide 99.9%)&lt;/td&gt;
          &lt;td&gt;$0.20/gram&lt;/td&gt;
          &lt;td&gt;12.58 g&lt;/td&gt;
          &lt;td&gt;2.50&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;boron-11 (p-B fusion)&lt;/td&gt;
          &lt;td&gt;$5/gram&lt;/td&gt;
          &lt;td&gt;15 g&lt;/td&gt;
          &lt;td&gt;76.00&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;lithium-7 (carbonate)&lt;/td&gt;
          &lt;td&gt;$0.06/g&lt;/td&gt;
          &lt;td&gt;7.4 g&lt;/td&gt;
          &lt;td&gt;0.44&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;deuterium (heavy water)&lt;/td&gt;
          &lt;td&gt;$600/liter&lt;/td&gt;
          &lt;td&gt;7.8 ml&lt;/td&gt;
          &lt;td&gt;4.00&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Fuel&lt;/th&gt;
          &lt;th&gt;Unit Price&lt;/th&gt;
          &lt;th&gt;Amount/TWh&lt;/th&gt;
          &lt;th&gt;$/TWh&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;gasoline&lt;/td&gt;
          &lt;td&gt;$1.5/l&lt;/td&gt;
          &lt;td&gt;1050l&lt;/td&gt;
          &lt;td&gt;$1570&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;/li&gt;
&lt;li&gt;Reserves of uranium could power the earth of 77 years, of thorium for 6500 years&lt;/li&gt;
&lt;li&gt;Author says: Since thorium is found in coal in traces, the burnt coal ash contains more energy than the coal itself.&lt;/li&gt;
&lt;li&gt;The problem with adopting thorium is that uranium is already too cheap.&lt;/li&gt;
&lt;li&gt;All cost of nuclear energy is of regulatory complience. Fuel is negligable.&lt;/li&gt;
&lt;li&gt;There is as much headroom in energy generation as in computation, but computation is not regulated.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.forbes.com/sites/michaelshellenberger/2019/03/11/it-sounds-crazy-but-fukushima-chernobyl-and-three-mile-island-show-why-nuclear-is-inherently-safe/&#34;&gt;Forbes article from Michael Shellenberger about how safe the nuclear power is&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/understanding-fukushima-accident&#34;&gt;Trying to understand the impact of Fukushima Daiichi nuclear accident&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;The Fukushima power plant failure (marked as &lt;em&gt;disaster&lt;/em&gt; by public) cost 0 lives due to radiation exposure.
&lt;ul&gt;
&lt;li&gt;16k people died&lt;/li&gt;
&lt;li&gt;6k were injured&lt;/li&gt;
&lt;li&gt;2.5k went missing&lt;/li&gt;
&lt;li&gt;Due to (sometimes forceful evacuation) there were 1600 hundred premature deaths in Japan, government protecting people from radiation levels common in Finland
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.wsj.com/articles/a-nuclear-paradigm-shift-1449014295&#34;&gt;https://www.wsj.com/articles/a-nuclear-paradigm-shift-1449014295&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://dose-response.org/wp-content/uploads/2015/12/WSJ-2015Dec2_A_nuclear_paradigm_shift-1.pdf&#34;&gt;http://dose-response.org/wp-content/uploads/2015/12/WSJ-2015Dec2_A_nuclear_paradigm_shift-1.pdf&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/understanding-fukushima-accident&#34;&gt;Trying to understand the impact of Fukushima Daiichi nuclear accident&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Nuclear power plants cannot explode with nuclear explosion, however, thanks to media, many people would say they can (60% of Americans)&lt;/li&gt;
&lt;li&gt;Energy poverty is estimated to kill 28k americans a year&lt;/li&gt;
&lt;li&gt;The rules for dealing with nuclear waste are too strict. The limit for radioactivity way below the limit that would be harmful to humans.&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;speed-limit-analogy&#34;&gt;Speed limit analogy&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Josh says that radiation limits are 100 times stricter than any proven impact to human health. Imagine how expensive car transportation would be if we set speed limit to 1.3km/h&lt;/li&gt;
&lt;li&gt;LNT - Linear No-Threshold Model states that radiation is dangerous in proportion to exposure with no limit on the low side. That means that people in places with high background radiation should have more cancer which Josh says is not true
&lt;ul&gt;
&lt;li&gt;J. Muller got Nobel Prize for demonstrating that ionizing radiation causes genetic mutation, he also authored the LNT model&lt;/li&gt;
&lt;li&gt;J. Muller also argued that the effect is not dependent on timing&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/Radiation_Dose_Chart_by_Xkcd.png&#34;
    alt=&#34;radiation dose chart&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/li&gt;
&lt;li&gt;Picture by Randall Munroe (&lt;a href=&#34;https://xkcd.com/&#34;&gt;https://xkcd.com/&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Consider how developing countries would use clean nuclear energy if we didn&amp;rsquo;t stifle the innovation and were able to give them safe reactors.&lt;/li&gt;
&lt;li&gt;The US Navy had over 6000 reactor-years of accident-free operation in 2016, it has built 526 reactor cores&lt;/li&gt;
&lt;li&gt;If we had perfected nuclear energy, all the engineering effort for energy efficiency could have been spent on improving our lives&lt;/li&gt;
&lt;li&gt;There is a correlation between GDP and energy use. Author argues that there is causality both ways (increase energy available =&amp;gt; increase GDP)&lt;/li&gt;
&lt;li&gt;Josh argues that green activists are opposed to energy in general, they would like to keep people with as little energy as possible so they are not transforming the earth.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Josh is thinking about quality of life as a function of production capability. If it takes an average worker in a factor a year to manufacture a car, then only rich people can afford it. If it takes them 10 days, everybody can afford it.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Josh used &amp;ldquo;percent of population it would take to make everyone have a flying car&amp;rdquo;&lt;/li&gt;
&lt;li&gt;The productivity is increased by more energy, better machines, and better processes.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Josh is really big fan of nanotechnology. He says that nanotechnology could rebuild all US infrastructure in a few days.&lt;/p&gt;
&lt;p&gt;Josh mentions [[Cybernetics]] in relation to how our political systems lack the feedback loops.&lt;/p&gt;
&lt;p&gt;Key Idea: &lt;strong&gt;Academia and Politics are disconnected form the feedback that would make public company fail.&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Why very seductive idea, without regulation we would have a few monopolies that mess up the environment for profit.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;We don&amp;rsquo;t punish bad predictions by public persons. If someone says that in 3 years time something terrible happens, they get popularity in the moment but 3 years later nobody cares.&lt;/p&gt;
&lt;p&gt;Josh aruges that people don&amp;rsquo;t udnerstand complex systems and blaim the closest entity for a failure&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Aerospace engineers for lack of flyings cars (instead of regulators)&lt;/li&gt;
&lt;li&gt;Pharmaceutics companies for being greedy rather than the regulators that make it expensive to make drugs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Prophets of bad news&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Al Gore warned us in 2007 nobel prize acceptance speach that polar caps will be gone by 2014&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Paul_R._Ehrlich&#34;&gt;Paul Ehrlich&lt;/a&gt; - population explosion, famine, wars&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Quotes&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Only in academia and government, where nobody faces consequences for failure, do you find people who are stupid enough to believe they know what is going to happen.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;—Eric Worrall&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;t is hard to imagine a more stupid or more dangerous way of making decisions than by putting those decisions in the hands of people who pay no price for being wrong.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;—Thomas Sowell&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;spaceflight&#34;&gt;Spaceflight&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Josh describes some engines including nuclear explosion propulsion
&lt;ul&gt;
&lt;li&gt;Interestingly he argues that radiation released by a takeoff of such a ship wouldn&amp;rsquo;t be too bad&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Outer space is a high radiation environment. We need to find out how to deal with radiation anyway so why not to use nuclear power?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;[[Complexity barrier]]&lt;/p&gt;
&lt;h3 id=&#34;fertile-techium-valley-metaphore&#34;&gt;Fertile Techium Valley metaphore&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;We are creating technological understanding that&amp;rsquo;s spilling into valleys like a lake&lt;/li&gt;
&lt;li&gt;Regulators create dams that completely wall of areas of understanding (nano tech, nuclear)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;second-atomic-age&#34;&gt;Second atomic age&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;nanotech and nuclear advancements will allow us to manipulate matter on atomic level&lt;/li&gt;
&lt;li&gt;4 billion tons of uranium is dissolved in the ocean, the bottom of the ocean contains 100 trillion tones, if we remove some from the ocean, the ocean floor uranium will leach back into the ocean&lt;/li&gt;
&lt;li&gt;Nielson test - successor of Turing test - judge AI/robot by the number of jobs it can take over from humans&lt;/li&gt;
&lt;li&gt;Josh argues that productivity is exponential and if we add nuclear and nanotech it will get hyperexponential&lt;/li&gt;
&lt;li&gt;Josh argues that making moral robots will be easy because we don&amp;rsquo;t have to replicate the reptile brain that makes people immoral&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;space-pier&#34;&gt;Space pier&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;300km long structure 100km hight accelerating projectiles in orbit making price of kg in orbit $1/kg&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;weather-control&#34;&gt;Weather control&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;release small nano &amp;ldquo;saturns&amp;rdquo; into the atmosphere, they&amp;rsquo;ll form a full cover of the earth and we can tilt them to either block or allow sunlight through, we can even focus sunlight onto power plants&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;If we have nanotech, we want the CO2 content in atmosphere to be high because everyone will have pocket printers using it to create almost any product.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The centuries-long growth in energy output (Henry Adams curve) stoped in 1970&lt;/p&gt;
&lt;p&gt;In dynamic (growing) society people can cooperate and both come ahead. In static (stagnating) society it&amp;rsquo;s more zero-sum game.&lt;/p&gt;
&lt;p&gt;The great stagnation is reflected in Science Fiction - from optimistic SF of early 20th century, we got to distopian SF of late 20th sentury&lt;/p&gt;
&lt;h1 id=&#34;thoughts&#34;&gt;Thoughts&lt;/h1&gt;
&lt;ul&gt;
&lt;li&gt;Bad news/predictions are memes that win over reality because of their high emotional impact&lt;/li&gt;
&lt;li&gt;Regulation is often a knee-jerk reaction to some small incident that gets blown out of proportion&lt;/li&gt;
&lt;li&gt;Nuclear power is regulated so much that it stifles innovation.&lt;/li&gt;
&lt;li&gt;People are so averse to risk that it hinders progress. 174 slightly irradiated people causes &lt;a href=&#34;https://en.wikipedia.org/wiki/Fukushima_nuclear_accident#Compensation_and_government_expenses&#34;&gt;187 &lt;strong&gt;billion&lt;/strong&gt; dollars expense&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Josh says that there is no reason to hold your breath for fusion since fission is already super cheap.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;If we get of this planet, we&amp;rsquo;ll open the frontier again. People will get free of Earth regulation and will be able to experiment with any/every technology.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Many wiki pages with topics form this book are highly controversial/disputed
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Paul_R._Ehrlich&#34;&gt;https://en.wikipedia.org/wiki/Paul_R._Ehrlich&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Radiation_effects_from_the_Fukushima_Daiichi_nuclear_disaster&#34;&gt;https://en.wikipedia.org/wiki/Radiation_effects_from_the_Fukushima_Daiichi_nuclear_disaster&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Charles T. Munger, Peter D. Kaufman - Poor Charlie&#39;s Almanack</title>
      <link>https://blog.viktomas.com/graph/munger-kaufman--poor-charlies-almanack/</link>
      <pubDate>Sat, 03 Feb 2024 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/munger-kaufman--poor-charlies-almanack/</guid>
      <description>&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/munger-kaufman--poor-charlies-almanack.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://openlibrary.org/works/OL20791443W/Poor_Charlie%27s_Almanack?edition=&#34;&gt;OpenLibrary&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My rating: ★★★★☆ (85%)&lt;/p&gt;
&lt;p&gt;Following is an assorted list of notes I made during reading the book. I wish I had something like this before I read it so that I could beforehand decide what areas of the book are most interesting to me and pay attention accordingly.&lt;/p&gt;
&lt;p&gt;Mental models:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Inversion - change the question and instead of asking how to reach great outcome, ask how to reach the worst possible outcome and then avoid doing that.
&lt;ul&gt;
&lt;li&gt;This change in thinking allows you to solve problems you otherwise wouldn&amp;rsquo;t be able to.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Permutations and combinations - probability
&lt;ul&gt;
&lt;li&gt;Examples &lt;a href=&#34;https://www.newtraderu.com/2023/06/10/permutations-combinations-probability-16-word-problems/&#34;&gt;Permutations, Combinations &amp;amp; Probability (16 Word Problems) - New Trader U&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Math explanation &lt;a href=&#34;https://www.mathsisfun.com/combinatorics/combinations-permutations.html&#34;&gt;Combinations and Permutations&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Bell curve (Gaussian distribution)&lt;/li&gt;
&lt;li&gt;Double entry bookkeeping
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.coursera.org/articles/double-entry-accounting&#34;&gt;Double-Entry Accounting: What It Is and How It Works | Coursera&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://www.quickmba.com/accounting/fin/double-entry/&#34;&gt;Double Entry Bookkeeping&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Who, when, where, what, why
&lt;ul&gt;
&lt;li&gt;Method of communication used in the Braun company. It gave the reader full context. Similar to GitLab&amp;rsquo;s &lt;a href=&#34;https://handbook.gitlab.com/teamops/decision-velocity/#low-context-communication&#34;&gt;low context communication&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Breaking point - material science&lt;/li&gt;
&lt;li&gt;Critical mass - physics&lt;/li&gt;
&lt;li&gt;Cognitive biases and heuristics&lt;/li&gt;
&lt;li&gt;Microeconomics
&lt;ul&gt;
&lt;li&gt;Think about it as ecosystem&lt;/li&gt;
&lt;li&gt;People/companies who specialise get really good in some niche&lt;/li&gt;
&lt;li&gt;Trademarks (legally registered symbol or name), patents, exclusive franchises&lt;/li&gt;
&lt;li&gt;Some process upgrades (new machine, new software) go straight to the customer and some go to the bottom line, depending on the competition and probably some other factors&lt;/li&gt;
&lt;li&gt;Surfing - being early bird in an emerging market (Microsoft, Intel, National Cache Register)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Advantages of scale
&lt;ul&gt;
&lt;li&gt;Doing complicated things in large volume enables better specialization than low volume&lt;/li&gt;
&lt;li&gt;Physics, larger spheric tank takes more content for less steel&lt;/li&gt;
&lt;li&gt;TV advertising - in the past only available to large companies&lt;/li&gt;
&lt;li&gt;Brand name&lt;/li&gt;
&lt;li&gt;One news paper per town&lt;/li&gt;
&lt;li&gt;Story of Walmart
&lt;ul&gt;
&lt;li&gt;Sam Walton destroyed all other small merchants in his area (he was fighting low for the territory) because he couldn&amp;rsquo;t fight head on the big companies&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Disadvantages of scale
&lt;ul&gt;
&lt;li&gt;Birocracy - brings established way of thinking, if you poke your head up with unconventional ideas, you make yourself a target&lt;/li&gt;
&lt;li&gt;Corruption (in a sense that people start looking out for themselves and their departments and if you don&amp;rsquo;t bother them, they don&amp;rsquo;t bother you)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Circle of competence
&lt;ul&gt;
&lt;li&gt;figure out your aptitudes, if you play games where other people have these aptitudes and you don&amp;rsquo;t you&amp;rsquo;ll lose&lt;/li&gt;
&lt;li&gt;Natural talent combined with hard work&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Man with a hammer - if you only have one tool (e.g. mathemtatics) you try to apply it to everythign (e.g. economics) even if the reality doesn&amp;rsquo;t fit the model&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Incentives&lt;/strong&gt; - do the employees/business aligned incentives with what you want?
&lt;ul&gt;
&lt;li&gt;Example of Federal Express when they were paying flight crews by an hour and could never get them on time and then they started paying by flight and it worked out&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Cut the cancer model: Part of the business works well and you keep that and cut out everything else (example GEICO)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Opportunity cost&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Tragedy of the commons&lt;/li&gt;
&lt;li&gt;Psychology
&lt;ul&gt;
&lt;li&gt;Denial - you make a wrong investment and then you are in denial that it&amp;rsquo;s wrong and commit to it more, or you put in more money to recoup the cost
&lt;ul&gt;
&lt;li&gt;Antidote: &amp;ldquo;I can write this one off and live to fight another day. I don&amp;rsquo;t have to obsessively pursue this thing till it breaks me.&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Appeal to man&amp;rsquo;s interests - when you are convincing a person to do something, always take the point of view &amp;ldquo;how does the action help them/prevent them from mistake&amp;rdquo; - only moral reasoning won&amp;rsquo;t help.
&lt;ul&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;If you would persuade, appeal to interest, not to reason.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Benjamin Franklin&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Self-serving bias - doing something that&amp;rsquo;s good to you and then rationalising that it&amp;rsquo;s good for the civilisation and that you are doing good deeds.&lt;/li&gt;
&lt;li&gt;Rewards and punishment super-response - this is pretty much the same as the incentives mental model
&lt;ul&gt;
&lt;li&gt;How to receive an advice congruently with Rewards principle?
&lt;ul&gt;
&lt;li&gt;
&lt;ol&gt;
&lt;li&gt;Fear professional advice, especially if it&amp;rsquo;s good for the adviser&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol start=&#34;2&#34;&gt;
&lt;li&gt;Learn basics of your adviser&amp;rsquo;s trade as you deal with the adviser&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;ol start=&#34;3&#34;&gt;
&lt;li&gt;double-check, disbelieve, or replace most of what you are told&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Don&amp;rsquo;t reward people for behaviour that can be easily faked (lines of code, slack responsiveness)&lt;/li&gt;
&lt;li&gt;Granny principle: eat your vegetables before the desert - if you make a habit of taking the most unpleasant work first in the day, you won&amp;rsquo;t be procrastinating on it&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Liking/loving tendency
&lt;ul&gt;
&lt;li&gt;If you like someone your thinking is impeded&lt;/li&gt;
&lt;li&gt;you ignore their faults and comply with their wishes&lt;/li&gt;
&lt;li&gt;favour things/people associated with that person&lt;/li&gt;
&lt;li&gt;distort other facts to keep loving/liking the person&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Disliking/hating tendency
&lt;ul&gt;
&lt;li&gt;Similar to liking tendency&lt;/li&gt;
&lt;li&gt;You ignore virtues of people/things you dislike (Seth and Apple, me and Windows)&lt;/li&gt;
&lt;li&gt;dislike things/people associated with the object of disliking&lt;/li&gt;
&lt;li&gt;distort other facts to keep hating&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;doubt avoidance tendency
&lt;ul&gt;
&lt;li&gt;People tend to quickly remove doubt from their thinking and be certain about their opinions. Probably evolutionary benefit from being decisive.&lt;/li&gt;
&lt;li&gt;This tendency triggers due to combination of stress and puzzlement.&lt;/li&gt;
&lt;li&gt;The best way to avoid this is not to make early conclusions (e.g. jury on a case can&amp;rsquo;t discuss the case)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Inconsistency-avoidance tendency
&lt;ul&gt;
&lt;li&gt;people like things as they always were&lt;/li&gt;
&lt;li&gt;people keep repeating behaviour that works&lt;/li&gt;
&lt;li&gt;this tendency makes it much easier to avoid bad habit than to change it&lt;/li&gt;
&lt;li&gt;human mind works like a human egg, once a sperm/idea gets in, it doesn&amp;rsquo;t let any other in&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;people accumulate large mental holdings of fixed conclusions&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;person who makes sacrifices assuming new identity holds on to it proportionately to the sacrifices&lt;/li&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;It&amp;rsquo;s important not to put one&amp;rsquo;s brain in chains before one has come anywhere near his full potentiality as a rational person&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Envy/jelousy tendency
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Envy is taboo and you can&amp;rsquo;t label someone&amp;rsquo;s actions as envy driven even if they are&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;It&amp;rsquo;s not greed that drives the word, but envy&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Warren Buffet&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Reciprocation tendency
&lt;ul&gt;
&lt;li&gt;People tend to reciprocate kindness and hostility&lt;/li&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;You can always tell the man off tomorrow, if it is such a good idea.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;This tendency can be misused for manipulation. If salesman gives threats you nicely and gives you a present, you feel obliged to reciprocate and buy something more expensive.&lt;/li&gt;
&lt;li&gt;Walmart and many other companies completely ban their employees accepting &lt;strong&gt;any&lt;/strong&gt; presents.&lt;/li&gt;
&lt;li&gt;Psychology experiment by Cialdini - ask people to take group of juvenile delinquents to zoo -&amp;gt; 1/6 acceptance rate, ask the people first to dedicate huge chunk of time weekly for two years to supervise them and when they refuse, ask if they would at least take them to the zoo -&amp;gt; 1/2 acceptance rate.
&lt;ul&gt;
&lt;li&gt;People reciprocated the concession&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Mere association tendency
&lt;ul&gt;
&lt;li&gt;messengers can be associated with the bad news. That&amp;rsquo;s why Berkshire Heathway has a policy that bad news has to be communicated immediately, so people don&amp;rsquo;t avoid being the messenger&lt;/li&gt;
&lt;li&gt;Charlie says that when you help someone in need, this tendency can kick in and the person will associate you with the bad situation they were in.
&lt;ul&gt;
&lt;li&gt;I&amp;rsquo;m not sure about this&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Excessive self-regard tendency
&lt;ul&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;All man&amp;rsquo;s decisions are suddenly regarded by him as better than would have been the case just before he made them.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;When betting lotto, people thing that they have better chances because they picked the numbers. Random numbers would have the same chance of winning.&lt;/li&gt;
&lt;li&gt;Executives have high self-appraisal and they overestimate how much they&amp;rsquo;ll contribute to the company during personal interviews. Charlie suggests to pick people purely on their previous track record.&lt;/li&gt;
&lt;li&gt;The self-regard tendency causes people to make excuses for their poor fixable performance.&lt;/li&gt;
&lt;li&gt;When son was taking candy saying that he would later replace it, father responded: &lt;em&gt;Son, it would be better for you to simply take all you want and call yourself a thief every time you do it&lt;/em&gt;.
&lt;ul&gt;
&lt;li&gt;This illustrates how people tell themself stories about their character being good.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Optimism tendency
&lt;ul&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;What a man wishes he also believes&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Demosthenes&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;A way to counter this tendency is to write down the expected probabilities of all events that have to happen&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Deprival-superreactoin tendency
&lt;ul&gt;
&lt;li&gt;People perceive loss as much worse than what it really is&lt;/li&gt;
&lt;li&gt;They hold on to unimportant small things&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Social-proof tendency
&lt;ul&gt;
&lt;li&gt;In psychology experiments, people can make huge errors if they are peer-pressured into guessing wrong.&lt;/li&gt;
&lt;li&gt;People want to fit in and so they are rather wrong in crowd than right alone&lt;/li&gt;
&lt;li&gt;Judith Rich Haris demonstrated that super-respect of teenagers for their peers makes it very hard to guide their behaviour. &lt;strong&gt;It&amp;rsquo;s better to manipulate their selection of peers.&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Triggered most easily when stress and puzzlement are present&lt;/li&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;Learn how to ignore the examples from others when they are wrong, because few skills are more worth having.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Contrast-misreaction tendency
&lt;ul&gt;
&lt;li&gt;Brain doesn&amp;rsquo;t have an absolute scale in it and it instead uses the contrast/difference between two things&lt;/li&gt;
&lt;li&gt;This makes people make buy expensive $1000 leather seats when they are already buying $65,000 car because relatively it&amp;rsquo;s not that much money.&lt;/li&gt;
&lt;li&gt;Realestate scam: salesmen shows 3 terrible largely overpriced houses and then shows one average house slightly overpriced and in comparison it looks like a bargain.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Avoid ideology - it kills independent thinking
&lt;ul&gt;
&lt;li&gt;Charlie doesn&amp;rsquo;t let himself to have an opinion unless he can state the counter-argument better that the opposing side. This will help him understand both sides of an argument and make sure his thinking is not badly affected by ideology.&lt;/li&gt;
&lt;li&gt;Darwin was really good at this. He spent 20 years trying to disprove his theory.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Markets are mostly efficient by sometimes there is a mispriced opportunity&lt;/p&gt;
&lt;p&gt;Only make bet when you see an opportunity&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Munger talks about horce racing and says that his friend was able to make a living (even after paying 17% &amp;ldquo;tax&amp;rdquo; to the racetrack) by betting only sometimes when he saw a mispriced bet&lt;/li&gt;
&lt;li&gt;Berkshire Hathaway got most of their profit (at the 1995) from roughly 10 bets they placed&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Better business strategy&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;If business earns 6% on capital and you hold the stock for 40 years, you&amp;rsquo;ll make roughly 6% even if you buy the stock at a great discount&lt;/li&gt;
&lt;li&gt;If business earns 18% on capital over 20 years, you earn more even if you buy it at expensive &lt;em&gt;looking&lt;/em&gt; price&lt;/li&gt;
&lt;li&gt;Business is more important than manager. Ideally you want both to be great.&lt;/li&gt;
&lt;li&gt;Finding them small - buy Walmart when it goes public - doesn&amp;rsquo;t work for BH because they have too much money&lt;/li&gt;
&lt;li&gt;Finding them big - also look for a great manager (Jack Welsh in GE)&lt;/li&gt;
&lt;li&gt;Sometimes you find business that can rise prices but consumption will stay up (Disney with its parks)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Taxes - you want to hold onto assets and pay one tax at the end&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;But Munger recommends paying your taxes and not try to avoid them at all cost by sketchy means&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The more ideology you follow, the harder it will be for you to think clearly&lt;/p&gt;
&lt;p&gt;If you design a system that&amp;rsquo;s easy to cheat,  you are ruining civilization. It&amp;rsquo;s better to have unfair system than system that&amp;rsquo;s easy to cheat.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;E.g. compensation for injuries together with crooked chiropractors&lt;/li&gt;
&lt;li&gt;you need to stop slop early, it&amp;rsquo;s hard to stop when you let it run&lt;/li&gt;
&lt;li&gt;Systems that allow cheating will cause much larger damage than a the few people who can&amp;rsquo;t be treated fairly.&lt;/li&gt;
&lt;li&gt;Navy, if your ship sinks, your career is over even if it wasn&amp;rsquo;t your fault. This might be unfair, but it creates strong incentive not to sink ships so in total, the navy is better off.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On designing systems: Charlie is saying how great systems are reliable and how religion in US was great for reliability because it instilled guilt in people.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Charlie says that you want to maximise experience of the people who have the most aptitude and determination. You don&amp;rsquo;t want to give equal access to resource to people once you know the winners, that&amp;rsquo;s how the civilization will advance. You don&amp;rsquo;t want to design ariplanes or pick a surgeon for your child in a egalitarian fashion.&lt;/li&gt;
&lt;/ul&gt;
&lt;blockquote&gt;
&lt;p&gt;Charlie on gambling: With simple mechanical house odds against me, why in the world would I ever want to do that.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;blockquote&gt;
&lt;p&gt;Deliver to the world what you would buy if you were on the other end.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;If you don&amp;rsquo;t have competence to answer a question, just say so.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Don&amp;rsquo;t be like the confused bee which doesn&amp;rsquo;t have genetic programming to tell other bees that the nectar is straight up and dances confusing dance instead.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When Charlie asked his father (a lawyer) about two clients one good and one bad, father responded that the good client is treating everyone right and so he alone wouldn&amp;rsquo;t bring enough business. This was a partially hidden lesson about how to behave in life.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;He made Charlie to reach the conclusion himself and the lesson stuck better.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Charlie talks about how his company designed great police helmets and he gave away the intellectual property because if he started making the helmets, his company would be exposed to lawsuits.&lt;/p&gt;
&lt;p&gt;How can rising price increase consumption?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Legally: people perceive the goods as higher quality&lt;/li&gt;
&lt;li&gt;Illegally: you use the extra money to &lt;strong&gt;bribe purchasing agent&lt;/strong&gt; at your customer&amp;rsquo;s company
&lt;ul&gt;
&lt;li&gt;I haven&amp;rsquo;t thought about illegal possibilities to explain the economy. I should be.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Theory of [[comparative advantage]].&lt;/p&gt;
&lt;p&gt;Sample of Warren Buffet&amp;rsquo;s time:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Half is spent reading&lt;/li&gt;
&lt;li&gt;Half is spent talking one-on-one with highly qualified people he trusts&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Avoid envy, it&amp;rsquo;s the only mortal sin that you won&amp;rsquo;t have any fun at.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Also avoid resentment, revange, and self-pitty. Charlie can tell you to suck it up, he had to when his son died of cancer.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Charlie early in his career tried to always manoeuvre his position so he reports to them.&lt;/p&gt;
&lt;p&gt;Epictetus believed that any misfortune in life provides learning opportunity and opportunity to behave well. One shouldn&amp;rsquo;t become immersed in self-pity&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>David Grann - The Wager A Tale of Shipwreck</title>
      <link>https://blog.viktomas.com/graph/david-grann--the-wager/</link>
      <pubDate>Tue, 30 Jan 2024 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/david-grann--the-wager/</guid>
      <description>&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/david-grann--the-wager.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://openlibrary.org/works/OL28738217W/Wager&#34;&gt;OpenLibrary&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My rating: ★★★★☆ (80%)&lt;/p&gt;
&lt;p&gt;David Grann pieces together mid-seventeenth century story of a British warship wrecked at the coast of Patagonia.&lt;/p&gt;
&lt;p&gt;I recommend reading this book if you are interested in getting a peak into the way of living over a quarter of a millennium ago, way before Britain became the worldwide power it was a century or two later. You get an idea about how the low sailors lived in terrible conditions, away from their families for many years. Also, the main story involves people surviving incredible hardships, which makes my day-to-day issues pale in comparison.&lt;/p&gt;
&lt;p&gt;I both read and listened to this book, roughly 50-50 split.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>M. Mitchell Waldrop - The Dream Machine</title>
      <link>https://blog.viktomas.com/graph/mitchell-waldrop--the-dream-machine/</link>
      <pubDate>Sat, 13 Jan 2024 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/mitchell-waldrop--the-dream-machine/</guid>
      <description>&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/mitchell-waldrop--the-dream-machine.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://openlibrary.org/works/OL4300550W/The_Dream_Machine&#34;&gt;OpenLibrary&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;My rating: ★★★☆☆ (60%)&lt;/p&gt;
&lt;p&gt;This book offers an incredibly detailed history of computing, weaving a narrative through the lens of J.C.R Licklider. Waldrop explains everything from the beginning of computers (analogue computers like Vannevar Bush&amp;rsquo;s Differential analyzer) to &amp;ldquo;modern&amp;rdquo; microchip-based computers of the 1980s.&lt;/p&gt;
&lt;p&gt;For someone who started using computers in the late 90s, this book was a great explanation of how computing got to that point.&lt;/p&gt;
&lt;p&gt;I gave this book a 60% rating because it was too dense. Waldrop did a great job of connecting all the important events in computing together through places and people. However, there were still hundreds of names and tens of universities and institutions, and I got routinely lost in the overload of information. Maybe when I read this book next time, I&amp;rsquo;ll try to create a detailed timeline and graph of relationships between projects and people.&lt;/p&gt;
&lt;p&gt;There were several key paradigm shifts in computing. They are obvious in hindsight, but at their time, they were always an opinion held by a minority and shunned by others.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;From analogue to digital computers
&lt;ul&gt;
&lt;li&gt;Neuman and others designing general-purpose computer&lt;/li&gt;
&lt;li&gt;The idea of the program being stored with the data&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;From batch to real-time operation
&lt;ul&gt;
&lt;li&gt;Started with TX-0 and TX-2, DEC went to crate PDP computers&lt;/li&gt;
&lt;li&gt;Time-sharing
&lt;ul&gt;
&lt;li&gt;When CTSS was introduced in 1961, current &amp;ldquo;online&amp;rdquo; patterns started emerging with people sharing ideas, code and files&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Project MAC&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;From isolated to networked computers
&lt;ul&gt;
&lt;li&gt;ARPA, Ethernet, TCP/IP&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;From mainframes to personal computers
&lt;ul&gt;
&lt;li&gt;PDP-1, PDP-10, Alto, TX-2, the microchip revolution and Apple II&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The key events in the history of computing were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1920s - Automating computations with analogue computers (Vannevar Bush&amp;rsquo;s Differential Analyzer)&lt;/li&gt;
&lt;li&gt;1930s - Move from analogue to digital computing - Claude Shannon&amp;rsquo;s 1937 paper where he used relay circuits for binary logic&lt;/li&gt;
&lt;li&gt;1940s - ENIAC for computing artillery trajectories where Goldstine, Mauchly, Eckert and Neumann came up with &lt;strong&gt;Von Neumann architecture&lt;/strong&gt; (concept of software - the purpose of computer stored in memory instead of being built-in to the hardware)&lt;/li&gt;
&lt;li&gt;1950s
&lt;ul&gt;
&lt;li&gt;Work on TX-0 that made some believe that personal computing is possible and led directly to the founding of DEC&lt;/li&gt;
&lt;li&gt;McCarthy created LISP at MIT - the first interactive programming language with an interpreter&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1960s
&lt;ul&gt;
&lt;li&gt;CTSS - Compatible time-sharing system created by Corbato&lt;/li&gt;
&lt;li&gt;Lick joined ARPA and started funding research for the man-computer symbiosis vision&lt;/li&gt;
&lt;li&gt;Project MAC - Advances in time-sharing and development of Multics - the spiritual parent of Unix&lt;/li&gt;
&lt;li&gt;UX research lead by Douglas Englebert (see the &lt;a href=&#34;https://www.youtube.com/watch?v=yJDv-zdhzMY&#34;&gt;mother of all demos&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Outside of academia, batch processing was still the only paradigm, IBM released the System-360&lt;/li&gt;
&lt;li&gt;1966 - Bob Taylor (ARPA leader) asks Larry Roberts to come to ARPA and start a networking project&lt;/li&gt;
&lt;li&gt;1969 - first computer connected to ARPANET&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1970s
&lt;ul&gt;
&lt;li&gt;Xerox PARC - brightest researchers went there with Bob Taylor as the hiring manager
&lt;ul&gt;
&lt;li&gt;Alto, Smalltalk, Ethernet, Mouse,&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Apple and Microsoft started&lt;/li&gt;
&lt;li&gt;microchip revolution made computing personal - Apple 2&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1980s
&lt;ul&gt;
&lt;li&gt;IBM PC&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;[[Dream Machine - Detailed notes]]&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Isaac Asimov - Second Foundation</title>
      <link>https://blog.viktomas.com/graph/isaac-asimov--second-foundation/</link>
      <pubDate>Sat, 02 Dec 2023 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/isaac-asimov--second-foundation/</guid>
      <description>&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/isaac-asimov-second-foundation.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://openlibrary.org/works/OL46309W/Second_Foundation?edition=key%3A/books/OL47314617M&#34;&gt;OpenLibrary&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Released in 1953, this is the last book of the original Foundation trilogy. It is OK, but it is also very similar in style with the previous two books. I&amp;rsquo;m not planning on reading the rest of the Foundation books.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Isaac Asimov - Foundation and Empire</title>
      <link>https://blog.viktomas.com/graph/isaac-asimov--foundation-and-empire/</link>
      <pubDate>Wed, 01 Nov 2023 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/isaac-asimov--foundation-and-empire/</guid>
      <description>&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/isaac-asimov-foundation-and-empire.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://openlibrary.org/works/OL46224W/Foundation_and_Empire?edition=key%3A/books/OL43003836M&#34;&gt;OpenLibrary&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Released a year after the first book (1952), this novel follows the story of an established foundation planet and it&amp;rsquo;s struggles in the galaxy.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Isaac Asimov - Foundation</title>
      <link>https://blog.viktomas.com/graph/isaac-asimov--foundation/</link>
      <pubDate>Sun, 01 Oct 2023 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/isaac-asimov--foundation/</guid>
      <description>&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/isaac-asimov-foundation.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://openlibrary.org/works/OL46125W/Foundation?edition=key%3A/books/OL47079544M&#34;&gt;OpenLibrary&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;First released in 1951, the Foundation novel describes a story of declining galactic empire and one man&amp;rsquo;s personal mission to soften the fall.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Neovim - Make LSP Workspace Symbols show only workspace symbols</title>
      <link>https://blog.viktomas.com/graph/neovim-make-lsp-workspace-symbols-show-only-workspace-symbols/</link>
      <pubDate>Tue, 26 Sep 2023 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/neovim-make-lsp-workspace-symbols-show-only-workspace-symbols/</guid>
      <description>&lt;p&gt;I copied Helix&amp;rsquo;s key mappings for showing LSP symbols. I map &lt;code&gt;space&lt;/code&gt;+&lt;code&gt;s&lt;/code&gt; to show buffer symbols and &lt;code&gt;space&lt;/code&gt;+&lt;code&gt;S&lt;/code&gt; to show workspace symbols. For showing the workspace symbols I use Telescope&amp;rsquo;s &lt;a href=&#34;https://github.com/nvim-telescope/telescope.nvim#neovim-lsp-pickers&#34;&gt;&lt;code&gt;builtin.lsp_workspace_symbols&lt;/code&gt; picker&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;But when I press &lt;code&gt;space&lt;/code&gt;+&lt;code&gt;S&lt;/code&gt;, I get all the symbols from all dependencies. The default &lt;code&gt;gopls&lt;/code&gt; behaviour is to show you all available symbols, not the symbols from your code as you might expect.&lt;/p&gt;
&lt;p&gt;Luckily, there is a &lt;a href=&#34;https://github.com/golang/tools/blob/master/gopls/doc/settings.md#symbolscope-enum&#34;&gt;&lt;code&gt;symbolScope&lt;/code&gt; setting for &lt;code&gt;gopls&lt;/code&gt;&lt;/a&gt;. It defaults to &lt;code&gt;all&lt;/code&gt; but you can change it to &lt;code&gt;workspace&lt;/code&gt; and then &lt;code&gt;gopls&lt;/code&gt; only gives you symbols from your project.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://github.com/viktomas/dotfiles/blob/6cb4d1b0ecd201c44f8c75b47cd1cf2c882021fa/nvim/.config/nvim/lua/custom/plugins/lsp.lua#L96-L104&#34;&gt;This is my lspconfig&lt;/a&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;lspconfig[&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;gopls&amp;#34;&lt;/span&gt;].setup({
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    capabilities = capabilities,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    on_attach = on_attach,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    settings = {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        gopls = {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            symbolScope = &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;workspace&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }, &lt;span style=&#34;color:#008000&#34;&gt;-- when I search for symbols, I don&amp;#39;t want to see dependencies&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    },
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;})
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Neovim LSP rename like a boss (with normal mode keymaps)</title>
      <link>https://blog.viktomas.com/graph/neovim-lsp-rename-normal-mode-keymaps/</link>
      <pubDate>Mon, 25 Sep 2023 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/neovim-lsp-rename-normal-mode-keymaps/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: If you want to use normal keybindings when LSP-renaming symbols in Neovim, use my config snippet below.&lt;/p&gt;
&lt;p&gt;You set up your Neovim with LSP. You set up the &lt;a href=&#34;https://github.com/neovim/nvim-lspconfig/&#34;&gt;&lt;code&gt;neovim/nvim-lspconfig&lt;/code&gt;&lt;/a&gt; plugin and map &lt;code&gt;space&lt;/code&gt;+&lt;code&gt;r&lt;/code&gt; to the LSP rename (&lt;code&gt;vim.keymap.set(&amp;quot;n&amp;quot;, &amp;quot;&amp;lt;leader&amp;gt;r&amp;quot;, vim.lsp.buf.rename)&lt;/code&gt;). Now you are ready. But when you press &lt;code&gt;space&lt;/code&gt;+&lt;code&gt;r&lt;/code&gt;, instead of seeing an in-place popup like you&amp;rsquo;d see in the VS Code, you see a prompt at the bottom of the screen:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;VS Code&lt;/th&gt;
          &lt;th&gt;Neovim&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/image_1687612185452_0.png&#34;
    alt=&#34;image.png&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/td&gt;
          &lt;td&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/image_1687612360099_0.png&#34;
    alt=&#34;image.png&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;This, by itself, wouldn&amp;rsquo;t be the end of the world. You are a vimmer after all (not to be confused with &lt;a href=&#34;https://cs.wikipedia.org/wiki/Arnold_Rimmer&#34;&gt;Rimmer&lt;/a&gt;). The command line prompt is a badge of honor, not a UX hindrance.&lt;/p&gt;
&lt;p&gt;But it&amp;rsquo;s not that simple, this command line input &lt;strong&gt;doesn&amp;rsquo;t let you use normal mode keybindings&lt;/strong&gt;. What are you? Some pleb that stoops to using arrow keys? Or worse, hold backspace till you delete the word?&lt;/p&gt;
&lt;p&gt;This post will help you solve this problem like a pro. Credit for the idea goes to &lt;a href=&#34;https://www.reddit.com/r/neovim/comments/14gtp2c/comment/jp9jzt0/&#34;&gt;&lt;code&gt;u/voreny&lt;/code&gt;on reddit&lt;/a&gt;.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Some plugins improve the rename UI, but it can be simpler than that.&lt;/p&gt;
&lt;p&gt;I didn&amp;rsquo;t know that every time you use the command line (whether it&amp;rsquo;s a prompt, &lt;code&gt;:&lt;/code&gt; command or a &lt;code&gt;/&lt;/code&gt; search expression), you can press &lt;code&gt;CTRL-F&lt;/code&gt; (&lt;code&gt;:help c_CTRL-F&lt;/code&gt;) which takes you to a special Command-line window. Here you can edit your current line or any line in the history and when you press Enter, it will use the current line.&lt;/p&gt;
&lt;p&gt;The important detail is that in the Command-line window, you can use the normal mode keybindings that you are used to 🎉&lt;/p&gt;
&lt;p&gt;You can trigger the rename and then press &lt;code&gt;CTRL-F&lt;/code&gt; to be able to edit it properly.&lt;/p&gt;
&lt;p&gt;I always want to use normal mode keybindings when I rename symbols so I wrote &lt;a href=&#34;https://github.com/viktomas/dotfiles/blob/6ec1561e0c1f45903e6e1196ee2e8224c3f3c879/nvim/.config/nvim/lua/custom/plugins/lsp.lua#L64C4-L87&#34;&gt;this helper&lt;/a&gt; to automatically switch to the Command-line window after I start renaming:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-lua&#34; data-lang=&#34;lua&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  vim.keymap.set(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;n&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;&amp;lt;leader&amp;gt;r&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#00f&#34;&gt;function&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#008000&#34;&gt;-- when rename opens the prompt, this autocommand will trigger&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#008000&#34;&gt;-- it will &amp;#34;press&amp;#34; CTRL-F to enter the command-line window `:h cmdwin`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#008000&#34;&gt;-- in this window I can use normal mode keybindings&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;local&lt;/span&gt; cmdId
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    cmdId = vim.api.nvim_create_autocmd({ &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;CmdlineEnter&amp;#34;&lt;/span&gt; }, {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        callback = &lt;span style=&#34;color:#00f&#34;&gt;function&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#00f&#34;&gt;local&lt;/span&gt; key = vim.api.nvim_replace_termcodes(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;&amp;lt;C-f&amp;gt;&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#00f&#34;&gt;true&lt;/span&gt;, &lt;span style=&#34;color:#00f&#34;&gt;false&lt;/span&gt;, &lt;span style=&#34;color:#00f&#34;&gt;true&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          vim.api.nvim_feedkeys(key, &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;c&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#00f&#34;&gt;false&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          vim.api.nvim_feedkeys(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;0&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;n&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#00f&#34;&gt;false&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#008000&#34;&gt;-- autocmd was triggered and so we can remove the ID and return true to delete the autocmd&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          cmdId = &lt;span style=&#34;color:#00f&#34;&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          &lt;span style=&#34;color:#00f&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#00f&#34;&gt;end&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      })
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    vim.lsp.buf.rename()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#008000&#34;&gt;-- if LPS couldn&amp;#39;t trigger rename on the symbol, clear the autocmd&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    vim.defer_fn(&lt;span style=&#34;color:#00f&#34;&gt;function&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#008000&#34;&gt;-- the cmdId is not nil only if the LSP failed to rename&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#00f&#34;&gt;if&lt;/span&gt; cmdId &lt;span style=&#34;color:#00f&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;          vim.api.nvim_del_autocmd(cmdId)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#00f&#34;&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#00f&#34;&gt;end&lt;/span&gt;, 500)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#00f&#34;&gt;end&lt;/span&gt;, bufoptsWithDesc(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;Rename symbol&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And here is the final product:&lt;/p&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/rename_1695295085895_0.gif&#34;
    alt=&#34;rename.gif&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>New lines and terminals: CR vs. LF</title>
      <link>https://blog.viktomas.com/graph/new-lines-and-terminals-cr-vs-lf/</link>
      <pubDate>Sun, 27 Aug 2023 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/new-lines-and-terminals-cr-vs-lf/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m building a terminal emulator in go: &lt;a href=&#34;https://github.com/viktomas/gritty&#34;&gt;gritty&lt;/a&gt;. I noticed that &lt;code&gt;/bin/sh&lt;/code&gt; is sending me the ASCII CR character back as a part of the response. I tend to absolutely ignore the CR because in my mind it&amp;rsquo;s a &amp;ldquo;Windows thing&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;But seeing the CR made me realise that I don&amp;rsquo;t have a clear idea about how new lines work. In my mind, &lt;code&gt;new line = \n&lt;/code&gt; but it might be more complex than that.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;name&lt;/th&gt;
          &lt;th&gt;ASCII hex code&lt;/th&gt;
          &lt;th&gt;abbreviation&lt;/th&gt;
          &lt;th&gt;escape sequence*&lt;/th&gt;
          &lt;th&gt;Caret notation&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Line Feed&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;0x0A&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;LF&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;\n&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;^J&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Carriage Return&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;0x0D&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;CR&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;\r&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&lt;code&gt;^M&lt;/code&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;Line Feed - Move the cursor one line down&lt;/li&gt;
&lt;li&gt;Carriage Return - Move the cursor to the beginning of the line&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Historically, these two actions had to happen together so you or the computer can start typing text on the next line.&lt;/p&gt;
&lt;p&gt;So why did I see the CR character when working on my terminal emulator? Well it shows that we live in the past, at least when it comes to terminals.&lt;/p&gt;

&lt;div class=&#34;mermaid&#34; align=&#34;center&#34;&gt;graph RL;
subgraph &#34;unix - LF-only land&#34;
SHELL[Shell]
end
subgraph &#34;terminal - CR-LF land&#34;
TERM[Terminal emulator]
end
SHELL --&#34;\n&#34;--&gt; PTY
PTY --&#34;\r\n&#34;--&gt; TERM&lt;/div&gt;
&lt;p&gt;When shell sends a line feed character to the PTY, the TTY driver translates that to &lt;code&gt;\r\n&lt;/code&gt; for the terminal (emulator). This is dependent on the TTY driver settings.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;stty -a&lt;/code&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;icrnl&lt;/code&gt; (&lt;code&gt;-icrnl&lt;/code&gt;) - Map (do not map) CR to NL on input.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;onlcr&lt;/code&gt; (&lt;code&gt;-onlcr&lt;/code&gt;) Map (do not map) NL to CR-NL on output.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;So in summary, the terminals and the terminal emulators are still using &lt;code&gt;\r&lt;/code&gt; even on unix systems (for example when you press enter, terminal sends &lt;code&gt;\r&lt;/code&gt; to the shell). That&amp;rsquo;s why I saw it in my&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How do you call the string &lt;code&gt;\n&lt;/code&gt; (backslash followed by lower case n)? It is called &lt;em&gt;&amp;ldquo;escape sequence for newline character&amp;rdquo;&lt;/em&gt;. The escape sequence comes originally from C and JavaScript and Go both adopt it.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;helpful-links&#34;&gt;Helpful links&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://superuser.com/questions/714078/wrong-newline-character-over-serial-port-cr-instead-of-lf&#34;&gt;linux - Wrong newline character over serial port (CR instead of LF) - Super User&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/ASCI&#34;&gt;ASCII - Wikipedia&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Backup</title>
      <link>https://blog.viktomas.com/graph/backup/</link>
      <pubDate>Sun, 20 Aug 2023 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/backup/</guid>
      <description>&lt;p&gt;To see how I arrived at this process, go to &lt;a href=&#34;https://blog.viktomas.com/graph/designing-my-backup-process&#34;&gt;Designing my backup process&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;data-classification&#34;&gt;Data classification&lt;/h2&gt;
&lt;p&gt;I have to classify data to four categories:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;absolute backup&lt;/strong&gt; - backed up to a device in my apartment and device outside of my apartment
&lt;ul&gt;
&lt;li&gt;this is data that is personal and if I loose it, it&amp;rsquo;s lost forever with no chance of retrieval&lt;/li&gt;
&lt;li&gt;pictures, personal documents&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;home backup&lt;/strong&gt; - backed up to my nas
&lt;ul&gt;
&lt;li&gt;this is convenience backup, movies, TV Series, books,&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;no backup&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;keychain&lt;/strong&gt; - I need to have my keychain stored somewhere where I can access it even if I lose all devices (theft, disaster)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;components&#34;&gt;Components&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Edge devices - my laptop and phone&lt;/li&gt;
&lt;li&gt;[[My home lab]]&lt;/li&gt;
&lt;li&gt;1TB &lt;a href=&#34;https://www.hetzner.com/storage/storage-box&#34;&gt;hetzner storage box&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;6TB home NAS (Asustor ???)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;absolute-backup&#34;&gt;Absolute Backup&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Nextcloud runs on [[My home lab]] (accessible only through Tailscale)&lt;/li&gt;
&lt;li&gt;Every day, the server backs up the nextcloud folder with &lt;a href=&#34;https://blog.viktomas.com/graph/restic&#34;&gt;restic&lt;/a&gt; into NAS and &lt;a href=&#34;https://www.hetzner.com/storage/storage-box&#34;&gt;hetzner storage box&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Mac and Phone use nextcloud clients&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;issues&#34;&gt;Issues:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;When my server dies, I might loose access to my data until I get to my computer and recover from backup&lt;/li&gt;
&lt;li&gt;Hetzner storage box always allows to delete files (when you have write access). If someone hacks my server, they can delete the backups.
&lt;ul&gt;
&lt;li&gt;I have 10 weekly snapshots of the box that can&amp;rsquo;t be accessed using the server credentials. I can recover from snapshot if somebody deletes my backups.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;how-can-i-loose-my-data&#34;&gt;How can I loose my data:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;My apartment burns down and &lt;strong&gt;I lost keychain or forgot the master password&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Somebody steals [[My home lab]] and my NAS and hetzner has critical data loss at the same time&lt;/li&gt;
&lt;li&gt;My backups are corrupted and I can&amp;rsquo;t recover from them when [[My home lab]] dies.&lt;/li&gt;
&lt;li&gt;Something happens to me and I won&amp;rsquo;t be paying for the Hetzner Storage Box&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;home-backup&#34;&gt;Home backup&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The data lives in &lt;code&gt;/share&lt;/code&gt; folder on [[My home lab]].&lt;/li&gt;
&lt;li&gt;Every night, it gets rsynced with my NAS&lt;/li&gt;
&lt;li&gt;The data is not personal and it&amp;rsquo;s not encrypted on NAS&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;how-can-i-loose-my-data-1&#34;&gt;How can I loose my data:&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;If [[My home lab]] and the NAS gets stolen or dies&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;keychain&#34;&gt;Keychain&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;All my keys are stored in my KeePassXC keychain.&lt;/li&gt;
&lt;li&gt;I have it hidden at home on a USB stick.&lt;/li&gt;
&lt;li&gt;I have it in Dropbox (but dropbox login requires my main email)&lt;/li&gt;
&lt;li&gt;I don&amp;rsquo;t know how to protect against forgetting my master key&lt;/li&gt;
&lt;li&gt;[[When I die]]&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Fish shell has different PATH than neovim</title>
      <link>https://blog.viktomas.com/graph/fish-shell-has-different-path-than-neovim/</link>
      <pubDate>Wed, 09 Aug 2023 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/fish-shell-has-different-path-than-neovim/</guid>
      <description>&lt;p&gt;TL;DR: neovim triggers shell commands in a non-interactive subshell that is initialised from scratch from your &lt;code&gt;fish.confg&lt;/code&gt; (or other shell setup script). Ensure you set the &lt;code&gt;$PATH&lt;/code&gt; the same way for both the interactive and the non-interactive shell.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Today, I found a strange thing. I added a yaml formatter to my neovim config (I use &lt;a href=&#34;https://github.com/mhartington/formatter.nvim/tree/master&#34;&gt;&lt;code&gt;mhartington/formatter.nvim&lt;/code&gt;&lt;/a&gt;). The formatter &lt;a href=&#34;https://github.com/mhartington/formatter.nvim/blob/master/lua/formatter/filetypes/yaml.lua#L12-L14&#34;&gt;runs &lt;code&gt;python3 -m pyaml&lt;/code&gt;&lt;/a&gt; to format the file. So I installed &lt;code&gt;pip3 install pyaml&lt;/code&gt; to have the module.&lt;/p&gt;
&lt;p&gt;When I ran the formatter from within neovim, I saw an error &lt;code&gt;Failed to run formatter python3: /opt/homebrew/python3... no module named pyaml&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;That is strange because I don&amp;rsquo;t use homebrew &lt;code&gt;python3&lt;/code&gt;. I install python using the &lt;a href=&#34;https://asdf-vm.com/&#34;&gt;asdf VM&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;It seems that my fish shell and my neovim have a different path&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fish: &lt;code&gt;which python3&lt;/code&gt; returns &lt;code&gt;/Users/tomas/.asdf/shims/python3&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;neovim: &lt;code&gt;!:which python3&lt;/code&gt; returns &lt;code&gt;/opt/homebrew/bin/python3&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;and the &lt;code&gt;echo $PATH&lt;/code&gt; (in fish) and &lt;code&gt;:!echo $PATH&lt;/code&gt; (in neovim) also return different value.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;How could this be?&lt;/p&gt;
&lt;p&gt;I looked through fish and neovim documentation, trying to find evidence that fish doesn&amp;rsquo;t send the &lt;code&gt;$PATH&lt;/code&gt; variable to its subprocess or that neovim ignores it.&lt;/p&gt;
&lt;p&gt;In the end, I found the issue by running &lt;code&gt;:echo $PATH&lt;/code&gt; and &lt;code&gt;:!echo $PATH&lt;/code&gt; in neovim and noticing that the value is different. The first command returns the same value as the fish shell, and the second returns a different path.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Learning:&lt;/strong&gt; When you run &lt;code&gt;:!&lt;/code&gt; in neovim, it creates a subshell. It&amp;rsquo;s still fish &lt;code&gt;:!echo $SHELL&lt;/code&gt; returns &lt;code&gt;/opt/homebrew/bin/fish&lt;/code&gt; but the initialisation is different (non-interactive).&lt;/p&gt;
&lt;p&gt;See, I tried to be smart and efficient and guarded most of my &lt;code&gt;config.fish&lt;/code&gt; shell setup with &lt;code&gt;if status is-interactive&lt;/code&gt;. That means I don&amp;rsquo;t set up autocompletion and other interactive-only features when I run scripts. But one of the setup steps in this interactive-only section was to initialise asdf. When I moved the asdf setup from the interactive-only section, the &lt;code&gt;:echo $PATH&lt;/code&gt; and &lt;code&gt;:!echo $PATH&lt;/code&gt; commands in neovim had identical output.&lt;/p&gt;
&lt;p&gt;This is the &lt;a href=&#34;https://github.com/viktomas/dotfiles/commit/a1b940ffba634fbaaab22aa60ea0a10d2196d1e2&#34;&gt;fix commit in my dotfiles&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Designing my backup process</title>
      <link>https://blog.viktomas.com/graph/designing-my-backup-process/</link>
      <pubDate>Sat, 05 Aug 2023 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/designing-my-backup-process/</guid>
      <description>&lt;p&gt;This page describes how I designed my current &lt;a href=&#34;https://blog.viktomas.com/graph/backup&#34;&gt;Backup&lt;/a&gt; process.&lt;/p&gt;
&lt;p&gt;This design phase started on [[2023-08-05]]&lt;/p&gt;
&lt;h3 id=&#34;situation-at-2023-08-05&#34;&gt;Situation at [[2023-08-05]]&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;So far, I&amp;rsquo;ve got my files placed in several places:
&lt;ul&gt;
&lt;li&gt;Home NAS&lt;/li&gt;
&lt;li&gt;Phone&lt;/li&gt;
&lt;li&gt;Computer&lt;/li&gt;
&lt;li&gt;Server&lt;/li&gt;
&lt;li&gt;Next Cloud (&lt;a href=&#34;https://www.hetzner.com/storage/storage-share&#34;&gt;Hetzner Storage Share&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;External drives
&lt;ul&gt;
&lt;li&gt;Some have the files directly on NTFS&lt;/li&gt;
&lt;li&gt;Some use restic&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I came up with a data classification that is in the &lt;a href=&#34;https://blog.viktomas.com/graph/backup&#34;&gt;Backup&lt;/a&gt; process.&lt;/p&gt;
&lt;h2 id=&#34;absolute-backup&#34;&gt;Absolute Backup&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;For the result I came up with, see the &amp;ldquo;Absolute Backup&amp;rdquo; in &lt;a href=&#34;https://blog.viktomas.com/graph/backup&#34;&gt;Backup&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;criteria-for-absolute-backup&#34;&gt;Criteria for absolute backup&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;It needs to be encrypted when stored on device that I don&amp;rsquo;t own or device that doesn&amp;rsquo;t have encrypted drives
&lt;ul&gt;
&lt;li&gt;If my NAS supports encrypted volumes (that require password on startup) then the data can live there.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;I need to have an easy access to that data. I assume it will be up to 1TB and I can&amp;rsquo;t fit all that on my laptop or my phone&lt;/li&gt;
&lt;li&gt;It is done automatically, my phone and mac get backed up every day&lt;/li&gt;
&lt;li&gt;the default automated account supports append-only rights (only write, no delete)&lt;/li&gt;
&lt;li&gt;I can easily delete photos that got backed up without these deleted photos being backed up forever&lt;/li&gt;
&lt;li&gt;I would like to back up some server data (e.g. DB for my projects)&lt;/li&gt;
&lt;li&gt;My wife should be able to use it as well&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;alternative-options&#34;&gt;Alternative options&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;syncthing option&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;Use syncthing for the day-to-day data. (e.g. documents, recent photos)&lt;/li&gt;
&lt;li&gt;use NAS for older pictures and videos&lt;/li&gt;
&lt;li&gt;back up both to cloud storage with restic&lt;/li&gt;
&lt;li&gt;This is more complicated than the chosen option with nextcloud&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>James S.A. Corey - Leviathan Falls</title>
      <link>https://blog.viktomas.com/graph/corey-james--leviathan-falls/</link>
      <pubDate>Wed, 05 Apr 2023 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/corey-james--leviathan-falls/</guid>
      <description>&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/james-corey--leviathan-falls.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://openlibrary.org/books/OL38900848M/Leviathan_Falls&#34;&gt;OpenLibrary&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>James S.A. Corey - Tiamat&#39;s Wrath</title>
      <link>https://blog.viktomas.com/graph/corey-james--tiamats-wrath/</link>
      <pubDate>Wed, 15 Mar 2023 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/corey-james--tiamats-wrath/</guid>
      <description>&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/james-corey--tiamats-wrath.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://openlibrary.org/books/OL28046229M/Tiamat%27s_Wrath&#34;&gt;OpenLibrary&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>James S.A. Corey - Persepolis Rising</title>
      <link>https://blog.viktomas.com/graph/corey-james--persepolis-rising/</link>
      <pubDate>Mon, 20 Feb 2023 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/corey-james--persepolis-rising/</guid>
      <description>&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/james-corey--persepolis-rising.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;{:height 508, :width 324}&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://openlibrary.org/works/OL24720594W/Persepolis_Rising&#34;&gt;OpenLibrary&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>James S.A. Corey - Babylon&#39;s Ashes</title>
      <link>https://blog.viktomas.com/graph/corey-james--babylons-ashes/</link>
      <pubDate>Mon, 16 Jan 2023 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/corey-james--babylons-ashes/</guid>
      <description>&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/corey-james--babylons-ashes.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://openlibrary.org/works/OL19099155W/Babylon%27s_Ashes_%28The_Expanse%29&#34;&gt;OpenLibrary&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Another twenty hours of listening to the audiobook, another story of our solar system changed by the proto-molecule.  This time we follow a story of recovery from a planet-wide terrorist attack that happened in &lt;a href=&#34;https://blog.viktomas.com/books/corey-james--nemesis-games/&#34;&gt;Nemesis Games&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The previous books I read from this series are&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/corey-james--leviathan-wakes&#34;&gt;James S.A. Corey - Leviathan Wakes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/corey-james--calibans-war&#34;&gt;James S.A. Corey - Caliban&amp;rsquo;s War&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/corey-james--abaddons-gate&#34;&gt;James S.A. Corey - Abaddon&amp;rsquo;s Gate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/corey-james--cibola-burn&#34;&gt;James S.A. Corey - Cibola Burn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/corey-james--nemesis-games&#34;&gt;James S.A. Corey - Nemesis Games&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</description>
    </item>
    
    <item>
      <title>Simulate kubernetes pod resisting shutdown</title>
      <link>https://blog.viktomas.com/graph/k8s-pod-resists-shutdown/</link>
      <pubDate>Fri, 13 Jan 2023 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/k8s-pod-resists-shutdown/</guid>
      <description>&lt;p&gt;This is a short post about kubernetes pod lifecycle, namely terminating a pod.&lt;/p&gt;
&lt;p&gt;When kubernetes shuts down a pod it will:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Send SIGTERM signal to the container process&lt;/li&gt;
&lt;li&gt;wait for the grace period (default is 30s)&lt;/li&gt;
&lt;li&gt;Send SIGKILL signal to the process&lt;/li&gt;
&lt;/ol&gt;
&lt;blockquote&gt;
&lt;p&gt;When a Pod is being deleted, it is shown as &lt;code&gt;Terminating&lt;/code&gt; by some kubectl commands.
This &lt;code&gt;Terminating&lt;/code&gt; status is not one of the Pod phases.
A Pod is granted a term to terminate gracefully, which defaults to 30 seconds.
You can use the flag &lt;code&gt;--force&lt;/code&gt; to &lt;a href=&#34;https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-termination-forced&#34;&gt;terminate a Pod by force&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;Copied from &lt;a href=&#34;https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle/#pod-phase&#34;&gt;Pod phase - Pod Lifecycle | Kubernetes&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If needed to simulate simulate a container process that ignores the &amp;ldquo;softer&amp;rdquo; SIGTERM and has to be shut down using SIGKILL. This is how I did it:&lt;/p&gt;
&lt;h2 id=&#34;create-pod-that-ignores-sigterm&#34;&gt;Create pod that ignores SIGTERM&lt;/h2&gt;
&lt;p&gt;I created &lt;code&gt;bash.yml&lt;/code&gt; file with the following content&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yml&#34; data-lang=&#34;yml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; apiVersion: apps/v1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; kind: Deployment
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; metadata:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   name: bash
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   labels:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     app: bash
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; spec:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   selector:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     matchLabels:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       app: bash
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;   template:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     metadata:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       labels:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         app: bash
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;     spec:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;       containers:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;         - image: ubuntu
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           name: ubuntu
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;           command: [&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;bash&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;-c&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;trap echo sigterm SIGTERM;while :;do echo hello; sleep 10;done&amp;#34;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;This is the key part of the template: &lt;code&gt;trap echo sigterm SIGTERM;while :;do echo hello; sleep 10;done&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The bash script that &amp;ldquo;traps&amp;rdquo; the SIGTERM signal and only prints &lt;code&gt;sigterm&lt;/code&gt; instead.&lt;/li&gt;
&lt;li&gt;And to keep the container alive, we print &lt;code&gt;hello&lt;/code&gt; every 10 seconds.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I created deployment with &lt;code&gt;kubectl apply -f bash.yml&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I deleted that deployment with &lt;code&gt;kubectl delete deployment bash&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;I observed the pod hanging in terminating state.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;kubectl get pod
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;NAME                    READY   STATUS        RESTARTS   AGE
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;bash-7cf45b6b47-8km59   1/1     Terminating   0          22s
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;additional-resources&#34;&gt;Additional resources&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/&#34;&gt;Define a Command and Arguments for a Container | Kubernetes&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://cloud.google.com/blog/products/containers-kubernetes/kubernetes-best-practices-terminating-with-grace&#34;&gt;Kubernetes best practices: terminating with grace | Google Cloud Blog&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Trying to understand the impact of Fukushima Daiichi nuclear accident</title>
      <link>https://blog.viktomas.com/graph/understanding-fukushima-accident/</link>
      <pubDate>Fri, 13 Jan 2023 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/understanding-fukushima-accident/</guid>
      <description>&lt;p&gt;In &lt;a href=&#34;https://blog.viktomas.com/graph/j-storrs-hall--where-is-my-flying-car&#34;&gt;books/J. Storrs Hall - Where Is My Flying Car&lt;/a&gt;, the author (&lt;a href=&#34;https://en.wikipedia.org/wiki/J._Storrs_Hall&#34;&gt;Josh&lt;/a&gt;) discusses at length the overblown risks of nuclear energy.&lt;/p&gt;
&lt;p&gt;The argument could be summed up as &amp;ldquo;&lt;strong&gt;ionising radiation is much less dangerous than the mainstream opinion&lt;/strong&gt;&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;I do believe that [[Scary ideas live longer]], and so it would be in line with my mental model if the public gets scared into making policies/decision based on fear, rather than real data.&lt;/p&gt;
&lt;p&gt;This short post will sum up my research on the topic. I&amp;rsquo;m not an expert. I&amp;rsquo;ll add all my references so you can make your own conclusion.&lt;/p&gt;
&lt;h2 id=&#34;surprising-claim-1-nobody-died-from-radiation-exposure---true&#34;&gt;Surprising claim 1: Nobody died from radiation exposure - True&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;The &lt;a href=&#34;https://en.wikipedia.org/wiki/2011_T%C5%8Dhoku_earthquake_and_tsunami&#34;&gt;2011 Tōhoku earthquake and tsunami&lt;/a&gt; killed roughly 20,000 people.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Residents&lt;/strong&gt; weren&amp;rsquo;t exposed to harmful radiation&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;No harmful health effects were found in 195,345 residents living in the vicinity of the plant who were screened by the end of May 2011. All the 1,080 children tested for thyroid gland exposure showed results within safe limits, according to the report submitted to IAEA in June. &amp;hellip; So while the was no major public exposure, let alone deaths from radiation, there were a number of victims of &amp;lsquo;disaster-related death&amp;rsquo;, especially old people uprooted from homes and hospital because of forced evacuation and other nuclear-related measures.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.world-nuclear.org/information-library/safety-and-security/safety-of-plants/appendices/fukushima-radiation-exposure.aspx#ECSArticleLink2&#34;&gt;(www.world-nuclear.org)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;No adverse health effects among Fukushima residents have been documented that could be directly attributed to radiation exposure from the accident.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.unscear.org/unscear/uploads/documents/fact-sheets/2020-2021-report/2313286-FukushimaBrochure_English.pdf&#34;&gt;(UNESCAR 2020 report)&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Emergency workers&lt;/strong&gt; (20000) of them received on average 13mSv extra radiation (174 of which received dose higher than 100mSv) &lt;a href=&#34;https://www.unscear.org/unscear/uploads/documents/fact-sheets/2020-2021-report/2313286-FukushimaBrochure_English.pdf&#34;&gt;(UNESCAR 2020 report)&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;13mSv is &lt;a href=&#34;https://en.wikipedia.org/wiki/Background_radiation&#34;&gt;2 to 3 years worth of background radiation&lt;/a&gt; or &lt;a href=&#34;https://upload.wikimedia.org/wikipedia/commons/2/20/Radiation_Dose_Chart_by_Xkcd.png&#34;&gt;2 chest CT Scans&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;100mSv is twice the yearly limit for radiation workers in US&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The conclusion is that nobody got injured by ionising radiation and 174 people might have &lt;strong&gt;slightly&lt;/strong&gt; elevated ERR (excess relative risk) of cancer.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Slightly because it is roughly 8% per 100mSv according to &lt;a href=&#34;https://www.jstage.jst.go.jp/article/jhps/55/1/55_32/_pdf&#34;&gt;J-EPISODE Japanese study&lt;/a&gt; however, the confidence intervals also included 0%
&lt;ul&gt;
&lt;li&gt;For those 174 people it means that if someone&amp;rsquo;s chance of getting cancer was 10%, after the work on Daiichi rescue operations, their chance is 10.8%&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;174 people having 8%+ higher relative cancer seems like a rounding error to 20k people dead, 6k injured, and 2k missing.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;surprising-claim-2-there-is-no-risk-threshold-for-low-dose-radiation---maybe-but-i-wouldnt-bet-my-health-on-it&#34;&gt;Surprising claim 2: there is no-risk threshold for low-dose radiation - Maybe, but I wouldn&amp;rsquo;t bet my health on it&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Hermann_Joseph_Muller&#34;&gt;Hermann J. Muller&lt;/a&gt; discovered in 1926 discovered that ionising radiation causes genetic mutations. He got Nobel Prize for it.&lt;/li&gt;
&lt;li&gt;During his Nobel Prize lecture, he argued that there&amp;rsquo;s no limit bellow which the ionising radiation would not be harmful. This is know as the LNT Linear No-Threshold Model.&lt;/li&gt;
&lt;li&gt;Whether this model is true or not &lt;a href=&#34;https://en.wikipedia.org/wiki/Linear_no-threshold_model#Controversy&#34;&gt;is disputed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Josh (the author of the book) is proponent of a threshold. I had a look at several research papers on the topic
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.jstage.jst.go.jp/article/jhps/55/1/55_32/_pdf&#34;&gt;Direct Risk Comparison between Radiation and Smoking on Cancer Mortality among Nuclear Workers in Japan&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Maybe 100mSv could have 0.08 ERR, but the statistical significance is not high enough&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://watermark.silverchair.com/ncw314.pdf?token=AQECAHi208BE49Ooan9kkhW_Ercy7Dm3ZL_9Cf3qfKAc485ysgAAA1AwggNMBgkqhkiG9w0BBwagggM9MIIDOQIBADCCAzIGCSqGSIb3DQEHATAeBglghkgBZQMEAS4wEQQMHnkOrt2qCBYDjrkgAgEQgIIDAwEAqVWZP-ZW2vJ0d88xsmI52ujjZPHKe4ZFNLY0JeeURYf5cbdOYd1qI57bxZQjTsWCpTqHP6WwvQOfZTM5QU_y91aSPtUnlXLW0HHPOXzLqoaKlQ9AtcMDZ7NYBZXeavnEGvqRfVn-hz4F5teK2LK_wuDbJ7t4HlsESSjewKbF89ckewY7Fu_IWGDyAXhN3lksgdZQ6iZ5jTm9yyOqZuH0YLCWAZ9HFc0J9_ALKGSvtkOex0G7VrCvjahn3yW8I7o5BPJh9IzoX4msr0wpkqpx9OCA3TBZTvlpm8jLlBpk6-6MhbefbVzmlaglwwpzroIPCahpG26PhBT6NJp6AdQBknkaiDSdgajOpJOg6BcLB_fpdCjbYziB561q3MmnAY4Cz4wKfFeYGl_PLdtdym8LfiSarh5oOQBh8Y5iGTIZIKOAEqdup5Jq5U1BRsIrqIJX7ZrQRgKo-m7TsLhxu6LE7sAadHX4nNTwrWJeH3cbRmP7ZsbbkswoXDC4SMbHZV1KBci7UckTshMPt9iPd6sFXOzQL1nbkgf3S4MPbeK0_ieCxlE8s7f81RP5ZockURjzF_vXb2mXb2MVXScrVYTBmFOrBmkmN0mZTeypsH6Bxn6HflLcxNxb-G3QQOoNeVDR_BLUC1cecuLz68jNlHqldBhH3xsnrNqFgAdNyqrN25F8llzlqsSbkI3aDosOGG5LcRYEFNWXwMbIsUsT_tAxPBKJ4K1nD-9BaLm6LV_0gtofXTu5d0Xky1hXkZZYbyHysQix0748l7a1Lndz54h7ocKYQhNpShMuD9ERJhxDWjHb3pkhNpkmI2prvAXBWbCVzdGFRx5BWLzxPNGH8BBe0YKNaOF4thTTO_Tp06vneeNdYOgmT1bRajvS7sL2q0YpC_RAmVCMGdro1jKsAvDDFy8OLJHBopD4Jyhq1sDNuDL0Qto0qQ4yPmJg8p5vxIaWsll8SHrMsPAkjHGElGM58UOj4k_4uPrA5bxCUl-e6XRVzSNE7xtXbUX2n1KKv5OghQ&#34;&gt;The International Nuclear Workers Study - INWORKS&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;The evidence did not suggest any large ‘no risk’ threshold for dose, or any possible beneficial effects&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;0.47 ERR for 1 Gy (Sv) and they suggest that the effects are linear, so 4.7% per every 100mSv extra&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;So whilst it seems that the effect of low exposure are tiny, there might be some. I wouldn&amp;rsquo;t want to live in a place where I get more than 10 mSv a year (&lt;a href=&#34;https://en.wikipedia.org/wiki/Background_radiation&#34;&gt;average American gets 6mSv&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;suprising-claim-3-1600-people-died-prematurely-thanks-to-mandatory-evacuation-of-the-exclusion-zone&#34;&gt;Suprising claim 3: 1600 people died prematurely thanks to mandatory evacuation of the exclusion zone&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;This is a contested claim. If it was true, it would mainly concern very old people who were uprooted from their homes.&lt;/li&gt;
&lt;li&gt;Source: &lt;a href=&#34;https://en.wikipedia.org/wiki/Radiation_effects_from_the_Fukushima_Daiichi_nuclear_disaster#cite_note-Fukushima_evacuation_has_killed_more_than_earthquake_and_tsunami,_survey_says-52&#34;&gt;NBC News&lt;/a&gt;
id:: 65db2fb2-581d-47f9-a8da-e3fb436b86c9&lt;/li&gt;
&lt;li&gt;However, if you want to sink your time into some drama, read the &lt;a href=&#34;https://en.wikipedia.org/wiki/Talk:Radiation_effects_from_the_Fukushima_Daiichi_nuclear_disaster&#34;&gt;Wiki discussion about this contest&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;I think it&amp;rsquo;s plausible but I wouldn&amp;rsquo;t treat it as hard truth unless another source is provided.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;suprising-claim-4-evacuation-and-establishment-of-exclusion-zone-is-a-huge-overreaction&#34;&gt;Suprising claim 4: Evacuation and establishment of exclusion zone is a huge overreaction&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;The &amp;ldquo;Claim 1&amp;rdquo; discussion above states that no resident was harmed by excess radiation. That might not be true if the Japanese government didn&amp;rsquo;t go beserk with the evacuation. So this is not black and white. We couldn&amp;rsquo;t have no evacuation and no irradiated people at the same time.&lt;/li&gt;
&lt;li&gt;That being said, following is a discussion of the current (early 2024) state of affairs.&lt;/li&gt;
&lt;li&gt;Looking at the &lt;a href=&#34;https://fukushima-radioactivity.jp/pc/?lang=en&#34;&gt;radiation measurement map&lt;/a&gt;. Except for the few kilometres around directly next to the powerplant, there is very little radiation.&lt;/li&gt;
&lt;li&gt;Based on the research above, I&amp;rsquo;d be OK with receiving extra 5mSv a year (added to the 4mSv of background radiation), that leads up to 0.57micro Sv/h&lt;/li&gt;
&lt;li&gt;The exclusion zone is huge &lt;a href=&#34;https://fukushima.travel/page/safety#map&#34;&gt;https://fukushima.travel/page/safety#map&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;It could be smaller. This is my rough drawing (red is existing exclusion zone, green is where the radiation seems potentially dangerous).
&lt;ul&gt;
&lt;li&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/image_1708864688165_0.png&#34;
    alt=&#34;image.png&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;key-takaways&#34;&gt;Key takaways&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;When put in comparison with the Tsunami (or even &lt;a href=&#34;https://en.wikipedia.org/wiki/List_of_countries_by_traffic-related_death_rate&#34;&gt;a bad month in traffic accidents&lt;/a&gt;) the human harm is neglegable&lt;/li&gt;
&lt;li&gt;Whilst I think that the exclusion zone is orders of magnitude larger than it should be, I understand the fear. When someone says every radiation is bad radiation, you want to be as far from Daiichi as possible. We could really use some research into what does 100mSv a year for many years mean. If it&amp;rsquo;s no big deal, we are spending so much money and effort for nothing.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>James S.A. Corey - Nemesis Games</title>
      <link>https://blog.viktomas.com/graph/corey-james--nemesis-games/</link>
      <pubDate>Sat, 31 Dec 2022 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/corey-james--nemesis-games/</guid>
      <description>&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/corey-james--nemesis-games.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://openlibrary.org/works/OL17755458W/Nemesis_Games&#34;&gt;OpenLibrary&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Nemesis Games will give you insight into the personal history of Rocinante&amp;rsquo;s crew. And it will also manage to kill many, many, many people in the process.&lt;/p&gt;
&lt;p&gt;The previous books I read from this series are&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/corey-james--leviathan-wakes&#34;&gt;James S.A. Corey - Leviathan Wakes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/corey-james--calibans-war&#34;&gt;James S.A. Corey - Caliban&amp;rsquo;s War&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/corey-james--abaddons-gate&#34;&gt;James S.A. Corey - Abaddon&amp;rsquo;s Gate&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/corey-james--cibola-burn&#34;&gt;James S.A. Corey - Cibola Burn&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</description>
    </item>
    
    <item>
      <title>James S.A. Corey - Cibola Burn</title>
      <link>https://blog.viktomas.com/graph/corey-james--cibola-burn/</link>
      <pubDate>Tue, 20 Dec 2022 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/corey-james--cibola-burn/</guid>
      <description>&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/corey-james--cibola-burn.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://openlibrary.org/works/OL17454175W/Cibola_burn&#34;&gt;OpenLibrary&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Cibola Burn is the fourth book of The Expanse series. I can&amp;rsquo;t believe I&amp;rsquo;ve already listened to this series for eighty hours. It&amp;rsquo;s still good fun. I&amp;rsquo;ve grown to like the crew of Rocinante similarly as I like the watch from Pratchett&amp;rsquo;s Discworld.&lt;/p&gt;
&lt;p&gt;This book describes exploration of an Earth-like world in a different solar system in our galaxy.&lt;/p&gt;
&lt;p&gt;The previous books I read from this series are&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/books/corey-james--leviathan-wakes/&#34;&gt;Leviathan Wakes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/books/corey-james--calibans-war/&#34;&gt;Caliban&amp;rsquo;s War&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/books/corey-james--abaddons-gate/&#34;&gt;Abaddon&amp;rsquo;s Gate&lt;/a&gt;&lt;/li&gt;
&lt;/ol&gt;
</description>
    </item>
    
    <item>
      <title>How much energy do you need to boil a litre of water</title>
      <link>https://blog.viktomas.com/graph/boiling-litre-of-water/</link>
      <pubDate>Sat, 03 Dec 2022 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/boiling-litre-of-water/</guid>
      <description>&lt;p&gt;longform: true&lt;/p&gt;
&lt;p&gt;My wife likes to boil water. It&amp;rsquo;s a kind of a hobby of hers. She boils a litre of water to make a cup of tea. On the other hand, I see the electricity meter spin every time I turn on the induction stove. I made boiling the right amount of water into a game. Can I get the amount exactly right?&lt;/p&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/how_much_energy_do_you_need_to_boil_a_litre_of_water.png&#34;
    alt=&#34;Tea kettle on pile of money&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;But does this matter? What difference does it make if you boil more water than you need? I didn&amp;rsquo;t know the exact answer, so I did a little research.&lt;/p&gt;
&lt;p&gt;For an induction stove, at sea level, with room temperature 20℃, it takes roughly &lt;strong&gt;0.12kWh&lt;/strong&gt; to boil a litre of water.&lt;/p&gt;
&lt;p&gt;In Europe, electricity prices reached an all-time high (it&amp;rsquo;s 2022-12-03 today), and it now costs about half a dollar/euro per 1 kWh, which means that it costs &lt;strong&gt;6¢ to boil a litre of water&lt;/strong&gt;. That&amp;rsquo;s not enough to start arguments at home, but it will add up. After all, one litre of boiling water costs the same as &lt;a href=&#34;https://www.digitalocean.com/pricing/droplets&#34;&gt;10h of the smallest Digital Ocean Droplet&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Keep reading if you are interested in how I reached the number.&lt;/p&gt;
&lt;hr&gt;
&lt;h2 id=&#34;calculation-details&#34;&gt;Calculation details&lt;/h2&gt;
&lt;p&gt;I took the formula from &lt;a href=&#34;https://www.quora.com/How-much-energy-is-needed-to-boil-water-How-much-energy-would-it-take-to-boil-1-liter-of-water&#34;&gt;How much energy is needed to boil water? How much energy would it take to boil 1 liter of water? - Quora&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1g of water raised by 1℃ takes 1 calorie (4.184 Joule)&lt;/li&gt;
&lt;li&gt;1 Joule = 1W/s&lt;/li&gt;
&lt;li&gt;1 kWh = 3 600 000 Jules&lt;/li&gt;
&lt;li&gt;1l from 20℃ to 100℃ is 1000g by 80℃ = 80k calories = 334720 Joules = 0,09298KWh at 100% efficiency&lt;/li&gt;
&lt;li&gt;That makes it roughly 0.116kWh to boil a litre of water at 80% efficiency of the induction stove.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It surprised me that the energy required to warm up water doesn&amp;rsquo;t change with different starting temperatures. When we ignore phase change (solid -&amp;gt; liquid -&amp;gt; steam), it always takes one calorie to increase the temperature by one degree. No matter if the starting temperature is 1℃ or 89℃. I should have paid more attention to primary school physics.&lt;/p&gt;
&lt;h2 id=&#34;cooking-efficiency&#34;&gt;Cooking efficiency&lt;/h2&gt;
&lt;p&gt;I read two sources to understand the cooking efficiency of electric coil and induction stoves:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.centurylife.org/is-induction-more-efficient-than-electric-coil-or-gas-an-energy-efficiency-comparison-between-stoves/&#34;&gt;CenturyLife.Org - Is Induction More Efficient Than Electric Coil or Gas? An Energy Efficiency Comparison Between Stoves&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Coil efficiency is similar to induction. Induction is better for short tasks, coil for longer tasks. US department of energy states 74-77% efficiency for coil and 84% for induction.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.aceee.org/files/proceedings/2014/data/papers/9-702.pdf&#34;&gt;Electric Power Research Institute - Induction Cooking Technology Design and Assessment&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;Induction cooker has around 77% efficiency.&lt;/li&gt;
&lt;li&gt;The electric coil has 81% efficiency for a large vessel, 41% for a small vessel.&lt;/li&gt;
&lt;li&gt;Half power is always more efficient than full power.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For my back-of-an-envelope calculation, this was enough to settle on roughly 80% efficiency for my induction stove.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>James S.A. Corey - Abaddon&#39;s Gate</title>
      <link>https://blog.viktomas.com/graph/corey-james--abaddons-gate/</link>
      <pubDate>Thu, 01 Dec 2022 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/corey-james--abaddons-gate/</guid>
      <description>&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/corey-james--abaddons-gate.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://openlibrary.org/works/OL17074648W/Abaddon%27s_Gate&#34;&gt;OpenLibrary&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Abaddon&amp;rsquo;s Gate is the third book of the Expanse series. A mysterious portal to another part of the universe has been opened in our solar system. Listen to this twenty-hour book to find out what&amp;rsquo;s on the other side.&lt;/p&gt;
&lt;p&gt;At the risk of repeating myself, I really enjoyed listening to this story for twenty hours. The book&amp;rsquo;s authors again use the literary style of narrating the story from the viewpoint of multiple people. This time it&amp;rsquo;s well-funded terrorist, head of security on a ship, pastor, and our loved captain of Rocinante: Holden.&lt;/p&gt;
&lt;p&gt;I recommend reading &lt;a href=&#34;https://blog.viktomas.com/graph/corey-james--leviathan-wakes&#34;&gt;James S.A. Corey - Leviathan Wakes&lt;/a&gt; and &lt;a href=&#34;https://blog.viktomas.com/graph/corey-james--calibans-war&#34;&gt;James S.A. Corey - Caliban&amp;rsquo;s War&lt;/a&gt; first.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Randall Munroe - What if? 2</title>
      <link>https://blog.viktomas.com/graph/randall-munroe--what-if-2/</link>
      <pubDate>Sun, 20 Nov 2022 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/randall-munroe--what-if-2/</guid>
      <description>&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/randall-munroe--what-if-2.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://openlibrary.org/works/OL27275984W/What_If_2&#34;&gt;OpenLibrary&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Same as &lt;a href=&#34;https://blog.viktomas.com/books/munroe-randall--how-to/&#34;&gt;How To&lt;/a&gt; and &lt;a href=&#34;https://blog.viktomas.com/books/munroe-randall--what-if/&#34;&gt;What if&lt;/a&gt; this book was an entertaining read. I wish I had physics so internalised as Randall so I could make back of a napkin, rough order of magnitude calculations as he does. I recommend reading all Randall&amp;rsquo;s books for the entertainment value. I don&amp;rsquo;t have hopes of remembering the physics.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Fixing goreleaser error: failed to publish artifacts .. already_exists</title>
      <link>https://blog.viktomas.com/graph/goreleaser-already-exists-error/</link>
      <pubDate>Thu, 17 Nov 2022 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/goreleaser-already-exists-error/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; If you have the same issue as I did, then you are not restricting the &lt;code&gt;goreleaser&lt;/code&gt; action to tags, and you trigger the same release from the &lt;code&gt;main&lt;/code&gt; branch and the git tag.&lt;/p&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/computers-on-a-race-track.png&#34;
    alt=&#34;computers on a race track&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;Today I tried to release a new version of &lt;a href=&#34;https://github.com/viktomas/godu&#34;&gt;&lt;code&gt;godu&lt;/code&gt;&lt;/a&gt; and the &lt;a href=&#34;https://github.com/viktomas/godu/actions/runs/3481888630/jobs/5823548323&#34;&gt;release action failed&lt;/a&gt; 💥.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ⨯ release failed after 2m18s
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    error=scm releases: failed to publish artifacts:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    failed to upload godu_1.4.0_Linux_arm64.tar.gz after 1 tries:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    POST https://uploads.github.com/repos/viktomas/godu/releases/83296480/assets?name=godu_1.4.0_Linux_arm64.tar.gz:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    422 Validation Failed [{Resource:ReleaseAsset Field:name Code:already_exists Message:}]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;After some searching, I found this GitHub issue &lt;a href=&#34;https://github.com/goreleaser/goreleaser/issues/2506#issuecomment-926846622&#34;&gt;[Bug]: publishing multiple artifacts broken&lt;/a&gt;, which explained the problem.&lt;/p&gt;
&lt;p&gt;In my &lt;a href=&#34;https://github.com/viktomas/godu/blob/86fcdd5978b17f884013413b431cef9163f8ddba/.github/workflows/release.yml&#34;&gt;release action&lt;/a&gt;, I don&amp;rsquo;t restrict where the action is run (tags, branches, PRs). I do that on purpose. I&amp;rsquo;m taking advantage of the following &lt;code&gt;goreleaser&lt;/code&gt; behaviour:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;When you trigger release action on a commit without a tag, &lt;code&gt;goreleaser&lt;/code&gt; runs in a &lt;em&gt;snapshot&lt;/em&gt; mode. It still validates that the release action works but it doesn&amp;rsquo;t publish the release.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The &lt;a href=&#34;https://github.com/goreleaser/goreleaser-action&#34;&gt;goreleaser GitHub action&lt;/a&gt; recommends to run it only on tags:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-yaml&#34; data-lang=&#34;yaml&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;on:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  push:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    tags:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      - &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#39;*&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But that way, I would lose the release verification on non-tag builds.&lt;/p&gt;
&lt;p&gt;I caused the issue by pushing both the tag and the &lt;code&gt;main&lt;/code&gt; branch at the same time, triggering two identical release actions.&lt;/p&gt;
&lt;p&gt;My solution is pragmatic: &lt;strong&gt;first push the &lt;code&gt;main&lt;/code&gt; branch, wait for the green build and then push the tag&lt;/strong&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>James S.A. Corey - Caliban&#39;s War</title>
      <link>https://blog.viktomas.com/graph/corey-james--calibans-war/</link>
      <pubDate>Mon, 14 Nov 2022 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/corey-james--calibans-war/</guid>
      <description>&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/james-corey--calibans-war.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;Caliban&amp;rsquo;s War is the second book of the Expanse series. Another twenty hours of listening to an entertaining story from our solar system.&lt;/p&gt;
&lt;p&gt;If you haven&amp;rsquo;t read &lt;a href=&#34;https://blog.viktomas.com/graph/corey-james--leviathan-wakes&#34;&gt;James S.A. Corey - Leviathan Wakes&lt;/a&gt; , definitely start with that, otherwise the events in Caliban&amp;rsquo;s war won&amp;rsquo;t make as much sense. After you finish reading (or listening to) &lt;a href=&#34;https://blog.viktomas.com/graph/corey-james--leviathan-wakes&#34;&gt;James S.A. Corey - Leviathan Wakes&lt;/a&gt; , you&amp;rsquo;ll know whether you want to keep reading through the series.&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;ll follow more characters than just two: a Martian marine, an Earther politician, a Ganymede scientist and of course, Holden, the main character of the series.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>James S.A. Corey - Leviathan Wakes</title>
      <link>https://blog.viktomas.com/graph/corey-james--leviathan-wakes/</link>
      <pubDate>Wed, 02 Nov 2022 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/corey-james--leviathan-wakes/</guid>
      <description>&lt;p&gt;Realistic sci-fi is the best genre of literature, right after comedy fantasy/sci-fi. I love when the rules of the universe (think gravity, space travel, technology) are close enough to our age that it&amp;rsquo;s not just hand-waving &amp;ldquo;magic&amp;rdquo; like teleports and warp drives. Technology is more fun when I can imagine it existing if we just improved the existing X by 100%.&lt;/p&gt;
&lt;p&gt;Realism is one of the reasons I loved &lt;a href=&#34;https://blog.viktomas.com/books/andy-weir--project-hail-mary/&#34;&gt;Project Hail Mary&lt;/a&gt; and &lt;a href=&#34;https://blog.viktomas.com/books/andy-weir--the-martian/&#34;&gt;Martian&lt;/a&gt;. And now I love the Expanse series too (Leviathan Wakes is book number one of the expanse series).&lt;/p&gt;
&lt;p&gt;I watched the TV show five years ago, and luckily, I forgot most of it. Now I can enjoy the plot again. And the plot is fantastic. Mr. Corey does a great job intertwining the stories of the two main characters, Holden and Muller. He gives you two distinct viewpoints on the same events.&lt;/p&gt;
&lt;p&gt;Join me and fly through our solar system with the Canterbury crew 🚀&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Pratchett, Gaiman - Good Omens</title>
      <link>https://blog.viktomas.com/graph/pratchett-gaiman--good-omens/</link>
      <pubDate>Tue, 04 Oct 2022 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/pratchett-gaiman--good-omens/</guid>
      <description>&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/good-omens.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://openlibrary.org/works/OL453936W/Good_Omens&#34;&gt;OpenLibrary&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This is pure Britishness in a book, packed with humour and funny phrasing to the brim. The only drawback for a non-native speaker is the huge vocabulary. I was lucky to listen to this book as an audiobook, so I could guess the meaning of many words from the context.&lt;/p&gt;
&lt;p&gt;The audiobook was the &amp;ldquo;Good Omens A Full Cast Production&amp;rdquo; version.&lt;/p&gt;
&lt;p&gt;It took me over a month to get through this book because, unlike other easy-going audiobooks this one required my full attention, and I couldn&amp;rsquo;t listen to it when working out or running.&lt;/p&gt;
&lt;p&gt;But it was worth it. Most of the time, I was grinning from ear to ear. If you like Pratchett&amp;rsquo;s comedy style, you&amp;rsquo;ll love the Gaiman sprinkled in.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Go: range is like a function call</title>
      <link>https://blog.viktomas.com/graph/go-range-function-call/</link>
      <pubDate>Tue, 27 Sep 2022 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/go-range-function-call/</guid>
      <description>&lt;p&gt;When I watched &lt;a href=&#34;https://learning.oreilly.com/videos/ultimate-go-programming/9780135261651/&#34;&gt;Ultimate Go Programming&lt;/a&gt; today, I learned about an unintuitive Go programming language behaviour. I&amp;rsquo;m going to show you.&lt;/p&gt;
&lt;p&gt;Have a look at the following code and tell me what will be printed in the console:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;arr := [...]&lt;span style=&#34;color:#2b91af&#34;&gt;string&lt;/span&gt;{&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;Hello&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;you&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;handsome&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;person&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fmt.Printf(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;before: %q\n&amp;#34;&lt;/span&gt;, arr[1])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;for&lt;/span&gt; i, v := &lt;span style=&#34;color:#00f&#34;&gt;range&lt;/span&gt; arr {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#008000&#34;&gt;// at the very first iteration we change second word: you -&amp;gt; from
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;  arr[1] = &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;from&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#00f&#34;&gt;if&lt;/span&gt; i == 1 {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#008000&#34;&gt;// second iteration, we print the value of second word from range
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;    fmt.Printf(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;after: %q\n&amp;#34;&lt;/span&gt;, v)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In the first iteration, we changed &lt;code&gt;&amp;quot;you&amp;quot;&lt;/code&gt; to &lt;code&gt;&amp;quot;from&amp;quot;&lt;/code&gt;; in the second iteration we printed the second element from the array. You might expect that you&amp;rsquo;ll see:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;before: &amp;#34;you&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;after: &amp;#34;from&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href=&#34;https://go.dev/play/p/ygD29ynwhgB&#34;&gt;Try it for yourself.&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The result is&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;before: &amp;#34;you&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;after: &amp;#34;you&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now let&amp;rsquo;s change the array to a slice:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;slice := []&lt;span style=&#34;color:#2b91af&#34;&gt;string&lt;/span&gt;{&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;Hello&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;you&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;handsome&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;person&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;fmt.Printf(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;before: %q\n&amp;#34;&lt;/span&gt;, slice[1])
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;for&lt;/span&gt; i, v := &lt;span style=&#34;color:#00f&#34;&gt;range&lt;/span&gt; slice {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  slice[1] = &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;from&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#00f&#34;&gt;if&lt;/span&gt; i == 1 {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    fmt.Printf(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;after: %q\n&amp;#34;&lt;/span&gt;, v)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When you run this code (&lt;a href=&#34;https://go.dev/play/p/Gutr5NKzMSV&#34;&gt;playground&lt;/a&gt;), you&amp;rsquo;ll see the expected&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;before: &amp;#34;you&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;after: &amp;#34;from&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Why do you think this is? (answer in 3.. 2.. 1..)&lt;/p&gt;
&lt;h3 id=&#34;the-answer&#34;&gt;The answer&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;range&lt;/code&gt; clause works exactly like a function call in the sense that you pass arguments to it &lt;strong&gt;by value&lt;/strong&gt;. That means that when you write &lt;code&gt;range thing&lt;/code&gt;,  the Go runtime will make a &lt;strong&gt;copy&lt;/strong&gt; of the &lt;code&gt;thing&lt;/code&gt; and ranges over the copy.&lt;/p&gt;
&lt;p&gt;We saw that ranging over slices behaves as we expect. That&amp;rsquo;s because of the internal representation of a slice:&lt;/p&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/slice_1664292137141_0.png&#34;
    alt=&#34;slice&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;When the Go runtime copies the slice, it only copies the small data structure containing a pointer to the backing array, length and capacity. That&amp;rsquo;s why we can see changes made to the slice during iteration, both the original &lt;code&gt;slice&lt;/code&gt; and the copied value used in &lt;code&gt;range&lt;/code&gt; point to the same backing array.&lt;/p&gt;
&lt;p&gt;Now you might start to see why the array from the first example behaved differently.&lt;/p&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/array_1664292297930_0.png&#34;
    alt=&#34;array&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;When &lt;code&gt;range&lt;/code&gt; copies the &lt;code&gt;arr&lt;/code&gt; value, it copies the whole array. Changing the original array doesn&amp;rsquo;t affect the &lt;code&gt;range&lt;/code&gt; iterations.&lt;/p&gt;
&lt;p&gt;So there you have it. **&lt;code&gt;range&lt;/code&gt; is like a function call. &lt;a href=&#34;https://go.dev/ref/spec#For_range&#34;&gt;The language specification&lt;/a&gt; doesn&amp;rsquo;t state that explicitly, but luckily, you probably won&amp;rsquo;t see this issue during normal programming. You can range over slices, maps, channels and arrays, but only arrays are copied whole. I hope this behaviour surprised you as it surprised me.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>I wrote a command line tool to export Logseq pages as blog posts</title>
      <link>https://blog.viktomas.com/graph/logseq-export/</link>
      <pubDate>Mon, 26 Sep 2022 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/logseq-export/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve got an exciting little program to share with you. It&amp;rsquo;s a command line utility that exports your public &lt;a href=&#34;https://logseq.com/&#34;&gt;Logseq&lt;/a&gt; pages into Markdown blog posts compatible with most of the static-site generators.&lt;/p&gt;
&lt;p&gt;All you have to do is write your post in Logseq, run the logseq-extractor command with a few parameters and your blog has got the latest version of your post, ready for publishing.&lt;/p&gt;
&lt;p&gt;Two weeks ago, I looked for this very program but couldn&amp;rsquo;t find it. I wasn&amp;rsquo;t the only one. Many people wanted the same. See this Logseq feature request: &lt;a href=&#34;https://discuss.logseq.com/t/command-line-to-export-pages-and-data/2871/8&#34;&gt;Command Line to Export Pages and Data - Feature Requests - Logseq&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;So without further ado, meet &lt;a href=&#34;https://github.com/viktomas/logseq-export&#34;&gt;logseq-export: Tool to export raw Logseq Markdown files into Markdown blog posts with front matter.&lt;/a&gt; 🚀&lt;/p&gt;
&lt;p&gt;I explained how to use it on the project&amp;rsquo;s README page, and I won&amp;rsquo;t repeat it here. I hope you&amp;rsquo;ll enjoy using it. Create a &lt;a href=&#34;https://github.com/viktomas/logseq-extractor/issues&#34;&gt;GitHub issue&lt;/a&gt; if you&amp;rsquo;d like a new feature or if you find a bug. You are welcomed to contribute code if you know the Go programming language.&lt;/p&gt;
&lt;p&gt;And yeah, this post has been published with &lt;code&gt;logseq-export&lt;/code&gt; 💪&lt;/p&gt;
&lt;p&gt;EDIT (2022-09-27): Now &lt;code&gt;logseq-export&lt;/code&gt; also exports your Logseq images to your blog 🎉&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Andy Weir - Martian</title>
      <link>https://blog.viktomas.com/graph/andy-weir--the-martian/</link>
      <pubDate>Thu, 08 Sep 2022 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/andy-weir--the-martian/</guid>
      <description>&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/andy-weir--martian.jpg&#34;
    alt=&#34;cover&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://openlibrary.org/books/OL26420821M/The_Martian&#34;&gt;OpenLibrary&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Andy Weir does not disappoint with his realistic sci-fi. I&amp;rsquo;ve read &lt;a href=&#34;https://blog.viktomas.com/books/andy-weir--project-hail-mary/&#34;&gt;Project Hail Mary&lt;/a&gt; and I&amp;rsquo;ve seen &lt;a href=&#34;https://www.imdb.com/title/tt3659388/&#34;&gt;the movie&lt;/a&gt; before listening to this book. My expectations were high, and Martian met them but not surpassed them.&lt;/p&gt;
&lt;p&gt;When you read this book, you&amp;rsquo;ll witness a sci-fi adventure in the near future. Humanity sends its third mission to Mars, and you get to follow a birlliant and resourceful botanist through an epic failure and struggle for survival. Every part of the story is believable and supported by current science.&lt;/p&gt;
&lt;p&gt;Side note: I couldn&amp;rsquo;t get the image of Matt Damon out of my head because  he played the main character in the movie. That&amp;rsquo;s why I prefer to read the book first and watch the movie later.&lt;/p&gt;
&lt;p&gt;If you haven&amp;rsquo;t read &lt;a href=&#34;https://blog.viktomas.com/books/andy-weir--project-hail-mary/&#34;&gt;Project Hail Mary&lt;/a&gt; yet, start with that. If you love it as much as I did, you&amp;rsquo;ll enjoy Martian too.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Go</title>
      <link>https://blog.viktomas.com/graph/go/</link>
      <pubDate>Wed, 17 Aug 2022 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/go/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/go___code-review&#34;&gt;Code Review&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[[Templ]]&lt;/p&gt;
&lt;p&gt;Learning resources:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://learning.oreilly.com/library/view/concurrency-in-go/9781491941294/&#34;&gt;Concurrency in Go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://learning.oreilly.com/videos/ultimate-go-programming/9780135261651/&#34;&gt;Ultimate Go Programming, Second Edition&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://learning.oreilly.com/library/view/learning-go/9781492077206/&#34;&gt;Learning Go&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://quii.gitbook.io/learn-go-with-tests/&#34;&gt;Learn Go with Tests&lt;/a&gt; - TDD exercises&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.simonandschuster.com/books/100-Go-Mistakes-and-How-to-Avoid-Them/Teiva-Harsanyi/9781617299599&#34;&gt;100 Go Mistakes and How to Avoid Them&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;setup&#34;&gt;Setup&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;$GOROOT&lt;/code&gt; - where your SDK is&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$GOPATH&lt;/code&gt; - where your go &lt;code&gt;src&lt;/code&gt;, &lt;code&gt;pkg&lt;/code&gt;, and &lt;code&gt;bin&lt;/code&gt; live&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;modules&#34;&gt;Modules&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;got mod init gitlab.com/viktomas/{name}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;go mod init&lt;/code&gt;  creates a new module, initializing the  &lt;code&gt;go.mod&lt;/code&gt;  file that describes it.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;go build&lt;/code&gt; ,  &lt;code&gt;go test&lt;/code&gt; , and other package-building commands add new dependencies to  &lt;code&gt;go.mod&lt;/code&gt;  as needed.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;go list -m all&lt;/code&gt;  prints the current module’s dependencies.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;go get&lt;/code&gt;  changes the required version of a dependency (or adds a new dependency).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;go mod tidy&lt;/code&gt;  removes unused dependencies.&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; read about minimal version selection &lt;a href=&#34;https://stackoverflow.com/a/70006832/606571&#34;&gt;https://stackoverflow.com/a/70006832/606571&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;build&#34;&gt;Build&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;go build -C dir -o output-file&lt;/code&gt; this will build the package in &lt;code&gt;dir&lt;/code&gt; and will produce output-file if the package is &lt;code&gt;main&lt;/code&gt; package. It will follow all the imports and will build those packages as well&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;variables&#34;&gt;Variables&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;h3 id=&#34;naming-conventions&#34;&gt;Naming conventions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;camel case - &lt;code&gt;seasonNumber&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;acronyms all uppercase - &lt;code&gt;theURL&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;first letter case decides public/private&lt;/li&gt;
&lt;li&gt;longer names for longer lifespan&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;declaration&#34;&gt;Declaration&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;var foo int&lt;/code&gt; - declare in different scope than where we assign, or just want to create &lt;em&gt;zero&lt;/em&gt; value&lt;/li&gt;
&lt;li&gt;&lt;code&gt;var foo int = 42&lt;/code&gt; - when compiler guesses wrong&lt;/li&gt;
&lt;li&gt;&lt;code&gt;foo := 42&lt;/code&gt; - all the time&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;type-conversions&#34;&gt;Type conversions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;var&lt;/span&gt; i &lt;span style=&#34;color:#2b91af&#34;&gt;int&lt;/span&gt; = 42
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;var&lt;/span&gt; j &lt;span style=&#34;color:#2b91af&#34;&gt;float32&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;j = float32(i)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;for converting numbers to strings, you have to use &lt;code&gt;strconv&lt;/code&gt; package, otherwise go will use int number as the unicode number (e.g. converting &lt;code&gt;42&lt;/code&gt; to &lt;code&gt;*&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;go doesn&amp;rsquo;t do automatic type conversion because it might loose information&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s different from &lt;em&gt;casting&lt;/em&gt;, casting is telling the runtime to trust us that there is a different type, conversion transforms one value in memory to a different representation&lt;/li&gt;
&lt;li&gt;You can do explicit type conversion between compatible structs&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;primitive-types&#34;&gt;Primitive types&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;h3 id=&#34;boolean&#34;&gt;Boolean&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;zero value is &lt;code&gt;false&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;numeric-types&#34;&gt;Numeric types&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;zero value is always &lt;code&gt;0&lt;/code&gt; or equvialent&lt;/li&gt;
&lt;li&gt;
&lt;h4 id=&#34;integer-int&#34;&gt;Integer &lt;code&gt;int&lt;/code&gt;&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;we don&amp;rsquo;t know the size, it will be at least 32, but it might be 64 bits&lt;/li&gt;
&lt;li&gt;also can be unsigned int with &lt;code&gt;uint&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;float&#34;&gt;Float&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;f := 3.14&lt;/code&gt; - always initialises to &lt;code&gt;float64&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;string&#34;&gt;String&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;collection of UTF-8 characters&lt;/li&gt;
&lt;li&gt;Immutable&lt;/li&gt;
&lt;li&gt;can be converted back and forth with &lt;code&gt;[]byte&lt;/code&gt; array&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;constants&#34;&gt;Constants&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;const&lt;/code&gt; keyword&lt;/li&gt;
&lt;li&gt;naming is the same as variables&lt;/li&gt;
&lt;li&gt;they need to be set up at compile time, you can assign the result of a function call to constant
&lt;ul&gt;
&lt;li&gt;const gets replaced with literal everywhere&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;iota&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;scoped to a constant block&lt;/li&gt;
&lt;li&gt;every time we use it it&amp;rsquo;s like using &lt;code&gt;i++&lt;/code&gt; starting with &lt;code&gt;0&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;const&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	a = &lt;span style=&#34;color:#00f&#34;&gt;iota&lt;/span&gt; &lt;span style=&#34;color:#008000&#34;&gt;// will be 0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;    b &lt;span style=&#34;color:#008000&#34;&gt;// 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;    c &lt;span style=&#34;color:#008000&#34;&gt;// 2
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;be careful, zero value is &lt;code&gt;0&lt;/code&gt; so uninitialised variable is going to be equal to the first constant
&lt;ul&gt;
&lt;li&gt;solution &lt;code&gt;_ = iota&lt;/code&gt; or &lt;code&gt;errorState = iota&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;iota&lt;/code&gt; should be used only for constants where the numerical representation doesn&amp;rsquo;t matter and is not stored
&lt;ul&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;Don’t use iota for defining constants where its values are explicitly
defined (elsewhere). For example, when implementing parts of a
specification and the specification says which values are assigned to
which constants, you should explicitly write the constant values. Use
iota for “internal” purposes only. That is, where the constants are
referred to by name rather than by value. That way you can optimally
enjoy iota by inserting new constants at any moment in time / location
in the list without the risk of breaking everything.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://oreil.ly/3MKwn&#34;&gt;Danny van Heumen&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;arrays&#34;&gt;Arrays&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;a := [3]int{97, 85, 93}&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;shorthand &lt;code&gt;a := [...]int{97, 85, 93}&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;len(a)&lt;/code&gt; to find out the length&lt;/li&gt;
&lt;li&gt;arrays are values
&lt;ul&gt;
&lt;li&gt;copied during re-assignment&lt;/li&gt;
&lt;li&gt;passed as values to functions&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;slices&#34;&gt;Slices&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;a := []int{97, 85, 93}&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;same initialisation as an array, but without specifying the length&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Slicing operations
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;a := [...]&lt;span style=&#34;color:#2b91af&#34;&gt;int&lt;/span&gt;{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;b := a[:] &lt;span style=&#34;color:#008000&#34;&gt;// slice of all elements
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;c := a[3:] &lt;span style=&#34;color:#008000&#34;&gt;// slice from 4th element (index 3 inclusive)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;d := a[:6] &lt;span style=&#34;color:#008000&#34;&gt;// slice first 6 elements (index 6 exclusive)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;e := a[3:6] &lt;span style=&#34;color:#008000&#34;&gt;// slice the 4th, 5th, and 6th elements
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;remove first element &lt;code&gt;a[1:]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;remove last element &lt;code&gt;a[:len(a)-1]&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;make([]int, len, cap)&lt;/code&gt; - initialise slice with &lt;code&gt;len&lt;/code&gt; length and &lt;code&gt;cap&lt;/code&gt; capacity&lt;/li&gt;
&lt;li&gt;&lt;code&gt;append(arr, el, el1, el2)&lt;/code&gt; appends element to the slice, it makes the underlying array larger if needs be
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;append&lt;/code&gt; can use &amp;ldquo;spread&amp;rdquo; operator to append another array: &lt;code&gt;a = append(a, []int{1,2,3,4}...)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;all stack operations are manipulating one underlying array&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;maps&#34;&gt;Maps&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;m := map[string]int{&amp;quot;a&amp;quot;: 1, &amp;quot;b&amp;quot;: 2}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;key type has to be testable for equality, &lt;strong&gt;struct, map and function can&amp;rsquo;t be a key&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;val := myMap[&amp;quot;key&amp;quot;]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;val, ok := myMap[&amp;quot;key&amp;quot;]&lt;/code&gt; - we can check if the key exists, &lt;code&gt;ok&lt;/code&gt; is convention&lt;/li&gt;
&lt;li&gt;you can use &lt;code&gt;len()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;delete(myMap, &amp;quot;key&amp;quot;)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;structs&#34;&gt;Structs&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;type&lt;/span&gt; Doctor &lt;span style=&#34;color:#00f&#34;&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  number &lt;span style=&#34;color:#2b91af&#34;&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  actorName &lt;span style=&#34;color:#2b91af&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  companions []&lt;span style=&#34;color:#2b91af&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;d := Doctor{
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  number: 3,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  actorName: &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;John Doe&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  companions: []&lt;span style=&#34;color:#2b91af&#34;&gt;string&lt;/span&gt;{&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;b&amp;#34;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;//or positional syntax (not recommended)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;&lt;/span&gt;d = Doctor{3, &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;John Doe&amp;#34;&lt;/span&gt;, []&lt;span style=&#34;color:#2b91af&#34;&gt;string&lt;/span&gt;{&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;a&amp;#34;&lt;/span&gt;, &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;b&amp;#34;&lt;/span&gt;}}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;Anonymous struct: &lt;code&gt;a := struct{name: string}{name: &amp;quot;Tomas&amp;quot;}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Structs are passed by value&lt;/li&gt;
&lt;li&gt;Embedding &lt;code&gt;type Bird struct {Animal, canFly: bool}&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;I need to be aware of the embedding when creating an instance: &lt;code&gt;bird := Bird{Animal: Animal{}, canFly: true}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Embedding is a good idea when we want consumers of our libraries to embed a complicated structure rather than extend an interface.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Tags
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;type&lt;/span&gt; Animal &lt;span style=&#34;color:#00f&#34;&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Name &lt;span style=&#34;color:#2b91af&#34;&gt;string&lt;/span&gt; &lt;span style=&#34;color:#a31515&#34;&gt;`required max:&amp;#34;100&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Origin &lt;span style=&#34;color:#2b91af&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;t := reflect.TypeOf(Animal{})
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;field, _ := t.FieldByName(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;Name&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;field.Tag
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;blockquote&gt;
&lt;p&gt;When not working with JSON (or other external protocols), resist the
temptation to use a pointer field to indicate no value. While a pointer
does provide a handy way to indicate no value, if you are not going to
modify the value, you should use a value type instead, paired with a
boolean.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;ul&gt;
&lt;li&gt;John Bonder - Learning Go&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Internal implementation introduces another two terms: &lt;em&gt;Alignment&lt;/em&gt; and &lt;em&gt;Padding&lt;/em&gt;
&lt;ul&gt;
&lt;li&gt;alignment and padding dictate how is the struct stored in memory, depending on the size of the word. It is a mechanism to avoid storing a value over two words, which would mean doubling the memory access for working with that value&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;embedding&#34;&gt;Embedding&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;You can embed a struct in another struct, then you can access the child fields and methods through the parent:
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;type&lt;/span&gt; user &lt;span style=&#34;color:#00f&#34;&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  name &lt;span style=&#34;color:#2b91af&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  email &lt;span style=&#34;color:#2b91af&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;type&lt;/span&gt; admin &lt;span style=&#34;color:#00f&#34;&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  user
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  accesLevel &lt;span style=&#34;color:#2b91af&#34;&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;if-statement&#34;&gt;If statement&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Initializer:
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;if&lt;/span&gt; val, ok := myMap[&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;key&amp;#34;&lt;/span&gt;]; ok {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  fmt.Println(val)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;The variables are scoped to the &lt;code&gt;if&lt;/code&gt; block&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Short circuiting - when evaluating &lt;code&gt;||&lt;/code&gt; go stops evaluating after the first &lt;code&gt;true&lt;/code&gt;, &lt;code&gt;&amp;amp;&amp;amp;&lt;/code&gt; stops evaluating after the first &lt;code&gt;false&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;switch-statement&#34;&gt;Switch statement&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;switch&lt;/span&gt; &amp;lt;tag&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;case&lt;/span&gt; 1, 5, 10:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  fmt.Println(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;one, five, or ten&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;default&lt;/span&gt;: 
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  fmt.Println(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;not one&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;You can use initialiser as well&lt;/li&gt;
&lt;li&gt;No braces, any statements between the case and the next case are part of the block&lt;/li&gt;
&lt;li&gt;Tagless syntax:
&lt;ul&gt;
&lt;li&gt;each &lt;code&gt;case&lt;/code&gt; can have a full comparison &lt;code&gt;case i &amp;lt; 10:&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Implicit break between cases, you can force immediate execution of the next case (without checking the condition) by using the &lt;code&gt;fallthrough&lt;/code&gt; keyword&lt;/li&gt;
&lt;li&gt;Type switch: &lt;code&gt;switch i.(type) {}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Break early with &lt;code&gt;break&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;for-statement&#34;&gt;For statement&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;for i:=0;i&amp;lt;10;i++&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;for i, j := 0, 0; i&amp;lt;5; i, j =i+1, j+1&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;TODO &lt;code&gt;i++&lt;/code&gt; is a statement, not an expression - investigate more about this design choice&lt;/li&gt;
&lt;li&gt;we can omit the initialiser &lt;code&gt;for ; i&amp;lt;10;i++&lt;/code&gt; or even the continuation statement &lt;code&gt;for ;i&amp;lt;10;&lt;/code&gt; (which is effectively a while loop)
&lt;ul&gt;
&lt;li&gt;syntax sugar for while loop: &lt;code&gt;for i&amp;lt;10&lt;/code&gt; (omitting the semicolons)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;for { break }&lt;/code&gt; for when we don&amp;rsquo;t know when to finish&lt;/li&gt;
&lt;li&gt;&lt;code&gt;continue&lt;/code&gt; - skip this iteration and start over with the next loop iteration&lt;/li&gt;
&lt;li&gt;we can &lt;strong&gt;label&lt;/strong&gt; which statement we want to break out of
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Label:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;for&lt;/span&gt; i := 0;i&amp;lt;5;i++ {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#00f&#34;&gt;for&lt;/span&gt; j := 0;j&amp;lt;5;j++ {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;if&lt;/span&gt; i*j &amp;gt; 10 {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;      &lt;span style=&#34;color:#00f&#34;&gt;break&lt;/span&gt; Label
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    fmt.Println(i*j)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;range&lt;/strong&gt; : &lt;code&gt;for k,v := range s {}&lt;/code&gt; to loop over arrays, slices, and maps&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;defer&#34;&gt;Defer&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;defer&lt;/code&gt; moves statement after the function is done, but before it returns any results to the calling function&lt;/li&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;a := &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;start&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;defer&lt;/span&gt; fmt.Println(a)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;a = &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;end&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;Will print &amp;ldquo;start&amp;rdquo; because &lt;code&gt;defer&lt;/code&gt; evaluates the argument the moment it is called&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;panic&lt;/code&gt; happens after &lt;code&gt;defer&lt;/code&gt; statements have been executed&lt;/li&gt;
&lt;li&gt;we can pass anonymous function to the &lt;code&gt;defer&lt;/code&gt; statement&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;panicrecover&#34;&gt;Panic/Recover&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;panic(error)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;err := recover()&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;defer&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;func&lt;/span&gt;(){
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  err := recover()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  handleError()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;pointers&#34;&gt;Pointers&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;var a *int&lt;/code&gt; - declare pointer&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;amp;&lt;/code&gt; -  &amp;ldquo;address of&amp;rdquo; operator - &lt;code&gt;a := &amp;amp;b&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;*&lt;/code&gt; - &amp;ldquo;dereferencing&amp;rdquo; operator &lt;code&gt;a := *b&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;lower precedence than the &lt;code&gt;.&lt;/code&gt; operator =&amp;gt; &lt;code&gt;(*a).val&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;pointer arithmetic available in the &lt;code&gt;unsafe&lt;/code&gt; package&lt;/li&gt;
&lt;li&gt;&lt;code&gt;new(myStruct)&lt;/code&gt; - we get back a pointer to an empty struct&lt;/li&gt;
&lt;li&gt;compiler automatically dereferences before using the&lt;code&gt;.&lt;/code&gt; operator
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;(*a).val&lt;/code&gt; == &lt;code&gt;a.val&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;When function returns pointer to a local variable, the Go runtime has to copy the value on the heap&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;functions&#34;&gt;Functions&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;You can pass arguments by reference or by value&lt;/li&gt;
&lt;li&gt;maps and slices are always passed by reference&lt;/li&gt;
&lt;li&gt;&lt;code&gt;func sum(values ...int) int {}&lt;/code&gt; Variadic parameter
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;values&lt;/code&gt; is a slice&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;You can return local variable as a pointer&lt;/li&gt;
&lt;li&gt;&lt;code&gt;func sum(values ...int) (result int){}&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;named return variable &lt;code&gt;result&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;func divide(a float64, b float64) (float64, error)&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;we can return error object as the second parameter&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;anonymous-functions&#34;&gt;Anonymous functions&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;best practice is to pass in the variable from outer scope as arguments
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;func&lt;/span&gt;(a){
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  fmt.Println(a)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;var divide func(float64, float64)(float64, error)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;methods&#34;&gt;Methods&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;functions that are executed on a know context (structs, primitive types)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;func (g greeter) greet() {}&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;g greeter&lt;/code&gt; is a value receiver
&lt;ul&gt;
&lt;li&gt;Use value receiver if all methods can use value receivers - that means they don&amp;rsquo;t need to mutate data and don&amp;rsquo;t work with synchronisation primitives&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;g *greeter&lt;/code&gt; is a pointer receiver
&lt;ul&gt;
&lt;li&gt;Use pointer receiver if even a single method needs to use pointer receiver&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Mixing the two is bad, because the type dictates whether it&amp;rsquo;s a value or a reference (user is a reference, time is a value) then you should respect the type and use its semantics even if you would otherwise use the other option&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;interface&#34;&gt;Interface&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Interface should represent &lt;strong&gt;behaviour&lt;/strong&gt;, &lt;del&gt;&lt;code&gt;Animal&lt;/code&gt;&lt;/del&gt; -&amp;gt; &lt;code&gt;Barker&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Interface value is internally represented as a &lt;a href=&#34;https://www.tapirgames.com/blog/golang-interface-implementation&#34;&gt;pair of pointers&lt;/a&gt;:
&lt;ul&gt;
&lt;li&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/image_1661196193865_0.png&#34;
    alt=&#34;image.png&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.timr.co/go-interfaces-the-tricky-parts/&#34;&gt;Go interfaces, the tricky parts&lt;/a&gt; from Tim Ruffles explains it really well&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;type&lt;/span&gt; Writer &lt;span style=&#34;color:#00f&#34;&gt;interface&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Write([]&lt;span style=&#34;color:#2b91af&#34;&gt;byte&lt;/span&gt;) (&lt;span style=&#34;color:#2b91af&#34;&gt;int&lt;/span&gt;, &lt;span style=&#34;color:#2b91af&#34;&gt;error&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;Naming convention is that if there&amp;rsquo;s only one method, we name the interface with the name of the method + &lt;code&gt;er&lt;/code&gt; e.g. &lt;code&gt;Write&lt;/code&gt; =&amp;gt; &lt;code&gt;Writer&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;When I want to add methods to a type, I have to have a control over it in my package. &lt;code&gt;type Counter int&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Composing same as struct embedding
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;type&lt;/span&gt; WriterCloser &lt;span style=&#34;color:#00f&#34;&gt;interface&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Writer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  Closer
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;t, ok := val.(TypeToConvertTo)&lt;/code&gt; - type conversion for interfaces&lt;/li&gt;
&lt;li&gt;&lt;code&gt;interface{}&lt;/code&gt; - empty interface&lt;/li&gt;
&lt;li&gt;Receiver trickery:
&lt;ul&gt;
&lt;li&gt;if the interface is stored as &lt;strong&gt;pointer&lt;/strong&gt;, it can &lt;strong&gt;use both value and pointer receivers&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;if the interface is stored as a &lt;strong&gt;value&lt;/strong&gt;, it can &lt;strong&gt;only use value receivers&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;printing&#34;&gt;Printing&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;%v&lt;/code&gt; - default printer for the value&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%+v&lt;/code&gt; - prints keys as well&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%#v&lt;/code&gt; - prints the full go syntax (invokes the &lt;code&gt;go.Stringer&lt;/code&gt; interface if the value implements it)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;%[1]v&lt;/code&gt;  - refers to the first argument (1 indexed)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;errors&#34;&gt;Errors&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Internally, error is implemented with &lt;code&gt;errorString&lt;/code&gt; in the &lt;code&gt;errors&lt;/code&gt; package&lt;/li&gt;
&lt;li&gt;&lt;code&gt;fmt.Errorf(&amp;quot;Error happened %w&amp;quot;)&lt;/code&gt; - &lt;code&gt;%w&lt;/code&gt; format verb wraps the error so it can be later unwrapped:&lt;/li&gt;
&lt;li&gt;When you handle multiple errors with the same treatment (e.g. prepending the same message) you can use &lt;code&gt;defer&lt;/code&gt; with named return value:
&lt;ul&gt;
&lt;li&gt;Before:
collapsed:: true
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;func&lt;/span&gt; DoSomeThings(val1 &lt;span style=&#34;color:#2b91af&#34;&gt;int&lt;/span&gt;, val2 &lt;span style=&#34;color:#2b91af&#34;&gt;string&lt;/span&gt;) (&lt;span style=&#34;color:#2b91af&#34;&gt;string&lt;/span&gt;, &lt;span style=&#34;color:#2b91af&#34;&gt;error&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    val3, err := doThing1(val1)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;if&lt;/span&gt; err != &lt;span style=&#34;color:#00f&#34;&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#00f&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;, fmt.Errorf(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;in DoSomeThings: %w&amp;#34;&lt;/span&gt;, err)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    val4, err := doThing2(val2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;if&lt;/span&gt; err != &lt;span style=&#34;color:#00f&#34;&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#00f&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;, fmt.Errorf(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;in DoSomeThings: %w&amp;#34;&lt;/span&gt;, err)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    result, err := doThing3(val3, val4)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;if&lt;/span&gt; err != &lt;span style=&#34;color:#00f&#34;&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#00f&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;, fmt.Errorf(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;in DoSomeThings: %w&amp;#34;&lt;/span&gt;, err)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;return&lt;/span&gt; result, &lt;span style=&#34;color:#00f&#34;&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;After:
collapsed:: true
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;func&lt;/span&gt; DoSomeThings(val1 &lt;span style=&#34;color:#2b91af&#34;&gt;int&lt;/span&gt;, val2 &lt;span style=&#34;color:#2b91af&#34;&gt;string&lt;/span&gt;) (_ &lt;span style=&#34;color:#2b91af&#34;&gt;string&lt;/span&gt;, err &lt;span style=&#34;color:#2b91af&#34;&gt;error&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;defer&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;func&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#00f&#34;&gt;if&lt;/span&gt; err != &lt;span style=&#34;color:#00f&#34;&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;            err = fmt.Errorf(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;in DoSomeThings: %w&amp;#34;&lt;/span&gt;, err)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }()
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    val3, err := doThing1(val1)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;if&lt;/span&gt; err != &lt;span style=&#34;color:#00f&#34;&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#00f&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;, err
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    val4, err := doThing2(val2)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;if&lt;/span&gt; err != &lt;span style=&#34;color:#00f&#34;&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;        &lt;span style=&#34;color:#00f&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;&amp;#34;&lt;/span&gt;, err
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    }
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    &lt;span style=&#34;color:#00f&#34;&gt;return&lt;/span&gt; doThing3(val3, val4)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;`&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;error-values&#34;&gt;Error values&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;You can define a &amp;ldquo;sentinel&amp;rdquo; error as &lt;code&gt;var ErrBadRequest := errors.New(&amp;quot;Bad Request&amp;quot;)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;This is useful if there is no need for additional context&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;using-type-to-provide-more-context&#34;&gt;Using type to provide more context&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/ardanlabs/gotraining/blob/master/topics/go/design/error_handling/README.md&#34;&gt;course material&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Type assertion switch:
&lt;ul&gt;
&lt;li&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;if err != nil {
  switch e := err.(type) {
  case *UnmarshalTypeError:
    fmt.Printf(&amp;#34;UnmarshalTypeError: Value[%s] Type[%v]\n&amp;#34;, e.Value, e.Type)
  case *InvalidUnmarshalError:
    fmt.Printf(&amp;#34;InvalidUnmarshalError: Type[%v]\n&amp;#34;, e.Type)
  default:
    fmt.Println(err)
}
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;performance&#34;&gt;Performance&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;h3 id=&#34;garbage-collection&#34;&gt;Garbage collection&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;TODO &lt;a href=&#34;https://www.forrestthewoods.com/blog/memory-bandwidth-napkin-math/&#34;&gt;Memory Bandwidth Napkin Math&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://go.dev/blog/ismmkeynote&#34;&gt;Getting to Go: The Journey of Go&amp;rsquo;s Garbage Collector - The Go Programming Language&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.ardanlabs.com/blog/2017/05/language-mechanics-on-stacks-and-pointers.html&#34;&gt;Language Mechanics On Stacks And Pointers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://segment.com/blog/allocation-efficiency-in-high-performance-go-services/&#34;&gt;Allocation efficiency in high-performance Go services | Twilio Segment Blog&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;performance-drains&#34;&gt;Performance drains&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Performance is most affected by these categories (in order)
&lt;ul&gt;
&lt;li&gt;Latency - IO Latency - network, disc, memory access&lt;/li&gt;
&lt;li&gt;Memory allocations (see garbage collection above)&lt;/li&gt;
&lt;li&gt;data access&lt;/li&gt;
&lt;li&gt;algorithm efficiencies&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;profiling&#34;&gt;Profiling&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;add this snippet to your main
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-go&#34; data-lang=&#34;go&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    f, err := os.Create(&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;cpuprofile&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#00f&#34;&gt;if&lt;/span&gt; err != &lt;span style=&#34;color:#00f&#34;&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		fmt.Fprintf(os.Stderr, &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;could not create CPU profile: %v\n&amp;#34;&lt;/span&gt;, err)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		os.Exit(1)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#00f&#34;&gt;if&lt;/span&gt; err := pprof.StartCPUProfile(f); err != &lt;span style=&#34;color:#00f&#34;&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		fmt.Fprintf(os.Stderr, &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;could not start CPU profile: %v\n&amp;#34;&lt;/span&gt;, err)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;		os.Exit(1)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;	&lt;span style=&#34;color:#00f&#34;&gt;defer&lt;/span&gt; pprof.StopCPUProfile()
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Then inspect the result with
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;go tool pprof -http=:7777 cpuprofile
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;design-values&#34;&gt;Design values&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Write less code, for every 20 lines of code you&amp;rsquo;ll introduce one bug&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;examples-of-hiding-complexity&#34;&gt;Examples of hiding complexity&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=rFejpH_tAHM&#34;&gt;dotGo 2015 - Rob Pike - Simplicity is Complicated - YouTube&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Garbage collection - not even included in the spec&lt;/li&gt;
&lt;li&gt;Import statement - simple string hides a large complexity&lt;/li&gt;
&lt;li&gt;&lt;code&gt;go&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;const&lt;/code&gt; - the typing of &lt;code&gt;const&lt;/code&gt; numbers into arbitrary precision variables&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;goconcurrency&#34;&gt;[[Go/Concurrency]]&lt;/h2&gt;
&lt;h2 id=&#34;resources&#34;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.habets.se/2025/07/Go-is-still-not-good.html&#34;&gt;Go is still not good&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Blake Crouch - Dark Matter</title>
      <link>https://blog.viktomas.com/books/crouch-blake--dark-matter/</link>
      <pubDate>Thu, 04 Aug 2022 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/crouch-blake--dark-matter/</guid>
      <description>&lt;p&gt;I found this book on a random book recommendation list on the internet: &lt;a href=&#34;https://www.goodreads.com/list/show/168038.Sci_fi_Recommendations_&#34;&gt;Cora&amp;rsquo;s Goodreads Sci-Fi list&lt;/a&gt;. This list contains several books I read and liked.&lt;/p&gt;
&lt;p&gt;I read &lt;a href=&#34;https://blog.viktomas.com/books/crouch-blake--recursion&#34;&gt;Recursion&lt;/a&gt; from Crouch last year and this book has got a similar feel to it. These books reuse several ideas, and the novels&amp;rsquo; style (false memory) is identical at the start. If you want to pick up only one of these books, I recommend this one (Dark Matter).&lt;/p&gt;
&lt;p&gt;Also, this book is much more thrilling than what I&amp;rsquo;m used to in other Sci-Fi novels. I had to put it down (stop listening) several times because the story got too intense.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m happy I listen to this book, but I will take a break from Blake Crouch for a while. I wouldn&amp;rsquo;t be surprised if his new novel &lt;a href=&#34;https://www.goodreads.com/book/show/59838811-upgrade&#34;&gt;Upgrade&lt;/a&gt; had the same style and feel.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Go/Code Review</title>
      <link>https://blog.viktomas.com/graph/go___code-review/</link>
      <pubDate>Thu, 28 Jul 2022 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/go___code-review/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://github.com/golang/go/wiki/CodeReviewComments&#34;&gt;CodeReviewComments · golang/go Wiki&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://docs.gitlab.com/ee/development/go_guide/&#34;&gt;Go standards and style guidelines | GitLab&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Security: Remember to run &lt;a href=&#34;https://docs.gitlab.com/ee/user/application_security/sast/index.html&#34;&gt;SAST&lt;/a&gt; and &lt;a href=&#34;https://docs.gitlab.com/ee/user/application_security/dependency_scanning/index.html&#34;&gt;Dependency Scanning&lt;/a&gt; on your project (or at least the &lt;a href=&#34;https://gitlab.com/gitlab-org/security-products/analyzers/gosec&#34;&gt; &lt;code&gt;gosec&lt;/code&gt;  analyzer&lt;/a&gt;),
and to follow our &lt;a href=&#34;https://docs.gitlab.com/ee/development/code_review.html#security&#34;&gt;Security requirements&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Run the &lt;a href=&#34;https://pkg.go.dev/golang.org/x/tools/cmd/goimports&#34;&gt;goimports command&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t accept maps as input or return maps as a part of your Public API (Joe Bonder, Learning Go, Pointers)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You don&amp;rsquo;t know what the keys are and you have to check the code&lt;/li&gt;
&lt;li&gt;Maps are mutable and you can&amp;rsquo;t make them immutable&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Don&amp;rsquo;t mutate slices that were passed to a function or document that behaviour (Joe Bonder, Learning Go, Pointers)&lt;/p&gt;
&lt;p&gt;Are tests run with &lt;code&gt;-race&lt;/code&gt; for race detection?&lt;/p&gt;
&lt;p&gt;When you see a buffered channel, what is the reason for the particular size of the buffer?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;what happens when the sending goroutine blocks?&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;resources&#34;&gt;Resources&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;[[Code Review Antipatterns]] - funny article about how to make other’s life real hard with bad reviews&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Shane Parrish - The Great Mental Models: General Thinking Concepts</title>
      <link>https://blog.viktomas.com/books/parrish-shane--the-great-mental-models/</link>
      <pubDate>Wed, 13 Jul 2022 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/parrish-shane--the-great-mental-models/</guid>
      <description>&lt;p&gt;The promise of this book sounds great. Read these 216 pages, and your thinking will get more efficient. Don&amp;rsquo;t expect that.&lt;/p&gt;
&lt;p&gt;The Great Mental Models have one thing going for them: the table of contents. Shane did a good job of curating the tools for better thinking but not describing them. The book itself was, surprisingly for me, worse than reading the articles on the topic on fs.blog.&lt;/p&gt;
&lt;p&gt;The book is too abstract and contains little practical advice. For almost every concept, I had to go on the internet and find examples and explanations from others.&lt;/p&gt;
&lt;p&gt;These are the valuable concepts that ended up in my permanent notes. You can do your own research.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://fs.blog/map-and-territory/&#34;&gt;Map is not a territory&lt;/a&gt; - Our understanding of the world is only an approximation. We should keep that in mind when making decisions.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://fs.blog/first-principles/&#34;&gt;First principles thinking&lt;/a&gt; - Try to decompose our reasoning for decisions into the smallest parts, then investigate each part separately.
&lt;ul&gt;
&lt;li&gt;Shane suggested 5 Whys method without giving any good examples. This method is originally meant for finding defects in a system, and it&amp;rsquo;s not obvious how it relates to the First principles thinking. This chapter was the least useful even though the model is interesting.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://fs.blog/probabilistic-thinking/&#34;&gt;Probabilistic thinking&lt;/a&gt; - A brief explanation of Byes Theorem and base rate neglect + fat tail curve (also called Power law randomness by Nassim Taleb).&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://fs.blog/occams-razor/&#34;&gt;Occam&amp;rsquo;s razor&lt;/a&gt; - If your map (understanding of the world) is too complex, look for a simpler explanation, this works for aliens, conspiracies, and even reading too much into your friend forgetting about your coffee catchup
&lt;ul&gt;
&lt;li&gt;This was personally the most useful model and the only one I understood from this book without further research.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://fs.blog/mental-model-hanlons-razor/&#34;&gt;Hanlon&amp;rsquo;s razor&lt;/a&gt; - When people do something bad, always assume negligence and incompetence before malice.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Read these five blog articles, do more of your own research on the internet and save yourself reading this book.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Marc-Uwe Kling - Qualityland</title>
      <link>https://blog.viktomas.com/books/kling-marc-uwe--qualityland/</link>
      <pubDate>Wed, 06 Jul 2022 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/kling-marc-uwe--qualityland/</guid>
      <description>&lt;p&gt;This is a fun little novel about the near future where marketing rules the world. It is a parody on today&amp;rsquo;s attention economics and big corporations dictating the rules.&lt;/p&gt;
&lt;p&gt;The main character is a bum by the standards of Qualityland, he doesn&amp;rsquo;t have a good job or a girlfriend, but he has a secret in his basement.&lt;/p&gt;
&lt;p&gt;At times it was too weird or too whacky. The ending is anticlimactic; it seems like the author ran out of time and needed to finish the book quickly.&lt;/p&gt;
&lt;p&gt;That being said, it&amp;rsquo;s a good comedy book, and I laughed out loud while listening to it.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Developer Journal</title>
      <link>https://blog.viktomas.com/graph/developer-journal/</link>
      <pubDate>Fri, 17 Jun 2022 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/developer-journal/</guid>
      <description>&lt;p&gt;The developer journal is a section of my knowledge graph where I try to capture learnings during my day-to-day work.&lt;/p&gt;
&lt;h2 id=&#34;sections&#34;&gt;Sections&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;h3 id=&#34;pros--cons-of-x&#34;&gt;Pros &amp;amp; Cons of X&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;TODO [[GraphQL vs gRPC]]&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;screw-up-story&#34;&gt;Screw-up story&lt;/h3&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;everything-you-need-to-know-about-x&#34;&gt;Everything you need to know about X&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/bash-shell&#34;&gt;Bash shell&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/git&#34;&gt;Git&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/go&#34;&gt;Go&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;join-me-as-i-poke-around-x-and-understand-how-it-works&#34;&gt;Join me as I poke around X and understand how it works&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;[[Linux boot process]]&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/fish-shell-has-different-path-than-neovim&#34;&gt;Fish shell has different PATH than neovim&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;[[Podman networking with tailscale tunnel]]&lt;/li&gt;
&lt;li&gt;[[ANSI escape sequences]]&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/new-lines-and-terminals-cr-vs-lf&#34;&gt;New lines and terminals - CR vs. LF&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;workflows--best-practices-checklists&#34;&gt;Workflows &amp;amp; best practices checklists&lt;/h3&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;annotated-code-walkthroughs&#34;&gt;Annotated code walkthroughs&lt;/h3&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;tips--tricks&#34;&gt;Tips &amp;amp; Tricks&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/image-resizing&#34;&gt;Image resizing&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/automation&#34;&gt;Automation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Find out what runs on a port on osx: &lt;code&gt;sudo lsof -i -P | grep LISTEN | grep :8080&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;candidates-for-join-me-as-i-poke-around-x-and-understand-how-it-works&#34;&gt;Candidates for &amp;ldquo;Join me as I poke around X and understand how it works&amp;rdquo;&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;SVG
&lt;ul&gt;
&lt;li&gt;For example, this SVG
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;svg xmlns=&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;http://www.w3.org/2000/svg&amp;#34;&lt;/span&gt; x=&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;0px&amp;#34;&lt;/span&gt; y=&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;0px&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;width=&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;32&amp;#34;&lt;/span&gt; height=&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;32&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;viewBox=&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;0 0 32 32&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;style=&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34; fill:#undefined;&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;path d=&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;M 5 5 L 5 9 C 14.93 9 23 17.07 23 27 L 27 27 C 27 14.85 17.15 5 5 5 z M 5 12 L 5 16 C 11.07 16 16 20.93 16 27 L 20 27 C 20 18.72 13.28 12 5 12 z M 8 21 A 3 3 0 0 0 8 27 A 3 3 0 0 0 8 21 z&amp;#34;&lt;/span&gt;&amp;gt;&amp;lt;/path&amp;gt;&amp;lt;/svg&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;has got a viewbox and width and height, how can I resize/alter the view window of the svg to make it fit the website&lt;/li&gt;
&lt;li&gt;also, how can I make images scale up and down while keeping aspect ratio&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;credit&#34;&gt;Credit&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Code diary is a concept that I&amp;rsquo;ve seen mentioned multiple times on HN and also in the [[David Thomas, Andrew Hunt - The Pragmatic Programmer]]&lt;/li&gt;
&lt;li&gt;I&amp;rsquo;ve seen a YouTube video from Semicolon&amp;amp;Sons
&lt;ul&gt;
&lt;li&gt;{{video &lt;a href=&#34;https://www.youtube.com/watch?v=tarmCEHfGa0%7D%7D&#34;&gt;https://www.youtube.com/watch?v=tarmCEHfGa0}}&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;In this video Jack Kinsella describes how he moved the more complex learnings from his software engineering from #spaced-repetition to code diary.&lt;/li&gt;
&lt;li&gt;His diary so far contains the following categories:
&lt;ul&gt;
&lt;li&gt;Pros &amp;amp; Cons of X - here he describes tradeoffs connected with a technology/design pattern&lt;/li&gt;
&lt;li&gt;Screw-up story - learnings from mistakes&lt;/li&gt;
&lt;li&gt;Everything you need to know about X - Overview of API/Technology e.g. &lt;em&gt;Docker basics&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Join me as I poke around X and understand how it works - noticing a phenomena and then going one level deeper and understanding why does it happen, e.g. Why colors disappear when we pipe output to another command?&lt;/li&gt;
&lt;li&gt;Workflows &amp;amp; best practices checklist that I prepared for myself&lt;/li&gt;
&lt;li&gt;Annotated code walkthroughs - e.g. finding a nice &lt;code&gt;Makefile&lt;/code&gt; and finding out what id does and leaving a lots of comments&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Improve your Logseq notes with MermaidJS diagrams</title>
      <link>https://blog.viktomas.com/posts/mermaidjs-diagrams-in-logseq/</link>
      <pubDate>Thu, 26 May 2022 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/mermaidjs-diagrams-in-logseq/</guid>
      <description>&lt;p&gt;One picture is worth a thousand words. Especially when you want to capture complex relationships between concepts or systems. That&amp;rsquo;s why I love using &lt;a href=&#34;https://mermaid-js.github.io/mermaid/#/&#34;&gt;MermaidJS&lt;/a&gt; for drawing diagrams.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 600px&#34; src=&#34;https://blog.viktomas.com/images/posts/mermaidjs-diagrams-in-logseq.jpg&#34; alt=&#34;Apples to Bananas&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Apples to Bananas&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The new Logseq extension &amp;ldquo;Fenced Code plus&amp;rdquo; now renders Mermaid diagrams, so it&amp;rsquo;s a good time for me to show you how to use MermaidJS with Logseq so you can quickly create diagrams only using your keyboard.&lt;/p&gt;
&lt;p&gt;If you haven&amp;rsquo;t used Logseq before, it&amp;rsquo;s the best notetaking app I&amp;rsquo;ve ever used. You can check my &lt;a href=&#34;https://blog.viktomas.com/posts/slip-box-after-a-year/&#34;&gt;Zettelkasten note-taking after one year&lt;/a&gt; post, where I explain why I like it so much. Or you can go directly to the &lt;a href=&#34;https://logseq.com/&#34;&gt;Logseq website&lt;/a&gt; and try the Live Demo.&lt;/p&gt;
&lt;p&gt;So, you are sold, and you&amp;rsquo;ve installed Logseq? Let&amp;rsquo;s create some diagrams! First, install the &lt;a href=&#34;https://github.com/xyhp915/logseq-fenced-code-plus&#34;&gt;Fenced Code Plus&lt;/a&gt; plugin by opening Logseq and clicking the three little dots in the top-right corner and selecting &amp;ldquo;Plugins&amp;rdquo;. Then search for &amp;ldquo;Fenced Code Plus&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Now we are ready to start with some diagrams. Type the following code in your Logseq:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-md&#34; data-lang=&#34;md&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;```mermaid
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;&lt;/span&gt;graph LR
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;Apples --&amp;gt; Bannana
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;```&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And you&amp;rsquo;ll see:&lt;/p&gt;

&lt;div class=&#34;mermaid&#34; align=&#34;center&#34;&gt;graph LR
Apples --&gt; Banana&lt;/div&gt;
&lt;p&gt;Pretty neat, isn&amp;rsquo;t it? Let&amp;rsquo;s go through the elements of the code snippet:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;mermaid&lt;/code&gt; - this will mark the code block as MermaidJS chart so the Fenced Code Plus plugin can render it&lt;/li&gt;
&lt;li&gt;&lt;code&gt;graph LR&lt;/code&gt; - this tells Mermaid to render the most common type of diagram, &lt;a href=&#34;https://mermaid-js.github.io/mermaid/#/flowchart&#34;&gt;Flowchart&lt;/a&gt;. Flowcharts are the best for quickly capturing relationships between concepts. The &lt;code&gt;LR&lt;/code&gt; stands for left-to-right (the direction of the diagram).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Apples --&amp;gt; Banana&lt;/code&gt; - We&amp;rsquo;ll draw two boxes (called nodes) and an arrow between them&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You can see that with four lines of code, we could draw a simple diagram. With a little bit of practice, it will be easier for you to &amp;ldquo;code&amp;rdquo; a diagram rather than use &lt;a href=&#34;https://excalidraw.com/&#34;&gt;Excalidraw&lt;/a&gt;&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; or diagrams.net.&lt;/p&gt;
&lt;h3 id=&#34;more-advanced-flowchart&#34;&gt;More advanced Flowchart&lt;/h3&gt;
&lt;p&gt;The Flowchart is the most intuitive and common MermaidJS chart, and I will explain a few more concepts to help you create better charts.&lt;/p&gt;
&lt;p&gt;Paste the following snippet to your Logseq:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-md&#34; data-lang=&#34;md&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;```mermaid
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;&lt;/span&gt;graph TB
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;subgraph Fruit
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;A[Green Apples] --&amp;#34;are more sour than&amp;#34;--&amp;gt; B[Bananas]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;end
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;B --&amp;#34;goes to&amp;#34;--&amp;gt; C(Banana milk shake)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;B --&amp;#34;goes to&amp;#34; --&amp;gt; D(Musli)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;D -.-&amp;gt; Sn1[Snack]
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;A -.-&amp;gt; Sn1
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;```&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;mermaid&#34; align=&#34;center&#34;&gt;graph TB
subgraph Fruit
A[Green Apples] --&#34;are more sour than&#34;--&gt; B[Bananas]
end
B --&#34;goes to&#34;--&gt; C(Banana milk shake)
B --&#34;goes to&#34; --&gt; D(Musli)
D -.-&gt; Sn[Snack]
A -.-&gt; Sn&lt;/div&gt;
&lt;p&gt;When you see the rendered chart, you can roughly understand what parts in the code snippet are responsible for certain nodes and arrows.&lt;/p&gt;
&lt;p&gt;This chart is a more advanced version of the previous one. These are the new elements we used:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;graph TB&lt;/code&gt; - we changed the direction of the chart to be &lt;code&gt;TB&lt;/code&gt; (top-to-bottom)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;A&lt;/code&gt;, &lt;code&gt;B&lt;/code&gt;, &lt;code&gt;C&lt;/code&gt;, &lt;code&gt;D&lt;/code&gt;, and &lt;code&gt;Sn1&lt;/code&gt; - These are node identifiers. We used multi-word labels for nodes, and so we had to introduce identifiers. Node identifier can be any sequence of alphanumerical characters (except for reserved words like &lt;code&gt;end&lt;/code&gt; and &lt;code&gt;graph&lt;/code&gt;)
&lt;ul&gt;
&lt;li&gt;The neat thing is that you add the label only once. When Mermaid sees &lt;code&gt;B[Bananas]&lt;/code&gt;, it remembers that B has sharp corners and text Banana, and you can refer to this node as &lt;code&gt;B&lt;/code&gt; in the rest of your code.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[]&lt;/code&gt; and &lt;code&gt;()&lt;/code&gt; - Using square and round brackets around labels will render sharp and rounded corners on the node.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;--&amp;quot;label&amp;quot;--&amp;gt;&lt;/code&gt; - We added a label to the arrows between nodes.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-.-&amp;gt;&lt;/code&gt; - We used dotted arrows.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;subgraph &amp;lt;name&amp;gt; ... end&lt;/code&gt; - We marked apples and bananas as fruit with a highlighting rectangle called &lt;code&gt;subgraph&lt;/code&gt;. All nodes whose names appear in the section between &lt;code&gt;subgraph&lt;/code&gt; and &lt;code&gt;end&lt;/code&gt; will be highlighted with a rectangle in the chart.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you are not sold on the idea of writing code to create charts, or you don&amp;rsquo;t want to install a plugin to your Logseq just yet, give Mermaid a go in their &lt;a href=&#34;https://mermaid-js.github.io/mermaid-live-editor/edit&#34;&gt;Live Editor&lt;/a&gt;, you can look at the &lt;a href=&#34;https://mermaid-js.github.io/mermaid/#/flowchart&#34;&gt;Mermaid documentation&lt;/a&gt; for reference.&lt;/p&gt;
&lt;p&gt;The Flowchart diagram I showed you is only one of ten available types of diagrams, but it is the one I used by far the most. If you learn the syntax I explained in this post, you&amp;rsquo;ll be able to explain complex relationships with MermaidJS graphs.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://excalidraw.com/&#34;&gt;Excalidraw&lt;/a&gt; is already part of Logseq, and you can add a drawing by typing in &lt;code&gt;/Draw&lt;/code&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Promises reduce your future choices</title>
      <link>https://blog.viktomas.com/posts/promises-reduce-choices/</link>
      <pubDate>Sun, 01 May 2022 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/promises-reduce-choices/</guid>
      <description>&lt;p&gt;It&amp;rsquo;s the end of a meeting. The whiteboard overflows with tasks. The facilitator looks into the room, asking, &amp;ldquo;Who will take on adding monitoring to our search?&amp;rdquo;. The awkward silence ensues.&lt;/p&gt;
&lt;p&gt;You know how to do it, and since none else raises their hand, you say, &amp;ldquo;I&amp;rsquo;ll do it&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;You just made a promise, and you just limited your future choices.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 600px&#34; src=&#34;https://blog.viktomas.com/images/posts/promises-reduce-choices.jpg&#34; alt=&#34;Say no&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Say no&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;When you promise to do something, you make the present more easy-going. You also set yourself up for working on a task that you would rather not do, maybe it is not enjoyable, or maybe there&amp;rsquo;s something more important to do.&lt;/p&gt;
&lt;p&gt;I love books from people from Basecamp, the company. The books are clear, simple and short. When I read &lt;a href=&#34;https://blog.viktomas.com/books/singer-ryan-shape-up/&#34;&gt;Shape up&lt;/a&gt;, and &lt;a href=&#34;https://blog.viktomas.com/books/fried-hansson-it-doesnt-have-to-be-crazy-at-work/&#34;&gt;It doesn&amp;rsquo;t have to be crazy at work&lt;/a&gt;, I found this interesting idea:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Our default response to any idea that comes up should be: &amp;ldquo;Interesting. Maybe some day.&amp;rdquo; In other words, a very soft &amp;ldquo;no&amp;rdquo; that leaves all our options open. We don&amp;rsquo;t put it in a backlog. We give it space so we can learn whether it&amp;rsquo;s really important and what it might entail.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s too early to say &amp;ldquo;yes&amp;rdquo; or &amp;ldquo;no&amp;rdquo; on first contact. Even if we&amp;rsquo;re excited about it, we shouldn&amp;rsquo;t make a commitment that we don&amp;rsquo;t yet understand. We need to do work on the idea before it&amp;rsquo;s shaped enough to bet resources on. If we always say &amp;ldquo;yes&amp;rdquo; to incoming requests we&amp;rsquo;ll end up with a giant pile of work that only grows.&lt;/p&gt;
&lt;p&gt;Source: &lt;a href=&#34;https://basecamp.com/shapeup/1.2-chapter-03#responding-to-raw-ideas&#34;&gt;Shape Up - Set Boundaries chapter&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;At Basecamp, they talk about promises in the context of project planning. They don&amp;rsquo;t promise their customers/colleagues to implement a feature because they would limit what they can work on next week, quarter, or year.&lt;/p&gt;
&lt;p&gt;This idea translates to everyday life as well.&lt;/p&gt;
&lt;p&gt;I am a people pleaser, and I often say I&amp;rsquo;ll do something to get out of an unpleasant conversation or to make others happy. And then I end up moving an acquaintance or writing extra documentation at a time when I&amp;rsquo;d rather work on my latest project or go for a run.&lt;/p&gt;
&lt;p&gt;I am not suggesting that you tell &amp;ldquo;no&amp;rdquo; to all your colleagues, friends, and family and go and binge-watch videos. But the fewer things you promise, the less tied are your hands in the future. And if you won&amp;rsquo;t find anything more important to do, you can still do the task you didn&amp;rsquo;t promise and pleasantly surprise the person.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Terry Pratchett - Making Money</title>
      <link>https://blog.viktomas.com/books/pratchett-terry--making-money/</link>
      <pubDate>Sun, 16 Jan 2022 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/pratchett-terry--making-money/</guid>
      <description>&lt;p&gt;If you&amp;rsquo;re considering reading this book, start with &lt;a href=&#34;https://blog.viktomas.com/books/pratchett-terry-going-postal/&#34;&gt;Going Postal&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Terry Pratchett came up with an ingenious way to lock Moist von Lipwig in another hilarious adventure. This time Lipwig has to use all his con-artist skills to convince people that you don&amp;rsquo;t need gold backing the Ankh-Morkorkian dollar.&lt;/p&gt;
&lt;p&gt;While Lipwig revives the banking industry, we enjoy several side stories. Lipwig&amp;rsquo;s fiance searches for golden golems. Banknote designer gets his personality fixed by Igor, and mad scientist designs a machine that accurately reflects the whole Discworld economics.&lt;/p&gt;
&lt;p&gt;This book was a fun read, and I fell in love with the main character already in &lt;a href=&#34;https://blog.viktomas.com/books/pratchett-terry-going-postal/&#34;&gt;Going Postal&lt;/a&gt;. However, compared to Going Postal, this book didn&amp;rsquo;t flow as easily. Usually, at the end of Pratchett&amp;rsquo;s book, all little story pieces fall in place like a large jigsaw puzzle, and this wasn&amp;rsquo;t the case with Making Money.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Terry Pratchett - Going Postal</title>
      <link>https://blog.viktomas.com/books/pratchett-terry--going-postal/</link>
      <pubDate>Wed, 12 Jan 2022 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/pratchett-terry--going-postal/</guid>
      <description>&lt;p&gt;Going Postal is the first part of a trilogy about a con artist Moist von Lipwig, the most likeable literary criminal.&lt;/p&gt;
&lt;p&gt;One day, the ruler of the largest city on Discworld decides that the local post office needs reviving and tasks mr. Lipwig with that task. From there, the book takes you on a rollercoaster ride, every page filled with unanticipated action, Pratchett&amp;rsquo;s humour, and crimes that somehow turn out to be moral.&lt;/p&gt;
&lt;p&gt;I read somewhere on the Internet that you should start the whole Discworld series with this novel because it best showcases Pratchett&amp;rsquo;s skill. They might be right. I recommend starting with either this book or Guards! Guards!&lt;/p&gt;
&lt;p&gt;When you finish reading this book, you can go ahead and pick up the next book in the series, &lt;a href=&#34;https://blog.viktomas.com/books/pratchett-terry-making-money/&#34;&gt;Making Money&lt;/a&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Philipp Dettmer - Immune</title>
      <link>https://blog.viktomas.com/books/philipp-dettmer--immune/</link>
      <pubDate>Tue, 21 Dec 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/philipp-dettmer--immune/</guid>
      <description>&lt;p&gt;Immune is a popular-science book explaining the human immune system. It presents a complex topic in layman&amp;rsquo;s language.&lt;/p&gt;
&lt;p&gt;Philipp Dettmer, the book&amp;rsquo;s author, is the creator of the educational YouTube channel &lt;a href=&#34;https://www.youtube.com/c/inanutshell&#34;&gt;Kurzgesagt - in a nutshell&lt;/a&gt;. I&amp;rsquo;ve been watching Kruzgesagt for many years, and I always appreciated their clear and objective messaging. A few months ago, the channel mentioned the book, and that was that.&lt;/p&gt;
&lt;p&gt;You don&amp;rsquo;t need to know anything about biology to read it. I haven&amp;rsquo;t studied biology past the primary-school introduction, and I could still understand the concepts. The fact that I could understand this book is a testimony to the clarity of the author&amp;rsquo;s explanation.&lt;/p&gt;
&lt;p&gt;When I need to explain a complex computer system to a colleague, I use a scenario that touches all the important parts of the system. For example, &amp;ldquo;Person searches on the page for properties for sale&amp;rdquo; or &amp;ldquo;Person wants to comment on a code review&amp;rdquo;. Using a scenario puts the important system&amp;rsquo;s components into perspective so my colleague can remember the walk-through better.&lt;/p&gt;
&lt;p&gt;Philipp chose the same approach with the immune system. He picked two infection scenarios that give the reader a holistic understanding of how our immune system works. These scenarios are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Stepping on a rusty nail (explains bacterial infection)&lt;/li&gt;
&lt;li&gt;Catching flu (explains viral infection)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The book wasn&amp;rsquo;t perfect, sometimes it dumbed down the explanation too much, and sometimes there were logical inconsistencies that made it impossible to grasp some details. But overall, I believe that reading this book is your best chance at getting a basic understanding of the immune system. The book is 370 pages, and you can read it as a novel, and you&amp;rsquo;ll rarely go back and re-read a paragraph or a page.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>My thoughts on investing: Index fund is all you need</title>
      <link>https://blog.viktomas.com/posts/investing-in-index-funds/</link>
      <pubDate>Sun, 21 Nov 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/investing-in-index-funds/</guid>
      <description>&lt;p&gt;I wish I thought about investing when I was younger. With a low-risk investment, you start to see your money compounding decades in the future. The sooner you start, the better. In this article, I&amp;rsquo;ll explain my thought process about investing and hopefully, I will help you think about money more efficiently.&lt;/p&gt;
&lt;p&gt;It all started when I had some extra savings. The interest on my savings account didn&amp;rsquo;t even cover half of the inflation. So I got motivated to learn how other people save and invest money.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 600px&#34; src=&#34;https://blog.viktomas.com/images/posts/investing-in-index-funds.jpg&#34; alt=&#34;Saving is done&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Saving is done&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;In the last two years I&amp;rsquo;ve read &lt;a href=&#34;https://blog.viktomas.com/books/malkiel-burton-random-walk-down-wallstreet/&#34;&gt;Random Walk down Wallstreet&lt;/a&gt;, &lt;a href=&#34;https://blog.viktomas.com/books/collins-jl-the-simple-path-to-wealth/&#34;&gt;Simple path to wealth&lt;/a&gt;, &lt;a href=&#34;https://blog.viktomas.com/books/jim-paul-what-i-learned-losing-a-million-dollars/&#34;&gt;What I Learned Losing a Million Dollars&lt;/a&gt;, &lt;a href=&#34;https://blog.viktomas.com/books/nassim-taleb-the-black-swan/&#34;&gt;Black swan&lt;/a&gt;, and many more articles. The more I read about how financial markets work, the more I felt like the Socrates of financial markets &amp;ldquo;I know that I know nothing&amp;rdquo;. Nobody knows what is going to happen, yet I&amp;rsquo;m supposed to invest my money. I&amp;rsquo;ll tell you what I learned.&lt;/p&gt;
&lt;p&gt;Before we start, here are two disclaimers:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;First, &lt;strong&gt;I take no responsibility for your actions.&lt;/strong&gt; If you invest your money, you are responsible for any gains or losses. I wish we lived in a world where this disclaimer wasn&amp;rsquo;t necessary.&lt;/li&gt;
&lt;li&gt;Second, I assume you don&amp;rsquo;t have any debt with an interest rate larger than 2% (mortgage is ok) and that you are saving money each month, ideally 20% to 50% of your income. If this is true, let&amp;rsquo;s continue; otherwise, you might want to reduce your expenses and pay off your debts first.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;motivation-1-not-investing--burning-money&#34;&gt;Motivation 1: not investing = burning money&lt;/h3&gt;
&lt;p&gt;Parting with your cash is not easy. Money on your account is safe, as safe as anything in the financial world could be, backed by the government (in EU up to 100,000 EUR). Taking this hard-earned cash and sending it to the risky stock market is daunting, and if you don&amp;rsquo;t think it through, you might lose the money very quickly. But having cash on a savings account is the same as burning a portion of your money. Here is an exercise that motivated me&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; to think about investing:&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s say that you are doing well and you&amp;rsquo;ve got $40,000 in your savings account. Interest on your account is 1% a year. Average index fund return is 7%&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;. This means you are missing out on 6% a year. If you invested in All-World index fund, you could be getting 7% instead of 1%. That&amp;rsquo;s extra $2,400 a year, $200 a month, $6.50 a day. Imagine every morning you take six bucks and flush them down the toilet. Over the long term, it gets even more significant thanks to compound interest. This calculation should motivate you to read up on investing.&lt;/p&gt;
&lt;h3 id=&#34;motivation-2-early-retirement&#34;&gt;Motivation 2: Early retirement&lt;/h3&gt;
&lt;p&gt;I took this tool from the book &lt;a href=&#34;https://blog.viktomas.com/books/collins-jl-the-simple-path-to-wealth/&#34;&gt;Simple path to wealth&lt;/a&gt;. JL Collins analysed past stock market performance&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; and he concluded that you can spend 4% of your portfolio each year, and the value of your portfolio shouldn&amp;rsquo;t decrease in the long-term. The portfolio should stay roughly the same, adjusted for inflation.&lt;/p&gt;
&lt;p&gt;So here&amp;rsquo;s the tool:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;For every $30,000 saved, you&amp;rsquo;ll get $100/month of retirement money.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The 4% is adjusted for inflation. You&amp;rsquo;ll take out $100 per month this year and $102 the next year if the inflation is 2%.&lt;/p&gt;
&lt;p&gt;If you are not living from your portfolio yet, this &amp;ldquo;retirement money&amp;rdquo; stays there and compounds.&lt;/p&gt;
&lt;h3 id=&#34;what-options-do-you-have&#34;&gt;What options do you have?&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;m only going to talk about passive investment. If you want to start a business, this is not the guide for you. For passive investment, your options are stock market, real estate, bonds, and &lt;a href=&#34;https://www.youtube.com/watch?v=Ntw7Dvctjb4&#34;&gt;crypto&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The interest you&amp;rsquo;ll get on bonds is low, but buying bonds might still make sense if you want to retire early. More on that later.&lt;/p&gt;
&lt;p&gt;That leaves real estate and the stock market.&lt;/p&gt;
&lt;p&gt;Real estate would require more paperwork, more taxes, maintenance, and maybe I&amp;rsquo;d have to deal with tenants as well. That doesn&amp;rsquo;t sound like a passive investment to me anymore.&lt;/p&gt;
&lt;p&gt;That leaves the stock market.&lt;/p&gt;
&lt;p&gt;What stock should you buy? When I read about picking individual stock (e.g. Tesla, Microsoft), between the authors that I trust there seems to be a consensus that amateurs can&amp;rsquo;t pick the winning stock and even fund managers probably can&amp;rsquo;t. An index fund then seemed like the best possible way to start investing.&lt;/p&gt;
&lt;h3 id=&#34;what-is-an-index&#34;&gt;What is an index?&lt;/h3&gt;
&lt;p&gt;An index is a weighted list of securities. For example, S&amp;amp;P 500 is a list of the 500 largest companies, and each company is represented in the index (has a weight) based on its market capitalisation. Market capitalisation is the number of shares times price per share and it is only one of many ways how to weigh the securities in the index.&lt;/p&gt;
&lt;p&gt;To get a better idea, check out this &lt;a href=&#34;https://www.slickcharts.com/sp500&#34;&gt;neat table&lt;/a&gt; that shows the individual weights of the S&amp;amp;P 500 index.&lt;/p&gt;
&lt;h3 id=&#34;what-is-an-index-fund&#34;&gt;What is an index fund?&lt;/h3&gt;
&lt;p&gt;An index fund is a pool of money invested into an index.&lt;/p&gt;
&lt;p&gt;Indexed funds are tracking an index. If the fund tracks S&amp;amp;P 500, then it should perform the same as the 500 largest US companies combined.&lt;/p&gt;
&lt;p&gt;The beauty of index funds is that they reduce the risk connected with an individual stock. For example, if Facebook gets regulated and loses half of its evaluation (fingers crossed), it won&amp;rsquo;t make a large dent in the indexed fund value because Facebook is only a small portion of the overall value (1.98% in S&amp;amp;P 500).&lt;/p&gt;
&lt;p&gt;That being said, an index fund won&amp;rsquo;t protect you from a stock market crash. If all stock loses value, your index fund does too.&lt;/p&gt;
&lt;p&gt;The simplicity of this solution is so enticing that when you visit a subreddit like &lt;a href=&#34;https://www.reddit.com/r/eupersonalfinance/&#34;&gt;r/eupersonalfinance&lt;/a&gt; you&amp;rsquo;ll see people&amp;rsquo;s portfolio strategy is often &amp;ldquo;100% VTI and chill&amp;rdquo;&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;You can invest in index funds either directly (using an investment company like Vanguard) or through Exchange Traded Funds (ETF) which work the same as buying an individual stock. Pick the option best for you based on your country and tax law.&lt;/p&gt;
&lt;h3 id=&#34;why-would-anyone-invest-in-individual-stock&#34;&gt;Why would anyone invest in individual stock?&lt;/h3&gt;
&lt;p&gt;For a human mind, it&amp;rsquo;s tough to have self-reflection to admit that it doesn&amp;rsquo;t know. It&amp;rsquo;s definitely the case with me.&lt;/p&gt;
&lt;p&gt;Many &amp;ldquo;features&amp;rdquo; of our brain make us think we can pick an individual stock. The important are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hindsight bias - When you look at the price history, and you think you could have anticipated it. &amp;ldquo;It&amp;rsquo;s obvious that Tesla was going to grow above $900. The climate change requires us to switch to EVs.&amp;rdquo;&lt;/li&gt;
&lt;li&gt;Illusory superiority - When you think you are better than average at most things you do. &amp;ldquo;Most individual investors lose money, but not you.&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The first individual stock I bought dropped 40% in value in the first month, and a year later, it hasn&amp;rsquo;t recovered. I didn&amp;rsquo;t sell the stock, and every time I look at my portfolio, I see it as a reminder not to bet on an individual stock.&lt;/p&gt;
&lt;p&gt;Nassim Taleb says that the Beginner&amp;rsquo;s luck for gamblers is a real thing&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;. If you weren&amp;rsquo;t lucky when you started betting, you didn&amp;rsquo;t become a gambler. I was lucky to lose on my first individual stock. I quickly found out how little I knew.&lt;/p&gt;
&lt;h3 id=&#34;the-one-big-assumption-stock-markets-are-going-up&#34;&gt;The one big assumption: Stock markets are going up&lt;/h3&gt;
&lt;p&gt;Investing in index funds&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt; is based on the assumption that stock markets are going up in the long term. By that, I mean that if you look at an index for a long enough time, it will increase in value.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.macrotrends.net/1319/dow-jones-100-year-historical-chart&#34;&gt;Historically, this is true&lt;/a&gt; even with the large economic crises of the past. But it is an assumption that is not guaranteed to be true in the future. On the other hand, I assume that if the stock market permanently crashes, I will have bigger problems than not having a good return on my investment.&lt;/p&gt;
&lt;h3 id=&#34;bonds-the-exception-to-the-rule&#34;&gt;Bonds, the exception to the rule&lt;/h3&gt;
&lt;p&gt;Stock markets always went up in the past, but when looking at the &lt;a href=&#34;https://www.macrotrends.net/1319/dow-jones-100-year-historical-chart&#34;&gt;DJIA 100 year history&lt;/a&gt; there were several large depressions in the last 100 years. If your investment horizon is shorter than twenty years, you might consider including bonds in your portfolio to reduce the short-term impact of a market crash. I found these three articles very useful in thinking about bonds:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.bankeronwheels.com/long-term-investing-strategies-for-financial-independence/&#34;&gt;How to build an investment portfolio for Long Term Returns | Bankeronwheels.com&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://jlcollinsnh.com/2021/11/14/are-bonds-done/&#34;&gt;Are bonds done? - JLCollinsnh&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.bankeronwheels.com/how-to-take-advantage-of-a-recession/&#34;&gt;How to take advantage of the next market crash. | Bankeronwheels.com&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;patience&#34;&gt;Patience&lt;/h3&gt;
&lt;p&gt;An investment that increases the value of your portfolio by roughly 7% per year&lt;sup id=&#34;fnref1:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; requires a lot of patience. It&amp;rsquo;s hard to keep your eyes on the target when you see the crypto and meme stock&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt; craziness going on. Why wait twenty years to be financially independent when you &amp;ldquo;can achieve&amp;rdquo; the same result in a month if you guess the next rising cryptocurrency and put your life savings on it?&lt;/p&gt;
&lt;p&gt;But whilst assuming that Bitcoin is always going to increase in value or thinking that you can get early on the next GME&lt;sup id=&#34;fnref1:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt; is very risky, believing that the stock market will increase in value over the next 20 years is much less so.&lt;/p&gt;
&lt;p&gt;Edit (2021-11-22): Thanks &lt;a href=&#34;https://twitter.com/KevSlashNull&#34;&gt;@KevSlashNull&lt;/a&gt; for clarification on the &amp;ldquo;Motivation 1&amp;rdquo; example. I said you are losing $6, but you are missing out on $6.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;I wrote &lt;a href=&#34;https://blog.viktomas.com/posts/opportunity-cost/&#34;&gt;a longer version of this argument&lt;/a&gt; last year.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.bankeronwheels.com/long-term-investing-strategies-for-financial-independence/&#34;&gt;How to build an investment portfolio for Long Term Returns | Bankeronwheels.com&lt;/a&gt; look for &amp;ldquo;World ETF Benchmark Total Return (1988-2020)&amp;rdquo;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref1:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;He used VTSAX index fund&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;VTI is a ticker for Vanguard&amp;rsquo;s all-world index ETF.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.viktomas.com/books/nassim-taleb-the-black-swan/&#34;&gt;Black swan&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;I mean indexes copying whole stock market like S&amp;amp;P 500, FTSE All-World or MSCI All-World, not speculative indexes like the Green-energy index&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Meme_stock&#34;&gt;Meme stock - Wikipedia&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref1:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Plato - Apology</title>
      <link>https://blog.viktomas.com/books/plato--apology/</link>
      <pubDate>Sun, 21 Nov 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/plato--apology/</guid>
      <description>&lt;p&gt;Apology is Plato&amp;rsquo;s book with the best Goodreads rating. Plato published it in 399 BC. I picked it up because I&amp;rsquo;m excited about learning something this timeless.&lt;/p&gt;
&lt;p&gt;The book is short, roughly 100 pages, and it describes Socrates&amp;rsquo; defence before Athenians sentenced him to death for corrupting the youth and not believing in goods.&lt;/p&gt;
&lt;p&gt;The defence wasn&amp;rsquo;t particularly good by today&amp;rsquo;s standards. The arguments Socrates used were not convincing. On the other hand, 2400 ago, this must have been the top-notch argumentation. And to be fair, I have no idea how would I defend myself for not believing in gods.&lt;/p&gt;
&lt;p&gt;The defence logic didn&amp;rsquo;t impress me, but the morality did. Socrates had his values and standards, and he died rather than sacrificing those values. He left three sons behind.&lt;/p&gt;
&lt;p&gt;I recommend reading the book because it&amp;rsquo;s a classic and will only take a couple of hours. The language is old, and you&amp;rsquo;ll need a dictionary at hand. I read the version with foreword and translation from James J. Helm.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Jim Paul - What I Learned Losing a Million Dollars</title>
      <link>https://blog.viktomas.com/books/jim-paul--what-i-learned-losing-a-million-dollars/</link>
      <pubDate>Thu, 18 Nov 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/jim-paul--what-i-learned-losing-a-million-dollars/</guid>
      <description>&lt;p&gt;First, you&amp;rsquo;ll read Jim&amp;rsquo;s story as a cautionary tale. Then Jim analyses where he made mistakes. Because of this split into two parts, it&amp;rsquo;s easy to read the book. The first part is just like any other novel, although focused on financial markets. The second part is a philosophy/psychology self-help manual for how to be less emotional when investing.&lt;/p&gt;
&lt;p&gt;Even though I invest in index funds and not in individual stocks, I found the advice helpful.&lt;/p&gt;
&lt;h2 id=&#34;why-should-you-read-it&#34;&gt;Why should you read it?&lt;/h2&gt;
&lt;p&gt;You should read it because it&amp;rsquo;s an easy read that will teach you about the psychology of trading in the stock market. The book has got two hundred pages, and you can read the first part where Jim tells his story in one afternoon.&lt;/p&gt;
&lt;p&gt;However, don&amp;rsquo;t expect any specific advice to help you make a concrete decision in the market. Jim is specifically washing his hands from concrete plans and only suggests how to think about investing.&lt;/p&gt;
&lt;h2 id=&#34;one-key-lesson&#34;&gt;One key lesson&lt;/h2&gt;
&lt;p&gt;Have a plan! Have a plan before you invest any money.&lt;/p&gt;
&lt;p&gt;You have to decide what loss are you willing to accept, what profit do you expect. You should prepare scenarios that say, &amp;ldquo;If A happens, I&amp;rsquo;m going to sell the stock/wait/buy more&amp;rdquo;. And you have to do this &lt;strong&gt;before&lt;/strong&gt; you invest. If you write these before investing and have the discipline to stick with the plan, you at least limit the amount of money you&amp;rsquo;ll lose. The upside is up to you and up to your analysis.&lt;/p&gt;
&lt;p&gt;The moment you invest, you&amp;rsquo;ll become emotionally attached to the investment. If you don&amp;rsquo;t have the plan, you&amp;rsquo;ll start justifying your investment even if it loses value. (&amp;ldquo;It&amp;rsquo;s just a tiny glitch, I&amp;rsquo;m going to wait a bit longer till the market turns.&amp;rdquo;) You&amp;rsquo;ll make it personal, and you&amp;rsquo;ll lose money &lt;em&gt;eventually&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Eventually is the important word. If you invest emotionally, it can work for you for years the same way it worked for Jim, but ultimately, you&amp;rsquo;ll make a mistake, you&amp;rsquo;ll double down to protect your ego, and you&amp;rsquo;ll lose money.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Denis E. Taylor - Heaven&#39;s River</title>
      <link>https://blog.viktomas.com/books/denis-taylor--heavens-river/</link>
      <pubDate>Fri, 12 Nov 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/denis-taylor--heavens-river/</guid>
      <description>&lt;p&gt;Read the story of several spaceships that contain uploaded human minds. These spaceships are Von Neumann probes; self-replicating spaceships meant to spread through the galaxy. Each spaceship has a cloned mined of an Earth engineer called Robert (Bob).&lt;/p&gt;
&lt;p&gt;This is the fourth book of the Bobiverse series, so if you are new to Bobiverse, you might want to start with the first book: &lt;a href=&#34;https://openlibrary.org/works/OL19123425W/We_Are_Legion_%28We_Are_Bob%29_%28Bobiverse%29_%28Volume_1%29&#34;&gt;We Are Legion (We Are Bob)&lt;/a&gt;. I also strongly recommend the audiobooks narrated by Ray Porter.&lt;/p&gt;
&lt;p&gt;Heaven&amp;rsquo;s river is a megastructure: a large tube orbiting a star with a civilization of otters in it! The book is a story of exploring this structure told by many different spaceships (Bobs).&lt;/p&gt;
&lt;p&gt;When I read the &lt;a href=&#34;https://blog.viktomas.com/books/andy-weir-project-hail-mary/&#34;&gt;Project Hail Mary&lt;/a&gt;, it reminded me of the Bobiverse. And I was stoked to find out that Denis Taylor had written the fourth book since I read the series! Heaven&amp;rsquo;s River.&lt;/p&gt;
&lt;p&gt;If &lt;em&gt;self-replicating sentient spaceships&lt;/em&gt; sound like your jam, read the first book. If you&amp;rsquo;ve already read the previous three books, I won&amp;rsquo;t be able to stop you from reading this one even if I tried.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Nassim Taleb - The Black Swan</title>
      <link>https://blog.viktomas.com/books/nassim-taleb--the-black-swan/</link>
      <pubDate>Wed, 10 Nov 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/nassim-taleb--the-black-swan/</guid>
      <description>&lt;p&gt;The Black Swan is a name for an event that is completely unpredictable. The original example is discovering black swans in Australia, disproving the observation that all swans are white.&lt;/p&gt;
&lt;p&gt;Nassim explains the problem he sees with measuring probability and how people use estimates to guide their important decisions.&lt;/p&gt;
&lt;h2 id=&#34;why-shouldnt-you-read-it&#34;&gt;Why shouldn&amp;rsquo;t you read it?&lt;/h2&gt;
&lt;p&gt;Unconventionally, I&amp;rsquo;ll start by telling you why should you &lt;strong&gt;not&lt;/strong&gt; read the book. Nassim is an insufferable author. The book has 366 pages, but it could be reduced to 150 if Nassim left out his ego and narcissism. The book could have been a pleasant, enlightening, and &lt;em&gt;short&lt;/em&gt; read if it wasn&amp;rsquo;t for the insults, tangents, and unnecessarily complicated words.&lt;/p&gt;
&lt;p&gt;Nassim is intelligent and unconventional in his ideas, but he also chose this book to settle petty disputes he encountered in his life. Overall, you&amp;rsquo;ll have to take a lot of &lt;em&gt;punishment&lt;/em&gt; to extract the good ideas. You can read a few well-rated articles on &lt;a href=&#34;https://www.lesswrong.com/&#34;&gt;LessWrong&lt;/a&gt; and end up better off.&lt;/p&gt;
&lt;h2 id=&#34;why-should-you-read-it&#34;&gt;Why should you read it?&lt;/h2&gt;
&lt;p&gt;The ideas in the book are interesting. I&amp;rsquo;m still new to the rationality movement, and the book gave me valuable insights into thinking about uncertainty and work scalability. If you&amp;rsquo;ve got plenty of time and patience and you can tolerate all the things I warned you about, give the book a shot.&lt;/p&gt;
&lt;h2 id=&#34;key-takeaways&#34;&gt;Key takeaways&lt;/h2&gt;
&lt;p&gt;There are &lt;strong&gt;two types of randomness&lt;/strong&gt;. Mild and extreme. The mild randomness&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; applies when there&amp;rsquo;s a natural limit to the variable, such as human height. The extreme randomness&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; applies when there&amp;rsquo;s no natural limit, like a person&amp;rsquo;s net worth. The key point in the book is that black swans happen when we mistake extreme randomness for a mild one. For example, when we assume that market movements are governed by mild randomness.&lt;/p&gt;
&lt;p&gt;There is &lt;strong&gt;scalable vs non-scalable work.&lt;/strong&gt; When your work doesn&amp;rsquo;t scale, that means that your reward is a function of how much time and effort you put in. Lawyers, doctors and engineers are in this category. If your work scales, then there is no limit on your reward. Startup founders, investors and book authors are doing scalable work. The problem with scalable work is that very few winners take most of the rewards.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Nobody can predict the future.&lt;/strong&gt; It&amp;rsquo;s useless to listen to experts when they predict the future. There&amp;rsquo;s plenty of data to support this in financial markets. &lt;a href=&#34;https://compoundadvisors.com/2021/how-to-invest-without-knowing-the-future&#34;&gt;Check the 2021 S&amp;amp;500 predictions&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;More supporting evidence doesn&amp;rsquo;t have much value.&lt;/strong&gt; After the first few values, any further evidence supporting your hypothesis doesn&amp;rsquo;t increase your confidence in the hypothesis. It can still be wrong. Two examples are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Newtonian physics (there was a large body of supporting evidence till Einstein proved it incomplete)&lt;/li&gt;
&lt;li&gt;Imaginary turkey (the bird) who thinks that people have its best interest in mind because they are feeding it (each day the confidence increases until Thanksgiving).&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;He calls it Gaussian randomness.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;He calls it Mandlebrotian randomness.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Andy Weir - Project Hail Mary</title>
      <link>https://blog.viktomas.com/books/andy-weir--project-hail-mary/</link>
      <pubDate>Sat, 30 Oct 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/andy-weir--project-hail-mary/</guid>
      <description>&lt;p&gt;I am genuinely excited about this book. It made me do two things I hadn&amp;rsquo;t done in years: dream about the book, and interrupt my reading because the story got too intense.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve never read Martian, Andy&amp;rsquo;s previous book, so I had no expectations when opening this book. I learned about the book from someone praising it on our company Slack. The storyline sucked me in and spit me out a week later when I finished listening to the captivating story.&lt;/p&gt;
&lt;h2 id=&#34;why-should-you-read-it&#34;&gt;Why should you read it?&lt;/h2&gt;
&lt;p&gt;You should read this book if you enjoy sci-fi and science. The story is happening in the present, and all the technology sounds plausible. It&amp;rsquo;s fascinating to think that this story could happen if only we got the fuel to power our spaceship.&lt;/p&gt;
&lt;p&gt;This book is very similar to Bobiverse series from Dennis E. Taylor. It describes a more advanced technology but not so advanced that you can&amp;rsquo;t imagine the current science progressing that far.&lt;/p&gt;
&lt;p&gt;If you want to read a story that explores nearby solar systems, if you want to read about space travel that could almost happen today, and if you want to get entertained with a very eventful storyline, Project Hail Mary is your next book!&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Zettelkasten note-taking after one year</title>
      <link>https://blog.viktomas.com/posts/slip-box-after-a-year/</link>
      <pubDate>Sun, 24 Oct 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/slip-box-after-a-year/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve been taking small, permanent, densely-linked notes for over a year. Now I&amp;rsquo;ll share how my understanding of the Zettelkasten (aka Slip-box) method changed and what I&amp;rsquo;ve learned. 16 months ago, I wrote a &lt;a href=&#34;https://blog.viktomas.com/posts/slip-box/&#34;&gt;popular post&lt;/a&gt; about Zettelkasten. I wrote it right after reading the &lt;a href=&#34;https://blog.viktomas.com/books/ahrens-sonke-how-to-take-smart-notes/&#34;&gt;How to Take Smart Notes&lt;/a&gt; book. I&amp;rsquo;ve been taking smart notes since then. I changed my process and software, but the premise is still the same. This is my update.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 100%&#34; src=&#34;https://blog.viktomas.com/images/posts/slipbox-after-a-year/slipbox-after-a-year.jpg&#34; alt=&#34;Year of Slip-box&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Year of Slip-box&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;why-the-motivation&#34;&gt;Why? (the motivation)&lt;/h2&gt;
&lt;p&gt;I got hooked on the Slip-box method because it focuses on building a &lt;em&gt;long-lasting&lt;/em&gt; knowledge base. The premise is that you&amp;rsquo;ll understand something once, and then you&amp;rsquo;ll always have this understanding stored in your Slip-box as a note. Wouldn&amp;rsquo;t that be wonderful?&lt;/p&gt;
&lt;p&gt;Before I learned about Slip-box, &lt;a href=&#34;https://blog.viktomas.com/posts/reading-is-hard&#34;&gt;I forgot most of the information I read&lt;/a&gt;. I would write notes that adopt the book&amp;rsquo;s terminology and structure. Writing notes this way made it impossible to reuse them when I read another book on the topic.&lt;/p&gt;
&lt;p&gt;The &amp;ldquo;why&amp;rdquo; hasn&amp;rsquo;t changed.&lt;/p&gt;
&lt;h2 id=&#34;what-the-method&#34;&gt;What? (the method)&lt;/h2&gt;
&lt;p&gt;Slip-box consists of short, atomic, densely-linked notes optimised for reading.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Short&lt;/strong&gt; - Short note is easier to read and keep it on a single topic. I try to keep my notes about four paragraphs or less.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Atomic&lt;/strong&gt; - The note contains one idea or fact, making the notes easier to link and deduplicate.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Densely-linked&lt;/strong&gt; - When the note uses another thought or fact, you don&amp;rsquo;t repeat it but refer (link) to it.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Optimised for reading&lt;/strong&gt; - You spend more time writing and polishing the note because you expect to read it over and over again as opposed to the write-and-forget style.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You optimise these notes for reading. You spent more time writing them because you explain the topic with &lt;a href=&#34;https://about.gitlab.com/company/culture/all-remote/effective-communication/#understanding-low-context-communication&#34;&gt;low context&lt;/a&gt; to your future self who already forgot all about it.&lt;/p&gt;
&lt;p&gt;Should you store a piece of information in your slip-box, or should you put it somewhere else?&lt;/p&gt;
&lt;p&gt;Imagine you learn about a new concept:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;e.g. Idea from Yuval Harari&amp;rsquo;s Sapiens that Europe and Asia developed better civilisation than Americas because Americas span vertically lot of climates making it harder to share agriculture progress between different climates.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Surely you want to put it in your Slip-box, but what about a shopping list? Or an idea for your new side-project?&lt;/p&gt;
&lt;p&gt;I initially kept two note systems, one for the long-lasting &amp;ldquo;permanent&amp;rdquo; notes and another for the day-to-day &amp;ldquo;ephemeral&amp;rdquo; notes. But now I keep all my notes in one place. I don&amp;rsquo;t have to decide which app to open to capture a thought. If the note shows not to be useful, I can delete it, or it will naturally fade into the background because it&amp;rsquo;s not densely linked to other notes.&lt;/p&gt;
&lt;p&gt;Creating links between notes makes you answer two questions for each new note:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;How does it fit into my existing knowledge?&lt;/li&gt;
&lt;li&gt;Does this piece of information conflict with my previous understanding?&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Answering these questions takes &lt;em&gt;a lot&lt;/em&gt; of time, but it pays off in the quality of your understanding and the ease of reading.&lt;/p&gt;
&lt;h2 id=&#34;how-the-software&#34;&gt;How? (the software)&lt;/h2&gt;
&lt;p&gt;Now let&amp;rsquo;s talk about how do I create and store my notes? I&amp;rsquo;ll walk you through the tools I tried (the cool part) and the process I use for taking my notes.&lt;/p&gt;
&lt;h3 id=&#34;the-tool&#34;&gt;The tool&lt;/h3&gt;
&lt;p&gt;If you are like me, you&amp;rsquo;ll spend a lot of time looking for the perfect tool at the expense of more productive activities like reading and learning. Here you might get lucky. You can start where I finished (Logseq) and be completely content with the solution the same I am now.&lt;/p&gt;
&lt;p&gt;Once I understood the Slip-box method, I had a clear idea about the requirements for the tool (ordered by priority):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Local plain text&lt;/strong&gt; - It had to store the notes locally in plain text (Markdown), so I can version them with &lt;code&gt;git&lt;/code&gt;. This disqualified cloud-based apps like Evernote, Notion, or even TidlyWiki.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Links&lt;/strong&gt; - The tool has to support creating links between files as references to other notes.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Easy to read&lt;/strong&gt; - Reading experience is more important than writing because you&amp;rsquo;ll be reading the note many times in the future.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Easy to write&lt;/strong&gt; - Creating new notes shouldn&amp;rsquo;t be unnecessarily complex (e.g. I don&amp;rsquo;t want to write a text note and then run a command to render my notes as web page).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Open-source&lt;/strong&gt; - If I can help it at all, the tool should be open-source. Even if the original author stops maintaining it, the tool has a chance to live on.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;dead-end-1-zettlr&#34;&gt;Dead end 1: Zettlr&lt;/h4&gt;
&lt;p&gt;I started taking notes with &lt;a href=&#34;https://www.zettlr.com/&#34;&gt;Zettlr&lt;/a&gt; . It is an open-source note-taking app that heavily relies on WikiLinks ( &lt;code&gt;[[202103100852]]&lt;/code&gt; ) to create links between files. Zettlr also automatically renders the markdown you are writing. It makes it easier to read the note even though you are constantly in edit mode.&lt;/p&gt;
&lt;p&gt;After a month or two, I started longing for a universal format because WikiLinks needed custom software to resolve them ( I came into terms with WikiLinks later). I decided to use plain markdown. It supports linking out of the box, and there are countless available tools to write and process it.&lt;/p&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/images/posts/slipbox-after-a-year/zettlr.png&#34;
    alt=&#34;Zettlr&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;h4 id=&#34;dead-end-2-vs-code&#34;&gt;Dead end 2: VS Code&lt;/h4&gt;
&lt;p&gt;So I left Zettel for &lt;a href=&#34;https://code.visualstudio.com&#34;&gt;VS Code&lt;/a&gt;. VS Code is a text editor for developers, so using it comes naturally to me. I wasn&amp;rsquo;t the only one going in this direction; there are &lt;a href=&#34;https://foambubble.github.io/&#34;&gt;FoamBubble&lt;/a&gt; and &lt;a href=&#34;https://www.dendron.so/&#34;&gt;Dendron&lt;/a&gt; projects that customise VS Code for note-taking. And I&amp;rsquo;m pretty sure &lt;a href=&#34;https://obsidian.md/&#34;&gt;Obsidian&lt;/a&gt; does as well, even though they don&amp;rsquo;t share their code.&lt;/p&gt;
&lt;p&gt;I developed &lt;a href=&#34;https://marketplace.visualstudio.com/items?itemName=viktomas.slipbox&#34;&gt;an extension&lt;/a&gt; that simplifies the most common tasks like creating and linking notes. I also use &lt;a href=&#34;https://www.markdownguide.org/basic-syntax#links&#34;&gt;Markdown Links&lt;/a&gt; to visualise relationships between my notes.&lt;/p&gt;
&lt;p&gt;This solution worked well for writing notes. I could stay in a familiar environment and insert/format text seamlessly. But reading non-rendered markdown is not pleasant, especially with attachments like images (You see &lt;code&gt;![description](/path/to/image)&lt;/code&gt; rather than the image itself).&lt;/p&gt;
&lt;p&gt;I noticed that I avoided adding images, renaming notes, splitting a note in two, and other operations. It was time to adopt a more complex tool again.&lt;/p&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/images/posts/slipbox-after-a-year/vscode.png&#34;
    alt=&#34;VS Code&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;h4 id=&#34;the-pinnacle-of-note-taking-logseq&#34;&gt;The pinnacle of note-taking: Logseq&lt;/h4&gt;
&lt;p&gt;I knew about &lt;a href=&#34;https://roamresearch.com/&#34;&gt;RoamResearch&lt;/a&gt; since I started taking Zettelkasten notes, and I liked it. It did what I needed except for having all notes stored in the cloud.&lt;/p&gt;
&lt;p&gt;I spent on average two or more hours a week either working on my extension for the VS Code or looking for a perfect tool. And then I found &lt;a href=&#34;https://logseq.com/&#34;&gt;Logseq&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Logseq was the missing piece for me. It looks like a RoamResearch clone with bits of inspiration from TiddlyWiki and Org-Mode. It ticks off all the requirements I mentioned earlier. The UI renders each paragraph the moment you stop editing it. That means all the text is nicely rendered, including images.&lt;/p&gt;
&lt;p&gt;You can hover over links to see a pop up with the linked note. You can open notes in the sidebar (press &lt;code&gt;shift&lt;/code&gt; before clicking) and edit two notes simultaneously. The hierarchical bullet-point structure pleasantly surprised me because it makes it easy to reorder my thoughts and move paragraphs between notes.&lt;/p&gt;
&lt;p&gt;The app stores all your notes as Markdown text files on your disk and allows you to publish your notes on the web. You can go to &lt;a href=&#34;https://logseq.github.io/&#34;&gt;Logseq web app&lt;/a&gt; and try out the app without installing the desktop app.&lt;/p&gt;
&lt;p&gt;I had to write a short script to convert my markdown notes into the Logseq format &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, and since then, I&amp;rsquo;ve been the happiest user. That was four months ago. Lastly, if you enjoy the app, please support the development team on &lt;a href=&#34;https://opencollective.com/logseq&#34;&gt;their OpenCollective page&lt;/a&gt; &lt;em&gt;(no affiliation)&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/images/posts/slipbox-after-a-year/logseq.png&#34;
    alt=&#34;Logseq&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;h3 id=&#34;the-process&#34;&gt;The process&lt;/h3&gt;
&lt;p&gt;In the following process, I&amp;rsquo;ll use the term &lt;em&gt;book&lt;/em&gt; to refer to any information resource (e.g. video, blog article, white paper, and so on)&lt;/p&gt;
&lt;p&gt;How I create a note:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I start reading a book, and I create new reference notes.&lt;/li&gt;
&lt;li&gt;I write many sentences that phrase my understanding of the book content.&lt;/li&gt;
&lt;li&gt;I group related sentences by topic.&lt;/li&gt;
&lt;li&gt;I create a new Permanent note for each interesting thought (group of sentences).&lt;/li&gt;
&lt;li&gt;I drag the group sentences in the permanent note.&lt;/li&gt;
&lt;li&gt;I look for related permanent notes to find where I can link the new note. In this step, I often rewrite or edit existing permanent notes to reflect my new understanding.&lt;/li&gt;
&lt;li&gt;I write the new permanent note in different words but still capture the main thought.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;main-issue---the-time&#34;&gt;Main issue - the time&lt;/h2&gt;
&lt;p&gt;Since I started with Slip-box, I felt that it takes &lt;strong&gt;too much time&lt;/strong&gt; to write good notes. It takes me roughly half an hour to produce one permanent note (including the time for reading). For example, when I read &lt;a href=&#34;https://blog.viktomas.com/books/winters-manshreck-wright-software-engineering-at-google/&#34;&gt;Software Engineering at Google&lt;/a&gt; it took me three hours to read a chapter and make five permanent notes. I&amp;rsquo;m comforting myself that now that I put effort to extract the knowledge and linking it with my existing notes, I&amp;rsquo;ll always have it readily available. But was it worth three hours of my time?&lt;/p&gt;
&lt;p&gt;I watched &lt;a href=&#34;https://www.youtube.com/playlist?list=PLHwtkAtdkx1IZoI7FZf1X50qyzRnmw_Vy&#34;&gt;Christian from Zettelkasten.de taking notes from a book&lt;/a&gt;. He&amp;rsquo;s a professional note-taker, and it still took him two hours to take four notes in the first video - it does take forever to make good permanent notes.&lt;/p&gt;
&lt;p&gt;My reading is now more productive in the long term because I make notes that are easy to revisit. However, it feels less productive because it takes 4-6 times longer to read a book.&lt;/p&gt;
&lt;p&gt;Side note: I incorporated spaced repetition with &lt;a href=&#34;https://apps.ankiweb.net/&#34;&gt;Anki&lt;/a&gt; into my learning, and I can&amp;rsquo;t help but feel that spaced repetition gives me a higher return on investment. ( &lt;a href=&#34;https://andymatuschak.org/prompts/&#34;&gt;How to write good prompts: using spaced repetition to create understanding&lt;/a&gt; got me hooked.) Maybe I&amp;rsquo;ll share more about that in one of the future blog posts.&lt;/p&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/images/posts/slipbox-after-a-year/slipbox-spaced-repetition-meme.jpg&#34;
    alt=&#34;Slip-box and Spaced repetition meme&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;Taking notes is fun. It&amp;rsquo;s even more fun with Logseq. For me, it stopped being a cool trend on HackerNews and Twitter and turned into a general habit that makes me better. However, taking notes with the Slip-box method takes a long time. For example, I stopped reading Thinking, Fast and Slow from Daniel Kahneman because taking notes took too long, and the book felt too dull. Maybe it would be more interesting if I could read it six times faster&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;If you haven&amp;rsquo;t tried Slip-box yet, I recommend you do. I recommend using Logseq, org-roam, or RoamResearch. Make atomic notes, create many links between them and don&amp;rsquo;t try to optimise the system till you have hundreds of notes (I&amp;rsquo;ve got roughly 400). Good luck!&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Logseq uses the note title as the filename. I had to rename links like &lt;code&gt;2021-10-24-note-title.md&lt;/code&gt; to &lt;code&gt;Note Title.md&lt;/code&gt; . (Yes, that space hurts my feelings.) And then, I had to change all references from &lt;code&gt;[Note Title](2021-10-24-note-title.md)&lt;/code&gt; to &lt;code&gt;[[Note Title]]&lt;/code&gt;.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;As I said, when I read non-fiction and make Slip-box notes, it takes me 4-6 times longer to read the same amount of text.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Crucial Conversations</title>
      <link>https://blog.viktomas.com/books/crucial-conversations/</link>
      <pubDate>Thu, 14 Oct 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/crucial-conversations/</guid>
      <description>&lt;p&gt;The four authors who wrote this book also started a consultancy to help resolve conflicts and increase efficiency in communication. The book is a fantastic resource for having a crucial conversation. The authors define a &lt;em&gt;crucial conversation&lt;/em&gt; as a conversation where:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;stakes are high&lt;/li&gt;
&lt;li&gt;emotions run wild&lt;/li&gt;
&lt;li&gt;opinions differ&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ever had one of those? ;)&lt;/p&gt;
&lt;h2 id=&#34;why-should-you-read-it&#34;&gt;Why should you read it?&lt;/h2&gt;
&lt;p&gt;You should read Crucial Conversations because you&amp;rsquo;ll get a good framework for dealing with conflict in a productive way. It will serve you well in both your professional and personal life. The book does not offer tricks on how to &amp;ldquo;win&amp;rdquo; over the other person. It strives to create win-win situations, helping people understand each other rather than impose their opinions on others.&lt;/p&gt;
&lt;h2 id=&#34;framework-in-a-nutshell&#34;&gt;Framework in a nutshell&lt;/h2&gt;
&lt;p&gt;The book has roughly 200 pages, and you can read it in an afternoon. I encourage you to read it because I won&amp;rsquo;t be able to do the method justice.&lt;/p&gt;
&lt;p&gt;There are several key concepts in the method:&lt;/p&gt;
&lt;h3 id=&#34;shared-pool-of-meaning&#34;&gt;Shared pool of meaning&lt;/h3&gt;
&lt;p&gt;A shared pool of meaning is the shared understanding of the group. If people share their meaning (understanding) it becomes public for the group. Everyone sees how the other person reached their conclusion, and when the group makes a decision, they can consider everyone&amp;rsquo;s understanding, possibly getting a better result.&lt;/p&gt;
&lt;h3 id=&#34;dialogue&#34;&gt;Dialogue&lt;/h3&gt;
&lt;p&gt;They define &lt;em&gt;dialogue&lt;/em&gt; as a free flow of meaning between people. It means filling the &lt;em&gt;shared pool of meaning&lt;/em&gt;. As soon as someone starts feeling unsafe, the flow is no longer free, and people either withdraw from the conversation (flight) or start forcing their meaning into the pool (fight).&lt;/p&gt;
&lt;h3 id=&#34;safety&#34;&gt;Safety&lt;/h3&gt;
&lt;p&gt;Feeling safe is the primary condition for the dialogue to happen. You can build safety on mutual respect and a common goal. If you don&amp;rsquo;t respect the other person (you think they are dumb, for example) or don&amp;rsquo;t share the same goal (you both want the same piece of pie), then there is a breach of safety, and the dialogue starts breaking down.&lt;/p&gt;
&lt;h3 id=&#34;stories&#34;&gt;Stories&lt;/h3&gt;
&lt;p&gt;You interpret what you see and hear and attach a meaning to it. The attached meaning is a story. The book is very adamant about the difference between facts (what you see and hear) and the story (how you interpret the facts).&lt;/p&gt;
&lt;p&gt;In my opinion, learning to distinguish between &lt;strong&gt;fact&lt;/strong&gt; (he looked at his phone a lot) and a &lt;strong&gt;story&lt;/strong&gt; (he&amp;rsquo;s disrespectful and doesn&amp;rsquo;t care about me) alone would &lt;strong&gt;make the book worth reading&lt;/strong&gt;. These two are so easy to confuse, and when you read a few examples, you&amp;rsquo;ll start noticing how often you do that in your relationships.&lt;/p&gt;
&lt;h2 id=&#34;what-should-you-be-careful-about&#34;&gt;What should you be careful about?&lt;/h2&gt;
&lt;p&gt;The book often reads like an infomercial for the method and the consultancy itself. It is understandable since their livelihood depends on it, but when you read the book, you need to stay critical of some of the statements because their authors also conducted case studies that back them up.&lt;/p&gt;
&lt;p&gt;However, the book&amp;rsquo;s concepts match my understanding of how the brain works (or fails to work), and I&amp;rsquo;m confident that the method makes sense.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Frank Herbert - Dune</title>
      <link>https://blog.viktomas.com/books/herbert-frank--dune/</link>
      <pubDate>Sun, 03 Oct 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/herbert-frank--dune/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve done it again. I&amp;rsquo;ve read the Dune for the third time. Actually, this time I listened to the controversial 2007 Audio Renaissance audiobook. Controversial because it&amp;rsquo;s dramatized with music and read by 12 different voice actors. I liked the format because it was easier to make sense of the many characters in the book.&lt;/p&gt;
&lt;p&gt;Herbert wrote Dune in a way that avoids specifics of how the technology looks and works, and so it&amp;rsquo;s as fun and &amp;ldquo;current&amp;rdquo; in 2021 as it was in 1965 when it was first published.&lt;/p&gt;
&lt;p&gt;The audiobook is a bit extreme with its ** twenty-one hours**. But I listened to it while driving across Europe, so listening to Dune filled time that I would otherwise listen to something regardless.&lt;/p&gt;
&lt;h2 id=&#34;why-should-you-read-it&#34;&gt;Why should you read it?&lt;/h2&gt;
&lt;p&gt;Because the new movie is out! And you&amp;rsquo;ve got a unique opportunity to use your imagination to create Arakis world in your head before Villeneuve draws it for you in his 2021 Dune movie.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Why are salaries so low</title>
      <link>https://blog.viktomas.com/posts/low-salaries/</link>
      <pubDate>Tue, 21 Sep 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/low-salaries/</guid>
      <description>&lt;p&gt;&lt;em&gt;Is there a link between our compensation and how much value your work creates? I think that reward is disconnected from the value provided.&lt;/em&gt;&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 600px&#34; src=&#34;https://blog.viktomas.com/images/posts/why-are-salaries-so-low.jpg&#34; alt=&#34;Why are salaries so low&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Why are salaries so low&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;A few months ago, I binged listened through the &lt;a href=&#34;https://nav.al/rich&#34;&gt;How to Get Rich&lt;/a&gt; from Naval Ravikant. He talks in great detail about the relationship between the work you do, the value the work provides, and the compensation you&amp;rsquo;ll get for it. And as I listened, one question crystalised in my mind.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Why are salaries so low?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Suppose your work has a large multiplier between your input and the value provided (i.e. it scales easily) like software, finance, marketing and arts. In that case, your reward could be in orders of magnitude different from occupations that don&amp;rsquo;t scale like carpentry. In software, you write a part of a program that will work for years and keep bringing value to the program&amp;rsquo;s owner (or their customers). But there seems to be a massive gap between the value of the employee&amp;rsquo;s contribution and their compensation. Why is that?&lt;/p&gt;
&lt;p&gt;My current working theory is that people don&amp;rsquo;t get compensated for the value they bring to the company as much as for the amount it would cost to get another person to contribute the same way to the company. In other words, if John, with roughly the same skill set, is willing to work for $100,000 a year, then that&amp;rsquo;s what I&amp;rsquo;m going to get, regardless of my work bringing $500,000 to the company.&lt;/p&gt;
&lt;p&gt;I also considered the option that exactly because some work scales so well, it becomes less valuable, but that wouldn&amp;rsquo;t explain the increase in stock value of software companies.&lt;/p&gt;
&lt;p&gt;I have surely a very simplified look at the problem, and in the real world, the salary will be a combination of the &amp;ldquo;competition&amp;rdquo; and the &amp;ldquo;value-added&amp;rdquo; factors. But for the individual contributor&amp;rsquo;s salary, the &amp;ldquo;competition&amp;rdquo; part seems much more significant. Also, I&amp;rsquo;m not suggesting that employees are getting ripped off. They don&amp;rsquo;t deserve the full reward if they don&amp;rsquo;t carry the risks.&lt;/p&gt;
&lt;h2 id=&#34;way-to-increase-the-salary&#34;&gt;Way to increase the salary&lt;/h2&gt;
&lt;p&gt;Naval suggest that you can increase your compensation by getting more accountability for your work. You want to be solely responsible for the work you do, including the downsides. This is why VP&amp;rsquo;s get more stock options. They&amp;rsquo;ve got more impact on the company.&lt;/p&gt;
&lt;p&gt;Ultimately, Naval hits that the end goal is always to start your own company. Only if you own the company you can fully capture the value.&lt;/p&gt;
&lt;p&gt;On a smaller scale, you can shift into a field/location where the competition isn&amp;rsquo;t that fierce.&lt;/p&gt;
&lt;p&gt;My thinking on this topic is not clear. I&amp;rsquo;ve never studied economy, and this pondering seems probably trivial and obvious to someone with a microeconomy background. I&amp;rsquo;ve decided to read the well-recognised textbook from Gregory Mankiw - &lt;a href=&#34;https://openlibrary.org/books/OL23174415M/Principles_of_microeconomics&#34;&gt;Principles of Microeconomics&lt;/a&gt;. If you have a clear understanding of the topic, let me know at &lt;a href=&#34;mailto:me@viktomas.com&#34;&gt;me@viktomas.com&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Richard P. Feynman - Surely You&#39;re Joking Mr Feynman!</title>
      <link>https://blog.viktomas.com/books/feynman-richard--surely-youre-joking-mr-feynman/</link>
      <pubDate>Sun, 01 Aug 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/feynman-richard--surely-youre-joking-mr-feynman/</guid>
      <description>&lt;p&gt;This book was published in 1985 as a loose collection of stories from &lt;a href=&#34;https://en.wikipedia.org/wiki/Richard_Feynman&#34;&gt;Feynman&lt;/a&gt; &amp;rsquo;s life. If he was at least half as gifted/driven as he makes himself to be in this book, he had to be an amazing person to be around. The book is hilarious and I laughed out loud many times.&lt;/p&gt;
&lt;h2 id=&#34;why-should-you-read-it&#34;&gt;Why should you read it?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Read it if you are interested in reasoning from first principles. - This book is very often quoted by people interested in critical thinking and reasoning from first principles. In the book, Feynman often emphasizes not believing what other people say automatically and thinking about the topic independently.&lt;/li&gt;
&lt;li&gt;Read it if you&amp;rsquo;d like to see how living by the rules of the scientific method looks like. - Feynman questioned everything and anyone. In his last chapter, &amp;ldquo;Cargo cult science&amp;rdquo;, he succinctly summed up what is wrong with modern science (motivated reasoning, not enough emphasis on reproducibility). His commentary is still true today, even though he wrote it in the 70s.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;what-to-be-careful-about&#34;&gt;What to be careful about?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Even though undoubtedly a brilliant and accomplished scientist, Feynman seems to be quite full of himself. You can&amp;rsquo;t read the book as an objective account of Feynman&amp;rsquo;s life but instead, read it as if Feynman told you the stories over a beer in a pub. Take it with a grain of salt.&lt;/li&gt;
&lt;li&gt;Parts of the book are getting very technical. You might have to re-read some pages multiple times (or skip them).&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Insurance is like gambling, don&#39;t overdo it</title>
      <link>https://blog.viktomas.com/posts/insurance/</link>
      <pubDate>Wed, 16 Jun 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/insurance/</guid>
      <description>&lt;p&gt;&lt;em&gt;Insurance companies, like betting companies, need high margins to keep operating. You are paying that margin.&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;You can insure anything these days. From satellite launches to the screen on your smartphone. But not all insurances are created equal. When does it make sense to get insurance, and when will it only cost you extra money? This post describes what insurance is, and it might change your mind on whether you need it or not.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 600px&#34; src=&#34;https://blog.viktomas.com/images/posts/insurance.webp&#34; alt=&#34;Insurance&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Insurance&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;The oxford dictionary defines insurance as:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;An arrangement by which a company or the state undertakes to provide a guarantee of compensation for specified loss, damage, illness, or death in return for payment of a specified premium.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The definition is a complex way of saying that you&amp;rsquo;ll pay someone a small amount of money, and they promise to pay you much more if an improbable event happens. It&amp;rsquo;s the same as a bet, but you don&amp;rsquo;t want to win.&lt;/p&gt;
&lt;p&gt;Betting and insurance have one thing in common. You pay more than what&amp;rsquo;s your chance to win. The betting/insurance company needs money to pay salaries, bills, and shareholders.&lt;/p&gt;
&lt;h2 id=&#34;scenario&#34;&gt;Scenario&lt;/h2&gt;
&lt;p&gt;Let&amp;rsquo;s say that the chance your house burning down this year is 1 in 10,000 and that your house costs $100,000. That means that you should pay a $10 fee (called the premium) to insure your house against burning down.&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;premium = house value * chance it burns down
$10 = $100,000 * 0.0001
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When 10,000 people insure their house, the insurance company collects $100,000 in fees. However, if the chance is correctly estimated, one of the houses is bound to burn down, and the insurance company will have to pay $100,000 to that one client. The insurance company won&amp;rsquo;t have any money to pay the bills and will go bankrupt.&lt;/p&gt;
&lt;p&gt;A profitable model is to ask for a $20 premium. That way, when the company pays the poor house owner $100,000, it will still have $100,000 left in the bank. From this extra money, they can pay bills and the agent who sold you the insurance.&lt;/p&gt;
&lt;p&gt;Now we have a semi-realistic scenario. You paid $20 - twice as much as what is the chance. The key morale of the story is:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Insurance companies (same as betting companies) always need to bill you more than the chance you get your big payoff.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If this weren&amp;rsquo;t the case, they would go bankrupt.&lt;/p&gt;
&lt;h2 id=&#34;why-pay-insurance&#34;&gt;Why pay insurance&lt;/h2&gt;
&lt;p&gt;Assuming you are not a betting man, or you are smart and bet only a small portion of your income as a fun activity, why would you pay for insurance (now that you know it&amp;rsquo;s almost the same as betting)?&lt;/p&gt;
&lt;p&gt;The answer is simple and important:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Rule #1: Insure only against events that would take away your financial freedom.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Assume you&amp;rsquo;ve got $10,000 saved up for any emergency, and you earn $40,000 a year.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;event&lt;/th&gt;
          &lt;th&gt;impact&lt;/th&gt;
          &lt;th&gt;should you insure?&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Your phone screen cracked.&lt;/td&gt;
          &lt;td&gt;You have to pay $200 for a new screen.&lt;/td&gt;
          &lt;td&gt;NO!&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;You crashed your car into a tree.&lt;/td&gt;
          &lt;td&gt;You have to pay $3,000 for repairs on your car.&lt;/td&gt;
          &lt;td&gt;Probably no, it&amp;rsquo;s not ruining you financially.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;You crashed your car into a Bentley on an intersection&lt;/td&gt;
          &lt;td&gt;$30,000 you must pay to the car owner + damage on your car.&lt;/td&gt;
          &lt;td&gt;YES, this sounds like it would set you back. You&amp;rsquo;d have to take a loan to pay for the damages.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Your house got damaged in a natural disaster.&lt;/td&gt;
          &lt;td&gt;Repairs will cost you over $100,000.&lt;/td&gt;
          &lt;td&gt;YES! it could take you many years to financially recover.&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;when-insuring-pay-as-little-as-possible&#34;&gt;When insuring, pay as little as possible&lt;/h2&gt;
&lt;p&gt;One difference between betting and insuring is the excess. Excess is an amount of money that you have to pay first before you get the insurance payment. From the house example, if you set excess to $5,000:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;event&lt;/th&gt;
          &lt;th&gt;cost&lt;/th&gt;
          &lt;th&gt;you pay&lt;/th&gt;
          &lt;th&gt;insurer pays&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Ground floor is flooded&lt;/td&gt;
          &lt;td&gt;$7,000 damage&lt;/td&gt;
          &lt;td&gt;$5,000&lt;/td&gt;
          &lt;td&gt;$2,000&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;The whole house burns down&lt;/td&gt;
          &lt;td&gt;$100,000&lt;/td&gt;
          &lt;td&gt;$5,000&lt;/td&gt;
          &lt;td&gt;$95,000&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Window breaks&lt;/td&gt;
          &lt;td&gt;$400&lt;/td&gt;
          &lt;td&gt;$400&lt;/td&gt;
          &lt;td&gt;$0, they won&amp;rsquo;t even know&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;The lower the excess, the higher the chance the insurance company needs to deal with you, the higher the premium.&lt;/p&gt;
&lt;p&gt;Following Rule #1, we don&amp;rsquo;t need to insure broken window or flooded rooms. That&amp;rsquo;s what our savings are for.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Rule #2, set the highest possible excess for your insurance&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You want to involve the insurance company only when the potential event causes you severe financial distress. You shouldn&amp;rsquo;t involve the insurance company in events that you can easily cover from your savings. If you do, you have to pay much more than what&amp;rsquo;s the chance of the event. I explained that at the beginning.&lt;/p&gt;
&lt;h2 id=&#34;hustle-if-you-want-to&#34;&gt;Hustle if you want to&lt;/h2&gt;
&lt;p&gt;Lastly, I&amp;rsquo;ve read advice&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; that you shouldn&amp;rsquo;t just renew your yearly insurance subscription automatically but should call the insurance company and try to get a better deal each year. This sounds like good advice, but I haven&amp;rsquo;t tried it yet.&lt;/p&gt;
&lt;p&gt;Insurance is a costly betting that&amp;rsquo;s only worth it if you can&amp;rsquo;t afford to pay for the damage yourself. That means it should be reserved for expensive assets and for your health. You will unnecessarily lose money if you insure something that your savings can cover.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Of course, you are taking a larger risk by not insuring cheaper items. The risk is logically and financially worth taking because, by definition, it can&amp;rsquo;t cause you severe problems. However, it&amp;rsquo;s a risk non the less. And it is your own, &lt;strong&gt;I take no responsibility&lt;/strong&gt;. If you cancel your iPhone screen insurance and drop it on a footpath tomorrow, pay for the repair knowing that you&amp;rsquo;ve done a smart thing.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;In &lt;a href=&#34;https://www.barefootinvestor.com/&#34;&gt;barefoot investor&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Ursula K. Le Guin - The Lathe of Heaven</title>
      <link>https://blog.viktomas.com/books/ursula-le-guin--the-lathe-of-heaven/</link>
      <pubDate>Sun, 30 May 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/ursula-le-guin--the-lathe-of-heaven/</guid>
      <description>&lt;p&gt;This novel is about dreams and reality. Usually, these are clearly separated but not in Portland, Oregon, not for George Orr, not in 1971.&lt;/p&gt;
&lt;p&gt;The whole story happens in a dystopian &amp;ldquo;future&amp;rdquo; where humanity suffers from overpopulation and climate change. Ursula projected the worries of the sixties into this book well: overpopulation, declining environment and the cold war.&lt;/p&gt;
&lt;p&gt;Overall, the book was OK but not great. I can&amp;rsquo;t but help to compare with &lt;a href=&#34;https://blog.viktomas.com/books/crouch-blake-recursion/&#34;&gt;Recursion&lt;/a&gt; - many details in the novel seemed not thought-through.&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;Details I struggled with (spoilers)&lt;/summary&gt;
&lt;ul&gt;
&lt;li&gt;Orr was portrayed as incredibly stable, thoughtful and down-to-earth, yet he let Dr. Harber take the world to the brink of destruction because he didn&amp;rsquo;t want to go to prison.&lt;/li&gt;
&lt;li&gt;The way how other people (Harber, Heather) remembered different realities was inconsistent. There was no logic to it.&lt;/li&gt;
&lt;li&gt;The final scene when everything started falling apart in Harber&amp;rsquo;s dream didn&amp;rsquo;t make any sense.&lt;/li&gt;
&lt;/ul&gt;
&lt;/details&gt;
&lt;p&gt;Logic has to be the struggle for every time travelling/reality changing story. The fact that the novel is old is likely to be responsible for my lack of enthusiasm. I might have read improved versions of the same type of story. Now I can&amp;rsquo;t appreciate the first but imperfect book.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Software Engineering at Google</title>
      <link>https://blog.viktomas.com/books/winters-manshreck-wright--software-engineering-at-google/</link>
      <pubDate>Sat, 22 May 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/winters-manshreck-wright--software-engineering-at-google/</guid>
      <description>&lt;p&gt;Subtitle: &amp;ldquo;Lessons Learned from Programming Over Time&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;This book is fantastic. It goes over all software engineering disciplines and touches on testing, documentation, CI, deployment and much more.&lt;/p&gt;
&lt;p&gt;It is similar to the Pragmatic Programmer because it focuses on general engineering advice. But it is less concerned with individuals and more with the teams and maintainability of software at scale. I appreciated the number of anecdotes (case studies), which made some of the advice more concrete and actionable.&lt;/p&gt;
&lt;p&gt;It took me three and a half months to read this book. I made roughly 40 permanent notes to my &lt;a href=&#34;https://blog.viktomas.com/posts/slip-box/&#34;&gt;Zettlekasten notes&lt;/a&gt;. Even though most of the concepts weren&amp;rsquo;t foreign to me, the authors (Titus Winters, Tom Manshreck, Hyrum Wright) described them much clearer, and I understood them better after reading this book.&lt;/p&gt;
&lt;p&gt;Reading this book gives an overview of engineering on a relatively high level without too many code examples. If you expect to improve your programming, I recommend books like Clean code and Refactoring. This book will teach you better engineering practices, not better programming.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>J.L. Collins - The simple path to wealth</title>
      <link>https://blog.viktomas.com/books/collins-jl--the-simple-path-to-wealth/</link>
      <pubDate>Wed, 14 Apr 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/collins-jl--the-simple-path-to-wealth/</guid>
      <description>&lt;p&gt;Find out how to retire early and think about investing no more than a few hours a year. This book offers a truly simple method for becoming financially independent.&lt;/p&gt;
&lt;p&gt;J.L. Collins&amp;rsquo; method fits in one sentence: &amp;ldquo;Learn to live way under your means and invest all your excess money into all market Vanguard indexed fund&amp;rdquo;. It sounds to be too good to be true.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not saying it is too good to be true, only that it sounds that way. If you invest tens of thousands of dollars a year, you want a complex and sophisticated method. The author says that investors are their own worst enemies: they overcomplicate their investment, try to pick the winning stock, and try to time the market. I&amp;rsquo;m guilty of all those things. After a few years of investing, I see that the author&amp;rsquo;s advice is the only one I need. I&amp;rsquo;ve tried to time the market and pick an individual stock. Luckily&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, I&amp;rsquo;ve always lost money on it.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve read the Random Walk Down Wall Street from Burton Malkiel (the 2019 edition), and so I knew the concepts behind index funds, but I&amp;rsquo;ve learnt a few new things:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Dollar-cost averaging is a bad idea. Historically, only one in four years the market drops. if you are trying to invest a big sum of money over time (say a year), you have a 75% chance you will be losing money. &lt;em&gt;(this is a very brief summary, have a look into the book for detailed explanation)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Buying your property is most likely not an investment but a splurge. Run the numbers. Don&amp;rsquo;t assume it&amp;rsquo;s always a good investment.&lt;/li&gt;
&lt;li&gt;If you can spend only 4% of your portfolio in a year, you are financially independent (you can live from your portfolio). The book mentions a study that was averaging a large amount of investing scenarios. A 4% yearly withdrawal from the investment was enough to keep the portfolio at least the same size over time in most of the scenarios.&lt;/li&gt;
&lt;li&gt;I&amp;rsquo;ve always worried about the future of indexed funds. Are the markets still going to be efficient if the majority of the capital is passive? J.L. Collins guesses that when there&amp;rsquo;s most of the capital in indexed funds, there will be more gains from active investing, which will motivate more investors into active trading. The markets are going to balance themselves again.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you don&amp;rsquo;t have time to read the whole book, watch this &lt;a href=&#34;https://www.youtube.com/watch?v=T71ibcZAX3I&#34;&gt;interview with J.L. Collins&lt;/a&gt;. I wholeheartedly recommend reading this fantastic book.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Luckily, because it allowed me to fool-proof my investment strategy early.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>CSS Week 3 - Display, Position, and Boxing-model</title>
      <link>https://blog.viktomas.com/posts/css-week-3-display-position-box/</link>
      <pubDate>Tue, 13 Apr 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/css-week-3-display-position-box/</guid>
      <description>&lt;p&gt;This was the most challenging section so far. Work and personal life intercepted my hour-a-day routine, and it took me three weeks to squeeze in the seven hours of learning. Also, this module&amp;rsquo;s boundaries weren&amp;rsquo;t clearly defined, which made me waste time branching out into unrelated topics.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 600px&#34; src=&#34;https://blog.viktomas.com/images/posts/css-week-3-display-position-box.jpg&#34; alt=&#34;Normal flow with boxes&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Normal flow with boxes&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;my-process&#34;&gt;My process&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ll change the format of the previous weeks and start with the process. Vaguely defined boundaries of the module, no dedicated learning time, and lack of video courses for this week&amp;rsquo;s topic stretched the learning to three weeks.&lt;/p&gt;
&lt;p&gt;The biggest problem this week was that I wasn&amp;rsquo;t clear about my learning goal and when will I consider my study finished. By definition, I don&amp;rsquo;t know what I need to learn before I start learning it.&lt;/p&gt;
&lt;h3 id=&#34;change-1-clear-boundaries&#34;&gt;Change 1: Clear boundaries&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;m going to spend the first hour of the week getting an overview of the topic and gathering a list of resources I want to learn from. I&amp;rsquo;ll order them by priority, and I&amp;rsquo;ll spend the next six hours going through them in the preselected order.&lt;/p&gt;
&lt;h3 id=&#34;change-2-notes&#34;&gt;Change 2: Notes&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ll make notes. I didn&amp;rsquo;t make many notes so far since I thought that I could always open MDN and read the documentation, but I noticed that I started forgetting what I learned. I&amp;rsquo;ll start making digital notes about the topics I&amp;rsquo;ve learned.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t practice much of what I&amp;rsquo;ve learnt. I thought about including some practice time (e.g. tweaking this blog) in my study, but I don&amp;rsquo;t have enough time in the tight schedule.&lt;/p&gt;
&lt;h2 id=&#34;what-did-i-know&#34;&gt;What did I know&lt;/h2&gt;
&lt;p&gt;I knew that you could position elements absolutely. I knew a few display properties, including flex and grid, which I learned about the last week. I knew how padding and margin work for block elements, including the margin collapsing.&lt;/p&gt;
&lt;h2 id=&#34;what-did-i-learn&#34;&gt;What did I learn&lt;/h2&gt;
&lt;p&gt;The most valuable thing I learned about this week was &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Normal_Flow&#34;&gt;Normal Flow&lt;/a&gt;. That&amp;rsquo;s how elements get positioned on the page if you don&amp;rsquo;t change a layout or position. The &lt;code&gt;block&lt;/code&gt; and &lt;code&gt;inline&lt;/code&gt; &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/The_box_model#block_and_inline_boxes&#34;&gt;element behaviour make the best sense in normal flow&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I vaguely remembered that people used &lt;code&gt;display: float&lt;/code&gt; for layouts. Now I know that the only reason to use &lt;code&gt;float&lt;/code&gt; is to make text flow around a block element on the page (e.g. image or aside). Modern layout methods completely removed the need for &lt;code&gt;float&lt;/code&gt;s.&lt;/p&gt;
&lt;p&gt;Position in CSS seems to be simpler than I thought as well. All elements have &lt;code&gt;static&lt;/code&gt; position by default, which means the elements are positioned exactly where the layout puts them. You can offset the element using the &lt;code&gt;relative&lt;/code&gt; position or take it out of the flow completely with &lt;code&gt;fixed&lt;/code&gt; and &lt;code&gt;absolute&lt;/code&gt;. And then there&amp;rsquo;s &lt;code&gt;sticky&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Lastly, I&amp;rsquo;ve learned about the &lt;code&gt;overflow&lt;/code&gt; and &lt;code&gt;min/max-width/height&lt;/code&gt;. Interesting about min/max dimensions is that max gets ignored if it&amp;rsquo;s smaller than min, and the actual dimension is ignored if it&amp;rsquo;s not within the min-max range. There is a &lt;a href=&#34;https://ishadeed.com/article/min-max-css/&#34;&gt;great explanation&lt;/a&gt; from Ahmad Shadeed.&lt;/p&gt;
&lt;h3 id=&#34;resources-for-learning&#34;&gt;Resources for learning&lt;/h3&gt;
&lt;p&gt;I found a fantastic video on the MDN site titled: &lt;a href=&#34;https://www.youtube.com/watch?v=aHUtMbJw8iA&#34;&gt;&amp;ldquo;Why Is CSS So Weird?&amp;rdquo;&lt;/a&gt; made by Miriam Suzanne. It&amp;rsquo;s 15 minutes long, and it&amp;rsquo;s the best overview I&amp;rsquo;ve ever seen. It explains the motivation for creating CSS and why it&amp;rsquo;s so much different from styling printed documents.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Learn/CSS/CSS_layout/Introduction&#34;&gt;Introduction to CSS layout - MDN&lt;/a&gt; - this is the best place to start and regularly return back to as you learn about normal flow, flexbox and grid&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://ishadeed.com/article/min-max-css/&#34;&gt;Min and Max Width/Height in CSS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/CSS/Containing_block#identifying_the_containing_block&#34;&gt;Identifying the containing block when positioning elements - MDN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/The_box_model&#34;&gt;The box model - MDN&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Learn/CSS/Building_blocks/Overflowing_content&#34;&gt;Overflowing content - MDN&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>George S. Clason - The Richest Man in Babylon</title>
      <link>https://blog.viktomas.com/books/clason-george--richest-man-in-babylon/</link>
      <pubDate>Sat, 10 Apr 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/clason-george--richest-man-in-babylon/</guid>
      <description>&lt;p&gt;This short book is a good introduction to the world of personal finance. First released in 1926, it predates modern stock markets and cryptocurrencies, but its truths are no less valid.&lt;/p&gt;
&lt;p&gt;The book contains several stories placed in ancient Babylon. Each is presenting one or more morals related to saving money. I listened to the audiobook, which lasted four hours, just an hour longer than a Joe Rogan podcast.&lt;/p&gt;
&lt;p&gt;The book&amp;rsquo;s personal finance advice is solid and worth the read, but I wonder whether the &amp;ldquo;biblical&amp;rdquo; language used throughout the book can deter a young audience. If I haven&amp;rsquo;t had an experience with investing, it would be easy to ignore the book&amp;rsquo;s advice as something that&amp;rsquo;s hundreds of years old and without consequence in the modern world.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Surely thou canst get hold of a few coppers and a piece of silver to repay the generosity of an old friend of thy father who aided thee whenst thou wast in need?&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Overall, the book was fun to listen to. It was a bit one-sided: all the characters and narrator cared about was gold, but if you write a book with under a hundred pages, there&amp;rsquo;s no space for nuanced life advice.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Blake Crouch - Recursion</title>
      <link>https://blog.viktomas.com/books/crouch-blake--recursion/</link>
      <pubDate>Tue, 06 Apr 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/crouch-blake--recursion/</guid>
      <description>&lt;!-- I tried to roughly follow a guide to write a better review: https://www.grammarly.com/blog/how-to-write-book-review/ --&gt;
&lt;p&gt;I found this book because it was &lt;a href=&#34;https://www.goodreads.com/choiceawards/best-books-2019&#34;&gt;voted the best Sci-Fi book of 2019 on Goodreads&lt;/a&gt;. After reading it, I agree with the vote.&lt;/p&gt;
&lt;p&gt;The book describes a New York city struck by a false memory syndrome: people have memories from lives that didn&amp;rsquo;t happen. The story&amp;rsquo;s main protagonists are Helena, a scientist specializing in memory research and Barry, NYPD detective. As you read their story, you&amp;rsquo;ll understand increasingly more about the mysterious mass memory issue.&lt;/p&gt;
&lt;p&gt;The author did a great job of keeping suspense throughout the book and presenting the reader with information that they don&amp;rsquo;t yet understand but will cause an &amp;ldquo;aha&amp;rdquo; moment later.&lt;/p&gt;
&lt;p&gt;I particularly enjoyed the food-for-thought material in the book. Pondering the question: &amp;ldquo;What is memory?&amp;rdquo; and later on in the book: &amp;ldquo;What is life and how to live a good one?&amp;rdquo;. Similarly to the &lt;a href=&#34;https://blog.viktomas.com/books/burke-sue-semiosis/&#34;&gt;Semiosis&lt;/a&gt;, I kept thinking about the story long after reading it.&lt;/p&gt;
&lt;details&gt;
&lt;summary&gt;Spoiler section&lt;/summary&gt;
&lt;p&gt;After the story evolved and I understood that the whole book is one big &lt;a href=&#34;https://en.wikipedia.org/wiki/Groundhog_Day_(film)&#34;&gt;Groundhog Day&lt;/a&gt; it made me think about how I live my life. How every day is precious, and I shouldn&amp;rsquo;t waste it. The sections where Berry and Helena relive their lives to spend more time with their sick family members motivated me to see my family.&lt;/p&gt;
&lt;p&gt;I know that these &amp;ldquo;motivational&amp;rdquo; effects don&amp;rsquo;t last long, and I&amp;rsquo;ll forget them quickly, but it was a good motivation non-the-less.&lt;/p&gt;
&lt;/details&gt;
</description>
    </item>
    
    <item>
      <title>CSS Week 2 - Grid and Flexbox</title>
      <link>https://blog.viktomas.com/posts/css-week-2-grid-flexbox/</link>
      <pubDate>Mon, 22 Mar 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/css-week-2-grid-flexbox/</guid>
      <description>&lt;p&gt;This is another episode of my CSS learning challenge. If you&amp;rsquo;d like to know how this all started, you can read the &lt;a href=&#34;https://blog.viktomas.com/posts/learning-css-in-two-months-week-0&#34;&gt;introduction post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Last week was fun. Both the Grid and Flexbox are newer CSS features and remove many pain points with positioning elements on the page. Unlike the &lt;a href=&#34;https://blog.viktomas.com/posts/learning-css-in-two-months-week-1&#34;&gt;last week&amp;rsquo;s selectors&lt;/a&gt;, I could see a practical use for almost every piece of information that I&amp;rsquo;ve learned.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 600px&#34; src=&#34;https://blog.viktomas.com/images/posts/css-week-2-grid-flexbox/flexgrid.jpg&#34; alt=&#34;Flexbox and Grid&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Flexbox and Grid&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;what-did-i-know&#34;&gt;What did I know&lt;/h2&gt;
&lt;p&gt;I knew that &lt;code&gt;display: flex&lt;/code&gt; often solved my positioning problems. If an element didn&amp;rsquo;t align, I set &lt;code&gt;display: flex&lt;/code&gt; on the parent element and voilà, problem solved. Apart from knowing that Flexbox is a bit more predictable than &lt;code&gt;display: block&lt;/code&gt;, I didn&amp;rsquo;t know much.&lt;/p&gt;
&lt;h2 id=&#34;what-did-i-learn&#34;&gt;What did I learn&lt;/h2&gt;
&lt;p&gt;Flexbox is a surprisingly old standard. In my mind, Flexbox was still at the cutting edge of browser technology, but Chrome fully supports it since 2012 and Firefox since 2014&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. Flexbox was the first CSS feature that provided complete control over box-alignment without hacks. This control has been since lifted into it&amp;rsquo;s &lt;a href=&#34;https://drafts.csswg.org/css-align/&#34;&gt;own specification&lt;/a&gt;, and it&amp;rsquo;s also used by the CSS Grid&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;div class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 400px&#34; src=&#34;https://blog.viktomas.com/images/posts/css-week-2-grid-flexbox/flexbox.jpg&#34; alt=&#34;/images/posts/css-week-2-grid-flexbox/flexbox.jpg&#34; /&gt;

&lt;p&gt;&lt;em&gt;Flexbox aligns items in one dimension&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;Grid is a more recent standard. Chrome and Firefox fully support it since 2017. Using &lt;code&gt;gap&lt;/code&gt; instead of &lt;code&gt;grid-gap&lt;/code&gt; to set the spacing between tracks (items) is supported since 2018. The important thing is that the evergreen browsers fully support the CSS Grid Layout.&lt;/p&gt;
&lt;p&gt;Grid is meant for two-dimensional positioning (i.e. you need both rows and columns to align), for example, creating the site layout or splitting your image gallery into two columns. You can use Flexbox for a two-dimensional layout as well (and it has been in Bootstrap 4), but it&amp;rsquo;s main purpose and power is a one-dimensional layout (row or column)&lt;sup id=&#34;fnref1:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;. For example, Flexbox would be suitable for Trello-like columns, where you want to align the cards into columns, but you don&amp;rsquo;t need them aligned in rows.&lt;/p&gt;
&lt;div class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 400px&#34; src=&#34;https://blog.viktomas.com/images/posts/css-week-2-grid-flexbox/grid.jpg&#34; alt=&#34;/images/posts/css-week-2-grid-flexbox/grid.jpg&#34; /&gt;

&lt;p&gt;&lt;em&gt;Grid aligns items in two dimensions&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;blockquote&gt;
&lt;ul&gt;
&lt;li&gt;do I only need to control the layout by row or column – use a flexbox&lt;sup id=&#34;fnref2:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;do I need to control the layout by row and column – use a grid&lt;sup id=&#34;fnref3:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;p&gt;I also completely removed Bootstrap 4 from this blog and used CSS Grid and Flexbox instead. It wasn&amp;rsquo;t as easy as the online courses and web resources suggested. It took me two afternoons.&lt;/p&gt;
&lt;h3 id=&#34;resources-for-learning&#34;&gt;Resources for learning&lt;/h3&gt;
&lt;p&gt;I&amp;rsquo;ve listened to both FrontendMasters courses on the topic: &lt;a href=&#34;https://frontendmasters.com/courses/css-grids-flexbox/&#34;&gt;CSS Grids and Flexbox for Responsive Web Design&lt;/a&gt; and &lt;a href=&#34;https://frontendmasters.com/courses/css-in-depth-v2/&#34;&gt;CSS In-Depth, v2&lt;/a&gt;. If you don&amp;rsquo;t have access to FrontendMasters don&amp;rsquo;t despair, you can get the same information from MDN, but you&amp;rsquo;ll have to put in more work because you won&amp;rsquo;t get spoon-fed the information from video courses. Follow this &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Basic_Concepts_of_Grid_Layout&#34;&gt;MDN guide on Grid layouts&lt;/a&gt; - it&amp;rsquo;s concise and clear.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Basic_Concepts_of_Grid_Layout&#34;&gt;Basic Concepts of grid layout - CSS: Cascading Style Sheets - MDN&lt;/a&gt; - Easy to digest guide explaining grid layouts.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;http://cssgridgarden.com/&#34;&gt;Grid garden&lt;/a&gt; - Fun game with 28 levels where you position water and poison to water plants and kill weeds.&lt;/li&gt;
&lt;li&gt;FrontendMasters
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://frontendmasters.com/courses/css-grids-flexbox/&#34;&gt;CSS Grids and Flexbox for Responsive Web Design from Jen Kramer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://frontendmasters.com/courses/css-in-depth-v2/&#34;&gt;CSS In-Depth, v2 from Estelle Weyl&lt;/a&gt; - the interactive slides are publicly available at &lt;a href=&#34;https://estelle.github.io/&#34;&gt;her GitHub&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;references&#34;&gt;References&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://css-tricks.com/snippets/css/complete-guide-grid/#fr-unit&#34;&gt;A Complete Guide to Grid - CSS-Tricks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://css-tricks.com/snippets/css/a-guide-to-flexbox/&#34;&gt;A Complete Guide to Flexbox - CSS-Tricks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://tympanus.net/codrops/css_reference/grid/&#34;&gt;A Complete Guide to CSS Grid - Codrops CSS Reference&lt;/a&gt; - much more extensive than it&amp;rsquo;s CSS-Tricks alternative&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;what-i-didnt-learn&#34;&gt;What I didn&amp;rsquo;t learn&lt;/h2&gt;
&lt;p&gt;What I&amp;rsquo;ve learnt this week has been immediately applicable, unlike &lt;a href=&#34;https://blog.viktomas.com/posts/learning-css-in-two-months-week-1&#34;&gt;last week&lt;/a&gt;. However, I still struggled when I tried to apply the knowledge for styling this blog. I understand the concepts well, and if I have a fixed, FullHD screen, I can create a grid with no problem. But I didn&amp;rsquo;t learn enough about the &amp;ldquo;responsive&amp;rdquo; part. Making the design responsive, I still create a few breakpoints and change the grid layout based on the breakpoint. Is that the best? I don&amp;rsquo;t know. I hoped that I wouldn&amp;rsquo;t have to use as many media queries after learning these cool new features.&lt;/p&gt;
&lt;h2 id=&#34;my-process&#34;&gt;My process&lt;/h2&gt;
&lt;p&gt;One week is a short time to learn two CSS standards, but at the same time, I need to keep this pace to get a complete overview in two months. After I know a bit of everything, I can go back and dive deeper.&lt;/p&gt;
&lt;p&gt;Next up: Display, position and box alignment&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://caniuse.com/?search=flexbox&#34;&gt;Caniuse flexbox&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Grid_Layout/Relationship_of_Grid_Layout&#34;&gt;Relationship of grid layout to other layout methods - CSS: Cascading Style Sheets | MDN&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref1:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref2:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref3:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>CSS Week 1 - Selectors</title>
      <link>https://blog.viktomas.com/posts/learning-css-in-two-months-week-1/</link>
      <pubDate>Sun, 14 Mar 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/learning-css-in-two-months-week-1/</guid>
      <description>&lt;p&gt;This is another episode of my CSS learning challenge. If you&amp;rsquo;d like to know how this all started, you can read the &lt;a href=&#34;https://blog.viktomas.com/posts/learning-css-in-two-months-week-0&#34;&gt;introduction post&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This week, I&amp;rsquo;ve spent roughly an hour each day learning about CSS Selectors. I started with a &lt;a href=&#34;https://frontendmasters.com/courses/css-in-depth-v2/&#34;&gt;FrontendMasters CSS Course&lt;/a&gt; to get an overview of the topic (roughly three hours), and then I followed up with reading blog posts and &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors&#34;&gt;MDN documentation&lt;/a&gt;.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 550px&#34; src=&#34;https://blog.viktomas.com/images/posts/learning-css-in-two-months-week-1.jpg&#34; alt=&#34;I choose you &lt;div&gt;&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;I choose you &lt;div&gt;&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;what-did-i-know&#34;&gt;What did I know&lt;/h2&gt;
&lt;p&gt;I knew that you could select by element, class, and id. I knew that the specificity increased in that order. I also knew that you could combine the selectors with space or &lt;code&gt;&amp;gt;&lt;/code&gt;, increasing specificity. I knew some pseudo-class selectors, even though I wouldn&amp;rsquo;t be able to call them that. And of course, I knew the nuke of selector specificity &lt;code&gt;!important&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Selectors I was able to create and understand well:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;div.danger&lt;/code&gt;, &lt;code&gt;ul &amp;gt; li&lt;/code&gt;, &lt;code&gt;.container h1&lt;/code&gt;, &lt;code&gt;.content p:first-child&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;what-did-i-learn&#34;&gt;What did I learn&lt;/h2&gt;
&lt;p&gt;CSS selectors are designed to style the markup without programmatically adding a &lt;code&gt;class&lt;/code&gt; attribute on every element we are interested in. This insight wasn&amp;rsquo;t quite apparent to me. And it also goes directly against the school of thought represented by &lt;a href=&#34;https://tailwindcss.com/&#34;&gt;Tailwind CSS&lt;/a&gt; where you only add classes and never custom CSS.&lt;/p&gt;
&lt;p&gt;I learned about &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/CSS/Attribute_selectors&#34;&gt;attribute selectors&lt;/a&gt;. I knew only vaguely that they exist, but now I know what they are and how to use them.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;input[type=checkbox]&lt;/code&gt; Matching input type is the most common use for exact attribute match.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;a[href$=.pdf]&lt;/code&gt; You can style all links that will open a PDF (to warn the user that it&amp;rsquo;s not a web page).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Also, there is some funky behaviour around case-sensitivity. HTML attributes like &lt;code&gt;class&lt;/code&gt; and &lt;code&gt;type&lt;/code&gt; are case insensitive, but the case must exactly match for custom attributes.&lt;/p&gt;
&lt;p&gt;The pseudo-selectors (&lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-classes&#34;&gt;classes&lt;/a&gt; and &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/CSS/Pseudo-elements&#34;&gt;elements&lt;/a&gt;)  dynamically select elements. You can&amp;rsquo;t select these parts of markup with the simpler &lt;code&gt;element&lt;/code&gt; selectors and their combinators. You can select &amp;ldquo;first paragraph in the body&amp;rdquo; or &amp;ldquo;every odd row of a table&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;I finally understand &lt;code&gt;::before&lt;/code&gt; and &lt;code&gt;::after&lt;/code&gt;. &lt;a href=&#34;https://estelle.github.io/CSS/generated/#slide3&#34;&gt;This slide&lt;/a&gt; from Estelle Weyl explains it the best. Basically, the &lt;code&gt;::before&lt;/code&gt; and &lt;code&gt;::after&lt;/code&gt; pseudo elements are created &lt;strong&gt;within&lt;/strong&gt; the selected element (e.g. inside a &lt;code&gt;&amp;lt;p&amp;gt;&lt;/code&gt; tag).&lt;/p&gt;
&lt;h2 id=&#34;what-i-didnt-learn&#34;&gt;What I didn&amp;rsquo;t learn&lt;/h2&gt;
&lt;p&gt;My learning still feels like trying to piece together hundreds of small and often unrelated pieces of the CSS specification. Most of the articles, the CSS course and MDN documentation are all missing real-world examples. They only show small isolated exercises to explain a single property. I now understand &lt;code&gt;:last-of-type&lt;/code&gt;, but what are the most common usages when writing production websites? Is it even important? Do engineers use it every day, every week or twice a year to solve some specific use-case?&lt;/p&gt;
&lt;h2 id=&#34;my-process&#34;&gt;My process&lt;/h2&gt;
&lt;p&gt;I made the mistake of trying to learn too many selectors. The kind of insight I&amp;rsquo;m looking for is: &amp;ldquo;Selectors are used to styling elements without adding too many &lt;code&gt;class&lt;/code&gt; and &lt;code&gt;id&lt;/code&gt; attributes. Out of the more obscure selectors like pseudo-element selectors, these two [fill in the blank] are the most useful because they help in these widespread scenarios [fill in the blank].&amp;rdquo;&lt;/p&gt;
&lt;p&gt;I have an advantage that I should use. I have seen countless CSS files in the last decade. That means I should be able to judge whether a certain syntax is commonly used. Instead of focusing on the full breadth of specification, I should get a broad overview of the topic within the first two or three days and then try to distil the core concepts and maybe one or two useful edge-cases.&lt;/p&gt;
&lt;p&gt;Next up: Flexbox and Grid. This is bound to be fun.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Learning CSS in two months</title>
      <link>https://blog.viktomas.com/posts/learning-css-in-two-months-week-0/</link>
      <pubDate>Sun, 07 Mar 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/learning-css-in-two-months-week-0/</guid>
      <description>&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; To improve my shallow knowledge of CSS, I&amp;rsquo;m going to learn CSS for roughly eight hours each week for eight weeks. Once a week I&amp;rsquo;ll write a report about what I&amp;rsquo;ve learnt. In the end, I expect to be able to predict how CSS change affects the page. This article is for engineers interested in improving their CSS skills.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 650px&#34; src=&#34;https://blog.viktomas.com/images/posts/learning-css-in-two-months-week-0/backend-fullstack-frontend.jpg&#34; alt=&#34;Backend to Frontend&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Backend to Frontend&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I want to position an SVG image in line with a text. I&amp;rsquo;ll place &lt;code&gt;img&lt;/code&gt; and &lt;code&gt;p&lt;/code&gt; tags in my markup, and both elements align to the top of the container. I open web search&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, type in &amp;ldquo;CSS image with text vertical center&amp;rdquo;. Scroll for a good looking StackOverflow answer and copy-paste the CSS snippet. If it doesn&amp;rsquo;t work, I&amp;rsquo;ll repeat the process with a bit different search term.&lt;/p&gt;

&lt;div class=&#34;mermaid&#34; align=&#34;center&#34;&gt;graph LR;
A[search for a solution] --&gt; B[select a good looking answer]
B --&gt; C[Paste the answer in my code]
C --&gt; D[&#34;Does it work?&#34;]
D --yes--&gt; E[Profit]
D --no--&gt;A&lt;/div&gt;
&lt;p&gt;Frontend development has been part of my engineering responsibilities for close to a decade. And the chart above explains my go-to development process. On the Dreyfus model&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, I got stuck as an advanced beginner. That means I can follow instructions, but I lack an understanding of the underlying principles.&lt;/p&gt;
&lt;p&gt;Over the years, I&amp;rsquo;ve come up with many excuses for not learning CSS well:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I&amp;rsquo;m not artistic. I have a very binary understanding of design: Does it look good or not?&lt;/li&gt;
&lt;li&gt;UI is not an exact science. You can&amp;rsquo;t write unit-tests for how easy it is to use.&lt;/li&gt;
&lt;li&gt;I told myself the HTML/CSS part of software engineering is not as valuable as the backend or backend-of-the-frontend work. I blame it on being surrounded by backend engineers for the first several years of my career.&lt;/li&gt;
&lt;li&gt;The longevity of the frontend code is in orders of magnitude shorter than the backend. UI design and frontend technologies are changing too often.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;These excuses have one thing in common, an implicit assumption that it&amp;rsquo;s either/or. Zero sum. If I learn CSS, it will push out what I know about databases. If I learn UI design principles, somehow, it&amp;rsquo;ll incinerate my algorithm knowledge.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 450px&#34; src=&#34;https://blog.viktomas.com/images/posts/learning-css-in-two-months-week-0/backend.jpg&#34; alt=&#34;Backend&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Backend&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;It&amp;rsquo;s time to test that assumption. I&amp;rsquo;m finally going to learn about CSS and UI design. And if that pushes some important backend knowledge out of my head, I&amp;rsquo;ll serve as both warning and validation for all the devs who resist learning CSS.&lt;/p&gt;
&lt;h2 id=&#34;benefits-of-knowing-css-well&#34;&gt;Benefits of knowing CSS well&lt;/h2&gt;
&lt;p&gt;But why would I want to change the situation? Shouldn&amp;rsquo;t I stay happily oblivious to the mysteries of fronted craft?&lt;/p&gt;
&lt;p&gt;My two primary motivators are a feeling of competence and being able to express my ideas better.&lt;/p&gt;
&lt;p&gt;The feeling of competence comes from being able to predict the outcome based on the action. E.g. I&amp;rsquo;ll change the &lt;code&gt;display&lt;/code&gt; property from &lt;code&gt;inline&lt;/code&gt; to &lt;code&gt;block&lt;/code&gt;, and I&amp;rsquo;ll be able to predict the result even before the browser renders it.&lt;/p&gt;
&lt;p&gt;I had an improved competence experience recently with TypeScript. I finished &lt;a href=&#34;https://blog.viktomas.com/books/vanderkam-dan--effective-typescript/&#34;&gt;Effective Typescript&lt;/a&gt;. After reading the book, I understand most of the type error messages, and I can fix them without trial and error or online searching.&lt;/p&gt;
&lt;p&gt;CSS is a part of my job, and it&amp;rsquo;s here to stay. I might as well feel competent at it. Learning it will also save me a lot of time by avoiding the trial and error process mentioned earlier.&lt;/p&gt;
&lt;p&gt;The second and equally important motivator is to be able to express my thoughts better. Being able to build design prototypes quickly will allow me to sketch out frontends for my ideas. I&amp;rsquo;ve been using Bootstrap, but I couldn&amp;rsquo;t customise it without losing too much time.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 450px&#34; src=&#34;https://blog.viktomas.com/images/posts/learning-css-in-two-months-week-0/fullstack.jpg&#34; alt=&#34;Fullstack&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Fullstack&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;the-process&#34;&gt;The process&lt;/h2&gt;
&lt;p&gt;My brain works the best in the morning, so I plan on spending the first hour of each workday learning CSS. On the weekends, I&amp;rsquo;m going to spend three hours each day making &lt;a href=&#34;https://blog.viktomas.com/posts/slip-box/&#34;&gt;notes&lt;/a&gt; and summarising what I&amp;rsquo;ve learnt into a short article.&lt;/p&gt;
&lt;h2 id=&#34;the-curriculum&#34;&gt;The curriculum&lt;/h2&gt;
&lt;p&gt;My CSS challenge takes two months. I&amp;rsquo;ve already spent a week preparing a plan and writing this article, so I&amp;rsquo;m going to split the remainder of the two months into eight weeks:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/learning-css-in-two-months-week-1&#34;&gt;selectors: element, class, id, specificity, pseudo selectors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/css-week-2-grid-flexbox&#34;&gt;flex, grid, responsive design&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/css-week-3-display-position-box&#34;&gt;display, position and box alignment&lt;/a&gt; (plus box-sizing, margin, padding, overflow, max/min-width)&lt;/li&gt;
&lt;li&gt;inheritance: what properties are getting inherited, how is inheritance used when designing the page, rem, em&lt;/li&gt;
&lt;li&gt;CSS pre and post processing (SASS, PostCSS)&lt;/li&gt;
&lt;li&gt;design basics (colors, composition)&lt;/li&gt;
&lt;li&gt;typography - fonts, how are they loaded, what font combinations should I use, strong, emphasis, webfonts&lt;/li&gt;
&lt;li&gt;accessibility (this might be a very HTML-oriented topic)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I&amp;rsquo;m omitting any CSS animation for lack of time.&lt;/p&gt;
&lt;p&gt;After finishing my two-months challenge, I will come back and edit the list to be the most accurate for other full-stack devs.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 450px&#34; src=&#34;https://blog.viktomas.com/images/posts/learning-css-in-two-months-week-0/frontend.jpg&#34; alt=&#34;Frontend&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Frontend&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h3 id=&#34;learning-materials&#34;&gt;Learning materials&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://about.gitlab.com/handbook/people-group/learning-and-development/&#34;&gt;GitLab paid&lt;/a&gt; for my &lt;a href=&#34;https://frontendmasters.com&#34;&gt;FrontendMasters&lt;/a&gt; account, which is going to be the primary source of overview information. I also considered &lt;a href=&#34;https://openlibrary.org/works/OL17549103W/Head_First_Html_And_Css?edition=headfirsthtmlcss00robs&#34;&gt;Head-First HTML and CSS&lt;/a&gt;, but it might not provide me with information fast enough since it&amp;rsquo;s very beginner-oriented.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ll use MDN for documentation, and I&amp;rsquo;ll link any other articles/materials relevant to the particular week in the week&amp;rsquo;s report.&lt;/p&gt;
&lt;h2 id=&#34;lets-start&#34;&gt;Let&amp;rsquo;s start&lt;/h2&gt;
&lt;p&gt;Tomorrow is the first day of the rest of my frontend engineering career. I&amp;rsquo;m incredibly excited about this experiment. Starting with the boxing model, I&amp;rsquo;m going to take on the CSS world.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;DuckDuckGo.com&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Dreyfus_model_of_skill_acquisition&#34;&gt;Dreyfus model of skill acquisition - Wikipedia&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Dan Vanderkam - Effective TypeScript</title>
      <link>https://blog.viktomas.com/books/vanderkam-dan--effective-typescript/</link>
      <pubDate>Fri, 05 Mar 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/vanderkam-dan--effective-typescript/</guid>
      <description>&lt;p&gt;When I started my programming career as a Java developer, my boss recommended that I read Effective Java. Even though I had a few semesters of Java programming behind my belt, I had a very superficial knowledge of the language till I read Effective Java.&lt;/p&gt;
&lt;p&gt;Now I have a similar experience with Vanderkam&amp;rsquo;s book. I&amp;rsquo;ve been programming in TypeScript for half a year, but I still didn&amp;rsquo;t understand many language concepts. After reading the book, I can debug type errors quickly, and I can write code with fewer type annotations, relying heavily on type inference.&lt;/p&gt;
&lt;p&gt;The book contains sixty-two short sections called &amp;ldquo;items&amp;rdquo;. You can read a couple a day, and you&amp;rsquo;ll still finish it in a month. It&amp;rsquo;s also good to read only a few items per day, so the concepts can sink in and exercise them when you are programming.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>How to be less gullible</title>
      <link>https://blog.viktomas.com/posts/how-to-be-less-gullible/</link>
      <pubDate>Wed, 24 Feb 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/how-to-be-less-gullible/</guid>
      <description>&lt;p&gt;I trust people. I trust strangers, news on the internet, and books. 90% times, this is a good strategy, but 10% is still worth considering. This article will explain why people are more likely to trust than to distrust and, more importantly, how we can improve our critical thinking.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 450px&#34; src=&#34;https://blog.viktomas.com/images/posts/how-to-be-less-gullible.svg&#34; alt=&#34;Theme illustration&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Illustration&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I clearly remember a scene from America&amp;rsquo;s Got Talent. This sketchy magician&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; introduced himself and said he used to be Marilyn Manson&amp;rsquo;s roommate. I didn&amp;rsquo;t think about it twice; a guy on a TV said it; it&amp;rsquo;s probably true.&lt;/p&gt;
&lt;p&gt;After the performance, the mean judge said that Marilyn Manson is a millionaire who doesn&amp;rsquo;t need roommates. It was such an obvious conclusion, and I should have thought of that. I was gullible again!&lt;/p&gt;
&lt;p&gt;To me, this happens often. I assume people tell the truth without too much second-guessing. I think it&amp;rsquo;s happening for two reasons, upbringing and genetics.&lt;/p&gt;
&lt;h2 id=&#34;upbringing&#34;&gt;Upbringing&lt;/h2&gt;
&lt;p&gt;When growing up, my dad required obedience and honesty, above all else. The concept of lying wasn&amp;rsquo;t a part of my childhood; the same way swearing isn&amp;rsquo;t part of Christianity. I tried it a few times. Every attempt got severely punished. I ended up thinking, &amp;ldquo;When lying hurts this much, why would anyone do it&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m so far up on the honesty scale that when somebody pretends to throw a stick to a dog, but they hide it behind their back, I see that as lying, especially if they let the dog search for the stick for more than a few seconds.&lt;/p&gt;
&lt;p&gt;When I&amp;rsquo;m this conditioned to honesty, it&amp;rsquo;s easy to assume everyone else is too&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;. You judge others based on your own experience.&lt;/p&gt;
&lt;h2 id=&#34;genetics&#34;&gt;Genetics&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve read somewhere&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; that people are, on average, more trusting than not. Historically, people needed to collaborate. Trusting the other people by default was a more effective strategy, even if you got burned a few times. Imagine a group of trusting people fighting over resources with a group of people who don&amp;rsquo;t trust each other.&lt;/p&gt;
&lt;p&gt;There is a cost connected to critical thinking. Scepticism makes it harder to take in new information; you have to doubt it first. It also makes you less popular if you often contest what others say.&lt;/p&gt;
&lt;p&gt;However, critical thinking and scepticism are now more important than ever. Today your best friend can start a sentence with &amp;ldquo;I&amp;rsquo;ve read on Facebook that&amp;hellip;&amp;rdquo; and you need to have tools to deal with data of varying trustworthiness coming in.&lt;/p&gt;
&lt;h2 id=&#34;how-to-fight-the-gullibleness&#34;&gt;How to fight the gullibleness&lt;/h2&gt;
&lt;p&gt;Are you as gullible as I am? Way on the &amp;ldquo;trusting&amp;rdquo; side of the spectrum? We will probably never be as sceptical or as critical thinking as we&amp;rsquo;d like, but we can improve. Here are four ways how I&amp;rsquo;ve learnt to be more critical and how I make sure that my knowledge is based on truth as much as possible.&lt;/p&gt;
&lt;h3 id=&#34;put-your-information-on-paper&#34;&gt;Put your information on paper&lt;/h3&gt;
&lt;p&gt;The brain sucks at recognising conflicting information, especially when it receives it at different times. One week you read about carbohydrates being the energy for your brain. The next week you read about a low-carb diet significantly improving cognitive functions. Without putting this on paper, your brain is not likely to recognise the conflict.&lt;/p&gt;
&lt;p&gt;Note-taking like &lt;a href=&#34;https://blog.viktomas.com/posts/slip-box/&#34;&gt;Zettelkasten&lt;/a&gt; solves this issue by forcing you to integrate the new piece of information with your existing knowledge (notes). If there is a blatant conflict, you need to think about it and resolve it before putting in the new note.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/slip-box/&#34;&gt;Zettelkasten&lt;/a&gt; note-taking is a time-consuming activity, and it&amp;rsquo;s only worth doing for topics you are interested in. For topics that are not too attractive for you, there is the next option.&lt;/p&gt;
&lt;h3 id=&#34;say-i-dont-know-and-i-dont-care&#34;&gt;Say: I don&amp;rsquo;t know, and I don&amp;rsquo;t care&lt;/h3&gt;
&lt;p&gt;There is so much information in the world. It&amp;rsquo;s not your obligation to ingest it all and to have an opinion on it. When you hear people talking about the US policy in the middle east, it&amp;rsquo;s OK to zone out, tell them that you don&amp;rsquo;t know anything about it and that you don&amp;rsquo;t care.&lt;/p&gt;
&lt;p&gt;You don&amp;rsquo;t have to be an ass about it. You can think the &amp;ldquo;don&amp;rsquo;t care&amp;rdquo; part to yourself and politely say that you don&amp;rsquo;t know enough about the topic to comment on it.&lt;/p&gt;
&lt;p&gt;If you take only one thing from this article, it should be zoning out when your friends or media start talking about stuff you don&amp;rsquo;t understand. You reduce the risk of storing rubbish in your memory.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;World would be a more beautiful place if people said, &amp;ldquo;I don&amp;rsquo;t know.&amp;rdquo; more often.&lt;/strong&gt;&lt;/p&gt;
&lt;h3 id=&#34;seek-debates-with-opposite-opinions&#34;&gt;Seek debates with opposite opinions&lt;/h3&gt;
&lt;p&gt;This one is my favourite. Since I don&amp;rsquo;t naturally doubt new information, I can let someone else do it for me. When you watch two smart people arguing for and against a resolution, it&amp;rsquo;s much easier to make up your own opinion.&lt;/p&gt;
&lt;p&gt;The best sources of high quality, civil debates and discussions are &lt;a href=&#34;https://munkdebates.com/&#34;&gt;Munk Debates&lt;/a&gt; and &lt;a href=&#34;https://news.ycombinator.com/&#34;&gt;Comment sections on HackerNews&lt;/a&gt;. The latter is especially close to my heart because most of the participants are engineers and the technical language makes it easy for me to understand and relate.&lt;/p&gt;
&lt;h3 id=&#34;read-books&#34;&gt;Read books&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/reading-is-hard/&#34;&gt;Reading books is hard&lt;/a&gt;, but compared to other sources of information like YouTube or news, books are backed by more research and have a more wholesome take on a topic.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m mentioning reading books as last because it doesn&amp;rsquo;t actively support scepticism like the previous three methods. However, an in-depth understanding of a topic provides you with a better starting position to recognise someone not telling the truth.&lt;/p&gt;
&lt;p&gt;These days we need to be more critical about the information that comes our way. We can fight disinformation by making good quality notes, not caring about certain topics, listening to other smart people debating, and reading books on the topics we are interested in.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Rudy_Coby&#34;&gt;Rudy Coby - Wikipedia&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;I would lie if I insisted that I always speak the truth. No one does. I don&amp;rsquo;t lie too often, and I&amp;rsquo;m not good at it.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;For the love of me, I can&amp;rsquo;t find the source. If you know it, please share it at &lt;a href=&#34;mailto:me@viktomas.com&#34;&gt;me@viktomas.com&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Switching from Dropbox to Nextcloud</title>
      <link>https://blog.viktomas.com/posts/from-dropbox-to-nextcloud/</link>
      <pubDate>Sun, 31 Jan 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/from-dropbox-to-nextcloud/</guid>
      <description>&lt;p&gt;Instead of a new year&amp;rsquo;s resolution, I&amp;rsquo;ve done a new year&amp;rsquo;s cleaning in 2021. My Dropbox subscription is about to expire in early February, and I had to decide whether I want to keep paying $120 for Dropbox or try something new. And so the first month of the year became a period of digital cleansing.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 450px&#34; src=&#34;https://blog.viktomas.com/images/posts/from-dropbox-to-nextcloud.jpg&#34; alt=&#34;Theme illustration&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Illustration&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;my-history-with-dropbox&#34;&gt;My history with Dropbox&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve been a Dropbox user since uni, and for the last four years, I&amp;rsquo;ve been paying for Dropbox Plus. I still remember when I first installed it, back then on Windows 7. I couldn&amp;rsquo;t believe how seamless the experience felt. I think I read the Dropbox origin story in Lean Startup. The way Dropbox worked was so novel that the founders had to create a video to illustrate how is Dropbox going to work. Only words wouldn&amp;rsquo;t do because people couldn&amp;rsquo;t imagine the seamlessness in the time of FTP and Samba share.&lt;/p&gt;
&lt;p&gt;At that time, Dropbox was the synonym for innovation, &lt;a href=&#34;https://www.theverge.com/2015/12/8/9873268/why-dropbox-mailbox-shutdown&#34;&gt;Mailbox&lt;/a&gt;, &lt;a href=&#34;https://www.dropbox.com/paper&#34;&gt;Paper&lt;/a&gt;, I&amp;rsquo;ve used it all, and I loved it. But in recent years, I started noticing that I use a constant portion of the features. I want to&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Backup my files&lt;/li&gt;
&lt;li&gt;Access them from my Android phone&lt;/li&gt;
&lt;li&gt;Share the files with other people through links&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Share folders with friends and family&lt;/strong&gt; (giving them write access)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;dropbox-stopped-being-the-best-option-for-me&#34;&gt;Dropbox stopped being the best option for me&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s nice to have the time-machine feature for additional safety, but I&amp;rsquo;ve never used it. It is convenient to scan documents directly into dropbox, but now there are better apps for that. All in all, I want cloud storage that&amp;rsquo;s available from my phone, nothing fancy.&lt;/p&gt;
&lt;p&gt;I started noticing drawbacks that made me look for alternatives. Some of those drawbacks were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The Linux support is working, but it&amp;rsquo;s not all that great on Arch&lt;/li&gt;
&lt;li&gt;I  only used a small fraction of the 2TB that I was paying for (now I use 100GB)&lt;/li&gt;
&lt;li&gt;It was hard to share large folders with people who didn&amp;rsquo;t have paid Dropbox&lt;/li&gt;
&lt;li&gt;I&amp;rsquo;d prefer to have my data stored in the EU, rather than the US&lt;/li&gt;
&lt;li&gt;Dropbox is closed-source&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;hello-nextcloud&#34;&gt;Hello Nextcloud&lt;/h2&gt;
&lt;p&gt;When I looked at the alternatives, I found Nextcloud. Popular fork of ownCloud and fully open-source&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; cloud storage platform. Nextcloud doesn&amp;rsquo;t offer hosting for individual users, but other providers do thanks to the permissive license. With a bit of Reddit&amp;rsquo;s help&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, I found &lt;a href=&#34;https://www.hetzner.com/storage/storage-share&#34;&gt;Hetzner&lt;/a&gt; a German hosting provider that can spin up a NextCloud instance for you at a very reasonable price (5.8 EUR/month for 500GB). The benefit of Nextcloud over ownCloud is that there are no restricted features. You get the full feature set of the enterprise version in every Nextcloud deployment.&lt;/p&gt;
&lt;p&gt;Creating a new Hetzner account takes a few minutes and then a few more till your new Nextcloud installation starts. You get an email with your admin login, and you can start creating normal users. Creating multiple users was a fantastic change from Dropbox where you need to pay an extra $80/year for more users&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;. I immediately made an account for myself and my girlfriend.&lt;/p&gt;
&lt;p&gt;So far I&amp;rsquo;m happy with the move. The synchronising seems to be slower than with Dropbox. Nextcloud doesn&amp;rsquo;t hash the file binary content, and whatever else it does, it takes a long time to validate that my 100GB of data is fully synchronised. This situation improved when I removed a few git repositories and &lt;code&gt;node_modules&lt;/code&gt; folders, but I didn&amp;rsquo;t have to do that with Dropbox.&lt;/p&gt;
&lt;p&gt;I also must admit that I am a bit more hesitant to blindly trust the Hetzner data availability as much as I did to Dropbox. That means that I replicate the Nextcloud data to one of my external hard drives as well. That&amp;rsquo;s not a problem though because when I migrated all my data from Dropbox, I reduced the overall size to 20% by deleting some of the files that I thought I could go back to &amp;ldquo;someday&amp;rdquo;.&lt;/p&gt;
&lt;h2 id=&#34;whats-next&#34;&gt;What&amp;rsquo;s next&lt;/h2&gt;
&lt;p&gt;One of the exciting Nextcloud features is natively supported &lt;a href=&#34;https://nextcloud.com/endtoend/&#34;&gt;End to End encryption&lt;/a&gt;. So far, I&amp;rsquo;ve been using &lt;a href=&#34;https://cryptomator.org/&#34;&gt;Cryptomator&lt;/a&gt; to securely store some of my data like bank statements and scanned ids. But using Nextcloud directly will reduce complexity.&lt;/p&gt;
&lt;h2 id=&#34;should-you-use-nextcloud&#34;&gt;Should you use Nextcloud&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;m not planning on going back, but this move is surely not for everyone. If you don&amp;rsquo;t use Linux, don&amp;rsquo;t have a preference for open-source, use Windows or Mac and want your cloud data storage to &amp;ldquo;just work&amp;rdquo;, or you&amp;rsquo;ll use all the additional features Dropbox offers, then you are better off paying a bit extra and keep using Dropbox.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;APGPLv3 license&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.reddit.com/r/NextCloud/comments/fvedtj/is_hetzner_a_reliable_option_to_host_nextcloud/&#34;&gt;Is Hetzner a reliable option to host Nextcloud? : NextCloud&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;Dropbox Family with up to 6 users.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Randall Munroe - What if?: serious scientific answers to absurd hypothetical questions</title>
      <link>https://blog.viktomas.com/books/munroe-randall--what-if/</link>
      <pubDate>Fri, 29 Jan 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/munroe-randall--what-if/</guid>
      <description>&lt;p&gt;Same as in &lt;a href=&#34;https://blog.viktomas.com/books/munroe-randall--how-to/&#34;&gt;How to&lt;/a&gt;, it&amp;rsquo;s a pleasure to see Randall&amp;rsquo;s thought process when answering absurd but interesting physics questions. The following snippet from the book shows this well:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;A mole (the animal) is small enough for me to pick up and throw.[citation needed] Anything I can throw weighs 1 pound. One pound is 1 kilogram. The number 602,214,129,000,000,000,000,000 looks about twice as long as a trillion, which means it&amp;rsquo;s about a trillion trillion. I happen to remember that a trillion trillion kilograms is how much a planet weighs.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;In this spirit, you&amp;rsquo;ll learn what would happen if you: build a wall looking like the periodic table where each brick is made out of the corresponding element, use a machine gun as a jetpack, lost all your DNA in a split second.&lt;/p&gt;
&lt;p&gt;The book both entertained me and thought me more about physics. Randall&amp;rsquo;s books are the perfect material from which we can teach children that physics is fun.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Terry Pratchett - Snuff</title>
      <link>https://blog.viktomas.com/books/pratchett-terry--snuff/</link>
      <pubDate>Fri, 29 Jan 2021 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/pratchett-terry--snuff/</guid>
      <description>&lt;p&gt;Reading Snuff was a bittersweet experience. Sweet because by now it&amp;rsquo;s impossible to disappoint me with stories about the Ankh-Morpork city watch. Bitter because this is the last book fo the series. And since Sir Terence David John Pratchett died in 2015, this is it.&lt;/p&gt;
&lt;p&gt;The story has a plot framed in a similar way to the Fifth Elephant. Commander Vimes goes to a foreign land, learns the local dynamic and solves a crime. The plot by itself doesn&amp;rsquo;t sound like much fun; it has been done before. But the opposite is true. Half of the enjoyment comes from knowing the characters and predicting what they are going to do. The second half comes from the unparalleled literary style with hilarious metaphors and timeless descriptions of human(oid) character.&lt;/p&gt;
&lt;p&gt;This book closes a year-long adventure. I miss you already Ankh-Morpork city watch.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Terry Pratchett - Night Watch</title>
      <link>https://blog.viktomas.com/books/pratchett-terry--night-watch/</link>
      <pubDate>Tue, 22 Dec 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/pratchett-terry--night-watch/</guid>
      <description>&lt;p&gt;Time travelling done right. That&amp;rsquo;s the book summed up in four words. As you can tell, I&amp;rsquo;m now a full-blown groupie of the Watch series. It would be as hard to disappoint me as having electronic conversations without funny GIFs.&lt;/p&gt;
&lt;p&gt;This novel is all about the origin story of the watch. Just when you thought that the watch characters couldn&amp;rsquo;t get any more colour and flavour, Sir Terry will take you 30 years back in time and gives you their detailed backstory. I refuse to accept that there are only two books left in the Watch series after this one.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Terry Pratchett - The Fifth Elephant</title>
      <link>https://blog.viktomas.com/books/pratchett-terry--fifth-elephant/</link>
      <pubDate>Fri, 04 Dec 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/pratchett-terry--fifth-elephant/</guid>
      <description>&lt;p&gt;This book takes the watch outside of Ankh-Morkork. I&amp;rsquo;m always surprised how fresh, non-repetitive and unpredictable the story is even though this is the fifth book on the same theme. Kudos to Terry.&lt;/p&gt;
&lt;p&gt;Uberwald, the wild west of Discworld is an excellent place for city-dwelling characters to step out of their comfort zone. &lt;strong&gt;Next sentence contains a mild spoiler&lt;/strong&gt;. This is also the first book of the series where I felt that the story got darker, and one of the characters I liked dies.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Pierre Hadot - Philosophy as a Way of Life</title>
      <link>https://blog.viktomas.com/books/hadot-pierre--philosophy-as-a-way-of-life/</link>
      <pubDate>Mon, 16 Nov 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/hadot-pierre--philosophy-as-a-way-of-life/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Pierre_Hadot&#34;&gt;Pierre Hadot&lt;/a&gt; was a French philosopher who spent his whole life studying ancient philosophy. He was a key proponent of thought that ancient philosophy was not the theoretical discipline studied at universities as we see it now but a way of life. Everyday practical exercises were an inseparable part of philosophy.&lt;/p&gt;
&lt;p&gt;Through the highly practical point of view, Hadot explains the work of Socrates and Marcus Aurelius. Modern scholars often misinterpreted Marcus Aurelius as a pessimist. In his Meditations, Marcus talks very dispassionately about sex, food and power.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;And in sexual intercourse that it is no more than the friction of a membrane and a spurt of mucus ejected.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;But instead of being a pessimist, he just tried to objectively describe things that people assign large value to and in doing so crave those things less.&lt;/p&gt;
&lt;p&gt;This book made it clear that philosophy was a great discipline of spirituality and only with the rise of Christianity, the philosophy became the study of logic and morality, disconnected from everyday life. Religion replaced the parts of philosophy that used to govern people&amp;rsquo;s lives in ancient Greece and Rome. And Hadot puts forward good arguments for Christianity copying and extending the good parts of ancient philosophy.&lt;/p&gt;
&lt;p&gt;Even though this book is a heavy textbook, it gave me an insight into the philosophy I&amp;rsquo;d love. The philosophy that&amp;rsquo;s all about bettering yourself and about living a full life instead of having arguments about fictional scenarios. Also, ancient philosophy seems to be close to Buddhism in all key aspects:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Desire and aversion are causing all suffering. The moment you want something you don&amp;rsquo;t have, or you don&amp;rsquo;t want something you&amp;rsquo;ve got, you are suffering.&lt;/li&gt;
&lt;li&gt;There is no self. The feeling of being separate from the world is an illusion.&lt;/li&gt;
&lt;li&gt;There is only the present moment, the past doesn&amp;rsquo;t exist anymore, and the future doesn&amp;rsquo;t exist yet.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>I want a local-first calendar</title>
      <link>https://blog.viktomas.com/posts/local-calendar/</link>
      <pubDate>Sun, 08 Nov 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/local-calendar/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m at the peak of my degoogling, slowly &lt;a href=&#34;https://blog.viktomas.com/posts/why-is-email-so-hard&#34;&gt;migrating of Gmail&lt;/a&gt;. I still use Google calendar, but hopefully, there&amp;rsquo;s an alternative. My personal calendar is much less collaborative than my work calendar. I don&amp;rsquo;t share it with friends, and I don&amp;rsquo;t use it to organise meetings. That makes it a perfect candidate for a &lt;a href=&#34;https://www.inkandswitch.com/local-first.html&#34;&gt;local-first app&lt;/a&gt;. Storing my calendar on my devices and synchronising it through services like Dropbox or git.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 350px&#34; src=&#34;https://blog.viktomas.com/images/posts/local-calendar.svg&#34; alt=&#34;Theme illustration&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Illustration&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;&lt;em&gt;Note: this article assumes an understanding of &lt;a href=&#34;https://git-scm.com/&#34;&gt;&lt;code&gt;git&lt;/code&gt; version control system&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;The only local, multi-platform calendar that I know of is &lt;a href=&#34;https://www.thunderbird.net/&#34;&gt;Thunderbird&lt;/a&gt;. It allows users to export their whole calendar in the iCalendar &lt;code&gt;.ics&lt;/code&gt; file. The textual iCalendar format could be good enough if there was a way to synchronise it between multiple devices. My use case is having one calendar on both mobile phone and desktop and synchronise it over Dropbox or similar cloud storage provider.&lt;/p&gt;
&lt;p&gt;In this regard, I love &lt;a href=&#34;https://joplinapp.org/&#34;&gt;Joplin&lt;/a&gt;, a local-first, open-source note-taking app that has both desktop and mobile clients synchronised with Dropbox.&lt;/p&gt;
&lt;h2 id=&#34;potential-solution&#34;&gt;Potential solution&lt;/h2&gt;
&lt;p&gt;After thinking about this problem for a while, I came up with a solution for a local-first calendar. The solution has to support one-person calendar needs. Advanced scheduling is out of scope. The more we can utilise current protocols and clients, the better. I have no intention of implementing a &lt;a href=&#34;https://www.thunderbird.net/&#34;&gt;Thunderbird&lt;/a&gt; equivalent.&lt;/p&gt;
&lt;h3 id=&#34;overview&#34;&gt;Overview&lt;/h3&gt;
&lt;p&gt;A large number of calendar clients supports connecting to CalDAV servers&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. And so that&amp;rsquo;s where the implementation would start. My idea is that the custom CalDAV server would run locally on the device.&lt;/p&gt;
&lt;p&gt;The CalDAV server would be a thin layer on top of a partitioned iCalendar format (explained below).&lt;/p&gt;
&lt;p&gt;Finally, the whole calendar data structure would be saved and synchronised in git.&lt;/p&gt;

&lt;div class=&#34;mermaid&#34; align=&#34;center&#34;&gt;graph TD;
A[&#34;Generic calendar client&#34;] --&gt; B[local CalDAV server]
B --&gt; C[Partitioned iCalendar format]
C --&gt; D[git]&lt;/div&gt;
&lt;h3 id=&#34;data-format---partitioned-icalendar&#34;&gt;Data format - partitioned iCalendar&lt;/h3&gt;
&lt;p&gt;Let&amp;rsquo;s start with the universal standard; the underlying structure would be partitioned iCalendar. The full calendar is a text file looking like this:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code class=&#34;language-ical&#34; data-lang=&#34;ical&#34;&gt;BEGIN:VCALENDAR
PRODID:-//Mozilla.org/NONSGML Mozilla Calendar V1.1//EN
VERSION:2.0
BEGIN:VTIMEZONE
    TZID:Europe/Prague
    BEGIN:DAYLIGHT
        ..
    END:DAYLIGHT
    BEGIN:STANDARD
        ..
    END:STANDARD
END:VTIMEZONE
BEGIN:VEVENT
    CREATED:20201101T142809Z
    DTSTAMP:20201101T144346Z
    SUMMARY:Test
    DTSTART;TZID=Europe/Prague:20201101T073000
    DTEND;TZID=Europe/Prague:20201101T083000
    DESCRIPTION:Event description
    BEGIN:VALARM
        ..
    END:VALARM
END:VEVENT
BEGIN:VTODO
    CREATED:20201101T144314Z
    DTSTAMP:20201101T144314Z
    SUMMARY:Don&amp;#39;t forget this todo
END:VTODO
END:VCALENDAR
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;(I added indentation for easier reading.)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;We would split this file into several smaller files:&lt;/p&gt;
&lt;p&gt;&lt;code&gt;timezone&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;BEGIN:VTIMEZONE
    TZID:Europe/Prague
    BEGIN:DAYLIGHT
        TZOFFSETFROM:+0100
        TZOFFSETTO:+0200
        TZNAME:CEST
        DTSTART:19700329T020000
        RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=3
    END:DAYLIGHT
    BEGIN:STANDARD
        TZOFFSETFROM:+0200
        TZOFFSETTO:+0100
        TZNAME:CET
        DTSTART:19701025T030000
        RRULE:FREQ=YEARLY;BYDAY=-1SU;BYMONTH=10
    END:STANDARD
END:VTIMEZONE
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;event-20201101T142809Z&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;BEGIN:VEVENT
    CREATED:20201101T142809Z
    DTSTAMP:20201101T144346Z
    SUMMARY:Test
    DTSTART;TZID=Europe/Prague:20201101T073000
    DTEND;TZID=Europe/Prague:20201101T083000
    DESCRIPTION:Event description
    BEGIN:VALARM
        ACTION:DISPLAY
        TRIGGER;VALUE=DURATION:-PT15M
        DESCRIPTION:Default Description
    END:VALARM
END:VEVENT
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;todo-20201101T144314Z&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;BEGIN:VTODO
    CREATED:20201101T144314Z
    DTSTAMP:20201101T144314Z
    SUMMARY:Don&amp;#39;t forget this todo
END:VTODO
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Splitting the events, todos, and other entries into separate files would allow us to keep the vast majority of the files unchanged during day to day use. In other words, instead of editing the large root iCalendar file all the time, we only need to edit a handful of small &lt;code&gt;event&lt;/code&gt; and &lt;code&gt;todo&lt;/code&gt; files each day.&lt;/p&gt;
&lt;h3 id=&#34;synchronisation&#34;&gt;Synchronisation&lt;/h3&gt;
&lt;p&gt;Now that we&amp;rsquo;ve got the whole calendar divided into small text files, we can choose the best available tool for synchronising text files: &lt;code&gt;git&lt;/code&gt;. Each edit to our calendar (e.g. changing and saving an event) is going to trigger a git commit.&lt;/p&gt;
&lt;p&gt;We will synchronise the calendar across devices by pushing to our central repository from one device and pulling from the other. Synchronisation (Merge) conflicts shouldn&amp;rsquo;t happen too often, but in the first iteration, we can resolve them using plain &lt;code&gt;git&lt;/code&gt; merge logic.&lt;/p&gt;
&lt;p&gt;The cool thing about using Git is that someone can maintain their personal (or team) calendar in git with Merge Requests. The team can, for example, discuss when would they like to have their stand up before merging the event.&lt;/p&gt;
&lt;h3 id=&#34;clients-connect-to-caldav-server&#34;&gt;Clients connect to CalDAV server&lt;/h3&gt;
&lt;p&gt;Implementing and running the server seems to be the trickiest part of the implementation. Maybe it would be possible to replace the internals of &lt;a href=&#34;https://github.com/LordEidi/fennel.js&#34;&gt;Fennel.js&lt;/a&gt; to connect to the partitioned iCalendar data structure. Another tricky part would be to make that server run on mobile devices. But I have seen it done before. For example, the &lt;a href=&#34;https://play.google.com/store/apps/details?id=com.ap.transmission.btc&#34;&gt;Transmission BTC&lt;/a&gt; starts an HTTP server.&lt;/p&gt;
&lt;p&gt;Calendar clients like &lt;a href=&#34;https://www.thunderbird.net/&#34;&gt;Thunderbird&lt;/a&gt; for desktop and &lt;a href=&#34;https://github.com/Etar-Group/Etar-Calendar&#34;&gt;Etar&lt;/a&gt; on Android) would connect to the local server.&lt;/p&gt;
&lt;p&gt;With some help, I could implement a proof of concept of such a local-first calendar in a week or two. Please let me know if you&amp;rsquo;d be interested in cooperating on implementing this in Go or JavaScript/TypeScript. My email is &lt;a href=&#34;mailto:me@viktomas.com&#34;&gt;me@viktomas.com&lt;/a&gt;. Also please let me know if I&amp;rsquo;m reinventing the wheel and someone has already done something similar.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/CalDAV#Client&#34;&gt;https://en.wikipedia.org/wiki/CalDAV#Client&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Terry Pratchett - Jingo</title>
      <link>https://blog.viktomas.com/books/pratchett-terry--jingo/</link>
      <pubDate>Fri, 30 Oct 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/pratchett-terry--jingo/</guid>
      <description>&lt;p&gt;The disadvantage of listening to the Discworld books in the form of audiobooks is that the uncontrollable bursts of laughter make you look quite silly. Jingo is a story of nationalism, war and murder. But it&amp;rsquo;s not a grim book that would bring you down when you read it. Even though the underlying topics are serious, the form couldn&amp;rsquo;t be more entertaining. You, for example, realise how little control do ordinary people have over their country&amp;rsquo;s policy. But you also hear the racial stereotypes from the mouths of Nobby Nobbs and Sergeant Colon which takes any seriousness away.&lt;/p&gt;
&lt;p&gt;The Klatchian D&amp;rsquo;regs are a great new addition to the Discworld. No-nonsense warriors who always charge at dawn and generally have the reputation of very egalitarian culture, they expect their woman, children and camels to fight well.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Why is email so hard? Unsatisfactory migration from Gmail to Zoho</title>
      <link>https://blog.viktomas.com/posts/why-is-email-so-hard/</link>
      <pubDate>Sun, 25 Oct 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/why-is-email-so-hard/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve just tried to get off Gmail. After a long twelve years, I decided it&amp;rsquo;s time to do what I preach and remove one more dependency on Google. I&amp;rsquo;ve already done that with &lt;a href=&#34;https://blog.viktomas.com/posts/break-free-from-youtube/&#34;&gt;YouTube&lt;/a&gt;,&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TL;DR&lt;/strong&gt;: Zoho Mail as an email provider, Thunderbird and K-9 as clients. But it is a pain.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 350px&#34; src=&#34;https://blog.viktomas.com/images/posts/why-is-email-so-hard.svg&#34; alt=&#34;Theme illustration&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Illustration&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I was sick of sharing my data with Google. I was sick of having a username that I made up in my late teens (still better than the previous two: &lt;code&gt;little.pink.hood&lt;/code&gt; and &lt;code&gt;DJ.bacon&lt;/code&gt;). And I was sick of all the rubbish that ends up in my Gmail inbox. It was time to start from scratch.&lt;/p&gt;
&lt;p&gt;Oh boy, was that a naive idea. Did I really think that I can easily change my email to a more generic service?&lt;/p&gt;
&lt;p&gt;I severely underestimated how terrible the user experience is as soon as I stop using a custom-built software like Gmail or Office 365. These providers built their clients to work well with their custom email services. Trying to connect to the email server using IMAP feels like travelling back in time.&lt;/p&gt;
&lt;p&gt;The latest version of IMAP, IMAP4, has been published in &lt;a href=&#34;https://tools.ietf.org/html/rfc3501&#34;&gt;2003 - 17 years ago&lt;/a&gt;. Two years after Microsoft released Windows XP. No wonder that people only use the web and native clients of the few largest email services.&lt;/p&gt;
&lt;h2 id=&#34;choosing-the-provider&#34;&gt;Choosing the provider&lt;/h2&gt;
&lt;p&gt;I wanted my email provider to be secure, always running, and cheap. I didn&amp;rsquo;t want it to sell my personal data or me as a subject for advertising.&lt;/p&gt;
&lt;p&gt;I considered using &lt;a href=&#34;https://github.com/sovereign/sovereign&#34;&gt;sovereign&lt;/a&gt;. It is a set of scripts for installing your custom email server. But do I really want to be responsible for keeping my email up 24/7? I could foresee the Christmas or Summer holiday outage of my email server.&lt;/p&gt;
&lt;p&gt;Recently, there was a big hype around hey.com, but I&amp;rsquo;m not ready to pay $100 annual fee to still have an email address like &lt;code&gt;my-name@someone-elses-domain.com&lt;/code&gt;. When they start supporting custom domains, I might switch if I&amp;rsquo;m still not used to the UX of third-party IMAP email clients.&lt;/p&gt;
&lt;p&gt;So I had to start looking for paid services that are cheap, but they provide IMAP and SMTP connection. This connection is needed to use the email server with any email client.&lt;/p&gt;
&lt;p&gt;I got &lt;a href=&#34;https://www.zoho.com/mail/zohomail-pricing.html&#34;&gt;Zoho Mail Lite&lt;/a&gt;. It cost 14 EUR a year, and it allows custom domains. That means I can finally have &lt;code&gt;me@viktomas.com&lt;/code&gt;. I used the free version of Zoho before, but that didn&amp;rsquo;t allow me to use IMAP (brilliant pricing move on Zoho&amp;rsquo;s part). Upgrading Zoho was a clear choice.&lt;/p&gt;
&lt;h2 id=&#34;choosing-a-client-either-rock-or-a-hard-place&#34;&gt;Choosing a client, either rock or a hard place&lt;/h2&gt;
&lt;p&gt;I use macOS. It&amp;rsquo;s an ok system, but I wouldn&amp;rsquo;t use it if it wasn&amp;rsquo;t required for work. One day I&amp;rsquo;m going to move back to Linux. The only way to keep this option open is not to lock in something as critical as email to a platform (e.g. starting using the osx Mail app). For that reason, I strictly picked &lt;a href=&#34;https://blog.viktomas.com/posts/foss/&#34;&gt;open-source&lt;/a&gt;, cross-platform client for desktop.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.thunderbird.net/&#34;&gt;Thunderbird&lt;/a&gt; seems to be the most supported desktop client out there. Using Thunderbird after being used to Gmail is not great. I haven&amp;rsquo;t had to do this much internet searching and configuring after installing a desktop app in ages. I had to configure things like DPI for the app, so the UI isn&amp;rsquo;t so tiny on a retina screen. Email threads are still not working 100%. Then again, the Thunderbird team is not making money off me and really appreciate the work they&amp;rsquo;ve done.&lt;/p&gt;
&lt;p&gt;For mobile (Android), I found &lt;a href=&#34;https://github.com/k9mail/k-9&#34;&gt;K-9&lt;/a&gt;. Unfortunately, it&amp;rsquo;s not being released through Play Store any more, and I had to get the latest through &lt;a href=&#34;https://f-droid.org/packages/com.fsck.k9/&#34;&gt;F-Droid&lt;/a&gt;. So far, it seems to be working well. It can&amp;rsquo;t match the UX of native apps like Gmail, but I don&amp;rsquo;t expect it to. The K-9 OSS team is doing a fantastic job.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve literally just finished the transition. I&amp;rsquo;m now planning on slowly setting the new email to all my accounts. I&amp;rsquo;ve still got 12 years worth of emails in Gmail, it&amp;rsquo;s 2.4 GB &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. When I&amp;rsquo;m ready to only use my Gmail account for forwarding, I&amp;rsquo;m going to migrate those emails to Zoho. Please, if you use a different solution and you are happy, send me a message, you know my email.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;I reduced the size by 30% by removing emails from the following Gmail searches: &lt;code&gt;category:social  -L:important&lt;/code&gt;, &lt;code&gt;category:promotions&lt;/code&gt;, and &lt;code&gt;has:attachment larger:1M&lt;/code&gt;.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Epictetus - Encheiridioin</title>
      <link>https://blog.viktomas.com/books/epictetus--encheiridion/</link>
      <pubDate>Mon, 19 Oct 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/epictetus--encheiridion/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;Some things are up to us and some things are not up to us.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The Stoic philosophy is very close to my heart because it teaches an approach to life, similar to Buddhism. Epictetus suggest that you only worry about things that you can change and forget about those you can&amp;rsquo;t. Furthermore, he suggests that if you learn to want the things that are happening as opposed to the things that are not happening, you are going to be always happy.&lt;/p&gt;
&lt;p&gt;The 53 rules, which make the actual content of this book take only about 35% of the pages. Instead of the long introduction explaining Stoic philosophy, I&amp;rsquo;d love the translator to add a brief explanation and examples of each rule. Without any additional information, I was able to understand maybe half of the rules.&lt;/p&gt;
&lt;p&gt;One rule that I really enjoyed was:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Rule 12: If you want to make progress, give up all considerations like these: “If I neglect my property I will have nothing to live on,” “If I do not punish my slave boy he will be bad.” It is better to die of hunger with distress and fear gone than to live upset in the midst of plenty. It is better for the slave boy to be bad than for you to be in a bad state. Begin therefore with little things. A little oil is spilled, little wine is stolen: say, &lt;strong&gt;“This is the price of tranquillity; this is the price of not being upset.”&lt;/strong&gt; Nothing comes for free. When you call the slave boy, keep in mind that he is capable of not paying attention, and even if he does pay attention he is capable of not doing any of the things that you want him to. But he is not in such a good position that your being upset or not depends on him. &lt;em&gt;Emphasis mine&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is such a healthy way to look at any troubles in life. Did you crash a car? Well let&amp;rsquo;s not stress about it, the crashed car is a &lt;em&gt;price for tranquillity&lt;/em&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>The things that make me happy</title>
      <link>https://blog.viktomas.com/posts/things-that-make-me-happy/</link>
      <pubDate>Sat, 17 Oct 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/things-that-make-me-happy/</guid>
      <description>&lt;p&gt;In the &lt;a href=&#34;https://blog.viktomas.com/posts/pot/&#34;&gt;last post&lt;/a&gt;, I got excited about getting a pot for my birthday. I got positive feedback (thanks Ben) and thought that I might list &lt;strong&gt;nine items&lt;/strong&gt; that I often use and that make my life better.&lt;/p&gt;
&lt;h2 id=&#34;100-cotton-sweatpants&#34;&gt;100% Cotton sweatpants&lt;/h2&gt;
&lt;p&gt;Being in comfortable clothes is underestimated. Since I moved out to go to uni, I wore jeans or chinos at all times. I thought that sweatpants are only for rappers, hardcore slavs and gym junkies. I still wouldn&amp;rsquo;t go out in my sweatpants, and I feel mildly judgemental about people who do. But at home? Nothing can beat the comfort of good-quality sweatpants on a cold day.&lt;/p&gt;
&lt;p&gt;I got the last two pairs from my girlfriend. She bought them in Terranova.&lt;/p&gt;
&lt;div class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 330px&#34; src=&#34;https://blog.viktomas.com/images/posts/things-that-make-me-happy/pants.png&#34; alt=&#34;/images/posts/things-that-make-me-happy/pants.png&#34; /&gt;

&lt;p&gt;&lt;em&gt;Credit: &lt;a href=&#34;https://www.terranovastyle.com/cz_cz/kalhoty-teplakove-jednobarevne-23-sab0042121001s047-kw-pantalone-ginnico-lungo-kw-grigio/&#34;&gt;terranovastyle.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;h2 id=&#34;bose-quitecomfort-35-ii&#34;&gt;Bose QuiteComfort 35 II&lt;/h2&gt;
&lt;p&gt;I mentioned these headphones before, and I should probably get some stock options from Bose for how much I promote them. I came across these for the first time when my ex-colleague Timothy let me try them up back in our Melbourne office. It was one of those massive open spaces where over a hundred people work on a floor without single doors, just a few barriers here and there. I put the headphones one and there it was: a quiet comfort. I bought myself my first pair the next day. That was in 2018, and the headphones were with me almost everywhere since then.&lt;/p&gt;
&lt;p&gt;They saved me from crying babies on an aeroplane, from drunk teenagers on a bus, and from hostel parties in Thailand (when I was hungover from the previous-day party).&lt;/p&gt;
&lt;div class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 400px&#34; src=&#34;https://blog.viktomas.com/images/posts/things-that-make-me-happy/bose-qc-35.png&#34; alt=&#34;/images/posts/things-that-make-me-happy/bose-qc-35.png&#34; /&gt;

&lt;p&gt;&lt;em&gt;Credit: &lt;a href=&#34;https://www.bose.com/en_us/products/headphones/over_ear_headphones/quietcomfort-35-wireless-ii.html#v=qc35_ii_black&#34;&gt;www.bose.com&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;h2 id=&#34;pocketbook-740&#34;&gt;PocketBook 740&lt;/h2&gt;
&lt;p&gt;Reading makes me happy. This ebook reader mediates that so I&amp;rsquo;m including it. It&amp;rsquo;s got 7.8&amp;quot; screen with backlight and it supports any document format that you throw at it. Those were the main reasons why I upgraded from my Kindle Paperwhite.&lt;/p&gt;
&lt;p&gt;But PocketBook is mainly a hardware company and so the reader software looks and feels a bit dated, and it never gets updated.&lt;/p&gt;
&lt;p&gt;I use the reader often, but it&amp;rsquo;s on the top of my &amp;ldquo;upgrade with something new&amp;rdquo; list. Maybe &lt;a href=&#34;https://onyxboox.com/boox_nova2&#34;&gt;ONYX BOOX NOVA 2&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;google-pixel-2-xl&#34;&gt;Google Pixel 2 XL&lt;/h2&gt;
&lt;p&gt;October 19, 2017. That was the day when Google released the best phone I&amp;rsquo;ve ever owned. The battery life brought back the memories of my beloved Nokia 3310, the fast charge was still a new thing, and I&amp;rsquo;m regularly delighted when I plug my Pixel to a charger minutes before I leave the house, and I get enough charge for the rest of my day.&lt;/p&gt;
&lt;p&gt;Almost three years after I bought mine, I&amp;rsquo;m starting to look for a new phone, but the shoes to fill are large. I think I&amp;rsquo;ll still survive 2021 with this sweetheart.&lt;/p&gt;
&lt;h2 id=&#34;screen-arm&#34;&gt;Screen arm&lt;/h2&gt;
&lt;p&gt;The look, the feel and the comfort of having your monitor attached to the tabletop with a dynamically positionable arm is something I can&amp;rsquo;t work without. It makes space on your desk and allows your head to be always in the right position.&lt;/p&gt;
&lt;p&gt;I got one inexpensive from a Czech supplier.&lt;/p&gt;
&lt;div class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 300px&#34; src=&#34;https://blog.viktomas.com/images/posts/things-that-make-me-happy/arm.jpg&#34; alt=&#34;/images/posts/things-that-make-me-happy/arm.jpg&#34; /&gt;

&lt;p&gt;&lt;em&gt;Credit: &lt;a href=&#34;https://www.alza.cz/alzapower-ergoarm-ar700-usb-d5346293.htm?o=33&#34;&gt;alza.cz&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;h2 id=&#34;skinners&#34;&gt;Skinners&lt;/h2&gt;
&lt;p&gt;Skinners are the brand of my barefoot shoes. They are not as much shoes as half-rubber socks. I bought the skinners because they were the cheapest barefoot &amp;ldquo;shoes&amp;rdquo; I could find. So far I&amp;rsquo;m quite happy with them even though the waterproofness of the sole lasted only around 80km of walking.&lt;/p&gt;
&lt;p&gt;The point in wearing barefoot shoes for me is that it makes walking in nature more fun, you notice what surface you walk on, and you&amp;rsquo;ve got to be more present otherwise you are going to get brought back to presence by sharp rocks and sticks.&lt;/p&gt;
&lt;div class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 400px&#34; src=&#34;https://blog.viktomas.com/images/posts/things-that-make-me-happy/skinners.png&#34; alt=&#34;/images/posts/things-that-make-me-happy/skinners.png&#34; /&gt;

&lt;p&gt;&lt;em&gt;Credit: &lt;a href=&#34;https://skinners.cc/en/&#34;&gt;skinners.cc&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;h2 id=&#34;feather-jacket&#34;&gt;Feather jacket&lt;/h2&gt;
&lt;p&gt;Feather jacket, similarly to the Bose headphones, is something you don&amp;rsquo;t know you need till you get the chance to try it.&lt;/p&gt;
&lt;p&gt;In my early twenties, I went on a mountain-climbing trip to Russian Caucasus mountains. When we were hiking up &lt;a href=&#34;https://en.wikipedia.org/wiki/Mount_Elbrus&#34;&gt;Elbrus&lt;/a&gt;, we started the last day of the ascent at 2 AM. It was so cold that the water in my water bottle froze. Normal layered clothes with Gore-Tex jacket was enough for going up, but when we made our rest stops, I thought I&amp;rsquo;m going to freeze. My friends just pulled their feather jackets out of their backpacks and put them over all other clothes.&lt;/p&gt;
&lt;p&gt;The advantage of a feather jacket is that it&amp;rsquo;s incredibly light, compact and insulating. You don&amp;rsquo;t need to climb mountains to benefit from having one.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve got three feather jackets, but the one that makes me happiest is Mountain Equipment Helium. It weighs a little over 100g (3.5oz). It compacts into a grapefruit-sized bundle. They are not making my model any more. Here&amp;rsquo;s a link to &lt;a href=&#34;https://www.mountain-equipment.co.uk/collections/helium-technology/products/odin-jacket&#34;&gt;the newer version&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 400px&#34; src=&#34;https://blog.viktomas.com/images/posts/things-that-make-me-happy/helium.jpg&#34; alt=&#34;/images/posts/things-that-make-me-happy/helium.jpg&#34; /&gt;

&lt;p&gt;Mountain Equipment Helium&lt;/p&gt;
&lt;/div&gt;

&lt;h2 id=&#34;trx-and-elastic-bands&#34;&gt;TRX and elastic bands&lt;/h2&gt;
&lt;p&gt;I like gyms better than owning all the gym equipment. That&amp;rsquo;s it. I don&amp;rsquo;t like going to the gym, I&amp;rsquo;m a shy exerciser next to other people and sometimes, but not often, I get annoyed by someone else&amp;rsquo;s behaviour.&lt;/p&gt;
&lt;p&gt;Since even before the pandemic, I would quite often just settle for exercising with my own weight at home. But certain muscles can&amp;rsquo;t be worked out without additional equipment. On top of that, it&amp;rsquo;s hard to increase the intensity with bodyweight exercises.&lt;/p&gt;
&lt;p&gt;The answer for me is TRX (suspended straps) and elastic bands. It pleases my minimalistic nature that I can fit my whole gym into a small bag.&lt;/p&gt;
&lt;div class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 400px&#34; src=&#34;https://blog.viktomas.com/images/posts/things-that-make-me-happy/band-trx.jpg&#34; alt=&#34;/images/posts/things-that-make-me-happy/band-trx.jpg&#34; /&gt;

&lt;p&gt;Bands and TRX&lt;/p&gt;
&lt;/div&gt;

&lt;h2 id=&#34;cable-organiser&#34;&gt;Cable organiser&lt;/h2&gt;
&lt;p&gt;The last thing on today&amp;rsquo;s list is a cable organiser. I bought mine before I went on nine months of travelling, but I use it often ever since. It replaced a big drawer filled with a mess of cables. The price of lost charging USB cables, USB sticks and headphones alone probably paid tenfold for it.&lt;/p&gt;
&lt;div class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 400px&#34; src=&#34;https://blog.viktomas.com/images/posts/things-that-make-me-happy/bubm-organizer.jpg&#34; alt=&#34;/images/posts/things-that-make-me-happy/bubm-organizer.jpg&#34; /&gt;

&lt;p&gt;&lt;em&gt;Credit: &lt;a href=&#34;https://www.aliexpress.com/item/32480976632.html&#34;&gt;BUBM Organizer Roll UP&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;I hope this list inspired you to reward yourself with something nice and useful. There are no affiliate links here. Let me know what makes you happy at &lt;a href=&#34;mailto:me@viktomas.com&#34;&gt;me@viktomas.com&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Terry Pratchett - Feet of Clay</title>
      <link>https://blog.viktomas.com/books/pratchett-terry--feet-of-clay/</link>
      <pubDate>Fri, 09 Oct 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/pratchett-terry--feet-of-clay/</guid>
      <description>&lt;p&gt;Who can mix crime novel with thoughtful discrimination critique and make it hilarious enough that you are going to be bursting out laughing? Only Sir Terrance.&lt;/p&gt;
&lt;p&gt;The main characters of the city watch are fully developed by now. You hear the name like Carrot or Nobby, and you start giggling without even hearing the rest.&lt;/p&gt;
&lt;p&gt;The most entertaining part of this story was Nobby trying to avoid his faith as a nobleman. He&amp;rsquo;s got an excellent spider-sense when it comes to a free lunch, and we could all learn from him.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>I got a pot for my last birthday!</title>
      <link>https://blog.viktomas.com/posts/pot/</link>
      <pubDate>Tue, 06 Oct 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/pot/</guid>
      <description>&lt;p&gt;Socks, underwear and now a cooking pot! Why are these the best presents? The answer is: I use these things every day, and so even a small improvement in quality makes a difference in the quality of my life.&lt;/p&gt;
&lt;div class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 300px&#34; src=&#34;https://blog.viktomas.com/images/posts/pot.jpg&#34; alt=&#34;/images/posts/pot.jpg&#34; /&gt;

&lt;p&gt;&lt;em&gt;Credit: &lt;a href=&#34;https://eshop.tescoma.cz/panev-hluboka-president-stone-s-poklici-28-cm&#34;&gt;Tescoma official site&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/div&gt;

&lt;p&gt;&lt;em&gt;This is a rare Tuesday edition of my Sunday article. :)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve got plenty of pots and pans, but most of them are low-end level Ikea cookware. My girlfriend and I cook every day, so even a small improvement in the cooking area is going to improve our life noticeably.&lt;/p&gt;
&lt;p&gt;The Barefoot Investor book has a chapter called &amp;ldquo;How to live like a multimillionaire right now&amp;rdquo;. The chapter suggests buying good underwear and a pillow. Scott Pape, the author, argues that those can&amp;rsquo;t get much better after a certain price point. So even the most wealthy people will have similar items as you. Same applies for a pot. Bill Gates is not going to have much better cooking pot than the one I got.&lt;/p&gt;
&lt;p&gt;I get super excited about getting something that I already use a lot  but in better quality. It feels better than getting a completely new thing. Examples of such things are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;iPhone 6 -&amp;gt; Pixel 2 XL (an hour a day)&lt;/li&gt;
&lt;li&gt;Anker SoundBuds NP10 -&amp;gt; Bose Quiet Comfort 35 (up to four hours a day)&lt;/li&gt;
&lt;li&gt;Low-end Ikea pot -&amp;gt; Tescoma President Stone (thirty minutes a day)&lt;/li&gt;
&lt;li&gt;Kindle Paperwhite -&amp;gt; PocketBook 740 (thirty minutes a day)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;When you upgrade like this, you already know how much you use the item, and you can judge how much value is the new thing going to bring. I talked more about this in my article on &lt;a href=&#34;https://blog.viktomas.com/posts/iteration/&#34;&gt;Iteration&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Another great benefit of such a swap is that it doesn&amp;rsquo;t increase the number of things you have to think about. Owning only items that I use is important to me. I wrote a whole article on &lt;a href=&#34;https://blog.viktomas.com/posts/minimalism/&#34;&gt;Minimalism&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Lately, I&amp;rsquo;m thinking about longevity. It would be great if I could buy an item and it would last me twenty years. I remember someone trying to create a jumper that should last a lifetime. But this mentality doesn&amp;rsquo;t seem to be mixable with capitalism. If a company makes shoes that will last 20 years, they&amp;rsquo;ll go out of business. Imagine buying Nike shoes and then not needing any for 20 years. Nike wouldn&amp;rsquo;t be the multi-billion dollar sneakers monster it is.&lt;/p&gt;
&lt;p&gt;Until we become less consuming as the whole society, getting high-quality items like the ones mentioned in this article is the closest I can get to having long-lasting, high-quality items.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>How long will your data last before it gets lost or destroyed</title>
      <link>https://blog.viktomas.com/posts/personal-data-longevity/</link>
      <pubDate>Mon, 28 Sep 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/personal-data-longevity/</guid>
      <description>&lt;p&gt;My generation is the last that doesn&amp;rsquo;t have their whole life electronically documented. When I started going to school, only two of my classmates had a computer. My digital life started roughly at age fifteen. So half of my life is digitally documented. But the question is for how long?&lt;/p&gt;
&lt;p&gt;I recently found out my docx password-locked diary. I was able to guess the password (the one password I always used before using a password manager&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;). It was on a seven-years-old hard drive in a folder called &lt;code&gt;old&lt;/code&gt; that came from a backup of an even older hard drive. It made me think about the best way to store information that I want to access in 30 years and about how long data usually lasts.&lt;/p&gt;
&lt;h2 id=&#34;physical-storage&#34;&gt;Physical storage&lt;/h2&gt;
&lt;p&gt;Initially, I thought that the storage medium itself would become the bottleneck in data longevity, after consulting Wikipedia&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; it seems that if the storage medium is well kept and not used, it might outlive you. The only exception to that rule is flash memory. The reading devices then become the main issue with physical media longevity.&lt;/p&gt;
&lt;p&gt;The storage media longevity is poorly documented on the Internet. There is no definitive answer for how long the data will last on a well-stored and not-used device. Cloud companies sponsor most of the research, and it is interested in heavily utilised HDD and SSD drives&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h3 id=&#34;floppy-disc&#34;&gt;Floppy disc&lt;/h3&gt;
&lt;p&gt;You can still easily read the high-density floppy discs (the 3.5&amp;quot; that were last before CDs), you only have to order USB floppy disc reader online for about $20&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;ve got the 5.25&amp;quot; disc, the USB reader will cost you double that. So if you had your data stored on 5.25&amp;quot; floppy disc in 1979&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt; and you kept the floppy disc in a dry, dark place, you might still be able to recover the data now, 40 years later for only $40. But if you stored the data on one of the not-so-common version of a floppy disc, it&amp;rsquo;s going to be much much harder to extract the data.&lt;/p&gt;
&lt;h3 id=&#34;hard-drive&#34;&gt;Hard drive&lt;/h3&gt;
&lt;p&gt;If you nicely tuck away your hard drive in dry, non-magnetic place, you have a chance of the data there lasting anything between 10 and 50 years&lt;sup id=&#34;fnref:6&#34;&gt;&lt;a href=&#34;#fn:6&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;6&lt;/a&gt;&lt;/sup&gt;, but since the magnetic field breakdown is not discrete, you are better of refreshing the data at least every five years.&lt;/p&gt;
&lt;h3 id=&#34;flash-storage&#34;&gt;Flash storage&lt;/h3&gt;
&lt;p&gt;USB sticks and SSD drives are using the same method for storing data&lt;sup id=&#34;fnref:7&#34;&gt;&lt;a href=&#34;#fn:7&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;7&lt;/a&gt;&lt;/sup&gt;. The most important factor for us is the &amp;ldquo;retention&amp;rdquo;. Retention means how long the NAND memory cell can keep its programmed state without being connected to power source&lt;sup id=&#34;fnref:8&#34;&gt;&lt;a href=&#34;#fn:8&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;8&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;For USB sticks, the thing that&amp;rsquo;s most likely to break is the circuitry that connects the control unit and the flash memory. If you store the USB stick well, the data might last up to 20 years&lt;sup id=&#34;fnref:9&#34;&gt;&lt;a href=&#34;#fn:9&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;9&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h2 id=&#34;cloud-storage&#34;&gt;Cloud storage&lt;/h2&gt;
&lt;p&gt;The Internet started to be generally available in 1989 when first private internet service providers began offering their services&lt;sup id=&#34;fnref:10&#34;&gt;&lt;a href=&#34;#fn:10&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;10&lt;/a&gt;&lt;/sup&gt;. But it was only in 2004 when Gmail launched&lt;sup id=&#34;fnref:11&#34;&gt;&lt;a href=&#34;#fn:11&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;11&lt;/a&gt;&lt;/sup&gt;. And Gmail is what I call the earliest cloud storage that is still available today. I joined Gmail in 2008, and the first emails are my first cloud digital trace that is still stored.&lt;/p&gt;
&lt;p&gt;Since I backed up my old hard drives to Dropbox, some data I now have in the cloud is much older than 2008. But those cloud bits are still younger than those first Gmail emails.&lt;/p&gt;
&lt;p&gt;Sixteen years of Gmail&amp;rsquo;s existence is not long enough to count cloud storage as a viable long-term digital storage solution.&lt;/p&gt;
&lt;h2 id=&#34;data-format-and-encryption&#34;&gt;Data format and encryption&lt;/h2&gt;
&lt;p&gt;The worst way to store your data would be a proprietary binary format. That means the data is encoded in a custom way on your storage media. The best example, although extreme, is old video games. They often had both custom storage and custom file format and are not playable or readable on newer devices&lt;sup id=&#34;fnref:12&#34;&gt;&lt;a href=&#34;#fn:12&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;12&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;The best way to store your data is in a plain text in UTF-8 or ASCII encoding. That&amp;rsquo;s one of the guiding philosophies of Unix systems&lt;sup id=&#34;fnref:13&#34;&gt;&lt;a href=&#34;#fn:13&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;13&lt;/a&gt;&lt;/sup&gt;. Plain text data created on a Unix machine in 1970 is still going to be readable today, giving the format the best chance to survive.&lt;/p&gt;
&lt;p&gt;When it comes to audio-visual data, I don&amp;rsquo;t have any suggestions. I think that the current VLC player can play any video file that I ever owned and I don&amp;rsquo;t think that&amp;rsquo;s going to change any time soon. But then again, digital video is still new data format compared to ASCII text. MPEG-1 has been developed in 1991&lt;sup id=&#34;fnref:14&#34;&gt;&lt;a href=&#34;#fn:14&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;14&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;h3 id=&#34;encryption&#34;&gt;Encryption&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/signal/&#34;&gt;I love encryption&lt;/a&gt;. But encrypting the data will significantly lower the chances of you or someone else being able to recover them decades from now, which is the point. Encryption is not suitable for storing data that your children might want to look at one day. Imagine that your grand grandma encrypted those black and white family pictures.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Encryption may exacerbate the problem of preserving data since decoding adds complexity even when the relevant software is available.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Digital_dark_age&#34;&gt;Digital dark age - Wikipedia&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;what-can-you-do&#34;&gt;What can you do&lt;/h2&gt;
&lt;h3 id=&#34;organised-data&#34;&gt;Organised data&lt;/h3&gt;
&lt;p&gt;Organise your data. The clearer your folder structure is, the more likely are you ever look at the data again.&lt;/p&gt;
&lt;h3 id=&#34;backup&#34;&gt;Backup&lt;/h3&gt;
&lt;p&gt;Store your data in multiple places. If the data is only in one spot, they are bound to be lost sooner or later.&lt;/p&gt;
&lt;h3 id=&#34;refresh&#34;&gt;Refresh&lt;/h3&gt;
&lt;p&gt;Every five years or so, you should take the data from your previous storage and copy it to a new storage medium. Magnetic hard drives need to refresh their magnetic field, and flash drives need to recharge the NAND gates.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Read more about how I use password manager in &lt;a href=&#34;https://blog.viktomas.com/posts/security-is-like-ogres/&#34;&gt;Security is like ogres&lt;/a&gt;.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Digital_obsolescence#Obsolescence_in_hardware&#34;&gt;Digital obsolescence - Wikipedia&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.howtogeek.com/322856/how-long-do-solid-state-drives-really-last/&#34;&gt;How Long Do Solid State Drives Really Last?&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.nypl.org/blog/2012/07/23/digital-archaeology-recovering-your-digital-history&#34;&gt;Digital Archaeology: Recovering your Digital History | The New York Public Library&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Floppy_disk#%E2%80%8B5_1%E2%81%844-inch_floppy_disk&#34;&gt;Floppy disk - Wikipedia&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:6&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://superuser.com/questions/284427/how-much-time-until-an-unused-hard-drive-loses-its-data&#34;&gt;backup - How much time until an unused hard drive loses its data? - Super User&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:6&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:7&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Flash_memory#NAND_flash&#34;&gt;Flash memory - Wikipedia&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:7&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:8&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.datarecovery.net/newsletters/what-kills-flash-drive.aspx&#34;&gt;What Kills Your Flash Drive and How You Can Avoid It&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:8&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:9&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://techstory.in/what-is-the-lifespan-of-a-usb-flash-drive/&#34;&gt;What Is The Lifespan of a USB Flash Drive? - TechStory&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:9&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:10&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Internet#History&#34;&gt;Internet - Wikipedia&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:10&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:11&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Gmail&#34;&gt;Gmail - Wikipedia&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:11&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:12&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Digital_obsolescence#Obsolescence_in_software&#34;&gt;Digital obsolescence - Wikipedia&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:12&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:13&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/The_Art_of_Unix_Programming&#34;&gt;The Art of Unix Programming&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:13&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:14&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/MPEG-1&#34;&gt;MPEG-1 - Wikipedia&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:14&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Compounding skills improve your life exponentially</title>
      <link>https://blog.viktomas.com/posts/compounding-skills/</link>
      <pubDate>Sun, 20 Sep 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/compounding-skills/</guid>
      <description>&lt;p&gt;We have an intuition about the benefit we get from learning a skill. Learning how to remember information better is more beneficial than learning how to recognise trees using leaves. What is the cause of the greater benefit? And what are some examples of more and less beneficial skills?&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 500px&#34; src=&#34;https://blog.viktomas.com/images/posts/compounding-skills.svg&#34; alt=&#34;Theme illustration&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Illustration&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I determine the utility of a skill as a sum of how much fun it is, how valuable it is to other people and how large is the context in which I can apply the skill. The best skill to have is the one that is fun to do, useful to people, and applicable in a wide area of activities.&lt;/p&gt;
&lt;p&gt;Today, I want to focus on the last part of the equation, the skill&amp;rsquo;s context size. The context size is what creates the compounding effect of the skill.&lt;/p&gt;
&lt;p&gt;For example, if you are an athlete, you can learn how to kick a soccer penalty. This skill is useful for a soccer player, but it has got a limited range of applications. On the other hand, you can learn general anatomy: how muscles work, how to exercise them and stretch them. The second skill will help with soccer training, but it will also help with any other sport as well as with staying healthy and mobile.&lt;/p&gt;
&lt;p&gt;Here are three examples of skills that have a large context area and so they are going to be useful throughout a variety of activities. If you learn them, they&amp;rsquo;ll be compounding their benefit for years to come. The sooner you learn them, the more benefit you&amp;rsquo;ll reap. Same as financial savings.&lt;/p&gt;
&lt;h2 id=&#34;note-taking&#34;&gt;Note-taking&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve spent a good portion of this year learning how to take notes. I discovered &lt;a href=&#34;https://blog.viktomas.com/posts/slip-box/&#34;&gt;Zettelkasten note-taking&lt;/a&gt;, and I realised the compounding potential.&lt;/p&gt;
&lt;p&gt;When you make notes using the Zettelkasten method, you optimise for read&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. You spend extra time writing the note as if the reader (the future you) doesn&amp;rsquo;t have any context, which makes all the notes timeless. You can read them ten days or ten years from now, and you should still get the same understanding. Every new note increases your knowledge base forever - a perfect example of compounding.&lt;/p&gt;
&lt;h2 id=&#34;writing&#34;&gt;Writing&lt;/h2&gt;
&lt;p&gt;Being able to clearly express your thoughts is a skill that permeates every knowledge work. Learning how to write so that people understand you is a skill that will stay with you at every step of your life.&lt;/p&gt;
&lt;p&gt;I decided to learn how to write this year. It is now more important than ever with my &lt;a href=&#34;https://blog.viktomas.com/posts/remote/&#34;&gt;remote job&lt;/a&gt; and with the increasing recognition of how remote work can be more productive and more healthy for knowledge workers.&lt;/p&gt;
&lt;p&gt;One of the paradigm shifts in remote work is writing everything down. Then other people can search through internal wiki rather than tapping you on the shoulder, which saves your time. But this can only work if they understand what you wrote.&lt;/p&gt;
&lt;h2 id=&#34;body-friendly-exercise&#34;&gt;Body-friendly exercise&lt;/h2&gt;
&lt;p&gt;The best people to teach you how to exercise are physiotherapists. They usually help people to recover from injuries or to mitigate some of the damage we do to our bodies with sitting jobs. They also know well what exercises are going to hurt you (e.g. poorly done crunches) and how to alter them so you won&amp;rsquo;t hurt your back or joints.&lt;/p&gt;
&lt;p&gt;If you learn how to exercise to strengthen your core, centre your joints, and stretch shortened muscles you are not only going to better perform in sports, but you are going to stay healthy and mobile for much longer in life.&lt;/p&gt;
&lt;h2 id=&#34;theres-plenty-more&#34;&gt;There&amp;rsquo;s plenty more&lt;/h2&gt;
&lt;p&gt;Financial investment, communication skills, meditation, critical thinking and more. That&amp;rsquo;s a brief list of what is now going through my head. I&amp;rsquo;m organising my thoughts on what to focus on next. If you&amp;rsquo;ve got any examples or thoughts on the topic, let me know on twitter or send me an email.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;In programming, that means optimising the system for users retrieving information from it, usually at the cost of write operations.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>How to describe a software issue</title>
      <link>https://blog.viktomas.com/posts/describe-software-issue/</link>
      <pubDate>Sun, 13 Sep 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/describe-software-issue/</guid>
      <description>&lt;p&gt;This article will help you become that one person who gets their technical problems solved first. Keep following these three guidelines, and you will greatly reduce the amount of suffering in the world.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 450px&#34; src=&#34;https://blog.viktomas.com/images/posts/describe-software-issue.svg&#34; alt=&#34;Theme illustration&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Illustration&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Imagine that you found an issue in your favourite software, here are the steps that you can take to report the issue to a software maintainer. They don&amp;rsquo;t take much effort, but they&amp;rsquo;ll make a world of difference for the person trying to understand your report.&lt;/p&gt;
&lt;h3 id=&#34;check-existing-issues&#34;&gt;Check existing issues&lt;/h3&gt;
&lt;p&gt;Majority of the software I use has an open issue tracking system. Before you start writing about the problem you are facing, check the issue list. Try to search for a few terms that would match your issue. Chances are the issue is already documented.&lt;/p&gt;
&lt;p&gt;If you manage to find an existing issue, leave a comment saying the same thing happens to you. If some important information about the issue is missing, mention that as well and possibly follow the following two guidelines.&lt;/p&gt;
&lt;p&gt;This reduces the load on both maintainers and you. Maintainers don&amp;rsquo;t have to classify the duplicate issue, and you don&amp;rsquo;t have to put in the effort to describe the issue clearly.&lt;/p&gt;
&lt;p&gt;Examples of issue tracking:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://bugzilla.mozilla.org/home&#34;&gt;Mozilla&amp;rsquo;s Bugzilla&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/gitlab-org/gitlab/-/issues&#34;&gt;GitLab issues&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/viktomas/godu/issues&#34;&gt;GitHub issues&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;reproducing-the-issue&#34;&gt;Reproducing the issue&lt;/h3&gt;
&lt;p&gt;You might have heard about Rubber duck debugging&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. In software engineering, it means you try to explain your problem to a rubber duck and by doing so, you&amp;rsquo;ll understand the problem better and often solve it altogether.&lt;/p&gt;
&lt;p&gt;Describing your issue works similarly. If you can&amp;rsquo;t clearly explain how did you arrive at the issue, what makes you think that an engineer without a context can? If you can, mention all the custom settings, software version and attach any logs that could contain cues for the engineers.&lt;/p&gt;
&lt;h3 id=&#34;gif-of-the-problem&#34;&gt;GIF of the problem&lt;/h3&gt;
&lt;p&gt;GIFs are not only a great way to thank you with Tom Hanks video&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, they are also a fantastic tool to show the issue. They say that &amp;ldquo;A picture is worth a thousand words&amp;rdquo;&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;. Moving pictures increases the worth even further. If the issue manifests itself with any user interface problem, or if you can reproduce it visually (e.g. click here, type this, click on the submit button), then GIF is the perfect choice for showing the issue.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://getkap.co/&#34;&gt;Kap&lt;/a&gt; - Mac screen capture&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/phw/peek&#34;&gt;Peek&lt;/a&gt; - Linux screen capture&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;examples&#34;&gt;Examples&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/gitlab-org/gitlab/-/issues/223704#relevant-logs-andor-screenshots&#34;&gt;Issue recording incorrect behaviour of the GitLab editor&lt;/a&gt; (Web IDE)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/gitlab-org/gitlab-vscode-extension/-/issues/129&#34;&gt;A recent issue to implement inserting snippets in VS Code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;hr&gt;
&lt;p&gt;Following these steps will save time for the maintainers. They can spend more time on making the software  better for you.&lt;/p&gt;
&lt;p&gt;But more importantly, &lt;strong&gt;it will save you time&lt;/strong&gt;. If you only send out an email saying something like &amp;ldquo;messaging doesn&amp;rsquo;t work&amp;rdquo;, you are in for a whole lot of trouble. Get ready for the back and forth communication when the engineer tries to extract enough details out of you to reproduce the issue. That&amp;rsquo;s in the end much more effort compared to a cleaner first report.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Rubber_duck_debugging&#34;&gt;https://en.wikipedia.org/wiki/Rubber_duck_debugging&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://media3.giphy.com/media/AhJIPUnoUYgyA/giphy.gif&#34;&gt;https://media3.giphy.com/media/AhJIPUnoUYgyA/giphy.gif&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/A_picture_is_worth_a_thousand_words&#34;&gt;https://en.wikipedia.org/wiki/A_picture_is_worth_a_thousand_words&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Facebook won&#39;t let you talk about this blog</title>
      <link>https://blog.viktomas.com/posts/facebook-censorship/</link>
      <pubDate>Sun, 06 Sep 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/facebook-censorship/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve heard about social networks censoring content, but I always thought it only affects hate speech or promoting violence. I never expected that my opinions could end up in the same bucket as stirring violence. And I&amp;rsquo;m perplexed by the way Facebook decides what you can and can&amp;rsquo;t talk about with your friends.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPDATE&lt;/strong&gt;(2021-02-08): Today I was able to share this blog through Facebook. So the situation described bellow is no longer happening. That doesn&amp;rsquo;t change my sentiment towards Facebook though.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 350px&#34; src=&#34;https://blog.viktomas.com/images/posts/facebook-censorship.svg&#34; alt=&#34;Theme illustration&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Illustration&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;A few weeks back, I was messaging with my ex-colleague and a good friend. We haven&amp;rsquo;t talked to each other since I started writing this blog and so, naturally, I wanted to brag, and I sent him a link.&lt;/p&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/images/posts/facebook-censorship/messenger.png&#34;
    alt=&#34;Bragging on Messenger&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;The message didn&amp;rsquo;t send. Tapping for details didn&amp;rsquo;t work&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. I thought it has to be a network issue. I opened my laptop and tried to send the message through the Facebook website.&lt;/p&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/images/posts/facebook-censorship/web.png&#34;
    alt=&#34;Bragging on the web&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;I couldn&amp;rsquo;t believe my eyes. Facebook won&amp;rsquo;t let me message my friend because it doesn&amp;rsquo;t agree with the content of my message. This private message censorship is both sad and hilarious at the same time.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s &lt;strong&gt;hilarious&lt;/strong&gt; because it proves the point I was making about end-to-end encryption being necessary when I talked about the &lt;a href=&#34;https://blog.viktomas.com/posts/signal&#34;&gt;Signal messaging app&lt;/a&gt;. It&amp;rsquo;s nobody&amp;rsquo;s business to know what I&amp;rsquo;m discussing with my friends. Spying on my messages is one thing, not allowing me to send them at all is whole another level.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s &lt;strong&gt;sad&lt;/strong&gt; for several reasons.&lt;/p&gt;
&lt;p&gt;First, I don&amp;rsquo;t rely on my site for making a living, but if I did (as so many of you do), then my livelihood would be damaged. There&amp;rsquo;s no way of knowing which of the plethora of vague &lt;a href=&#34;https://www.facebook.com/communitystandards/&#34;&gt;Facebook Community Standards&lt;/a&gt; are you allegedly breaking.&lt;/p&gt;
&lt;p&gt;Second, not all of my friends are on Signal, and so I sometimes have to talk about my site as &lt;code&gt;viktomas[dot]com&lt;/code&gt;. It hurts every time I type that into a Facebook message.&lt;/p&gt;
&lt;p&gt;Third, this happens retrospectively&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;. If anybody posted or talked about this blog, Facebook went and deleted those messages, rewriting history.&lt;/p&gt;
&lt;h2 id=&#34;the-dispute-process&#34;&gt;The dispute process&lt;/h2&gt;
&lt;p&gt;There is a dispute process that doesn&amp;rsquo;t work. You can send Facebook a note saying that you think they made a mistake, but your message goes straight to &lt;a href=&#34;https://en.wikipedia.org/wiki/Null_device&#34;&gt;&lt;code&gt;/dev/null&lt;/code&gt;&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;They&amp;rsquo;ll even tell you that they &lt;strong&gt;&amp;ldquo;won&amp;rsquo;t have a look at your report&amp;rdquo;&lt;/strong&gt;:&lt;/p&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/images/posts/facebook-censorship/report.png&#34;
    alt=&#34;Trying to report the issue&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;I understand that a service with 2.7 billion users&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;, can&amp;rsquo;t handle individual requests. But then they should be a bit more transparent about the reasons why their algorithm blocks your site so you can decide whether you let Facebook dictate your content or not. Facebook designed non-transparent censorship, and it doesn&amp;rsquo;t allow users to contest the decisions. Dreamwidth co-owner xb95 says it the best:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;[It&amp;rsquo;s] a bit of a /shrug moment on the subject itself. &amp;ldquo;Facebook gonna Facebook&amp;rdquo; I think is approximately how we feel about this.&lt;/p&gt;
&lt;p&gt;xb95 &lt;a href=&#34;https://news.ycombinator.com/item?id=23958445&#34;&gt;on hackernews&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Countless blog posts&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; recommend the following 3 steps to resolve the issue:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Go through all your content and make sure that it complies with the 27 pages long, vague &lt;a href=&#34;https://www.facebook.com/communitystandards/&#34;&gt;Facebook Community Standards&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Use the useless form that I mentioned earlier&lt;/li&gt;
&lt;li&gt;Sign up for Facebook Ads and contest their ban as a paying customer&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;I even found advice recommending to change your domain.&lt;/p&gt;
&lt;h2 id=&#34;others-having-the-same-issue&#34;&gt;Others having the same issue&lt;/h2&gt;
&lt;p&gt;Dramwidth got blocked in July 2020&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;. FolioHD got blocked in July 2020&lt;sup id=&#34;fnref1:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;. When it happened to FolioHD, t
he founder Corry Watilo had to contact his friends in Facebook and start &lt;a href=&#34;https://twitter.com/watilo/status/1282856692083032064/retweets/with_comments&#34;&gt;a small Twitter campaign&lt;/a&gt; to unblock his domain.&lt;/p&gt;
&lt;p&gt;But the majority of the cases ends up without any resolution. Not many people have the privilege of having friends with friends in the Facebook support centre.&lt;/p&gt;
&lt;h2 id=&#34;my-take-away&#34;&gt;My take away&lt;/h2&gt;
&lt;p&gt;When I was in my early twenties, still at uni, Facebook banned me without any explanation. I lost tens of connections to acquaintances that I never recovered. I got burnt, and I haven&amp;rsquo;t had a Facebook account for years after that. But eventually, after the services I used (Whatsapp, Instagram) got one by one acquired by Facebook, I gave in. I started another account with a different email so I can talk to people who aren&amp;rsquo;t on Signal or Whatsapp. I wish I could do without it.&lt;/p&gt;
&lt;p&gt;Somebody at Facebook really doesn&amp;rsquo;t like me. But the whole situation is funny rather than angering. I don&amp;rsquo;t need Facebook, and even though it would be nice if you could share my articles the way you want, you are not likely too dependent on Facebook if you follow my blog.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m going to embrace &amp;ldquo;Facebook gonna Facebook&amp;rdquo; and introduce a new subtitle for my blog: &amp;ldquo;Content so good that Facebook won&amp;rsquo;t let you talk about it.&amp;rdquo;&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Android Messenger only shows a dialogue saying that you can&amp;rsquo;t reply to this method. I get it, I also often forget to test for the edge case scenarios when I write code.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://watilo.com/facebooks-community-standards-censorship-has-far-reaching-consequences&#34;&gt;Original post&lt;/a&gt;, &lt;a href=&#34;https://news.ycombinator.com/item?id=23956988&#34;&gt;Hackernews thread&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref1:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;2.7 billion monthly active users in Q2 2020 according to &lt;a href=&#34;https://www.statista.com/statistics/264810/number-of-monthly-active-facebook-users-worldwide/&#34;&gt;statista&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;I&amp;rsquo;m not going to link them, but the Google search term is &lt;code&gt;facebook community standards block -site:facebook.com&lt;/code&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://andrewducker.dreamwidth.org/3861716.html&#34;&gt;Original post&lt;/a&gt;, &lt;a href=&#34;https://news.ycombinator.com/item?id=23956640&#34;&gt;Hackernews thread&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Pierce Brown - Morning Star</title>
      <link>https://blog.viktomas.com/books/brown-pierce--morning-star/</link>
      <pubDate>Mon, 31 Aug 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/brown-pierce--morning-star/</guid>
      <description>&lt;p&gt;Trilogy: &lt;a href=&#34;https://blog.viktomas.com/books/pierce-brown-red-rising&#34;&gt;Red Rising&lt;/a&gt;, &lt;a href=&#34;https://blog.viktomas.com/books/pierce-brown-golden-son&#34;&gt;Golden Son&lt;/a&gt;, Morning Star&lt;/p&gt;
&lt;p&gt;The third book in the Red Rising Saga is a bit repetitive end you can see some of the plot twists coming from miles away. But the book wasn&amp;rsquo;t a disappointment. It made for a good ending to the trilogy.&lt;/p&gt;
&lt;p&gt;The catch? The trilogy is now &lt;a href=&#34;https://www.goodreads.com/series/117100-red-rising-saga&#34;&gt;pentalogy&lt;/a&gt;. But I&amp;rsquo;m going to end with the third book because it brings a nice ending to the story and there is only so much time I can spend binge-reading sci-fi soap operas.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Pierce Brown - Golden Son</title>
      <link>https://blog.viktomas.com/books/brown-pierce--golden-son/</link>
      <pubDate>Fri, 28 Aug 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/brown-pierce--golden-son/</guid>
      <description>&lt;p&gt;Trilogy: &lt;a href=&#34;https://blog.viktomas.com/books/pierce-brown-red-rising&#34;&gt;Red Rising&lt;/a&gt;, Golden Son, &lt;a href=&#34;https://blog.viktomas.com/books/pierce-brown-morning-star&#34;&gt;Morning Star&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;It would be hard not to spoil the first book when talking about what happened in the second, so I&amp;rsquo;ll instead talk about some aspects of the trilogy that I love.&lt;/p&gt;
&lt;p&gt;The story doesn&amp;rsquo;t go into detail of how the science-fiction perks like terraforming, artificial gravity and their razors (light sabres) work. And so it boils down very much to a story about society and interpersonal relationships which is the most interesting part anyway.&lt;/p&gt;
&lt;p&gt;The main hero Darrow is living in a high-class world where a low-born like himself shouldn&amp;rsquo;t be. He&amp;rsquo;s trying to infiltrate the society and bring a revolution. Yet, he&amp;rsquo;s making solid friendships and romantic relationships. The story is of constant alliance and betrayal.&lt;/p&gt;
&lt;p&gt;The book is very unpredictable. You never know who&amp;rsquo;s going to turn out to be a great friend and who&amp;rsquo;s going to betray the main hero.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Pierce Brown - Red Rising</title>
      <link>https://blog.viktomas.com/books/brown-pierce--red-rising/</link>
      <pubDate>Sun, 23 Aug 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/brown-pierce--red-rising/</guid>
      <description>&lt;p&gt;Trilogy: Red Rising, &lt;a href=&#34;https://blog.viktomas.com/books/pierce-brown-golden-son&#34;&gt;Golden Son&lt;/a&gt;, &lt;a href=&#34;https://blog.viktomas.com/books/pierce-brown-morning-star&#34;&gt;Morning Star&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Red rising is what happens when you cross-bread &lt;a href=&#34;https://www.goodreads.com/book/show/5129.Brave_New_World&#34;&gt;Brave New World&lt;/a&gt; with &lt;a href=&#34;https://www.goodreads.com/book/show/6186357-the-maze-runner&#34;&gt;The Maze Runner&lt;/a&gt; and the &lt;a href=&#34;https://www.goodreads.com/book/show/13496.A_Game_of_Thrones&#34;&gt;Game of Thrones&lt;/a&gt;. Even though the book&amp;rsquo;s concepts are not original, the way how Pierce Brown puts them together is incredibly amusing and propelled me into a two-week binge read of the whole trilogy.&lt;/p&gt;
&lt;p&gt;In this science-fiction dystopian novel, the main hero is a kid from the lowest cast in the solar system. He&amp;rsquo;s about to stir up an uprising for a better world and for democracy which happens to be a dirty word. The whole story happens on Mars, and instead of saying more, I recommend you get the book and read it. But be warned, it&amp;rsquo;s similar to Game of Thrones addictiveness.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Douglas E. Harding - On Having No Head</title>
      <link>https://blog.viktomas.com/books/harding-douglas--on-having-no-head/</link>
      <pubDate>Mon, 17 Aug 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/harding-douglas--on-having-no-head/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve heard about Douglas&amp;rsquo; book when I read &lt;a href=&#34;https://www.goodreads.com/book/show/18774981-waking-up&#34;&gt;Waking Up from Sam Harris&lt;/a&gt;. On Having No Head is a spiritual book, first published in 1961. Giving a good pointer to what Buddha might have meant when he said that there is no self.&lt;/p&gt;
&lt;p&gt;The simple idea that Douglas presents in his book is this: &amp;ldquo;Can you see your head? If not, how do you know it exists?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;It can feel quite strange when you explore that experience and do the exercises.&lt;/p&gt;
&lt;p&gt;For more information, I strongly recommend visiting &lt;a href=&#34;https://headless.org&#34;&gt;The Headless Way&lt;/a&gt;. You can even participate in online meditation sessions. I&amp;rsquo;ve done it, and the community is welcoming and pleasant.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Ryan Singer - Shape Up</title>
      <link>https://blog.viktomas.com/books/singer-ryan--shape-up/</link>
      <pubDate>Fri, 14 Aug 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/singer-ryan--shape-up/</guid>
      <description>&lt;p&gt;This book is free to read or download on the &lt;a href=&#34;https://basecamp.com/shapeup&#34;&gt;Basecamp website&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This short book (130 pages) is a great overview of the product development process used by Basecamp. As it is always the case with books from this company, there is plenty of controversial or counter-intuitive thoughts as well as plain genius ones.&lt;/p&gt;
&lt;h2 id=&#34;budgeting-appetite&#34;&gt;Budgeting (Appetite)&lt;/h2&gt;
&lt;p&gt;Budgeting is a method of managing software development when the team first introduces a limit on the maximum amount of resources (time, people) spent on the project. The team decides that solving the problem is only worth X amount of resources. If the project doesn&amp;rsquo;t fit in that budget, it&amp;rsquo;s not worth doing. At Basecamp, they call this Appetite.&lt;/p&gt;
&lt;h2 id=&#34;decentralized-lists&#34;&gt;Decentralized lists&lt;/h2&gt;
&lt;p&gt;This is an outrageous idea. At Basecamp, they don&amp;rsquo;t have one central backlog of all the issues or feature ideas. They say that grooming this backlog is not worth the effort because most of the tasks are never going to get done. Instead, each department in Basecamp has its list of &amp;ldquo;issues we&amp;rsquo;d like to do&amp;rdquo;, and they try to shape them into projects. The argument is that the important issues are going to come up over and over again. I guess this can work for a small company of 50 people.&lt;/p&gt;
&lt;h2 id=&#34;hill-charts&#34;&gt;Hill charts&lt;/h2&gt;
&lt;p&gt;Hill charts are an ingenious way of displaying the project progress. Instead of trying to put estimates on the unfinished parts of the project, they visually display the level of uncertainty on a &amp;ldquo;normal distribution&amp;rdquo; hill chart. I recommend reading the &lt;a href=&#34;https://basecamp.com/shapeup/3.4-chapter-13#work-is-like-a-hill&#34;&gt;Work is like a hill&lt;/a&gt; chapter in full.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Simpleton: privacy-aware web analytics made with Nginx and GoAccess</title>
      <link>https://blog.viktomas.com/posts/simpleton-analytics/</link>
      <pubDate>Sun, 09 Aug 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/simpleton-analytics/</guid>
      <description>&lt;p&gt;Hacker News is crowded with articles about blog owners making their custom web analytics&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. I thought it looked like a fun weekend project. Let me show you &lt;a href=&#34;https://gitlab.com/viktomas/simpleton-analytics&#34;&gt;Simpleton Analytics&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TL;DR visit the &lt;a href=&#34;https://gitlab.com/viktomas/simpleton-analytics&#34;&gt;project repository&lt;/a&gt;, and you can have your analytics set up in a few minutes.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;My requirements were clear. Privacy, price, time. I want to know the bare minimum about my visitors, no cookies, no session tracking, no sharing with 3rd parties. It had to be cheap, running on the smallest VPC instance. It had to be fun to make and the implementation needed to fit into a weekend.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 700px&#34; src=&#34;https://blog.viktomas.com/images/posts/simpleton-analytics.svg&#34; alt=&#34;Theme illustration&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Illustration&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;saturday&#34;&gt;Saturday&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve started researching all the possible technologies, and I quickly settled on the combination of storing access logs and then processing them with &lt;a href=&#34;https://goaccess.io/&#34;&gt;GoAccess&lt;/a&gt;. No database because installing it, designing the schema for tracking requests and implementing data access in some HTTP server sounds like fun, but it would at least tripled the effort I wanted to put in.&lt;/p&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/images/posts/simpleton-analytics/goaccess-screenshot.png&#34;
    alt=&#34;Simpleton screenshot&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;I almost ended up writing a custom go HTTP server though. There is a neat golang utility called &lt;a href=&#34;https://github.com/caddyserver/certmagic&#34;&gt;certmagic&lt;/a&gt; which autonomously handles obtaining Let&amp;rsquo;s Encrypt certificates. Certmagic is used in the &lt;a href=&#34;https://github.com/caddyserver/caddy&#34;&gt;caddy&lt;/a&gt; server. Again, in the name of &lt;a href=&#34;https://blog.viktomas.com/posts/iteration/&#34;&gt;iteration&lt;/a&gt; and to keep the scope within one weekend, I decided to use caddy directly. But Caddy 2 is only using JSON logs that are not compatible with GoAccess&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;. Stubbornly trying to find a workaround for this issue took me almost the whole day before I gave up.&lt;/p&gt;
&lt;h2 id=&#34;sunday&#34;&gt;Sunday&lt;/h2&gt;
&lt;p&gt;I knew that if I kept banging my head into the Caddy wall, I can say goodbye to the weekend time box. So I settled for a more &lt;a href=&#34;https://about.gitlab.com/handbook/values/#boring-solutions&#34;&gt;boring solution&lt;/a&gt;: Nginx. Ngnix was created ten years before Let&amp;rsquo;s Encrypt&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;, and their integration is painful. You have to install more dependencies, and in the end, you run a script that &lt;strong&gt;modifies your existing config files&lt;/strong&gt; 😱&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;. There are virtually thousands of different blog articles describing how to do it.&lt;/p&gt;
&lt;p&gt;After adding a trivial &lt;code&gt;fetch()&lt;/code&gt; call to this blog site and fiddling a bit with the &lt;code&gt;referrer&lt;/code&gt; header (I had to pass &lt;code&gt;document.referrer&lt;/code&gt; to the call), I could see all page views nicely in the logs.&lt;/p&gt;
&lt;p&gt;Now I just needed to process the access logs with GoAccess. That was a pleasant surprise. GoAccess worked well out of the box. Both the terminal and the HTTP versions are great. An added bonus is that the terminal version shows you the page views in real-time.&lt;/p&gt;
&lt;p&gt;That concluded the weekend project. Simple analytics that worked great. I even wrote an article about my observation of how &lt;a href=&#34;https://blog.viktomas.com/posts/adblock-skews-analytics/&#34;&gt;AdBlockers hide the majority of visitors from web analytics&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;two-weeks-later&#34;&gt;Two weeks later&lt;/h2&gt;
&lt;p&gt;What is the default log retention for Nginx? You guessed it, two weeks. After two weeks, I started noticing that older logs are disappearing. Now I had a chance to learn about &lt;a href=&#34;https://linux.die.net/man/8/logrotate&#34;&gt;logrotate&lt;/a&gt;, a utility that runs every midnight on all Ubuntu distributions. It chunks your logs into day-long files, and it deletes these after some time.&lt;/p&gt;
&lt;p&gt;By default, it adds a suffix number to the log file and after two days compresses them. Day one you&amp;rsquo;ve got &lt;code&gt;access.log&lt;/code&gt; day three &lt;code&gt;access.log&lt;/code&gt;, &lt;code&gt;access.log.1&lt;/code&gt;, &lt;code&gt;access.log.2.gz&lt;/code&gt;. I&amp;rsquo;m not a fan of this default behaviour, and so I changed the configuration to use timestamps. All glory to &lt;code&gt;access.log-20200806.gz&lt;/code&gt; format.&lt;/p&gt;
&lt;h2 id=&#34;two-months-later&#34;&gt;Two months later&lt;/h2&gt;
&lt;p&gt;All the previous work was done by manual typing in commands and changing configuration files. I&amp;rsquo;ve created a &lt;a href=&#34;https://martinfowler.com/bliki/SnowflakeServer.html&#34;&gt;snowflake&lt;/a&gt;. After seeing that the server works well, I thought it&amp;rsquo;s a shame that nobody else can use it. So I wrote an ansible provisioning script that can install the analytics automatically. That spawned another weekend project that you &lt;a href=&#34;https://gitlab.com/viktomas/simpleton-analytics&#34;&gt;can benefit from right now&lt;/a&gt;. Ansible wasn&amp;rsquo;t the coolest choice, but it fitted the requirements (time, cost) the best.&lt;/p&gt;
&lt;p&gt;Now you can spin up your instance (I use $5 Digital Ocean) and try it for yourself. You only need five bucks and a domain.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.justbartek.ca/analytics-without-google/&#34;&gt;Analytics without Google&lt;/a&gt;, &lt;a href=&#34;https://www.digitalinklingsblog.com/my-messy-analytics-breakup/&#34;&gt;My Messy Analytics Breakup&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;The combined log format that GoAccess uses is out of scope for Caddy 2 &lt;a href=&#34;https://github.com/caddyserver/caddy/issues/3505&#34;&gt;GitHub issue&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Let%27s_Encrypt&#34;&gt;2014&lt;/a&gt; - &lt;a href=&#34;https://en.wikipedia.org/wiki/Nginx&#34;&gt;2004&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.nginx.com/blog/using-free-ssltls-certificates-from-lets-encrypt-with-nginx/&#34;&gt;Official blog article&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Terry Pratchett - Men at Arms</title>
      <link>https://blog.viktomas.com/books/pratchett-terry--men-at-arms/</link>
      <pubDate>Sun, 09 Aug 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/pratchett-terry--men-at-arms/</guid>
      <description>&lt;p&gt;After reading &lt;a href=&#34;https://blog.viktomas.com/books/pratchett-terry-guards-guards/&#34;&gt;Guards! Guards!&lt;/a&gt;, I was hooked to the Watch series and this book was no disappointment. Pratchett develops the peculiar characters of the Ankh-Morpork city night watch (Nobby, Carrot) even further and adds new watch members: a dwarf, a troll (I love Detritus), and an undead.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve listened to this book as an audiobook and people had to think I&amp;rsquo;m crazy when walking through the city and laughing out loud most of the time. This book is golden, especially when read by Nigel Planer.&lt;/p&gt;
&lt;p&gt;Next up: &lt;a href=&#34;https://www.goodreads.com/book/show/833426.Feet_of_Clay&#34;&gt;Feet of Clay&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Discworld#/media/File:Discworld_Reading_Order_Guide_3.0_(cropped).jpg&#34;&gt;&lt;img
    src=&#34;https://upload.wikimedia.org/wikipedia/commons/thumb/1/12/Discworld_Reading_Order_Guide_3.0_%28cropped%29.jpg/780px-Discworld_Reading_Order_Guide_3.0_%28cropped%29.jpg&#34;
    alt=&#34;Discworld reading order&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Source: Wikipedia&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Start working less to produce more, strange approach to prioritisation</title>
      <link>https://blog.viktomas.com/posts/stop-working-so-hard/</link>
      <pubDate>Sun, 02 Aug 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/stop-working-so-hard/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m going to talk about preventing burn out and getting a better sense of control at your job. I&amp;rsquo;ll explain why I think we feel overwhelmed at work. Lastly, I suggest setting a hard limit on reactive work, solution based on my own experience.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 400px&#34; src=&#34;https://blog.viktomas.com/images/posts/stop-working-so-hard.svg&#34; alt=&#34;Theme illustration&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Illustration&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;First, let&amp;rsquo;s have a look at what it looks like when you are overwhelmed from work. We&amp;rsquo;ll start by dividing work into two categories: Work that someone defined for you and work that you defined for yourself&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;The work that was defined for you is &lt;strong&gt;reactive&lt;/strong&gt;. You have less control over when and how you do it. Your boss asked you to review a document by tomorrow. You got an email with a complaint from a client. Your deadline is coming.&lt;/p&gt;
&lt;p&gt;The work that you defined for yourself is &lt;strong&gt;proactive&lt;/strong&gt;. You decided that the best thing for the product is stronger marketing, and you design a strategy. You know that the lathe at your workshop needs maintenance, and you&amp;rsquo;ll do it before it breaks. You document the common pain points in your product so users can quickly find answers to their problems.&lt;/p&gt;
&lt;p&gt;For the purpose of this article:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Being overwhelmed means having a disproportionate amount of work defined for you.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;You know your working process needs improvement, but there&amp;rsquo;s no time to stop and think, improve and learn. You entered a vicious cycle.&lt;/p&gt;
&lt;p&gt;When you are overwhelmed, it&amp;rsquo;s caused by insufficient prioritisation and possibly lacking delegation if you are in a position to delegate some of your work. I faced this situation on my previous project where there was virtually unlimited (and not prioritised) pile of work that needed to be done. If that wasn&amp;rsquo;t enough, there were user support requests and failing infrastructure. I&amp;rsquo;ve noticed that no matter how long I did this reactive work, there wasn&amp;rsquo;t a significant change in the value I produced.&lt;/p&gt;
&lt;p&gt;Countless methods explain how to get better at workload management. Some of the most influential books are &lt;a href=&#34;https://blog.viktomas.com/books/allen-david-getting-things-done/&#34;&gt;David Allen&amp;rsquo;s Getting Things Done&lt;/a&gt; and &lt;a href=&#34;https://www.goodreads.com/book/show/36072.The_7_Habits_of_Highly_Effective_People&#34;&gt;Stephen Covey&amp;rsquo;s The 7 Habits of Highly Effective People&lt;/a&gt;. Instead of writing a summary of these books, I want to focus on a specific aspect of handling large workloads: Budgeting&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;, which is prioritisation supported by hard time boxing&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;My argument is built on the assumption that not all work is as urgent as it seems. I&amp;rsquo;ll explain that limiting the overall time you spend on reactive work won&amp;rsquo;t hurt your business or job as much as you&amp;rsquo;d think.&lt;/p&gt;
&lt;h2 id=&#34;reducing-time-for-reactive-work-forces-prioritisation&#34;&gt;Reducing time for reactive work forces prioritisation&lt;/h2&gt;
&lt;p&gt;What will happen when you reduce the commitment to the reactive work by a third? Instead of reacting nine hours a day, you&amp;rsquo;ll react six? From my experience: &lt;strong&gt;nothing much&lt;/strong&gt;. Users have to wait longer to get your response. Some conversations will fall through the cracks. A handful of people get really upset because you won&amp;rsquo;t have time to fulfil their requests. That&amp;rsquo;s it.&lt;/p&gt;
&lt;p&gt;When you do this, you will get a few more unpleasant conversations, but you&amp;rsquo;ll get three hours of your life back every day. Instead of finishing late, you can now finish on time.&lt;/p&gt;
&lt;p&gt;Even better, you have &lt;strong&gt;two hours&lt;/strong&gt; to work on something that you define for yourself. In these two hours, you can improve the process, improve documentation, automate some part of your work, or just finish early to recharge your batteries. The added benefit is that the proactive work starts in mid-term, reducing your reactive work. You&amp;rsquo;ll enter a virtuous cycle&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Prioritisation is the best productivity method because not doing something saves more energy than doing it efficiently. By limiting the time you spend on reactive work, you force yourself to prioritise more. This is the same approach that Basecamp uses for their software development process&lt;sup id=&#34;fnref1:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;They limit each project to six weeks. The time limit won&amp;rsquo;t change, only the scope of the project will. When they know they&amp;rsquo;ve got only six weeks, it&amp;rsquo;s easier to make the decision about what to include and what to leave out. The same applies when you limit your reactive part of your workday to six hours. Six hours is fixed, the content of those six hours is up to you. Not everything is going to make it, and you have to pick the crucial bits.&lt;/p&gt;
&lt;p&gt;I found this method naturally as I was burning out on my previous project. I couldn&amp;rsquo;t do the reactive part of my work for eight-plus hours any more. As I reduced the time, I started by just finishing early. For the first couple of weeks, I worked only those six hours, recharging my batteries. But then, I started having energy and motivation to define some of my own work. I improved the user support process and automated some of my tasks.&lt;/p&gt;
&lt;p&gt;I highly recommend trying this if you find yourself reacting to external stimuli the whole day. The sense of control and much-needed rest is going to be worth those few more unpleasant conversations.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;I borrowed this classification from &lt;a href=&#34;https://blog.viktomas.com/books/allen-david-getting-things-done/&#34;&gt;Getting Things Done&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;The term budgeting is from the &amp;ldquo;It Doesn&amp;rsquo;t Have to Be Crazy at Work, and it&amp;rsquo;s described as appetite in the &lt;a href=&#34;https://basecamp.com/shapeup/1.2-chapter-03#fixed-time-variable-scope&#34;&gt;Shape Up&lt;/a&gt; by Ryan Singer&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.viktomas.com/books/fried-hansson--it-doesnt-have-to-be-crazy-at-work/&#34;&gt;Fried, Hansson - It Doesn&amp;rsquo;t Have to Be Crazy at Work&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref1:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Virtuous_circle_and_vicious_circle&#34;&gt;Virtuous cycle on Wikipedia&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Designing a digital pirate map</title>
      <link>https://blog.viktomas.com/posts/digital-pirate-map/</link>
      <pubDate>Sat, 25 Jul 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/digital-pirate-map/</guid>
      <description>&lt;p&gt;When I was little, I loved pirate tales. There was always a great deal of adventure and exotic lands. And one more thing was almost given: There is going to be a treasure, and someone is going to have the map. Without the map, you don&amp;rsquo;t get the treasure.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 380px&#34; src=&#34;https://blog.viktomas.com/images/posts/digital-pirate-map.svg&#34; alt=&#34;Theme illustration&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Illustration&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Today we are going to design a digital pirate map. A service where you can hide a text secret (treasure) and only you can ever find it.&lt;/p&gt;
&lt;p&gt;When I wrote about &lt;a href=&#34;https://blog.viktomas.com/posts/losing-google-account/&#34;&gt;losing your Google account&lt;/a&gt; I thought about where I could hide the recovery keys for my services. My idea was to put them in my parent&amp;rsquo;s house or put them in a time capsule and hide them in my backyard. We will do better than that.&lt;/p&gt;
&lt;h2 id=&#34;how-will-it-look&#34;&gt;How will it look&lt;/h2&gt;
&lt;p&gt;Imagine a website like Google Maps, just more piraty.&lt;/p&gt;
&lt;h3 id=&#34;saving-secrets&#34;&gt;Saving secrets&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Enter your date of birth&lt;/li&gt;
&lt;li&gt;Click on a map&lt;/li&gt;
&lt;li&gt;Store your secret&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;reading-secrets&#34;&gt;Reading secrets&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;Enter your date of birth&lt;/li&gt;
&lt;li&gt;Click on a map (you need to click within 5m radius)&lt;/li&gt;
&lt;li&gt;See your secret&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This service would be used for secrets recovery and time capsule type of information so we can&amp;rsquo;t ask people to enter a password. That would be like looking for a torch, at night, without a torch. However, we can&amp;rsquo;t just let users click on the map and show them the secret because someone might create a meter by meter grid and ask for all passwords in an area.&lt;/p&gt;
&lt;p&gt;We need information about the user that they&amp;rsquo;ll never forget, but it won&amp;rsquo;t identify them too closely. The second property is going to be useful if someone hacks the service. We are going to use &lt;strong&gt;the date of birth&lt;/strong&gt;. Knowing that someone born on the second of September 1974 stored &lt;code&gt;youllneverguessmypassword&lt;/code&gt; secret at the foot of the Empire State Building in New York is not as useful to the hacker as knowing that it was Timothy Hammerworth.&lt;/p&gt;
&lt;h2 id=&#34;encryption&#34;&gt;Encryption&lt;/h2&gt;
&lt;p&gt;The secretes must be encrypted so they can&amp;rsquo;t get compromised if/when someone hacks the server. Requiring the user to remember a strong password would defeat the purpose. We want people to get their secrets just by knowing the location on the map.&lt;/p&gt;
&lt;h3 id=&#34;naive-solution-that-wont-scale&#34;&gt;Naive solution that won&amp;rsquo;t scale&lt;/h3&gt;
&lt;p&gt;When you click on a map, the click gets translated to GPS coordinates like &lt;a href=&#34;https://www.google.com/maps/place/48%C2%B051&#39;29.9%22N+2%C2%B017&#39;39.9%22E/@48.8583039,2.2938668,19z&#34;&gt;(&lt;code&gt;48.858303&lt;/code&gt;, &lt;code&gt;2.294414&lt;/code&gt;)&lt;/a&gt;. This coordinate is then used as a password and encrypts your secret. Later, when the service wants to find out whether there is a secret under a given coordinate, it needs to try to decrypt every secret on the server.&lt;/p&gt;
&lt;p&gt;This wouldn&amp;rsquo;t scale. Even if one decryption attempt took only 10 ms, with a thousand secrets, we would have to wait ten seconds for each response. You click, you wait ten seconds, you get an answer. All the while, hoping there is no one else using the service.&lt;/p&gt;
&lt;p&gt;We will improve on this solution by categorising these encrypted secrets by user&amp;rsquo;s date of birth. So when someone tries to retrieve a secret, we only need to decrypt all the secrets stored for their date of birth. This speeds up the process by several orders of magnitude, but it still starts to break down if there are more than 100 secrets for the same date of birth.&lt;/p&gt;
&lt;h2 id=&#34;general-issues&#34;&gt;General issues&lt;/h2&gt;
&lt;h3 id=&#34;map-precision&#34;&gt;Map precision&lt;/h3&gt;
&lt;p&gt;If we set the required precision to 5m, then we are strongly dependent on the map visual accuracy. I&amp;rsquo;m not sure whether the GPS coordinates always land on the same visual representation on a map, e.g. corner of a house. How would Google Maps compare with Open Street Maps? Would there be a strong lock-in with one provider? If this provider updates their maps, are people going to lose their secrets?&lt;/p&gt;
&lt;h3 id=&#34;rounding-up-coordinates&#34;&gt;Rounding up coordinates&lt;/h3&gt;
&lt;p&gt;The service can&amp;rsquo;t allow just any coordinates. That would mean that you have to click with centimetre accuracy. We would need to round the coordinate numbers. Every click in a 5m x 5m square needs to produce the exact same coordinates used as an encryption password. Visually this could be solved by having 5m x 5m grid tiles on the map. This would be more complicated, the world is not a square that we could fill with 5m x 5m squares.&lt;/p&gt;
&lt;h2 id=&#34;are-we-going-to-build-it&#34;&gt;Are we going to build it?&lt;/h2&gt;
&lt;p&gt;This idea got me excited and reminded me of my childhood where I was hiding things in the backyard and imagined that those are pirate treasures.&lt;/p&gt;
&lt;p&gt;Decrypting a larger number of secrets is going to be demanding on computation resources and hence expensive. There could be potentially some subscription fee. &lt;em&gt;Pay $10 to save a secret.&lt;/em&gt; But the service would first have to run for years to have the level of trust required for such payment.&lt;/p&gt;
&lt;p&gt;Unless we could make the encryption and decryption process extremely cheap, I wouldn&amp;rsquo;t want to build this cool thing.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Fried, Hansson - It Doesn&#39;t Have to Be Crazy at Work</title>
      <link>https://blog.viktomas.com/books/fried-hansson--it-doesnt-have-to-be-crazy-at-work/</link>
      <pubDate>Sun, 19 Jul 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/fried-hansson--it-doesnt-have-to-be-crazy-at-work/</guid>
      <description>&lt;p&gt;This is the third book from the duo Jason Fried and David Heinemeier Hansson. Rework was about product design, Remote was about remote work, this one is about company culture and processes to support deep work.&lt;/p&gt;
&lt;p&gt;I am fortunate enough to work at GitLab where we implemented the majority of the processes described in this book (&lt;a href=&#34;https://about.gitlab.com/handbook/&#34;&gt;GitLab Handbook&lt;/a&gt;). But few concepts were exciting, and they applied to my personal life and side projects.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Prioritisation is the best productivity method.&lt;/strong&gt; You can optimise how many things can you do during a day and how well, but nothing gives you as much efficiency as &lt;strong&gt;not&lt;/strong&gt; doing something. Prioritisation helps you not to optimise work that doesn&amp;rsquo;t have to happen at all.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Optimising workspace for deep work.&lt;/strong&gt; GitLab is great at this, and the book gave me a vocabulary to talk about this phenomena. You want to put respect for other people&amp;rsquo;s time and attention at the forefront of your company&amp;rsquo;s processes. Examples: People can&amp;rsquo;t see each other calendars, so it makes it hard to organise meetings. No decisions should happen in real-time chat, so you don&amp;rsquo;t have to be always online or risk missing out.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Budgeting vs Estimation.&lt;/strong&gt; People are bad at estimating, but good at budgeting. Ask them how long feature X is going to take, and you won&amp;rsquo;t get a precise answer, but tell them to get as close to feature X as you can in 6 weeks (budgeting), and they will do a good job.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Three principles distilled from Getting Things Done</title>
      <link>https://blog.viktomas.com/posts/gtd-concepts/</link>
      <pubDate>Sun, 19 Jul 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/gtd-concepts/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://blog.viktomas.com/books/allen-david-getting-things-done/&#34;&gt;Getting Things Done&lt;/a&gt; (GTD) is a method of managing your work. David Allen published it 19 years ago as a result of his life&amp;rsquo;s work coaching executives. The method takes time and effort to implement, but the key concepts behind it can benefit you today. This article explains the building blocks of GTD and how they help you clear your head from all unfinished work.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 300px&#34; src=&#34;https://blog.viktomas.com/images/posts/gtd-concepts.svg&#34; alt=&#34;Theme illustration&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Illustration&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;the-core-idea-of-gtd&#34;&gt;The core idea of GTD&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;You can keep all unfinished tasks and thinking in an external note-taking system and not have them in your head.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Each one of the following concepts is helping you with moving the responsibility for remembering things from your mind to your system.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;One place&lt;/strong&gt; - You store all your notes in one system with a clear structure. You separate notes that do and don&amp;rsquo;t need your action.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Next Action format&lt;/strong&gt; - Any note that still needs your action has a specific structure.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Weekly revision&lt;/strong&gt; - You are continuously revising your notes, so no important note gets forgotten.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If your productivity system has these three elements, it will allow you to stop thinking about unfinished tasks, regardless of whether you follow GTD to the latter.&lt;/p&gt;
&lt;h3 id=&#34;one-place&#34;&gt;One place&lt;/h3&gt;
&lt;p&gt;How many places would you now have to check to get all our outstanding work? Email, calendar, task list app on your phone, plain-text TODOs on your computer, paper notes, and your head. You can&amp;rsquo;t guarantee that you are going to look to that one spot where you made the critical note. So you subconsciously can&amp;rsquo;t let the important tasks out of your mind, and they will still occupy your mental space.&lt;/p&gt;
&lt;p&gt;If you consciously replace all these systems with one, you don&amp;rsquo;t have to worry about where to look for a note or whether you&amp;rsquo;ve got a complete picture. Combined with the next two principles, it will allow your mind to forget about the task temporarily and leave your note-taking system to keep track of it.&lt;/p&gt;
&lt;p&gt;There is an exception to the one place principle: &lt;strong&gt;Calendar&lt;/strong&gt;. Anything that has to happen at a particular time goes to your calendar. The calendar is just too damn good at keeping temporal information to try to substitute it by a note-taking app.&lt;/p&gt;
&lt;h3 id=&#34;next-action-format&#34;&gt;Next Action format&lt;/h3&gt;
&lt;p&gt;David Allen introduces the concept of &amp;ldquo;Stuff&amp;rdquo;. Stuff is anything that you need to do something about. You&amp;rsquo;ve made a commitment to yourself or to others to change something.&lt;/p&gt;
&lt;p&gt;An example of stuff is &lt;em&gt;&amp;ldquo;Car needs fixing&amp;rdquo;&lt;/em&gt; or just &lt;em&gt;&amp;ldquo;Car&amp;rdquo;&lt;/em&gt;. If your TODO lists are like mine used to be, they are full of such reminders. &lt;em&gt;&amp;ldquo;Car&amp;rdquo;&lt;/em&gt; tells you that something needs to be done, but it doesn&amp;rsquo;t say what. The vagueness of such note helps you procrastinate.&lt;/p&gt;
&lt;p&gt;Contrast that with the &lt;strong&gt;Next Action&lt;/strong&gt; note format: What is the very next &lt;strong&gt;physical&lt;/strong&gt; action that you need to take to move this thing forward? You need to be able to close your eyes and see yourself doing the physical activity and see the outcome.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Car&amp;rdquo;&lt;/em&gt; changes to &lt;em&gt;&amp;ldquo;Call my friend Jim and ask him for contact information of the mechanic he was so happy with&amp;rdquo;&lt;/em&gt;. Don&amp;rsquo;t worry about what happens next. You&amp;rsquo;ll come up with the Next Next Action after you&amp;rsquo;ve done this one.&lt;/p&gt;
&lt;p&gt;You should often process all your &amp;ldquo;stuff&amp;rdquo; and turn it into next actions or archived notes for reference.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Pro tip: If you come up with the next action and it takes less than two minutes, &lt;strong&gt;do it straight away&lt;/strong&gt;&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3 id=&#34;weekly-revision&#34;&gt;Weekly revision&lt;/h3&gt;
&lt;p&gt;Regularly revisiting my notes is where my previous system lacked the most.&lt;/p&gt;
&lt;p&gt;Revising your notes means archiving notes that you don&amp;rsquo;t need to do anything about any more. It means organising the notes that need action into lists and picking the ones you can do something about the next week.&lt;/p&gt;
&lt;p&gt;If you don&amp;rsquo;t do this, there is a good chance that some important outstanding task gets lost in the older and dusty parts of your system. When that happens, your mind is going to realise that it can&amp;rsquo;t trust the system, and it will take back the responsibility for remembering all outstanding work.&lt;/p&gt;
&lt;p&gt;Without the weekly revision, you also don&amp;rsquo;t know whether the next actions you work on are the most important work you could be doing. Maybe the note that you created a few weeks ago is now more important.&lt;/p&gt;
&lt;p&gt;You should revisit your priorities and maybe put some things on a back burner, so you can focus on the things that matter now. This process takes just over an hour each week, but that&amp;rsquo;s pennies when you consider how much mental space this activity frees up.&lt;/p&gt;
&lt;h2 id=&#34;gtd-in-detail&#34;&gt;GTD in detail&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.viktomas.com/books/allen-david-getting-things-done/&#34;&gt;The book&lt;/a&gt; has dense 270 pages, and this summary contains only the principles that struck me the most. You can read the book if you are interested in the details of the method. If you don&amp;rsquo;t have that much time, I recommend &lt;a href=&#34;https://hamberg.no/gtd/&#34;&gt;Erlend Hamberg&amp;rsquo;s GTD guide&lt;/a&gt;. It doesn&amp;rsquo;t push any software agenda, and it&amp;rsquo;s nicely illustrated.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve implemented these concepts just under a month ago. Once I feel I have a good grasp of the practical details, I&amp;rsquo;m going to share much more practical workflow with the tools I&amp;rsquo;m using for my system.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Read the book &lt;a href=&#34;https://blog.viktomas.com/books/allen-david-getting-things-done/&#34;&gt;Getting Things Done&lt;/a&gt; from David Allen to get many more tips with deeper explanation.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>How to create animated gif from multiple images with ImageMagick</title>
      <link>https://blog.viktomas.com/posts/making-animated-gif/</link>
      <pubDate>Sun, 12 Jul 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/making-animated-gif/</guid>
      <description>&lt;p&gt;Read this tutorial if you have several images and you would like to make them into an animated gif.&lt;/p&gt;
&lt;p&gt;This quick tutorial is going to work best for you if you are on Mac OS and you know how to run commands in the terminal. Every Unix system should work fine; you&amp;rsquo;ll just need to install the dependencies differently.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: This article is much more technical than what I usually write, let me know if you like👍 or dislike👎 it.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;install-prerequisites-and-get-your-images-ready&#34;&gt;Install prerequisites and get your images ready&lt;/h2&gt;
&lt;p&gt;This section uses Mac OS &lt;a href=&#34;https://brew.sh/&#34;&gt;homebrew&lt;/a&gt; package manager, but you can find the dependencies on any Unix system.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Install &lt;a href=&#34;https://imagemagick.org/&#34;&gt;ImageMagick&lt;/a&gt; with &lt;code&gt;brew install imagemagick&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Install &lt;a href=&#34;https://www.gimp.org/&#34;&gt;Gimp&lt;/a&gt; with &lt;code&gt;brew cask install gimp&lt;/code&gt;.
&lt;ul&gt;
&lt;li&gt;Skip installing Gimp if you don&amp;rsquo;t need to custom crop your images.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now put your images in one folder. Alphabetical order of the file names will decide the order in which the pictures show in the animation.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;└── folder-for-images
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├── 2020-07-07.jpg
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├── 2020-07-08.jpg
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├── 2020-07-09.jpg
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    └── 2020-07-10.jpg
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you need more complex renaming and you are not a shell scripting guru, have a look at &lt;a href=&#34;https://github.com/laurent22/massren&#34;&gt;&lt;code&gt;massren&lt;/code&gt;&lt;/a&gt;. It lets you use your favourite editor to rename multiple files.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s move to the gif making.&lt;/p&gt;
&lt;h2 id=&#34;step-0-custom-crop-your-images-optional&#34;&gt;Step 0: Custom crop your images (optional)&lt;/h2&gt;
&lt;p&gt;This step is optional and is only necessary if your images contain the subject of animation in different spots, For example, if you were taking screenshots, and each image has a different aspect ratio.&lt;/p&gt;
&lt;p&gt;This step takes the largest portion of the time, so try to avoid it at the time you are getting the pictures.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Goal&lt;/strong&gt;: Make sure that all the images contain the same object at the same spot.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;&lt;/th&gt;
          &lt;th&gt;first&lt;/th&gt;
          &lt;th&gt;second&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;before&lt;/td&gt;
          &lt;td&gt;&lt;img
    src=&#34;https://blog.viktomas.com/images/posts/making-animated-gif/core-small0.png&#34;
    alt=&#34;core-small0.png&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/td&gt;
          &lt;td&gt;&lt;img
    src=&#34;https://blog.viktomas.com/images/posts/making-animated-gif/core-small1.png&#34;
    alt=&#34;core-small1.png&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;after&lt;/td&gt;
          &lt;td&gt;&lt;img
    src=&#34;https://blog.viktomas.com/images/posts/making-animated-gif/cropped-core0.png&#34;
    alt=&#34;cropped-core0.png&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/td&gt;
          &lt;td&gt;&lt;img
    src=&#34;https://blog.viktomas.com/images/posts/making-animated-gif/cropped-core1.png&#34;
    alt=&#34;cropped-core1.png&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;ol&gt;
&lt;li&gt;Drag all the images into Gimp window&lt;/li&gt;
&lt;li&gt;Select the crop tool &lt;img
    src=&#34;https://blog.viktomas.com/images/posts/making-animated-gif/crop-tool.png&#34;
    alt=&#34;crop tool&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/li&gt;
&lt;li&gt;Zoom in &lt;img
    src=&#34;https://blog.viktomas.com/images/posts/making-animated-gif/zoom.png&#34;
    alt=&#34;zoom&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/li&gt;
&lt;li&gt;Crop each image and export it. (&lt;code&gt;File&lt;/code&gt; -&amp;gt; &lt;code&gt;Export as&lt;/code&gt;)&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id=&#34;step-1-use-imagemagick-to-create-the-gif&#34;&gt;Step 1: Use ImageMagick to create the gif&lt;/h2&gt;
&lt;p&gt;Now we run one command that will do all the work. The command is not changing the current images so you don&amp;rsquo;t have to worry about losing your data.&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;cd folder-for-images
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;convert &lt;span style=&#34;color:#a31515&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;&lt;/span&gt;  2020*.jpg &lt;span style=&#34;color:#a31515&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;&lt;/span&gt;  -gravity center -crop 1:1 +repage &lt;span style=&#34;color:#a31515&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;&lt;/span&gt;  -resize 800x800 &lt;span style=&#34;color:#a31515&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;&lt;/span&gt;  -set delay 50 &lt;span style=&#34;color:#a31515&#34;&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;&lt;/span&gt;  animation.gif
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;explaining-the-command&#34;&gt;Explaining the command&lt;/h3&gt;
&lt;p&gt;The &lt;code&gt;convert&lt;/code&gt; command is part of the &lt;a href=&#34;#install-prerequisites-and-get-your-images-ready&#34;&gt;ImageMagick&lt;/a&gt; installation.&lt;/p&gt;

&lt;div class=&#34;mermaid&#34; align=&#34;center&#34;&gt;graph TD;
A[&#34;Gather image files&#34;] --&gt; B
B[&#34;Corp images to aspect ratio (optional)&#34;] --&gt; C
C[&#34;Resize images (optional)&#34;] --&gt; D
D[&#34;Set animation delay&#34;]&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;2020*.jpg&lt;/code&gt; - &lt;strong&gt;Gather image files&lt;/strong&gt; - we&amp;rsquo;ll process all jpg files in the folder starting with &lt;code&gt;2020&lt;/code&gt;. You can change the glob pattern or the extension.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-gravity center -crop 1:1 +repage&lt;/code&gt; - &lt;strong&gt;Corp images to aspect ratio (optional)&lt;/strong&gt; - we&amp;rsquo;ll crop the images to have the same width and height (&lt;code&gt;1:1&lt;/code&gt;) and we&amp;rsquo;ll crop around the &lt;code&gt;center&lt;/code&gt; of the image. Then we &lt;code&gt;+repage&lt;/code&gt; the canvas to reflect the new aspect ratio.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-resize 800x800&lt;/code&gt; - &lt;strong&gt;Resize images (optional)&lt;/strong&gt; - If you publish your gif on the internet, it&amp;rsquo;s a good idea to make it smaller so people can quickly fetch it. &lt;code&gt;800x800&lt;/code&gt; is in pixels, and it matches the previously set &lt;code&gt;1:1&lt;/code&gt; aspect ratio. &lt;code&gt;convert&lt;/code&gt; will always preserve the original aspect ratio, and so the specified dimensions present an upper limit.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;-set delay 50&lt;/code&gt; - &lt;strong&gt;Set animation delay&lt;/strong&gt; - wait 50 ms before showing the next image in the gif&lt;/li&gt;
&lt;li&gt;&lt;code&gt;animation.gif&lt;/code&gt; - Name of the output file. Has to end with &lt;code&gt;.gif&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;examples&#34;&gt;Examples&lt;/h2&gt;
&lt;h3 id=&#34;gif-from-photos&#34;&gt;Gif from photos&lt;/h3&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/images/posts/making-animated-gif/animation.gif&#34;
    alt=&#34;Animated cactus&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;h3 id=&#34;gif-from-screenshots&#34;&gt;Gif from screenshots&lt;/h3&gt;
&lt;p&gt;This one is from my previous article: &lt;a href=&#34;https://blog.viktomas.com/posts/one-hit-wonder-on-hn/&#34;&gt;How my article became one-hit-wonder on hacker news&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/images/posts/one-hit-wonder-hn/medium.gif&#34;
    alt=&#34;HN front page&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>David Allen - Getting Things Done</title>
      <link>https://blog.viktomas.com/books/allen-david--getting-things-done/</link>
      <pubDate>Wed, 08 Jul 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/allen-david--getting-things-done/</guid>
      <description>&lt;p&gt;This book had to be revolutionary during its time (2001), but even though the book was updated in 2015, it feels lagging in time. Especially the parts where the author focuses on in-trays and office supplies as the primary tools for staying organised are not useful. Those sections can be, in my opinion, completely skipped if you spend most of your day working with a computer.&lt;/p&gt;
&lt;p&gt;The core ideas, on the other hand, are as valid as they ever were.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Put everything from your head into a note-taking app&lt;/li&gt;
&lt;li&gt;Make sure that instead of generic “broken car” you track specific next actions “call Dave to get a contact for the car mechanic he recommended”&lt;/li&gt;
&lt;li&gt;Have distinct categories where you put a different type of information, so you don’t have to think about categorising&lt;/li&gt;
&lt;li&gt;Review all your outstanding work once a week so you can trust your system being up to date&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Rather than reading the whole book as I did, I recommend reading an abstract (e.g. getAbstract.com) or one of the &lt;a href=&#34;https://hamberg.no/gtd&#34;&gt;good blog articles&lt;/a&gt; explaining the methodology (my own coming up too).&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>How my article became one-hit-wonder on hacker news</title>
      <link>https://blog.viktomas.com/posts/one-hit-wonder-on-hn/</link>
      <pubDate>Sun, 05 Jul 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/one-hit-wonder-on-hn/</guid>
      <description>&lt;p&gt;Today I&amp;rsquo;m going to tell the story of fleeting success. You&amp;rsquo;ll learn how my article reached the hacker news front page. And how it stayed there for two whole days, changing my perception about what is achievable with my writing hobby.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 300px&#34; src=&#34;https://blog.viktomas.com/images/posts/one-hit-wonder-on-hn.svg&#34; alt=&#34;Theme illustration&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Illustration&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I started this blog as a new year&amp;rsquo;s resolution for 2020. One article per week. I didn&amp;rsquo;t have gigantic aspirations. I wanted to learn how to express myself better because &lt;a href=&#34;https://blog.viktomas.com/posts/remote/&#34;&gt;remote work&lt;/a&gt; is all about written communication. And I wanted to share thoughts about my interests.&lt;/p&gt;
&lt;p&gt;First two months I didn&amp;rsquo;t publish the articles I wrote. I didn&amp;rsquo;t want to create yet another blog with only a handful posts in it. The writing had to become a habit first.&lt;/p&gt;
&lt;p&gt;After I started publishing on this site, I didn&amp;rsquo;t share it with anybody until late April when I mentioned &lt;a href=&#34;https://blog.viktomas.com/posts/plaintext-passwords/&#34;&gt;an article&lt;/a&gt; on &lt;a href=&#34;https://news.ycombinator.com/item?id=22914281&#34;&gt;hacker news&lt;/a&gt; for the first time. Two people liked it, and about fifty read it according to my analytics.&lt;/p&gt;
&lt;p&gt;On Sunday 3rd of May 2020 at 9 AM (CET) I mention my article &lt;a href=&#34;https://blog.viktomas.com/posts/losing-google-account/&#34;&gt;&amp;ldquo;What would you do if you lost your Google account?&amp;rdquo;&lt;/a&gt; on &lt;a href=&#34;https://news.ycombinator.com/item?id=23057365&#34;&gt;hacker news&lt;/a&gt;. I was expecting the same results: a couple dozen people read it, a few would like it. But with strike of luck, plenty of people liked the article and of it went to the front page.&lt;/p&gt;
&lt;p&gt;By 10 AM, fifteen hundred people visited the site, four times the number of visits since I started the blog. In the following 24 hours, another ten thousand people viewed the blog, and by the time the article left the front page on Monday, &lt;strong&gt;sixteen thousand people&lt;/strong&gt; have read it&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. The real number is going to be over thirty thousand because &lt;a href=&#34;https://blog.viktomas.com/posts/adblock-skews-analytics/&#34;&gt;60% of hacker news readers don&amp;rsquo;t show in analytics thanks to AdBlock&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I was ecstatic. The whole day I was walking with a wide grin on my face. I immediately googled the WikiHow article on &lt;a href=&#34;https://www.wikihow.com/Handle-Fame&#34;&gt;How To handle fame&lt;/a&gt;. And I took plenty of screenshots because I thought that the article is bound to drop off from the front page after a few minutes and I wanted to have a memory.&lt;/p&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/images/posts/one-hit-wonder-hn/medium.gif&#34;
    alt=&#34;&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;There was a trickle of people coming to see the article ever since. Now about fifty people view the article each week.&lt;/p&gt;
&lt;p&gt;The time of my two-day fame has now passed, but I took away valuable lessons.&lt;/p&gt;
&lt;p&gt;The first lesson is that I can produce something of value outside of my programming job. I knew I design and write high-quality code and systems and I get well paid for doing that. However, this experience showed me that I could create something else people enjoy.&lt;/p&gt;
&lt;p&gt;The second lesson is the type of article people enjoy. The generic articles about &lt;a href=&#34;https://blog.viktomas.com/posts/foss/&#34;&gt;FOSS&lt;/a&gt; and &lt;a href=&#34;https://blog.viktomas.com/posts/meditation-introduction/&#34;&gt;Meditation&lt;/a&gt; are presumably not as interesting as the more down-to-earth articles that contain a few howtos that people can apply straight away. Since the &amp;ldquo;loosing your google account&amp;rdquo; article this story repeated itself once more with the &lt;a href=&#34;https://blog.viktomas.com/posts/slip-box/&#34;&gt;Zettlekasten article&lt;/a&gt;. This strengthens my hypothesis that the article needs to provide useful, applicable tool/information to the readers, not just abstract food for thought.&lt;/p&gt;
&lt;p&gt;I liked Robert Heaton&amp;rsquo;s &lt;a href=&#34;https://robertheaton.com/2019/09/24/how-to-come-up-with-blog-post-ideas/&#34;&gt;Made-Up-Award principle&lt;/a&gt;: you should write your article to be the best in some narrow category. Exaggerated example: &amp;ldquo;best introduction to ruby programming for marketing experts focusing on food marketing&amp;rdquo;. Another important rule for me is that I have to wish I found that article a few days/weeks before because it would help me solve a problem.&lt;/p&gt;
&lt;p&gt;This event gave me just enough extrinsic motivation to help me overcome the initial period when I was considering whether I want to spend eight hours each week writing an article that fifty people read. It helped me to commit to writing as the next of my many hobbies.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;The numbers are from Mixpanel analytics. I copied them from a conversation with my friend because the Mixpanel stats have been long lost thanks to me exceeding the monthly limit.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Terry Pratchett - Guards! Guards!</title>
      <link>https://blog.viktomas.com/books/pratchett-terry--guards-guards/</link>
      <pubDate>Fri, 03 Jul 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/pratchett-terry--guards-guards/</guid>
      <description>&lt;p&gt;This is the fantasy series I was looking for. After reading this book, I&amp;rsquo;m using the &lt;a href=&#34;https://i.stack.imgur.com/339aO.jpg&#34;&gt;Discworld reading guide&lt;/a&gt; to binge read all the watch novels.&lt;/p&gt;
&lt;p&gt;This book is following the story of a police unit in a city where crime is legalized and encouraged. This way, you run into hilarious situations like being persecuted for arresting the head thief or having troubles for suggesting that assassins are murderers.&lt;/p&gt;
&lt;p&gt;If that wasn&amp;rsquo;t funny enough, you&amp;rsquo;ve got the constable Carrot, two-meter tall man who was raised by dwarfs and considers himself being one. He sometimes goes into the cellar and bashes himself in the head with an axe handle to remind himself of the good times in the mine.&lt;/p&gt;
&lt;p&gt;Overall, I haven&amp;rsquo;t had this many laughing out loud moments with a book since reading &lt;a href=&#34;https://www.goodreads.com/book/show/16181775-the-rosie-project&#34;&gt;The Rosie Project&lt;/a&gt;. I started reading Men At Arms - so far, I&amp;rsquo;m not disappointed.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>AdBlockers hide the majority of visitors from web analytics</title>
      <link>https://blog.viktomas.com/posts/adblock-skews-analytics/</link>
      <pubDate>Sun, 28 Jun 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/adblock-skews-analytics/</guid>
      <description>&lt;p&gt;I used Mixpanel analytics to tell me how many people are reading my articles. Recently I implemented my custom analytics. I was astonished when my custom analytics showed me more than twice the number of page views than the numbers from Mixpanel. AdBlock was hiding sixty per cent of my site&amp;rsquo;s visitors from Mixpanel.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 350px&#34; src=&#34;https://blog.viktomas.com/images/posts/adblock-skews-analytics.svg&#34; alt=&#34;Theme illustration&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Illustration&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;Everyone who publishes on the internet loves analytics. It&amp;rsquo;s a big part of the writing feedback process. That&amp;rsquo;s why I included analytics on this blog. I decided to use &lt;a href=&#34;https://mixpanel.com/&#34;&gt;Mixpanel&lt;/a&gt; because I value my user&amp;rsquo;s &lt;a href=&#34;https://blog.viktomas.com/posts/privacy/&#34;&gt;privacy&lt;/a&gt;. As far as I was able to tell, Mixpanel is not using the captured user data for advertisement. I only wanted to know that &lt;em&gt;someone&lt;/em&gt; visited my blog; I didn&amp;rsquo;t need all the detailed user demographic you get from Google Analytics.&lt;/p&gt;
&lt;p&gt;MixPanel is a terrific tool, but the free plan only allows for a thousand monthly users. When I published my &lt;a href=&#34;https://blog.viktomas.com/posts/slip-box/&#34;&gt;Zettelkasten article&lt;/a&gt;, I exceeded my limit by order of magnitude. The plan that would handle small bursts of traffic like that would cost me $400 a month, a clear overkill for my humble blog. So I decided to create my custom analytics.&lt;/p&gt;
&lt;h2 id=&#34;my-custom-analytics&#34;&gt;My custom analytics&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve seen articles on Hacker News about blog authors creating their custom analytics&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, and I thought: &amp;ldquo;Why shouldn&amp;rsquo;t I do the same?&amp;rdquo; The only requirement: If a page gets opened in a browser I want to know about it. No funnels, no cookies, no demographics.&lt;/p&gt;
&lt;p&gt;Every time someone loads a page on this blog, the browser sends a ping to my server. The server captures the ping as an nginx access log entry&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;. I store the IP address, User-Agent (the browser type), the page visited, and the referrer&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt; if the browser shares it.&lt;/p&gt;
&lt;p&gt;I use &lt;a href=&#34;https://goaccess.io/&#34;&gt;goaccess&lt;/a&gt; to process the logs and get useful statistics. I&amp;rsquo;m planning on &lt;a href=&#34;https://blog.viktomas.com/posts/foss/&#34;&gt;open-sourcing&lt;/a&gt; the whole setup once I extensively tested it.&lt;/p&gt;
&lt;h2 id=&#34;the-difference&#34;&gt;The difference&lt;/h2&gt;
&lt;p&gt;After building my custom analytics, I created one more test account on Mixpanel to compare the results, and I was astonished by the difference in page view numbers. The only explanation is that AdBlockers like &lt;a href=&#34;https://getublock.com/&#34;&gt;UBlock Origin&lt;/a&gt; block the Mixpanel tracking.&lt;/p&gt;
&lt;p&gt;The following numbers are for the period between 14th and 26th June 2020.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Total page views in Mixpanel: &lt;strong&gt;2,140&lt;/strong&gt;&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;Total page views in my custom analytics: &lt;strong&gt;5,358&lt;/strong&gt;&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mixpanel analytics captures only &lt;strong&gt;40%&lt;/strong&gt; of all page views on my blog.&lt;/p&gt;
&lt;h3 id=&#34;daily-page-views-difference&#34;&gt;Daily page views difference&lt;/h3&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/images/posts/adblock-skews-analytics/daily-page-views.svg&#34;
    alt=&#34;Daily page views difference&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;h2 id=&#34;measuring-method-and-interpretation&#34;&gt;Measuring method and interpretation&lt;/h2&gt;
&lt;p&gt;Both analytics measure the same thing: &lt;strong&gt;A browser opened a page on my blog&lt;/strong&gt;.  I looked into the access logs in my custom analytics, and I&amp;rsquo;m confident that the number of page views is realistic and captures real people visiting the site.&lt;/p&gt;
&lt;p&gt;Even though the sample of more than five thousand requests is statistically significant, it can&amp;rsquo;t be extrapolated to just any website. The audience of this blog is tech-savvy, and the chance of them having AdBlocker installed is much higher than in the general population.&lt;/p&gt;
&lt;p&gt;The results are not going to be specific to Mixpanel, and the same decreased numbers can be expected for any other commercial analytics out there.&lt;/p&gt;
&lt;h2 id=&#34;the-future-of-analytics&#34;&gt;The future of analytics&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s fantastic that so many of my readers are using AdBlock to protect their privacy. I hope this trend will continue, and it&amp;rsquo;s going to be increasingly harder to track complex user behaviour on the internet.&lt;/p&gt;
&lt;p&gt;I was cautious about gathering only the absolute minimum of information about my readers. I only care about how many times each page gets viewed as feedback on my writing. Until privacy-aware analytics like &lt;a href=&#34;https://simpleanalytics.com/&#34;&gt;simpleanalytics&lt;/a&gt; get whitelisted in AdBlock lists, using access logs is the only reliable way to get the full picture.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m going to keep using the Mixpanel and my custom analytics side by side a bit longer. But once I exceed my limit in Mixpanel again, I&amp;rsquo;m just going to remove it and rely on my custom analytics. I got really excited when I saw that 150% jump in traffic as I started measuring all of it.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Update 2020-07-19:&lt;/strong&gt; Adam Graham pointed out that it&amp;rsquo;s not clear whether Mixpanel gets affected by AdBlockers or not. I updated the lead paragraph for better clarity.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.justbartek.ca/analytics-without-google/&#34;&gt;Analytics without Google&lt;/a&gt;, &lt;a href=&#34;https://www.digitalinklingsblog.com/my-messy-analytics-breakup/&#34;&gt;My Messy Analytics Breakup&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;An access log is a text file where each line represents one request to the server.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;Referrer header is the most controversial information I store. I keep it because it&amp;rsquo;s great to know where this blog is mentioned, but it does help to track user behaviour. The header itself has &lt;a href=&#34;https://developer.mozilla.org/en-US/docs/Web/Security/Referer_header:_privacy_and_security_concerns&#34;&gt;security problems&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/images/posts/adblock-skews-analytics/mxpanel.png&#34;
    alt=&#34;Total Page Views in Mixpanel&#34;
    loading=&#34;lazy&#34;
    
/&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/images/posts/adblock-skews-analytics/goaccess.png&#34;
    alt=&#34;Total Page Views in my own analytics&#34;
    loading=&#34;lazy&#34;
    
/&gt; (the difference between total and valid requests are the crawlers)&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Focus on strategic and outsource utility work</title>
      <link>https://blog.viktomas.com/posts/strategic-vs-utility/</link>
      <pubDate>Sun, 21 Jun 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/strategic-vs-utility/</guid>
      <description>&lt;p&gt;This article explains the concept of utility and strategic software and how it easily translates into everyday life. Originally, the concept has been used by large enterprises to decide how they should divide their development efforts. Now, it can help you prioritise your side project just as well.&lt;/p&gt;
&lt;p&gt;My parents aren’t rich. Growing up, I had to think about money and scarcity. My dad would always prefer building or fixing something himself over getting a tradie to do it. Saving was always more important than investment.&lt;/p&gt;
&lt;p&gt;And that’s why I turn every coin twice before spending it. $5 a month for a service? Are you nuts? That’s $60 a year. I&amp;rsquo;ll build it myself instead. Do you want $200 for a kitchen pot that would simplify my cooking? No, thank you. Website analytics for $10 a month? &lt;strong&gt;I&amp;rsquo;m going to do it myself to save money.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Martin Fowler, in his article &lt;a href=&#34;https://martinfowler.com/bliki/UtilityVsStrategicDichotomy.html&#34;&gt;Utility vs. Strategic - Dichotomy&lt;/a&gt; explains the following concept: &lt;em&gt;Utility software&lt;/em&gt; is your company&amp;rsquo;s office suite and payroll system. &lt;em&gt;Strategic software&lt;/em&gt; is a critical system providing your company with a competitive advantage. Google&amp;rsquo;s strategic software is its search engine implementation. You should buy utility software as-is and always build your strategic software.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;If you are Google, you must be perfecting your search engine rather than creating your custom payroll system.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This concept is useful for individuals too.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;You are&lt;/th&gt;
          &lt;th&gt;Strategic activities&lt;/th&gt;
          &lt;th&gt;Utility activities&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Blog writer&lt;/td&gt;
          &lt;td&gt;Producing a high quality reading material&lt;/td&gt;
          &lt;td&gt;Designing blog, maintaining your computer, maintaining a blogging platform&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Visual artist&lt;/td&gt;
          &lt;td&gt;Producing drawings, paintings, designs&lt;/td&gt;
          &lt;td&gt;Configuring and installing your drawing software, social media marketing, printing and selling your artwork&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Professional athlete&lt;/td&gt;
          &lt;td&gt;Training, competing&lt;/td&gt;
          &lt;td&gt;Transportation, nutrition planning, scheduling the competitions, gear design&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Spending time on a task should be backed by answering YES to one of the following questions:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Do you enjoy doing it &lt;strong&gt;a lot&lt;/strong&gt;?&lt;/li&gt;
&lt;li&gt;Does it set you apart from others? If someone else is going to do the task, will it significantly change the outcome?&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Is the money saved by doing it yourself worth the effort?&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The last point is the trickiest. It&amp;rsquo;s only too easy to see that you are going to save $100, but the &lt;a href=&#34;https://blog.viktomas.com/posts/opportunity-cost/&#34;&gt;opportunity cost&lt;/a&gt; might be much higher. Make sure you are saving enough money to make up for not doing an activity that is more fun, more rewarding or more profitable.&lt;/p&gt;
&lt;p&gt;I need to get out of this scarcity, do-it-all-yourself mindset. It&amp;rsquo;s good not to spend money carelessly, but it&amp;rsquo;s worse to spend time on things that don&amp;rsquo;t improve the outcome of my work, and they don&amp;rsquo;t bring me joy. But that&amp;rsquo;s easier said than done, even thinking about spending $10 a month on a service that I can implement myself feels uncomfortable.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m going to solve this inertia by forking out a fixed amount I have to spend each month on reducing, automating and replacing my &lt;em&gt;utility activities&lt;/em&gt;. I will spend $100 each month to support this blog and my other side projects. I hypothesise that I&amp;rsquo;ll enjoy working on them more and they will benefit more people. I&amp;rsquo;m considering spending on services like DigitalOcean credit, Hemingway app, and Fivver designer.&lt;/p&gt;
&lt;p&gt;I want to focus only on the few parts of my hobbies that I enjoy and that bring value to other people and me. I will maximise this provided value by not spending time on things that can be cheaply purchased. I&amp;rsquo;ll try to return to this topic in a few months and let you know how this experiment went.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Gary Provost - 100 Ways to Improve Your Writing</title>
      <link>https://blog.viktomas.com/books/provost-gary--100-ways-to-improve-your-writing/</link>
      <pubDate>Fri, 19 Jun 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/provost-gary--100-ways-to-improve-your-writing/</guid>
      <description>&lt;p&gt;One of Gary&amp;rsquo;s tips is &amp;ldquo;Make yourself likeable&amp;rdquo;. And does he make a good job of it. The book describes the rules of both style and grammar in a way that&amp;rsquo;s easy to digest and down to earth. A much larger portion of the book is spent on style-related advice. That&amp;rsquo;s a good thing when tools like Grammarly and Hemingway app provide advanced grammar and composition checks.&lt;/p&gt;
&lt;p&gt;The key takeaway from the book is the word &lt;strong&gt;Simplicity&lt;/strong&gt;. Don&amp;rsquo;t write something in two words when one will do the job. Don&amp;rsquo;t add a sentence that doesn&amp;rsquo;t contribute to the topic. Cut away sentences from the start and from the end, till you can&amp;rsquo;t cut any further. That&amp;rsquo;s how you find your text&amp;rsquo;s real beginning and end.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Easy-going work doesn&#39;t provide much value</title>
      <link>https://blog.viktomas.com/posts/time-vs-value/</link>
      <pubDate>Sun, 14 Jun 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/time-vs-value/</guid>
      <description>&lt;p&gt;The whole day of work can feel great, but not provide value to the outside world. This article explains that the time spent at work isn’t necessarily directly related to the value produced.&lt;/p&gt;
&lt;p&gt;This is especially true for children of middle-class parents (myself included). Parents who worked nine to five jobs and got paid a fixed salary for a fixed time.&lt;/p&gt;
&lt;h2 id=&#34;predictable-tasks-feel-great&#34;&gt;Predictable tasks feel great&lt;/h2&gt;
&lt;p&gt;I got reminded of this concept last month at work. Every week I produced a report for &lt;a href=&#34;https://gitter.im&#34;&gt;our service&lt;/a&gt;. This report would contain the number of active users, messages sent between users and a few other metrics. The value of this report is to provide my team with motivation and understanding of the service.&lt;/p&gt;
&lt;p&gt;I looked into the database to get these numbers and compile them into a nice Slack message. This took me 15 minutes each week. And I count an additional 15 minutes as the price of context switching&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. Every time I&amp;rsquo;ve done this report, I felt satisfaction for a job well done.&lt;/p&gt;
&lt;p&gt;But then I was about to move teams and I wanted to reduce the load on my colleagues. So I wrote a program that will create this report automatically every week. It took me five hours to write it. And all of a sudden, my half an hour a week seemed like time wasted and all the satisfaction seemed unfounded.&lt;/p&gt;
&lt;p&gt;Was I providing value by creating the report manually each week?&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Sometimes you are doing a task because it&amp;rsquo;s easy, predictable and you feel in control.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;solving-a-problem-the-hard-way&#34;&gt;Solving a problem the hard way&lt;/h2&gt;
&lt;p&gt;As a software engineer, I&amp;rsquo;m solving puzzles for a living. Each time I&amp;rsquo;m having a new problem to solve I decide on a solution quite early on and try to follow through.&lt;/p&gt;
&lt;p&gt;This works 90% of the time but sometimes I get stuck. And instead of coming up with different solutions to the problem, I&amp;rsquo;m pushing through with my, now the favourite, solution. (Imagine a rat in a maze trying the same dead-end over and over again.)&lt;/p&gt;
&lt;p&gt;What I don&amp;rsquo;t realize at the moment is that &lt;strong&gt;time spent trying to solve the issue the hard way doesn&amp;rsquo;t provide any value over other solutions&lt;/strong&gt;. The best thing is to get up from the keyboard and either talk to someone about the solution or at least give the problem an hour or so to sit.&lt;/p&gt;
&lt;p&gt;This helps to switch from the very low-level solution mode into the big picture view.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Sometimes the best thing to do is forgetting what you&amp;rsquo;ve done and starting over.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;working-out-of-the-inbox&#34;&gt;Working out of the inbox&lt;/h2&gt;
&lt;p&gt;When you work by solving one email after another, you have a clear progress indicator, you can easily measure your work and you can even get into a flow state where you forget yourself.&lt;/p&gt;
&lt;p&gt;Also, none of these indicators shows whether you provide value to someone. I would guess that the lack of discrimination and prioritization in the work is causing a massive inefficiency in our value delivery.&lt;/p&gt;
&lt;p&gt;A big portion of my work is to review my colleague&amp;rsquo;s work in a process called the code review. I get many emails during the day saying: &amp;ldquo;A change to the system is ready for your review&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Originally, I would jump on these tasks as soon as they hit my inbox. They have all the advantages mentioned before: they are very predictable, easy to measure and give me a hit of endorphins for finishing them.&lt;/p&gt;
&lt;p&gt;Now I schedule these review tasks into multiple blocks a day, allowing me to better work with my &lt;a href=&#34;https://blog.viktomas.com/posts/energy-levels/&#34;&gt;energy levels&lt;/a&gt;. Solving the hardest problems undistracted when my mind is the clearest.&lt;/p&gt;
&lt;p&gt;And some emails that don&amp;rsquo;t seem too important or directly concerning my work, I&amp;rsquo;ll leave unattended till they drop from the first page of my inbox.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Some work feels great because you know what to do. You are in control. You know the results you can expect. &lt;strong&gt;This is when your alarm bells should go off.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;If the work is this easy, feel-good and predictable, it probably means that it doesn&amp;rsquo;t provide as much value to the world as work that would challenge you.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.rescuetime.com/context-switching/&#34;&gt;Context switching&lt;/a&gt; is a term originally used in computer science. It represents the act of changing the computer memory to get the computer ready for a new process (program). This nicely translates to normal work where you have to change the things in your immediate memory to prepare yourself for solving a new problem.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Zettelkasten note-taking in 10 minutes</title>
      <link>https://blog.viktomas.com/posts/slip-box/</link>
      <pubDate>Sun, 07 Jun 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/slip-box/</guid>
      <description>&lt;p&gt;&lt;em&gt;Update: I wrote an &lt;a href=&#34;https://blog.viktomas.com/posts/slip-box-after-a-year/&#34;&gt;article about what I&amp;rsquo;ve learned from using Zettelkasten for 16 months&lt;/a&gt;, you might be interested in reading it.&lt;/em&gt;&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/reading-is-hard/&#34;&gt;Reading is hard and books don&amp;rsquo;t work&lt;/a&gt;. Zettelkasten aka slip-box note-taking is the new cool kid on the block. Don&amp;rsquo;t go down the same rabbit hole as I did, researching the method for tens of hours. This article should be enough of the introduction to get you started.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 330px&#34; src=&#34;https://blog.viktomas.com/images/posts/slip-box.svg&#34; alt=&#34;Theme illustration&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Illustration&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;h2 id=&#34;why&#34;&gt;Why&lt;/h2&gt;
&lt;p&gt;Slip-box method promises to prevent your notes from piling up deep within your note-taking app and being forgotten. Instead, using this method will improve the value of your notes as you create more of them. This method also gives you better and quicker feedback than usual note-taking.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Advice #1&lt;/strong&gt;: Don&amp;rsquo;t try to get this method perfect from the get go&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. The advanced practices are useful only when you&amp;rsquo;ve got close to 1000 notes&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;As with everything else you want to utilize &lt;a href=&#34;https://blog.viktomas.com/posts/iteration/&#34;&gt;iteration&lt;/a&gt;. Read this article, use it to create your first couple hundred notes and then research more details if you feel like your current process should be improved.&lt;/p&gt;
&lt;h2 id=&#34;the-slip-box-method&#34;&gt;The slip-box method&lt;/h2&gt;
&lt;p&gt;&lt;em&gt;The source for the method summary is Sönke Ahrens&amp;rsquo; book &lt;a href=&#34;https://blog.viktomas.com/books/ahrens-sonke--how-to-take-smart-notes/&#34;&gt;How to Take Smart Notes&lt;/a&gt;. I only added the technical aspects.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;You write notes with a clear purpose: &lt;strong&gt;your future self is going to be reorganizing them and using them to produce articles or books&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;You fill your slip-box with notes by following this process:&lt;/p&gt;
&lt;h3 id=&#34;1-make-notes-as-you-read&#34;&gt;1) make notes as you read&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Advice #2&lt;/strong&gt;: Always use your own words. Copying doesn&amp;rsquo;t give you feedback on your understanding.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let&amp;rsquo;s call these &lt;em&gt;resource notes&lt;/em&gt;. Writing resource notes is where you get the first feedback from the method: Are you paying attention and do you understand the text? At this step, you are not trying to predict how your notes are going to fit in the slip-box, you are just trying to capture the essence of the text.&lt;/p&gt;
&lt;p&gt;You can use a separate app like &lt;a href=&#34;https://www.zotero.org/&#34;&gt;Zotero&lt;/a&gt; for these notes. But &lt;strong&gt;I recommend&lt;/strong&gt; having them as Markdown files in a &lt;code&gt;Resources&lt;/code&gt; folder&lt;/p&gt;
&lt;p&gt;Folder structure so far:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;└── Resources
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    └── Sonke Ahrens - How to Take Smart Notes.md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Reference note:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-md&#34; data-lang=&#34;md&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;title: How to Take Smart Notes: One Simple Technique to Boost Writing, Learning and Thinking – for Students, Academics and Nonfiction Book Writers
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;author: Sönke Ahrens
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;type: book
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;link: https://www.goodreads.com/book/show/34507927-how-to-take-smart-notes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;# How to Take Smart Notes
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;-&lt;/span&gt; **Short feedback loop** - Writing literary notes provides quick feedback on our understanding of the text. We double-check this understanding when we try to make permanent notes out of the literary notes. (p54)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;-&lt;/span&gt; Fleeting notes - they are supposed to capture an idea for a brief period before it is processed, 1 or 2 days max (p43)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;em&gt;The file content format is arbitrary, I choose to use &lt;a href=&#34;https://jekyllrb.com/docs/front-matter/&#34;&gt;Frontmatter&lt;/a&gt; for the metadata, but it&amp;rsquo;s not that important.&lt;/em&gt;&lt;/p&gt;
&lt;h3 id=&#34;2-write-atomic-self-contained-permanent-notes&#34;&gt;2) write atomic, self-contained, permanent notes&lt;/h3&gt;
&lt;p&gt;Remember, the purpose of slip-box is to aid your future self to make use of the notes for writing. The main unit of information within the method is a permanent note. This note is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;atomic&lt;/strong&gt;: always focused on a single topic, that makes linking notes easier&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;self-contained&lt;/strong&gt;: you will forget the context in a few weeks, the note needs to explain itself in separation from the fleeting context&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;permanent&lt;/strong&gt;: you are never going to delete the note, it might just fade into the background if there aren&amp;rsquo;t many links to it&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;concise&lt;/strong&gt;: few paragraphs maximum, restricting the size helps you get the gist and keep the note atomic&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;You try to turn you reference notes into permanent notes whilst avoiding conflict of concepts and duplication, these problems show the clearest when you think &amp;ldquo;How am I going to link this note to the other of my slip-box notes?&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Permanent notes are just markdown files in a separate folder. These files need to have a unique identifier so other notes can link to them unambiguously.&lt;/p&gt;
&lt;p&gt;Folder structure so far:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── Resources
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   └── Sonke Ahrens - How to Take Smart Notes.md
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;└── Permanent notes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    └── 20200605153129 Slip-box.md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id=&#34;3-link-permanent-notes-together&#34;&gt;3) link permanent notes together&lt;/h3&gt;
&lt;p&gt;The purpose of linking is to give you feedback, avoid duplication and capture the context of the permanent note. Ask yourself: How does the piece of information fit into the network of my permanent notes? Does it complement, contradict or otherwise interfere with your current notes?&lt;/p&gt;
&lt;p&gt;The linking is done by placing links like these &lt;code&gt;[[20200606154308]]&lt;/code&gt; into notes. Most of the slip-box software allows you to click on this link and opens a note with ID &lt;code&gt;20200606154308&lt;/code&gt; for you.&lt;/p&gt;
&lt;p&gt;Folder structure so far:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-txt&#34; data-lang=&#34;txt&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;├── Resources
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;│   └── Sonke Ahrens - How to Take Smart Notes.md
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;└── Permanent notes
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    ├── 20200605145305 Slip-box software.md
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;    └── 20200605153129 Slip-box.md
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;File &lt;code&gt;20200606154308 Slip-box.md&lt;/code&gt;:&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-md&#34; data-lang=&#34;md&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;# Slip-box
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;See also:
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;-&lt;/span&gt; [[20200605145305]] Slip-box software
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;div class=&#34;mermaid&#34; align=&#34;center&#34;&gt;graph LR;
A[&#34;20200605153129 Slip-box&#34;] -- &#34;[[20200605145305]]&#34; --&gt; B[20200605145305 Slip-box software]&lt;/div&gt;
&lt;h3 id=&#34;4--tag-permanent-notes&#34;&gt;4)  tag permanent notes&lt;/h3&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Advice #3&lt;/strong&gt;: Tag the notes by the context you would like to retrieve it by&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Example: You have a note on &lt;a href=&#34;https://en.wikipedia.org/wiki/Stanford_prison_experiment&#34;&gt;Stanford prison experiment&lt;/a&gt;&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;. Using tags like &lt;code&gt;#psychology&lt;/code&gt; &lt;code&gt;#experiment&lt;/code&gt; is hardly going to aid you in finding this note when you are writing or thinking about a problem. Better would be &lt;code&gt;#&amp;quot;power dynamics in groups&amp;quot;&lt;/code&gt; &lt;code&gt;#&amp;quot;misuse of power&amp;quot;&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;the-software&#34;&gt;The software&lt;/h2&gt;
&lt;p&gt;This is the part that took me a long time to research. But it is simple.&lt;/p&gt;
&lt;p&gt;Use &lt;a href=&#34;https://www.zettlr.com/&#34;&gt;Zettlr&lt;/a&gt;. It&amp;rsquo;s &lt;a href=&#34;https://blog.viktomas.com/posts/foss/&#34;&gt;Free and Open-Source&lt;/a&gt;, uses Markdown files and it&amp;rsquo;s &lt;a href=&#34;https://en.wiktionary.org/wiki/vendor-agnostic&#34;&gt;vendor agnostic&lt;/a&gt;. It&amp;rsquo;s the only app you need, &lt;strong&gt;you can migrate to other apps later if you decide to&lt;/strong&gt;.&lt;/p&gt;
&lt;h3 id=&#34;zettlr-in-2-minutes&#34;&gt;Zettlr in 2 minutes&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&#34;https://www.zettlr.com/download&#34;&gt;Download and install Zettlr&lt;/a&gt; (on Mac &lt;code&gt;brew cask install Zettlr&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://docs.zettlr.com/en/guides/guide-zettelkasten/&#34;&gt;Set it up for Zettelkasten&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Create a new note (&lt;code&gt;CMD&lt;/code&gt;+&lt;code&gt;N&lt;/code&gt;), add name the generated ID (e.g. &lt;code&gt;20200606154308 My first note.md&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Create a second note (e.g. &lt;code&gt;20200605145305 My second note.md&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Link from first note to second note by typing &lt;code&gt;[[&lt;/code&gt; in the first note and using auto-complete&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id=&#34;alternatives&#34;&gt;Alternatives&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://zettelkasten.de/the-archive/&#34;&gt;Archive&lt;/a&gt; - looks great, no vendor lock-in, but not open-source and it is macOS only&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://brettterpstra.com/projects/nvalt/&#34;&gt;nvAlt&lt;/a&gt; Famous notational velocity.&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.zotero.org/&#34;&gt;Zotero&lt;/a&gt; - you might want to add this to your toolbox if you plan on academic publication of your work. Overkill for anyone else.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;example-slip-box&#34;&gt;Example slip-box&lt;/h2&gt;
&lt;p&gt;The closest to a full slip-box example are &lt;a href=&#34;https://notes.andymatuschak.org/About_these_notes&#34;&gt;Andy Matuschak&amp;rsquo;s notes&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;This should be enough detail to get you started. The critical idea is atomic notes linked together. That prevents the notes from being forgotten somewhere deep in your note-taking app.&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.zettlr.com/&#34;&gt;Zettlr&lt;/a&gt; is a good app to start with. The slip-box is just a few text files linked together with unique ids. Many other apps support the same linking style as Zettlr.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t do &lt;a href=&#34;https://youtu.be/kXnR7qX3BDc?t=1602&#34;&gt;a big migration of your current notes&lt;/a&gt;. You can migrate them when you are planning to use them.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;&lt;em&gt;Update: I wrote an &lt;a href=&#34;https://blog.viktomas.com/posts/slip-box-after-a-year/&#34;&gt;article about what I&amp;rsquo;ve learned from using Zettelkasten for 16 months&lt;/a&gt;, you might be interested in reading it.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;This article &lt;a href=&#34;https://softdroid.net/zettelkasten-delaet-zametki-za-10-minut&#34;&gt;has been translated to Russian language&lt;/a&gt; by Vladimir on softdroid.net.&lt;/em&gt;&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://youtu.be/kXnR7qX3BDc?t=1399&#34;&gt;Sonke says it himself&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://zettelkasten.de/posts/three-layers-structure-zettelkasten/#bottom-layer-content&#34;&gt;tags and links between the notes are going to be OK&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;I changed the example from Sonke&amp;rsquo;s book a bit to make more sense to me.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Sönke Ahrens - How to Take Smart Notes: One Simple Technique to Boost Writing, Learning and Thinking – for Students, Academics and Nonfiction Book Writers</title>
      <link>https://blog.viktomas.com/books/ahrens-sonke--how-to-take-smart-notes/</link>
      <pubDate>Sat, 06 Jun 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/ahrens-sonke--how-to-take-smart-notes/</guid>
      <description>&lt;p&gt;![/static/books/ahrens-sonke&amp;ndash;how-to-take-smart-notes.jpg]&lt;/p&gt;
&lt;p&gt;&lt;a href=&#34;https://www.goodreads.com/book/show/34507927-how-to-take-smart-notes&#34;&gt;Goodreads&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This book is a good introduction into the motivation and science behind using atomic interconnected notes, a method known as slip-box or German Zettelkasten. The massive drawback of the book is that the description of the system is not giving enough examples of the process. You are therefore not able, for example, to make slip-box notes directly from the book without looking into external resources like the &lt;a href=&#34;https://zettelkasten.de/&#34;&gt;zettelkasten.de&lt;/a&gt; site.&lt;/p&gt;
&lt;p&gt;I liked how succinctly author explained how important it is to have a feedback process in your learning and how slip-box process gives this feedback in several different forms:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;making notes from literature in your own words validates your understanding of the text&lt;/li&gt;
&lt;li&gt;turning your literature notes into permanent notes gives you feedback about how the literature fits into your current understanding of the topic.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Why do you forget most of what you read?</title>
      <link>https://blog.viktomas.com/posts/reading-is-hard/</link>
      <pubDate>Sun, 31 May 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/reading-is-hard/</guid>
      <description>&lt;p&gt;Reading books takes time and in the end, you&amp;rsquo;ll forget most of what you&amp;rsquo;ve read. The ideas are not getting transmitted to your brain and the concepts seem clear only until you try to explain them.&lt;/p&gt;
&lt;p&gt;You are not alone. This article explains this phenomenon and provides useful tools to improve information retention and understanding.&lt;/p&gt;
&lt;p&gt;Last year, I read more books than any other year, 28. Roughly half of them are non-fiction. Throughout the year I noticed a recurring issue:&lt;/p&gt;
&lt;p&gt;When I finished a book, I had a feeling that I perfectly understood the topic. Then I tried to give a gist to my friend and I wasn&amp;rsquo;t able to create two coherent sentences about the ideas in the book that I spent hours reading.&lt;/p&gt;
&lt;h2 id=&#34;why-books-dont-work&#34;&gt;Why books don&amp;rsquo;t work&lt;/h2&gt;
&lt;p&gt;If you haven&amp;rsquo;t already, I recommend reading Andy Matuschak&amp;rsquo;s article &lt;a href=&#34;https://andymatuschak.org/books/&#34;&gt;Why books don&amp;rsquo;t work&lt;/a&gt;. My understanding of the problem is heavily influenced by Andy&amp;rsquo;s post. His article has profoundly changed how I view reading non-fiction. It mentions exactly the experience I had when trying to recall what the book was about. The experience of &amp;ldquo;I think I&amp;rsquo;ve got this&amp;rdquo; turning into &amp;ldquo;I have no idea what I&amp;rsquo;m talking about&amp;rdquo; in a matter of seconds.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;I realized I&amp;rsquo;m not alone.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The main takeaway is that the cognitive model of a book is not aligned with how humans learn. Books are based on an idea of clear transmission of the concept from the paper to your head. But human brains need much more interaction and analysis before they remember anything.&lt;/p&gt;
&lt;p&gt;Whilst Andy is &lt;a href=&#34;https://numinous.productions/ttft/&#34;&gt;focusing his energy on researching novel ways of teaching/presenting information&lt;/a&gt;, I want to offer a few incremental improvements for learning from books.&lt;/p&gt;
&lt;h2 id=&#34;techniques-to-improve-retentionunderstanding&#34;&gt;Techniques to improve retention/understanding&lt;/h2&gt;
&lt;p&gt;Since realizing that reading a book doesn&amp;rsquo;t automatically equal remembering and understanding the concepts, I started researching and experimenting with ways to improve my retention. These are learning techniques and I&amp;rsquo;m not using them when I want to enjoy the book just for the experience of reading.&lt;/p&gt;
&lt;h3 id=&#34;read-the-summary-first&#34;&gt;Read the summary first&lt;/h3&gt;
&lt;p&gt;In the book &lt;a href=&#34;https://www.goodreads.com/book/show/3063393-pragmatic-thinking-and-learning&#34;&gt;Pragmatic Thinking&lt;/a&gt; Andy Hunt mentions the &lt;a href=&#34;https://en.wikipedia.org/wiki/SQ3R&#34;&gt;SQ3R&lt;/a&gt; process that helps comprehension when reading. The S and Q at the beginning stand for Survey and Question. That means go through the table of contents and chapter summaries and come up with questions about the material.&lt;/p&gt;
&lt;p&gt;I like to take this tip a bit further and check whether the book has got a summary on &lt;a href=&#34;https://www.getabstract.com/&#34;&gt;getAbstract.com&lt;/a&gt;. I read through the table of contents, chapter summaries and getabstract and I try to find concepts that I would like to learn the most. This process also tells me what to expect when I read the book.&lt;/p&gt;
&lt;h3 id=&#34;highlighting&#34;&gt;Highlighting&lt;/h3&gt;
&lt;p&gt;When I&amp;rsquo;m reading a book, I&amp;rsquo;m highlighting interesting sentences or paragraphs in the chapter I read. That doesn&amp;rsquo;t require too much additional effort and allows me to get through the chapter relatively quickly. This is important for two reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Sense of achievement - When I see quick progress, it motivates me to keep going.&lt;/li&gt;
&lt;li&gt;Low entry barrier - If I have to put more effort into the reading (e.g. I&amp;rsquo;d have more complicated note-taking during the reading itself), it lowers the chance of me picking my book at all.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;making-notes&#34;&gt;Making notes&lt;/h3&gt;
&lt;p&gt;When I&amp;rsquo;m finished with the chapter, I take out my paper notebook and go through the highlighted bits to remind myself what the chapter was about. Then I try to sum up the chapter in a couple of A5 pages &lt;strong&gt;using my own words&lt;/strong&gt;. This is important because just copying snippets from the book doesn&amp;rsquo;t make me understand the concepts deeply.&lt;/p&gt;
&lt;h3 id=&#34;three-paragraph-summary&#34;&gt;Three paragraph summary&lt;/h3&gt;
&lt;p&gt;This is the last part of my reading process. I don&amp;rsquo;t consider the book finished until I wrote a short summary. I&amp;rsquo;m trying to capture the one or two key takeaways I really want to remember. Only when I write the summary and publish it on &lt;a href=&#34;https://blog.viktomas.com/books&#34;&gt;this blog&lt;/a&gt;, I consider the book finished.&lt;/p&gt;
&lt;h2 id=&#34;feature-experiments-and-conclusion&#34;&gt;Feature experiments and conclusion&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;d love to be even more efficient in my reading and learn how to fast-read so I can skim quickly through parts of the text that are not rich with new information.&lt;/p&gt;
&lt;p&gt;Improving the way you learn is really exciting because it is one of the investments that pay off every time you learn something in the future. It&amp;rsquo;s similar to investing money, the sooner you learn how to do it well, the larger compound interest you are about to reap.&lt;/p&gt;
&lt;p&gt;I hope my tips sparked some thinking and experimentation of your own.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Optimize your personal energy</title>
      <link>https://blog.viktomas.com/posts/energy-levels/</link>
      <pubDate>Sun, 24 May 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/energy-levels/</guid>
      <description>&lt;p&gt;When I was young, I never paid much attention to how much energy I had at any given moment. I never tried to schedule really demanding activities before my meals or avoid difficult tasks just before going to sleep.&lt;/p&gt;
&lt;p&gt;In this article, I want to have a look at what I mean by my personal energy and how I optimize it to be productive and to enjoy my day without an unnecessary struggle.&lt;/p&gt;
&lt;h2 id=&#34;personal-energy&#34;&gt;Personal energy&lt;/h2&gt;
&lt;p&gt;In the past, I knew that people are getting tired or they are antsy but I never gave much thought to what activities have an effect on the level of my alertness during a day. I took it as something that is &amp;ldquo;just&amp;rdquo; happening and can&amp;rsquo;t be affected.&lt;/p&gt;
&lt;p&gt;I only realized that our energy during a day can be affected and worked with when I read about how coffee, exercise and eating light meals helps &lt;a href=&#34;https://blog.viktomas.com/books/adams-scott-how-to-fail-at-almost-everything/&#34;&gt;Scott Adams&lt;/a&gt; stay focused and maintain good energy. I was in my mid 20&amp;rsquo;s.&lt;/p&gt;
&lt;p&gt;But even then, I didn&amp;rsquo;t pay much attention to it, either because I did have enough energy or because I wasn&amp;rsquo;t aware enough. That changed in the last few years when I really started looking at what can I do to feel more alert, productive and happy.&lt;/p&gt;
&lt;h2 id=&#34;trust-but-verify&#34;&gt;Trust but verify&lt;/h2&gt;
&lt;p&gt;This article contains a few tips on how to keep your energy high, but there are no references to the science behind these concepts. Maintaining a high level of personal energy is an individual endeavour. I&amp;rsquo;m convinced everyone can benefit from the following tips but the best thing to do is to have a baseline of diet/behaviour and then &lt;strong&gt;experiment&lt;/strong&gt; and see what gives and what drains your energy.&lt;/p&gt;
&lt;h2 id=&#34;coffee-&#34;&gt;Coffee ☕️&lt;/h2&gt;
&lt;p&gt;OMG, I love coffee so much.&lt;/p&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/images/posts/coffee-brain-hug-cup.jpg&#34;
    alt=&#34;Hug my brain&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Source: &lt;a href=&#34;https://wanna-joke.com/coffee-lovers-2/&#34;&gt;wanna-joke.com&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;For me, coffee is the best way to raise my alertness and make myself amped up for creative work or a workout. It&amp;rsquo;s probably not healthy to consume coffee in large doses&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;, but with moderation, this is the ambrosia&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; for me. On bad days, I use it to make myself work out. But usually, I just have it in regular intervals to feel the kick and get clarity of mind.&lt;/p&gt;
&lt;h2 id=&#34;food&#34;&gt;Food&lt;/h2&gt;
&lt;p&gt;Food affects my energy the most. Heavy meal (a lot of carbohydrates or meat) or junk food (salty, fatty), can easily end the clear, productive day. Or worse, I can still feel queasy the next day.&lt;/p&gt;
&lt;p&gt;My silver bullet solution is to eat a lot of veggies, stray away from large portions of carbohydrates and eat meat with moderation, especially red meat. I know, it&amp;rsquo;s nothing new under the sun. However, have you ever tried to eat like this for more than a week? If you are anything like me 5 years ago, you haven&amp;rsquo;t.&lt;/p&gt;
&lt;h2 id=&#34;exercise&#34;&gt;Exercise&lt;/h2&gt;
&lt;p&gt;This is very counterintuitive. If you go and spend half an hour to an hour working out, you will have much more energy afterwards than when you started. Surely there is some scientific explanation for it. But it&amp;rsquo;s not really important because you can try it for yourself if you haven&amp;rsquo;t yet. Or ask anyone who regularly works out.&lt;/p&gt;
&lt;p&gt;This brings me to the ultimate combo:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You feel tired -&amp;gt; have a coffee -&amp;gt; go workout -&amp;gt; you can do anything now&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id=&#34;meditation&#34;&gt;Meditation&lt;/h2&gt;
&lt;p&gt;Sometimes I feel unfocused and low on energy. I would just like to just watch YouTube for hours. Then I&amp;rsquo;ll do 10-20 minutes of mindfulness meditation and as I finish, my thinking is clear and I&amp;rsquo;m good to do some cognitively complicated tasks.&lt;/p&gt;
&lt;h2 id=&#34;alcohol&#34;&gt;Alcohol&lt;/h2&gt;
&lt;p&gt;Alcohol is great when you want to party all night. Even though &lt;a href=&#34;https://blog.viktomas.com/alcohol-abstinence/&#34;&gt;I&amp;rsquo;m not drinking any more&lt;/a&gt;, I&amp;rsquo;ve spent the majority of my adult life practising heavy social drinking and I&amp;rsquo;m not trying to be on a high horse here. A reasonable dose of hard liquor will make you want to go on even when your sober self would be begging to go to the bed.&lt;/p&gt;
&lt;p&gt;There is a price for that. At the very least you&amp;rsquo;ll write the next day off.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;Try to be aware of how you feel during the day. If you feel tired ask yourself why? What did you do in the past few hours that made you feel that way? Experiment with doing activities at a different time of the day. And when it comes to increasing your energy, try coffee and exercise.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;There is not a consensus (AFAIK) on how bad it is to drink coffee but I assume since it&amp;rsquo;s a drug, it can&amp;rsquo;t be healthy.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Ambrosia&#34;&gt;Ambrosia&lt;/a&gt;, the drink of gods&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Break free from the shackles of YouTube</title>
      <link>https://blog.viktomas.com/posts/break-free-from-youtube/</link>
      <pubDate>Sun, 17 May 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/break-free-from-youtube/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve watched YouTube for &lt;a href=&#34;https://blog.viktomas.com/posts/youtube-usage&#34;&gt;2,042 hours in the last 7 years&lt;/a&gt;. Over those years, I&amp;rsquo;ve tried to limit my YouTube watching several times. Every couple of years or so I would go cold turkey, but I always relapsed back to excessive watching. Let&amp;rsquo;s see why YouTube has such power over us, and how to limit our usage without stopping completely.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve listened to The New York Times podcast &lt;a href=&#34;https://www.nytimes.com/2020/04/16/podcasts/rabbit-hole-internet-youtube-virus.html&#34;&gt;Rabbit Hole&lt;/a&gt;. And Guillaume Chaslot, former Google engineer, talks about developing the YouTube recommendation engine. This piece of software knows about every video you&amp;rsquo;ve previously watched and uses machine learning to guess what you are most likely to enjoy next. The issue is that the recommendation engine optimizes for the &lt;strong&gt;time spent watching videos&lt;/strong&gt;, not for content quality or value to your education/health/well-being.&lt;/p&gt;
&lt;p&gt;That is the reason why an innocent YouTube visit to &amp;ldquo;just watch the latest SpaceX news&amp;rdquo; ends up with me watching Connor McGregor&amp;rsquo;s UFC Knockout compilation 3 hours later.&lt;/p&gt;
&lt;p&gt;Historically, I sometimes did get fed up with how much time I spent on YouTube and I went cold turkey. Installing a site blocker in my browser&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; removed my access to YouTube. But eventually, I would end up pausing the blocker and sneaking back in. The longest I lasted without any YouTube was maybe two weeks.&lt;/p&gt;
&lt;p&gt;Last time I blocked YouTube was mid-April this year. But towards the end of the month, I was again sneaking on YouTube in a private window where the site blocker wasn&amp;rsquo;t on. But then I noticed something:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;When I used YouTube in a private window, without my account data, I spent much less time watching it.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The reason being that the recommendation engine loses all its power when I&amp;rsquo;m not logged in. The recommendations go from &lt;em&gt;&amp;ldquo;Even I didn&amp;rsquo;t know I wanted to watch this video so bad&amp;rdquo;&lt;/em&gt; to &lt;em&gt;&amp;ldquo;I&amp;rsquo;ve seen half of this and the other half doesn&amp;rsquo;t look interesting at all&amp;rdquo;&lt;/em&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Level 1 (Beginner)&lt;/strong&gt;: Install site blocker&lt;sup id=&#34;fnref1:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; and only watch YouTube in a private window.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now, &amp;ldquo;turning off&amp;rdquo; the recommendation engine goes a long way towards reducing the time spent watching YouTube. But there are two more things you can do to decrease negative effects YouTube has on your productivity.&lt;/p&gt;
&lt;p&gt;The first is a recommendation from &lt;a href=&#34;books/newport-cal-deep-work/&#34;&gt;Deep Work from Cal Newport&lt;/a&gt;. Cal Newport says that our distractions (like watching videos on the internet) are not that bad in and of themselves. What makes them detrimental to our focus and attention span is that we reach for them any time the going gets tough. Did you get stuck on a task? YouTube! Are you waiting 5 minutes before your friend arrives? HackerNews! And this way we train our brain to give up on a task too easily.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Level 2 (Intermediate)&lt;/strong&gt;: Never switch to YouTube on a whim. Plan when are you going to catch up on the latest videos.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;We can significantly reduce the negative effects distractions have on our focus by scheduling distractions in our day. Saying &lt;em&gt;I&amp;rsquo;ll watch funny cat videos for twenty minutes starting in an hour&lt;/em&gt;. Doesn&amp;rsquo;t hurt the willpower anywhere near as much as saying &lt;em&gt;Writing this article is boring, what&amp;rsquo;s happening on YouTube NOW?&lt;/em&gt;&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Level 3 (Expert)&lt;/strong&gt;: Burn the bridges. &lt;a href=&#34;https://myaccount.google.com/deleteservices&#34;&gt;Delete your YouTube account&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;A week ago, I took the first advice from this article to the extreme. I &lt;a href=&#34;https://blog.viktomas.com/posts/youtube-usage&#34;&gt;backed up my watching history and did some fun analysis on it&lt;/a&gt; but then I deleted all the YouTube data in my Google account. Since then, I don&amp;rsquo;t even need a site block + private window combination. I get the same effect, but this time around I can&amp;rsquo;t go back&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;In this article, we looked at what I think is the most addictive component of YouTube, the recommendation engine. Then I suggested several ways to reduce the negative impact this recommendation engine has on your productivity, ending with a hardcore &lt;em&gt;&amp;ldquo;delete all your history&amp;rdquo;&lt;/em&gt; advice. I followed my advice and likely permanently reduced my YouTube dependence.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.proginosko.com/leechblock/&#34;&gt;LeechBlock&lt;/a&gt; is my favourite lately. I was using &lt;a href=&#34;https://addons.mozilla.org/en-US/firefox/addon/blocksite/&#34;&gt;Blocksite&lt;/a&gt; in the past, but it was routinely using so much CPU that I could fry eggs on my MacBook.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref1:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;YouTube doesn&amp;rsquo;t support importing your watch history. Once you delete your account data, you won&amp;rsquo;t be getting as good recommendations as you used to. Not for the next few years.&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Richard P. Feynman - What Do You Care What Other People Think?</title>
      <link>https://blog.viktomas.com/books/feynman-richard--what-do-you-care-what-other-people-think/</link>
      <pubDate>Wed, 13 May 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/feynman-richard--what-do-you-care-what-other-people-think/</guid>
      <description>&lt;p&gt;Richard Feynman seems like a really cool guy. I&amp;rsquo;ve never heard of him and I still don&amp;rsquo;t know what he got his Nobel Prize for, but the way how he discusses his childhood, love for science and loved one&amp;rsquo;s shows that he had both his brain and his hearth in the right place.&lt;/p&gt;
&lt;p&gt;I enjoyed the part about his childhood the most, because it was not just fun, but there were lessons about parenting that I can learn from Richard&amp;rsquo;s mother. The main ones being:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Never punish a child for its curiosity.&lt;/li&gt;
&lt;li&gt;Explain kid the concepts, reward understanding, not memorization.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The final address speech for the academy of sciences brought home one important point. We are all ignorant, nothing is certain, and we should be careful about assuming we are right.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>A script to analyse 7&#43; years of my YouTube history</title>
      <link>https://blog.viktomas.com/posts/youtube-usage/</link>
      <pubDate>Fri, 08 May 2020 16:33:00 +0100</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/youtube-usage/</guid>
      <description>&lt;p&gt;Before deleting my YouTube account, I used Google Takeout to get a complete history of all videos I watched. I used this history to analyse how much time I have spent watching YouTube and what I watched the most. &lt;strong&gt;I open-sourced the process and the scripts as &lt;a href=&#34;https://gitlab.com/viktomas/total-youtube-watchtime&#34;&gt;Total YouTube Watchtime&lt;/a&gt; so you can do the same.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/images/posts/youtube-usage/chart-screenshot.png&#34;
    alt=&#34;My watchtime since 2013&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;I decided to delete my YouTube account as a part of wider de-googling. But I had a few uploaded videos that I wanted to get back from YouTube. I&amp;rsquo;ve mentioned &lt;a href=&#34;https://blog.viktomas.com/posts/losing-google-account/#prepare-for-the-worst&#34;&gt;before&lt;/a&gt; how I appreciate Google allowing you to download all your data through the Takeout.&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; When I downloaded all my YouTube data, I&amp;rsquo;ve noticed an interesting file included. That file was named &lt;code&gt;watch-history&lt;/code&gt; and it contained a list of all the videos I&amp;rsquo;ve ever watched.&lt;/p&gt;
&lt;p&gt;Looking through the file I&amp;rsquo;ve found that it contained a title, link and time when I watched each video.&lt;/p&gt;
&lt;p&gt;Only the video duration was missing so I used YouTube Data API to find out how long each video is. After that I was ready to look into the history of my YouTube watching. The results are not too flattering.&lt;/p&gt;
&lt;h2 id=&#34;i-spent-a-lot-of-time-watching-youtube&#34;&gt;I spent &lt;strong&gt;a lot&lt;/strong&gt; of time watching YouTube&lt;/h2&gt;
&lt;p&gt;Ok, now to the meat of the article. How long did I spend watching YouTube? &lt;strong&gt;I watched 21,396 videos totalling 2,042.5 hours in 7 years&lt;/strong&gt; since starting my account. That is 255 work days (8h), or 85 full days (24h). &lt;strong&gt;45 minutes per day&lt;/strong&gt; on average.&lt;/p&gt;
&lt;p&gt;In the past, I read statistics like:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Watching TV was the leisure activity that occupied the most time (2.8 hours per day), accounting for just over half of all leisure time, on average.&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;And to be honest, I thought that&amp;rsquo;s a lot of time spent watching TV and believed myself to be more sophisticated. But now I have to get off my high horse and realize I like to watch videos as much as the next person.&lt;/p&gt;
&lt;h3 id=&#34;disclaimer&#34;&gt;Disclaimer&lt;/h3&gt;
&lt;p&gt;There always has to be one, doesn&amp;rsquo;t it? Please take my results with a grain of salt for the following reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;YouTube doesn&amp;rsquo;t tell you how much of the video you have watched, so my computation can&amp;rsquo;t differentiate between watching 1 minute of a 60-minute video and watching the whole thing. For that reason I count at most 30 minutes of each video, even when it&amp;rsquo;s longer than that&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/li&gt;
&lt;li&gt;Some of the videos (15% in my case) are no longer available and YouTube won&amp;rsquo;t tell you how long they were. I counted those as 4 minute long.&lt;/li&gt;
&lt;li&gt;I shuffled the months in the chart above (the values are real but assigned to a different month). I could see patterns of behaviour and decided to keep &lt;a href=&#34;https://blog.viktomas.com/posts/privacy/&#34;&gt;my privacy&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;fun-with-data&#34;&gt;Fun with data&lt;/h2&gt;
&lt;p&gt;The script I wrote plots aggregated watch time by month into a chart. The chart clearly showed patterns in my watch time and I did correlate them with events like holidays, injuries, sabbaticals and so on. For example, I was able to quickly locate my overseas travel.&lt;/p&gt;
&lt;h3 id=&#34;my-top-10-videos&#34;&gt;My top 10 videos&lt;/h3&gt;
&lt;p&gt;I was excited when I realized I&amp;rsquo;ll be able to find out which videos I enjoyed the most in the past years. The excitement was a bit reduced when I got my results and realized that I used to listen to music on YouTube before I got my Spotify account. Not surprisingly, the most watched videos are music clips all watched before 2016 when I got Spotify.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=M97vR2V4vTs&#34;&gt;Rudimental - Waiting All Night ft. Ella Eyre&lt;/a&gt; watched 40 times&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=bVRnMrl2oj8&#34;&gt;Laurent Wolf - No Stress&lt;/a&gt; watched 29 times&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=77Ms1oCiDH4&#34;&gt;Anders Nilsen - Salsa Tequila&lt;/a&gt; watched 29 times&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=vVXIK1xCRpY&#34;&gt;Audioslave - Show Me How to Live&lt;/a&gt; watched 27 times&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=Wg8DMqFuip8&#34;&gt;The Dead Weather - Blue Blood Blues&lt;/a&gt; watched 27 times&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=aB16fJpoj-I&#34;&gt;Hilltop Hoods - Cosby Sweater&lt;/a&gt; watched 24 times&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=JdNWatH4vNY&#34;&gt;skeewiff ft. george clooney - man of constant sorrow&lt;/a&gt; watched 24 times&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=iErNRBTPbEc&#34;&gt;Jack White - Love Interruption&lt;/a&gt; watched 22 times&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=PkQ5rEJaTmk&#34;&gt;Swedish House Mafia - One (Your Name)&lt;/a&gt; watched 20 times&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=axbUCR1nKRA&#34;&gt;Full Despicable Me Theme Song - Pharrell Williams&lt;/a&gt; watched 20 times&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;i-classfas-fa-historyi-total-youtube-watchtime&#34;&gt;&lt;i class=&#34;fas fa-history&#34;&gt;&lt;/i&gt; Total YouTube Watchtime&lt;/h2&gt;
&lt;p&gt;I had good fun digging through my YouTube history and when I mentioned it to my friends they were interested in doing the same. So I polished the scripts, documented the process and published all my work as open-source - &lt;a href=&#34;https://gitlab.com/viktomas/total-youtube-watchtime&#34;&gt;Total YouTube Watchtime&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;If you&amp;rsquo;ve got some programming background, you should be able to replicate what I&amp;rsquo;ve done relatively easily with your own history. If you find any issues or come up with improvements, send me a Merge request.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;YouTube is a big portion of my entertainment so I&amp;rsquo;m not surprised that I&amp;rsquo;ve spent on average 45 minutes each day watching it. Not being surprised doesn&amp;rsquo;t mean I would like to keep spending my time this way and indeed my real chart is showing some good decline in watch time this year. I&amp;rsquo;ve got a few tips and tricks on how to reduce the appeal of YouTube. I&amp;rsquo;m going to share them in the next article.&lt;/p&gt;
&lt;p&gt;The main activity I&amp;rsquo;m replacing YouTube with is &lt;a href=&#34;https://blog.viktomas.com/books&#34;&gt;reading&lt;/a&gt;.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://takeout.google.com/&#34;&gt;Google Takeout&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.bls.gov/news.release/atus.nr0.htm&#34;&gt;American Time Use Survey 2018 results&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;The longest video I&amp;rsquo;ve had in my history is &lt;a href=&#34;https://www.youtube.com/watch?v=RtU_mdL2vBM&#34;&gt;NASA ISS live feed&lt;/a&gt; 534 days long and counting. I was relieved when I found that I didn&amp;rsquo;t spend almost two years extra watching YouTube.&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Give it to me: A polite request for feedback</title>
      <link>https://blog.viktomas.com/posts/give-it-to-me/</link>
      <pubDate>Sun, 03 May 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/give-it-to-me/</guid>
      <description>&lt;p&gt;Today we&amp;rsquo;ll have a look at how you can give me feedback for these articles. I&amp;rsquo;ll explain my motivation for writing, why is your opinion important to me and how you can share it. &lt;strong&gt;I guarantee I&amp;rsquo;m going to read every single comment.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;tldr&#34;&gt;TL;DR&lt;/h2&gt;
&lt;p&gt;You can give me feedback through comments on Google Doc&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. You can go to this document by clicking the &amp;ldquo;Give Feedback&amp;rdquo; button at the end of each article.&lt;/p&gt;
&lt;h2 id=&#34;why-do-i-keep-a-blog&#34;&gt;Why do I keep a blog&lt;/h2&gt;
&lt;p&gt;After I started working remotely full-time, I found out that explaining myself in writing is very different from sharing my thoughts in person. And part of this revelation was that I have plenty of space for improvement there. I started writing this blog to give myself motivation and accountability for learning the skill of writing. So the priority of this blog is to share ideas as clearly as possible, even though, of course, I&amp;rsquo;m trying to make your reading an enjoyable process too.&lt;/p&gt;
&lt;h2 id=&#34;how-to-do-this-better&#34;&gt;How to do this better&lt;/h2&gt;
&lt;p&gt;After writing articles for a few months I&amp;rsquo;m confident that I have formed a habit of writing. But can I do it well? I understand every idea I&amp;rsquo;m sharing here, but do you? Do the other readers understand? Are there any other readers?&lt;/p&gt;
&lt;p&gt;These questions nudged me to think of a feedback process. Scott Adams mentions in his book &lt;a href=&#34;https://blog.viktomas.com/books/adams-scott-how-to-fail-at-almost-everything/&#34;&gt;How to Fail at Almost Everything and Still Win Big&lt;/a&gt; the reasons why his Dilbert comic strip got so successful was that he included his email in the drawing itself and after that he started receiving feedback from his readers. See &lt;a href=&#34;https://dilbert.com/strip/1990-01-01&#34;&gt;before&lt;/a&gt; &amp;amp; &lt;a href=&#34;https://dilbert.com/strip/2001-01-01&#34;&gt;after&lt;/a&gt;. &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;h2 id=&#34;what-feedback-do-i-want&#34;&gt;What feedback do I want&lt;/h2&gt;
&lt;p&gt;Any constructive feedback is highly welcomed. As long as it is civil. I would also highly appreciate any suggestions.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The conclusion is confusing&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;That&amp;rsquo;s good. It shows me which part I should work on&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The conclusion is sidetracking from the thought introduced at the beginning of the article. The concept of Flumbus should be dropped and instead the conclusion should be driven from the Plumpot section.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Well done, this is amazing! Not only you are telling me what&amp;rsquo;s wrong, but you are helping me by explaining your understanding. Few of these will get you a mention in credits.&lt;/p&gt;
&lt;h2 id=&#34;what-feedback-should-you-keep-to-yourself&#34;&gt;What feedback should you keep to yourself&lt;/h2&gt;
&lt;p&gt;Feedback that I can&amp;rsquo;t act on, insults, anything that you wouldn&amp;rsquo;t say in my face: I&amp;rsquo;m 186 cm, 85 kg, sporty, with a bit of martial arts background.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This sucks.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I can&amp;rsquo;t act on this feedback, it doesn&amp;rsquo;t give me a way to improve.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You have to be stupid to write this.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Maybe you have a valid point but it&amp;rsquo;s going to be hard for me to find it with this presentation.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;F#!k you, you @#$!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is clearly violating the last condition (unless you are a 2 meters tall 100 kg boxer).&lt;/p&gt;
&lt;h2 id=&#34;feedback-process&#34;&gt;Feedback process&lt;/h2&gt;
&lt;p&gt;I was considering many alternatives starting with simple solutions like a standard comment section under each article to more complex workflows that would include Git and GitLab. Comment section would provide the lowest barrier to entry, but it would support generic feedback and not provide good enough tools for giving specific feedback. The hard-core option using GitLab would disqualify any person who&amp;rsquo;s not familiar with software development.&lt;/p&gt;
&lt;h3 id=&#34;google-docs&#34;&gt;Google Docs&lt;/h3&gt;
&lt;p&gt;The winner is Google Docs. Google made it extremely simple to contribute to its documents and even though commenting on documents is still not a common practice, it is easy to learn and understand. All the following aspects contributed to the decision:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Encourages giving concrete feedback as opposed to generic &lt;em&gt;This is great&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;Familiar software - almost everyone has experience either with Google Docs or Microsoft Word&lt;/li&gt;
&lt;li&gt;Free of charge&lt;/li&gt;
&lt;li&gt;Supports anonymous contribution - No login necessary&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;If you decide to spend time and effort and tell me about something that could be improved in my writing or in my fact checking, I&amp;rsquo;ll be incredibly grateful. If your feedback is constructive and helps me improve the article (and myself) I&amp;rsquo;ll include you in a &amp;ldquo;Credits&amp;rdquo; section at the bottom of the article as a means of showing at least some of my appreciation.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s all improve together!&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;If you haven&amp;rsquo;t got much experience with commenting on documents, the &lt;a href=&#34;https://www.howtogeek.com/397601/how-to-add-comments-in-google-docs/&#34;&gt;How to Add Comments in Google Docs&lt;/a&gt; should help you.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;In case you are wondering why I didn&amp;rsquo;t include the pictures directly, it&amp;rsquo;s because Scott is asking $35 a pop :)&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</description>
    </item>
    
    <item>
      <title>Bohumil Hrabal - I Served the King of England </title>
      <link>https://blog.viktomas.com/books/hrabal-bohumil--i-served-the-king-of-england/</link>
      <pubDate>Wed, 29 Apr 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/hrabal-bohumil--i-served-the-king-of-england/</guid>
      <description>&lt;p&gt;When I started reading this e-book, I thought that I&amp;rsquo;ve got to get a faulty file. Bohumil definitely wasn&amp;rsquo;t messing around when starting this book. It&amp;rsquo;s on since the page 1.&lt;/p&gt;
&lt;p&gt;My impression of the book is of a downhill action packed ride like in the movies &lt;a href=&#34;https://www.imdb.com/title/tt0106856/&#34;&gt;Falling Down&lt;/a&gt;, &lt;a href=&#34;https://www.imdb.com/title/tt0111257/?ref_=fn_al_tt_1&#34;&gt;Speed&lt;/a&gt; or &lt;a href=&#34;https://www.imdb.com/title/tt0479884/?ref_=nm_flmg_act_31&#34;&gt;Crank&lt;/a&gt;. You get into a very eventful stream of experience of the main character Jan. Following his story from early teens to old age in one big sentence. And when I say sentence I mean it.&lt;/p&gt;
&lt;p&gt;When Bohumil (the author) went to a primary school, they were teaching him about the letters, punctuation and sentences. After that he said:&lt;/p&gt;
&lt;p&gt;&lt;img
    src=&#34;https://i.imgflip.com/1qbj6g.jpg&#34;
    alt=&#34;I&amp;rsquo;ve got this&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;And went on writing this book. You could count the paragraphs on your fingers and sentences are pages long. But this unique style contributed to the &amp;ldquo;uninterrupted flow of events&amp;rdquo; experience.&lt;/p&gt;
&lt;p&gt;The book is funny at times and really dark at others. As Jan (main character) gets older, the book gets more serious. I enjoyed reading it and would agree that it&amp;rsquo;s one of the better book Czech literature has to offer.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>David Thomas, Andrew Hunt - The Pragmatic Programmer</title>
      <link>https://blog.viktomas.com/books/thomas-hunt--pragmatic-programmer/</link>
      <pubDate>Sat, 25 Apr 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/thomas-hunt--pragmatic-programmer/</guid>
      <description>&lt;p&gt;I have no idea, why did it take me 10 years of professional programming to get this book and read it. Maybe it was the 1999 release date that made it look too old. Too old to provide any useful advice. I&amp;rsquo;m therefore really happy that the authors decided to give that book a polish and release 20th anniversary edition.&lt;/p&gt;
&lt;p&gt;This book instantly made it to top 5 technical books I&amp;rsquo;ve ever read and I now understand why the first edition had such a massive cult around it. It is well-rounded &amp;ldquo;How to be a software developer&amp;rdquo; guide that will provide value to both starting engineers and long time professionals.&lt;/p&gt;
&lt;p&gt;It contains a good mix of soft, lofty ideas and hard practical coding advice. Both big picture and detailed oriented programmers will find their value in it.&lt;/p&gt;
&lt;p&gt;One thing is for certain. This is not the last time I&amp;rsquo;m reading this book.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>What would you do if you lost your Google account?</title>
      <link>https://blog.viktomas.com/posts/losing-google-account/</link>
      <pubDate>Sat, 25 Apr 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/losing-google-account/</guid>
      <description>&lt;p&gt;I was reading horror stories in the past about people getting locked out of their Google accounts. If you are anything like me, half of your digital life is stored in Google. Losing access to all this data would be traumatic at best.&lt;/p&gt;
&lt;p&gt;In this article I&amp;rsquo;m researching what happens when you forget your password or lose your phone. What information will Google want to know about you and how can you best prepare for this situation so you don&amp;rsquo;t lose access to your account completely.&lt;/p&gt;
&lt;figure class=&#34;center&#34;&gt;
    &lt;img style=&#34;max-width: 450px&#34; src=&#34;https://blog.viktomas.com/images/posts/losing-google-account.svg&#34; alt=&#34;Theme illustration&#34; /&gt;
&lt;figcaption&gt;
&lt;p&gt;&lt;em&gt;&amp;ldquo;Illustration&amp;rdquo; by &lt;a href=&#34;https://ljubicapetkovic.com&#34;&gt;Ljubica Petkovic&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;
&lt;/figcaption&gt;
&lt;/figure&gt;
&lt;p&gt;I&amp;rsquo;ve been using the same Google account for the last 12 years&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. And to be honest, I&amp;rsquo;ve never changed the password and never turned on the 2-Step Verification&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt; because I was afraid that I&amp;rsquo;ll lose my phone or forget my password and I won&amp;rsquo;t be able to access my account any more. I think this is not sustainable, so let&amp;rsquo;s have a look at what happens when you forget your password or you lose your phone.&lt;/p&gt;
&lt;p&gt;Google is using the following two steps to authenticate you:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1st step - &lt;strong&gt;Password&lt;/strong&gt; (mandatory) - To prove that it is really you, you need to provide Google with a text password&lt;/li&gt;
&lt;li&gt;2nd step - &lt;strong&gt;You phone&lt;/strong&gt; (optional) - Google uses different means (SMS, notifications, authenticator app) to enable your phone to uniquely identify you. On top of that it&amp;rsquo;s possible to use Security keys or keys generated by your password manager, but for simplicity we&amp;rsquo;ll use the phone example.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;This approach combines something you know (password) with something you have (phone) to make it much harder for someone to impersonate you (e.g. by tricking you to enter a password into a fake log-in dialogue).&lt;/p&gt;
&lt;h2 id=&#34;turning-on-2-step-verification&#34;&gt;Turning on 2-Step Verification&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;First, you can relax. 2-Step Verification can be turned back off&lt;/strong&gt;&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;When you follow the steps in &lt;a href=&#34;https://myaccount.google.com/signinoptions/two-step-verification/enroll-welcome&#34;&gt;Google&amp;rsquo;s guide&lt;/a&gt;, you get asked which of the following options would you&amp;rsquo;d like to use:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Notifications (Prompts) to your Android phone&lt;/li&gt;
&lt;li&gt;Security Key - USB stick-like device e.g. YubiKey&lt;/li&gt;
&lt;li&gt;SMS and Phone calls&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I choose notifications for convenience.&lt;/p&gt;
&lt;p&gt;Then Google asks whether I&amp;rsquo;d like to use a backup number in case you lose my phone. But if I lose my phone my number is gone too since I always use prepaid. I chose to get &lt;strong&gt;backup codes&lt;/strong&gt; instead. They are single-use codes that are more versatile than a phone number.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Tip 1: Store your backup keys in your password manager so if you don&amp;rsquo;t have your phone on you, you can still log in.&lt;/strong&gt;&lt;/p&gt;
&lt;h2 id=&#34;account-recovery-when-you-cant-prove-it-is-you&#34;&gt;Account recovery: when you can&amp;rsquo;t prove it is you&lt;/h2&gt;
&lt;p&gt;You lost your phone and your dog ate your backup codes. Or you are having soap opera level amnesia and you don&amp;rsquo;t remember your password. How do you access your Google account?&lt;/p&gt;
&lt;p&gt;Now you are going to end up with the dreaded &lt;em&gt;Google Account Recovery&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;The algorithm used by google to evaluate your identity is not openly known. Here are the things Google will want to know from you:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;What is the last password you remember?&lt;/li&gt;
&lt;li&gt;Do you still have access to your mobile devices?&lt;/li&gt;
&lt;li&gt;Your recovery phone&lt;/li&gt;
&lt;li&gt;Your recovery email&lt;/li&gt;
&lt;li&gt;Answer to your security question (&lt;em&gt;deprecated&lt;/em&gt;)&lt;/li&gt;
&lt;li&gt;Request for providing additional details in writing (e.g. when you created your account, if you are travelling)&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Now if you answer all of these sufficiently (and ideally from the same browser and IP address that you usually use), you are going to get a link to a page where you reset your password.&lt;/p&gt;
&lt;p&gt;If you don&amp;rsquo;t answer these questions well enough, Google won&amp;rsquo;t grant you access to your account and it recommends that you forget about it and start a new one&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;We couldn&amp;rsquo;t be sure that you&amp;rsquo;re the owner. To keep accounts safe, we can&amp;rsquo;t give access to them if we can&amp;rsquo;t confirm who the owner is.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;Tip 2: Keep your recovery information up to date&lt;/strong&gt;&lt;sup id=&#34;fnref:5&#34;&gt;&lt;a href=&#34;#fn:5&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;5&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;The best way to prepare for his situation is to have all your recovery information up to date. I&amp;rsquo;m not sure how all these recovery options affect the security. It seems to me that if you provide too many ways how to reset your account&amp;rsquo;s password, it makes it easier for someone else to do it as well.&lt;/p&gt;
&lt;h2 id=&#34;prepare-for-the-worst&#34;&gt;Prepare for the worst&lt;/h2&gt;
&lt;p&gt;The way I understand it, if you get to the &amp;ldquo;Account recovery&amp;rdquo; phase, you can&amp;rsquo;t be certain that you are going to get your account back. Most likely having your recovery email and phone up to date is going to be enough, but what if your IP looks really suspicious for some reason (trip to Thailand maybe)? One of my other Google accounts actually have been inactive for so long that Google doesn&amp;rsquo;t trust me when I enter the password and there&amp;rsquo;s no way to recover.&lt;/p&gt;
&lt;p&gt;There is one more option for super paranoid people. Backup all your data. For all things I dislike about Google, they do give you a full access to your data. Visit &lt;a href=&#34;https://takeout.google.com/&#34;&gt;Google Takeout&lt;/a&gt; to back up all your data locally (for me it is 2.8GB of email that I&amp;rsquo;m interested in). This approach brings its own risks. I&amp;rsquo;d strongly recommend encrypting the backup otherwise you have a big portion of your online life lying in a plaintext on your hard drive.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;I hope this article helped you to understand what might happen if you forget/lose your credentials/phone. I feel much more confident about both the security of my account and how to recover it should the situation arise.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Find out when you started your account by looking for &lt;a href=&#34;https://webapps.stackexchange.com/a/50790&#34;&gt;the very first message&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.google.com/landing/2step/index.html&#34;&gt;2-Step Authentication Google site&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://support.google.com/accounts/answer/1064203&#34;&gt;Turning off 2-Step Verification&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://support.google.com/accounts/answer/7564124&#34;&gt;Create a replacement account&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:5&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://support.google.com/accounts/answer/183723&#34;&gt;Account recovery information&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:5&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Using text passwords for encryption is safe enough</title>
      <link>https://blog.viktomas.com/posts/plaintext-passwords/</link>
      <pubDate>Sun, 19 Apr 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/plaintext-passwords/</guid>
      <description>&lt;p&gt;I had a creeping suspicion in my head lately. I&amp;rsquo;m using a text password as a key to encrypt all my other passwords. I started to worry that the text password is not safe enough and I&amp;rsquo;m only placing a minor obstacle between my passwords and a curious person. Let&amp;rsquo;s have a look whether I was right.&lt;/p&gt;
&lt;p&gt;I like the idea of knowing that some things are just mine, especially my thoughts. That&amp;rsquo;s why I like to have as much of my data encrypted or, when 3rd party service stores it, at least behind a strong password. I recently wrote about security and about your &lt;a href=&#34;https://blog.viktomas.com/posts/security-is-like-ogres/#the-core&#34;&gt;password manager being at the core of it&lt;/a&gt;. My &lt;a href=&#34;https://keepassxc.org&#34;&gt;password manager&lt;/a&gt; contains all my debit cards, all passwords to websites, and a quite few encryption keys. But there is one issue with my password manager that was my little dirty secret. Until now.&lt;/p&gt;
&lt;h2 id=&#34;using-text-passwords&#34;&gt;Using text passwords&lt;/h2&gt;
&lt;p&gt;My keychain file (the file where password manager encrypts all the passwords) is using only a text password as an encryption key and I store this keychain on Dropbox (which is relatively unsafe storage). I did this because I was always afraid that if I use a long key I don&amp;rsquo;t personally remember (e.g. RSA private key), I&amp;rsquo;m going to lose it and all my data with it. The password is not trivial, but it&amp;rsquo;s only 15 characters. I now want to look at how safe my data behind this password actually is if I need to consider any alternatives to a text password.&lt;/p&gt;
&lt;p&gt;I have to admit that for designing the password I was using a &lt;a href=&#34;https://xkcd.com/936/&#34;&gt;XKCD comic&lt;/a&gt;. The advice there is the following: Choose 4 random words, chain them together and the level of entropy is going to be ~ 44 bits which means that at 1000 guesses/second it&amp;rsquo;s going to take 550 years to crack.&lt;/p&gt;
&lt;p&gt;The problem with my keychain is that it&amp;rsquo;s not a web service that can limit the number of login attempts. If someone gets a hold of the keychain file, the sky&amp;rsquo;s the limit when it comes to brute forcing the password.&lt;/p&gt;
&lt;h3 id=&#34;cracking-my-own-password&#34;&gt;Cracking my own password&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Password Manager: &lt;a href=&#34;https://keepassxc.org&#34;&gt;KeePassXC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Cipher: AES (kdbx 4.0)&lt;/li&gt;
&lt;li&gt;Attempts per second: 1&lt;/li&gt;
&lt;li&gt;How many attempts are necessary 2^44&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;After researching several articles &lt;a href=&#34;https://madcityhacker.com/2018/11/04/cracking-keepass-databases-with-hashcat/&#34;&gt;[a]&lt;/a&gt;&lt;a href=&#34;https://www.rubydevices.com.au/blog/how-to-hack-keepass&#34;&gt;[b]&lt;/a&gt;&lt;a href=&#34;https://keepassxc.org/docs/#faq-security-why-pm&#34;&gt;[c]&lt;/a&gt;&lt;a href=&#34;https://www.harmj0y.net/blog/redteaming/a-case-study-in-attacking-keepass/&#34;&gt;[d]&lt;/a&gt;&lt;a href=&#34;https://security.stackexchange.com/a/8477&#34;&gt;[e]&lt;/a&gt; I learned that my assumption from the previous section is incorrect.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The problem with my keychain is that it&amp;rsquo;s not a web service that can limit the number of login attempts. If someone gets a hold of the keychain file, the sky&amp;rsquo;s the limit when it comes to brute forcing the password.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The keychain file is encrypted using a cypher (AES) that by itself &lt;em&gt;could&lt;/em&gt; be easier to crack. However, before the key is used it goes through a large number of so called key transformations&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; so in the end it takes milliseconds to validate one password. On top of that, you can tweak how many times the key should be transformed based on how long you are willing to wait for the keychain to open.&lt;/p&gt;
&lt;p&gt;So when you saw &amp;ldquo;Attempts per second&amp;rdquo; being equal to 1, that means that I asked KeePassXC to run the key transformations for one second on my i9 MacBook Pro.&lt;/p&gt;
&lt;p&gt;That means that if I tried to brute force (with a dictionary) a password with 4 common words in it on my laptop, it would take 550,000 years&lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;Now, this number is definitely way too optimistic. Following factors could significantly reduce the time:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;I&amp;rsquo;m not sure whether KeePassXC uses all 12 CPU cores on my PC, probably not. That means I could divide the brute force time by 12 - 46,000 years&lt;/li&gt;
&lt;li&gt;Using some strong GPU could easily bring down the number by two orders of magnitude - 460 years&lt;/li&gt;
&lt;li&gt;Using 460 strong computers would bring this time down to year&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Even though these steps would require a lot of effort, they are not outside of the realm of possibility. It would just cost up to 12 million dollars&lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;These computations are very crude. Please if you have better understanding/information about the kdbx 4.0 file format and how to brute force the passwords, let me know&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;how-to-prevent-a-hacker-with-12m-from-getting-to-your-passwords&#34;&gt;How to prevent a hacker with $12M from getting to your passwords?&lt;/h2&gt;
&lt;p&gt;It sounds like there is no need for a drastic change. Few orders of magnitude will make the change infeasible even for Jeff Bezos.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Add a couple words that are not in the dictionary. Use a different language or a slang. That should rule out the dictionary attack and make the password not crackable at least in your lifetime.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;This investigation was a very pleasant surprise to me. I was living under an impression that I&amp;rsquo;m storing my passwords pretty much in a glorified text file and now after invalidating my assumption I realize that my passwords are safe.&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;Six-word password including some non-dictionary words is in combination with thousands of key transformations almost impossible to crack.&lt;/p&gt;
&lt;h4 id=&#34;acknowledgements&#34;&gt;Acknowledgements&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Thanks Andrei Damian-Fekete for helping to clarify parts of the article and fixing some of my grammar&lt;/li&gt;
&lt;/ul&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;60,000 times by default&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;I&amp;rsquo;m still using the &lt;a href=&#34;https://xkcd.com/936/&#34;&gt;XKCD comic&lt;/a&gt; as a base for my calculations&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;1 &lt;code&gt;p3.2xlarge&lt;/code&gt; &lt;a href=&#34;https://aws.amazon.com/ec2/pricing/on-demand/&#34;&gt;costs $3/hour&lt;/a&gt; =&amp;gt; 460 * 3 * 24 * 365 = 12,088,800&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;All this effort can be reduced to almost no effort at all if someone can get access to your computer and listen on your keyboard the moment you are typing in your password. The same is true if there is a bug in the keychain software itself. For example the KeePassXC &lt;a href=&#34;https://keepassxc.org/docs/#faq-audit&#34;&gt;can&amp;rsquo;t guarantee there isn&amp;rsquo;t an encryption bug&lt;/a&gt;. However, the same applies for other encryption mechanisms like OpenSSL that encrypts virtually all traffic on the internet.&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Cal Newport - Deep Work: Rules for Focused Success in a Distracted World</title>
      <link>https://blog.viktomas.com/books/newport-cal--deep-work/</link>
      <pubDate>Sat, 18 Apr 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/newport-cal--deep-work/</guid>
      <description>&lt;p&gt;I have a mixed feeling about this book. On one hand it was extremely repetitive and the first part of the book felt like a broken record. But this might just be because I&amp;rsquo;m familiar with the concepts explained, and I was already putting a large emphasis on focused work free from distraction. When the topic is new to me I actually quite appreciate repetition since it gives me a lot of examples and points of view for the same argument.&lt;/p&gt;
&lt;p&gt;The second part of the book, the part where you get concrete advice on what to do, was less repetitive. It fit well into the framework explained and there were a few gems that are going to be super useful to me:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You don&amp;rsquo;t have to avoid distraction (e.g. YouTube) completely, it&amp;rsquo;s enough to schedule it well in advance&lt;/li&gt;
&lt;li&gt;The benefit of every tool and platform you use needs to be weighted against your personal goals and values so you can see the costs as well&lt;/li&gt;
&lt;li&gt;There is not clear cause -&amp;gt; effect relationship in a lot of the knowledge work (emails, meetings, &amp;hellip;) and in the absence of this clear measurement people default to what is easiest and often try to look busy doing it&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Since this is such a short read, I would recommend it to a friend, especially if they are struggling with focus.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Note: I wish the author added the citations to the text, so I could recognize when he&amp;rsquo;s expressing his opinion and when is the fact supported by some research&lt;/em&gt;&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Burton G. Malkiel - A Random Walk Down Wall Street</title>
      <link>https://blog.viktomas.com/books/malkiel-burton--random-walk-down-wallstreet/</link>
      <pubDate>Mon, 13 Apr 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/malkiel-burton--random-walk-down-wallstreet/</guid>
      <description>&lt;p&gt;When I read Barefoot investor three years ago, I felt like I discovered a whole new world. Lowering taxes by saving for retirement, indexed funds? In my late twenties I finally started saving more intelligently.&lt;/p&gt;
&lt;p&gt;Now the Random Walk took it a one step further. I actually understand the concepts behind the saving mechanisms and stock markets. I loved how the book encouraged critical thinking by describing smart concepts (authors of which often deserved Nobel Prize) and then showing their shortcomings.&lt;/p&gt;
&lt;p&gt;As an engineer I love scientific approach and it is delight when Burton shows sometimes 30 years, other times 200 years of historical data to support his arguments.&lt;/p&gt;
&lt;p&gt;The closing chapter that was talking about the obvious question &lt;em&gt;&amp;ldquo;What if everyone does indexing&amp;rdquo;&lt;/em&gt; could be more detailed, because I still don&amp;rsquo;t believe that the stock pricing would be efficient if the whole stock market is in indexed funds.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>My workflow</title>
      <link>https://blog.viktomas.com/posts/my-workflow/</link>
      <pubDate>Sun, 12 Apr 2020 17:33:00 +0200</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/my-workflow/</guid>
      <description>&lt;p&gt;Since the dawn of time (my school years) I&amp;rsquo;ve been battling procrastination. Doing the assignments at the latest possible time was a popular activity in my social circles and I don&amp;rsquo;t remember when/if I actually started working on an assignment the day I got it.&lt;/p&gt;
&lt;p&gt;There was one mystical place where procrastination mostly avoided me and that place was the office. With colleagues sitting all around me and working, there doesn&amp;rsquo;t seem to be any alternative other than to work as well. You can still procrastinate by doing a simpler task instead of more complex task, but in this post when I say procrastination, I&amp;rsquo;m talking about doing something else than work: watching YouTube, reading blogs and news or chatting with friends over some message platform.&lt;/p&gt;
&lt;p&gt;Now the problem with this mystical place called the office is that its powers don&amp;rsquo;t extend to &lt;a href=&#34;https://blog.viktomas.com/posts/remote&#34;&gt;remote work&lt;/a&gt;. If you are in your flat, it&amp;rsquo;s easy to just open the YouTube video or to message your friend how is she doing. And this applies to anyone working remotely, regardless whether it&amp;rsquo;s full time or 2 days a month.&lt;/p&gt;
&lt;p&gt;To battle the procrastination and improve focus I started looking around for a workflow that would help me stay focused during remote work.&lt;/p&gt;
&lt;h2 id=&#34;my-workflow&#34;&gt;My workflow&lt;/h2&gt;
&lt;p&gt;My work-in-progress approach to focused work consists of two key parts: 25 minute units of uninterrupted work and structured, plain text task list.&lt;/p&gt;
&lt;h3 id=&#34;25-minute-units&#34;&gt;25 minute units&lt;/h3&gt;
&lt;p&gt;I borrowed the core idea from &lt;a href=&#34;#apendix-1-pomodoro&#34;&gt;Pomodoro technique&lt;/a&gt; and enhanced it with additional set of rules.&lt;/p&gt;
&lt;p&gt;You split your work into units of 25 minutes of uninterrupted work. No responding to messages, no checking news. You can do that after the 25 minutes is over but not until then. And you try to focus these units on one thing.&lt;/p&gt;
&lt;p&gt;And these additional rules are not part of Pomodoro:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;You work 12 units a day&lt;/li&gt;
&lt;li&gt;You try to take a high level view after finishing a unit (if you were bogged down in task details, you stop and ask: &amp;ldquo;Is there a different way to achieve the same goal?&amp;rdquo;), end of the unit is a good time to change direction&lt;/li&gt;
&lt;li&gt;You don&amp;rsquo;t have to take the break (but you have to do the high level view exercise)&lt;/li&gt;
&lt;li&gt;Meetings don&amp;rsquo;t count as a unit&lt;/li&gt;
&lt;/ul&gt;
&lt;h4 id=&#34;timer&#34;&gt;timer&lt;/h4&gt;
&lt;p&gt;I started by using &lt;a href=&#34;https://setapp.com/apps/be-focused&#34;&gt;Be focused app&lt;/a&gt; on my Mac, but after a while I decided to create my own app for two main reasons:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I want to use free and open-source software as much as possible.&lt;/li&gt;
&lt;li&gt;I didn&amp;rsquo;t have access to my raw data.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The result is &lt;a href=&#34;https://gitlab.com/viktomas/timer/&#34;&gt;timer&lt;/a&gt; a tiny CLI utility go program that keeps track of your units in an easy to work with JSON file.&lt;/p&gt;
&lt;h3 id=&#34;structured-plain-text-task-list&#34;&gt;Structured, plain text task list&lt;/h3&gt;
&lt;p&gt;This is the second ingredient to my focused work. I keep all my tasks with temporary notes in a text file like &lt;code&gt;2020-04-12.md&lt;/code&gt;. The file has the following life-cycle.&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;At the end of the previous day I created task file for the next day and I put in the tasks I would like to do tomorrow&lt;/li&gt;
&lt;li&gt;On the day I use the first unit to go through all my email and put in additional tasks like &amp;ldquo;respond to John&amp;rdquo;, &amp;ldquo;review Alex&amp;rsquo;s work&amp;rdquo;&lt;/li&gt;
&lt;li&gt;I always put the main task of the day first, but I limit the amount of units I&amp;rsquo;ll work on it (max 6)&lt;/li&gt;
&lt;li&gt;Then I go through the remaining tasks&lt;/li&gt;
&lt;li&gt;During the day or at the very latest at the end of the day I try to put all my temporary notes on the GitLab issues&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt; so I don&amp;rsquo;t keep any information to myself.&lt;/li&gt;
&lt;li&gt;I create a draft of the task file for the next day.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The key trick for me was putting the main task first, but making sure I won&amp;rsquo;t spend the whole day working on it ignoring conversations and other important small tasks.&lt;/p&gt;
&lt;h4 id=&#34;example-file&#34;&gt;Example file&lt;/h4&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-markdown&#34; data-lang=&#34;markdown&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;# Debug production database issue (max 4 units)✅
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;-&lt;/span&gt; [link to the issue](https://gitlab.com/project/issues/123)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;-&lt;/span&gt; temporary note
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;## Review Matthews code✅
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;-&lt;/span&gt; [link to the MR](https://gitlab.com/project/merge_requests/321)
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;## Prepare agenda for the monthly meeting✅
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;font-weight:bold&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;-&lt;/span&gt; get statistics for the last month❌
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;-&lt;/span&gt; mention the production outage✅
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;-&lt;/span&gt; shout out to John✅
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;So here you have it. This is still work in progress and I would welcome any feedback. The main sticking point for me is that 5-minute breaks between units sometimes stretch to 40 or more minutes and that I feel guilty if I can finish my units quickly (equal to roughly 7 hours of work) and I feel less guilty if I get distracted and I spent 9 hours at the computer.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;GitLab issues is a system we use for tracking work tasks.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Minimalism</title>
      <link>https://blog.viktomas.com/posts/minimalism/</link>
      <pubDate>Sun, 05 Apr 2020 14:02:00 +0200</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/minimalism/</guid>
      <description>&lt;p&gt;I was sitting in my rented room in central Melbourne. After months of preparations I was closing &lt;em&gt;my suitcase&lt;/em&gt;, expecting an Uber any minute taking me to the airport. Leaving Australia after almost five years of living there and closing or at least pausing a chapter in my life.&lt;/p&gt;
&lt;p&gt;This article is going to be focused on one critical section of the previous paragraph: &amp;ldquo;my suitcase&amp;rdquo;. I&amp;rsquo;m going to be writing about how I managed to squish five years of my life to a suitcase, even though I lived in a fully furnished house, owned motorbike and at one point in time even a car.&lt;/p&gt;
&lt;h2 id=&#34;minimalism&#34;&gt;Minimalism&lt;/h2&gt;
&lt;p&gt;This term is heavily used in hipster, millennial setting. My definition might be a bit different.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Minimalism is a process of evaluating your current and future activities and possessions based on benefit to stress ratio. And only accepting the ones where the benefit is significantly larger than stress.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The way people sometimes look at minimalism is as process of throwing away stuff you don&amp;rsquo;t use. That&amp;rsquo;s surely under my definition, since a vase you haven&amp;rsquo;t used for two years doesn&amp;rsquo;t bring you any benefit, but the stress (cleaning it, having space for it, even just having it in your life) is non-zero.&lt;/p&gt;
&lt;p&gt;But my definition is a bit broader and can be used on activities or even on things like a car which you are still using. But I&amp;rsquo;ll be focusing mainly on material stuff since it&amp;rsquo;s the easiest to understand. The following table illustrates the process:&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Activity/Possession&lt;/th&gt;
          &lt;th&gt;Benefit&lt;/th&gt;
          &lt;th&gt;Stress&lt;/th&gt;
          &lt;th&gt;Result&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Car when living in city centre&lt;/td&gt;
          &lt;td&gt;Freedom to go for weekend trips or shopping to a mall&lt;/td&gt;
          &lt;td&gt;Repairs, registration fees, parking, insurance, ..&lt;/td&gt;
          &lt;td&gt;Sell&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Tennis racket when I&amp;rsquo;m not a tennis player&lt;/td&gt;
          &lt;td&gt;I don&amp;rsquo;t have to pay the rent when I go once every two years to play&lt;/td&gt;
          &lt;td&gt;storage space&lt;/td&gt;
          &lt;td&gt;Sell/Give away&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Expensive headphones&lt;/td&gt;
          &lt;td&gt;Listening to good music every day&lt;/td&gt;
          &lt;td&gt;Lot of money, worrying that I can lose them&lt;/td&gt;
          &lt;td&gt;Keep&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Drinking&lt;/td&gt;
          &lt;td&gt;Easy to be social, meeting more new people, good stories&lt;/td&gt;
          &lt;td&gt;Costs money, lost days to hungover, the morning shame&lt;/td&gt;
          &lt;td&gt;Stop&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;advantages-to-practising-minimalism&#34;&gt;Advantages to practising minimalism&lt;/h2&gt;
&lt;p&gt;By definition, practising minimalism reduces stress in your life. That&amp;rsquo;s by far the biggest reason to use it for me. But it is not the only one.&lt;/p&gt;
&lt;p&gt;Minimalism helps you live below your means. If you focus on only keeping/buying the stuff that brings you exceptional value, you don&amp;rsquo;t have to spend all the money you are earning and you can even focus on &lt;a href=&#34;https://blog.viktomas.com/posts/opportunity-cost&#34;&gt;using your savings to act on some opportunities&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Having less, rather than more, stuff in your life makes it easier for you to focus on the stuff that matters to you. With the car example, if you decide to sell your car, you can spend the time and resources on practising martial arts, collecting post stamps or anything else that is more important to you than a car.&lt;/p&gt;
&lt;h2 id=&#34;tips-and-tricks-how-to-practice-minimalism&#34;&gt;Tips and tricks how to practice minimalism&lt;/h2&gt;
&lt;p&gt;The key is to minimize your attachment to things. Meaning you don&amp;rsquo;t care too much if you loose a thing, break it or loose it. This is not always going to be the case, I love my expensive headphones and I&amp;rsquo;d cry if anything happened to them, but as a rule of thumb you should be striving to keep the attachment low with the following tricks:&lt;/p&gt;
&lt;h3 id=&#34;1---use-iteration&#34;&gt;1 - Use iteration&lt;/h3&gt;
&lt;p&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/iteration&#34;&gt;Iteration&lt;/a&gt; is the art of starting small, validating that you really want to continue it that direction and then doing another step. In minimalism, classical example is when you want to start a new hobby, get the bare minimum of cheap tools to begin with and then if you still like it in a month, buy a bit more and then a bit more.&lt;/p&gt;
&lt;p&gt;Extension of this trick is to only buy expensive thing if you already own the same kind of thing that is cheaper and you use it very often. One of my recent examples is investing $200 on a new Pocketbook e-book reader only after heavily using the cheapest Kindle for two years.&lt;/p&gt;
&lt;h3 id=&#34;2---buy-second-hand-stuff-if-possible&#34;&gt;2 - Buy second hand stuff if possible&lt;/h3&gt;
&lt;p&gt;Imagine you are selling at TV that you are not using any more. If you bought a new one, it could have easily cost you $1500 and you are going to be selling it for $400. But if you bought it second hand, there is a good chance you bought it for $600 or less and you are still selling it for $400.&lt;/p&gt;
&lt;p&gt;This example illustrates why it&amp;rsquo;s easier to get rid of second hand stuff. On top of that, the definition of minimalism is to have things with a great benefit to you after you considered stress. If &lt;code&gt;hustle of buying second hand &amp;lt; $900&lt;/code&gt;, you can see how buying second hand is minimalistic.&lt;/p&gt;
&lt;h3 id=&#34;3---always-prefer-more-common-things&#34;&gt;3 - Always prefer more common things&lt;/h3&gt;
&lt;p&gt;If you are about to buy new car and you have a choice whether to buy factory Kia Rio or some tuned up, painted Holden Ute, always go with the more common, boring thing (Kia here if you were in doubt). You are less likely to be attached to the more common thing and it&amp;rsquo;s in orders of magnitude easier to sell (extension of 2nd trick).&lt;/p&gt;
&lt;h3 id=&#34;4---avoid-impulse-buying&#34;&gt;4 - Avoid impulse buying&lt;/h3&gt;
&lt;p&gt;If you don&amp;rsquo;t &lt;strong&gt;need&lt;/strong&gt; to buy the thing immediately, don&amp;rsquo;t. Give it a week or rather two. Especially with expenses over $100. The expectation is more often than not better than the real deal and the expectation and excitement dies down over time. After a couple of weeks you might sober up and realize that the thing you wanted that much is not actually going to bring you that much joy.&lt;/p&gt;
&lt;p&gt;My recent example was a 3D printer. Early last week I was supper excited to buy $250 3D printer, thinking about all the things I&amp;rsquo;m going to print. Now, almost a week later I&amp;rsquo;m not at all convinced I need it.&lt;/p&gt;
&lt;h2 id=&#34;drawbacks-of-minimalism&#34;&gt;Drawbacks of minimalism&lt;/h2&gt;
&lt;p&gt;Even though I&amp;rsquo;m a big proponent of minimalism, there are drawbacks. Especially if you are living on a tight budget and you are in a country house, there might be less stress with hoarding than in a city flat and the benefit of not spending a penny more might be more important to you.&lt;/p&gt;
&lt;p&gt;Another drawback I can think of is the &amp;ldquo;I could totally use that thing I got rid of&amp;rdquo; effect. If you found a vase that you haven&amp;rsquo;t used for two years and you just threw it away, you can bet your hat on having at least two or three situations in the following month when you could totally use that vase. This is just a side effect of loading the vase again to the front of your mind and it is inseparable part of getting rid of old stuff.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;So by following the minimalistic process and by trying to live by the tricks I mentioned, I managed to sell my motorbike for only $500 less than for what I bought it three years earlier. I sold my car for almost the same amount. And with the little furniture I had, it was very similar story. In the end, when I was waiting for my flight at Tullamarine airport, I had room to spare in my suitcase.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Why I Love SpaceX</title>
      <link>https://blog.viktomas.com/posts/spacex/</link>
      <pubDate>Sun, 29 Mar 2020 11:57:00 +0200</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/spacex/</guid>
      <description>&lt;p&gt;Probably my favourite company of all time, SpaceX, is a manufacturer of rockets and satellites. They inspire people around the whole world and are a great showcase of what is good about US.&lt;/p&gt;
&lt;h2 id=&#34;1---making-life-multi-planetary&#34;&gt;1 - Making life multi planetary&lt;/h2&gt;
&lt;p&gt;SpaceX&amp;rsquo;s mission is nothing less than making sure that humanity can survive a mass extinction event on Earth. It&amp;rsquo;s the whole way Elon Musk, the influential founder and Chief Engineer of SpaceX evaluates his priorities when faced between two options: &lt;strong&gt;Which option is going to get us humans faster to having a self-sustained colony on Mars&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;One of the major reasons for keeping the company privately owned is that SpaceX doesn&amp;rsquo;t want to be forced by shareholders to prioritize short-term profit driven goals over colonization of other planets.&lt;/p&gt;
&lt;h2 id=&#34;2---i-can-relive-the-70s-space-program&#34;&gt;2 - I can relive the 70s space program&lt;/h2&gt;
&lt;p&gt;SpaceX is incredibly open about what they are doing and what their plans are. You can even watch their rocket launches in real-time on their &lt;a href=&#34;https://www.youtube.com/user/spacexchannel&#34;&gt;YouTube channel&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;The event that will always be written in my memory is when SpaceX launched the first (and to this day last) Falcon Heavy. I remember watching the launch first thing in the morning, seeing the notoriously famous &lt;a href=&#34;https://youtu.be/wbSwFU6tY1c?t=1786&#34;&gt;simultaneous landing of two boosters&lt;/a&gt; and being for a short moment really proud to be human.&lt;/p&gt;
&lt;h2 id=&#34;3---starship-and-dearmoon&#34;&gt;3 - Starship and #dearmoon&lt;/h2&gt;
&lt;p&gt;The idea of this vehicle was part of the SpaceX since the very beginning, but they needed to start being profitable first. The real Starship manufacturing and planning started with the &lt;a href=&#34;https://dearmoon.earth/&#34;&gt;#dearmoon project&lt;/a&gt; announcement on 17th of September 2018. Where Yusaku Maezawa, Japanese business owner and arts patron, sponsored part of the Starship development and bought the first commercial manned flight around the Moon.&lt;/p&gt;
&lt;p&gt;Since then SpaceX has been focusing on coming up with a design and mainly manufacturing process to build a factory line for these largest flown rockets. They are planned to be fully reusable, capable of orbital refuelling and being able to make a trip to Mars and back.&lt;/p&gt;
&lt;p&gt;Looking at the concept videos for this spacecraft and seeing how serious SpaceX is about the mission is inspiring.&lt;/p&gt;
&lt;hr&gt;
&lt;p&gt;Without a doubt, exploring our Solar system with manned missions is the thing that I&amp;rsquo;m most excited about. The only drawback is that as soon as a human lives and health is concerned, the speed of innovation slows down to a pace of severely drunk snail. The amount of certification and tests needed to use vehicle for transferring humans is unimaginable. That&amp;rsquo;s the reason why the Dragon 2 Crew capsule slips the delivery timelines so much. Compared to the intended missions of Starship, Dragon is very simple and small vehicle.&lt;/p&gt;
&lt;p&gt;For this reason, I don&amp;rsquo;t believe SpaceX is going to be able to send humans to Mars in the 20s. But fingers &lt;a href=&#34;http://clowder.net/hop/railroad/MeMa.htm&#34;&gt;crossed for the first launch window of 2030&lt;/a&gt;.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Opportunity cost</title>
      <link>https://blog.viktomas.com/posts/opportunity-cost/</link>
      <pubDate>Sun, 22 Mar 2020 17:20:00 +0100</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/opportunity-cost/</guid>
      <description>&lt;p&gt;Thanks to the virus the economy goes bananas. My initial instinct is to do nothing. I mean financially. Hold on to my savings and wait this situation out. And this initial reflex, hoarding savings, is what nudged me to write about a concept that is still quite foreign to me.&lt;/p&gt;
&lt;p&gt;I grew up in a lower middle class family. Both parents educated but not earning too much money. There was always a big emphasis on saving in my upbringing. Nobody in my vicinity was trying to use money to make more money. You earn money with hard work and you spend it on mortgage, car, food and other necessities.&lt;/p&gt;
&lt;p&gt;But there is a cost to gathering money on your savings account. And not an obvious one. The cost is called opportunity cost.&lt;/p&gt;
&lt;p&gt;You are making decisions every day, from trivial decisions like should I buy five or eight bananas to life altering like should I buy this house the other one. Sometimes you don&amp;rsquo;t even make the decision consciously like when you stay at home and read a book, you might not even thing about it as a decision but there are many alternatives, go and eat out, go for a workout and so on.&lt;/p&gt;
&lt;p&gt;Opportunity cost is the difference between the option you&amp;rsquo;ve chosen and the option you haven&amp;rsquo;t. The following examples will shine more light into what I mean.&lt;/p&gt;
&lt;h2 id=&#34;simple-savings&#34;&gt;Simple savings&lt;/h2&gt;
&lt;p&gt;So you&amp;rsquo;ve been saving for a year and was able to save $10,000. You haven&amp;rsquo;t thought about investing it and you keep the money safe in your savings account at 1.8%p.a.&lt;/p&gt;
&lt;p&gt;In a year you are going to earn $180 as an interest on your account. That&amp;rsquo;s the option you&amp;rsquo;ve chosen (whether consciously or unconsciously). Option A.&lt;/p&gt;
&lt;p&gt;Now alternative would be to put the savings in an indexed fund based on an index like S&amp;amp;P 500. This index grew in 2019 by 20% in value. If you put your $10,000 in this fund in January 2019, you could have potentially made roughly $2,000 on this investment.&lt;/p&gt;
&lt;p&gt;Now the cost of this missed opportunity in this example is $1,820 that you&amp;rsquo;ve paid but maybe didn&amp;rsquo;t even realize that.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;In this instance your safe bet paid off because the index dropped much more than that in the first quarter of 2020.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id=&#34;renovating-a-flat&#34;&gt;Renovating a flat&lt;/h2&gt;
&lt;p&gt;You bought a flat and it needs a renovation before you can find a tenant. If you&amp;rsquo;d let the tradesmen do it would cost you $20,000 just for the labour. This professional renovation would take four months.&lt;/p&gt;
&lt;p&gt;You decided to do this work yourself in your free time over next two years. You saved $20,000 right? Not so fast.&lt;/p&gt;
&lt;p&gt;If the self-made renovation takes two years, that&amp;rsquo;s twenty months that you could have been getting rent and you didn&amp;rsquo;t. So you saved $20.000 on the labour fees, but potentially lost 20 months of rent from a tenant. If the monthly income from rent is $600, you didn&amp;rsquo;t save $20,000 but $8.000 and you paid with 2 years of your free time.&lt;/p&gt;
&lt;h2 id=&#34;motivation-to-consider-the-cost&#34;&gt;Motivation to consider the cost&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s super easy to do nothing. And we might realize that there is a cost connected with doing nothing, but as long as we don&amp;rsquo;t have an exact number in front of our eyes, we don&amp;rsquo;t have the motivation start considering the opportunities.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s why I propose the following calculation to spark your and mine enthusiasm about doing something rather than nothing with our savings.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s assume option A being keeping your savings in a savings account which exactly covers inflation e.g. 1.5% (which is super generous for the majority of the savings accounts).&lt;/p&gt;
&lt;p&gt;For option B, let&amp;rsquo;s play it super safe and invest to government bonds at 5% yearly interest.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;interest&lt;/th&gt;
          &lt;th&gt;savings initially&lt;/th&gt;
          &lt;th&gt;savings after 10 years&lt;/th&gt;
          &lt;th&gt;savings after 20 years&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;1.5%&lt;/td&gt;
          &lt;td&gt;$10,000&lt;/td&gt;
          &lt;td&gt;$11,605.41&lt;/td&gt;
          &lt;td&gt;$13,468.55&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;5%&lt;/td&gt;
          &lt;td&gt;$10,000&lt;/td&gt;
          &lt;td&gt;$16,288.95&lt;/td&gt;
          &lt;td&gt;$26,532.98&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;Source: &lt;a href=&#34;https://www.thecalculatorsite.com/finance/calculators/compoundinterestcalculator.php&#34;&gt;Compound Interest Calculator&lt;/a&gt;&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;
&lt;p&gt;On this simple example is shown that the opportunity cost of keeping your ten grand in savings account as opposed to low risk investment is over $13,000 in twenty years, $653 a year, close to $2 a day difference. &lt;strong&gt;This difference only grows bigger if you increase your savings&lt;/strong&gt;. I hope that motivates you as much as it motivates me.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;Compound interval: yearly&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Remote</title>
      <link>https://blog.viktomas.com/posts/remote/</link>
      <pubDate>Sun, 15 Mar 2020 19:20:00 +0100</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/remote/</guid>
      <description>&lt;p&gt;Interesting times, interesting times. Let&amp;rsquo;s not wait till the government orders quarantine. If your work involves predominantly computer, you have to start working remotely. This is how you do it.&lt;/p&gt;
&lt;p&gt;Who am I to talk? I&amp;rsquo;m a software engineer at GitLab, the largest all remote company in the world. In my ten-year career I&amp;rsquo;ve worked in teams as small as two and as large as forty people. I&amp;rsquo;ve had all collocated team, I&amp;rsquo;ve worked with outsourced offshore team from China and now it&amp;rsquo;s all remote.&lt;/p&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/remote/homeoffice.jpg&#34;
    alt=&#34;Homeoffice - Ljubica Petković&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;Picture: &lt;strong&gt;Homeoffice&lt;/strong&gt; - Ljubica Petković&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not going to lie, this article is heavily inspired by GitLab blog article on the same topic (featured on Hacker News) &lt;a href=&#34;https://about.gitlab.com/blog/2020/03/06/resources-for-companies-embracing-remote-work/&#34;&gt;https://about.gitlab.com/blog/2020/03/06/resources-for-companies-embracing-remote-work/&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;remote-vs-co-located&#34;&gt;Remote vs. Co-located&lt;/h2&gt;
&lt;p&gt;First, there are different levels of remote work. Let&amp;rsquo;s look at examples ordered by the distance team members have from each other. I&amp;rsquo;m not considering company branches (e.g. Google in Mountain View vs Google in Sydney).&lt;/p&gt;
&lt;h3 id=&#34;classification&#34;&gt;Classification&lt;/h3&gt;
&lt;ol&gt;
&lt;li&gt;No work from home policy. Everyone is in the office&lt;/li&gt;
&lt;li&gt;Team member is sick and takes a home office&lt;/li&gt;
&lt;li&gt;One or more team members are working remotely full time&lt;/li&gt;
&lt;li&gt;Everyone works remotely (no two colleagues collocated), there is no central office&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;The key difference between the last two modes of remote is that the second last creates the &amp;ldquo;us vs. them&amp;rdquo; mentality. Information is often located at the main office and that&amp;rsquo;s where the career opportunities are as well. I&amp;rsquo;m going to be talking about the last mode of remote. It&amp;rsquo;s the most relevant for current world-wide quarantine.&lt;/p&gt;
&lt;p&gt;There are a few things that you usually do in the office that you won&amp;rsquo;t be able to do when working from home:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;tap your colleague on the shoulder and ask a question&lt;/li&gt;
&lt;li&gt;shout out a question and get immediate answer&lt;/li&gt;
&lt;li&gt;if you are a manager: control that your direct reports show up for 8 hours&lt;/li&gt;
&lt;li&gt;have a chat over a water cooler or lunch with your colleagues&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Only the last one example is (in my opinion) a downgrade from an office. None of the previous actions is necessary (and as we show even optimal) for knowledge workers to do their job.&lt;/p&gt;
&lt;p&gt;Communication is one of the most important parts of work and it&amp;rsquo;s format fundamentally changes when you start working remotely. One of the common misconceptions is to think that remote work is almost the same as office work with a bit more &amp;ldquo;skype&amp;rdquo; in it.&lt;/p&gt;
&lt;p&gt;When you are not collocated in the office you have a unique chance to make processes asynchronous.&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;In the office&lt;/th&gt;
          &lt;th&gt;Remote&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;Meeting to resolve a specific issue&lt;/td&gt;
          &lt;td&gt;Issue tracker issue with comments and suggestions&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Planning or status meetings&lt;/td&gt;
          &lt;td&gt;Video call with clear agenda written up in advance&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Asking colleague question about internal process&lt;/td&gt;
          &lt;td&gt;searching handbook/intranet for an answer&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;Water cooler conversation&lt;/td&gt;
          &lt;td&gt;Scheduled video call catchup&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;You are measured by the time you put in&lt;/td&gt;
          &lt;td&gt;You are measured by the results you provide&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id=&#34;drawbacks-of-remote-working&#34;&gt;Drawbacks of remote working&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s not all sunshine and rainbows. For a seasoned office worker there might be several unpleasant changes to the processes and in some cases even insurmountable difference of the environment.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s go from the mildest issues to the largest (at least from my perspective).&lt;/p&gt;
&lt;p&gt;The mildest issue with remote work is to have the discipline to work and not be distracted by social media, news, YouTube and like. This is larger issue for some. What helps me a lot is having a separate office in my flat that I use for work.&lt;/p&gt;
&lt;p&gt;Connected to the previous issue is work-life balance. It can be easier to stop thinking about work or stop doing work when you leave physical office as opposed to just closing your laptop in your living room. It&amp;rsquo;s important to set yourself &amp;ldquo;working hours&amp;rdquo; and not work during your free time. The important thing here is that the working hours don&amp;rsquo;t have to be anything like the standards nine-to-five. You can start your day early, then go to the gym just before lunch, have a long lunch with a colleague, run your errands in early afternoon when the shops and government offices are empty and then start working again in the evening. Whatever works for you is fine.&lt;/p&gt;
&lt;p&gt;The change in thinking and processes is a massive issue with remote work. If the process is not clear, you can just sit behind your computer at home and not know what to do. We&amp;rsquo;ll talk about documentation in more detail in the How to section.&lt;/p&gt;
&lt;p&gt;The main and largest issue with remote work is the lack of human contact. This is something I still struggle with.&lt;/p&gt;
&lt;h2 id=&#34;benefits-of-remote-working&#34;&gt;Benefits of remote working&lt;/h2&gt;
&lt;h3 id=&#34;from-the-employee-perspective&#34;&gt;From the employee perspective&lt;/h3&gt;
&lt;p&gt;The freedom to live where you want is the largest benefit. I always tried to live next to my office to reduce commute but now I actually live in the same building as my office. And that can be in the country if I decide. So far I can live in my home town working for one of the best companies in the world. When I travel in my camper van, I can still work.&lt;/p&gt;
&lt;p&gt;You can pick remote company that aligns the best with your values, skill set and ambitions.&lt;/p&gt;
&lt;p&gt;Depending on when you live right now you might save a significant portion of your day on commuting.&lt;/p&gt;
&lt;h3 id=&#34;from-the-employer-perspective&#34;&gt;From the employer perspective&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;savings for office space can be invested in sponsoring your employee&amp;rsquo;s home office&lt;/li&gt;
&lt;li&gt;you can find talent everywhere and cheaper because your employees don&amp;rsquo;t have to pay rent for living in the centre of a larger city&lt;/li&gt;
&lt;li&gt;your employees are going to be more efficient when they can work on their own terms&lt;/li&gt;
&lt;li&gt;thanks to more extensive documentation there is not that much know-how leaving the company with an employee&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;how-to&#34;&gt;How To&lt;/h2&gt;
&lt;p&gt;So after reading the previous sections you are thinking: That sounds great. And it&amp;rsquo;s not like I have any other option anyway.&lt;/p&gt;
&lt;h3 id=&#34;document-your-work&#34;&gt;Document your work&lt;/h3&gt;
&lt;p&gt;The most important thing is documentation. You work on an issue? Document what you are planning to do, ask for comments and then document what you are doing. That way you don&amp;rsquo;t have to give in person/video updates, everyone can read in their own time what&amp;rsquo;s happening. We use GitLab issues for that, but any other issue tracker like Trello, Jira or GitHub should be fine. GitLab issues is great for software companies because it&amp;rsquo;s so close to the source code.&lt;/p&gt;
&lt;h3 id=&#34;document-your-processes&#34;&gt;Document your processes&lt;/h3&gt;
&lt;p&gt;Documenting processes showed to be one of the most valuable thing for GitLab as it scaled from a dozen or so employees to twelve hundred.&lt;/p&gt;
&lt;p&gt;We use &lt;a href=&#34;https://docs.gitlab.com/ee/user/project/pages/&#34;&gt;GitLab Pages&lt;/a&gt; f. It&amp;rsquo;s got seamless integration with the git repository where our whole handbook is stored:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;handbook - &lt;a href=&#34;https://about.gitlab.com/handbook/&#34;&gt;https://about.gitlab.com/handbook/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;the git repo - &lt;a href=&#34;https://gitlab.com/gitlab-com/www-gitlab-com/-/tree/master&#34;&gt;https://gitlab.com/gitlab-com/www-gitlab-com/-/tree/master&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;meeting-as-a-last-resort&#34;&gt;Meeting as a last resort&lt;/h3&gt;
&lt;p&gt;Surprising amount of discussion and decisions can be done asynchronously through discussion on issues. When you do have to organize a meeting. Have a clear agenda before. At GitLab we use Google Docs because it&amp;rsquo;s so easy to cooperate on them real-time during the meeting.&lt;/p&gt;
&lt;p&gt;For video conferencing we use &lt;a href=&#34;https://zoom.us/&#34;&gt;Zoom.us&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id=&#34;stay-focused&#34;&gt;Stay focused&lt;/h3&gt;
&lt;p&gt;Procrastination is a much larger issue when you don&amp;rsquo;t have people around. It would feel weird to open YouTube at work, but at home it can&amp;rsquo;t hurt to watch that new video can it?&lt;/p&gt;
&lt;p&gt;I strongly recommend using something like a &lt;a href=&#34;https://en.wikipedia.org/wiki/Pomodoro_Technique&#34;&gt;Pomodoro timer&lt;/a&gt;. I&amp;rsquo;m dividing my day into twenty-five minute units and if I feel that I need to do something other than work (watch a video, read news, make a coffee) I do it outside of these blocks. Example. I read through my emails the first 25 minute block, then I make myself a coffee and read a bit of news, then I work 3 blocks in a row before taking another break. I do 10 - 14 of these blocks a day depending on meetings (which I don&amp;rsquo;t count as units), how much fun the task is and how urgent it is.&lt;/p&gt;
&lt;h3 id=&#34;organize-your-own-space&#34;&gt;Organize your own space&lt;/h3&gt;
&lt;p&gt;If possible you should make sure that you&amp;rsquo;ve got your own room when no one else will interrupt or distract you from work.&lt;/p&gt;
&lt;p&gt;If that is not possible, you have to at least take some quite corner in your flat and put on headphones.&lt;/p&gt;
&lt;p&gt;Either way you should set boundaries with the other members of your household to make sure you they know not to interrupt you when you&amp;rsquo;re working. Otherwise your productivity flies out of the window.&lt;/p&gt;
&lt;p&gt;This was my introduction. Another great resources are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=GD9M33_z-dM&#34;&gt;Sid (CEO of GitLab) with Savannah Peterson talking about remote&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;allremote.info&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Hashtag: Vanlife</title>
      <link>https://blog.viktomas.com/posts/van-life/</link>
      <pubDate>Sun, 08 Mar 2020 09:31:00 +0100</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/van-life/</guid>
      <description>&lt;p&gt;Last Summer, after years of watching YouTube videos about tiny homes and van conversions, I made the decision. I&amp;rsquo;m going to buy myself a van. Convert it to a camper van and potentially even move into it.&lt;/p&gt;
&lt;h2 id=&#34;purchase&#34;&gt;Purchase&lt;/h2&gt;
&lt;p&gt;My requirements were quite simple. It needed to be L2H2 (classification of length and height). It had to be around 8K USD so that I&amp;rsquo;m not too afraid to drill and cut holes in it. Good condition and low mileage.&lt;/p&gt;
&lt;p&gt;At the start of August I was a proud owner of Citroen Jumper 2012 L2H2. Later on I found some added advantages of this car that I had no idea about when I made the purchase:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Citroen, Peugeot and Fiat cooperated on building this van and all three companies are selling it under different brand. That means abundance of spare parts on the market. And a lot of conversion videos are using one of these models.&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s (on of) the widest van on the market. The interior is 185 cm wide which means I could build an aft crosswise bed saving a lot of space&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/van-life/new-van.jpg&#34;
    alt=&#34;new-van&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;h2 id=&#34;build&#34;&gt;Build&lt;/h2&gt;
&lt;p&gt;This is extremely broad topic and I might go into technical details in another post.&lt;/p&gt;
&lt;p&gt;The build took me roughly a month and a half of almost every hour of spare time I had. That means month and a half of doing my day job till early afternoon and rest of the day spent working on the van. Falling exhausted into the bed and then starting over again the next day. I had amazing support from my friends, namely Vejvis, Matej, Seth and others. Without them the build would take at least twice as long. I pretty much hadn&amp;rsquo;t used a drill before I started the conversion, towards the end I had a basic tool set and was able to do tasks like measure and design my metal bed frame. Do carpentry and insulation. Cut a massive hole in the roof of my van. And much more.&lt;/p&gt;
&lt;p&gt;Those 45 days were the maximum amount of time I could go at this pace. Towards the end I wanted to pour petrol on the van and set it on fire. At least I have a baseline for how long it is possible for me to keep high focus on a single project.&lt;/p&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/van-life/stripped.jpg&#34;
    alt=&#34;stripped&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;h2 id=&#34;trips&#34;&gt;Trips&lt;/h2&gt;
&lt;p&gt;In October my girlfriend and I went on a two-week trip around Balkans, and we found out the reality of #vanlife for myself. Some things are hard to appreciate just from the YouTube videos and blog. Having a base and shelter everywhere you go feels amazing. When you&amp;rsquo;ve got full tanks, full jerry cans of water and stocked pantry, you feel like sky is the limit of where you can go and what you can do there.&lt;/p&gt;
&lt;p&gt;But there is a massive dark side of living in a van that lot of people are alluding to in their videos and articles but it&amp;rsquo;s impossible to appreciate till you try it for yourself. The main things are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;the privacy and hustle of finding nice spots to camp for the night&lt;/li&gt;
&lt;li&gt;taking the poo shovel and going to poo in the morning, or sometimes looking for open café/public toilet if you are in the civilization&lt;/li&gt;
&lt;li&gt;the van is a tiny space if you can&amp;rsquo;t go outside (weather, long nights in winter)&lt;/li&gt;
&lt;li&gt;there is very limited supply of water and you can&amp;rsquo;t shower and you can&amp;rsquo;t wash as often as you are used to from your apartment&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For all the reasons above I realized that even though being in the van is amazing at times, it is equally amazing to return to the comfort of your apartment. Full time #vanlife isn&amp;rsquo;t for me. At least not till I come up with a smart way to build a shower a toilet into the van. My takeaway is that trips up to a month long are a great idea, everything over that would probably make me miss home too much.&lt;/p&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/van-life/mountains.jpg&#34;
    alt=&#34;mountains&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img
    src=&#34;https://blog.viktomas.com/van-life/sea.jpg&#34;
    alt=&#34;sea&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/p&gt;
&lt;h2 id=&#34;future&#34;&gt;Future&lt;/h2&gt;
&lt;p&gt;So far we&amp;rsquo;ve done a two-week trip in Balkans and week of winter camping in Italian Alps. Autumn ✓, Winter ✓. Next trip for the van is April in Southern Europe.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Iteration</title>
      <link>https://blog.viktomas.com/posts/iteration/</link>
      <pubDate>Sat, 29 Feb 2020 11:15:00 +0100</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/iteration/</guid>
      <description>&lt;p&gt;Today I&amp;rsquo;m going to be writing about one concept that is as common in software development as it is counterintuitive. With the added benefit that it translates well into every day life.&lt;/p&gt;
&lt;p&gt;Imagine you are about to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;pick up painting as a new hobby&lt;/li&gt;
&lt;li&gt;change career from salesperson to a carpenter&lt;/li&gt;
&lt;li&gt;start going to the gym&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If you are anything like me, you would do actions like:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;buy yourself expensive art equipment and text books&lt;/li&gt;
&lt;li&gt;quit your job and get a workshop&lt;/li&gt;
&lt;li&gt;sign up for the gym and get new gym gear&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;If these seem like a reasonable steps, you are in for a treat.&lt;/p&gt;
&lt;h2 id=&#34;history-of-software-development&#34;&gt;History of software development&lt;/h2&gt;
&lt;p&gt;Back in the day when you wanted to create a big system (think internet banking), you&amp;rsquo;d plan everything in advance. You&amp;rsquo;d document all the requirements from users (send a payment, log in), you&amp;rsquo;d create tasks for software engineers, testers, designers and so on. And then you would close teams of people into a building for years and let them build the system. After a few years you would usually end up with a system having the following characteristics:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;it doesn&amp;rsquo;t have a lot of functionality users want&lt;/li&gt;
&lt;li&gt;it has a lot of functionality no one needs&lt;/li&gt;
&lt;li&gt;it was more expensive to build than anticipated&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;And that would be pretty much the best case scenario. Lot of these projects didn&amp;rsquo;t get finished at all &lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. This a classic example of a Waterfall Model &lt;sup id=&#34;fnref:2&#34;&gt;&lt;a href=&#34;#fn:2&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;2&lt;/a&gt;&lt;/sup&gt;. The decision-making is based on a wrong assumption that you can know in advance what you want to build/do. You probably noticed that the description of the process is parallel to the actions that I suggested at the beginning. They also assume that you know best what to do upfront.&lt;/p&gt;
&lt;h2 id=&#34;nice-to-meet-you-iteration&#34;&gt;Nice to meet you iteration&lt;/h2&gt;
&lt;p&gt;There&amp;rsquo;s been too many failed software waterfalls and in the 1990s there&amp;rsquo;s been a shift in thinking about software movement called Agile Software Development &lt;sup id=&#34;fnref:3&#34;&gt;&lt;a href=&#34;#fn:3&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;3&lt;/a&gt;&lt;/sup&gt;. This movement started process that was closely communicating with the customer and delivering small improvements on the software often.&lt;/p&gt;
&lt;p&gt;Imagine that you are going to a customer on Monday, asking: &amp;ldquo;How are you happy with the current version of your internet shop?&amp;rdquo; The customer would say: &amp;ldquo;It&amp;rsquo;s OK but I would like the users to be able to buy a new T-Shirt immediately.&amp;rdquo; The customer tells you about the whole workflow they&amp;rsquo;d prepared for it but you explain to them that the only thing you can do in a week is a &amp;ldquo;Buy now&amp;rdquo; button, that will a) add the goods to the shopping cart and b) goes immediately to the check out. It&amp;rsquo;s much more simple. The whole work took 3 hours. Users can use it by Friday and in the end you&amp;rsquo;ll find out that the users and the customer are happy with this small iteration. No more work is necessary. Customer saved money, you saved time and users got the functionality they needed much earlier.&lt;/p&gt;
&lt;p&gt;OK, but how does this translate to a world out of software engineering? Well, I&amp;rsquo;m glad you asked.&lt;/p&gt;
&lt;h2 id=&#34;iteration-in-private-life&#34;&gt;Iteration in private life&lt;/h2&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;What you want to do&lt;/th&gt;
          &lt;th&gt;All at once&lt;/th&gt;
          &lt;th&gt;Iteration&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;pick up painting as a new hobby&lt;/td&gt;
          &lt;td&gt;buy yourself an expensive art equipment and text books&lt;/td&gt;
          &lt;td&gt;get a pencil No. 2 and a notebook (together for $2) and do a few free online tutorials before buying another equipment&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;change career from salesperson to a carpenter&lt;/td&gt;
          &lt;td&gt;quit your job and get a workshop&lt;/td&gt;
          &lt;td&gt;build a one small piece of furniture for your friend in your garage&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;start going to the gym&lt;/td&gt;
          &lt;td&gt;sign up for the gym and get new gym gear&lt;/td&gt;
          &lt;td&gt;do 2x20 minutes of exercise at home with your own weight&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;You can see how the iteration requires much less investment and allows you to act much sooner? What if you find out you don&amp;rsquo;t like painting? What if you hate working with wood when it&amp;rsquo;s an order from a customer as opposed to a fun project with no pressure? Or you&amp;rsquo;ll hate gym because of the vibe you get there?&lt;/p&gt;
&lt;p&gt;All these things can be avoided or their impact minimized if you start with a tiny &amp;ldquo;trial&amp;rdquo; first.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Iteration is all about delivering the smallest possible value as soon as possible&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id=&#34;two-way-door-decision&#34;&gt;Two way door decision&lt;/h2&gt;
&lt;p&gt;What is better than a tiny change that required tiny amount of time/resources? It&amp;rsquo;s a tiny change that can be easily cancelled, reverted or discarded. This makes the decision or change even easier to make because there is close to no repercussion for doing so. These decisions are called &lt;em&gt;Two way door decisions&lt;/em&gt;&lt;sup id=&#34;fnref:4&#34;&gt;&lt;a href=&#34;#fn:4&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;4&lt;/a&gt;&lt;/sup&gt; and example of one is to decide you are going to pick up painting, not telling anyone and buying only pencil and cheap notebook. What is the cost of cancelling such a decision? Only your time and $2 for the equipment.&lt;/p&gt;
&lt;p&gt;One-way door decision on the other hand might be changing your cell-phone plan and operator. The amount of hustle is much larger but on top of that you might have to sign up for a year or two and cancelling your decision might cost you a massive fine.&lt;/p&gt;
&lt;p&gt;I came up with the idea for this article because I just used it. I always loved teaching and explaining technical stuff to people and I&amp;rsquo;d been toying with an idea of becoming a teacher for quite some time now. Few months back I decided I want to get a job as a part-time teacher on my alma mater secondary school specialized in computer science. But couple weeks ago I&amp;rsquo;ve realized I didn&amp;rsquo;t take a single step towards that resolution.&lt;/p&gt;
&lt;p&gt;After a bit of introspection I realized that I was doing a waterfall, one-way door decision. I would have to spend tremendous amount of effort to get certified to teach in a government institution and I would have to sign up to a year of regular classes at the very least. When I looked at it this way my love for teaching was dwindling.&lt;/p&gt;
&lt;p&gt;So how to make this a small iteration, two-way door decision? I&amp;rsquo;m going to start with developing an afternoon course for software engineers in technology that I know well. The cost of doing this is only the time it will take me to prepare the course. There is no equipment or certification necessary. As soon as I give the lecture, there is nothing preventing me from not doing it ever again.&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/List_of_failed_and_overbudget_custom_software_projects&#34;&gt;Wikipedia: Failed software projects&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:2&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Waterfall_model&#34;&gt;Wikipedia: Waterfall software development model&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:2&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:3&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Agile_software_development&#34;&gt;Wikipedia: Agile software development&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:3&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li id=&#34;fn:4&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://about.gitlab.com/handbook/values/#make-two-way-door-decisions&#34;&gt;GitLab Handbook: Two way door decisions&lt;/a&gt;&amp;#160;&lt;a href=&#34;#fnref:4&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Signal - the secure messenger</title>
      <link>https://blog.viktomas.com/posts/signal/</link>
      <pubDate>Sun, 23 Feb 2020 10:46:00 +0100</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/signal/</guid>
      <description>&lt;p&gt;After writing about &lt;a href=&#34;./privacy.md&#34;&gt;privacy&lt;/a&gt; and &lt;a href=&#34;security-is-like-ogres.md&#34;&gt;security&lt;/a&gt; in general, this is the first time I&amp;rsquo;m going to be talking about a specific solution. Full disclosure: I&amp;rsquo;m not a security professional, more of an enthusiast, so please take the advice with a grain of salt.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve been disconcerted with the messaging situation for a few years now. I&amp;rsquo;ve been super excited about using WhatsApp back in the days when it &lt;a href=&#34;https://www.investopedia.com/articles/investing/032515/whatsapp-best-facebook-purchase-ever.asp&#34;&gt;was still an independent company&lt;/a&gt;. Now it was just another app that gets my data and uses it for advertisement. Admittedly it&amp;rsquo;s still way better than using Facebook Messenger. That&amp;rsquo;s because WhatsApp only uses my metadata (social graph, contacts, who and when am I talking to) whilst Facebook Messenger parses the whole content of my message (and possibly my phone calls, who knows) and uses them to create my profile to sell me better to advertisers and of course provide it to US authorities (hopefully they are not interested in my shopping lists but still it&amp;rsquo;s non of their beeswax).&lt;/p&gt;
&lt;p&gt;So the main reasons why I cringe every time I submit the message through Messenger, WhatsApp or Gmail are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I provide Facebook or Google with more of my private data&lt;/li&gt;
&lt;li&gt;I support their dodgy behaviour&lt;/li&gt;
&lt;li&gt;I&amp;rsquo;m making it harder for private and secure principles to spread&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;criteria-for-choosing-the-new-chat-app&#34;&gt;Criteria for choosing the new chat app&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve been investigating possible solutions/improvements for the last few months and I knew that once I&amp;rsquo;ll find a good alternative I&amp;rsquo;ll have to go through the hustle of convincing my core social network to install it and use it when talking with me. That means the solution had to have the following features:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Simplicity: my mum and grandpa could use it&lt;/li&gt;
&lt;li&gt;Feature parity: the core features (messages, emojis, video calls, file and location sharing) had to be present and seamless to use&lt;/li&gt;
&lt;li&gt;Privacy &amp;amp; Security: Leading the space in E2E encryption and in general collecting no/minimal data about me&lt;/li&gt;
&lt;li&gt;Independent: Doesn&amp;rsquo;t belong to a company that already gathers huge amount of data about users&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;the-2nd-best-option---matrixriot&#34;&gt;The 2nd best option - Matrix/Riot&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve been using Matrix for a while. I&amp;rsquo;ve even been on a call with its founder Matthew once. The great advantage of Matrix protocol compared to the winner (Signal) is that it is decentralized. That means it is supported and even encouraged for people to write different servers and clients to be used for sending messages in the Matrix network. This makes it amazing for technical folks as proved by &lt;a href=&#34;https://matrix.org/blog/2019/12/19/welcoming-mozilla-to-matrix&#34;&gt;Mozilla using Matrix for the company&amp;rsquo;s communication&lt;/a&gt;. I would use it as a slack alternative in a team.&lt;/p&gt;
&lt;p&gt;Making the protocol open-source and the Matrix network decentralized has a massive drawback as well. It makes changes to it slower as &lt;a href=&#34;https://matrix.org/blog/2020/01/02/on-privacy-versus-freedom&#34;&gt;Matthew admitted around Christmas&lt;/a&gt;. It means that the team needs to focus on supporting the community and backwards compatibility as well as developing new features. When you have centralized service, you can make changes to the whole network, when it&amp;rsquo;s decentralized, you need to take into account all the servers operated by other people.&lt;/p&gt;
&lt;p&gt;Thanks to this the Riot app (the main Matrix chat app) doesn&amp;rsquo;t have all the bells and whistles that the popular messengers do have. As a result even though I like Matrix&amp;rsquo;s mission as much as Signal&amp;rsquo;s, I had to discard it as a viable option because it&amp;rsquo;s not satisfying the Simplicity and the Feature parity requirements.&lt;/p&gt;
&lt;h2 id=&#34;signal---the-clear-winner&#34;&gt;Signal - the clear winner&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://signal.org/&#34;&gt;Signal&lt;/a&gt; has been created with only one goal: Make the communication more private. It&amp;rsquo;s founder &lt;a href=&#34;https://en.wikipedia.org/wiki/Moxie_Marlinspike&#34;&gt;Moxie Marlinspike&lt;/a&gt; open-sourced all the encryption algorithms and protocols. So for example WhatsApp is using one of these protocols (Signal protocol) for its E2E encryption.&lt;/p&gt;
&lt;p&gt;Signal is pushing the envelope when it comes to &lt;a href=&#34;https://signal.org/blog/&#34;&gt;forgetting information about its users&lt;/a&gt;. And as far as my technical knowledge goes I choose to trust Signal that they are doing whatever they can to stay the most private and secure messenger out there.&lt;/p&gt;
&lt;p&gt;Signal ticks all the boxes in my requirements. It has all the features I&amp;rsquo;d expect from a chat application. It&amp;rsquo;s one of the most private and secure apps you can find (if not the most private). Signal.org is independent not-for-profit organization and even though it resides in US, it doesn&amp;rsquo;t gather any information about you so even if the intelligence agencies wanted some of your data, they won&amp;rsquo;t get it.&lt;/p&gt;
&lt;p&gt;But the most impressive and important characteristic of Signal app is its &lt;strong&gt;simplicity&lt;/strong&gt;. I can install it on my mum&amp;rsquo;s or grandpa&amp;rsquo;s phone with clear conscience that they will be able to use it.&lt;/p&gt;
&lt;h2 id=&#34;decision-has-been-made-what-now&#34;&gt;Decision has been made, what now?&lt;/h2&gt;
&lt;p&gt;Now I am &amp;ldquo;that guy&amp;rdquo;. I&amp;rsquo;m slowly convincing all my friends to start using Signal so that I don&amp;rsquo;t have to give Facebook or Google any more information about me. It&amp;rsquo;s hard to explain the importance of Privacy and Security to them but writing articles like these is helping me sort out my thoughts on the topic.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not going to stop using WhatsApp or FB Messenger any time soon but each new person using Signal is a fraction of information that is now just between us, leaving Facebook and Google out of it. If Signal keeps up this good work, I can see a bright future.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Amor Towles - Rules of Civility</title>
      <link>https://blog.viktomas.com/books/towles-amor--rules-of-civility/</link>
      <pubDate>Sun, 23 Feb 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/towles-amor--rules-of-civility/</guid>
      <description>&lt;p&gt;Rules of Civility made me love the idea New York even though I&amp;rsquo;ve never been. Following the story of 22yo Katherine Kontent I&amp;rsquo;ve found her the most relatable female character ever (maybe because the author is a guy?). And her dilemma when she had to often decide between love, friendship and career was unbelievably relatable to me.&lt;/p&gt;
&lt;p&gt;The story in this book is a story of life choices and how they can change your life for good or bad in an instant. It&amp;rsquo;s capturing the essence of one&amp;rsquo;s twenties: a lot of friends, a lot of choices made, some good some bad. But don&amp;rsquo;t be afraid, even though this is not a cookie cutter happy, upbeat story, you won&amp;rsquo;t fall into depression after reading it.&lt;/p&gt;
&lt;p&gt;This novel has been great for my vocabulary too. Even though there was a tremendous amount of new words I could almost always guess their meaning in the context, saving me the round trip to the dictionary.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Meditation, introduction</title>
      <link>https://blog.viktomas.com/posts/meditation-introduction/</link>
      <pubDate>Sun, 16 Feb 2020 10:37:43 +0100</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/meditation-introduction/</guid>
      <description>&lt;p&gt;This post is an introduction to meditation. If you are meditating regularly, you can skip right over it.&lt;/p&gt;
&lt;h2 id=&#34;what-i-mean-by-meditation&#34;&gt;What I mean by meditation?&lt;/h2&gt;
&lt;p&gt;When I refer to meditation, I mean mindfulness meditation. That means paying close attention to what is happening in your own mind and consciously trying not to change or force anything. The main goal (at least for me) is to understand better what my own mind is and how it operates.&lt;/p&gt;
&lt;p&gt;When I&amp;rsquo;m talking about meditation I&amp;rsquo;m not talking about religion. I&amp;rsquo;m also not trying to make you believe in some supernatural phenomena. So even though I found certain spiritual concepts from Buddhism useful, I&amp;rsquo;m going to leave that topic out completely since it&amp;rsquo;s not necessary and it too often triggers &amp;ldquo;bullshit filters&amp;rdquo; and makes people zone out.&lt;/p&gt;
&lt;h2 id=&#34;why-am-i-doing-meditation&#34;&gt;Why am I doing meditation?&lt;/h2&gt;
&lt;p&gt;I had actually quite unusual reason to start meditating. I was doing online course on dating. James Marshall&amp;rsquo;s &lt;a href=&#34;https://vip.thenaturallifestyles.com/five-principles-secret&#34;&gt;5 principles of natural seduction&lt;/a&gt;&lt;a href=&#34;#footnotes&#34;&gt;1&lt;/a&gt;. And the first principle was &amp;ldquo;Awareness&amp;rdquo; with an introduction to meditation and mindfulness concepts. It was the single most valuable thing that researching and learning dating brought me.&lt;/p&gt;
&lt;p&gt;Now I&amp;rsquo;m no longer focusing on meditation as a means to be able to better talk to strangers. Nowadays I&amp;rsquo;ve got two reasons I keep meditating.&lt;/p&gt;
&lt;p&gt;The first one being the more immediate observable benefits. I&amp;rsquo;m no longer as affected/controlled by my emotions as I used to. When I get swept away with anger, anxiety or any other negative emotion, I can sometimes realize that it is just an emotion and I have a choice whether to keep feeding it and focusing on it or let it go. I can earlier realize that something is not making me happy. I also spend less time lost in thought oblivious to my surrounding. All of these increase greatly the quality of my life and happiness. Of course, I&amp;rsquo;m not a saint who never gets angry or depressed, these emotions are just not as strong as they used to.&lt;/p&gt;
&lt;p&gt;The second reason I keep meditating is that I increasingly realize that I know nothing about the inner workings of my own mind. By quiet introspection I&amp;rsquo;m trying to find answers to questions like: What is a thought? What is vision and how is it different from hearing? If you haven&amp;rsquo;t spent some time sitting quietly and observing the mess that we all have in our heads, this is bound to sound willy-nilly esoteric and I&amp;rsquo;m therefore going to stop right here.&lt;/p&gt;
&lt;h2 id=&#34;how-do-i-do-meditation&#34;&gt;How do I do meditation?&lt;/h2&gt;
&lt;p&gt;The process and purpose of meditation sound simple: &lt;strong&gt;Sit down with your back upright and observe what is happening in your mind&lt;/strong&gt;. If it only was this simple in practice. I&amp;rsquo;m trying to do exactly that but there is a plethora of little tricks and tips that are very useful to support the main objective. For example, I prefer to close my eyes even though I&amp;rsquo;m sometimes meditating with eyes open. When my mind is all over the place, I focus solely on my breath.&lt;/p&gt;
&lt;p&gt;What I find indispensable are meditation courses and guided meditation and nowadays around 20% of my meditation time are guided meditations. I can, with clear heart, recommend the following two courses: &lt;a href=&#34;https://www.headspace.com/&#34;&gt;Headspace&lt;/a&gt; which I found excellent in the beginning. And &lt;a href=&#34;https://wakingup.com/&#34;&gt;Waking Up&lt;/a&gt; which provides much more in depth explanation of the concepts and I use it till this day.&lt;/p&gt;
&lt;p&gt;And how long do I meditate? I&amp;rsquo;m striving for an hour a day but I can observe positive results even when I reduce this time to twenty minutes a day. Majority of the meditation teachers are saying that ten minutes a day is enough to observe positive benefits, but twenty seems to be the minimum amount of time for me.&lt;/p&gt;
&lt;h2 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h2&gt;
&lt;p&gt;People sometimes compare meditation to working out. Working out makes your body healthier and meditation makes your mind healthier. This metaphor goes a long way:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;at the beginning, you don&amp;rsquo;t want to do it, it&amp;rsquo;s painful&lt;/li&gt;
&lt;li&gt;and even when you do it for months, there are times when you don&amp;rsquo;t want to start&lt;/li&gt;
&lt;li&gt;you don&amp;rsquo;t observe the benefits till you do it for a longer (month+) period of time&lt;/li&gt;
&lt;li&gt;it allows you to experience world differently
&lt;ul&gt;
&lt;li&gt;you can hike up a hill and take the view&lt;/li&gt;
&lt;li&gt;you can listen to something that would usually insult your ego and not get angry or reactive&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;the benefits go away as you stop&lt;/li&gt;
&lt;li&gt;the experience is not transferable - try to explain to someone the feeling you get when you finish workout/run/hike/climb&lt;/li&gt;
&lt;li&gt;doing it regularly is the only way to benefit from it (one workout in a month is probably worse than none, same with meditation)&lt;/li&gt;
&lt;li&gt;creating a regular time in schedule helps to keep it up&lt;/li&gt;
&lt;li&gt;&lt;em&gt;and so on…&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;footnotes&#34;&gt;Footnotes&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;[1] This is actually the only course that I would recommend to anyone, because it doesn&amp;rsquo;t treat women and dating as a game that you can either win or lose.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>David Spiegelhalter - The Art of Statistics: How to Learn from Data</title>
      <link>https://blog.viktomas.com/books/spiegelhalter-david--the-art-of-statistics/</link>
      <pubDate>Wed, 12 Feb 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/spiegelhalter-david--the-art-of-statistics/</guid>
      <description>&lt;p&gt;This book is something. A chapter in I went to a nearby office supplies store and I bought notebook to make notes. The first few chapters I felt like statistician. Sir David Spiegelhalter (yeah, you can get knighted for statistics) explained the basics of statistics really clearly and it gave me hope that even I could get statistically enlightened even though I always struggled with the concepts. This was the 5* part.&lt;/p&gt;
&lt;p&gt;Then past the regression modelling the book transformed into hard to understand mumbo-jumbo and I was able to get to the closing chapters just by the unprecedented power of will. This was the &amp;ldquo;Screw this, I&amp;rsquo;m going to quit&amp;rdquo; 2* part&lt;/p&gt;
&lt;p&gt;The last 3 chapters were again written for humans with some good takeaways, overall 4* mainly because David is a Knight.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Security is like ogres</title>
      <link>https://blog.viktomas.com/posts/security-is-like-ogres/</link>
      <pubDate>Sat, 08 Feb 2020 09:17:48 +0100</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/security-is-like-ogres/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve just seen security report in the news about &lt;a href=&#34;https://insinuator.net/2020/02/critical-bluetooth-vulnerability-in-android-cve-2020-0022/&#34;&gt;a critical Bluetooth Vulnerability on Android devices&lt;/a&gt;. The report says that the attacker was able to run arbitrary code on Android 8 and 9 devices. Just by being within the Bluetooth range. That got me thinking. How safe can I be from breaches of my privacy/security. Ever. No matter how much effort I would spend on keeping my devices and accounts secured.&lt;/p&gt;
&lt;p&gt;There is going to be kind of onion-layered model to the security I&amp;rsquo;ve got in mind. The title of this article is referring to the famous line from Shrek, (Ogres are like an onion). The metaphor will take us a long way. Size of each layer represents three things: the &lt;strong&gt;amount of our private data&lt;/strong&gt; that leaks, the &lt;strong&gt;probability&lt;/strong&gt; that it leaks and &lt;strong&gt;how ok we are&lt;/strong&gt; with leaking (e.g the onion skin - large amount of data about us leaks, it&amp;rsquo;s happening as we speak, and we are mostly ok with that). The closer to the core we&amp;rsquo;ll get the more important the information is to us and the more close to the heart we&amp;rsquo;d like to keep it.&lt;/p&gt;
&lt;h2 id=&#34;the-skin&#34;&gt;The Skin&lt;/h2&gt;
&lt;p&gt;The skin is the membrane that protects the onion. It is the largest surface area and by definition it&amp;rsquo;s exposed to the outer world. In our digital life, skin are the services that we use every day - social media, email, chat applications. We share information with those services (most importantly information about our behaviour).&lt;/p&gt;
&lt;p&gt;The size of this layer means that the amount of data that leaks is massive. We are almost willingly sharing our location, behaviour, habits and detailed personal information (are we single, how much do we earn..) (we don&amp;rsquo;t share this information directly, but our behaviour falls into certain categories) with thousands of companies, and they use that data for advertising.&lt;/p&gt;
&lt;p&gt;The probability that this is happening is ~1. It&amp;rsquo;s happening as we speak.&lt;/p&gt;
&lt;p&gt;The only thing we can do about this is to choose the services we use and be more careful about the data we provide them with. This is no easy, black &amp;amp; white, problem with easy solution like: install XYZ and live happily ever after. Google provides the best search results, all your friends are on Facebook and that Insta feed is so nice. There are privacy oriented alternatives at &lt;a href=&#34;https://www.privacytools.io/&#34;&gt;privacytools.io&lt;/a&gt; but using them usually comes at the cost of &amp;ldquo;using something different than the majority of the population&amp;rdquo;&lt;/p&gt;
&lt;h2 id=&#34;the-inner-layers&#34;&gt;The inner layers&lt;/h2&gt;
&lt;p&gt;The inner layers are the part where you can make the most difference. They are not exposed as the onion skin, they are juicier and you wouldn&amp;rsquo;t be ok with that information falling into someone&amp;rsquo;s hands. This includes your private emails, messages and cloud files. We are no longer talking about behaviour (e.g. google knowing that you like to shop on eBay for things costing $100 each month). This is more about the specifics. This is some particular person knowing that one of those eBay items was a big black dildo.&lt;/p&gt;
&lt;p&gt;The probability of the inner layers being exposed is not too high. And you can make it tiny by using the best security practices like password manager setting different password for each site. Use Two-Factor Authentication for you most important services. Use single sing on with Google or other provider and so on. I&amp;rsquo;ll be going into details of these in future articles but for now simply Googling &amp;ldquo;Personal cyber security&amp;rdquo; will find satisfying results.&lt;/p&gt;
&lt;h2 id=&#34;the-core&#34;&gt;The core&lt;/h2&gt;
&lt;p&gt;This is where the juiciest stuff it&amp;rsquo;s your password manager itself. It&amp;rsquo;s your online banking. It&amp;rsquo;s all the files stored on your encrypted hard drive. You can tell it&amp;rsquo;s not too much data compared to the amount of your Instagram pictures or instant messaging with your closest friends.&lt;/p&gt;
&lt;p&gt;You would certainly not expect this data to leak ever and luckily the chance of that happening is very low. The things responsible for keeping this layer so hidden are the core technologies of the internet, SSL, encryption of all kind and security of your operating system. These things are used by all the people (exaggeration) and so their security is extremely tight. That being said, breaches like the one mentioned in the security report mentioned at the begging of this post still happen.&lt;/p&gt;
&lt;p&gt;There is only one thing we can do here, making sure that we use the best technologies available (always HTTPS, encrypting hard drives, use secure OS like mac or Linux) and mainly &lt;strong&gt;installing security updates as soon as possible&lt;/strong&gt;. There are always going to be vulnerabilities, but we can reduce how long they are exploitable by running frequent updates.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Privacy</title>
      <link>https://blog.viktomas.com/posts/privacy/</link>
      <pubDate>Sun, 02 Feb 2020 09:11:34 +0100</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/privacy/</guid>
      <description>&lt;p&gt;Two years ago I read George Orwell&amp;rsquo;s novel 1984 that describes a dystopian future where authoritarian regime got complete control over people&amp;rsquo;s lives. The book is amazingly written and it is as relevant today as it ever was. Reading it sent me on down a rabbit hole of research about how much privacy do I have in my current life. Let me put on my tinfoil hat and tell you some of what I found.&lt;/p&gt;
&lt;h2 id=&#34;what-is-privacy&#34;&gt;What is privacy?&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;privacy&lt;/strong&gt; noun&lt;/p&gt;
&lt;p&gt;the state of being alone and not watched or interrupted by other people&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is how the Oxford Dictionary defines privacy. For me, the word represents that if I don&amp;rsquo;t wish my actions (I read an article about a controversial topic), data (my bathing suit pictures from latest holiday) or thoughts to be public (available to other people to see), they won&amp;rsquo;t be.&lt;/p&gt;
&lt;h2 id=&#34;why-is-it-important&#34;&gt;Why is it important?&lt;/h2&gt;
&lt;p&gt;People behave differently in private and when they know they can be watched. That&amp;rsquo;s the whole point of surveillance cameras. When you talk to your friend, would you say the same things if you knew the transcript of your conversation is going to be available to your potential employer during the next interview? No, you would censor yourself and that would not only limit the quality of conversation but it would over the time limit the quality of your thinking. You wouldn&amp;rsquo;t be able to discuss any controversial topics like addiction, racial issues, religion or politics.&lt;/p&gt;
&lt;p&gt;Now half of the readers switched off thinking: &amp;ldquo;Tomas, you need to stop reading books like 1984&amp;rdquo;. But to those I say: Just search for &amp;ldquo;social media background checks&amp;rdquo;. And that&amp;rsquo;s only one example.&lt;/p&gt;
&lt;h2 id=&#34;most-common-argument-against-privacy&#34;&gt;Most common argument against privacy&lt;/h2&gt;
&lt;p&gt;People who tend not to worry about their privacy often say a variation of &amp;ldquo;If you don&amp;rsquo;t have nothing to hide, you have nothing to worry about&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;Proponents of privacy usually chuck a wobbly at this point, yelling: &amp;ldquo;Yeah, yeah, give me keys from your house and all your papers like id&amp;rsquo;s and bank account statements if you&amp;rsquo;ve got nothing to hide&amp;rdquo;. And while this is a perfectly valid reaction to the naive statement, one argument won me over much more:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;The fact that you don&amp;rsquo;t decide to exercise your right doesn&amp;rsquo;t mean that other people don&amp;rsquo;t need it or that the right shouldn&amp;rsquo;t be present.&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You could just substitute privacy with any other right like &amp;ldquo;freedom of speech&amp;rdquo; or &amp;ldquo;right to organise&amp;rdquo;.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m not an activist, oppressed minority and I live in a country where freedom of speech still works well. That doesn&amp;rsquo;t mean I&amp;rsquo;m going to be sharing my private conversations/data just because nobody is probably interested (except for thousands of companies using the data for advertising). That would make it that much harder for people who have to hide what they are talking about in an interest in their safety.&lt;/p&gt;
&lt;h2 id=&#34;but-what-about-terrorismcrime&#34;&gt;But what about terrorism/crime/???&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Those who would give up essential Liberty, to purchase a little temporary Safety, deserve neither Liberty nor Safety.&lt;/p&gt;
&lt;p&gt;Ben Franklin&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Stronger or at least the current rights ensuring privacy are making it harder for law enforcement agencies to fight crime and terrorism, that&amp;rsquo;s for certain. But it&amp;rsquo;s not a black and white issue. There is no guarantee that if we give away part of our privacy there&amp;rsquo;s going to be less crime and less terrorism. Just look at the NSA&amp;rsquo;s scandals over the last decade and see if there are fewer mass shootings and less terrorist attacks in the states.&lt;/p&gt;
&lt;p&gt;On top of that Terrorism is a massively exaggerated issue. Since 9-11, terrorists kill every year &amp;ldquo;about fifty people in the European Union, about ten people in the USA, about seven people in China, and up to 25,000 people globally (mostly in Iraq, Afghanistan, Pakistan, Nigeria and Syria). In contrast, each year traffic accidents kill about 80,000 Europeans, 40,000 Americans, 270,000 Chinese, and 1.25 million people altogether.&amp;rdquo; [1]&lt;/p&gt;
&lt;p&gt;How much of your privacy will you sacrifice for 0.06% improvement in traffic casualties?&lt;/p&gt;
&lt;h2 id=&#34;theres-no-such-thing-as-free-lunch&#34;&gt;There&amp;rsquo;s no such thing as free lunch&lt;/h2&gt;
&lt;p&gt;My closing thought is that a lot of services we are using are &amp;ldquo;for free&amp;rdquo;. When you use Gmail, all your emails and hour behaviour (do you read the email, do you click through, do you respond) is being parsed and used for ad targeting. Same with Google search, Youtube and Facebook. It doesn&amp;rsquo;t have to be like that, but you&amp;rsquo;ll have to pay. In one of the next articles, I&amp;rsquo;ll dive into alternatives to mainstream online services.&lt;/p&gt;
&lt;p&gt;[1] - Yuval Noah Harari - 21 Lessons for the 21st Century&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Terry Pratchett - Small Gods</title>
      <link>https://blog.viktomas.com/books/pratchett-terry--small-gods/</link>
      <pubDate>Sun, 02 Feb 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/pratchett-terry--small-gods/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m a firm believer in the God of lettuce. It&amp;rsquo;s a safe bet I&amp;rsquo;m told.&lt;/p&gt;
&lt;p&gt;The dynamic between a god needing his follower more than follower the god creates tricky and funny situations throughout the book. Of course, Pratchett&amp;rsquo;s Discworld is a gift that keeps giving. Like for example the Omnians having the silly naive idea that world is a sphere circling around the sun, whilst we all well know it&amp;rsquo;s a disc on backs of four elephants standing on a giant turtle (there&amp;rsquo;s good eating on one of these).&lt;/p&gt;
&lt;p&gt;My favourite character was a philosopher named Didactylos whose world view I&amp;rsquo;m planning on adopting.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Free and Open-Source Software</title>
      <link>https://blog.viktomas.com/posts/foss/</link>
      <pubDate>Sun, 26 Jan 2020 09:01:16 +0100</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/foss/</guid>
      <description>&lt;p&gt;This article is mainly a personal research to clear my thoughts about what FOSS is and isn&amp;rsquo;t. Before we start, let&amp;rsquo;s quickly mention some famous examples:&lt;/p&gt;
&lt;p&gt;Firefox, Linux, Git, Gimp, Eclipse, GitLab, most programming languages and thousands more.&lt;/p&gt;
&lt;h2 id=&#34;f-is-for-free&#34;&gt;F is for Free&lt;/h2&gt;
&lt;p&gt;Usually when you publish a piece of software, you publish it &amp;ldquo;under a license&amp;rdquo;. Which means you attach a contract to your code that says how it can and can&amp;rsquo;t be used and shared.&lt;/p&gt;
&lt;p&gt;Free licences allow users of your code to change it and republish it. Some are more strict - GPL license forces you to publish all work build on top of the original code. Whilst others are more lenient and even allow you to change the license of the code if you wish (MIT, Apache).&lt;/p&gt;
&lt;h2 id=&#34;open-source&#34;&gt;Open-Source&lt;/h2&gt;
&lt;p&gt;On top of free license, FOSS is open source. That simply means that all the source code is published on the web for everyone to see. This amongst other things allows people to contribute to the software.&lt;/p&gt;
&lt;h2 id=&#34;why-people-do-it&#34;&gt;Why People do it?&lt;/h2&gt;
&lt;p&gt;In Czech we&amp;rsquo;ve got an old proverb, it can be roughly translated as&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Even chicken doesn&amp;rsquo;t peck for free.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Why would people volunteer their time and resources to build something for free? Well it&amp;rsquo;s not always completely altruistic act. More often than not the company/individual that shares the code gets something in advance be it better security, lower development cost, easier hiring thanks to the popularity of the software and so on. The three most common models are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;a company open sources non-core part of their product, e.g. infrastructure orchestration. There is only a marginal risk of them losing business over someone else being able to orchestrate their infrastructure better. But the benefit is that if people start using this orchestration and contributing back to it, the original company will reduce their development and maintenance cost&lt;/li&gt;
&lt;li&gt;a company or an individual builds their business around providing premium support to the open-sourced software - canonical with Ubuntu is a good example&lt;/li&gt;
&lt;li&gt;company builds proprietary/non free version on top of open core (I work at GitLab which does exactly that)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;should-you-use-it&#34;&gt;Should you use it?&lt;/h2&gt;
&lt;p&gt;You already are right now, this blog is built with HUGO, stored using Git on a GitLab.com instance, travelling to you over bazillion linux nodes and is shown in a browser that, if you are an average user, is Chrome which at least has open-source core.&lt;/p&gt;
&lt;p&gt;But that&amp;rsquo;s not the point, everybody is using the mainstream FOSS and you will too. I mean should you chose FOSS in the remaining cases? The cases where the market hasn&amp;rsquo;t converged on FOSS yet. Gimp vs Photoshop, MacOS or Windows vs Linux, IntelliJ Idea vs Eclipse, Sublime vs VS Code, Shotwell vs Picassa, the list goes on.&lt;/p&gt;
&lt;p&gt;The answer is: &amp;ldquo;it depends&amp;rdquo;. It depends on at least three factors: Do you have enough software skills to debug issues? Do you have time for that? And the most important of all: Is it fun for you to fiddle with your software?&lt;/p&gt;
&lt;p&gt;Unless the answer to all three questions is yes, I&amp;rsquo;d strongly recommend paying someone to worry instead of you. That comes from a person who spent the whole yesterday trying to make my vim show me details of error that it was already highlighting. I failed miserably and it plunged me into depression mixed with &amp;ldquo;screw FOSS&amp;rdquo; attitude. But I&amp;rsquo;m going to be spending countless hours debugging FOSS issues in no time. Don&amp;rsquo;t you worry.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Slow endorphins</title>
      <link>https://blog.viktomas.com/posts/slow-endorphins/</link>
      <pubDate>Wed, 22 Jan 2020 21:56:01 +0100</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/slow-endorphins/</guid>
      <description>&lt;p&gt;Watching YouTube or reading a book? Scrolling through Instagram or calling a friend? Eating a pizza or working out? Playing computer games or going out for a walk?&lt;/p&gt;
&lt;p&gt;If you are anything like me, you&amp;rsquo;d much more prefer to do the former. It&amp;rsquo;s so easy that you could almost say those things are doing you and not the other way around. I think this is happening because these things reward you immediately. Your nervous system that is still made much more for the African savannah as opposed to the modern city is incetivizing you to do things that feel good now, there might not be tomorrow.&lt;/p&gt;
&lt;p&gt;Two minute YouTube video gives you as much emotion as half an hour of reading a book? Go for it. You can overview all of your friend&amp;rsquo;s lives on Instagram in a fraction of time it would take to have a real conversation with one. And that cheese ❤️.&lt;/p&gt;
&lt;p&gt;Modern life is optimized for quick gratification and there might be a good reason to opt out from the viscous loop of fast endorphins. Let&amp;rsquo;s do a bit thought exercise together.&lt;/p&gt;
&lt;p&gt;Close your eyes and think about a moment in the past where you were really happy. You spent amazing time with your friends, you achieved something great, you saw something you won&amp;rsquo;t forget for years. After you vividly imagine one scene, try it for two more times. This should give you a sample of 3 worth while experiences.&lt;/p&gt;
&lt;p&gt;Now let&amp;rsquo;s see my examples:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Spending evening in the back of my camper van with my girlfriend and my best friends&lt;/li&gt;
&lt;li&gt;Pushing myself to close that stock account I was postponing for months&lt;/li&gt;
&lt;li&gt;Finishing my last book&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Your are probably very different but I assume they&amp;rsquo;ll have one of two (or both) things in common, they either contain people really close to you or they are a result of prolonged effort. The second kind is the one I&amp;rsquo;m mainly interested in this article.&lt;/p&gt;
&lt;p&gt;The more I think about the things I do in life the more short term, high endorphins experiences I&amp;rsquo;m weeding out of my day to day life. I think that people have been happy for thousands of year without the need for social networks or streaming video services. All I&amp;rsquo;m asking is you to do your own introspection. Do it in the morning when your mind is really sharp, possibly after your first coffee if you drink one. And see for yourself whether the social media or the video streaming services has a positive effect on your life.&lt;/p&gt;
&lt;p&gt;There is another way. You can limit the amount of time you spent on an app each day. Android 10 has a &lt;em&gt;Digital Wellbeing&lt;/em&gt; section in settings where you can limit the amount of time that an app can be open. And at the same time you can see stats in there that will give you and idea about your current usage. Try to set a limit to 80% of your current average usage. Or 60%. And after a few weeks let me know how did it go?&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Karel Čapek - R.U.R.</title>
      <link>https://blog.viktomas.com/books/capek-karel--r-u-r/</link>
      <pubDate>Mon, 20 Jan 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/capek-karel--r-u-r/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve picked this book for two reasons. It&amp;rsquo;s my country&amp;rsquo;s classics and it&amp;rsquo;s super short. The 3 hours that it took to read R.U.R. was time well spent. If the book was any longer, I&amp;rsquo;d mind the old and rudimentary style (I guess inherent to plays).&lt;/p&gt;
&lt;p&gt;Many of the concepts mentioned in this play are still valid today, e.g. Should we allow AI to make AI? Should robots carry guns? Can people behave cruelly to a robot without consciousness? And is it ok to replace human work force with machine learning?&lt;/p&gt;
&lt;p&gt;That being said the early 20th century style comes at a cost of for example having to endure the role of Helena whose naivety and silliness and the whole overall subtext of (women are supposed to be pretty and not much else) pisses me off.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Randall Munroe - How To: Absurd Scientific Advice for Common Real-World Problems</title>
      <link>https://blog.viktomas.com/books/munroe-randall--how-to/</link>
      <pubDate>Fri, 17 Jan 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/munroe-randall--how-to/</guid>
      <description>&lt;p&gt;Is it a fiction, is it non-fiction? Who knows, who cares. This book looks long but thanks to the rich imagery I chewed through it in no time. The clarity of Munroe&amp;rsquo;s explanation makes me feel smart. He only slipped once when he was explaining the hit precision for different ball sports but maybe that was just because he got me used to spoon feeding of facts in a very clear manner.&lt;/p&gt;
&lt;p&gt;I laughed out loud multiple times when reading How To. Once uncontrollably. You&amp;rsquo;ll know when you read the advice on how to loose election.&lt;/p&gt;
&lt;p&gt;If my physics teachers used just one of these examples during their classes, I&amp;rsquo;d most likely went on a career in theoretical physics. I have to say: &amp;ldquo;Thank Jesus they didn&amp;rsquo;t&amp;rdquo;. Because engineering is much more fun.&lt;/p&gt;
&lt;p&gt;If you have a river near by that you&amp;rsquo;d like to cross, do yourself a favour and do it as Randall says.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Sue Burke - Semiosis</title>
      <link>https://blog.viktomas.com/books/burke-sue--semiosis/</link>
      <pubDate>Thu, 16 Jan 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/burke-sue--semiosis/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve never read a sci-fi quite like this. Semiosis tells a story in a way that will give you both detail and large overview of the idea.&lt;/p&gt;
&lt;p&gt;Detail because the story is told by people (and plants) and large overview because the stories are told by different people in different generations of settlers on Pax.&lt;/p&gt;
&lt;p&gt;The book stretched my vocabulary because there is a lot of chemistry and botanic terms that you don&amp;rsquo;t come across in literature unless it&amp;rsquo;s your field of study.&lt;/p&gt;
&lt;p&gt;This book shows well the issue of information retention and how small population can&amp;rsquo;t afford to stay as specialized as people are in today&amp;rsquo;s economy and hence has to lower their understanding and use of technology. How long would our electronics and machine last if we lost the collective knowledge of the global world? 100 years? 200?&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>How I stopped drinking for a year</title>
      <link>https://blog.viktomas.com/posts/alcohol-abstinence/</link>
      <pubDate>Mon, 13 Jan 2020 20:00:00 +0100</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/alcohol-abstinence/</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;As all Buddhas refrained from alcohol until the end of their lives, so I too will refrain from alcohol until the end of my life.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;The five precepts, the most important system of morality for Buddhist lay people &lt;a href=&#34;https://en.wikipedia.org/wiki/Five_precepts#Fifth_precept&#34;&gt;1&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m writing this article on Saturday morning after a Friday night out with my Friends. We&amp;rsquo;ve hit the pub and everybody was merry. Beer was flowing and shots were had, just not by me. I came back home around midnight. Brushed my teeth and set an alarm for 8AM so I get 8 hours of sleep. In the morning I did some journaling, meditated and after nice breakfast and coffee sat to my computer to write this post. No hungover, no regrets, clear mind.&lt;/p&gt;
&lt;p&gt;This introduction would look radically different a few years back. I would have drunk beers and shots, tried to convince my friends to take the party further and if successful, I would rock up home at 4+AM, wallet empty and I wouldn&amp;rsquo;t even remember it. In the morning I would just grab my laptop and watch TV series for a good part of the day feeling sorry for myself.&lt;/p&gt;
&lt;h2 id=&#34;my-history-of-drinking&#34;&gt;My history of drinking&lt;/h2&gt;
&lt;p&gt;I started drinking very late for a Czech guy. I had my first serious piss up on the day of my 18th birthday. The same night I had my first black out as well. Experience that would accompany me on each larger social occasion till my 30&amp;rsquo;s. Since then my life revolved around alcohol. Every week there would be several occasions to drink. Climbing? What about first climbing and then drinking in a pub? Walking on Slackline? How about get a few bottles of wine to make it more fun.&lt;/p&gt;
&lt;p&gt;Don&amp;rsquo;t let me start with uni. There was a pub under almost every apartment building in my dorms. Student parties happening at least every fortnight. And finishing exams? I don&amp;rsquo;t know many better reasons for celebration (childbirths, weddings, finishing uni).&lt;/p&gt;
&lt;p&gt;This is not unusual at all. My experience would be of an average Czech adolescent.&lt;/p&gt;
&lt;p&gt;One returning theme would be part of my drinking experiences. I&amp;rsquo;m a better person when I&amp;rsquo;m hammered. I like others more, I&amp;rsquo;m more fun, I&amp;rsquo;m not afraid, I&amp;rsquo;m more extroverted. I&amp;rsquo;m more everything. Quite often when I wasn&amp;rsquo;t enough of something, solution was just a few drinks away.&lt;/p&gt;
&lt;h2 id=&#34;12-years-later&#34;&gt;12 years later&lt;/h2&gt;
&lt;p&gt;Not that much changed in regard to drinking when I was approaching my 30th birthday. I knew a few things. I didn&amp;rsquo;t feel that much shame or anxiety after my blackouts, I knew to drink a lot of water as I&amp;rsquo;m out drinking (something they should have thought us in school), I had better taste in spirits, wine and beer.&lt;/p&gt;
&lt;p&gt;I quit my job as well, got a decent bonus and had good savings and decided to travel for two years. Europe, Asia, South America. Without even knowing it this was the beginning of end (for my drinking).&lt;/p&gt;
&lt;p&gt;After 5 months of travel and experiences I found myself in a &lt;a href=&#34;http://www.suanmokkh-idh.org/&#34;&gt;Buddhist monastery in Southern Thailand&lt;/a&gt;. It was a day before New Years Eve and just a few days after participating in one of the infamous Full Moon parties of Ko Phangan (the Ibiza of Asia). I stayed in the monastery for 12 days on a silent retreat. I didn&amp;rsquo;t get any huge revelations or awakening but on day 8 our retreat leader had a talk about the 5 precepts, analogous to the Christian 10 commandments.&lt;/p&gt;
&lt;p&gt;The lady was talking about not hurting people and not stealing and then she mentioned the fifth. She said &amp;ldquo;And the fifth precept huh?&amp;rdquo; and smiled. There were a few murmured laughs around. Then she said something that stayed with me for the rest of the retreat and I sure had a lot of time to think about it.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Without the fifth percept, you can&amp;rsquo;t uphold the rest.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Reflecting on my past, majority of the things I&amp;rsquo;ve done I&amp;rsquo;m not proud of were under the influence of alcohol. I did mental balance scorecard and decided to try a year without alcohol. Might as well since the retreat finished on 11th of January, only 354 days to go.&lt;/p&gt;
&lt;h2 id=&#34;the-alcohol-free-experience&#34;&gt;The alcohol free experience&lt;/h2&gt;
&lt;p&gt;The experience is very daunting, after using alcohol as social lubricant for over a decade, it&amp;rsquo;s not easy to socialize. You realize that the interactions with strangers are more awkward and that you&amp;rsquo;d actually much prefer to go home and read/sleep/do the thing. I&amp;rsquo;m not saying that I would &lt;em&gt;actually&lt;/em&gt; prefer reading over human contact &lt;a href=&#34;#note1&#34;&gt;1&lt;/a&gt; but I surely feel that tendency more when I&amp;rsquo;m sober.&lt;/p&gt;
&lt;p&gt;One thing you notice almost instantly is the weird experience of not having a hungover after a night out. Hungovers were a part of my life, big one too. The only thing I have to plan for now when I&amp;rsquo;m coming home from a party is to shift my alarm to allow for roughly eight hours of sleep. I don&amp;rsquo;t have to worry about spending a good part of the next day in my bead watching movies/series.&lt;/p&gt;
&lt;h3 id=&#34;dating&#34;&gt;Dating&lt;/h3&gt;
&lt;p&gt;This is, where I think a major hole in an black and white argument like &amp;ldquo;Drinking is terrible, everybody should stop&amp;rdquo; breaks down. Of course it&amp;rsquo;s possible to start a romantic relationship without an alcohol, but a small dose will definitely help and most of us in this day and age need every bit of help they can get. Alcohol makes people putting aside their reservations and judgement and makes romantic encounters easier to happen.&lt;/p&gt;
&lt;p&gt;Since I had a girlfriend at the time I stopped drinking, this issue is not affecting me, but I would probably recommend to single people to keep drinking.&lt;/p&gt;
&lt;h2 id=&#34;the-future&#34;&gt;The future&lt;/h2&gt;
&lt;p&gt;It&amp;rsquo;s seventh of January , year and a week since I stopped drinking. I&amp;rsquo;m not planning on starting any time soon because I don&amp;rsquo;t trust myself with being able to keep a moderate approach to alcohol. And to be honest, I don&amp;rsquo;t miss that experience at all after a year. I&amp;rsquo;ve learnt how to enjoy the company of my friends and family without alcohol and I think this reality is going to be like a good whisky, getting better with age.&lt;/p&gt;
&lt;p&gt;&lt;span id=&#34;#note1&#34;&gt;[1]&lt;/span&gt; Or at least not all the time.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Susan Basterfield, Anthony Cabraal - Better work together: How the power of community can transform your business</title>
      <link>https://blog.viktomas.com/books/basterfield-cabraal--better-work-together/</link>
      <pubDate>Sun, 05 Jan 2020 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/basterfield-cabraal--better-work-together/</guid>
      <description>&lt;p&gt;The book follows a story of an entity called Enspiral from New Zealand (if this sounds vague that&amp;rsquo;s because it is). After reading the book you find out that Enspiral started as a consulting company but evolved as a very egalitarian community of people.&lt;/p&gt;
&lt;p&gt;The book is interesting but at the same time it&amp;rsquo;s very hard to read and follow. That is caused by both lack of clarity on what it is about and the fact each part is written by a different author.&lt;/p&gt;
&lt;p&gt;I both enjoy reading this book and hated how much work I had to do to comprehend what it was about.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Split brain phenomena</title>
      <link>https://blog.viktomas.com/posts/split-brain-phenomena/</link>
      <pubDate>Sun, 15 Dec 2019 20:00:00 +0100</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/posts/split-brain-phenomena/</guid>
      <description>&lt;p&gt;What do you do when epileptic seizures take a control of your brain and large storms of random neural activity starts to spread through your brain? You cut your brain in half to limit the blast radius.&lt;/p&gt;
&lt;p&gt;The human brain is split into two hemispheres right above the brain stem. The reason for that is not clear but I&amp;rsquo;m pretty sure it&amp;rsquo;s the same why we split CPU&amp;rsquo;s into cores. Connecting the layers of neurons is expensive and probably not necessary. (all my speculations)&lt;/p&gt;
&lt;p&gt;The independence of these two parts of the human brain became obvious in the research of Roger W. Sperry. He started studying interocular transfer with cats (studying why information learnt with one eye is available to the solving problems with the other eye). He found out that when severing the corpus collosum in cat brain, he can teach the cat to recognize geometric objects with one eye, but the learning won&amp;rsquo;t transfer to the other hemisphere and the other eye can&amp;rsquo;t recognise the objects.&lt;/p&gt;
&lt;p&gt;This initial research informed Sperry&amp;rsquo;s methodic for investigating patients who thanks to their intractable seizures had their corpus collosum severed in a procedure called callosotomy&lt;sup id=&#34;fnref:1&#34;&gt;&lt;a href=&#34;#fn:1&#34; class=&#34;footnote-ref&#34; role=&#34;doc-noteref&#34;&gt;1&lt;/a&gt;&lt;/sup&gt;. He invented series of tests that were relying on showing different information to different eyes. Using these tests he was able to demonstrate what each hemisphere is better at (e.g. Left - language, arithmetic, analysis; Right - spacial and pattern recognition).&lt;/p&gt;
&lt;p&gt;These tests convinced him that (in his words) each hemisphere is:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;indeed a conscious system in its own right, perceiving, thinking, remembering, reasoning, willing, and emoting, all at a characteristically human level, and &amp;hellip; both the left and the right hemisphere may be conscious simultaneously in different, even in mutually conflicting, mental experiences that run along in parallel.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;He was awarded with Nobel Prize in Medicine for this discovery in 1981 &lt;a href=&#34;https://www.nobelprize.org/prizes/medicine/1981/sperry/article/&#34;&gt;1&lt;/a&gt;&lt;/p&gt;
&lt;div class=&#34;footnotes&#34; role=&#34;doc-endnotes&#34;&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id=&#34;fn:1&#34;&gt;
&lt;p&gt;&lt;a href=&#34;https://www.ncbi.nlm.nih.gov/pmc/articles/PMC2812715/&#34;&gt;95 patients in 20 years in Montreal&lt;/a&gt; It seems that for certain types of seizures it is still a valid type of treatment today.&amp;#160;&lt;a href=&#34;#fnref:1&#34; class=&#34;footnote-backref&#34; role=&#34;doc-backlink&#34;&gt;&amp;#x21a9;&amp;#xfe0e;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;
</description>
    </item>
    
    <item>
      <title>Scott Adams - How to Fail at Almost Everything and Still Win Big: Kind of the Story of My Life</title>
      <link>https://blog.viktomas.com/books/adams-scott--how-to-fail-at-almost-everything/</link>
      <pubDate>Fri, 02 Sep 2016 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/books/adams-scott--how-to-fail-at-almost-everything/</guid>
      <description>&lt;p&gt;This book is by far the best self-help book I&amp;rsquo;ve ever read. It is witty, funny and it touches on all aspects of living a good life. When the book was published, lot of the concepts were not well known (at least to me).&lt;/p&gt;
&lt;p&gt;The most important takeaways were:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Getting a coffee to get yourself to exercise is a good deal even if the coffee by itself could be less healthy&lt;/li&gt;
&lt;li&gt;When you are not hungry or tired, stock up on healthy food and snacks. Make eating healthy much easier than eating rubbish&lt;/li&gt;
&lt;li&gt;Make sure that people can give you feedback (e.g. Scott&amp;rsquo;s email on the Dilbert comic)&lt;/li&gt;
&lt;li&gt;Prefer process over goals, make sure you enjoy the process&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Automation</title>
      <link>https://blog.viktomas.com/graph/automation/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/automation/</guid>
      <description>&lt;h3 id=&#34;crontab&#34;&gt;Crontab&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;There is a &lt;a href=&#34;https://github.com/viktomas/dotfiles#crontab&#34;&gt;crontab section&lt;/a&gt; in my &lt;a href=&#34;https://github.com/viktomas/dotfiles&#34;&gt;&lt;code&gt;dotfiles&lt;/code&gt;&lt;/a&gt; readme. (&lt;code&gt;vim ~/.dotfiles/README.md&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;espanzo&#34;&gt;Espanzo&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;I installed espanzo with &lt;code&gt;brew install --cask espanzo&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;My espanzo config is in my dotfiles &lt;a href=&#34;https://github.com/viktomas/dotfiles/tree/master/espanso&#34;&gt;https://github.com/viktomas/dotfiles/tree/master/espanso&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;I can press &lt;code&gt;Alt+Space&lt;/code&gt; to trigger the command palette.&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Bash shell</title>
      <link>https://blog.viktomas.com/graph/bash-shell/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/bash-shell/</guid>
      <description>&lt;h2 id=&#34;script-flags&#34;&gt;Script flags&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;#!/usr/bin/env bash
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;set -e  &lt;span style=&#34;color:#008000&#34;&gt;# Abort script at first error, when a command exits with non-zero status (except in until or while loops, if-tests, list constructs)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;set -u  &lt;span style=&#34;color:#008000&#34;&gt;# Attempt to use undefined variable outputs error message, and forces an exit&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;# set -x  # Similar to verbose mode (-v), but expands commands&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;set -o pipefail  &lt;span style=&#34;color:#008000&#34;&gt;# Causes a pipeline to return the exit status of the last command in the pipe that returned a non-zero return value.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;eof-marker-for-large-verbatim-text&#34;&gt;EOF marker for large verbatim text&lt;/h2&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;read -r -d &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#39;&amp;#39;&lt;/span&gt; JSON_PAYLOAD &lt;span style=&#34;color:#a31515&#34;&gt;&amp;lt;&amp;lt;&amp;#39;EOF&amp;#39;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;    &amp;#34;prompt_version&amp;#34;: 1,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;    &amp;#34;project_path&amp;#34;: &amp;#34;gitlab-org/gitlab-vscode-extension&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;    &amp;#34;project_id&amp;#34;: -1,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;    &amp;#34;choices_count&amp;#34;: 1
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;EOF&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;echo $JSON_PAYLOAD
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;wget&#34;&gt;Wget&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Download a file to a folder
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;wget -P /path/to/folder http://example.com/file.tar.gz
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;directory&#34;&gt;Directory&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Get current script directory
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;SCRIPT_DIR=&lt;span style=&#34;color:#00f&#34;&gt;$(&lt;/span&gt; cd -- &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#00f&#34;&gt;$(&lt;/span&gt; dirname -- &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;${&lt;/span&gt;BASH_SOURCE[0]&lt;span style=&#34;color:#a31515&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;&lt;/span&gt; &lt;span style=&#34;color:#00f&#34;&gt;)&lt;/span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;&lt;/span&gt; &amp;amp;&amp;gt; /dev/null &amp;amp;&amp;amp; pwd &lt;span style=&#34;color:#00f&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;environment-variables&#34;&gt;Environment variables&lt;/h2&gt;
&lt;p&gt;Default value&lt;/p&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt; export MY_VARIABLE=&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;&lt;/span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;${&lt;/span&gt;MY_VARIABLE&lt;span style=&#34;color:#00f&#34;&gt;:-&lt;/span&gt;defaultValue&lt;span style=&#34;color:#a31515&#34;&gt;}&lt;/span&gt;&lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;functions&#34;&gt;Functions&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;my_func() {
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#00f&#34;&gt;return&lt;/span&gt; &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#34;Hello World&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;RESULT=&lt;span style=&#34;color:#00f&#34;&gt;$(&lt;/span&gt;my_func&lt;span style=&#34;color:#00f&#34;&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;if-statement&#34;&gt;If statement&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;if&lt;/span&gt; [-a file];&lt;span style=&#34;color:#00f&#34;&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  ...
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#00f&#34;&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Table of all primaries (test command shortcuts) POSIX-Compliant&lt;/strong&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Primary&lt;/th&gt;
          &lt;th&gt;Meaning&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ -a FILE ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;FILE exists.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ -b FILE ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;FILE exists and is a block-special file.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ -c FILE ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;FILE exists and is a character-special file.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ -d FILE ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;FILE exists and is a directory.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ -e FILE ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;FILE exists.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ -f FILE ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;FILE exists and is a regular file.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ -g FILE ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;FILE exists and its SGID bit is set.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ -h FILE ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;FILE exists and is a symbolic link.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ -k FILE ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;FILE exists and its sticky bit is set.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ -p FILE ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;FILE exists and is a named pipe (FIFO).&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ -r FILE ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;FILE exists and is readable.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ -s FILE ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;FILE exists and has a size greater than zero.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ -t FD ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;file descriptor FD is open and refers to a terminal.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ -u FILE ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;FILE exists and its SUID (set user ID) bit is set.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ -w FILE ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;FILE exists and is writable.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ -x FILE ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;FILE exists and is executable.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ -O FILE ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;FILE exists and is owned by the effective user ID.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ -G FILE ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;FILE exists and is owned by the effective group ID.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ -L FILE ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;FILE exists and is a symbolic link.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ -N FILE ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;FILE exists and has been modified since it was last read.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ -S FILE ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;FILE exists and is a socket.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ FILE1 -nt FILE2 ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;FILE1 has been changed more recently than FILE2, or if FILE1 exists and FILE2 does not.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ FILE1 -ot FILE2 ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;FILE1 is older than FILE2, or is FILE2 exists and FILE1 does not.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ FILE1 -ef FILE2 ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;FILE1 and FILE2 refer to the same device and inode numbers.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ -o OPTIONNAME ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;shell option &amp;ldquo;OPTIONNAME&amp;rdquo; is enabled.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[[ STRING =~ ^regex$ ]]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;STRING matches regex&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ -z STRING ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;the length of &amp;ldquo;STRING&amp;rdquo; is zero.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ -n STRING ] or [ STRING ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;the length of &amp;ldquo;STRING&amp;rdquo; is non-zero.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ STRING1 == STRING2 ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;the strings are equal.  &amp;ldquo;=&amp;rdquo; may be used instead of &amp;ldquo;==&amp;rdquo; for strict POSIX compliance.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ STRING1 != STRING2 ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;the strings are not equal.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ STRING1 &amp;lt; STRING2 ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&amp;ldquo;STRING1&amp;rdquo; sorts before &amp;ldquo;STRING2&amp;rdquo; lexicographically in the current locale.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ STRING1 &amp;gt; STRING2 ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&amp;ldquo;STRING1&amp;rdquo; sorts after &amp;ldquo;STRING2&amp;rdquo; lexicographically in the current locale.&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[ ARG1 OP ARG2 ]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;&amp;ldquo;OP&amp;rdquo; is one of -eq, -ne, -lt, -le, -gt or -ge. *&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;*&lt;/code&gt; These arithmetic binary operators return true if &amp;ldquo;ARG1&amp;rdquo;  is equal to, not equal to, less than, less than or equal to, greater than, or greater than or equal to &amp;ldquo;ARG2&amp;rdquo;, respectively.  &amp;ldquo;ARG1&amp;rdquo; and &amp;ldquo;ARG2&amp;rdquo; are integers.&lt;/li&gt;
&lt;li&gt;Source: &lt;a href=&#34;https://tldp.org/LDP/Bash-Beginners-Guide/html/sect_07_01.html&#34;&gt;Introduction to if&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Table of primaries - non-posix complient (using &lt;code&gt;[[ ]]&lt;/code&gt;)&lt;/strong&gt;&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;Primary&lt;/th&gt;
          &lt;th&gt;Meaning&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[[ STRING =~ ^regex$ ]]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;STRING matches regex&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;&lt;code&gt;[[ STRING != *&amp;quot;substring&amp;quot;* ]]&lt;/code&gt;&lt;/td&gt;
          &lt;td&gt;STRING doesn&amp;rsquo;t contain substring&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If a command returns &lt;code&gt;0&lt;/code&gt;, it&amp;rsquo;s considered &lt;code&gt;TRUE&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Git</title>
      <link>https://blog.viktomas.com/graph/git/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/git/</guid>
      <description>&lt;p&gt;Delete all tags:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git tag | xargs git tag -d
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Range diff:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-sh&#34; data-lang=&#34;sh&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&lt;span style=&#34;color:#008000&#34;&gt;# Diff the diffs using `git range-diff`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git range-diff &lt;span style=&#34;color:#a31515&#34;&gt;${&lt;/span&gt;PREVIOUS_TAG&lt;span style=&#34;color:#a31515&#34;&gt;}&lt;/span&gt;..main &lt;span style=&#34;color:#a31515&#34;&gt;${&lt;/span&gt;NEW_TAG&lt;span style=&#34;color:#a31515&#34;&gt;}&lt;/span&gt;..update-fork-to-&lt;span style=&#34;color:#a31515&#34;&gt;${&lt;/span&gt;NEW_TAG&lt;span style=&#34;color:#a31515&#34;&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;is the working directory dirty?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;if [ -z &amp;quot;$(git status --porcelain)&amp;quot; ]; then&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Counting the lines of code in a Git repository &lt;code&gt;git ls-files | xargs wc -l&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Starting a new orphan commit in a repository &lt;code&gt;git checkout --orphan branch-name&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Remove a file through the whole history (good when you commit a binary or secrets by accident)&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;background-color:#fff;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;git filter-branch --index-filter &lt;span style=&#34;color:#a31515&#34;&gt;&amp;#39;git rm -rf --cached --ignore-unmatch path_to_file&amp;#39;&lt;/span&gt; HEAD
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;HTTP credentials&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Git sometimes caches the credentials. On MacOS, you see that &lt;code&gt;git config --get credential.helper&lt;/code&gt; returns &lt;code&gt;osxkeychain&lt;/code&gt; and you can find the cached credentials in keychain under the domain name (e.g. &lt;code&gt;gitlab.com&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Image resizing</title>
      <link>https://blog.viktomas.com/graph/image-resizing/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/image-resizing/</guid>
      <description>&lt;h2 id=&#34;svg&#34;&gt;SVG&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;rsvg-convert tanuki.svg -w 13 -h 13 -f svg -o tanuki13.svg&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;(had to install &lt;code&gt;librsvg&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id=&#34;png&#34;&gt;PNG&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;convert input.png -resize 50%  output.png&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Index</title>
      <link>https://blog.viktomas.com/graph/_main_index/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/_main_index/</guid>
      <description>&lt;p&gt;Hey, welcome. I’m Tomas. I like software, learning, privacy and healthy lifestyle. I work as a software engineer &lt;a href=&#34;https://about.gitlab.com/&#34;&gt;@GitLab&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id=&#34;most-popular-posts&#34;&gt;Most popular posts&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/slip-box-after-a-year/&#34;&gt;Zettelkasten note-taking after one year&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/boiling-litre-of-water&#34;&gt;How much energy do you need to boil a litre of water&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/slip-box/&#34;&gt;Zettelkasten note-taking in 10 minutes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/youtube-usage/&#34;&gt;A script to analyse 7+ years of my YouTube history&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/losing-google-account/&#34;&gt;What would you do if you lost your Google account?&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;categories-with-older-posts&#34;&gt;Categories with older posts&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/tech-and-software-category&#34;&gt;Tech &amp;amp; Software&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/productivity-category&#34;&gt;Productivity&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/lifestyle-category&#34;&gt;Lifestyle&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/security-and-privacy-category&#34;&gt;Security &amp;amp; Privacy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;open-source&#34;&gt;Open source&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/viktomas/godu/&#34;&gt;&lt;strong&gt;godu&lt;/strong&gt;&lt;/a&gt; - make space on your SSD&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/viktomas/gritty&#34;&gt;&lt;strong&gt;gritty&lt;/strong&gt;&lt;/a&gt; - terminal emulator written in Go&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/viktomas/gpic&#34;&gt;&lt;strong&gt;gpic&lt;/strong&gt;&lt;/a&gt; - remove similar photos from your albums&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href=&#34;https://github.com/viktomas/logseq-export&#34;&gt;logseq-export&lt;/a&gt;&lt;/strong&gt; - Export your Logseq graph into a static website&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/viktomas/simpleton-analytics&#34;&gt;&lt;strong&gt;Simpleton Analytics&lt;/strong&gt;&lt;/a&gt; - Analytics made simple&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/viktomas/total-youtube-watchtime&#34;&gt;&lt;strong&gt;Total YouTube Watchtime&lt;/strong&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://gitlab.com/gitlab-org/gitlab-vscode-extension&#34;&gt;GitLab Workflow&lt;/a&gt; - VS Code extension that integrates with GitLab, this is a project that I&amp;rsquo;m maintaining at GitLab&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Lifestyle</title>
      <link>https://blog.viktomas.com/graph/lifestyle-category/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/lifestyle-category/</guid>
      <description>&lt;p&gt;Mixed bag of posts about my life and general thoughts.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/mindset-when-buying-things&#34;&gt;How will you sell the thing you just bought - A strategy for smarter shopping&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/boiling-litre-of-water/&#34;&gt;How much energy do you need to boil a litre of water&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/investing-in-index-funds/&#34;&gt;My thoughts on investing: Index fund is all you need&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/low-salaries/&#34;&gt;Why are salaries so low&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/insurance/&#34;&gt;Insurance is like gambling, don&amp;rsquo;t overdo it&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/how-to-be-less-gullible/&#34;&gt;How to be less gullible&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/things-that-make-me-happy/&#34;&gt;The things that make me happy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/pot/&#34;&gt;I got a pot for my last birthday!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/one-hit-wonder-on-hn/&#34;&gt;How my article became one-hit-wonder on hacker news&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/minimalism/&#34;&gt;Minimalism&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/opportunity-cost/&#34;&gt;Opportunity cost&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/remote/&#34;&gt;Remote&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/van-life/&#34;&gt;Hashtag: Vanlife&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/meditation-introduction/&#34;&gt;Meditation, introduction&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/slow-endorphins/&#34;&gt;Slow endorphins&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/alcohol-abstinence/&#34;&gt;How I stopped drinking for a year&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>My Library</title>
      <link>https://blog.viktomas.com/graph/my-library/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/my-library/</guid>
      <description>&lt;p&gt;I love reading both fiction and non-fiction books. Here I keep a short review for each book I finish. This section is mainly for my benefit, but write me a message if you’d like to talk about books.&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>neovim</title>
      <link>https://blog.viktomas.com/graph/neovim/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/neovim/</guid>
      <description>&lt;p&gt;TODO read &lt;a href=&#34;https://news.ycombinator.com/item?id=26284618&#34;&gt;A Vim Guide for Advanced Users | Hacker News&lt;/a&gt;&lt;/p&gt;
&lt;h2 id=&#34;plugin-development&#34;&gt;Plugin development&lt;/h2&gt;
&lt;p&gt;&lt;a href=&#34;https://www.youtube.com/watch?v=wkxtHV1hzEY&#34;&gt;Create Neovim Plugins with Lua - YouTube&lt;/a&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&#34;&#34; type=&#34;checkbox&#34;&gt; watch &lt;a href=&#34;https://www.youtube.com/watch?v=HXABdG3xJW4&#34;&gt;Developing a Neovim Docker Plugin from Scratch - YouTube&lt;/a&gt; which was recommended in &lt;a href=&#34;https://www.jonashietala.se/blog/2024/05/02/customizing_neovim/&#34;&gt;Jonas Hietala: Customizing Neovim&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;kbd&gt;Ctrl&lt;/kbd&gt;+&lt;kbd&gt;w&lt;/kbd&gt; deletes the last word in insert mode&lt;/p&gt;
&lt;p&gt;🫵 custom mapping&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;inspect custom mappings with &lt;code&gt;:map&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;copy current file path to system clipboard &lt;code&gt;:let @+ = expand(&amp;quot;%&amp;quot;)&lt;/code&gt;&lt;/p&gt;
&lt;h2 id=&#34;minimal-reproduction-for-bugs&#34;&gt;Minimal reproduction for bugs&lt;/h2&gt;
&lt;p&gt;Follow the &lt;a href=&#34;./assets/scripts/test_oxide.sh&#34;&gt;test oxide script&lt;/a&gt; to set up minimal reproduction scenario&lt;/p&gt;
&lt;h2 id=&#34;help&#34;&gt;Help&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;F1&lt;/code&gt; - 🫵 fuzzy search through tags&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CTRL-]&lt;/code&gt; - go to tag&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CTRL-T&lt;/code&gt; - go back - tag stack&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Ctlr+O&lt;/code&gt; - go back - jump list&lt;/li&gt;
&lt;li&gt;&lt;code&gt;:helpgrep&lt;/code&gt; - grep through all help pages&lt;/li&gt;
&lt;li&gt;&lt;code&gt;:Helptags&lt;/code&gt; - fzf search through help tags&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;search-and-replace&#34;&gt;Search and replace&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;h4 id=&#34;visual-selected-text&#34;&gt;Visual selected text&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;yank it&lt;/li&gt;
&lt;li&gt;type in the &lt;code&gt;:%s/&amp;lt;C-R&amp;gt;0/replace text/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Ctrl+R&lt;/code&gt; pastes a register&lt;/li&gt;
&lt;li&gt;&lt;code&gt;0&lt;/code&gt; is the yank register&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;across-the-whole-project&#34;&gt;across the whole project&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;:grep &amp;lt;search term&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;:cfdo %s/&amp;lt;search term&amp;gt;/&amp;lt;replace term&amp;gt;/g&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;(If you want to save the changes in all files) &lt;code&gt;:cfdo update&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;movement&#34;&gt;Movement&lt;/h2&gt;
&lt;h2 id=&#34;lsp-support&#34;&gt;LSP support&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;I installed the &lt;code&gt;nvim-lspconfig&lt;/code&gt; plugin to make the LSP server config eaiser &lt;a href=&#34;https://github.com/neovim/nvim-lspconfig&#34;&gt;https://github.com/neovim/nvim-lspconfig&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;For &lt;strong&gt;TypeScript&lt;/strong&gt;, it required me to install the language server with
&lt;ul&gt;
&lt;li&gt;
&lt;pre tabindex=&#34;0&#34;&gt;&lt;code&gt;npm install -g typescript typescript-language-server
&lt;/code&gt;&lt;/pre&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Other LS configs can be found here &lt;a href=&#34;https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#tsserver&#34;&gt;https://github.com/neovim/nvim-lspconfig/blob/master/doc/server_configurations.md#tsserver&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Rename tweak: &lt;a href=&#34;https://blog.viktomas.com/graph/neovim-lsp-rename-normal-mode-keymaps&#34;&gt;Neovim LSP rename like a boss (with normal mode keymaps)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/neovim-make-lsp-workspace-symbols-show-only-workspace-symbols&#34;&gt;Neovim - Make LSP Workspace Symbols show only workspace symbols&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;autocompletion&#34;&gt;Autocompletion&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://github.com/hrsh7th/nvim-cmp&#34;&gt;https://github.com/hrsh7th/nvim-cmp&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;debugging&#34;&gt;Debugging&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;h3 id=&#34;mappings&#34;&gt;mappings&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;:verbose map &amp;lt;key&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;taken from &lt;a href=&#34;https://github.com/nanotee/nvim-lua-guide#debugging-lua-mappingscommandsautocommands&#34;&gt;Debugging Lua mappings/commands/autocommands&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;general&#34;&gt;General&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;open logs with &lt;code&gt;:e $NVIM_LOG_FILE&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;set verbosity &lt;code&gt;-V9&lt;/code&gt; (e.g. &lt;code&gt;vim -V9 file.txt&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;h3 id=&#34;lua-modules&#34;&gt;lua modules&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;I found where lua module is loaded from with &lt;code&gt;:lua print(debug.getinfo(package.loaded[&amp;quot;nvim-treesitter.configs&amp;quot;].attach_module, &amp;quot;S&amp;quot;).source)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;I found out that &lt;code&gt;lazy.nvim&lt;/code&gt; changed the &lt;code&gt;runtimepath&lt;/code&gt; with a slight delay. So my init script was able to import the module from the &amp;ldquo;default&amp;rdquo; &lt;code&gt;runtimepath&lt;/code&gt; and shortly after &lt;code&gt;lazy.nvim&lt;/code&gt; changed &lt;code&gt;runtimpath&lt;/code&gt; but the pesky module has already been loaded.&lt;/li&gt;
&lt;li&gt;The best way is to skip init file with &lt;code&gt;nvim -u NONE&lt;/code&gt; and then inspect the &lt;code&gt;:set runtimepath&lt;/code&gt; to see where the modules can come from&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;formatting&#34;&gt;Formatting&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;:noautocmd w&lt;/code&gt; will turn off the &amp;ldquo;format on save&amp;rdquo; for this single command&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;fast-search-and-replace&#34;&gt;Fast search and replace&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;cgn&lt;/code&gt; replaces the next search term, then you can press &lt;code&gt;.&lt;/code&gt; to repeat
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://news.ycombinator.com/item?id=26285372&#34;&gt;https://news.ycombinator.com/item?id=26285372&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id=&#34;todos&#34;&gt;TODOs&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;It happens to me quite often that I see some diagnostics
&lt;ul&gt;
&lt;li&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/image_1691567422945_0.png&#34;
    alt=&#34;image.png&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/li&gt;
&lt;li&gt;But I don&amp;rsquo;t know what plugin is adding them.&lt;/li&gt;
&lt;li&gt;I need to find a way to diagnose the diagnostics 👹&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;I sometimes see error in the command window:
&lt;ul&gt;
&lt;li&gt;&lt;img
    src=&#34;https://blog.viktomas.com/assets/graph/image_1691568492677_0.png&#34;
    alt=&#34;image.png&#34;
    loading=&#34;lazy&#34;
    
/&gt;&lt;/li&gt;
&lt;li&gt;I would like to be able to quickly copy it to the clipboard so I can search for solution on the web.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://vimeo.com/15443936?login=true&#34;&gt;Globals, Command Line and Functions on Vimeo&lt;/a&gt; - video recommended on Reddit&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Productivity</title>
      <link>https://blog.viktomas.com/graph/productivity-category/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/productivity-category/</guid>
      <description>&lt;p&gt;Here I write thoughts about how to do more with less&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/logseq-export/&#34;&gt;I wrote a command line tool to export Logseq pages as blog posts&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/mermaidjs-diagrams-in-logseq/&#34;&gt;Improve your Logseq notes with MermaidJS diagrams&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/promises-reduce-choices/&#34;&gt;Promises reduce your future choices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/slip-box-after-a-year/&#34;&gt;Zettelkasten note-taking after one year&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/compounding-skills/&#34;&gt;Compounding skills improve your life exponentially&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/stop-working-so-hard/&#34;&gt;Start working less to produce more, strange approach to prioritisation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/gtd-concepts/&#34;&gt;Three principles distilled from Getting Things Done&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/strategic-vs-utility/&#34;&gt;Focus on strategic and outsource utility work&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/time-vs-value/&#34;&gt;Easy-going work doesn&amp;rsquo;t provide much value&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/slip-box/&#34;&gt;Zettelkasten note-taking in 10 minutes&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/reading-is-hard/&#34;&gt;Why do you forget most of what you read?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/energy-levels/&#34;&gt;Optimize your personal energy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/break-free-from-youtube/&#34;&gt;Break free from the shackles of YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/my-workflow/&#34;&gt;My workflow&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/iteration/&#34;&gt;Iteration&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>restic</title>
      <link>https://blog.viktomas.com/graph/restic/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/restic/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://restic.net/&#34;&gt;restic&lt;/a&gt; is a backup software similar to Git, but for normal data (not source code). It stores the data encrypted and compressed. That makes it ideal for backing up to storage that you don&amp;rsquo;t own (e.g. cloud).&lt;/p&gt;
&lt;p&gt;Docs: &lt;a href=&#34;https://restic.readthedocs.io/en/latest/index.html&#34;&gt;https://restic.readthedocs.io/en/latest/index.html&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;[[Hetzner storage box]]&lt;/p&gt;
</description>
    </item>
    
    <item>
      <title>Security &amp; Privacy</title>
      <link>https://blog.viktomas.com/graph/security-and-privacy-category/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/security-and-privacy-category/</guid>
      <description>&lt;p&gt;I value my privacy, I love E2E encryption and oppose every and any government attempt to weaken encryption and listen to what their citizens talk about.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/facebook-censorship/&#34;&gt;Facebook won&amp;rsquo;t let you talk about this blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/digital-pirate-map/&#34;&gt;Designing a digital pirate map&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/plaintext-passwords/&#34;&gt;Using text passwords for encryption is safe enough&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/signal/&#34;&gt;Signal - the secure messenger&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/security-is-like-ogres/&#34;&gt;Security is like ogres&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/privacy/&#34;&gt;Privacy&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
    <item>
      <title>Tech &amp; Software</title>
      <link>https://blog.viktomas.com/graph/tech-and-software-category/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <author>me@viktomas.com (Tomas Vik)</author>
      <guid>https://blog.viktomas.com/graph/tech-and-software-category/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m a software engineer. That means I spend 10h a day at a computer and I love it. Here are my thoughts about computers and tech in general.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/circular-dependencies-in-javascript-explained&#34;&gt;Circular Dependencies in JavaScript Explained&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/typescript-di-es-decorators&#34;&gt;TypeScript Dependency Injection using ES Decorators&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/whitespace-sensitive-treesitter-grammar&#34;&gt;Example of whitespace-sensitive TreeSitter grammar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/gitlab-ci-skip-jobs-in-forks&#34;&gt;Skip GitLab CI jobs in forks&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/k8s-pod-resists-shutdown&#34;&gt;Simulate kubernetes pod resisting shutdown&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/goreleaser-already-exists-error&#34;&gt;Fixing goreleaser error - failed to publish artifacts .. already_exists&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/graph/go-range-function-call&#34;&gt;Go - range is like a function call&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/css-week-3-display-position-box/&#34;&gt;CSS Week 3 - Display, Position, and Boxing-model&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/css-week-2-grid-flexbox/&#34;&gt;CSS Week 2 - Grid and Flexbox&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/learning-css-in-two-months-week-1/&#34;&gt;CSS Week 1 - Selectors&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/learning-css-in-two-months-week-0/&#34;&gt;Learning CSS in two months&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/from-dropbox-to-nextcloud/&#34;&gt;Switching from Dropbox to Nextcloud&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/local-calendar/&#34;&gt;I want a local-first calendar&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/why-is-email-so-hard/&#34;&gt;Why is email so hard? Unsatisfactory migration from Gmail to Zoho&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/personal-data-longevity/&#34;&gt;How long will your data last before it gets lost or destroyed&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/describe-software-issue/&#34;&gt;How to describe a software issue&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/simpleton-analytics/&#34;&gt;Simpleton: privacy-aware web analytics made with Nginx and GoAccess&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/making-animated-gif/&#34;&gt;How to create animated gif from multiple images with ImageMagick&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/adblock-skews-analytics/&#34;&gt;AdBlockers hide the majority of visitors from web analytics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/youtube-usage/&#34;&gt;A script to analyse 7+ years of my YouTube history&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/losing-google-account/&#34;&gt;What would you do if you lost your Google account?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/spacex/&#34;&gt;Why I Love SpaceX&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href=&#34;https://blog.viktomas.com/posts/foss/&#34;&gt;Free and Open-Source Software&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
    </item>
    
  </channel>
</rss>
