<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.10.0">Jekyll</generator><link href="http://danielfava.com/feed.xml" rel="self" type="application/atom+xml" /><link href="http://danielfava.com/" rel="alternate" type="text/html" /><updated>2026-05-21T14:07:13+00:00</updated><id>http://danielfava.com/feed.xml</id><title type="html">Daniel S. Fava</title><subtitle></subtitle><entry><title type="html">Tech Lead, a retrospective</title><link href="http://danielfava.com/2026/04/18/tech-lead-retrospective.html" rel="alternate" type="text/html" title="Tech Lead, a retrospective" /><published>2026-04-18T00:00:00+00:00</published><updated>2026-04-18T00:00:00+00:00</updated><id>http://danielfava.com/2026/04/18/tech-lead-retrospective</id><content type="html" xml:base="http://danielfava.com/2026/04/18/tech-lead-retrospective.html"><![CDATA[<p>I have been the tech lead of a ~12 person team for the past couple of years.
Recently I moved into the role of engineering manager.
Before I get too deep into the trenches of my new role, I wanted to capture what I’ve learned.</p>

<!--more-->

<h2 id="gardener-versus-grand-master-chess-player">Gardener versus grand master chess player</h2>

<p>Depending on the circle you are in, we hear about leaders as grand master chess players.  In this case, the game pieces are members of the team.  The media tends to gravitate towards the extraordinary, but in reality, the grand master metaphor is less applicable than it is made to be.</p>

<p>A more appropriate metaphor is that of a gardener.  Plants grow by themselves; the gardener doesn’t <em>make</em> plants grow.  But the gardener is instrumental in creating an environment that directs growth.
It’s about placing things where they can thrive, pruning when needed, and shaping the overall ecosystem.</p>

<p>With this metaphor in mind, here are some core principles that I’ve found helpful as a tech-lead.</p>

<h2 id="hierarchy-and-optimization">Hierarchy and optimization</h2>

<p>When in doubt, optimize in this order:</p>

<ol>
  <li>company</li>
  <li>team</li>
  <li>individual</li>
</ol>

<ul>
  <li>If it’s slower for me (individual) but faster/better for the team, optimize for the team.</li>
  <li>If it’s slower for the team but faster/better for the company, optimize for the company.</li>
</ul>

<p>I’ve touched on this on a previous post.  See <a href="/leadership/2025/09/22/tech-lead.html">Late bloomer: Reflections on Becoming a Tech Lead</a>.</p>

<h2 id="creative-boundaries-freedom-and-agency">Creative boundaries, freedom and agency</h2>

<p>There are good reasons to give people agency and freedom.  From a macro point of view, distribution can scale better than centralization.  And from a local point of view, intrinsic motivation is more powerful than extrinsic motivation.</p>

<p>But freedom does not necessarily mean:</p>

<ul>
  <li>you get to re-write systems whenever you want</li>
  <li>you get to choose whatever programming language and technologies you want</li>
  <li>you get to make decisions that impact others without consulting them</li>
</ul>

<p>So how do we balance freedom and agency against the need to organize and cooperate?</p>

<p>As a tech lead, I’ve come to think in terms of <strong>creative boundaries</strong>:</p>

<ul>
  <li>you have freedom, and you give freedom within bounds</li>
  <li>most bounds are fluid; some are hard and non-negotiable</li>
  <li>you define the bounds as a team</li>
</ul>

<p>It creates a shared contract with clear expectations, but loose enough to accommodate different personalities in the team.  This doesn’t come for free; it takes effort. 
It means focusing on the <em>forming</em> and <em>norming</em> phases of a team’s development so we can get through the <em>storming</em> part and into <em>performing</em> (<a href="https://en.wikipedia.org/wiki/Tuckman%27s_stages_of_group_development">Tuckman’s stages of group development</a>).</p>

<p>And to clarify, coordination doesn’t mean coordinating with the tech-lead.  We don’t want the tech lead to be a <em>single point of failure</em>.  Coordinating means individual contributors will think about involving stakeholders (whoever those are) when needed.</p>

<p>For example, before re-writing a large piece of code, have team members ask themselves:</p>

<ul>
  <li>Who owns or uses this code, and have I talked to them?</li>
  <li>Who else should be aware or involved in this decision?</li>
  <li>Is this the right time to do this work?</li>
  <li>Does this align with what the team and organization need right now?</li>
</ul>

<h3 id="tight-loose-tight">Tight-loose-tight</h3>

<p>When it comes to boundaries and expectations towards the team, a helpful model is the <em>“tight-loose-tight”</em>:</p>

<p><strong>Tight on what we want to achieve</strong></p>

<ul>
  <li>Have a well-thought-out list of focus initiatives.  The responsibility for having such a list tends to lie with the product manager/owner.
The list usually combines external company initiatives and internal team needs.
It is put together iteratively, with input from the engineering manager and the tech lead.
The EM helps match people’s strengths and interests to the work. The tech lead brings input on complexity and effort.</li>
</ul>

<p><strong>Loose on how to do it</strong></p>

<ul>
  <li>Developers have a lot of freedom in defining the “how”.</li>
</ul>

<p><strong>Tight on measuring achievement</strong></p>

<ul>
  <li>Follow-up on progress and end-result.  Note that achievement doesn’t need to be success; achievement means closure.  It’s more about accountability (taking ownership and driving towards completion) than outcome (success).</li>
</ul>

<h2 id="decision-making-its-about-commitment-not-consensus">Decision making: It’s about commitment, not consensus</h2>

<p><strong>Focus on <em>commitment</em> instead of <em>consensus</em></strong>.  In practice, that means not everybody in the team needs to agree; but everybody should be able to live with any decision.</p>

<p><strong>It is not a democracy</strong>.  Taking a vote is not the only way to break out of interminable rounds of discussion.</p>

<p>You can propose a decision and ask people “can you live with this decision?”  It’s not about making people happy.  It’s also not about forcing a decision onto them.  It’s about asking for their commitment.</p>

<p>Decision making is something I struggled with.  I shared technical leadership responsibilities with our area architect.  In retrospect, I suspect the team wanted more direction than what I gave them.<br />
I should have driven a clearer split of responsibilities between myself and our architect, and I should have invested in ways to settle our differences so that the team would benefit from a <strong>consistent message</strong>.</p>

<h3 id="the-importance-of-having-a-consistent-message">The importance of having a consistent message</h3>

<p>It is important for the team to get a relatively consistent message from tech-lead, manager, product manager, and architect.  To that end, we often discuss internally before presenting an initiative to the team.  This type of coordination is time well spent.</p>

<p>Even still, I struggled with the question: can I pull the “I’m the tech-lead” card in order to settle a discussion?  Would it be legitimate for me to claim the power of settling a discussion?
Even though some people wanted me to settle discussions, that authority was never formalized, so I didn’t treat it as part of my toolbelt.</p>

<p>Instead, I became comfortable asking probing questions.  And it is totally legitimate for a tech lead (or anyone in the team) to <em>ask questions and make observations</em>.  Through the questions I asked and the observations I made, I was often able to lead people and decisions towards an outcome without needing to pull the “tech-lead card” out of my pocket.</p>

<h2 id="working-outside-of-the-team">Working outside of the team</h2>

<p>The principles above mostly play out within the team. But the tech-lead’s role also extends outward.</p>

<p>Depending on your organization, this can be a significant part of the role—or barely visible.
While I was tech lead, our area architect was embedded in our team; so the role of communicating externally was shared between us. 
If that were not the case, I would have been expected to attend more sync meetings with architects and tech-leads of adjacent areas.</p>

<p>The tech-lead is also often responsible for security within the team, and interfacing with security initiatives coming from outside of the team.  You can delegate part of that, but you may still get pulled into discussions.</p>

<h2 id="rituals">Rituals</h2>

<p>Our company worked in cycles: short planning periods (“flex”) followed by longer execution periods (“focus”).</p>

<h3 id="weekly-planning">Weekly planning</h3>

<p>During focus periods, we held a short weekly planning meeting between product manager, engineering manager, tech-lead, and architect.  We met on Friday to discuss what the next week might look like.</p>

<p>The planning wasn’t driven by tasks from the backlog.  Instead, we shared our understanding of how the week went and where we thought we were in accomplishing our goals for the current <em>focus period</em>.</p>

<h3 id="focus-planning">Focus planning</h3>

<p>The project manager, engineering manager, area architect, and tech-lead kept a finger on what was going on outside the team.  As the focus period ended, and we entered the <em>flex</em> period, we would already have a sense of our standing towards the outside world; meaning, which company objectives would require our attention, which teams we would need to coordinate with, etc.  These ideas formed the basis for planning the next focus period.</p>

<p>Focus goals are crafted under the responsibility of the product manager.  The product manager, engineering manager, and tech-lead discussed the goals amongst themselves, and brought a fairly refined view of the world to the team.</p>

<h2 id="examples">Examples</h2>

<p>In addition to participating in planning, here are some concrete tasks I found myself doing regularly.</p>

<p>I kept an eye on communication channels to make sure questions being directed towards our team were being answered.  It wasn’t about answering them myself (or even knowing the answers).  It was just making sure someone from our team eventually addressed these questions.</p>

<p>I also kept an eye on pull requests for two reasons:
One, to take the opportunity to learn, teach, and share knowledge; thus nudging the code towards clarity and uniformity.  And two, to help keep the team focused.  It’s reasonable to ask: <em>what’s the context of this pull request, how does it fit into the weekly goals or focus period.</em>  It is not about policing; it’s about understanding where people are coming from and making sure people are working together.</p>

<p>I worked on tasks that were likely to fall through the cracks.  I looked for tech debt that was in the foundations of what we do, and that was likely to remain unaddressed.  Those were the tasks that I gravitated towards.</p>

<p>During my time as tech lead, I paid attention to overall library design and refactoring; that involved:</p>
<ul>
  <li>removing redundant code spread across libraries, and removing repeated type definitions</li>
  <li>seeking opportunities to define types so we benefit from type checking</li>
  <li>splitting packages that had grown too big and too confusing</li>
  <li>preventing creation of unwanted imports from one package into another</li>
  <li>adding missing features in underlying libs and unifying how we approach fundamental problems, like how to query the DB</li>
  <li>writing documentation, etc.</li>
</ul>

<h2 id="summary">Summary</h2>

<p>Being a tech lead is a balancing act:</p>

<ul>
  <li>If you <strong>over-coordinate</strong>, you risk becoming a bottleneck, and if you <strong>under-coordinate</strong>, you risk chaos and divergence</li>
  <li>If you <strong>avoid conflicts</strong>, you postpone decisions, but if you <strong>overuse authority</strong> you risk disengaging the team</li>
  <li>If you <strong>ignore tech debt</strong> you create long-term drag, but if you <strong>focus only on coding</strong> you miss the system view</li>
</ul>

<p>The job is to create clarity with other leaders:</p>
<ul>
  <li>crafting a consistent message,</li>
  <li>defining boundaries,</li>
  <li>planning initiatives,</li>
  <li>guiding decisions.</li>
</ul>

<p>Clarity comes from repeatedly asking:</p>

<ul>
  <li>what are we doing?</li>
  <li>why are we doing it?</li>
  <li>what matters now?</li>
  <li>what does “done” mean?</li>
</ul>]]></content><author><name></name></author><summary type="html"><![CDATA[I have been the tech lead of a ~12 person team for the past couple of years. Recently I moved into the role of engineering manager. Before I get too deep into the trenches of my new role, I wanted to capture what I’ve learned.]]></summary></entry><entry><title type="html">AI and PR reviews</title><link href="http://danielfava.com/software-engineering/2026/02/25/ai-pr-reviews.html" rel="alternate" type="text/html" title="AI and PR reviews" /><published>2026-02-25T09:00:00+00:00</published><updated>2026-02-25T09:00:00+00:00</updated><id>http://danielfava.com/software-engineering/2026/02/25/ai-pr-reviews</id><content type="html" xml:base="http://danielfava.com/software-engineering/2026/02/25/ai-pr-reviews.html"><![CDATA[<p>With AI doing so much coding, the bottleneck has become reviews.</p>

<ul>
  <li>What do we do with those pull requests with thousand of lines of changes that the AI has created?</li>
  <li>Do we trust it and merge it?  Do we spend the time to review it?</li>
  <li>It might have taken 20 minutes to create the PR, but if it takes 2 days to review it, have we gained in efficiency?</li>
</ul>

<p>There are many axis we can use to evaluate a change; for example:</p>

<ul>
  <li>syntactical (typically easy to review, lower risk) versus semantical changes (typically harder to review, higher risk)</li>
  <li>changes in the critical path (e.g. movement of money) versus less critical (e.g. backoffice changes)</li>
  <li>reversible changes versus non-reversible ones (or reversible but incurring a large amount of clean-up effort)</li>
</ul>

<p>In of all of these dimensions, there are subspaces where I’m totally fine with large changes driven by AI.</p>

<p>And there are some spaces where AI changes and AI reviewers should (IMHO) be driven and understood by a human.</p>

<p>My wish is that AI will help us undertake the huge yet boring refactorings that we keep of pushing into the future; like replacing libraries that are old and deprecated but that we don’t dare to replace because the function signatures changed and the refactoring would touch thousand of lines in hundreds of files.</p>

<p>These are the types of changes are large (boring to be made by a human), but easy for AI and easy for a human to review.</p>

<p>What I really dislike is changes that are large and modify logic (as opposed to being syntactical).  Those types of changes (semantic changes) are hard to review and carry a lot of risk.  We need to try to break these down into paletable chunks that are digestible by a human.  I’m not quite ready to let an AI take care of banking accounting systems, for example. It’s too risky; it would be a recipe for disaster.</p>

<!--more-->

<h2 id="breaking-it-down">Breaking it down</h2>

<p>When adding a feature, or making a modification in general, we need to understand which parts fall in which subspaces, and we need to craft the work and the pull-requests into chunks.  Each chunk fitting into one of these subspaces.  Meaning.. don’t mix a risky semantical changes together with a thousand of lines syntactical change!</p>

<p>To me, a change is like a theorem you need to prove, and the implementation is the proof of the theorem.  Bare with me for a moment:</p>

<p>Modifications are typically like this:</p>
<ul>
  <li>we want a lot of the system’s behavior to stay the same.  Call it <code class="language-plaintext highlighter-rouge">C</code> for <em>constant</em>.</li>
  <li>we want some of the system’s behavior to stop existing.  Call it <code class="language-plaintext highlighter-rouge">S</code> for <em>stop</em>.</li>
  <li>we want to add some new behavior into the system.  Call it <code class="language-plaintext highlighter-rouge">N</code> for <em>new</em>.</li>
</ul>

<p>So, today the system behaves as <code class="language-plaintext highlighter-rouge">C union S</code>.
We want to make modifications so that the system behaves as <code class="language-plaintext highlighter-rouge">C union N</code>.  That means, continue doing <code class="language-plaintext highlighter-rouge">C</code>, stop doing <code class="language-plaintext highlighter-rouge">S</code> and add <code class="language-plaintext highlighter-rouge">N</code>.
Sure, sometimes we don’t have <code class="language-plaintext highlighter-rouge">N</code>, and sometimes we don’t have <code class="language-plaintext highlighter-rouge">S</code>, but in general we have both.</p>

<p>We want to go from <code class="language-plaintext highlighter-rouge">C union S</code> and modify it and we hope these modifications will create a system that satisfies <code class="language-plaintext highlighter-rouge">C union N</code>.
I’ll make a analogy between pull-requests (PRs) and theorem proving… but first a quick reminder:</p>

<p>When proving something new, we start with a set of things we know, and we apply logical steps to the things we already know in order to grow the set of things we know.  More precisely:</p>

<ul>
  <li>When proving something, we start with a set of assumptions. These are the things we know are true, or assume are true.</li>
  <li>To prove something we take small deduction steps.  Deduction rules are rules that were carefully crafted in order not to change the truth of a system; they can add truths we didn’t know before, but they can’t add a falsehood.</li>
  <li>So we start with the assumptions, cleverly apply deduction steps, and hope to arrive at a conclusion.</li>
</ul>

<p>The analogy with theorem proving is the following:</p>

<ul>
  <li>Our set of assumption is <code class="language-plaintext highlighter-rouge">C union S</code>, meaning, it’s how the system behaves today</li>
  <li>In order to get to <code class="language-plaintext highlighter-rouge">C union N</code>, we make small modifications starting from <code class="language-plaintext highlighter-rouge">C union S</code>.  Each modification is provably correct (we can look at the modification and see that it is correct).</li>
  <li>After a sequence of incontestable modifications, we arrive at <code class="language-plaintext highlighter-rouge">C union N</code>.</li>
</ul>

<p><code class="language-plaintext highlighter-rouge">C union S</code> –PR1–&gt; <code class="language-plaintext highlighter-rouge">C_1</code> –PR2–&gt; <code class="language-plaintext highlighter-rouge">C_2</code> –&gt; … – PRN –&gt; <code class="language-plaintext highlighter-rouge">C union N</code></p>

<p>Observations:</p>

<ul>
  <li>A proof is the sequence of steps from a set of assumptions to a conclusion.</li>
  <li>Stating a conclusion is not the same as proving the conclusion.</li>
</ul>

<p>Transferring that back to AI and pull requests:</p>

<ul>
  <li>I can see that a modification to the system is correct when I reasonably understand the existing system (the assumptions) and I can see the steps that lead it to a new system (the sequence of small PRs in between).</li>
  <li>A very large PR that is not understandable is like stating a conclusion without giving any proof of the conclusion!</li>
</ul>

<p>Trusting a large PR created by an AI without understanding it is like trusting a conclusion without understanding the assumptions and the reasoning behind it.</p>]]></content><author><name>Daniel Fava</name></author><category term="software-engineering" /><summary type="html"><![CDATA[With AI doing so much coding, the bottleneck has become reviews. What do we do with those pull requests with thousand of lines of changes that the AI has created? Do we trust it and merge it? Do we spend the time to review it? It might have taken 20 minutes to create the PR, but if it takes 2 days to review it, have we gained in efficiency? There are many axis we can use to evaluate a change; for example: syntactical (typically easy to review, lower risk) versus semantical changes (typically harder to review, higher risk) changes in the critical path (e.g. movement of money) versus less critical (e.g. backoffice changes) reversible changes versus non-reversible ones (or reversible but incurring a large amount of clean-up effort) In of all of these dimensions, there are subspaces where I’m totally fine with large changes driven by AI. And there are some spaces where AI changes and AI reviewers should (IMHO) be driven and understood by a human. My wish is that AI will help us undertake the huge yet boring refactorings that we keep of pushing into the future; like replacing libraries that are old and deprecated but that we don’t dare to replace because the function signatures changed and the refactoring would touch thousand of lines in hundreds of files. These are the types of changes are large (boring to be made by a human), but easy for AI and easy for a human to review. What I really dislike is changes that are large and modify logic (as opposed to being syntactical).  Those types of changes (semantic changes) are hard to review and carry a lot of risk.  We need to try to break these down into paletable chunks that are digestible by a human.  I’m not quite ready to let an AI take care of banking accounting systems, for example. It’s too risky; it would be a recipe for disaster.]]></summary></entry><entry><title type="html">Late bloomer: Reflections on Becoming a Tech Lead</title><link href="http://danielfava.com/leadership/2025/09/22/tech-lead.html" rel="alternate" type="text/html" title="Late bloomer: Reflections on Becoming a Tech Lead" /><published>2025-09-22T09:00:00+00:00</published><updated>2025-09-22T09:00:00+00:00</updated><id>http://danielfava.com/leadership/2025/09/22/tech-lead</id><content type="html" xml:base="http://danielfava.com/leadership/2025/09/22/tech-lead.html"><![CDATA[<p>I started doing low-level programming and architecture at Intel and Apple, then I got a PhD and dabbled in academia.  But it wasn’t until I re-joined industry as a high-level software developer that became a tech lead.  And despite my degrees and experience, I still felt uncomfortable with the role.</p>

<p>The truth is, I have an ambivalent attitude towards responsibility.  A former manager of mine once said I had an over-inflated sense of responsibility (I’m pretty sure he didn’t mean it as a compliment).  I felt hunted by questions like, what if I don’t know what to do or make the wrong call?  What if the circumstance demands my attention but I’m unavailable because I’m feeling disconnected, scared, or sad?  Being an individual contributor (as opposed to a lead) allowed me to take on responsibility without risking divulging the ups and downs of my internal existence.</p>

<p>I knew I was chickening out.  The technical name for it is <em>avoidance behavior</em>.  But eventually I felt like I could lean on my colleagues for guidance and moral support, and so I took the tech lead role.</p>

<!--more-->

<h2 id="help-me-help-you">Help me, help you</h2>

<p>I had recently joined the team when I became tech lead.  That forced me to revisit my romanticized view on infallibility and leadership.  (When a disciple asks a question, a Zen master will sometimes make a silly looking face.  By deliberately embarrassing him/herself, the master quickly moves past the fear of looking foolish, which frees his/her mind to focus on what matters.)  Similarly, I was the first to voice my shortcomings as a newcomer, and I encouraged the team to guide me.</p>

<h2 id="company-over-team-team-over-individual">Company over team, team over individual</h2>

<p>In fact, we needed the full engagement of the team.  We were working on a complex and timely corporate merger.  A colleague of mine likened it to assembling and airplane while in free fall.  It was frantic and chaotic.  Operational instability and incident handling took a lot of our focus.  I took on tasks that helped me build my knowledge portfolio while also contributing to the team’s mission.  For example, I refactored code that had been neglected during the great reshuffle and automated tasks that sapped attention from the team.  I am learning to be more of an <em>enabler</em> than an individual contributor.  (Although I still enjoy programming and making direct technical contributions)</p>

<h2 id="conclusion">Conclusion</h2>

<p>Work is not separate from life as a whole; we can only compartmentalize so much.  I started my career focusing mostly on the tech.  Today I’m more interested in <em>how I work</em> and <em>who I work with</em> rather than with <em>what I work on</em>.  I’m looking to create a positive feedback loop, with work improving my personal life and vice-versa.  Being a tech lead, I felt vulnerable but also lucky to be surrounded by people who are helping me become a better version of myself.</p>]]></content><author><name>Daniel Fava</name></author><category term="leadership" /><summary type="html"><![CDATA[I started doing low-level programming and architecture at Intel and Apple, then I got a PhD and dabbled in academia. But it wasn’t until I re-joined industry as a high-level software developer that became a tech lead. And despite my degrees and experience, I still felt uncomfortable with the role. The truth is, I have an ambivalent attitude towards responsibility. A former manager of mine once said I had an over-inflated sense of responsibility (I’m pretty sure he didn’t mean it as a compliment). I felt hunted by questions like, what if I don’t know what to do or make the wrong call? What if the circumstance demands my attention but I’m unavailable because I’m feeling disconnected, scared, or sad? Being an individual contributor (as opposed to a lead) allowed me to take on responsibility without risking divulging the ups and downs of my internal existence. I knew I was chickening out. The technical name for it is avoidance behavior. But eventually I felt like I could lean on my colleagues for guidance and moral support, and so I took the tech lead role.]]></summary></entry><entry><title type="html">What I think about when I think about music</title><link href="http://danielfava.com/music/2025/05/17/music.html" rel="alternate" type="text/html" title="What I think about when I think about music" /><published>2025-05-17T09:00:00+00:00</published><updated>2025-05-17T09:00:00+00:00</updated><id>http://danielfava.com/music/2025/05/17/music</id><content type="html" xml:base="http://danielfava.com/music/2025/05/17/music.html"><![CDATA[<p>Recently I started to learn the piano on my own.
With an app installed on my phone, I began to learn from the very beginning.
Eventually I bumped into questions about music theory, so I incorporated ChatGPT and YouTube as learning partners.</p>

<p>I figured that being inspired by music in general would keep my motivation,
so I started reading a book,
:book: <a href="https://en.wikipedia.org/wiki/Absolutely_on_Music">Absolutely on music</a>,
that is a conversation between the author and an orchestra conductor.
One interesting thing about the book is that you can listen to the pieces they are talking.</p>

<p>This opened a fantastic door for me, which I continue to explore with the help of ChatGPT even after finishing the book.
Here is a collection of conversations with ChatGPT that I’ve found interesting.</p>

<!--more-->

<p>The first is a conversation about the end of the romantic period, the industrial revolution, postmodernism, and the contemporary classical music: <a href="/music/postmodernism.html">Postmodernism, the industrial revolution, and contemporary classical music</a>.</p>

<p>This one is part of a conversation about Mahler where ChatGPT called a piece of music philosophical, and we explored what that meant:
<a href="/music/marhler_philosophical_music.html">Mahler and what it means for music to be philosophical</a>.</p>

<p>One about <a href="/music/brahsm_and_beethoven.html">Brahms as a continuation of Beethoven</a>.</p>

<p>This one is about something called <em>period music</em>, which means trying to mimic the instruments of the time that the music was composed.  Music played with period instruments sounds subtlety different: <a href="/music/period_music.html">Period music and listening to subtleties</a>.</p>

<p>A short conversation about a niche type of music called <a href="/music/twelve_tone.html">twelve tone music</a>, where all notes are used.</p>

<p>A short conversation on <a href="/music/stravinsky.html">Stravinsky’s <em>Le Sacre du Printemps</em> and his arrest</a>.</p>]]></content><author><name>Daniel Fava and ChatGPT</name></author><category term="music" /><summary type="html"><![CDATA[Recently I started to learn the piano on my own. With an app installed on my phone, I began to learn from the very beginning. Eventually I bumped into questions about music theory, so I incorporated ChatGPT and YouTube as learning partners. I figured that being inspired by music in general would keep my motivation, so I started reading a book, :book: Absolutely on music, that is a conversation between the author and an orchestra conductor. One interesting thing about the book is that you can listen to the pieces they are talking. This opened a fantastic door for me, which I continue to explore with the help of ChatGPT even after finishing the book. Here is a collection of conversations with ChatGPT that I’ve found interesting.]]></summary></entry><entry><title type="html">You get what you measure</title><link href="http://danielfava.com/socio/2024/04/25/performance.html" rel="alternate" type="text/html" title="You get what you measure" /><published>2024-04-25T08:50:00+00:00</published><updated>2024-04-25T08:50:00+00:00</updated><id>http://danielfava.com/socio/2024/04/25/performance</id><content type="html" xml:base="http://danielfava.com/socio/2024/04/25/performance.html"><![CDATA[<p>This is a short post on how measuring performance can backfire.  So you are trying to foster a culture and you decide to measure how close (or far) your organization is from that culture.  Although your intentions are good, your efforts can backfire. You can end up with a culture that is the opposite from what you intended in the first place.</p>

<p>We will walk through two ideas which, put together, lead to the concept of <em>“you get what you measure.”</em>  We then close with what this could mean for your organization.</p>

<!--more-->

<h2 id="measurement-influences-behavior">Measurement influences behavior</h2>

<p>Think about the difference between measuring the length of a house versus measuring people’s kindness.
Unlike measuring inanimate objects, measuring <a href="https://en.wikipedia.org/wiki/Adaptive_system">adaptive systems</a> is difficult.  An adaptive system is a system that reacts to being measured.  So, the act of measuring influences the outcome.</p>

<p>Different from measuring length of inanimate objects, if you measure people’s kindness, people will tend to act kinder.  You can never get to the actual truth–there will always a bias in the measurement.
That can be good.  By measuring kindness, kinder people.  Win!</p>

<h2 id="a-measurement-is-a-proxy-not-the-actual-attribute">A measurement is a proxy, not the actual attribute</h2>

<p>The second idea is the idea that a measurement is a proxy, and a proxy is not the actual attribute.</p>

<p>Going back to kindness, how would you measure it?
Kindness is an abstract concept.  You can’t measure it directly, but you can try to quantify it by measuring a proxy for kindness.<br />
For example, maybe you measure whether a person makes charitable contributions, whether they sent you a message on your birthday, or whether they tend to hold the door for the next person coming in line.</p>

<p>This <a href="https://en.wikipedia.org/wiki/Zen#cite_note-FOOTNOTESuzuki1997154-135">Zen buddhist</a> saying
<em>“don’t mistake the moon by the finger pointing at the moon”</em>
can help us remember the distinction between an attribute and it’s proxy.</p>

<h2 id="you-get-what-you-measure">You get what you measure</h2>

<p>So, the combination of (1) adaptive system and (2) measurement-by-proxy has a catchphrase: <em>you get what you measure.</em>
Here is an exaggerated example:</p>

<p>You have a customer support center where people look into tickets created when a customer calls with a complaint.  You want to measure and improve the quality of this organization.</p>

<p>If you measure quality by how fast tickets are closed, analysts will find the easiest answers to the complains and close the ticket with “xyz is likely the culprit” without doing due diligence.  So customers will have to call back with the same complaint, and new tickets will be opened for the same issue.  On paper, you are closing tickets faster than ever!  In practice, your customers are getting pretty frustrated because their problems are not being addressed.</p>

<p>Say you decide to measure quality by how fast tickets are responded to (as opposed to how fast they are closed).  Then someone will create a bot that fills the new tickets with messages like <em>“Looking into it..”</em>  All tickets get an initial response, never mind the fact that the response is useless.</p>

<p>Once you have put a system in place to measure (1) an adaptive system that (2) can only the quantified via a proxy, then <em>you get what you measure</em>.  And what you measure is not necessarily what you want to foster.  No matter how complex you make the metrics, there will come a point where optimizing for the metric will clash with simply “doing the right thing.”</p>

<h2 id="over-time">Over time</h2>

<p>You are probably thinking: “That’s a pretty cynical view on people!” or “The people I work with are not like you describe”.
You are right!  Your employees or co-workers are not like that.. at least not now.  But they may become more selfish once you put a performance measurement system into practice.  The reason is that performance measurement systems put people on the spot. They have to solve a dilema: do I improve the metric or do I “do the right thing”?</p>

<p>May people will be altruistic.  They want to do the right thing.  Plus, if the company isn’t doing well, no one will do well.  So it’s logical to look after the health of the company. But one bad apple is all it takes to shift behavior.</p>

<p>Although you may not notice when one person in your organization puts benefiting themselves over “the right thing”, other closer by will.  People have beliefs and values (call it a compass), and they will not change their behavior because of one or two more self-centered individuals.  Many of your employees will keep doing “the right thing”, but a few of them may decide to “do the right thing” somewhere else.  Over time, the frustration of seeing a bad apple benefitting themselves will crumble your employees’ motivation .  They will get tired of being put on the spot and forced to choose between “the right thing” and the metric.  You can’t blame them.  It’s not a fair situation to be in in the first place.</p>

<p>So, over time, the system will select for the less altruistic of us, and eventually the company will look the opposite of what the performance-measurement system intended to foster.</p>

<h2 id="what-then">What then</h2>

<p>Okay.. but if we shouldn’t measure performance, what can we do instead?</p>

<p>If the goal is to foster behavior, then create a culture that allows for this behavior to flourish.  The shift is from <em>measuring people</em> to <em>enabling them</em>.  Embrace the fact that none of this is a hard science, and stop trying to put a number on something that can’t be properly quantified.  Encourage discussions on culture instead.</p>]]></content><author><name>Daniel Fava</name></author><category term="socio" /><summary type="html"><![CDATA[This is a short post on how measuring performance can backfire. So you are trying to foster a culture and you decide to measure how close (or far) your organization is from that culture. Although your intentions are good, your efforts can backfire. You can end up with a culture that is the opposite from what you intended in the first place. We will walk through two ideas which, put together, lead to the concept of “you get what you measure.” We then close with what this could mean for your organization.]]></summary></entry><entry><title type="html">Go, Scala and case classes</title><link href="http://danielfava.com/programming-languages/2023/03/14/caseclasses.html" rel="alternate" type="text/html" title="Go, Scala and case classes" /><published>2023-03-14T12:00:00+00:00</published><updated>2023-03-14T12:00:00+00:00</updated><id>http://danielfava.com/programming-languages/2023/03/14/caseclasses</id><content type="html" xml:base="http://danielfava.com/programming-languages/2023/03/14/caseclasses.html"><![CDATA[<p>In this blog post, we will take a look at Go and Scala, and specifically, at their approach to case classes.</p>

<p>One of Scala’s key features is its support for case classes. Case classes are meant for holding immutable data. They are similar to regular classes, but they come with a number of useful features out-of-the-box, such as the ability to generate a toString method, a copy method; they also come with matching support.</p>

<p>Go, on the other hand, does not have built-in support for case classes.  We will look at three different approaches that can be used instead.</p>

<!--more-->

<p>Before we dive into Go, here’s an example of two case classes, <code class="language-plaintext highlighter-rouge">Dollar</code> and <code class="language-plaintext highlighter-rouge">Euro</code>, that extend a common <code class="language-plaintext highlighter-rouge">Currency</code> class in Scala:</p>

<div class="language-scala highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">abstract</span> <span class="k">class</span> <span class="nc">Currency</span><span class="o">(</span><span class="k">val</span> <span class="nv">name</span><span class="k">:</span> <span class="kt">String</span><span class="o">,</span> <span class="k">val</span> <span class="nv">alpha</span><span class="k">:</span> <span class="kt">String</span><span class="o">,</span> <span class="k">val</span> <span class="nv">symbol</span><span class="k">:</span> <span class="kt">String</span><span class="o">)</span>

<span class="k">case</span> <span class="k">class</span> <span class="nc">Dollar</span><span class="o">()</span> <span class="k">extends</span> <span class="nc">Currency</span><span class="o">(</span><span class="s">"US Dollar"</span><span class="o">,</span> <span class="s">"USD, "</span><span class="n">$</span><span class="s">")
case class Euro() extends Currency("</span><span class="nc">Euro</span><span class="s">", "</span><span class="nc">EUR</span><span class="s">", "</span><span class="err">€"</span><span class="o">)</span>

<span class="k">val</span> <span class="nv">dollar</span> <span class="k">=</span> <span class="nc">Dollar</span><span class="o">()</span>
<span class="k">val</span> <span class="nv">euro</span> <span class="k">=</span> <span class="nc">Euro</span><span class="o">()</span>

<span class="nf">println</span><span class="o">(</span><span class="nv">dollar</span><span class="o">.</span><span class="py">name</span><span class="o">)</span>   <span class="c1">// Output: US Dollar</span>
<span class="nf">println</span><span class="o">(</span><span class="nv">dollar</span><span class="o">.</span><span class="py">alpha</span><span class="o">)</span>  <span class="c1">// Output: USD</span>
<span class="nf">println</span><span class="o">(</span><span class="nv">dollar</span><span class="o">.</span><span class="py">symbol</span><span class="o">)</span> <span class="c1">// Output: $</span>
<span class="nf">println</span><span class="o">(</span><span class="nv">euro</span><span class="o">.</span><span class="py">name</span><span class="o">)</span>     <span class="c1">// Output: Euro</span>
<span class="nf">println</span><span class="o">(</span><span class="nv">euro</span><span class="o">.</span><span class="py">alpha</span><span class="o">)</span>    <span class="c1">// Output: EUR</span>
<span class="nf">println</span><span class="o">(</span><span class="nv">euro</span><span class="o">.</span><span class="py">symbol</span><span class="o">)</span>   <span class="c1">// Output: €</span>
</code></pre></div></div>

<p>Next, we’ll try three different approaches to model case classes in Go:</p>

<ol>
  <li>structs</li>
  <li>enums</li>
  <li>interface and “empty” types definitions</li>
</ol>

<h2 id="structs">Structs</h2>

<p>We use structs to hold data.  Going back to the currency example, we can define a <code class="language-plaintext highlighter-rouge">Currency</code> as such:</p>

<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">package</span> <span class="n">main</span>

<span class="k">import</span> <span class="p">(</span>
	<span class="s">"fmt"</span>
<span class="p">)</span>

<span class="k">type</span> <span class="n">Currency</span> <span class="k">struct</span> <span class="p">{</span>
	<span class="n">Name</span>   <span class="kt">string</span>
	<span class="n">Alpha</span>  <span class="kt">string</span>
	<span class="n">Symbol</span> <span class="kt">string</span>
<span class="p">}</span>

<span class="k">type</span> <span class="n">dollar</span> <span class="k">struct</span> <span class="p">{</span>
	<span class="n">Currency</span>
<span class="p">}</span>

<span class="k">type</span> <span class="n">euro</span> <span class="k">struct</span> <span class="p">{</span>
	<span class="n">Currency</span>
<span class="p">}</span>

<span class="k">var</span> <span class="p">(</span>
	<span class="n">Dollar</span> <span class="o">=</span> <span class="n">dollar</span><span class="p">{</span><span class="n">Currency</span><span class="p">{</span><span class="s">"US Dollar"</span><span class="p">,</span> <span class="s">"USD"</span><span class="p">,</span> <span class="s">"$"</span><span class="p">}}</span>
	<span class="n">Euro</span>   <span class="o">=</span> <span class="n">euro</span><span class="p">{</span><span class="n">Currency</span><span class="p">{</span><span class="s">"Euro"</span><span class="p">,</span> <span class="s">"EUR"</span><span class="p">,</span> <span class="s">"€"</span><span class="p">}}</span>
<span class="p">)</span>

<span class="k">func</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
	<span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="n">Dollar</span><span class="o">.</span><span class="n">Name</span><span class="p">)</span>   <span class="c">// Output: US Dollar</span>
	<span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="n">Dollar</span><span class="o">.</span><span class="n">Alpha</span><span class="p">)</span>  <span class="c">// Output: USD</span>
	<span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="n">Dollar</span><span class="o">.</span><span class="n">Symbol</span><span class="p">)</span> <span class="c">// Output: $</span>
	<span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="n">Euro</span><span class="o">.</span><span class="n">Name</span><span class="p">)</span>     <span class="c">// Output: Euro</span>
	<span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="n">Euro</span><span class="o">.</span><span class="n">Alpha</span><span class="p">)</span>    <span class="c">// Output: EUR</span>
	<span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="n">Euro</span><span class="o">.</span><span class="n">Symbol</span><span class="p">)</span>   <span class="c">// Output: €</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="enums">Enums</h2>

<p>Enums, short for enumerations, are a type in programming that allows you to define a set of named values. They are used to represent a fixed set of possible values for a variable, parameter, or property.</p>

<p>Here is an alternative implementation to our “currency” example.  In this implementation, we are removing information from the structs and putting it in methods.  If you squint, you can see the interplay between <a href="">data and code</a>:  Functions can be implemented as table look-ups, where the function’s behavior is precomputed and stored in a data structure, rather than being computed on the fly.  Conversely, data can sometimes be computed or generated on-the-fly by code, rather than being stored.</p>

<p>The struct here would only have to hold one integer for each currency… so there is no point of a struct at all!  Instead of a struct holding an integer, we just have the integer.  And we have one integer value for each currency.  In other words, the struct collapses into an enum.</p>

<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">package</span> <span class="n">main</span>

<span class="k">import</span> <span class="p">(</span>
    <span class="s">"fmt"</span>
<span class="p">)</span>

<span class="k">type</span> <span class="n">Currency</span> <span class="kt">int</span>

<span class="k">const</span> <span class="p">(</span>
    <span class="n">Dollar</span> <span class="n">Currency</span> <span class="o">=</span> <span class="no">iota</span>
    <span class="n">Euro</span>
<span class="p">)</span>

<span class="k">func</span> <span class="p">(</span><span class="n">c</span> <span class="n">Currency</span><span class="p">)</span> <span class="n">String</span><span class="p">()</span> <span class="kt">string</span> <span class="p">{</span>
    <span class="k">switch</span> <span class="n">c</span> <span class="p">{</span>
    <span class="k">case</span> <span class="n">Dollar</span><span class="o">:</span>
        <span class="k">return</span> <span class="s">"US Dollar"</span>
    <span class="k">case</span> <span class="n">Euro</span><span class="o">:</span>
        <span class="k">return</span> <span class="s">"Euro"</span>
    <span class="k">default</span><span class="o">:</span>
        <span class="k">return</span> <span class="s">"Unknown"</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">func</span> <span class="p">(</span><span class="n">c</span> <span class="n">Currency</span><span class="p">)</span> <span class="n">Alpha</span><span class="p">()</span> <span class="kt">string</span> <span class="p">{</span>
    <span class="k">switch</span> <span class="n">c</span> <span class="p">{</span>
    <span class="k">case</span> <span class="n">Dollar</span><span class="o">:</span>
        <span class="k">return</span> <span class="s">"USD"</span>
    <span class="k">case</span> <span class="n">Euro</span><span class="o">:</span>
        <span class="k">return</span> <span class="s">"EUR"</span>
    <span class="k">default</span><span class="o">:</span>
        <span class="k">return</span> <span class="s">"Unknown"</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">func</span> <span class="p">(</span><span class="n">c</span> <span class="n">Currency</span><span class="p">)</span> <span class="n">Symbol</span><span class="p">()</span> <span class="kt">string</span> <span class="p">{</span>
    <span class="k">switch</span> <span class="n">c</span> <span class="p">{</span>
    <span class="k">case</span> <span class="n">Dollar</span><span class="o">:</span>
        <span class="k">return</span> <span class="s">"$"</span>
    <span class="k">case</span> <span class="n">Euro</span><span class="o">:</span>
        <span class="k">return</span> <span class="s">"€"</span>
    <span class="k">default</span><span class="o">:</span>
        <span class="k">return</span> <span class="s">"?"</span>
    <span class="p">}</span>
<span class="p">}</span>

<span class="k">func</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span>
    <span class="n">dollar</span> <span class="o">:=</span> <span class="n">Dollar</span>
    <span class="n">euro</span> <span class="o">:=</span> <span class="n">Euro</span>

    <span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="n">dollar</span><span class="o">.</span><span class="n">String</span><span class="p">())</span> <span class="c">// Output: US Dollar</span>
    <span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="n">Symbol</span><span class="p">(</span><span class="n">dollar</span><span class="p">))</span>  <span class="c">// Output: $</span>
    <span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="n">euro</span><span class="o">.</span><span class="n">String</span><span class="p">())</span>   <span class="c">// Output: Euro</span>
    <span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="n">Symbol</span><span class="p">(</span><span class="n">euro</span><span class="p">))</span>    <span class="c">// Output: €</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="empty-struct">Empty struct</h2>

<p>We can push this interplay between data and code further.  We don’t need an integer for each currency, we can have that information in the type itself.  With this approach, the struct is empty.</p>

<p>We define the <code class="language-plaintext highlighter-rouge">Currency</code> type as an interface, and each currency then implements this interface accordingly:</p>

<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">package</span> <span class="n">currency</span>

<span class="k">type</span> <span class="n">Currency</span> <span class="k">interface</span> <span class="p">{</span>
	<span class="n">String</span><span class="p">()</span> <span class="kt">string</span>
	<span class="n">Alpha</span><span class="p">()</span> <span class="kt">string</span>
	<span class="n">Symbol</span><span class="p">()</span> <span class="kt">string</span>
	<span class="n">IsValid</span><span class="p">()</span> <span class="kt">bool</span>
<span class="p">}</span>

<span class="k">type</span> <span class="n">dollar</span> <span class="k">struct</span><span class="p">{}</span>
<span class="k">type</span> <span class="n">euro</span> <span class="k">struct</span><span class="p">{}</span>
<span class="k">type</span> <span class="n">empty</span> <span class="k">struct</span><span class="p">{}</span>

<span class="k">var</span> <span class="p">(</span>
	<span class="n">Dollar</span> <span class="o">=</span> <span class="n">dollar</span><span class="p">{}</span>
	<span class="n">Euro</span>   <span class="o">=</span> <span class="n">euro</span><span class="p">{}</span>
	<span class="n">Empty</span>  <span class="o">=</span> <span class="n">empty</span><span class="p">{}</span>
<span class="p">)</span>

<span class="c">// Dollars</span>
<span class="k">func</span> <span class="p">(</span><span class="n">dollar</span><span class="p">)</span> <span class="n">String</span><span class="p">()</span> <span class="kt">string</span> <span class="p">{</span>
	<span class="k">return</span> <span class="s">"US Dollar"</span>
<span class="p">}</span>

<span class="k">func</span> <span class="p">(</span><span class="n">dollar</span><span class="p">)</span> <span class="n">Alpha</span><span class="p">()</span> <span class="kt">string</span> <span class="p">{</span>
	<span class="k">return</span> <span class="s">"USD"</span>
<span class="p">}</span>

<span class="k">func</span> <span class="p">(</span><span class="n">dollar</span><span class="p">)</span> <span class="n">Symbol</span><span class="p">()</span> <span class="kt">string</span> <span class="p">{</span>
	<span class="k">return</span> <span class="s">"$"</span>
<span class="p">}</span>

<span class="k">func</span> <span class="p">(</span><span class="n">dollar</span><span class="p">)</span> <span class="n">Valid</span><span class="p">()</span> <span class="kt">bool</span> <span class="p">{</span>
	<span class="k">return</span> <span class="no">true</span>
<span class="p">}</span>

<span class="c">// Euros</span>
<span class="k">func</span> <span class="p">(</span><span class="n">euro</span><span class="p">)</span> <span class="n">String</span><span class="p">()</span> <span class="kt">string</span> <span class="p">{</span>
	<span class="k">return</span> <span class="s">"Euro"</span>
<span class="p">}</span>

<span class="k">func</span> <span class="p">(</span><span class="n">euro</span><span class="p">)</span> <span class="n">Alpha</span><span class="p">()</span> <span class="kt">string</span> <span class="p">{</span>
	<span class="k">return</span> <span class="s">"EUR"</span>
<span class="p">}</span>

<span class="k">func</span> <span class="p">(</span><span class="n">euro</span><span class="p">)</span> <span class="n">Symbol</span><span class="p">()</span> <span class="kt">string</span> <span class="p">{</span>
	<span class="k">return</span> <span class="s">"€"</span>
<span class="p">}</span>

<span class="k">func</span> <span class="p">(</span><span class="n">euro</span><span class="p">)</span> <span class="n">Valid</span><span class="p">()</span> <span class="kt">bool</span> <span class="p">{</span>
	<span class="k">return</span> <span class="no">true</span>
<span class="p">}</span>

<span class="c">// A zero value for the class</span>
<span class="k">func</span> <span class="p">(</span><span class="n">empty</span><span class="p">)</span> <span class="n">String</span><span class="p">()</span> <span class="kt">string</span> <span class="p">{</span>
	<span class="nb">panic</span><span class="p">(</span><span class="s">"attempting to access an invalid currency"</span><span class="p">)</span>
<span class="p">}</span>

<span class="k">func</span> <span class="p">(</span><span class="n">empty</span><span class="p">)</span> <span class="n">Alpha</span><span class="p">()</span> <span class="kt">string</span> <span class="p">{</span>
	<span class="nb">panic</span><span class="p">(</span><span class="s">"attempting to access an invalid currency"</span><span class="p">)</span>
<span class="p">}</span>

<span class="k">func</span> <span class="p">(</span><span class="n">empty</span><span class="p">)</span> <span class="n">Symbol</span><span class="p">()</span> <span class="kt">string</span> <span class="p">{</span>
	<span class="nb">panic</span><span class="p">(</span><span class="s">"attempting to access an invalid currency"</span><span class="p">)</span>
<span class="p">}</span>

<span class="k">func</span> <span class="p">(</span><span class="n">empty</span><span class="p">)</span> <span class="n">Valid</span><span class="p">()</span> <span class="kt">bool</span> <span class="p">{</span>
	<span class="k">return</span> <span class="no">false</span>
<span class="p">}</span>
</code></pre></div></div>

<h2 id="comparison">Comparison</h2>

<p>The three approaches above have their pros and cons.</p>

<ol>
  <li>struct
    <ul>
      <li><em>pros:</em> the variable <code class="language-plaintext highlighter-rouge">structs.currency.Dollar</code> cannot be redefined; the variable is of type <code class="language-plaintext highlighter-rouge">dollar</code> and these types are unexported.</li>
      <li><em>cons:</em> we expose the internal structure to library clients</li>
    </ul>
  </li>
  <li>enums
    <ul>
      <li><em>pros:</em> currencies like <code class="language-plaintext highlighter-rouge">enum.currency.Dollar</code> are defined as <code class="language-plaintext highlighter-rouge">const</code>, so they cannot be re-assigned</li>
      <li><em>cons:</em> we need to implement accessor methods (those methods don’t come for free)</li>
    </ul>
  </li>
  <li>empty struct; information in the type
    <ul>
      <li><em>pros:</em> the variable <code class="language-plaintext highlighter-rouge">emptystruct.currency.Dollar</code> cannot be redefined; the variable is of type <code class="language-plaintext highlighter-rouge">dollar</code> and these types are unexported.  We have well defined interfaces.</li>
      <li><em>cons:</em> we need to implement accessor methods (those methods don’t come for free in Go, like they do in Scala)</li>
    </ul>
  </li>
</ol>

<p>To me, option (3) is what comes the closest to case classes.  Unfortunately, options (3) is not very idiomatic Go.  That option also relies more heavily on the capabilities of the type system.  And that’s where things start to go wrong for Go.  To illustrate, let’s look at marshaling.</p>

<h2 id="marshaling-and-unmarshaling">Marshaling and Unmarshaling</h2>

<p>Marshaling is the process of converting an object or data structure from its in-memory representation to a format that can be stored or transmitted. In other words, marshaling takes an object in a program’s memory and converts it to a format that can be written to disk, sent over a network, or otherwise persisted.</p>

<p>It is trivial to marshal and unmarshal structs as in example (1) and enums, like in example (2).  When marshaling a struct, you do structural decomposition of the struct’s elements until you get to elementary data types.  Thankfully, the <code class="language-plaintext highlighter-rouge">json</code> package does that for us, so we don’t even think about this decomposition.</p>

<p>Marshaling for (3) is also easy:</p>

<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">jsonData</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">json</span><span class="o">.</span><span class="n">Marshal</span><span class="p">(</span><span class="n">currency</span><span class="o">.</span><span class="n">Dollar</span><span class="p">)</span>
<span class="k">if</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span>
    <span class="nb">println</span><span class="p">(</span><span class="n">err</span><span class="o">.</span><span class="n">Error</span><span class="p">())</span>
<span class="p">}</span>
</code></pre></div></div>

<p>How about unmarshal?</p>

<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">var</span> <span class="n">d</span> <span class="n">currency</span><span class="o">.</span><span class="n">Currency</span>
<span class="n">err</span> <span class="o">=</span> <span class="n">json</span><span class="o">.</span><span class="n">Unmarshal</span><span class="p">(</span><span class="n">jsonData</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">d</span><span class="p">)</span>
<span class="k">if</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span>
    <span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"Error unmarshaling JSON:"</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span>
<span class="p">}</span>
</code></pre></div></div>

<p>The code above gives a runtime error: <code class="language-plaintext highlighter-rouge">Error unmarshaling JSON: json: cannot unmarshal object into Go value of type currency.Currency</code>.  If we trace through the json package, we see the following stack trace:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>json.Unmarshal
  json.(*decodeState).unmarshal
    json.(*decodeState).value
      json.(*decodeState).object
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">object()</code> function is trying to figure out what we are unmarshaling into.  It can unmarshal to the empty interface:</p>

<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">if</span> <span class="n">v</span><span class="o">.</span><span class="n">Kind</span><span class="p">()</span> <span class="o">==</span> <span class="n">reflect</span><span class="o">.</span><span class="n">Interface</span> <span class="o">&amp;&amp;</span> <span class="n">v</span><span class="o">.</span><span class="n">NumMethod</span><span class="p">()</span> <span class="o">==</span> <span class="m">0</span> <span class="p">{</span>
    <span class="n">oi</span> <span class="o">:=</span> <span class="n">d</span><span class="o">.</span><span class="n">objectInterface</span><span class="p">()</span>
    <span class="n">v</span><span class="o">.</span><span class="n">Set</span><span class="p">(</span><span class="n">reflect</span><span class="o">.</span><span class="n">ValueOf</span><span class="p">(</span><span class="n">oi</span><span class="p">))</span>
    <span class="k">return</span> <span class="no">nil</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Otherwise, the <code class="language-plaintext highlighter-rouge">object()</code> function checks if the kind of the target is a map or a struct.  If it is neither, it returns the error we’ve seen:</p>

<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">default</span><span class="o">:</span>
    <span class="n">d</span><span class="o">.</span><span class="n">saveError</span><span class="p">(</span><span class="o">&amp;</span><span class="n">UnmarshalTypeError</span><span class="p">{</span><span class="n">Value</span><span class="o">:</span> <span class="s">"object"</span><span class="p">,</span> <span class="n">Type</span><span class="o">:</span> <span class="n">t</span><span class="p">,</span> <span class="n">Offset</span><span class="o">:</span> <span class="kt">int64</span><span class="p">(</span><span class="n">d</span><span class="o">.</span><span class="n">off</span><span class="p">)})</span>
    <span class="n">d</span><span class="o">.</span><span class="n">skip</span><span class="p">()</span>
    <span class="k">return</span> <span class="no">nil</span>
</code></pre></div></div>

<p>Maybe you are thinking… “wait a minute, how can the unmarshaler be able to tell what object it’s dealing with?”  Let’s make the example simpler.  Say we write a marshaler that marshals our currency into strings like “Dollar” and “Euro”.  Then what we want the unmarshaler to do is simple:</p>

<ol>
  <li>Parse the JSON, unmarshal it as a string, then check:</li>
  <li>If the string is “Euro”, return <code class="language-plaintext highlighter-rouge">euro{}</code>.  If the string is “Dollar” return <code class="language-plaintext highlighter-rouge">dollar{}</code>.  Otherwise, return <code class="language-plaintext highlighter-rouge">empty{}</code>.</li>
</ol>

<p>Unfortunately, if we try to force the default unmarshaler down this path, we again get a <code class="language-plaintext highlighter-rouge">json: cannot unmarshal string into Go value of type currency.Currency</code> error.  The call stack is a bit different:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>json.Unmarshal
  json.(*decodeState).unmarshal
    json.(*decodeState).value
      json.(*decodeState).object
        json.(*decodeState).literalStore
</code></pre></div></div>

<p>We to get a bit deeper into the decoder.  The error message is now coming from <code class="language-plaintext highlighter-rouge">literalStore()</code>.  At this point, the unmarshaler has determined that it’s unmarshaling a string and it is trying to put it into an interface.  Inside <code class="language-plaintext highlighter-rouge">literalStore()</code> we see this:</p>

<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">case</span> <span class="n">reflect</span><span class="o">.</span><span class="n">Interface</span><span class="o">:</span>
    <span class="k">if</span> <span class="n">v</span><span class="o">.</span><span class="n">NumMethod</span><span class="p">()</span> <span class="o">==</span> <span class="m">0</span> <span class="p">{</span>
        <span class="n">v</span><span class="o">.</span><span class="n">Set</span><span class="p">(</span><span class="n">reflect</span><span class="o">.</span><span class="n">ValueOf</span><span class="p">(</span><span class="kt">string</span><span class="p">(</span><span class="n">s</span><span class="p">)))</span>
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
        <span class="n">d</span><span class="o">.</span><span class="n">saveError</span><span class="p">(</span><span class="o">&amp;</span><span class="n">UnmarshalTypeError</span><span class="p">{</span><span class="n">Value</span><span class="o">:</span> <span class="s">"string"</span><span class="p">,</span> <span class="n">Type</span><span class="o">:</span> <span class="n">v</span><span class="o">.</span><span class="n">Type</span><span class="p">(),</span> <span class="n">Offset</span><span class="o">:</span> <span class="kt">int64</span><span class="p">(</span><span class="n">d</span><span class="o">.</span><span class="n">readIndex</span><span class="p">())})</span>
    <span class="p">}</span>
</code></pre></div></div>

<p>Again, when trying to unmarshal into an interface, the unmarshaler checks the number of methods declared by the interface.  If there is one or more methods declared, the unmarshaler errors out.  So it’s possible to unmarshal to an empty interface, but we can’t unmarshal to <code class="language-plaintext highlighter-rouge">Currency</code> because <code class="language-plaintext highlighter-rouge">Currency</code> declares several methods.</p>

<p>We want to somehow tell the unmarshaler to use custom logic when dealing with the <code class="language-plaintext highlighter-rouge">Currency</code> interface.  We could then implement this logic in the currency package alongside the interface.  The algorithm would work for all known currencies (USD, EUR, etc).  By “known” I mean currencies known at compile time.  The method would check if the string is <code class="language-plaintext highlighter-rouge">Dollar</code> and create the dollar type, similar for <code class="language-plaintext highlighter-rouge">Euro</code> and etc.  We want something like this:</p>

<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">func</span> <span class="n">UnmarshalJSON</span><span class="p">(</span><span class="n">data</span> <span class="p">[]</span><span class="kt">byte</span><span class="p">)</span> <span class="p">(</span><span class="n">Currency</span><span class="p">,</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span>
    <span class="k">var</span> <span class="n">s</span> <span class="kt">string</span>
    <span class="k">if</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">json</span><span class="o">.</span><span class="n">Unmarshal</span><span class="p">(</span><span class="n">data</span><span class="p">,</span> <span class="o">&amp;</span><span class="n">s</span><span class="p">);</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span>
        <span class="k">return</span> <span class="n">Empty</span><span class="p">,</span> <span class="n">err</span>
    <span class="p">}</span>
    <span class="k">switch</span> <span class="p">(</span><span class="n">s</span><span class="p">)</span> <span class="p">{</span>
      <span class="k">case</span> <span class="s">"USD"</span><span class="o">:</span>
        <span class="k">return</span> <span class="n">Dollar</span><span class="p">,</span> <span class="no">nil</span>
      <span class="k">case</span> <span class="s">"EUR"</span><span class="o">:</span>
        <span class="k">return</span> <span class="n">Euro</span><span class="p">,</span> <span class="no">nil</span>
      <span class="k">default</span><span class="o">:</span>
        <span class="k">return</span> <span class="n">Empty</span><span class="p">,</span> <span class="s">"Invalid currency"</span>
    <span class="p">}</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Even if this were possible in Go and the json package, what happens if someone creates a new currency by implementing the interface methods?</p>

<h3 id="sealed-interfaces">Sealed interfaces</h3>

<p>Say we managed to ship the currency package out.  Then someone comes along and implements another currency; the Brazilian Real, for example. What should our custom unmarshaler do when it encounters this new currency?  Since the unmarshaler was implemented before this new currency, it will not recognize that currency and will return the empty one instead along with an error.  What can the currency package managers do about this?</p>

<p>Scala faces a similar issue, and it offers a couple of solutions:</p>

<ul>
  <li>we can prevent classes from being extended by declaring them as <code class="language-plaintext highlighter-rouge">final</code>, or</li>
  <li>we can define a <code class="language-plaintext highlighter-rouge">sealed</code> trait. A <code class="language-plaintext highlighter-rouge">sealed</code> trait can only be extended in the same source file it is declared.</li>
</ul>

<p>In Go, we can get a similar effect as sealed traits by adding an unexported function signature to the interface.  For example:</p>

<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">type</span> <span class="n">Currency</span> <span class="k">interface</span> <span class="p">{</span>
	<span class="n">Name</span><span class="p">()</span> <span class="kt">string</span>
	<span class="n">Alpha</span><span class="p">()</span> <span class="kt">string</span>
	<span class="n">Symbol</span><span class="p">()</span> <span class="kt">string</span>
    <span class="n">IsValid</span><span class="p">()</span> <span class="kt">bool</span>
    <span class="n">sealed</span><span class="p">()</span>
<span class="p">}</span>
</code></pre></div></div>

<p>Because of <code class="language-plaintext highlighter-rouge">sealed()</code>, only the currency package will be able to implement currencies.  (Note that there is nothing special about the name “<code class="language-plaintext highlighter-rouge">sealed</code>”.  We could have used any lowercase function name.)</p>

<p>I learned about sealed interfaces in Go from <a href="https://blog.chewxy.com/2018/03/18/golang-interfaces/#sealed-interfaces">Chewxy</a>.  And by using sealed interfaces, <a href="https://github.com/BurntSushi/go-sumtype">BurntSushi</a> has built a tool for checking exhaustive patter matching in Go.  Neat :-)</p>

<p>Sealed interfaces solves one of our problems: that of safely extending currencies inside the <code class="language-plaintext highlighter-rouge">currency</code> package.  But we are still left with one problem: <em>how to plumb the implementation of our unmarshaling function into the <code class="language-plaintext highlighter-rouge">encoding/json</code> package.</em>  Concretely, we want to use <code class="language-plaintext highlighter-rouge">func UnmarshalJSON(data []byte) (Currency, error)</code> inside <code class="language-plaintext highlighter-rouge">literalStore()</code> in the <code class="language-plaintext highlighter-rouge">encoding/json</code> package.</p>

<p>The problem boils down to associating a “static” function to an interface.  Looking at the method signature for our unmarshaler; it doesn’t have a receiving object:</p>

<div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">func</span> <span class="n">UnmarshalJSON</span><span class="p">(</span><span class="n">data</span> <span class="p">[]</span><span class="kt">byte</span><span class="p">)</span> <span class="p">(</span><span class="n">Currency</span><span class="p">,</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span>
</code></pre></div></div>

<p>The custom unmarshal logic doesn’t operate on an instance; it “operates on the class.”  For better or worse, there is no way in Go to express a “static” function of an interface. At least not as far as I know.</p>

<h2 id="conclusion">Conclusion</h2>

<p>There are may ways to implement something like case classes in Go.  None of them seem to do justice, in my opinion.  As a Go programmer, I miss algebraic data types.  If we had them, error handling in Go would look nicer.  But I am getting ahead of myself!  Before you think that I’m advocating for changes to Go or the json package, you should watch <a href="https://www.youtube.com/watch?v=rFejpH_tAHM&amp;t=3s">this talk by Rob Pike</a>.  Languages are different.  I too get annoyed with the lack of this or that.  But I’m also glad that Go isn’t like Scala!  Scala is great in many ways, I am glad it exists, and I love functional programming in general.  But Go’s goals are different from Scala’s, and I welcome their difference.</p>]]></content><author><name>Daniel Fava, co-authored by ChatGPT</name></author><category term="programming-languages" /><summary type="html"><![CDATA[In this blog post, we will take a look at Go and Scala, and specifically, at their approach to case classes. One of Scala’s key features is its support for case classes. Case classes are meant for holding immutable data. They are similar to regular classes, but they come with a number of useful features out-of-the-box, such as the ability to generate a toString method, a copy method; they also come with matching support. Go, on the other hand, does not have built-in support for case classes. We will look at three different approaches that can be used instead.]]></summary></entry><entry><title type="html">Yesterday I defended the PhD</title><link href="http://danielfava.com/personal/2021/06/15/phdpreface.html" rel="alternate" type="text/html" title="Yesterday I defended the PhD" /><published>2021-06-15T12:00:00+00:00</published><updated>2021-06-15T12:00:00+00:00</updated><id>http://danielfava.com/personal/2021/06/15/phdpreface</id><content type="html" xml:base="http://danielfava.com/personal/2021/06/15/phdpreface.html"><![CDATA[<script type="text/x-mathjax-config">
MathJax.Hub.Config({
  tex2jax: {
    inlineMath: [['$','$'], ['\\(','\\)']],
    processEscapes: true
  }
});
</script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"></script>

<p>As cliché as it sounds, the story of my PhD started in my childhood.
Growing up, I wanted to be a scientist. 
In my teenage years, I had my eyes on a <a href="http://www.upa.unicamp.br/cursao">joint math and physics program</a>
at the <em>Universidade Estadual de Campinas</em> (<a href="https://www.unicamp.br/unicamp/english/">UNICAMP</a>), Brazil.
I started the program in 2001 and still remember 
Professor Alcibíades Rigas class on linear algebra and analytical geometry.
Rigas used a graduate level book written in English as the main resource for this freshman level course—in a country where most don’t speak English.
It’s an understatement to say that the class was hard.
But rather than an exercise in gratuitous punishment,
Rigas helped us build a solid foundation.
I fell in love with the campus and the program, but I left midway through my freshman year.
While taking entrance exams in Brazil, I had also submitted applications for college in the US.
When notified of my acceptance at the Rochester Institute of Technology (<a href="https://www.rit.edu/">RIT</a>), I chose the unknown over a life I had been falling in love with.
<!--more--></p>

<p>Moving to the US was a momentous decision for me.
Leaving a liberal, public (free) university that is strong in theory and the sciences and going to a paid, conservative school with a focus on industrial application… had I made a big mistake?
The feeling of isolation, the cold, and the political climate post 9/11 weighed hard.  But I also made life-long friends during this time, and learned to embraced the engineer in me.
In the end, RIT did prepare us well for industry.
After college, I worked at Intel on one of the <a href="https://en.wikipedia.org/wiki/Larrabee_(microarchitecture)">first many-core CPU architectures</a>. 
At Apple, I worked on the <a href="https://en.wikipedia.org/wiki/Apple_A7">first 64-bit cellphone processor to hit the market</a>.
But my childhood dream of being a scientist looked far away in the rear-view mirror.
So on the verge of becoming a father, with the encouragement and support of my wife, I took an order of magnitude pay-cut and made a u-turn into graduate school.</p>

<p>I enrolled in the PhD program in Computer Science at the University of California in Santa Cruz (<a href="https://www.ucsc.edu/">UCSC</a>) in California.  Wanting to find my way back to math and science, I took classes in machine learning and in the theory of programming languages.
I became interested in logic and was exposed to formal methods.
But I struggled to find my footing,
and life in the US was not easy for two graduate students with a kid.
With the help of the <a href="https://index.goodcountry.org">Good Country Index</a>, I made a list of potential places to live. 
A serendipitous e-mail from <a href="https://www.mn.uio.no/ifi/english/people/aca/olaf/">Olaf</a> (now my PhD co-advisor) and the support from amazing friends put us in motion towards Norway.</p>

<p>At the University of Oslo (<a href="https://www.uio.no/english/">UiO</a>), I continued studying <a href="https://www.mn.uio.no/ifi/english/research/groups/psy/">programming languages and formal methods</a>.
In this thesis you may sense the pushes and pull of a person with mixed interests.
The operational semantics and the proof by simulation that appear early in the document come from wanting to deepen my mathematical background.
The work of manipulating symbols in a formal system, however, is more fitting to a theoretician than to the engineer who I had become.  So I am grateful to <a href="https://martinsteffen.github.io/">Martin</a>, my advisor, for taking my interest and curiosity seriously, for encouraging me to develop my own research style, and for helping me bridge my knowledge gap.</p>

<p>I also wanted to build a modest trail, starting with real world source code and veering towards math. 
A trail that someone like my past self—a programmer who aspires to learn more but who does not yet have graduate-level training—might find useful.
With the goal of bringing the thesis’ work to practice, I began looking at source code again.
My exposure to industrial code bases and my experience dealing its complexities helped me a lot.
I studied the thread sanitizer library (<a href="https://clang.llvm.org/docs/ThreadSanitizer.html">TSan</a>), the <a href="https://golang.org/doc/articles/race_detector">Go data race detector</a>, and the implementation of channels in the Go runtime.
What started as tinkering developed into the latter part of the thesis.
In the process I was exposed to open-source development, which I have been interested in since my undergraduate studies.</p>

<p>I am tremendously grateful for the journey.  Risking opening <em>and finishing</em> with a cliché: I hope you will find the work interesting.  Thank you.</p>

<p><em>That was the preface to my thesis.  Below is a technical blurb.  If you fond them to be interesting, you can check out the <a href="/thesis/dfava_thesis.pdf">PDF</a>.</em></p>

<p><br /></p>

<h2 id="thesis-blurb">Thesis blurb</h2>

<p>Go is an open-source programming language developed at Google that has become the underpinning of large amounts of virtual infrastructure, especially in the area of cloud computing.  Inspired by Go, this thesis analyzes a programming environment where threads synchronize with each other via the exchange of messages over channels.  Go specifies this interaction on a document called the memory model, written in English.  We present a mathematical interpretation of the Go memory model document.  Our mathematization brings benefits.  For example, it allows us to more easily relate the language’s design to the language’s implementation.  As evidence, we were able to find and fix a non-trivial bug in the Go data-race detector.  Rooted in theory, our improvements to the Go data-race detector were incorporated into <a href="https://golang.org/doc/go1.16#runtime">release 1.16</a> of the language.  In this thesis (<a href="/thesis/dfava_thesis.pdf">PDF</a>), we share our experience applying formal methods to a large, real-world software project.</p>]]></content><author><name></name></author><category term="personal" /><summary type="html"><![CDATA[As cliché as it sounds, the story of my PhD started in my childhood. Growing up, I wanted to be a scientist. In my teenage years, I had my eyes on a joint math and physics program at the Universidade Estadual de Campinas (UNICAMP), Brazil. I started the program in 2001 and still remember Professor Alcibíades Rigas class on linear algebra and analytical geometry. Rigas used a graduate level book written in English as the main resource for this freshman level course—in a country where most don’t speak English. It’s an understatement to say that the class was hard. But rather than an exercise in gratuitous punishment, Rigas helped us build a solid foundation. I fell in love with the campus and the program, but I left midway through my freshman year. While taking entrance exams in Brazil, I had also submitted applications for college in the US. When notified of my acceptance at the Rochester Institute of Technology (RIT), I chose the unknown over a life I had been falling in love with.]]></summary></entry><entry><title type="html">Concurrency, Distribution, and the Go memory model</title><link href="http://danielfava.com/programming-languages/2020/07/07/concurrencyvdistribution.html" rel="alternate" type="text/html" title="Concurrency, Distribution, and the Go memory model" /><published>2020-07-07T12:00:00+00:00</published><updated>2020-07-07T12:00:00+00:00</updated><id>http://danielfava.com/programming-languages/2020/07/07/concurrencyvdistribution</id><content type="html" xml:base="http://danielfava.com/programming-languages/2020/07/07/concurrencyvdistribution.html"><![CDATA[<script type="text/x-mathjax-config">
MathJax.Hub.Config({
  tex2jax: {
    inlineMath: [['$','$'], ['\\(','\\)']],
    processEscapes: true
  }
});
</script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"></script>

<p>The Go memory model specifies two main ways in channels are used for synchronization:</p>

<ol>
  <li>A send onto a channel happens-before the corresponding receive from that channel completes.</li>
  <li>The $k^{th}$ receive from a channel with capacity $C$ happens-before the $(k+C)^{th}$ send onto that channel completes.</li>
</ol>

<p>Recall that <em>happens-before</em> is a mathematical relation, as discussed <a href="/programming-languages/2020/03/11/mm-hb.html">here</a>.</p>

<p>Rule (1) above has been around for a while.  The rule is very similar to what was originally proposed by <a href="https://dl.acm.org/doi/abs/10.1145/3335772.3335934">Lamport in 1978</a>.  It establishes a happens-before relation between a sender and its corresponding receiver.
Rule (2) is a bit more esoteric.  It was not present in Lamport’s study of distributed systems.  There is a good reason for that absence.</p>

<!--more-->

<blockquote>
  <p>Go is a language in between concurrency and distribution.</p>
</blockquote>

<p>Both concurrency and distribution speak of independent agents cooperating on a common task.  For that to happen, agents need to coordinate, to synchronize.  Although similar in many ways, <em>concurrency</em> and <em>distribution</em> are fundamentally different.  Because of this difference, synchronization in the setting of distribution differs from synchronization for concurrency.</p>

<p>In a concurrent systems, we assume that the agents are under/within a single environment.  In Go, for example, all agents (goroutines) are under a single umbrella, in this case the Go runtime.  This overarching environment allows us to assume that no messages are lost during transmission.</p>

<p>In distributed system, however, there is no such point of authority—at least not without making lots of extra assumptions about the system.  For example, it may be impossible to tell whether a message was received.  A network delay may be indistinguishable from a crashed/failed node.  This impossibility exist even if we label some node as the “authoritative source of information about the state of the system.”  After all, what if we are unable to reach this special node?  In a distributed system, communication is no longer perfect, and we are forced to deal with this fact at some point.</p>

<p>Locks are often used to program concurrent systems, where the agents are located under a central resource manager.  This manager can be the operating system, or a language runtime with the help of the OS.  Different from locks, channels are a step towards synchronization in the setting of distribution.</p>

<p>Go borrowed rule (1) from Lamport’s research on distribution.  On the other hand, rule (2) comes from the realization that Go is not all the way there.  Rule (2) allows for the use of channels as locks, with <em>send</em> acting as <code class="language-plaintext highlighter-rouge">acquire</code> and <em>receive</em> as <code class="language-plaintext highlighter-rouge">release</code> (see <a href="/programming-languages/2020/06/24/channelsvlocks.html">previous post</a> for details):</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  T0            T1
c &lt;- 0     |  c &lt;- 0
z := 42    |  z := 43
&lt;- c       |  &lt;- c
</code></pre></div></div>

<p>Rule (1) gives us an order, while rule (2) is related to mutual exclusion (an order exists, but we don’t know which).  In a sense, rule (1) is <a href="https://en.wikipedia.org/wiki/Intuitionistic_logic">constructive or intuitionistic</a>, while rule (2) is <a href="https://en.wikipedia.org/wiki/Classical_logic">classical</a>.  If you are interested, you can find more on Section 3.5 of our paper <a href="https://doi.org/10.1016/j.scico.2020.102473">Ready, set, Go! Data-race detection and the Go language</a>.</p>

<h2 id="conclusion">Conclusion</h2>

<p>While channels are typically used to program distributed systems, Go has a slightly different angle on message passing.  Go introduces rule (2), which takes into account the channels’ capacity:</p>

<ol start="2">
<li />  The $k^{th}$ receive from a channel with capacity $C$ happens-before the $(k+C)^{th}$ send onto that channel completes.
</ol>

<p>With rule (2), we can program channels as locks.  This puts the language in the spectrum between concurrency and distribution.</p>]]></content><author><name></name></author><category term="programming-languages" /><summary type="html"><![CDATA[The Go memory model specifies two main ways in channels are used for synchronization: A send onto a channel happens-before the corresponding receive from that channel completes. The $k^{th}$ receive from a channel with capacity $C$ happens-before the $(k+C)^{th}$ send onto that channel completes. Recall that happens-before is a mathematical relation, as discussed here. Rule (1) above has been around for a while. The rule is very similar to what was originally proposed by Lamport in 1978. It establishes a happens-before relation between a sender and its corresponding receiver. Rule (2) is a bit more esoteric. It was not present in Lamport’s study of distributed systems. There is a good reason for that absence.]]></summary></entry><entry><title type="html">Channels vs Locks</title><link href="http://danielfava.com/programming-languages/2020/06/24/channelsvlocks.html" rel="alternate" type="text/html" title="Channels vs Locks" /><published>2020-06-24T12:00:00+00:00</published><updated>2020-06-24T12:00:00+00:00</updated><id>http://danielfava.com/programming-languages/2020/06/24/channelsvlocks</id><content type="html" xml:base="http://danielfava.com/programming-languages/2020/06/24/channelsvlocks.html"><![CDATA[<script type="text/x-mathjax-config">
MathJax.Hub.Config({
  tex2jax: {
    inlineMath: [['$','$'], ['\\(','\\)']],
    processEscapes: true
  }
});
</script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"></script>

<p>With channels, we typically establish that two things are synchronized because A happens-before B.  We often know the order in which they happen.  In this post, we’ll see a use (or “misuse”) of channels.  We will be able to establish that two things are synchronized, but we won’t know the order between them.  We won’t know which happened first.  We will then relate and contrast channels with locks: how are they different, how are they similar.</p>

<!--more-->

<p>The typical example of channel communication is:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  T0            T1
z := 42    |  
c &lt;- 0     |  &lt;- c
           |  z := 43
</code></pre></div></div>

<p>Thread <code class="language-plaintext highlighter-rouge">T0</code> does something (write to the shared variable <code class="language-plaintext highlighter-rouge">z</code>) and informs a partnet, <code class="language-plaintext highlighter-rouge">T1</code> by sending on a channel.  <code class="language-plaintext highlighter-rouge">T1</code> learns about the write to <code class="language-plaintext highlighter-rouge">z</code> by receiving from the channel.  <code class="language-plaintext highlighter-rouge">T1</code> can then use <code class="language-plaintext highlighter-rouge">z</code> without causing a data race.</p>

<p>The Go memory model specifies two main ways to synchronize with channels:</p>

<ol>
  <li>A send onto a channel happens-before the corresponding receive from that channel completes.</li>
  <li>The $k^{th}$ receive from a channel with capacity $C$ happens-before the $(k+C)^{th}$ send onto that channel completes.</li>
</ol>

<p>Rule (1) is the rule used to reason about the example above: <code class="language-plaintext highlighter-rouge">T0</code>’s send happens-before <code class="language-plaintext highlighter-rouge">T1</code>’s receive.  Rule (2) is a bit more esoteric.  It allows us to use (or “misuse”, depending on your point of view) channels as locks.</p>

<h2 id="channels-as-locks">Channels as locks</h2>

<p>Here is an example of channels being used as locks.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  T0            T1
c &lt;- 0     |  c &lt;- 0
z := 42    |  z := 43
&lt;- c       |  &lt;- c
</code></pre></div></div>

<p>In this example, the channel <code class="language-plaintext highlighter-rouge">c</code> has capacity 1.  Threads <code class="language-plaintext highlighter-rouge">T0</code> and <code class="language-plaintext highlighter-rouge">T1</code> are both trying to access some shared resource, say <code class="language-plaintext highlighter-rouge">z</code>.  Before accessing <code class="language-plaintext highlighter-rouge">z</code>, a thread sends a message on the channel <code class="language-plaintext highlighter-rouge">c</code>, and receives from the channel afterwards.</p>

<p>Note that the send and its corresponding receive do not contribute to synchronization in this example.  The send is matched by a receive from the same thread; nothing new is learned from this exchange.  Rule (1) is mute here: the receive is in happens-before the send not just because of rule (1) but, more obviously, because of program order.  Yet, this program is properly synchronized.</p>

<p>This program is properly synchronized because the channel is acting like a lock: <em>send</em> is acting like the <code class="language-plaintext highlighter-rouge">acquire</code> operation, and the <em>receive</em> as the <code class="language-plaintext highlighter-rouge">release</code>.  What allows for this interaction is Rule (2).
To see that, let us assume that <code class="language-plaintext highlighter-rouge">T1</code> is the first thread to perform the send operation.  (We could easily apply the same logic assuming <code class="language-plaintext highlighter-rouge">T0</code> was first.)  Since the channel has capacity 1, <code class="language-plaintext highlighter-rouge">T0</code> will not be able to send onto the channel until <code class="language-plaintext highlighter-rouge">T1</code> has received from it.  Rule (2) then links the reception by <code class="language-plaintext highlighter-rouge">T1</code> to the send by <code class="language-plaintext highlighter-rouge">T0</code>:  the 0<sup>th</sup> receive happens-before the 1<sup>st</sup> send completes.  By this reasoning, we know that the write <code class="language-plaintext highlighter-rouge">z := 43</code> by <code class="language-plaintext highlighter-rouge">T1</code> in the past of <code class="language-plaintext highlighter-rouge">T0</code>.  Therefore, <code class="language-plaintext highlighter-rouge">T0</code> can access <code class="language-plaintext highlighter-rouge">z</code> without causing a data race.</p>

<p>For a rigorous discussion, see Section 3.5 of our paper <a href="https://doi.org/10.1016/j.scico.2020.102473">Ready, set, Go! Data-race detection and the Go language</a>.</p>

<h2 id="conclusion">Conclusion</h2>

<p>Go channels are a bit more than channels in their pure sense.  In particular, rule (2), which allows us to use channels as locks, gives us extra power.  In the <a href="/programming-languages/2020/07/07/concurrencyvdistribution.html">next post</a> I argue that this power is not necessarily a good thing.  Spoiler alert.  The possibility of using channels as locks is a good thing when it comes to concurrency.  However, this power makes Go less of a language for distribution.</p>

<p>Also, although we can make channels behave as locks, in <a href="/programming-languages/2020/07/08/everywordcounts.html">this post</a> I discuss how synchronization through locks is <em>fundamentally different</em> from synchronization via channels.  The neat thing about the post is that we’ll get to explore the Go runtime.  We’ll also be bring together many of the concepts we’ve talked about in this blog so far.</p>]]></content><author><name></name></author><category term="programming-languages" /><summary type="html"><![CDATA[With channels, we typically establish that two things are synchronized because A happens-before B. We often know the order in which they happen. In this post, we’ll see a use (or “misuse”) of channels. We will be able to establish that two things are synchronized, but we won’t know the order between them. We won’t know which happened first. We will then relate and contrast channels with locks: how are they different, how are they similar.]]></summary></entry><entry><title type="html">What makes Go special</title><link href="http://danielfava.com/programming-languages/2020/06/23/especial.html" rel="alternate" type="text/html" title="What makes Go special" /><published>2020-06-23T12:00:00+00:00</published><updated>2020-06-23T12:00:00+00:00</updated><id>http://danielfava.com/programming-languages/2020/06/23/especial</id><content type="html" xml:base="http://danielfava.com/programming-languages/2020/06/23/especial.html"><![CDATA[<script type="text/x-mathjax-config">
MathJax.Hub.Config({
  tex2jax: {
    inlineMath: [['$','$'], ['\\(','\\)']],
    processEscapes: true
  }
});
</script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js?config=TeX-AMS-MML_HTMLorMML" type="text/javascript"></script>

<p><img src="/img/goroutine.png" width="350" alt="goroutine" align="right" hspace="20" vspace="15" />
What stands out the most in Go, to me, are goroutines and channels.  The language was built for the many-core.  It sprung from the observation that processors are not getting much faster at doing one thing, but are becoming faster by doing many things at once.  To benefit from this trend, we ought to write multithreaded applications.  Go makes it super easy to have multiple threads of execution.  By prepending the keyword <code class="language-plaintext highlighter-rouge">go</code> at invocation, any function can run asynchronously (on its own “thread”).
For example, 
the program below has only one goroutine, the <em>main</em> goroutine.
<!--more--></p>

<pre><code class="language-{go}">package main
var a string
func setA() { a = "hello" }

func main() {
  setA()
  print(a)
}
</code></pre>

<p>If we prepend the call to <code class="language-plaintext highlighter-rouge">setA</code> with <code class="language-plaintext highlighter-rouge">go</code>, the function <code class="language-plaintext highlighter-rouge">setA</code> will run on its own “thread of execution”, or as we say in Go,  <em>goroutine</em>.</p>

<pre><code class="language-{go}">package main
var a string
func setA() { a = "hello" }

func main() {
  go setA()
  print(a)
}
</code></pre>

<p>The ease with which we can turn sequential code into concurrent code is staggering.  With great power, however, comes great responsibility.  By making <code class="language-plaintext highlighter-rouge">setA</code> run asynchronously, we broke the above program.  It is now possible for the <code class="language-plaintext highlighter-rouge">print</code> in <code class="language-plaintext highlighter-rouge">main</code> to execute before <code class="language-plaintext highlighter-rouge">setA</code> has a chance to set <code class="language-plaintext highlighter-rouge">a</code> to <code class="language-plaintext highlighter-rouge">hello</code>.  As a consequence, it is possible for this program to print the empty string.
This situation is an example of a <em>data race</em>.</p>

<blockquote>
  <p>A data race constitutes
two unsynchronized accesses to the same memory location, with at least one of the accesses being a <em>write</em> access.</p>
</blockquote>

<p>Note that <em>read</em> accesses are never in conflict.  In other words, we can’t have a data race between two read accesses.
(There is also a definition of data races in terms of traces, and being able to put the two conflicting operations side-by-side in a trace.  That definition is in-line with an idea of races as two conflicting access occurring “at the same time”.  In a future post, I’ll analyze the difference between these definitions.<!-- I analyze the difference between these definitions [here][TODO].  The writing is a critique of the side-by-side or "at the same time" definition.-->)</p>

<p><img src="/img/channels.png" width="350" alt="goroutine" align="right" hspace="20" vspace="15" />
Instead of locks, Go advocates synchronization via channel communication—sending and receiving messages on channels.  We can repair the program as follows.  We’ll create a channel, called <code class="language-plaintext highlighter-rouge">done</code>, that is shared between the two goroutines, we’ll send a message after writing to the shared variable in <code class="language-plaintext highlighter-rouge">setA</code>, and we’ll receive a message before reading from the shared variable in <code class="language-plaintext highlighter-rouge">main</code>.</p>

<pre><code class="language-{go}">package main
var done = make(chan bool, 10)
var a string
func setA() { a = "hello"; done &lt;- true }

func main() {
  setA()
  &lt;- done
  print(a)
}
</code></pre>

<p>We can think about the repair as follows.  The reception of the message is blocking, meaning that the <code class="language-plaintext highlighter-rouge">main</code> goroutine will block until a message is available to be received.  Recall from a <a href="/programming-languages/2020/03/12/gomm.html">previous post</a> that, according to the <a href="https://golang.org/ref/mem">Go memory model</a>, a <em>send</em> on a channel happens-before the corresponding <em>receive</em> completes.  So the <em>send</em> and its corresponding <em>receive</em> work to place the setting of <code class="language-plaintext highlighter-rouge">a</code> in <code class="language-plaintext highlighter-rouge">setA</code> in <em>happens-before</em> relation to the reading of <code class="language-plaintext highlighter-rouge">a</code> in <code class="language-plaintext highlighter-rouge">main</code>.  (You can brush up on the happens-before relation <a href="/programming-languages/2020/03/11/mm-hb.html">here</a>.)</p>

<p>In the <a href="/programming-languages/2020/06/24/concurrencyvdistribution.html">next post</a>, I plan to we discuss the difference between <em>concurrency</em> and <em>distribution</em>, relating the two concepts to different types of synchronization.  We make a connection between concurrency and locks and between distribution and channels.  After that, we look at how channels can be used as locks and later argue that these synchronization primitives are actually fundamentally different.</p>]]></content><author><name></name></author><category term="programming-languages" /><summary type="html"><![CDATA[What stands out the most in Go, to me, are goroutines and channels. The language was built for the many-core. It sprung from the observation that processors are not getting much faster at doing one thing, but are becoming faster by doing many things at once. To benefit from this trend, we ought to write multithreaded applications. Go makes it super easy to have multiple threads of execution. By prepending the keyword go at invocation, any function can run asynchronously (on its own “thread”). For example, the program below has only one goroutine, the main goroutine.]]></summary></entry></feed>