<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>James Simas</title><link>https://www.jamessimas.com/</link><description>Recent content on James Simas</description><generator>Hugo -- 0.150.0</generator><language>en-us</language><lastBuildDate>Tue, 24 Feb 2026 16:18:22 -0800</lastBuildDate><atom:link href="https://www.jamessimas.com/index.xml" rel="self" type="application/rss+xml"/><item><title>Finding the single number with XOR</title><link>https://www.jamessimas.com/posts/2026/xoring-numbers/</link><pubDate>Tue, 24 Feb 2026 16:18:22 -0800</pubDate><guid>https://www.jamessimas.com/posts/2026/xoring-numbers/</guid><description>&lt;p&gt;I&amp;rsquo;ve been drilling on LeetCode recently and ran into &lt;a href="https://leetcode.com/problems/single-number/description/"&gt;a problem&lt;/a&gt; which I did not know how to solve &lt;em&gt;while using constant extra space&lt;/em&gt;:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Given a non-empty array of integers nums, every element appears twice except for one. Find that single one.&lt;/p&gt;
&lt;p&gt;You must implement a solution with a linear runtime complexity and use only constant extra space.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example 1:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Input: nums = [2,2,1]&lt;/li&gt;
&lt;li&gt;Output: 1&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Example 2:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Input: nums = [4,1,2,1,2]&lt;/li&gt;
&lt;li&gt;Output: 4&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Example 3:&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>SQL Common Table Expressions</title><link>https://www.jamessimas.com/posts/2025/sql-common-table-expressions/</link><pubDate>Thu, 18 Dec 2025 15:19:03 -0800</pubDate><guid>https://www.jamessimas.com/posts/2025/sql-common-table-expressions/</guid><description>&lt;p&gt;Today I spent some time learning about SQL common table expressions (aka &amp;ldquo;CTEs&amp;rdquo;). I already use subqueries, so they were easy to understand.&lt;/p&gt;
&lt;p&gt;The syntax is very simple:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;WITH&lt;/span&gt; my_cte &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; col1, col2, col3
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; table1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; col1, col3
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; my_cte
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here&amp;rsquo;s a more complex example with two CTEs:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;WITH&lt;/span&gt; my_cte1 &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; col1, col2, col3
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; table1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;),
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;my_cte2 &lt;span style="color:#66d9ef"&gt;AS&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; col4, col5, col6
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; table1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;SELECT&lt;/span&gt; my_table.&lt;span style="color:#f92672"&gt;*&lt;/span&gt;, my_cte1.col1, my_cte2.col4
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;FROM&lt;/span&gt; my_table
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;JOIN&lt;/span&gt; my_cte1 &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; my_table.fkey_id1 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; my_cte1.col1
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;JOIN&lt;/span&gt; my_cte2 &lt;span style="color:#66d9ef"&gt;ON&lt;/span&gt; my_table.fkey_id4 &lt;span style="color:#f92672"&gt;=&lt;/span&gt; my_cte1.col4
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;WHERE&lt;/span&gt; ...
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In general, I should prefer CTEs over subqueries because:&lt;/p&gt;</description></item><item><title>BASH Process Substitution</title><link>https://www.jamessimas.com/posts/2025/bash-process-substitution/</link><pubDate>Tue, 16 Dec 2025 20:25:05 -0800</pubDate><guid>https://www.jamessimas.com/posts/2025/bash-process-substitution/</guid><description>&lt;p&gt;Today, I learned about shell process substitution from Break on Penguin&amp;rsquo;s latest &lt;a href="https://www.youtube.com/watch?v=2A4bs40scSo"&gt;video&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Assume you have two files:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ cat file1
a
b
c
$ cat file2
c
b
a
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To see if they are identical when sorted &lt;em&gt;without manually creating your own temporary files&lt;/em&gt;, you can:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;diff &amp;lt;&lt;span style="color:#f92672"&gt;(&lt;/span&gt;sort file1&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;(&lt;/span&gt;sort file2&lt;span style="color:#f92672"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What is happening here?&lt;/p&gt;
&lt;p&gt;&lt;code&gt;&amp;lt;()&lt;/code&gt; is doing &lt;a href="https://www.gnu.org/software/bash/manual/html_node/Process-Substitution.html"&gt;process substitution&lt;/a&gt;, which is running the command and then exposing its output as a temporary file.&lt;/p&gt;</description></item><item><title>Sublime Text Arithmetic Command</title><link>https://www.jamessimas.com/posts/2025/sublime-text-arithmetic-command/</link><pubDate>Wed, 19 Nov 2025 20:08:52 -0800</pubDate><guid>https://www.jamessimas.com/posts/2025/sublime-text-arithmetic-command/</guid><description>&lt;p&gt;I&amp;rsquo;ve been using Sublime Text as my main text editor since August of 2014. I know it pretty well, but occassionally I still learn something new and useful.&lt;/p&gt;
&lt;p&gt;Today I learned about the &lt;code&gt;Arithmetic&lt;/code&gt; command from a &lt;a href="https://www.youtube.com/watch?v=taLCxwgcrVk&amp;amp;source_ve_path=MTc4NDI0"&gt;video by OdatNurd&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="summary-of-what-i-learned"&gt;Summary of what I learned&lt;/h2&gt;
&lt;h3 id="variables"&gt;Variables&lt;/h3&gt;
&lt;p&gt;The following variables are supported:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left"&gt;Variable&lt;/th&gt;
&lt;th style="text-align: left"&gt;What it does&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;s&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;The literal selected text&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;i&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;The selected text interpreted as a number (&lt;code&gt;0&lt;/code&gt;, if interpretation fails)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;i&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;The index of each selection (0-indexed)&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h3 id="converstions"&gt;Converstions&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;hex(x) // to hex
int(x) // to decimal
bin(x) // to binary
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="format-is-supported"&gt;format() is supported&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;format(x, &amp;#39;,&amp;#39;) // add comma separators to number, 1234 -&amp;gt; 1,234
format(x, &amp;#39;^80&amp;#39;) // center selected text in 80-character column
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="math-package-is-supported"&gt;math package is supported&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;math.ceil(x)
math.floor(x)
&lt;/code&gt;&lt;/pre&gt;&lt;blockquote class="github-alert github-alert-tip"&gt;
&lt;div class="github-alert-title"&gt;TIP: update numbers of an ordered list&lt;/div&gt;
&lt;div class="github-alert-content"&gt;&lt;p&gt;This is particularly useful; I do this all the time!&lt;/p&gt;</description></item><item><title>SSH Key Best Practices</title><link>https://www.jamessimas.com/posts/2025/ssh-key-best-practices/</link><pubDate>Wed, 10 Sep 2025 21:41:10 -0700</pubDate><guid>https://www.jamessimas.com/posts/2025/ssh-key-best-practices/</guid><description>&lt;p&gt;Today I needed to create a new SSH public/private keypair for work. I wanted to make sure I was following modern best practices for this, so I did some reading online.&lt;/p&gt;
&lt;p&gt;I found these two articles to be very helpful:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.brandonchecketts.com/archives/ssh-ed25519-key-best-practices-for-2025"&gt;SSH Key Best Practices for 2025 – Using ed25519, key rotation, and other best practices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://smallstep.com/blog/ssh-agent-explained/"&gt;SSH Agent Explained&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="things-i-learned"&gt;Things I learned&lt;/h2&gt;
&lt;p&gt;I didn&amp;rsquo;t ever think to change the comment at the end of the keyfile. Now I plan to date them, as it suggests. Using the email sub-alias (+) is clever and I&amp;rsquo;m stealing that.&lt;/p&gt;</description></item><item><title>Treating strings as numbers in Golang</title><link>https://www.jamessimas.com/posts/2025/unmarshaling-strings-as-numbers/</link><pubDate>Thu, 28 Aug 2025 18:50:28 -0700</pubDate><guid>https://www.jamessimas.com/posts/2025/unmarshaling-strings-as-numbers/</guid><description>&lt;p&gt;Today I encountered an API which sometimes sends back numbers as strings.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Example response:&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;#34;age&amp;#34;&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;30&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;That&amp;rsquo;s annoying, because I wanted my struct in Go to be like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;type&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Person&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Age&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`json:&amp;#34;age&amp;#34;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I learned that json struct tags have a &lt;a href="https://pkg.go.dev/encoding/json"&gt;string&lt;/a&gt; option meant for dealing with exactly this sort of problem:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;The &amp;ldquo;string&amp;rdquo; option signals that a field is stored as JSON inside a JSON-encoded string. It applies only to fields of string, floating point, integer, or boolean types. This extra level of encoding is sometimes used when communicating with JavaScript programs:&lt;/p&gt;</description></item><item><title>Even Easier Git Rebasing</title><link>https://www.jamessimas.com/posts/2025/git-rebase/</link><pubDate>Thu, 28 Aug 2025 17:50:28 -0700</pubDate><guid>https://www.jamessimas.com/posts/2025/git-rebase/</guid><description>&lt;p&gt;Rebasing your feature branch on &lt;code&gt;main&lt;/code&gt; regularly is a good idea.&lt;/p&gt;
&lt;p&gt;I used to do it like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# update local copy of main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git fetch origin main:main
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# rebase on local main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git rebase main
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This always felt a litle off because I was worried I&amp;rsquo;d typo &lt;code&gt;main:main&lt;/code&gt; and mess it up.&lt;/p&gt;
&lt;p&gt;This works just as well and feels much better to me:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# update local copy of `origin/main`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git fetch
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# rebase on origin/main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git rebase origin/main
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>How to add values to an HTTP query string in Go</title><link>https://www.jamessimas.com/posts/2025/add-values-to-http-query-string/</link><pubDate>Tue, 26 Aug 2025 18:58:08 -0700</pubDate><guid>https://www.jamessimas.com/posts/2025/add-values-to-http-query-string/</guid><description>&lt;p&gt;Here&amp;rsquo;s how to add key/value pairs to an &lt;code&gt;http.Reqest&lt;/code&gt;&amp;rsquo;s query string in Go:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;net/http&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// create a request&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;req&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;_&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;NewRequest&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;MethodGet&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;http://www.example.com/&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// get the current query string from the http.Request&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;values&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;req&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;URL&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Query&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// add or set values&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;values&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Set&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;myKey1&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;myVal1&amp;#34;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// overwrite!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;values&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Add&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;myKey1&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;myVal2&amp;#34;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// append!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// add values back to the request&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;req&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;URL&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;RawQuery&lt;/span&gt; = &lt;span style="color:#a6e22e"&gt;values&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Encode&lt;/span&gt;() &lt;span style="color:#75715e"&gt;// query string: mykey1=myVal1&amp;amp;myKey1=myVal2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// print the url&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;req&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;URL&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;String&lt;/span&gt;())
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The above program will output:&lt;/p&gt;</description></item><item><title>Binaries on Macos</title><link>https://www.jamessimas.com/posts/2025/binaries-on-macos/</link><pubDate>Fri, 22 Aug 2025 09:07:47 -0700</pubDate><guid>https://www.jamessimas.com/posts/2025/binaries-on-macos/</guid><description>&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left"&gt;Path&lt;/th&gt;
&lt;th style="text-align: left"&gt;Note&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;/usr/local/bin/&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;System-wide binaries go here!&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;&lt;code&gt;~/bin/&lt;/code&gt;&lt;/td&gt;
&lt;td style="text-align: left"&gt;My user&amp;rsquo;s binaries go here!&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;</description></item><item><title>Initial thoughts on Ghostty</title><link>https://www.jamessimas.com/posts/2025/ghostty-initial-thoughts/</link><pubDate>Mon, 18 Aug 2025 19:34:22 -0700</pubDate><guid>https://www.jamessimas.com/posts/2025/ghostty-initial-thoughts/</guid><description>&lt;p&gt;I&amp;rsquo;ve been using &lt;a href="https://alacritty.org"&gt;Alacritty&lt;/a&gt; exclusively for over a year. It&amp;rsquo;s fantastic!&lt;/p&gt;
&lt;p&gt;But I listened to an &lt;a href="https://www.youtube.com/watch?v=o-qtso47ECk"&gt;interview&lt;/a&gt; with Mitchell Hashimoto and he talked about trying to make terminal multiplexers obsolete. It struck a cord with me. I&amp;rsquo;ve been using &lt;a href="https://zellij.dev"&gt;Zellij&lt;/a&gt; ever since I switched from Iterm2 to Alacritty and it&amp;rsquo;s &lt;em&gt;great&lt;/em&gt;, but also it can be cumbersome.&lt;/p&gt;
&lt;p&gt;I find it cumbersome to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Search through this history (I don&amp;rsquo;t do it frequently enough for the keybindings to stick in my head.)&lt;/li&gt;
&lt;li&gt;Splitting and closing panes. (Whereas iTerm2&amp;rsquo;s keybindings to do this are burned into my brain forever.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;For all iTerm2&amp;rsquo;s faults, I miss it sometimes. (The biggest reason I ditched it is because you can&amp;rsquo;t commit its config to version control easily. Its config is huuuuuuge. And I won&amp;rsquo;t daily drive anything whose config I can&amp;rsquo;t version.)&lt;/p&gt;</description></item><item><title>Using Github Issues</title><link>https://www.jamessimas.com/posts/2025/github-issues/</link><pubDate>Thu, 10 Jul 2025 17:29:30 -0700</pubDate><guid>https://www.jamessimas.com/posts/2025/github-issues/</guid><description>&lt;p&gt;&lt;a href="https://overcast.fm/+AAmkop73ppc"&gt;This interview&lt;/a&gt; with Simon Willison is great.&lt;/p&gt;
&lt;p&gt;It pushed&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; me into using &lt;a href="https://docs.github.com/en/issues/tracking-your-work-with-issues/configuring-issues/quickstart"&gt;GitHub Issues&lt;/a&gt; for my private repositories. They&amp;rsquo;re wonderful. (In the past, I&amp;rsquo;ve been just tracking everything in Markdown documents. That worked, but was just OK.)&lt;/p&gt;
&lt;p&gt;As an example, I have a private GitHub repo with notes and documents for a private network I maintain (as a volunteer). It&amp;rsquo;s very ad-hoc and I sometimes go months between without working on it.&lt;/p&gt;</description></item><item><title>HTTP/1, HTTP/2, and HTTP/3</title><link>https://www.jamessimas.com/posts/2025/http-versions/</link><pubDate>Wed, 09 Jul 2025 20:09:59 -0700</pubDate><guid>https://www.jamessimas.com/posts/2025/http-versions/</guid><description>&lt;p&gt;There have been four&lt;sup id="fnref:1"&gt;&lt;a href="#fn:1" class="footnote-ref" role="doc-noteref"&gt;1&lt;/a&gt;&lt;/sup&gt; major versions of HTTP in-use in the last 30-ish years:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th style="text-align: left"&gt;Version&lt;/th&gt;
&lt;th style="text-align: left"&gt;RFC&lt;/th&gt;
&lt;th style="text-align: left"&gt;Year&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;HTTP/1.0&lt;/td&gt;
&lt;td style="text-align: left"&gt;RFC 1945&lt;/td&gt;
&lt;td style="text-align: left"&gt;1996&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;HTTP/1.1&lt;/td&gt;
&lt;td style="text-align: left"&gt;RFC 2068&lt;/td&gt;
&lt;td style="text-align: left"&gt;1997&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;HTTP/2&lt;/td&gt;
&lt;td style="text-align: left"&gt;RFC 7540&lt;/td&gt;
&lt;td style="text-align: left"&gt;2015&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td style="text-align: left"&gt;HTTP/3&lt;/td&gt;
&lt;td style="text-align: left"&gt;RFC 9114&lt;/td&gt;
&lt;td style="text-align: left"&gt;2022&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;It&amp;rsquo;s surprising to me how quickly HTTP/1.1 was released after HTTP/1.0. Less than one year!&lt;/p&gt;
&lt;h2 id="http10"&gt;HTTP/1.0&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;A simple, text-based protocol.&lt;/li&gt;
&lt;li&gt;Runs over TCP.&lt;/li&gt;
&lt;li&gt;Only officially supports a single HTTP request and response over each TCP connection, then the connection was torn down.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="http11"&gt;HTTP/1.1&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Still a text-based protocol.&lt;/li&gt;
&lt;li&gt;Added connection re-use.
&lt;ul&gt;
&lt;li&gt;On by default.&lt;/li&gt;
&lt;li&gt;Controlled via the &lt;code&gt;Connection: keep-alive&lt;/code&gt; header and tuned via &lt;code&gt;Keep-Alive&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Added the &lt;code&gt;Host&lt;/code&gt; header, which allows multiple websites to be hosted at a single IP address.&lt;/li&gt;
&lt;li&gt;Better cache control mechanisms.&lt;/li&gt;
&lt;li&gt;Added HTTP pipelining (allowing multiple requests to be sent in succession before responses were received). Apparently never got widespread support, though.&lt;/li&gt;
&lt;li&gt;Still suffers from Head of Line blocking.
&lt;ul&gt;
&lt;li&gt;Even though TCP connections get re-used, a given request/response cycle must complete before the connection is eligible for re-use.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Many browsers improved throughput by allowing up to 6 TCP connections per domain. Websites took this even further with domain sharding.
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Example:&lt;/strong&gt; Sharding resources over www1.foo.bar, www2.foo.bar, www3.foo.bar gives you 18 connections to play with.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;No compression of headers. Lots of redundant data sent for each request/response in the headers, which is inefficient.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="http2"&gt;HTTP/2&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Based on pioneering work done by Google with their SPDY (pronounced: &amp;ldquo;speedy&amp;rdquo;) protocol in the 2010s.&lt;/li&gt;
&lt;li&gt;No longer a text-based protocol; now a binary-based protocol.&lt;/li&gt;
&lt;li&gt;Allows request multiplexing over a single TCP connection.&lt;/li&gt;
&lt;li&gt;Solved the &lt;em&gt;application-layer&lt;/em&gt; Head of Line Blocking problem, but did not solve it for the transport layer (e.g., a dropped TCP packet would still delay all requests/responses behind it).&lt;/li&gt;
&lt;li&gt;Adds header compression.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="http3"&gt;HTTP/3&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Still a binary-based protocol.&lt;/li&gt;
&lt;li&gt;Moved from TCP to UDP+QUIC for the transport layer. Many improvements come from this.
&lt;ul&gt;
&lt;li&gt;Faster connection setup
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Old:&lt;/strong&gt; Setting up a TLS connection with older protocols required around three round trips (3-RTT): the TCP handshake (around 1-RTT) and TLS handshake (2-RTT).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;New:&lt;/strong&gt; Setting up a TLS connection with QUIC requires a single round trip (1-RTT) because the transport connection setup and TLS handshakes are merged. Note that 0-RTT resumption is possible with QUIC as well.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Avoids the transport-layer head of line blocking problem by using multiple streams. Head of line blocking now fixed at both HTTP and transport layer.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Faster connection migration via Connection IDs. (Allows a client to switch networks seamlessly while browsing.)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="closing"&gt;Closing&lt;/h2&gt;
&lt;p&gt;It was interesting going down this rabbit hole on HTTP.&lt;/p&gt;</description></item><item><title>System Design Patterns by Sean Goedecke</title><link>https://www.jamessimas.com/posts/2025/system-design-patterns-by-sean-goedecke/</link><pubDate>Wed, 02 Jul 2025 17:03:28 -0700</pubDate><guid>https://www.jamessimas.com/posts/2025/system-design-patterns-by-sean-goedecke/</guid><description>&lt;p&gt;&lt;a href="https://www.seangoedecke.com/good-system-design/"&gt;This blog post&lt;/a&gt; by Sean Goedecke was a great read on high-level system design patterns.&lt;/p&gt;
&lt;p&gt;Most of them were familiar to me, but I got several good ideas from it.&lt;/p&gt;
&lt;p&gt;Using a database as queue:&lt;/p&gt;
&lt;blockquote&gt;&lt;p&gt;Sometimes you want to roll your own queue system. For instance, if you want to enqueue a job to run in a month, you probably shouldn’t put an item on the Redis queue. Redis persistence is typically not guaranteed over that period of time (and even if it is, you likely want to be able to query for those far-future enqueued jobs in a way that would be tricky with the Redis job queue). In this case, I typically create a database table for the pending operation with columns for each param plus a &lt;code&gt;scheduled_at&lt;/code&gt; column. I then use a daily job to check for these items with &lt;code&gt;scheduled_at &amp;lt;= today&lt;/code&gt;, and either delete them or mark them as complete once the job has finished.&lt;/p&gt;</description></item><item><title>Tools to Organize Your Life</title><link>https://www.jamessimas.com/posts/2025/tools-to-organize-your-life/</link><pubDate>Wed, 25 Jun 2025 14:22:39 -0700</pubDate><guid>https://www.jamessimas.com/posts/2025/tools-to-organize-your-life/</guid><description>&lt;p&gt;Much productivity advice on the internet is too complicated and not actually that helpful.&lt;/p&gt;
&lt;p&gt;Complicated systems are less likely to be used due to the friction of using them and are more brittle in the face of changing needs. You are better off use basic, flexible systems; you are more likely to use simple systems and simple systems can adapt to change more easily.&lt;/p&gt;
&lt;p&gt;There are only a few tools you need to completely run your personal life. They are:&lt;/p&gt;</description></item><item><title>Keep Email Useful</title><link>https://www.jamessimas.com/posts/2025/keep-email-useful/</link><pubDate>Thu, 19 Jun 2025 09:40:27 -0600</pubDate><guid>https://www.jamessimas.com/posts/2025/keep-email-useful/</guid><description>&lt;p&gt;I get the impression that a lot of people are overwhelmed by their personal email inbox nowadays and get so much email that they&amp;rsquo;ve more or less given up on it.&lt;/p&gt;
&lt;p&gt;I don&amp;rsquo;t have that problem and that&amp;rsquo;s by design, not by accident. This post explains the rules I use to keep my personal email useful and very manageable.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Unsubscribe aggressively&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Any time you give your email address out nowadays, you will get put on a mailing list.&lt;/p&gt;</description></item><item><title>Echo Router Parameters</title><link>https://www.jamessimas.com/posts/2025/echo-router-params/</link><pubDate>Fri, 06 Jun 2025 15:21:38 -0700</pubDate><guid>https://www.jamessimas.com/posts/2025/echo-router-params/</guid><description>&lt;p&gt;I regularly have to look up how to create an &lt;a href="https://echo.labstack.com/docs/routing"&gt;Echo router&lt;/a&gt; context with (a) path parameters and (b) query parameters, so I&amp;rsquo;m making this post as a cheat sheet for my future self.&lt;/p&gt;
&lt;h2 id="path-parameters"&gt;Path parameters&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; &lt;code&gt;/some/random/path/:id&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// create your context&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;ctx&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;echo&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;New&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;NewContext&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;request&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;response&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// add your path param&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;ctx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;SetParamNames&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;id&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;ctx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;SetParamValues&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;foo&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="query-parameters"&gt;Query parameters&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Example:&lt;/strong&gt; &lt;code&gt;/some/random/path?key1=value1&amp;amp;key2=value2&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// create your request&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;request&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;httptest&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;NewRequest&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;MethodPost&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;/some/random/path&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// get existing query params&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;query&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;request&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;URL&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Query&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// add or set new params&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;query&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Add&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;key1&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;value1&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;query&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Set&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;key2&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;value2&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// encode the query params back to the request&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;request&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;URL&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;RawQuery&lt;/span&gt; = &lt;span style="color:#a6e22e"&gt;query&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Encode&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// create your context with the request&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;ctx&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;echo&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;New&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;NewContext&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;request&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;response&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Go Backoff Algorithms</title><link>https://www.jamessimas.com/posts/2025/go-backoff-algorithms/</link><pubDate>Wed, 04 Jun 2025 10:07:18 -0700</pubDate><guid>https://www.jamessimas.com/posts/2025/go-backoff-algorithms/</guid><description>&lt;p&gt;I ran across &lt;a href="https://commaok.xyz/post/simple-backoff/"&gt;a blog post&lt;/a&gt; by Josh Bleecher Snyder today which has some beautiful backoff algorithms in Go.&lt;/p&gt;
&lt;p&gt;Capturing them here in case his blog ever goes offline.&lt;/p&gt;
&lt;h2 id="algorithm-1"&gt;Algorithm 1&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;do&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;ctx&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;context&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Context&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;error&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;maxAttempts&lt;/span&gt; = &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;baseDelay&lt;/span&gt; = &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Second&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;maxDelay&lt;/span&gt; = &lt;span style="color:#ae81ff"&gt;60&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Second&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;delay&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;baseDelay&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;attempt&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;range&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;maxAttempts&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;request&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;ctx&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;delay&lt;/span&gt; &lt;span style="color:#f92672"&gt;*=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;delay&lt;/span&gt; = min(&lt;span style="color:#a6e22e"&gt;delay&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;maxDelay&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;jitter&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;multiplyDuration&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;delay&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;rand&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Float64&lt;/span&gt;()&lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0.5&lt;/span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0.25&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// ±25%&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;sleepTime&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;delay&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;jitter&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;select&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;case&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;-&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;ctx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Done&lt;/span&gt;():
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ctx&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Err&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;case&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;-&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;After&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;sleepTime&lt;/span&gt;):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Errorf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;failed after %d attempts&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;maxAttempts&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;multiplyDuration&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;d&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Duration&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;mul&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;float64&lt;/span&gt;) &lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Duration&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Duration&lt;/span&gt;(float64(&lt;span style="color:#a6e22e"&gt;d&lt;/span&gt;) &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;mul&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="algorithm-2"&gt;Algorithm 2&lt;/h2&gt;
&lt;p&gt;I really like this one. It&amp;rsquo;s very easy to read.&lt;/p&gt;</description></item><item><title>How to view and remove routes on macOS</title><link>https://www.jamessimas.com/posts/2025/macos-route-table/</link><pubDate>Fri, 30 May 2025 13:29:54 -0700</pubDate><guid>https://www.jamessimas.com/posts/2025/macos-route-table/</guid><description>&lt;p&gt;Today I needed to remove a bad route on macOS. Normally I just reboot to do that, but I decided to learn how to do it without rebooting.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s how I did it.&lt;/p&gt;
&lt;p&gt;First, view the routes to confirm the route is bad:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;netstat -rn | grep IP_ADDR
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Grab the IP you care about from the &amp;ldquo;Destination&amp;rdquo; column. Use it to delete the route:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;sudo route -n delete DEST_IP_ADDR
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Done!&lt;/p&gt;</description></item><item><title>Fixing a filename in git on a case insensitive filesystem</title><link>https://www.jamessimas.com/posts/2025/git-fixing-filename-case-insensitive-fs/</link><pubDate>Thu, 29 May 2025 14:16:28 -0700</pubDate><guid>https://www.jamessimas.com/posts/2025/git-fixing-filename-case-insensitive-fs/</guid><description>&lt;p&gt;My work laptop was provisioned with a case-insensitive filesystem for some strange reason.&lt;/p&gt;
&lt;p&gt;This makes renaming stuff in a git repo &amp;ldquo;fun&amp;rdquo;:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$mv README.md readme.md
mv: &amp;#39;README.md&amp;#39; and &amp;#39;readme.md&amp;#39; are the same file
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here&amp;rsquo;s a workaround for this problem:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# give the file a temp name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git mv README.md readme_temp.md
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git com -m &lt;span style="color:#e6db74"&gt;&amp;#34;Rename 1 of 2&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# then name it what you actually want to call it&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git mv readme_temp.md readme.md
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git com -m &lt;span style="color:#e6db74"&gt;&amp;#34;Rename 2 of 2&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Solved!&lt;/p&gt;</description></item><item><title>Grep's Buffering + Pipes</title><link>https://www.jamessimas.com/posts/2025/greps-buffering-pipes/</link><pubDate>Wed, 28 May 2025 19:59:55 -0700</pubDate><guid>https://www.jamessimas.com/posts/2025/greps-buffering-pipes/</guid><description>&lt;p&gt;I got bit by this again today, so I&amp;rsquo;m writing it down so I can reference it later.&lt;/p&gt;
&lt;p&gt;When running &lt;code&gt;docker logs -f CONTAINER_NAME | grep -v &amp;quot;foo&amp;quot; | jq&lt;/code&gt;, it is important to consider grep&amp;rsquo;s buffers.&lt;/p&gt;
&lt;p&gt;I am using GNU grep and, by default, it uses block buffering when not connected to a terminal (which is my case, since I piped it to &lt;code&gt;jq&lt;/code&gt;). This means &lt;code&gt;jq&lt;/code&gt; doesn&amp;rsquo;t get any input until a large-ish amount of text (4k? 8k?) is sent to &lt;code&gt;grep&lt;/code&gt;. Since container I was inspecting logs little, I got zero log lines.&lt;/p&gt;</description></item><item><title>Playing around with trees in Golang</title><link>https://www.jamessimas.com/posts/2025/golang-trees/</link><pubDate>Tue, 20 May 2025 09:44:24 -0700</pubDate><guid>https://www.jamessimas.com/posts/2025/golang-trees/</guid><description>&lt;p&gt;I was playing around with implementing Depth First Search (DFS) and Breadth First Search (BFS) in Go today.&lt;/p&gt;
&lt;p&gt;I made a tree which looked like this&amp;hellip;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt; 0
/ \
1 2
/ \ / \
3 4 5 6
/ \
7 8
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I then made some Go code to walk the tree using DFS and BFS:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// Node is a very basic struct which represents&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// a node in the tree.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;type&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Node&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Value&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Left&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Node&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Right&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Node&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// dfs() walks the tree (starting at the provided root node)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// in a depth first fashion. It uses a stack.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dfs&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;node&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Node&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// base case&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;node&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;DFS visiting:&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;node&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Value&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;node&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Left&lt;/span&gt; &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;dfs&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;node&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Left&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;node&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Right&lt;/span&gt; &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;dfs&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;node&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Right&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// bfs() walks the tree (starting at the provided root node)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// in a breadth first fashion. It uses a queue.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bfs&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;node&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Node&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// base case&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;node&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;queue&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; []&lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Node&lt;/span&gt;{&lt;span style="color:#a6e22e"&gt;node&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;depth&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; len(&lt;span style="color:#a6e22e"&gt;queue&lt;/span&gt;) &lt;span style="color:#f92672"&gt;&amp;gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;_&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;node&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;range&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;queue&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;queue&lt;/span&gt; = &lt;span style="color:#a6e22e"&gt;queue&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;:]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;BFS visiting: %d (depth: %d)\n&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;node&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Value&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;depth&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;node&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Left&lt;/span&gt; &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;queue&lt;/span&gt; = append(&lt;span style="color:#a6e22e"&gt;queue&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;node&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Left&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;node&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Right&lt;/span&gt; &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;queue&lt;/span&gt; = append(&lt;span style="color:#a6e22e"&gt;queue&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;node&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Right&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;depth&lt;/span&gt; &lt;span style="color:#f92672"&gt;+=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// define our tree (see above diagram)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;tree&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Node&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Value&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Left&lt;/span&gt;: &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Node&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Value&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Left&lt;/span&gt;: &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Node&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Value&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Right&lt;/span&gt;: &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Node&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Value&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Right&lt;/span&gt;: &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Node&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Value&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Left&lt;/span&gt;: &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Node&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Value&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Right&lt;/span&gt;: &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Node&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Value&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;6&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Left&lt;/span&gt;: &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Node&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Value&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;7&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Right&lt;/span&gt;: &lt;span style="color:#f92672"&gt;&amp;amp;&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Node&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Value&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// call our funcs&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;dfs&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;tree&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;bfs&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;tree&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Running the code outputs:&lt;/p&gt;</description></item><item><title>Enums in Go Part Deux - Marshaling and Unmarshaling!</title><link>https://www.jamessimas.com/posts/2025/enums-in-go-marshal-and-unmarshal/</link><pubDate>Thu, 15 May 2025 21:04:01 -0700</pubDate><guid>https://www.jamessimas.com/posts/2025/enums-in-go-marshal-and-unmarshal/</guid><description>&lt;p&gt;My &lt;a href="https://www.jamessimas.com/posts/enums-in-go/"&gt;blog post&lt;/a&gt; from yesterday made me think&amp;hellip; how can you marshal and unmarshal enums in Go correctly?&lt;/p&gt;
&lt;p&gt;So I modified &lt;code&gt;internal/coffee/coffee.go&lt;/code&gt; and added a &lt;code&gt;MarshalText()&lt;/code&gt; and &lt;code&gt;UnmarshalText()&lt;/code&gt; methods:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;coffee&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;strings&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//go:generate stringer -linecomment -type=Coffee&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;type&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Coffee&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Drip&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Coffee&lt;/span&gt; = &lt;span style="color:#66d9ef"&gt;iota&lt;/span&gt; &lt;span style="color:#75715e"&gt;// drip coffee&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Latte&lt;/span&gt; &lt;span style="color:#75715e"&gt;// latte&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Breve&lt;/span&gt; &lt;span style="color:#75715e"&gt;// breve&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Cappuccino&lt;/span&gt; &lt;span style="color:#75715e"&gt;// cappuccino&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Coffee&lt;/span&gt;) &lt;span style="color:#a6e22e"&gt;MarshalText&lt;/span&gt;() ([]&lt;span style="color:#66d9ef"&gt;byte&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;error&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; []byte(&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;String&lt;/span&gt;()), &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Coffee&lt;/span&gt;) &lt;span style="color:#a6e22e"&gt;UnmarshalText&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;text&lt;/span&gt; []&lt;span style="color:#66d9ef"&gt;byte&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;error&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;want&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; string(&lt;span style="color:#a6e22e"&gt;text&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &amp;lt; len(&lt;span style="color:#a6e22e"&gt;_Coffee_index&lt;/span&gt;)&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;_Coffee_name&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;_Coffee_index&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;]:&lt;span style="color:#a6e22e"&gt;_Coffee_index&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;+&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;]]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;strings&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;EqualFold&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;want&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt; = &lt;span style="color:#a6e22e"&gt;Coffee&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Errorf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;invalid Coffee %q&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;want&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I then modified &lt;code&gt;main.go&lt;/code&gt; to add a new type named &lt;code&gt;Drink&lt;/code&gt; which expected a &lt;code&gt;Coffee&lt;/code&gt; in its field:&lt;/p&gt;</description></item><item><title>Enums in Go</title><link>https://www.jamessimas.com/posts/2025/enums-in-go/</link><pubDate>Wed, 14 May 2025 10:37:47 -0700</pubDate><guid>https://www.jamessimas.com/posts/2025/enums-in-go/</guid><description>&lt;p&gt;I was asked yesterday how you implement enums in Go. I didn&amp;rsquo;t know, so I spent some time this morning learning how to do it.&lt;/p&gt;
&lt;p&gt;It turns out this is ridiculously easy to do and Go has the &lt;a href="https://pkg.go.dev/golang.org/x/tools/cmd/stringer"&gt;stringer&lt;/a&gt; tool which makes it super simple. (stringer codegens the code which prints your enum as a string.)&lt;/p&gt;
&lt;h2 id="example"&gt;Example&lt;/h2&gt;
&lt;p&gt;I created a &lt;a href="https://github.com/jamessimas/goenumtest/tree/main"&gt;repo&lt;/a&gt; with the following structure:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;go.mod
main.go
internal/coffee/coffee.go
internal/coffee/coffee_string.go
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;internal/coffee/coffee.go&lt;/code&gt; looks like this:&lt;/p&gt;</description></item><item><title>Workflow Musings</title><link>https://www.jamessimas.com/posts/2025/workflow-musings/</link><pubDate>Mon, 05 May 2025 20:25:44 -0700</pubDate><guid>https://www.jamessimas.com/posts/2025/workflow-musings/</guid><description>&lt;h2 id="getting-things-ready-in-advance"&gt;Getting things ready in advance&lt;/h2&gt;
&lt;p&gt;I&amp;rsquo;ve been musing on how ridiculously useful it is to get things ready in advance. Especially the day before.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Examples:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Setting my workout clothes out. (I&amp;rsquo;m more likely to workout.)&lt;/li&gt;
&lt;li&gt;Packing my backpack with everything I need for work in the morning. (No hunting around in the morning for stuff when my brain is waking up and wasting 15 minutes or getting frustrated.)&lt;/li&gt;
&lt;li&gt;Setting everything I need to shower and brush my teeth &lt;em&gt;after&lt;/em&gt; late-night roller skating in the guest bathroom. (So I can shower there and not wake up my wife.)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It can sometimes feel silly in the moment, but I&amp;rsquo;ve found it makes it a lot easier to get the outcomes I want in life (e.g., working out, leaving on time, etc.)&lt;/p&gt;</description></item><item><title>Weekly planning sessions</title><link>https://www.jamessimas.com/posts/2025/weekly-planning-sessions/</link><pubDate>Sat, 01 Feb 2025 09:19:32 -0700</pubDate><guid>https://www.jamessimas.com/posts/2025/weekly-planning-sessions/</guid><description>&lt;p&gt;I&amp;rsquo;ve been doing a weekly planning session for the last five or so years. It is one of the most helpful things I do to organize my life, keep myself physically healthy, and moving forward.&lt;/p&gt;
&lt;p&gt;This process has become even more valuable to me since having a child, as I am now responsible for a lot more and time is more scarce.&lt;/p&gt;
&lt;p&gt;In this post, I&amp;rsquo;ll describe what I do, why it&amp;rsquo;s useful, and how I do it.&lt;/p&gt;</description></item><item><title>Go Test Parallelism</title><link>https://www.jamessimas.com/posts/2024/go-test-parallelism/</link><pubDate>Fri, 18 Oct 2024 07:52:50 -0700</pubDate><guid>https://www.jamessimas.com/posts/2024/go-test-parallelism/</guid><description>&lt;p&gt;This post documents some testing I did around whether unit tests in Golang are run in parallel.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;TLDR:&lt;/strong&gt; Tests in a given package run serially, unless &lt;code&gt;t.Parallel()&lt;/code&gt; is specified.&lt;/p&gt;
&lt;p&gt;To test this, I created two files in a directory named &lt;code&gt;gotest&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ ls
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;one_test.go two_test.go
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// one_test.go&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;testing&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;time&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;TestOne&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;t&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;testing&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;T&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;1 starts:&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Now&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;String&lt;/span&gt;())
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Sleep&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Second&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;1 ends:&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Now&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;String&lt;/span&gt;())
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// two_test.go&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;testing&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;time&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;TestTwo&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;t&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;testing&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;T&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;2 starts:&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Now&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;String&lt;/span&gt;())
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;2 ends:&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Now&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;String&lt;/span&gt;())
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When I ran the tests, you can see that &lt;code&gt;TestOne&lt;/code&gt; blocked &lt;code&gt;TestTwo&lt;/code&gt; from running for five seconds:&lt;/p&gt;</description></item><item><title>Go sub-slice gotchas</title><link>https://www.jamessimas.com/posts/2024/go-subslice-gotchas/</link><pubDate>Sun, 11 Aug 2024 07:30:15 -0700</pubDate><guid>https://www.jamessimas.com/posts/2024/go-subslice-gotchas/</guid><description>&lt;p&gt;Thanks to &lt;a href="https://jvns.ca/blog/2024/08/06/go-structs-copied-on-assignment/"&gt;Julia Evan&amp;rsquo;s latest post&lt;/a&gt;, I learned that creating new slices by sub-slicing an existing slice has an important caveat: They can sometimes use the same backing array! 😬&lt;/p&gt;
&lt;p&gt;This is important to understand if you mutate the sub-slice.&lt;/p&gt;
&lt;p&gt;Take the below example, wherein we accidentally mutate &lt;code&gt;s1&lt;/code&gt;!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;s1&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; []&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;{&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;} &lt;span style="color:#75715e"&gt;// len == 6, capacity == 6&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;s2&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;s1&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;:&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;] &lt;span style="color:#75715e"&gt;// len == 4, capacity == 5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Modifies both s1 and s2, because they share the same backing array.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;s2&lt;/span&gt;[&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;] = &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Modifies both s1 and s2, because the length of s2 after adding the new&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// element does not exceed the capacity of the s2 slice.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;s2&lt;/span&gt; = append(&lt;span style="color:#a6e22e"&gt;s2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Modifies only s2, because adding this element increases the length of s2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// beyond the capacity of the s2 slice. This allocats a new backing array,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// copies all elements to it, and then appends 30 to it. So s1 does not get&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// modified.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;s2&lt;/span&gt; = append(&lt;span style="color:#a6e22e"&gt;s2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;30&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;s1&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;s1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;s2&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;s2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Its output is:&lt;/p&gt;</description></item><item><title>Unifi Network Application Upgrade</title><link>https://www.jamessimas.com/posts/2024/unifi-network-application-upgrade/</link><pubDate>Mon, 22 Jul 2024 08:29:44 -0700</pubDate><guid>https://www.jamessimas.com/posts/2024/unifi-network-application-upgrade/</guid><description>&lt;p&gt;I run &lt;a href="https://www.ui.com/"&gt;Unifi&lt;/a&gt; network gear in my house. As I have multiple wireless access points, I use a controller to manage them so clients can seamlessly roam between them.&lt;/p&gt;
&lt;p&gt;I run Unifi&amp;rsquo;s controller software as a Docker container (from &lt;a href="https://fleet.linuxserver.io/image?name=linuxserver/unifi-network-application"&gt;here&lt;/a&gt; and &lt;a href="https://github.com/linuxserver/docker-unifi-network-application"&gt;here&lt;/a&gt;) to save myself from running Yet Another Appliance™ and paying for more hardware. I&amp;rsquo;ve been running v6 for a while, but recently upgraded to v8.&lt;/p&gt;
&lt;p&gt;These are my notes to myself for how I set this up.&lt;/p&gt;</description></item><item><title>Configuring a Git pre-push hook to run unit tests</title><link>https://www.jamessimas.com/posts/2024/git-pre-push-hook/</link><pubDate>Wed, 26 Jun 2024 10:42:46 -0700</pubDate><guid>https://www.jamessimas.com/posts/2024/git-pre-push-hook/</guid><description>&lt;p&gt;A coworker turned me onto this lovely technique the other day. You can use a git pre-push hook to run all of your Golang unit tests before pushing.&lt;/p&gt;
&lt;p&gt;To do this, make a the following file: &lt;code&gt;$YOUR_REPO/.git/hooks/pre-push&lt;/code&gt; The file must be executable.&lt;/p&gt;
&lt;p&gt;The file&amp;rsquo;s contents should be:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#!/bin/sh
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; ! go test ./... ; &lt;span style="color:#66d9ef"&gt;then&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; echo
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; echo &lt;span style="color:#e6db74"&gt;&amp;#34;Rejecting commit. Unit tests failed.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; echo
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; exit &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;fi&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Easy peasy.&lt;/p&gt;</description></item><item><title>How to care for your Invisalign braces</title><link>https://www.jamessimas.com/posts/2024/how-to-care-for-your-invisalign-braces/</link><pubDate>Sun, 14 Apr 2024 08:42:56 -0700</pubDate><guid>https://www.jamessimas.com/posts/2024/how-to-care-for-your-invisalign-braces/</guid><description>&lt;p&gt;I wore Invisalign braces from January of 2022 to early 2023. They require a lot of brushing and maintenance while wearing them.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a few things I did along the way which made that easier.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;1. Create brushing stations&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;You&amp;rsquo;re going to brush and floss a lot. (Like a lot.) Anytime you eat or drink anything besides water you must remove the Invisalign trays, brush your teeth and trays, and then floss.&lt;/p&gt;</description></item><item><title>Using git worktrees</title><link>https://www.jamessimas.com/posts/2024/git-worktree/</link><pubDate>Wed, 27 Mar 2024 10:33:49 -0700</pubDate><guid>https://www.jamessimas.com/posts/2024/git-worktree/</guid><description>&lt;p&gt;Have you ever been developing on a feature branch and needed to look at a separate branch on the same repo?&lt;/p&gt;
&lt;p&gt;I have.&lt;/p&gt;
&lt;p&gt;When this happens, I normally do one of two things:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;git stash&lt;/code&gt; my changes and change branches
&lt;ul&gt;
&lt;li&gt;This is annoying because it&amp;rsquo;s a lot of steps.&lt;/li&gt;
&lt;li&gt;I also have to remember which stash to pop when I come back to this branch.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Stage all my changes and store them in a work-in-progress commit
&lt;ul&gt;
&lt;li&gt;This is better than #1 but doesn&amp;rsquo;t let you view both branches simultaneously.&lt;/li&gt;
&lt;li&gt;But it&amp;rsquo;s still annoying if you have files you haven&amp;rsquo;t staged yet and don&amp;rsquo;t want to stage yet.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Both these have drawbacks. For example, they don&amp;rsquo;t let me look at both branches at the same time in my text editor.&lt;/p&gt;</description></item><item><title>How my digital life is backed up</title><link>https://www.jamessimas.com/posts/2024/how-my-digital-life-is-backed-up/</link><pubDate>Fri, 22 Mar 2024 20:30:01 -0700</pubDate><guid>https://www.jamessimas.com/posts/2024/how-my-digital-life-is-backed-up/</guid><description>&lt;p&gt;Derek Sivers recently wrote a &lt;a href="https://sive.rs/backup"&gt;post&lt;/a&gt; explaining how he backups his computers. His post inspired me to improve my own backup strategy and also to write this post.&lt;/p&gt;
&lt;h2 id="my-computer"&gt;My computer&lt;/h2&gt;
&lt;p&gt;I only have two personal computers whose data I care about; my Macbook Pro and my wife&amp;rsquo;s Macbook Air. The strategies for backing these up are the same, so I&amp;rsquo;ll just talk about my computer.&lt;/p&gt;
&lt;p&gt;It has a lot of important things: files, videos, photos, personal code, and more. I&amp;rsquo;d be pretty sad and set back if I lost all of it. So I&amp;rsquo;m pretty exhaustive about my backup strategy, but it ends up taking very little of my personal time because most of it happens with little thought on my part.&lt;/p&gt;</description></item><item><title>About</title><link>https://www.jamessimas.com/about/</link><pubDate>Tue, 12 Mar 2024 19:58:00 -0800</pubDate><guid>https://www.jamessimas.com/about/</guid><description>&lt;p&gt;I am a lifelong learner working in lovely Seattle, Washington as a software developer.&lt;/p&gt;
&lt;p&gt;I write services, tooling, and automation in Golang and Python to help manage a security-related cloud service. When I&amp;rsquo;m not at work, I can generally be found reading, working out, biking, and generally trying to improve myself or learn something new.&lt;/p&gt;
&lt;p&gt;See what I&amp;rsquo;m up to &lt;a href="https://www.jamessimas.com/now"&gt;now&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="favorite-things"&gt;Favorite things&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Software:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.sublimetext.com/"&gt;Sublime Text&lt;/a&gt; - best text editor on the market&lt;/li&gt;
&lt;li&gt;&lt;a href="https://culturedcode.com/things/"&gt;Things 3&lt;/a&gt; - best todo list I&amp;rsquo;ve found&lt;/li&gt;
&lt;li&gt;&lt;a href="https://flexibits.com/fantastical"&gt;Fantastical&lt;/a&gt; - the only calendar app you need&lt;/li&gt;
&lt;li&gt;&lt;a href="https://bear.app/"&gt;Bear&lt;/a&gt; - polished markdown notes&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Hardware:&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>Running a subset of Go tests</title><link>https://www.jamessimas.com/posts/2024/running-a-subset-of-go-tests/</link><pubDate>Thu, 07 Mar 2024 12:33:05 -0800</pubDate><guid>https://www.jamessimas.com/posts/2024/running-a-subset-of-go-tests/</guid><description>&lt;p&gt;It is often useful to run a subset of the tests in a Go project. You might do this because you only want to see test results for one package or to run tests faster.&lt;/p&gt;
&lt;p&gt;For these examples, assume your project is a Go module named &lt;code&gt;examplemodule&lt;/code&gt;. It has the following structure:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;examplemodule
|_ go.mod
|_ go.sum
|_ internal
|_ foo
| |_ foo.go
| |_ foo_test.go
|_ bar
|_ bar.go
|_ bar_test.go
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here&amp;rsquo;s the most useful techniques I use to do this:&lt;/p&gt;</description></item><item><title>Max and min integer values in Golang</title><link>https://www.jamessimas.com/posts/2024/golang-max-and-minimum-int-values/</link><pubDate>Tue, 05 Mar 2024 14:32:02 -0800</pubDate><guid>https://www.jamessimas.com/posts/2024/golang-max-and-minimum-int-values/</guid><description>&lt;p&gt;Today I needed to use the maximum unsigned 64-bit integer value possible in Golang.&lt;/p&gt;
&lt;p&gt;Here is a short program I wrote with some help from &lt;a href="https://stackoverflow.com/questions/6878590/"&gt;Stack Overflow&lt;/a&gt; to help me remember how to calculate these without any dependencies.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;minUint32&lt;/span&gt; = uint32(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;maxUint32&lt;/span&gt; = ^uint32(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;minUint64&lt;/span&gt; = uint64(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;maxUint64&lt;/span&gt; = ^uint64(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;minInt32&lt;/span&gt; = int32(&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;maxInt32&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;maxInt32&lt;/span&gt; = int32(&lt;span style="color:#a6e22e"&gt;maxUint32&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;minInt64&lt;/span&gt; = int64(&lt;span style="color:#f92672"&gt;-&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;maxInt64&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;maxInt64&lt;/span&gt; = int64(&lt;span style="color:#a6e22e"&gt;maxUint64&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;details&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;numeric&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int32&lt;/span&gt; | &lt;span style="color:#66d9ef"&gt;int64&lt;/span&gt; | &lt;span style="color:#66d9ef"&gt;uint32&lt;/span&gt; | &lt;span style="color:#66d9ef"&gt;uint64&lt;/span&gt;](&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;num&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;numeric&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;%9s -&amp;gt; dec: %21d\tbin: %65b\n&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;num&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;num&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;details&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;minUint32&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;minUint32&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;details&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;maxUint32&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;maxUint32&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;details&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;minUint64&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;minUint64&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;details&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;maxUint64&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;maxUint64&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;details&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;minInt32&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;minInt32&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;details&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;maxInt32&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;maxInt32&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;details&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;minInt64&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;minInt64&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;details&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;maxInt64&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;maxInt64&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Running that shows:&lt;/p&gt;</description></item><item><title>Using 'git commit --fixup'</title><link>https://www.jamessimas.com/posts/2024/using-git-commit-fixup/</link><pubDate>Tue, 20 Feb 2024 09:37:51 -0800</pubDate><guid>https://www.jamessimas.com/posts/2024/using-git-commit-fixup/</guid><description>&lt;p&gt;I learned something new from &lt;a href="https://jvns.ca/blog/2024/02/16/popular-git-config-options/"&gt;Julia Evans&lt;/a&gt; today.&lt;/p&gt;
&lt;p&gt;Git has a &lt;code&gt;--fixup&lt;/code&gt; argument when committing files which makes it easy to create fixup commits which can get automatically squashed when rebasing. This is fantastic!&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve known about &lt;code&gt;git commit --amend&lt;/code&gt; for years, but this allows you to fixup commits which are several commits back without &lt;em&gt;manually&lt;/em&gt; moving a bunch of lines around while interactively rebasing&amp;hellip;&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s assume you have a repo which looks like shown below. &lt;code&gt;696792e9&lt;/code&gt; is our &amp;ldquo;bad&amp;rdquo; commit, which we need to fixup.&lt;/p&gt;</description></item><item><title>Go build tags</title><link>https://www.jamessimas.com/posts/2024/go-build-tags/</link><pubDate>Wed, 03 Jan 2024 07:42:31 -0800</pubDate><guid>https://www.jamessimas.com/posts/2024/go-build-tags/</guid><description>&lt;p&gt;Today I learned about Go build tags. Here&amp;rsquo;s some quick notes to help me remember how to use them.&lt;/p&gt;
&lt;p&gt;Assume you have directory like so:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ ls -1
extra.go
go.mod
main.go
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And &lt;code&gt;main.go&lt;/code&gt; has contents:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;numbers&lt;/span&gt; = []&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;one&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;two&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;_&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;number&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;range&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;numbers&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;number&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And &lt;code&gt;extra.go&lt;/code&gt; has contents:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//go:build extrastuff&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;init&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;numbers&lt;/span&gt; = append(&lt;span style="color:#a6e22e"&gt;numbers&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;three&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;four&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you build without any tags, you get this:&lt;/p&gt;</description></item><item><title>Using gonew to easily create template repos</title><link>https://www.jamessimas.com/posts/2023/using-gonew-to-easily-create-template-repos/</link><pubDate>Thu, 14 Dec 2023 20:11:05 -0800</pubDate><guid>https://www.jamessimas.com/posts/2023/using-gonew-to-easily-create-template-repos/</guid><description>&lt;p&gt;Now that I&amp;rsquo;ve been writing Golang for a while, when I start a new project, I typically know the sort of layout I&amp;rsquo;m looking for.&lt;/p&gt;
&lt;p&gt;I typically go for something like this:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;.
├── cmd
│ └── demo
│ └── main.go
├── go.mod
├── internal
│ └── subpkg
│ ├── subpkg.go
│ └── subpkg_test.go
└── LICENSE
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And often there are lots of ascillary files that go along with this, like Makefiles, CI/CD config files, Dockerfiles, docker-compose files, etc.&lt;/p&gt;</description></item><item><title>Checking an error's type in Golang</title><link>https://www.jamessimas.com/posts/2023/checking-an-errors-type/</link><pubDate>Thu, 07 Dec 2023 07:22:53 -0800</pubDate><guid>https://www.jamessimas.com/posts/2023/checking-an-errors-type/</guid><description>&lt;p&gt;I was not very familiar with checking an error&amp;rsquo;s type in Golang, so I spent a few minutes learning about it today. It turns out that it&amp;rsquo;s incredibly easy to do.&lt;/p&gt;
&lt;p&gt;Running the below code shows the output: &lt;code&gt;2009/11/10 23:00:00 got custom error: err1&lt;/code&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;errors&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;log&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;customErr&lt;/span&gt; = &lt;span style="color:#a6e22e"&gt;errors&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;New&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;err1&amp;#34;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// create a error, identified by its var name&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// oops always returns our custom error. Oops!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;oops&lt;/span&gt;() &lt;span style="color:#66d9ef"&gt;error&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;customErr&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;oops&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;errors&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Is&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;customErr&lt;/span&gt;) { &lt;span style="color:#75715e"&gt;// check error type with errors.Is()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Fatal&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;got custom error: &amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is doing more than just matching the string of the error, as this does &lt;strong&gt;not&lt;/strong&gt; show any output:&lt;/p&gt;</description></item><item><title>Benchmarking Unnecessary Allocations</title><link>https://www.jamessimas.com/posts/2023/benchmarking-unnecessary-allocations/</link><pubDate>Sat, 30 Sep 2023 20:12:53 -0700</pubDate><guid>https://www.jamessimas.com/posts/2023/benchmarking-unnecessary-allocations/</guid><description>&lt;p&gt;I&amp;rsquo;ve also been thinking more about unnecessary allocations in my Go code and how to avoid them by pre-declaring the length of a slice up front.&lt;/p&gt;
&lt;p&gt;Normally, I&amp;rsquo;d write something like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;s&lt;/span&gt; []&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;_&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;val&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;otherSlice&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;s&lt;/span&gt; = append(&lt;span style="color:#a6e22e"&gt;s&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;val&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Since I don&amp;rsquo;t specify the size of &lt;code&gt;s&lt;/code&gt;, if &lt;code&gt;otherSlice&lt;/code&gt; is large, the array underlying &lt;code&gt;s&lt;/code&gt; might not be large enough to hold all the values; then a new array will have to be allocated and (I presume) all existing values copied out of it one at a time to fill the new array.&lt;/p&gt;</description></item><item><title>Templating files with Golang</title><link>https://www.jamessimas.com/posts/2023/golang-templating/</link><pubDate>Tue, 19 Sep 2023 20:47:59 -0700</pubDate><guid>https://www.jamessimas.com/posts/2023/golang-templating/</guid><description>&lt;p&gt;I recently went through &lt;a href="https://www.digitalocean.com/community/tutorials/how-to-use-templates-in-go"&gt;How To Use Templates in Go&lt;/a&gt; to refresh my memory on Golang templates. I was reminded how great they are and learned several things along the way.&lt;/p&gt;
&lt;p&gt;I learned that the below syntaxes are equivalent:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;{{ . | len }}&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{{ (len .) }}&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here is the program I wrote and tweaked along the way, to refresh my memory in the future:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;html/template&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;os&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;strings&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;type&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Pet&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Name&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Sex&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Intact&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;bool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Age&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Breed&lt;/span&gt; []&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;dogs&lt;/span&gt; = []&lt;span style="color:#a6e22e"&gt;Pet&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// This is why you should use html/template and not text/template when&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// rendering HTML. Especially if you don&amp;#39;t trust the source of your&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// data!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;//
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt; // You don&amp;#39;t want the template you render to do (potentially) malicious&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// things in your user&amp;#39;s webbrowser.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Name&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;&amp;lt;script&amp;gt;alert(\&amp;#34;Gotcha!\&amp;#34;);&amp;lt;/script&amp;gt;Jujube&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Sex&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Female&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Intact&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Age&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;10 months&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Breed&lt;/span&gt;: []&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;German Shepherd&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Pitbull&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Name&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Zephyr&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Sex&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Male&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Intact&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Age&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;13 years, 3 months&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Breed&lt;/span&gt;: []&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;German Shepherd&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Border Collie&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Name&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Roger&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Sex&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Male&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Intact&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Age&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;9 years, 7 months&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Breed&lt;/span&gt;: []&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;German Shepherd&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Border Collie&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Name&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Missi&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Sex&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;Female&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Intact&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Age&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#34;99 years, 2 months&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;Breed&lt;/span&gt;: []&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Teacup Poodle&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// This is how you add functions to your template. You can add functions from&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// other packages or define them inline here.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;//
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// See petsHtml.tmpl for an example of using &amp;#34;join&amp;#34;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;funcMap&lt;/span&gt; = &lt;span style="color:#a6e22e"&gt;template&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;FuncMap&lt;/span&gt;{
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;dec&amp;#34;&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;func&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt; { &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; }, &lt;span style="color:#75715e"&gt;// Inline!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;replace&amp;#34;&lt;/span&gt;: &lt;span style="color:#a6e22e"&gt;strings&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;ReplaceAll&lt;/span&gt;, &lt;span style="color:#75715e"&gt;// Other package!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;join&amp;#34;&lt;/span&gt;: &lt;span style="color:#a6e22e"&gt;strings&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Join&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Create Template, add functions, and load template files.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;tmpl&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;template&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;New&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;Funcs&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;funcMap&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;ParseGlob&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;*.tmpl&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt; &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; panic(&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Create a file.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;f&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;os&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;File&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;f&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt; = &lt;span style="color:#a6e22e"&gt;os&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Create&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;pets.html&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt; &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; panic(&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;defer&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;f&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Close&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;// Execute a template by name with data &amp;#34;dogs&amp;#34; and write to writer &amp;#34;f&amp;#34;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt; = &lt;span style="color:#a6e22e"&gt;tmpl&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;ExecuteTemplate&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;f&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;petsHtml.tmpl&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;dogs&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;err&lt;/span&gt; &lt;span style="color:#f92672"&gt;!=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; panic(&lt;span style="color:#a6e22e"&gt;err&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;And here are the files I wrote and tweaked along the way:&lt;/p&gt;</description></item><item><title>Goroutines outlive their calling function</title><link>https://www.jamessimas.com/posts/2023/goroutines-outlive-their-calling-function/</link><pubDate>Mon, 18 Sep 2023 09:37:32 -0700</pubDate><guid>https://www.jamessimas.com/posts/2023/goroutines-outlive-their-calling-function/</guid><description>&lt;p&gt;While watching &lt;a href="https://www.youtube.com/watch?v=f6kdp27TYZs&amp;amp;t=1060s"&gt;a talk by Rob Pike&lt;/a&gt; I learned today something about Goroutines which surprised me: Goroutines outlive their calling function.&lt;/p&gt;
&lt;p&gt;Said another way, if the function which created the goroutine returns, the goroutine will continue running. (&lt;code&gt;main()&lt;/code&gt; is the one exception.) This is fantastic! 🎉&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an example of this in practice.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;time&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;person&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;msg&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;) &lt;span style="color:#f92672"&gt;&amp;lt;-&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;chan&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt; { &lt;span style="color:#75715e"&gt;// Function returns a receive-only channel&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;ch&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; make(&lt;span style="color:#66d9ef"&gt;chan&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// Create unbuffered channel&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;go&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;func&lt;/span&gt;() { &lt;span style="color:#75715e"&gt;// This goroutine lives on after person() returns&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; ; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Sleep&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Duration&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;rand&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Intn&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;1e3&lt;/span&gt;)) &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Millisecond&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;ch&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Sprintf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;%s %d&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;msg&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;ch&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;james&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;person&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;james&amp;#34;&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// Assign returned channel to variable&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;sinah&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;person&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;sinah&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &amp;lt; &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#f92672"&gt;&amp;lt;-&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;james&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// Block, waiting for value on channel&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#f92672"&gt;&amp;lt;-&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;sinah&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Done!&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Output:&lt;/p&gt;</description></item><item><title>Getting the Git Commit in Go</title><link>https://www.jamessimas.com/posts/2023/getting-the-git-commit-in-go/</link><pubDate>Fri, 01 Sep 2023 17:28:13 -0700</pubDate><guid>https://www.jamessimas.com/posts/2023/getting-the-git-commit-in-go/</guid><description>&lt;p&gt;&lt;a href="https://go.dev/doc/go1.18#debug/buildinfo"&gt;Go 1.18&lt;/a&gt; added a feature to easily get the Git commit version that the binary was built from.&lt;/p&gt;
&lt;p&gt;This is so much easier than the old way of doing it! 🎉&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;runtime/debug&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;info&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;_&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;debug&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;ReadBuildInfo&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;_&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;setting&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;range&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;info&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Settings&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;setting&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Key&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;vcs.revision&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;||&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;setting&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Key&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;vcs.time&amp;#34;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;%s:\t%s\n&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;setting&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Key&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;setting&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Value&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-plain" data-lang="plain"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ go build git-version
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ ./git-version
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;vcs.revision: 4d47dd39d1debbdf10715fd9ff967e09d4347f02
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;vcs.time: 2023-09-02T00:21:21Z
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;More info &lt;a href="https://shibumi.dev/posts/go-18-feature/"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;blockquote class="github-alert github-alert-warning"&gt;
&lt;div class="github-alert-title"&gt;warning&lt;/div&gt;
&lt;div class="github-alert-content"&gt;&lt;p&gt;For this to work, you must build with &lt;code&gt;go build -o ./build/foo&lt;/code&gt;. Using &lt;code&gt;go build -o ./build/foo/main.go&lt;/code&gt; will not work.&lt;/p&gt;</description></item><item><title>Waiting for data from a Go channel with a timeout</title><link>https://www.jamessimas.com/posts/2023/wait-for-data-from-go-channels/</link><pubDate>Fri, 01 Sep 2023 09:19:32 -0700</pubDate><guid>https://www.jamessimas.com/posts/2023/wait-for-data-from-go-channels/</guid><description>&lt;p&gt;The other day I ran into a situation where I wanted my function to block until it received data from a Go channel. But I didn&amp;rsquo;t want it to block indefinitely. I wanted it to timeout after a few seconds if it didn&amp;rsquo;t get any data.&lt;/p&gt;
&lt;p&gt;My coworker Dan showed me a technique I didn&amp;rsquo;t know about to easily accomplish this. It wasn&amp;rsquo;t surprising to learn how easy it was, given that Go has strong support for concurrency out the gate.&lt;/p&gt;</description></item><item><title>Blocking with Channels in Go</title><link>https://www.jamessimas.com/posts/2023/blocking-with-channels-in-go/</link><pubDate>Thu, 17 Aug 2023 21:00:44 -0700</pubDate><guid>https://www.jamessimas.com/posts/2023/blocking-with-channels-in-go/</guid><description>&lt;h2 id="example-1"&gt;Example 1&lt;/h2&gt;
&lt;p&gt;In the below code, &lt;code&gt;&amp;lt;-messages&lt;/code&gt; will block until it gets something on the channel.
This prevents &lt;code&gt;main()&lt;/code&gt; from exiting until one item is received on the channel.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;time&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;waitThenSend&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;msg&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;chan&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Sleep&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Second&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;msg&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;-&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;badwolf&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;messages&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; make(&lt;span style="color:#66d9ef"&gt;chan&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// make unbuffered channel&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;go&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;func&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;waitThenSend&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;messages&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// make goroutine, pass in channel&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;-&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;messages&lt;/span&gt; &lt;span style="color:#75715e"&gt;// blocks until channel receives a value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;done&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="example-2"&gt;Example 2&lt;/h2&gt;
&lt;p&gt;The below example demonstrates using a &lt;code&gt;sync.WaitGroup&lt;/code&gt;to keep the program running until all of the goroutines have exited. Data is sent to the function via the unbuffered channel named &lt;code&gt;numbers&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Easy templating with Python and Jinja</title><link>https://www.jamessimas.com/posts/2023/easy-templating-with-python-and-jinja2/</link><pubDate>Tue, 04 Jul 2023 15:19:23 -0700</pubDate><guid>https://www.jamessimas.com/posts/2023/easy-templating-with-python-and-jinja2/</guid><description>&lt;p&gt;At work, I&amp;rsquo;ve been using both Golang and Ruby to render Nomad jobspec files in a consistent manner across environments.&lt;/p&gt;
&lt;p&gt;But Python is my one true love and I wanted to learn how to do it in Python. Turns out I already knew how&amp;hellip; you can do it in Jinja2!&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve used Jinja2 in the past a lot for Django and Ansible, so this was pretty easy to pick up. Here are some notes for future me when I want to inevitably do this again.&lt;/p&gt;</description></item><item><title>Latency Numbers Every Programmer Should Know</title><link>https://www.jamessimas.com/posts/2023/latency-numbers-every-programmer-should-know/</link><pubDate>Sat, 24 Jun 2023 08:34:08 -0700</pubDate><guid>https://www.jamessimas.com/posts/2023/latency-numbers-every-programmer-should-know/</guid><description>&lt;p&gt;These are useful and I&amp;rsquo;m putting them here so I can find them easily wherever I am.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Latency Comparison Numbers (~2012)
----------------------------------
L1 cache reference 0.5 ns
Branch mispredict 5 ns
L2 cache reference 7 ns 14x L1 cache
Mutex lock/unlock 25 ns
Main memory reference 100 ns 20x L2 cache, 200x L1 cache
Compress 1K bytes with Zippy 3,000 ns 3 us
Send 1K bytes over 1 Gbps network 10,000 ns 10 us
Read 4K randomly from SSD* 150,000 ns 150 us ~1GB/sec SSD
Read 1 MB sequentially from memory 250,000 ns 250 us
Round trip within same datacenter 500,000 ns 500 us
Read 1 MB sequentially from SSD* 1,000,000 ns 1,000 us 1 ms ~1GB/sec SSD, 4X memory
Disk seek 10,000,000 ns 10,000 us 10 ms 20x datacenter roundtrip
Read 1 MB sequentially from disk 20,000,000 ns 20,000 us 20 ms 80x memory, 20X SSD
Send packet CA-&amp;gt;Netherlands-&amp;gt;CA 150,000,000 ns 150,000 us 150 ms
Notes
-----
1 ns = 10^-9 seconds
1 us = 10^-6 seconds = 1,000 ns
1 ms = 10^-3 seconds = 1,000 us = 1,000,000 ns
Credit
------
By Jeff Dean: http://research.google.com/people/jeff/
Originally by Peter Norvig: http://norvig.com/21-days.html#answers
Contributions
-------------
&amp;#39;Humanized&amp;#39; comparison: https://gist.github.com/hellerbarde/2843375
Visual comparison chart: http://i.imgur.com/k0t1e.png
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Source: &lt;a href="https://gist.github.com/jboner/2841832"&gt;https://gist.github.com/jboner/2841832&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Python dataclasses are awesome!</title><link>https://www.jamessimas.com/posts/2023/python-dataclass/</link><pubDate>Mon, 22 May 2023 19:46:10 -0700</pubDate><guid>https://www.jamessimas.com/posts/2023/python-dataclass/</guid><description>&lt;p&gt;Last week, I was working on some Python at work and I found myself wishing for an equivalent to Golang&amp;rsquo;s structs. Rather than passing in a bunch of core data types (string, dict, int, etc.) in an out of methods, I wanted to pass in a single object with predictable attributes. But&amp;hellip;. I didn&amp;rsquo;t want to go through all the trouble of creating a class with a constructor, and passing in all the various attributes.&lt;/p&gt;</description></item><item><title>nil maps in Golang</title><link>https://www.jamessimas.com/posts/2023/nil-maps-golang/</link><pubDate>Sat, 07 Jan 2023 11:38:06 -0800</pubDate><guid>https://www.jamessimas.com/posts/2023/nil-maps-golang/</guid><description>&lt;p&gt;I&amp;rsquo;ve been a bit confused for a while over when a map in Golang gets created with a value of &lt;code&gt;nil&lt;/code&gt; (its zero value) and when it does not, so I&amp;rsquo;m writing this to help me remember.&lt;/p&gt;
&lt;p&gt;Let&amp;rsquo;s look at various ways to initialize a map:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;m1&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;map&lt;/span&gt;[&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;]&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;{} &lt;span style="color:#75715e"&gt;// initializes map&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;m2&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; make(&lt;span style="color:#66d9ef"&gt;map&lt;/span&gt;[&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;]&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// also initializes map&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;m3&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;map&lt;/span&gt;[&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;]&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt; &lt;span style="color:#75715e"&gt;// does NOT initialize the map! HERE BE DRAGONS!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;m1&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;m2&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;m3&lt;/span&gt; &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;m1&lt;/span&gt;[&lt;span style="color:#e6db74"&gt;&amp;#34;foo&amp;#34;&lt;/span&gt;] = &lt;span style="color:#e6db74"&gt;&amp;#34;bar&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;m2&lt;/span&gt;[&lt;span style="color:#e6db74"&gt;&amp;#34;foo&amp;#34;&lt;/span&gt;] = &lt;span style="color:#e6db74"&gt;&amp;#34;bar&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;m3&lt;/span&gt;[&lt;span style="color:#e6db74"&gt;&amp;#34;foo&amp;#34;&lt;/span&gt;] = &lt;span style="color:#e6db74"&gt;&amp;#34;bar&amp;#34;&lt;/span&gt; &lt;span style="color:#75715e"&gt;// panics because the map is NOT initialized, i.e., map is still nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;My takeaways from this are:&lt;/p&gt;</description></item><item><title>Thoughts on travel to Hawaii</title><link>https://www.jamessimas.com/posts/2022/thoughts-on-travel/</link><pubDate>Tue, 08 Nov 2022 10:19:58 -1000</pubDate><guid>https://www.jamessimas.com/posts/2022/thoughts-on-travel/</guid><description>&lt;p&gt;My wife and I recently went to the Hawaiin islands for a few days for a vacatoin. Here&amp;rsquo;s what worked well and didn&amp;rsquo;t well about the trip.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Resorts&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;We stayed in resorts for the first time. This was new; normally we stay in Airbnbs or the like.&lt;/p&gt;
&lt;p&gt;Pros:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Consistent experience.&lt;/li&gt;
&lt;li&gt;Clean and nice.&lt;/li&gt;
&lt;li&gt;Pools and hottubs.&lt;/li&gt;
&lt;li&gt;Safe. We felt very good leaving laptops and the like in the room.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Cons:&lt;/p&gt;</description></item><item><title>Built-in Go HTTP server</title><link>https://www.jamessimas.com/posts/2022/built-in-go-http-server/</link><pubDate>Fri, 14 Oct 2022 13:37:26 -0700</pubDate><guid>https://www.jamessimas.com/posts/2022/built-in-go-http-server/</guid><description>&lt;p&gt;Go has a built-in HTTP server in &lt;code&gt;net/http&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s me playing around using it:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;net/http&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;strings&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;hello&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;w&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;ResponseWriter&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;req&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Request&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Fprintf&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;w&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;hello\n&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;details&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;w&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;ResponseWriter&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;req&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Request&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;resp&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; []&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;{}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;resp&lt;/span&gt; = append(&lt;span style="color:#a6e22e"&gt;resp&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;Request Details:&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;resp&lt;/span&gt; = append(&lt;span style="color:#a6e22e"&gt;resp&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Sprintf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;- Request proto: %s&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;req&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Proto&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;resp&lt;/span&gt; = append(&lt;span style="color:#a6e22e"&gt;resp&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Sprintf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;- Headers:&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;val&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;range&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;req&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Header&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;resp&lt;/span&gt; = append(&lt;span style="color:#a6e22e"&gt;resp&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Sprintf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;\t- %s: %s&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;val&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;resp&lt;/span&gt; = append(&lt;span style="color:#a6e22e"&gt;resp&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Fprintf&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;w&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;strings&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Join&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;resp&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;HandleFunc&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/hello&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;hello&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;HandleFunc&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/details&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;details&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Started.&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;http&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;ListenAndServe&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;127.0.0.1:9999&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Exiting.&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&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;/details&lt;/code&gt; endpoint returns interesting stuff about the HTTP request, like its protocol and headers:&lt;/p&gt;</description></item><item><title>Fixing: File is not `goimports`-ed (goimports)</title><link>https://www.jamessimas.com/posts/2022/file-not-goimported/</link><pubDate>Wed, 05 Oct 2022 16:09:26 -0700</pubDate><guid>https://www.jamessimas.com/posts/2022/file-not-goimported/</guid><description>&lt;p&gt;The other day, I was linting my Go code with &lt;a href="https://golangci-lint.run/"&gt;golangci-lint&lt;/a&gt; when I got this error:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-text" data-lang="text"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;File is not `goimports`-ed (goimports)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I examined the file and found nothing amiss, but the linter insisted something was wrong.&lt;/p&gt;
&lt;p&gt;Eventually, I realized I had used spaces to indent the file rather than tabs. Changing the indent character to tabs fixed it.&lt;/p&gt;
&lt;p&gt;I then ran into the same error on a second file. This time, I had a comment which was wrong. There were two spaces before the first word in the comment (see below).&lt;/p&gt;</description></item><item><title>Linux load average</title><link>https://www.jamessimas.com/posts/2022/load-average/</link><pubDate>Fri, 16 Sep 2022 14:48:56 -0700</pubDate><guid>https://www.jamessimas.com/posts/2022/load-average/</guid><description>&lt;p&gt;This post documents the high level concepts I need to remember about *nix Load Average.&lt;/p&gt;
&lt;p&gt;Load average can been seen in the output of &lt;code&gt;uptime&lt;/code&gt; and &lt;code&gt;top&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;From &lt;code&gt;uptime&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ uptime
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;14:40 up &lt;span style="color:#ae81ff"&gt;21&lt;/span&gt; days, 21:48, &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt; users, load averages: 2.63 2.75 3.45
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;From &lt;code&gt;top&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;root@blog-server-2:~# top -n &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; | head -2
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;top - 15:28:37 up &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt; days, 12:41, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; user, load average: 0.04, 0.03, 0.00
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Tasks: &lt;span style="color:#ae81ff"&gt;95&lt;/span&gt; total, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; running, &lt;span style="color:#ae81ff"&gt;94&lt;/span&gt; sleeping, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; stopped, &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; zombie
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;root@blog-server-2:~#
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There are 3 decimal numbers shown. They present the load average over three different time scales:&lt;/p&gt;</description></item><item><title>Using entr to get immediate test feedback</title><link>https://www.jamessimas.com/posts/2022/using-entr-to-get-immediate-test-feedback/</link><pubDate>Wed, 07 Sep 2022 15:27:15 -0700</pubDate><guid>https://www.jamessimas.com/posts/2022/using-entr-to-get-immediate-test-feedback/</guid><description>&lt;h2 id="old-and-new-workflows"&gt;Old and new workflows&lt;/h2&gt;
&lt;p&gt;My dev workflow used to look like this:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Write some code and save it&lt;/li&gt;
&lt;li&gt;Change to my Terminal window&lt;/li&gt;
&lt;li&gt;Up-arrow to find my command to run unit tests (typically &lt;code&gt;make test&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Press Enter&lt;/li&gt;
&lt;li&gt;Wait for tests to run and examine test output&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;This worked pretty well, but was a lot of manual steps when you figure that I did this dozens (hundreds?) of times per day. That&amp;rsquo;s a lot of energy spent doing the same thing over and over again.&lt;/p&gt;</description></item><item><title>Go and pass by value</title><link>https://www.jamessimas.com/posts/2022/go-and-pass-by-value/</link><pubDate>Thu, 01 Sep 2022 18:25:35 -0700</pubDate><guid>https://www.jamessimas.com/posts/2022/go-and-pass-by-value/</guid><description>&lt;p&gt;Go normally uses pass-by-value for function calls. When you pass a variable into a function or method, Go will (under the hood) create a new variable, copy the old variable&amp;rsquo;s value into it, and then pass the new variable (not the original variable) into the function or method.&lt;/p&gt;
&lt;h2 id="non-pointer-values"&gt;Non-pointer values&lt;/h2&gt;
&lt;p&gt;These types behave as described above and are sometimes called non-pointer values:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Strings&lt;/li&gt;
&lt;li&gt;Ints&lt;/li&gt;
&lt;li&gt;Floats&lt;/li&gt;
&lt;li&gt;Booleans&lt;/li&gt;
&lt;li&gt;Arrays&lt;/li&gt;
&lt;li&gt;Structs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here&amp;rsquo;s an example of how these work. Note that the variables &lt;code&gt;myString&lt;/code&gt; and &lt;code&gt;si&lt;/code&gt; do not point to the same memory address:&lt;/p&gt;</description></item><item><title>Constants in Go</title><link>https://www.jamessimas.com/posts/2022/constants-in-go/</link><pubDate>Tue, 16 Aug 2022 08:49:12 -0700</pubDate><guid>https://www.jamessimas.com/posts/2022/constants-in-go/</guid><description>&lt;h4 id="constants-syntax"&gt;Constants syntax&lt;/h4&gt;
&lt;p&gt;I always have a hard time remembering the syntax of declaring constants in Go. So here&amp;rsquo;s some reminders to myself.&lt;/p&gt;
&lt;p&gt;It is possible to declare constants one per line like you&amp;rsquo;d expect. Note that the there are typed and untyped constants as shown here below.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;vermKnid&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt; = &lt;span style="color:#e6db74"&gt;&amp;#34;scram&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;fox&lt;/span&gt; = &lt;span style="color:#e6db74"&gt;&amp;#34;foxes likes loxes&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;vermKnid&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;fox&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But you can also use a constant declaration group, which does the same thing but is easier to read if you&amp;rsquo;re declaring a bunch of constants.&lt;/p&gt;</description></item><item><title>Open a file or folder from the macOS CLI</title><link>https://www.jamessimas.com/posts/2022/open-a-file-or-folder-on-mac-from-the-terminal/</link><pubDate>Tue, 09 Aug 2022 09:20:02 -0700</pubDate><guid>https://www.jamessimas.com/posts/2022/open-a-file-or-folder-on-mac-from-the-terminal/</guid><description>&lt;p&gt;You can open the a file from the macOS CLI with the command &lt;code&gt;open&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;To open a file with the default app, use: &lt;code&gt;open $FILENAME&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;To open the current directory, use: &lt;code&gt;open .&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;To open a specific directory, use &lt;code&gt;open $DIRECTORY_NAME&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;To open a URL, use: &lt;code&gt;open $URL&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Thanks to &lt;a href="https://nicolasbouliane.com/blog/how-to-open-a-file-in-preview-or-finder-from-the-terminal"&gt;this post&lt;/a&gt; for teaching me this.&lt;/p&gt;</description></item><item><title>Python type hints</title><link>https://www.jamessimas.com/posts/2022/python-type-hints/</link><pubDate>Fri, 05 Aug 2022 16:36:39 -0700</pubDate><guid>https://www.jamessimas.com/posts/2022/python-type-hints/</guid><description>&lt;p&gt;After working with Go for a while, one of the biggest drawbacks to Python for me is that the types of parameters to functions and methods are completely opaque without good documentation.&lt;/p&gt;
&lt;p&gt;For example, let&amp;rsquo;s take this silly function right here:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;my_func&lt;/span&gt;(thing1, thing2):
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; print(thing1 &lt;span style="color:#f92672"&gt;+&lt;/span&gt; thing2)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This function will happily accept strings or ints (or floats, for that matter) as input and depending on the type, will do completely separate things!&lt;/p&gt;</description></item><item><title>Mutexes and concurrent access in Go</title><link>https://www.jamessimas.com/posts/2022/mutexes-in-go/</link><pubDate>Fri, 22 Jul 2022 14:49:09 -0700</pubDate><guid>https://www.jamessimas.com/posts/2022/mutexes-in-go/</guid><description>&lt;p&gt;Golang has mutexes (short for mutually exclusion) to manage concurrent access to a shared object via multiple goroutines.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an example (taken from the excellent &lt;a href="https://gobyexample.com/mutexes"&gt;Go by Example: Mutexes&lt;/a&gt;).&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;sync&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;type&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Counter&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;struct&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;mu&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sync&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Mutex&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;count&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;map&lt;/span&gt;[&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;]&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;c&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;Counter&lt;/span&gt;) &lt;span style="color:#a6e22e"&gt;Inc&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;mu&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Lock&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;defer&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;mu&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Unlock&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;c&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;count&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;]&lt;span style="color:#f92672"&gt;++&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;cnt&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Counter&lt;/span&gt;{&lt;span style="color:#a6e22e"&gt;count&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;map&lt;/span&gt;[&lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;]&lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;{&lt;span style="color:#e6db74"&gt;&amp;#34;james&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;spartacus&amp;#34;&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;}}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;wg&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sync&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;WaitGroup&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;increment&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;func&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;n&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; ; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &amp;lt; &lt;span style="color:#a6e22e"&gt;n&lt;/span&gt; ; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;cnt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Inc&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;wg&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Done&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;wg&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Add&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;go&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;increment&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;james&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;100000&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;go&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;increment&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;james&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;100000&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;go&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;increment&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;spartacus&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;10000&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;wg&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Wait&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;cnt&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This code defines a simple &lt;code&gt;Counter&lt;/code&gt; struct with a single method named &lt;code&gt;Inc&lt;/code&gt; to increment the &lt;code&gt;count&lt;/code&gt; map. &lt;code&gt;Inc&lt;/code&gt; is responsible for managing the locking and unlocking of the mutex with &lt;code&gt;c.mu.Lock()&lt;/code&gt; to lock it and &lt;code&gt;defer c.mu.Unlock()&lt;/code&gt; to unlock it as the method is returning.&lt;/p&gt;</description></item><item><title>Go routines and WaitGroups</title><link>https://www.jamessimas.com/posts/2022/go-routines-and-waitgroups/</link><pubDate>Mon, 18 Jul 2022 16:34:10 -0700</pubDate><guid>https://www.jamessimas.com/posts/2022/go-routines-and-waitgroups/</guid><description>&lt;p&gt;Working with Goroutines is simple. You simply pre-prend your function call with &lt;code&gt;go&lt;/code&gt; and you&amp;rsquo;re off and running.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an example which calls the &lt;code&gt;expensive()&lt;/code&gt; function five times before exiting.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;time&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;expensive&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;id&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Worker %d starting\n&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Sleep&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Second&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// Oh, so expensive!&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Worker %d ending\n&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &amp;lt; &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;&lt;span style="color:#f92672"&gt;++&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;go&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;expensive&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Exiting!&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But it has a problem&amp;hellip; running the program shows output like this:&lt;/p&gt;</description></item><item><title>Closures in Go</title><link>https://www.jamessimas.com/posts/2022/closures-in-go/</link><pubDate>Wed, 13 Jul 2022 14:25:24 -0700</pubDate><guid>https://www.jamessimas.com/posts/2022/closures-in-go/</guid><description>&lt;p&gt;In Go, it&amp;rsquo;s pretty easy to write an anonymous function.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;func&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;s&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;s is:&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;s&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }(&lt;span style="color:#e6db74"&gt;&amp;#34;hello world&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Running the above code produces:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-sh" data-lang="sh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ go run main.go
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;s is: hello world
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You can even assign the anonymous function to a variable like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;myFunc&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;func&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;s&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;){
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;s is:&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;s&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;myFunc&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;hello again, world!&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now we get this output from the above code:&lt;/p&gt;</description></item><item><title>Generics in Go 1.18</title><link>https://www.jamessimas.com/posts/2022/go-1-18-generics/</link><pubDate>Tue, 12 Jul 2022 15:22:00 -0700</pubDate><guid>https://www.jamessimas.com/posts/2022/go-1-18-generics/</guid><description>&lt;p&gt;In Go 1.18, we get access to Genrics. Huzzah!&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s an basic example of how to use them:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;PrintAge&lt;/span&gt;[&lt;span style="color:#a6e22e"&gt;age&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;float32&lt;/span&gt; | &lt;span style="color:#66d9ef"&gt;int64&lt;/span&gt;](&lt;span style="color:#a6e22e"&gt;myAge&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;age&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Printf&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;age: %s \t type: %T\n&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;myAge&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;myAge&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;age1&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;float32&lt;/span&gt; = &lt;span style="color:#ae81ff"&gt;30.5&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;var&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;age2&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;int64&lt;/span&gt; = &lt;span style="color:#ae81ff"&gt;32&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;PrintAge&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;age1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;PrintAge&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;age2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Running the above program gives us the below output. You can see that it happily accepted the float32 and int64 values without issue.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;age: %!s(float32=30.5) type: float32
age: %!s(int64=32) type: int64
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This saves us from having to either (a) define a separate PrintAge function for every type of number we want to accept or (b) writing the PrintAge to accept type &lt;code&gt;interface{}&lt;/code&gt; which would then accept types we don&amp;rsquo;t want to accept (and having to mess with type assertions and all that).&lt;/p&gt;</description></item><item><title>Go defer</title><link>https://www.jamessimas.com/posts/2021/go-defer/</link><pubDate>Tue, 20 Jul 2021 07:32:34 -0700</pubDate><guid>https://www.jamessimas.com/posts/2021/go-defer/</guid><description>&lt;p&gt;&lt;code&gt;defer&lt;/code&gt; in go is used to run a function later on. Specifically, the specified function will run when the enclosing function returns.&lt;/p&gt;
&lt;p&gt;There&amp;rsquo;s no clean equivalent to this in Python that I&amp;rsquo;ve found.&lt;/p&gt;
&lt;p&gt;The quintessential example is closing a file handle as your program exits.&lt;/p&gt;
&lt;h2 id="example"&gt;Example&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;os&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;file&lt;/span&gt; &lt;span style="color:#f92672"&gt;:=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;createFile&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;/tmp/testingdefer.txt&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;defer&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;closeFile&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;file&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;writeFile&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;file&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;createFile&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;) (&lt;span style="color:#a6e22e"&gt;file&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;os&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;File&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;creating file: &amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;file&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;_&lt;/span&gt; = &lt;span style="color:#a6e22e"&gt;os&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Create&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;path&lt;/span&gt;) &lt;span style="color:#75715e"&gt;// skipping error handling for brevity&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;writeFile&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;file&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;os&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;File&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;writing file&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Fprintln&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;file&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;here is some data for you!&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;closeFile&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;file&lt;/span&gt; &lt;span style="color:#f92672"&gt;*&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;os&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;File&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;closing file&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;file&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Close&lt;/span&gt;() &lt;span style="color:#75715e"&gt;// skipping error handling for brevity&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Empty Go Interfaces</title><link>https://www.jamessimas.com/posts/2021/empty-go-interfaces/</link><pubDate>Sun, 11 Jul 2021 15:10:58 -0700</pubDate><guid>https://www.jamessimas.com/posts/2021/empty-go-interfaces/</guid><description>&lt;p&gt;When declaring function parameters in Go, you must type the incoming data. Here&amp;rsquo;s an example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;fmt&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;print_stuff&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;s&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;) {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;fmt&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Println&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;s&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;print_stuff&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;Passing string!&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;s string&lt;/code&gt; indicates that we&amp;rsquo;re passing a variable of type &lt;code&gt;string&lt;/code&gt; into the function. This prevents us from from passing into variables of any other type. For example, this will fail with &lt;code&gt;./prog.go:10:17: cannot use 42 (type untyped int) as type string in argument to example_str&lt;/code&gt; if you try to pass an integer.&lt;/p&gt;</description></item><item><title>Line beaks in file names on Linux</title><link>https://www.jamessimas.com/posts/2021/line-breaks-in-file-names-on-linux/</link><pubDate>Tue, 02 Feb 2021 22:01:33 -0800</pubDate><guid>https://www.jamessimas.com/posts/2021/line-breaks-in-file-names-on-linux/</guid><description>&lt;p&gt;Today I accidentally created a file whose name had a newline character in it. I didn&amp;rsquo;t notice it when I did it, but here&amp;rsquo;s how it showed up in my shell. There was a directory whose name shared the first few characters of the filename.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[22:07] james_simas@widget /var/tmp $ ls o*
oops? &amp;lt;--- Suspicious file!
oops: &amp;lt;--- Directory
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I tried to delete it:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[22:07] james_simas@widget /var/tmp $ rm &amp;#39;oops?&amp;#39;
rm: oops?: No such file or directory
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then I realized the my shell wasn&amp;rsquo;t interpreting the character right:&lt;/p&gt;</description></item><item><title>Translating characters with tr</title><link>https://www.jamessimas.com/posts/2021/translating-characters-with-tr/</link><pubDate>Thu, 14 Jan 2021 18:41:51 -0800</pubDate><guid>https://www.jamessimas.com/posts/2021/translating-characters-with-tr/</guid><description>&lt;p&gt;I recently was having to work with Ansible for several days to deploy changes globally across prod. I was storing my playbook limit in a file like so:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;18:45&lt;span style="color:#f92672"&gt;]&lt;/span&gt; james_simas@widget ~/Downloads $ cat limit.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;host1.domain.com
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;host2.domain.com
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;host3.domain.com
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;At one point, I needed to use supply the list of hostnames in BASH, but rather than having them be newline separated, I needed them to be separated by commas like this:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;host1.domain.com,host2.domain.com,host3.domain.com
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I didn&amp;rsquo;t want to modify my original files (I still needed them) and this seemed like a problem somebody else has problably solved. I Googled a bit and found an answer using &lt;code&gt;tr&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>How to use extra_vars_path in the tower_job_template Ansible module</title><link>https://www.jamessimas.com/posts/2020/using-ansibles-extra-vars-path/</link><pubDate>Thu, 19 Mar 2020 21:20:35 -0700</pubDate><guid>https://www.jamessimas.com/posts/2020/using-ansibles-extra-vars-path/</guid><description>&lt;p&gt;Today I was using Ansible&amp;rsquo;s &lt;code&gt;tower_job_template&lt;/code&gt; module in a playbook. I needed to add extra variables to the job template, but Ansible&amp;rsquo;s public &lt;a href="https://docs.ansible.com/ansible/latest/modules/tower_job_template_module.html"&gt;documentation&lt;/a&gt; of the the &lt;code&gt;tower_job_template&lt;/code&gt; module had no examples of how to do this. I was unable to find any compelling examples on Google.&lt;/p&gt;
&lt;p&gt;I was a bit of poking around the Ansible API, it turns out this was far easier than I had anticipated.&lt;/p&gt;
&lt;p&gt;Without further ado, here&amp;rsquo;s how you use &lt;code&gt;extra_vars_path&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>Converting blog to Terraform &amp; Ansible</title><link>https://www.jamessimas.com/posts/2019/convert-blog-to-terraform-and-ansible/</link><pubDate>Sat, 05 Oct 2019 14:33:22 -0700</pubDate><guid>https://www.jamessimas.com/posts/2019/convert-blog-to-terraform-and-ansible/</guid><description>&lt;p&gt;Setting up my blog has always been easy. Previous to today, you just had to:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Provision an Ubuntu 18 VM somewhere (I&amp;rsquo;ve been using &lt;a href="https://www.digitalocean.com/"&gt;Digital Ocean&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Install Apache and remove its default website&lt;/li&gt;
&lt;li&gt;Use &lt;a href="https://gohugo.io"&gt;Hugo&lt;/a&gt; to generate the site&amp;rsquo;s static files and copy them to the VM host&lt;/li&gt;
&lt;li&gt;Done!&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;But, never being one to sit still, I&amp;rsquo;ve decided to up my game and move to automatic provisioning with Terraform and Ansible.&lt;/p&gt;
&lt;p&gt;Why? Because it&amp;rsquo;s fucking cool, that&amp;rsquo;s why!&lt;/p&gt;</description></item><item><title>Operating on a subset of lines with sed</title><link>https://www.jamessimas.com/posts/2019/operating-on-a-subset-of-lines-with-sed/</link><pubDate>Wed, 11 Sep 2019 18:07:33 -0700</pubDate><guid>https://www.jamessimas.com/posts/2019/operating-on-a-subset-of-lines-with-sed/</guid><description>&lt;p&gt;Today a coworker posed an interesting question to me.&lt;/p&gt;
&lt;p&gt;Given a BIG-IP configuration file with thousands of records like this&amp;hellip;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;gtm pool /Common/p_example {
members {
/Common/2001:668:fc78:0:f811:3ef2:fed7:98cc:vs6_2001_668_fc78_0_f811-3ef2-fed7_98cc-80 {
order 0
}
}
monitor /Common/gateway_icmp
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&amp;hellip;how can we easily replace every colon in the name &lt;code&gt;:&lt;/code&gt; with &lt;code&gt;\\:&lt;/code&gt;?&lt;/p&gt;
&lt;p&gt;In short, &lt;code&gt;/Common/2001:668:fc78:0:f811:3ef2:fed7:98cc:vs6_2001_668_fc78_0_f811-3ef2-fed7_98cc-80&lt;/code&gt; needed to become &lt;code&gt;/Common/2001\\:668\\:fc78\\:0\\:f811\\:3ef2\\:fed7\\:98cc\\:vs6_2001_668_fc78_0_f811-3ef2-fed7_98cc-80&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This must only be done on the lines with start with &lt;code&gt;/Common&lt;/code&gt; and which also contain the string &lt;code&gt;vs6&lt;/code&gt;. He could not guarantee that colons would not be found elsewhere in the file.&lt;/p&gt;</description></item><item><title>Using SMS is like Killing Whales for Oil</title><link>https://www.jamessimas.com/posts/2019/sms-sucks/</link><pubDate>Thu, 15 Aug 2019 20:54:34 -0700</pubDate><guid>https://www.jamessimas.com/posts/2019/sms-sucks/</guid><description>&lt;p&gt;If you&amp;rsquo;ve known me for a while, you probably know that I have a soap box. This soap box has &amp;ldquo;STOP USING SMS&amp;rdquo; written on the side in red Sharpie.&lt;/p&gt;
&lt;p&gt;It&amp;rsquo;s true. I hate SMS/MMS. The protocols are terrible and like hunting whales for oil. (Sure, you &lt;em&gt;could&lt;/em&gt; do that, but why would you when there are so many better technologies out there?!)&lt;/p&gt;
&lt;h1 id="the-pain-points"&gt;The Pain Points&lt;/h1&gt;
&lt;h2 id="slow"&gt;Slow&lt;/h2&gt;
&lt;p&gt;Text messages are slow to deliver. Seriously. I often experience delays of several seconds (or tens of seconds!) waiting for text messages to send. This is especially true if I&amp;rsquo;m in my work&amp;rsquo;s office building which has many areas where cell signal is weak.&lt;/p&gt;</description></item><item><title>Notes on sed</title><link>https://www.jamessimas.com/posts/2019/notes-on-sed/</link><pubDate>Sat, 15 Jun 2019 15:44:09 -0700</pubDate><guid>https://www.jamessimas.com/posts/2019/notes-on-sed/</guid><description>&lt;p&gt;I&amp;rsquo;ve always been a bit hit-or-miss with sed and haven&amp;rsquo;t understood it to the level to which I wanted. Today I aimed to change that and these are my notes from sitting down to learn it.&lt;/p&gt;
&lt;p&gt;Replace a string in a file (first occurrence per line only):&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cat file.txt | sed &amp;#39;s/oldstring/newstring/&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Replace a string in a file (all occurrences per line, i.e., globally):&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cat file.txt | sed &amp;#39;s/oldstring/newstring/g&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Use your own delimiters by just dropping them in place of &lt;code&gt;/&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>Digital Declutter Reflections</title><link>https://www.jamessimas.com/posts/2019/digital-declutter-reflections/</link><pubDate>Sat, 23 Mar 2019 11:40:30 -0700</pubDate><guid>https://www.jamessimas.com/posts/2019/digital-declutter-reflections/</guid><description>&lt;p&gt;A few days ago, I finished my Digital Declutter Experiment. Here&amp;rsquo;s what I accomplished:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Successfully fixed my leaky kitchen faucet&lt;/li&gt;
&lt;li&gt;Attempted to replace the burned out lights in my car&amp;rsquo;s climate control dashboard, but did not succeed.
&lt;ul&gt;
&lt;li&gt;It turns out you have to take apart a ton of the dashboard to replace the tiny light-bulbs which burned out. I spent an hour and a half on it before deciding it was more work than it is worth to me.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Worked out 3-5 times at the gym each week.
&lt;ul&gt;
&lt;li&gt;This goal got severely impeded by a nasty cold I&amp;rsquo;ve had off and on for several weeks.&lt;/li&gt;
&lt;li&gt;It became clear that the amount of energy I was expending in exercising was causing me to relapse into sickness again, so I&amp;rsquo;ve had to take more time off than I wanted or anticipated.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Read several books
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com/Seveneves-Neal-Stephenson/dp/0062334514/ref=sr_1_2?keywords=seveneves&amp;amp;qid=1553366627&amp;amp;s=gateway&amp;amp;sr=8-2"&gt;Seveneves by Neal Stephensen&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com/Untrue-Everything-Believe-Infidelity-Science/dp/0316463612/ref=sr_1_1?keywords=untrue&amp;amp;qid=1553366674&amp;amp;s=gateway&amp;amp;sr=8-1"&gt;Untrue by Wednesday Martin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com/Discipline-Equals-Freedom-Field-Manual/dp/1250156947/ref=sr_1_1?keywords=discipline+equals+freedom&amp;amp;qid=1553366790&amp;amp;s=gateway&amp;amp;sr=8-1"&gt;Discipline Equals Freedom by Jocko Willink&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com/How-Become-Straight-Student-Unconventional/dp/0767922719/ref=sr_1_2?keywords=how+to+become+straight+a&amp;amp;qid=1553366814&amp;amp;s=gateway&amp;amp;sr=8-2"&gt;How to Become a Straight-A Student by Cal Newport&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Started a puzzle with Sinah&lt;/li&gt;
&lt;li&gt;Significantly cut down my time on-line&lt;/li&gt;
&lt;li&gt;Had significantly more face-to-face interactions with friends and family&lt;/li&gt;
&lt;/ul&gt;
&lt;h1 id="things-ive-learned"&gt;Things I&amp;rsquo;ve learned&lt;/h1&gt;
&lt;h2 id="youtube-can-be-awesome"&gt;YouTube Can Be Awesome&lt;/h2&gt;
&lt;p&gt;YouTube was very helpful in fixing my leaky faucet. The tutorials I found were accurate, clear, and to the point. This made fixing my faucet significantly easier than it would have otherwise been.&lt;/p&gt;</description></item><item><title>TCL - Part 2</title><link>https://www.jamessimas.com/posts/2019/tcl-part-2/</link><pubDate>Fri, 22 Feb 2019 20:46:48 -0800</pubDate><guid>https://www.jamessimas.com/posts/2019/tcl-part-2/</guid><description>&lt;h2 id="lists-continued"&gt;Lists (Continued)&lt;/h2&gt;
&lt;p&gt;Appending to lists is simple with &lt;code&gt;lappend&lt;/code&gt;:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; &lt;code&gt;lappend&lt;/code&gt; takes just the name of the list. It updates the specified list, so you do not have to use &lt;code&gt;set&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-tcl" data-lang="tcl"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;set&lt;/span&gt; list &lt;span style="color:#66d9ef"&gt;{&lt;/span&gt;this is &lt;span style="color:#66d9ef"&gt;{&lt;/span&gt;a list&lt;span style="color:#66d9ef"&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;this is &lt;span style="color:#66d9ef"&gt;{&lt;/span&gt;a list&lt;span style="color:#66d9ef"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;%&lt;/span&gt; lappend list &lt;span style="color:#66d9ef"&gt;{&lt;/span&gt;more stuff here&lt;span style="color:#66d9ef"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;this is &lt;span style="color:#66d9ef"&gt;{&lt;/span&gt;a list&lt;span style="color:#66d9ef"&gt;}&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;{&lt;/span&gt;more stuff here&lt;span style="color:#66d9ef"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;%&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;%&lt;/span&gt; puts $list
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;this is &lt;span style="color:#66d9ef"&gt;{&lt;/span&gt;a list&lt;span style="color:#66d9ef"&gt;}&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;{&lt;/span&gt;more stuff here&lt;span style="color:#66d9ef"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Inserting into a list is done with &lt;code&gt;linsert&lt;/code&gt;. It is zero-indexed:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-tcl" data-lang="tcl"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;%&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;set&lt;/span&gt; list &lt;span style="color:#66d9ef"&gt;[&lt;/span&gt;linsert $list &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;{&lt;/span&gt;of stuff with&lt;span style="color:#66d9ef"&gt;}]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;this is &lt;span style="color:#66d9ef"&gt;{&lt;/span&gt;a list&lt;span style="color:#66d9ef"&gt;}&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;{&lt;/span&gt;of stuff with&lt;span style="color:#66d9ef"&gt;}&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;{&lt;/span&gt;more stuff here&lt;span style="color:#66d9ef"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;%&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;%&lt;/span&gt; puts $list
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;this is &lt;span style="color:#66d9ef"&gt;{&lt;/span&gt;a list&lt;span style="color:#66d9ef"&gt;}&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;{&lt;/span&gt;of stuff with&lt;span style="color:#66d9ef"&gt;}&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;{&lt;/span&gt;more stuff here&lt;span style="color:#66d9ef"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;%&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="split"&gt;Split&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;split&lt;/code&gt; accepts:&lt;/p&gt;</description></item><item><title>Digital Declutter Experiment</title><link>https://www.jamessimas.com/posts/2019/digital-declutter-experiment/</link><pubDate>Tue, 19 Feb 2019 14:55:05 -0800</pubDate><guid>https://www.jamessimas.com/posts/2019/digital-declutter-experiment/</guid><description>&lt;p&gt;I recently finished &amp;ldquo;Digital Essentialism&amp;rdquo; by Cal Newport. As part of my resolution to get more value from the books I read, I will be conducting his recommended &amp;ldquo;Digital Declutter&amp;rdquo; experiment for the next 30 days.&lt;/p&gt;
&lt;p&gt;As such, here are the technology rules I will follow from 2019-02-19 to 2019-03-21.&lt;/p&gt;
&lt;h2 id="the-rules"&gt;The Rules&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Email
&lt;ul&gt;
&lt;li&gt;My personal email will be checked once per day.&lt;/li&gt;
&lt;li&gt;I already do this, but feel like it is a useful habit, so I am continuing it.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Text messaging / message services
&lt;ul&gt;
&lt;li&gt;All group threads will be muted.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Reddit
&lt;ul&gt;
&lt;li&gt;I will not use Reddit during this time. It&amp;rsquo;s a black hole!&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Streaks
&lt;ul&gt;
&lt;li&gt;I will not use my habit tracking app during this time and will pause all habits it is tracking.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Streaming Video Media
&lt;ul&gt;
&lt;li&gt;Includes:
&lt;ul&gt;
&lt;li&gt;YouTube&lt;/li&gt;
&lt;li&gt;Netflix&lt;/li&gt;
&lt;li&gt;Amazon Prime&lt;/li&gt;
&lt;li&gt;etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;I will limit this to no more than 5 hours per week. It must be with my wife or friends. I will track it with a sticky note next to the TV.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;IMDB
&lt;ul&gt;
&lt;li&gt;I will not use IMDB during this month.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="exemptions-and-operating-procedures"&gt;Exemptions and Operating Procedures&lt;/h2&gt;
&lt;p&gt;This a list of apps or services I which are exempted from this experiment.&lt;/p&gt;</description></item><item><title>TCL - Part 1</title><link>https://www.jamessimas.com/posts/2019/tcl-part-1/</link><pubDate>Mon, 18 Feb 2019 11:57:54 -0800</pubDate><guid>https://www.jamessimas.com/posts/2019/tcl-part-1/</guid><description>&lt;p&gt;I&amp;rsquo;ve been improving my knowledge of TCL since I&amp;rsquo;m starting to work with a lot of iRules (which are based on TCL) in my current position. With that said, here&amp;rsquo;s some notes I took from my latest round of studying and learning.&lt;/p&gt;
&lt;p&gt;Many thanks to &lt;a href="https://www.amazon.com/Exploring-Expect-Tcl-based-Automating-Interactive/dp/1565920902/ref=sr_1_fkmrnull_1?keywords=expect+oreilly&amp;amp;qid=1550883342&amp;amp;s=gateway&amp;amp;sr=8-1-fkmrnull"&gt;Exploring Expect by Don Libes&lt;/a&gt; for facilitating my learning!&lt;/p&gt;
&lt;h2 id="getting-setup"&gt;Getting setup&lt;/h2&gt;
&lt;p&gt;Installing TCL on Ubuntu: &lt;code&gt;apt install tcl&lt;/code&gt;&lt;/p&gt;
&lt;p&gt;Launching the TCL shell: &lt;code&gt;tclsh&lt;/code&gt;&lt;/p&gt;
&lt;h2 id="variables"&gt;Variables&lt;/h2&gt;
&lt;p&gt;Setting a variable: &lt;code&gt;set i 100&lt;/code&gt;&lt;/p&gt;</description></item><item><title>Some of my favorite things</title><link>https://www.jamessimas.com/faves/</link><pubDate>Sat, 16 Feb 2019 15:38:26 -0800</pubDate><guid>https://www.jamessimas.com/faves/</guid><description>&lt;p&gt;In no particular order, here are some things which delight me:&lt;/p&gt;
&lt;h3 id="books--blogs"&gt;Books &amp;amp; Blogs&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Cal Newport&amp;rsquo;s &lt;a href="https://www.amazon.com/s/ref=nb_sb_noss?url=search-alias%3Daps&amp;amp;field-keywords=cal+newport"&gt;books&lt;/a&gt; and &lt;a href="http://calnewport.com/blog/"&gt;blog&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;This man has significantly improved my working life and made me more effective in general.&lt;/li&gt;
&lt;li&gt;I strongly recommend &lt;a href="https://www.amazon.com/Deep-Work-Focused-Success-Distracted/dp/1455586692/ref=sr_1_3?ie=UTF8&amp;amp;qid=1550366400&amp;amp;sr=8-3&amp;amp;keywords=deep+work"&gt;Deep Work&lt;/a&gt; and &lt;a href="https://www.amazon.com/Digital-Minimalism-Choosing-Focused-Noisy-ebook/dp/B07DBRBP7G/ref=sr_1_fkmr1_1?ie=UTF8&amp;amp;qid=1550366165&amp;amp;sr=8-1-fkmr1&amp;amp;keywords=digital+essentialism+book+newport"&gt;Digital Minimalism&lt;/a&gt;. Digital Minimalism was responsible for helping me kick my Reddit and YouTube habit.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.amazon.com/Coffeehouse-Investor-Wealth-Ignore-Street/dp/159184584X/ref=sr_1_1?ie=UTF8&amp;amp;qid=1550366457&amp;amp;sr=8-1&amp;amp;keywords=coffeehouse+investor"&gt;The Coffeehouse Investor&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;This book kickstarted my Save For Retirement Like A Motherfucker(tm) plan.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="software"&gt;Software&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.sublimetext.com/"&gt;Sublime Text&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;I basically live in a text editor for work, so a great text editor is essential.&lt;/li&gt;
&lt;li&gt;This is some of the best money I&amp;rsquo;ve ever spent a piece of software.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://culturedcode.com/things/"&gt;Things 3&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;What do you get when you combine people who &lt;em&gt;really&lt;/em&gt; get good design and engineers? Things 3. That&amp;rsquo;s what.&lt;/li&gt;
&lt;li&gt;This is easily the best to-do list app that I&amp;rsquo;ve ever used.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="other"&gt;Other&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.tombihn.com/"&gt;Tom Bihn&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;They make some of the most enjoyable to use travel gear out there.&lt;/li&gt;
&lt;li&gt;I own many products by them and my favorite is their packing cubes.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.goruck.com/gr1/"&gt;GoRuck GR1&lt;/a&gt;
&lt;ul&gt;
&lt;li&gt;This is the best backpack I&amp;rsquo;ve ever owned. Hands down. I had no idea I could enjoy using a backpack so much.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Initial commit</title><link>https://www.jamessimas.com/posts/2019/initial-commit/</link><pubDate>Sat, 16 Feb 2019 13:52:13 -0800</pubDate><guid>https://www.jamessimas.com/posts/2019/initial-commit/</guid><description>&lt;p&gt;I&amp;rsquo;ve tried this blog thing before. It hasn&amp;rsquo;t stuck (probably because I wrote in the style I learned in college.)&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m giving it another shot, but this time it will be much more free form and less academic.&lt;/p&gt;
&lt;p&gt;I will use this to record anything I find interesting.&lt;/p&gt;</description></item><item><title>ab</title><link>https://www.jamessimas.com/recipes/ab/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.jamessimas.com/recipes/ab/</guid><description>&lt;ul&gt;
&lt;li&gt;Send 10,000 requests, using 10 sockets at a time: &lt;code&gt;ab -n 10000 -c 10 https://10.10.10.10/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Send requests with a BIG-IP persistence cookie: &lt;code&gt;ab -n 10000 -C BIGipServerMyPool=1677787402.36895.0000 http://10.10.10.10/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>ansible</title><link>https://www.jamessimas.com/recipes/ansible/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.jamessimas.com/recipes/ansible/</guid><description>&lt;ul&gt;
&lt;li&gt;Specify vault file password file via env var: &lt;code&gt;export ANSIBLE_VAULT_PASSWORD_FILE=/path/to/file&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>bash</title><link>https://www.jamessimas.com/recipes/bash/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.jamessimas.com/recipes/bash/</guid><description>&lt;p&gt;&lt;strong&gt;Miscellaneous:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Run script with verbose output: &lt;code&gt;bash -v&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Check for syntax errors: &lt;code&gt;bash -n&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Show xtrace info: &lt;code&gt;bash -x&lt;/code&gt;
&lt;ul&gt;
&lt;li&gt;Lines which start with &lt;code&gt;+&lt;/code&gt; are executed in the shell&lt;/li&gt;
&lt;li&gt;Lines which start with &lt;code&gt;++&lt;/code&gt; are executed in a sub-shell&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Loop over alphabet with upper and lower case: &lt;code&gt;for l in {{A..Z},{a..z}}; do echo $l ; done&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Print text in beautiful columns by piping to: &lt;code&gt;column -t&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Echo a string to stderr: &lt;code&gt;&amp;gt;&amp;amp;2 echo Hello, world.&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Keyboard shortcuts:&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>curl</title><link>https://www.jamessimas.com/recipes/curl/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.jamessimas.com/recipes/curl/</guid><description>&lt;ul&gt;
&lt;li&gt;Display response code and total time: &lt;code&gt;curl -s -w &amp;quot;%{http_code} - %{time_total}\n&amp;quot; -o /dev/null www.jamessimas.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;curl multiple IPs with one command: &lt;code&gt;curl 10.20.20.8[0-9]:80/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Overriding DNS: &lt;code&gt;curl --resolve &amp;quot;www.jamessimas.com:80/10.11.12.13&amp;quot; www.jamessimas.com&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>cut</title><link>https://www.jamessimas.com/recipes/cut/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.jamessimas.com/recipes/cut/</guid><description>&lt;p&gt;&lt;strong&gt;Delimited:&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;The delimiter in the below examples is &lt;code&gt;:&lt;/code&gt;.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Show field 1: &lt;code&gt;cut -f 1 -d : /etc/password&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Show field 2 and sort results numerically: &lt;code&gt;cut -f 2 -d : /etc/password | sort -n&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Show all fields &lt;em&gt;after&lt;/em&gt; field 1: &lt;code&gt;cut -d: -f 2:&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Show fields 1 through 2: &lt;code&gt;cut -d : -f1-2&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Miscellaneous:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cut 10 from start of line: &lt;code&gt;cut -c -10&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>dig</title><link>https://www.jamessimas.com/recipes/dig/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.jamessimas.com/recipes/dig/</guid><description>&lt;ul&gt;
&lt;li&gt;Display short response: &lt;code&gt;dig +short www.google.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Display only answer section: &lt;code&gt;dig +noall +answer www.google.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Specify source address for query: &lt;code&gt;dig -b &amp;lt;source address[:#port]&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Specify DNS server to query: &lt;code&gt;dig @DNS_SERVER www.google.com&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Use ends0: &lt;code&gt;dig @DNS_SERVER +subnet=10.11.12.13 1.1.1.1&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>git</title><link>https://www.jamessimas.com/recipes/git/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.jamessimas.com/recipes/git/</guid><description>&lt;p&gt;&lt;strong&gt;Branching and Checkout:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Clean up local banches:
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;git remote prune --dry-run origin&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;git remote prune origin&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;Update local branch without it being checked out: &lt;code&gt;git fetch origin src_branch:local_branch&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Show which remote branch local branches are tracking: &lt;code&gt;git branch -vv&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Display branches by last commit date: &lt;code&gt;git for-each-ref --sort=-committerdate refs/heads/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Copy files/directories from another branch to current branch: &lt;code&gt;git checkout source_branch -- path/to/dir/ path/to/file.txt&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Reset to a particular commit &lt;strong&gt;without&lt;/strong&gt; losing changes:
&lt;ul&gt;
&lt;li&gt;Reset to one commit past most recent: &lt;code&gt;git reset HEAD^&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Reset to particular commit: &lt;code&gt;git reset COMMIT_ID&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Diffing branches:&lt;/strong&gt;&lt;/p&gt;</description></item><item><title>golang</title><link>https://www.jamessimas.com/recipes/golang/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.jamessimas.com/recipes/golang/</guid><description>&lt;p&gt;&lt;strong&gt;go doc&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Run web server: &lt;code&gt;godoc -http=localhost:8888 -index -links&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;View web server: http://localhost:8888
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Tip:&lt;/strong&gt; Add &lt;code&gt;?m=all&lt;/code&gt; to URL to show unexported types, funcs, etc.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;go test&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Run all tests:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Run all tests: &lt;code&gt;go test ./...&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Run all tests in package: &lt;code&gt;go test modulename/pkg/packagename/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Run all tests in file: &lt;code&gt;go test path/to/file_test.go&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Run subset of tests:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Run function tests: &lt;code&gt;go test path/to/file_test.go -run FUNCTION_TEST_NAME&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Run a single test in function tests: &lt;code&gt;go test path/to/file_test.go -run FUNCTION_TEST_NAME/test_name_here&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tips:&lt;/p&gt;</description></item><item><title>macOS</title><link>https://www.jamessimas.com/recipes/macos/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.jamessimas.com/recipes/macos/</guid><description>&lt;h2 id="allow-an-app-to-run"&gt;Allow an app to run&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo xattr -rd com.apple.quarantine /path/to/the.app
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="disable-emoji-predictions-in-macos-sonoma-and-higher"&gt;Disable emoji predictions in macOS Sonoma and higher&lt;/h2&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo defaults write /Library/Preferences/FeatureFlags/Domain/UIKit.plist emoji_enhancements -dict-add Enabled -bool NO
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Source: &lt;a href="https://www.reddit.com/r/MacOS/comments/16wzdk9/is_there_a_way_to_turn_off_the_new_emoji/"&gt;https://www.reddit.com/r/MacOS/comments/16wzdk9/is_there_a_way_to_turn_off_the_new_emoji/&lt;/a&gt;&lt;/p&gt;
&lt;h2 id="dock"&gt;Dock&lt;/h2&gt;
&lt;p&gt;Configure &lt;a href="https://macos-defaults.com/dock/autohide-delay.html"&gt;auto-hide delay&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# set to 200ms (default)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;defaults write com.apple.dock &lt;span style="color:#e6db74"&gt;&amp;#34;autohide-delay&amp;#34;&lt;/span&gt; -float &lt;span style="color:#e6db74"&gt;&amp;#34;0.2&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; killall Dock
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# set to 30ms&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;defaults write com.apple.dock &lt;span style="color:#e6db74"&gt;&amp;#34;autohide-delay&amp;#34;&lt;/span&gt; -float &lt;span style="color:#e6db74"&gt;&amp;#34;0.03&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; killall Dock
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# set to immediate&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;defaults write com.apple.dock &lt;span style="color:#e6db74"&gt;&amp;#34;autohide-delay&amp;#34;&lt;/span&gt; -float &lt;span style="color:#e6db74"&gt;&amp;#34;0&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; killall Dock
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="finding-what-processes-are-using-a-tcp-port"&gt;Finding what processes are using a TCP port&lt;/h3&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;sudo lsof -nP -iTCP -sTCP:LISTEN
&lt;/code&gt;&lt;/pre&gt;&lt;h3 id="time-machine"&gt;Time Machine&lt;/h3&gt;
&lt;p&gt;Configure backup speed:&lt;/p&gt;</description></item><item><title>Now</title><link>https://www.jamessimas.com/now/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.jamessimas.com/now/</guid><description>&lt;p&gt;&lt;strong&gt;Last updated:&lt;/strong&gt; 2025-08-22&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Where am I located?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;Seattle, WA 🌦️&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What do I do for work?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m still a software developer for F5. 💻 I write back-end tooling, services, and automation to make managing a cloud service at-scale possible.&lt;/p&gt;
&lt;p&gt;I spend most of my time working in Golang nowdays and write tooling to orchestrate backend infrastructure.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;What else is going on?&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m in love with VIM-keybindings for coding.&lt;/p&gt;
&lt;p&gt;I switched to the Ghostty terminal.&lt;/p&gt;</description></item><item><title>rsync</title><link>https://www.jamessimas.com/recipes/rsync/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.jamessimas.com/recipes/rsync/</guid><description>&lt;p&gt;&lt;strong&gt;Copy directory recursively with status bars:&lt;/strong&gt;&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;rsync -avh --progress -e ssh /source/dir/ user@remotehost:/dest/dir/
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>sort</title><link>https://www.jamessimas.com/recipes/sort/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.jamessimas.com/recipes/sort/</guid><description>&lt;ul&gt;
&lt;li&gt;Numericaly sort file. Fields are separated by &lt;code&gt;:&lt;/code&gt;. Use key in position 2: &lt;code&gt;sort -n -k2 -t : /etc/password&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Sort by size of directories/files: &lt;code&gt;du -h | sort -n&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>ssh-add</title><link>https://www.jamessimas.com/recipes/ssh-add/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.jamessimas.com/recipes/ssh-add/</guid><description>&lt;ul&gt;
&lt;li&gt;Add identities:
&lt;ul&gt;
&lt;li&gt;Default: &lt;code&gt;ssh-add&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Specific: &lt;code&gt;ssh-add path/to/identity&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;With 1h lifetime: &lt;code&gt;ssh-add -l 3600 path/to/identity&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;List identities: &lt;code&gt;ssh-add -l&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Locking:
&lt;ul&gt;
&lt;li&gt;Lock w/ password: &lt;code&gt;ssh-add -x&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Unlock: &lt;code&gt;ssh-add -X&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Delete identity: &lt;code&gt;ssh-add -d path/to/identity&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Delete all identities: &lt;code&gt;ssh-add -D&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>tarsnap</title><link>https://www.jamessimas.com/recipes/tarsnap/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.jamessimas.com/recipes/tarsnap/</guid><description>&lt;ul&gt;
&lt;li&gt;List archives: &lt;code&gt;tarsnap --list-archives | sort&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;List size of all archives: &lt;code&gt;tarsnap --print-stats&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Create archive: &lt;code&gt;tarsnap -v -c -f ARCHIVE_NAME /path/to/file /path/to/dir&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Restore archive: &lt;code&gt;tarsnap -v -x -f ARCHIVE_NAME&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Delete archive: &lt;code&gt;tarsnap -d -f ARCHIVE_NAME&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Useful doc: &lt;a href="https://www.tarsnap.com/simple-usage.html"&gt;https://www.tarsnap.com/simple-usage.html&lt;/a&gt;&lt;/p&gt;</description></item><item><title>tmux</title><link>https://www.jamessimas.com/recipes/tmux/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.jamessimas.com/recipes/tmux/</guid><description>&lt;h2 id="favorite-commands"&gt;Favorite commands&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Create session: &lt;code&gt;tmux new [-s &amp;lt;session name&amp;gt;]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Detach session: &lt;code&gt;Ctrl + b, d&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Attach session: &lt;code&gt;tmux a -t &amp;lt;session name&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Rename session (while in it): &lt;code&gt;Ctrl + b, $&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;List sessions: &lt;code&gt;tmux ls OR Ctrl + b, s&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Kill session: &lt;code&gt;tmux kill-session -t &amp;lt;session name&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Go to previous session: &lt;code&gt;Ctrl + b, (&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Go to next session: &lt;code&gt;Ctrl + b, )&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="scrolling"&gt;Scrolling&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Scroll session: &lt;code&gt;Ctrl + B + [ Page Up | Page Down ]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Enable scroll mode: &lt;code&gt;Ctrl + b, [&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Exit scroll mode: &lt;code&gt;q&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="panes"&gt;Panes&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Move pane left/right: &lt;code&gt;Ctrl + B + [ { | } ]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Toggle between pane layouts: &lt;code&gt;Ctrl + b + spacebar&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Split window into panes vertically: &lt;code&gt;Ctrl + b + &amp;quot;&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Split window into panes horizontally: &lt;code&gt;Ctrl + b + %&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Kill pane: &lt;code&gt;Ctrl + b + x&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Switch to pane to the direction: &lt;code&gt;Ctrl + b + &amp;lt;arrow key&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="helpful-websites"&gt;Helpful websites&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://danielmiessler.com/study/tmux/"&gt;https://danielmiessler.com/study/tmux/&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://tmuxcheatsheet.com/"&gt;https://tmuxcheatsheet.com/&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="sharing-a-tmux-session-across-user-accounts"&gt;Sharing a TMUX session across user accounts&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Create new session: &lt;code&gt;tmux -S /tmp/shareds new -s shared&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Have them connect: &lt;code&gt;sudo tmux -S /tmp/shareds attach -t shared&lt;/code&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Source: &lt;a href="https://www.howtoforge.com/sharing-terminal-sessions-with-tmux-and-screen"&gt;https://www.howtoforge.com/sharing-terminal-sessions-with-tmux-and-screen&lt;/a&gt;&lt;/p&gt;</description></item></channel></rss>