<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Mario Sangiorgio</title>
    <description>The latest articles on Forem by Mario Sangiorgio (@mariosangiorgio).</description>
    <link>https://forem.com/mariosangiorgio</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F31247%2F077ee57c-19f4-4f51-8f33-48f0287e6990.jpeg</url>
      <title>Forem: Mario Sangiorgio</title>
      <link>https://forem.com/mariosangiorgio</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/mariosangiorgio"/>
    <language>en</language>
    <item>
      <title>Efficiently compute permutations</title>
      <dc:creator>Mario Sangiorgio</dc:creator>
      <pubDate>Fri, 06 Apr 2018 00:00:00 +0000</pubDate>
      <link>https://forem.com/mariosangiorgio/efficiently-compute-permutations-2phk</link>
      <guid>https://forem.com/mariosangiorgio/efficiently-compute-permutations-2phk</guid>
      <description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Permutation&lt;/strong&gt; : each of several possible ways in which a set or number of things can be ordered or arranged.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  The problem
&lt;/h1&gt;

&lt;p&gt;Given several items, it could be interesting to find all the possible ways we can arrange them. For instance, the string &lt;code&gt;ABC&lt;/code&gt; has six permutations: &lt;code&gt;ABC&lt;/code&gt;, &lt;code&gt;ACB&lt;/code&gt;, &lt;code&gt;BAC&lt;/code&gt;, &lt;code&gt;BCA&lt;/code&gt;, &lt;code&gt;CAB&lt;/code&gt;, &lt;code&gt;CBA&lt;/code&gt;. Note that the number of permuration is the &lt;a href="https://en.wikipedia.org/wiki/Factorial"&gt;factorial&lt;/a&gt; of the number of items. This happens because we can pick any of the items as the first one, we have &lt;code&gt;#items - 1&lt;/code&gt; choices for the second and so on till we reach the last item with a single choice.&lt;/p&gt;

&lt;h1&gt;
  
  
  A recursive solution
&lt;/h1&gt;

&lt;p&gt;We could compute all the permutations recursively, as shown in this Python function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;permutations&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="c1"&gt;# We keep only the distinct items to avoid returning duplicates
&lt;/span&gt;  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;list&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
    &lt;span class="n"&gt;others&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[:]&lt;/span&gt;
    &lt;span class="n"&gt;others&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;remove&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;permutation&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="n"&gt;permutations&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;others&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
      &lt;span class="c1"&gt;# Note: if we want lexicographical order we should insert in front
&lt;/span&gt;      &lt;span class="c1"&gt;# assuming that items are sorted
&lt;/span&gt;      &lt;span class="n"&gt;permutation&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;append&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;permutation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;We could execute this and get the results we expected:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;permutations&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;permutations&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="p"&gt;[[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  A better approach
&lt;/h1&gt;

&lt;p&gt;This solution works, it is nice and simple but it isn’t very efficient: it requires us to create a lot of copies of the list of items so that we can pass them into the next recursive step. Another drawback is that this function computes (and keeps in memory) &lt;em&gt;all&lt;/em&gt; the permutations, which it’s a waste if we only need a few of them.&lt;/p&gt;

&lt;p&gt;We could look at this from another angle and ask ourselves if there is any way we could take a list of items and find out only the &lt;em&gt;next&lt;/em&gt; permutation, whatever that means.&lt;/p&gt;

&lt;p&gt;If we talk about the &lt;em&gt;next&lt;/em&gt; permutation we kind of imply that there is an order between them. In principle the definition of permutations doesn’t imply any order, but we could always add a constraint ourselves and require some ordering. Using the &lt;a href="https://en.wikipedia.org/wiki/Lexicographical_order"&gt;lexicographical order&lt;/a&gt; is a good choice that allows us to &lt;a href="https://en.wikipedia.org/wiki/Permutation#Generation_in_lexicographic_order"&gt;generate&lt;/a&gt; the next permutation for a given list of items.&lt;/p&gt;

&lt;p&gt;Going back to our initial example, we could start from &lt;code&gt;ABC&lt;/code&gt;, reorganize the items to get &lt;code&gt;ACB&lt;/code&gt;, do it another time to obtain &lt;code&gt;BAC&lt;/code&gt;, and so on. This will allow us to compute all the permutations, but this time one of a time and without unnecessary copies of the list.&lt;/p&gt;

&lt;p&gt;The first list in lexicographical order has all its items in &lt;em&gt;non-decreasing&lt;/em&gt; order: &lt;code&gt;forall i: items[i] &amp;lt;= items[i+1]&lt;/code&gt;. In our example, we have &lt;code&gt;ABC&lt;/code&gt; and &lt;code&gt;A &amp;lt; B&lt;/code&gt; and &lt;code&gt;B &amp;lt; C&lt;/code&gt;. On the opposite, the last item has all its items in &lt;em&gt;non-incresing&lt;/em&gt; order: &lt;code&gt;forall i: items[i] &amp;gt;= items[i+1]&lt;/code&gt;. In our example, we have &lt;code&gt;CBA&lt;/code&gt; and &lt;code&gt;C &amp;gt; B&lt;/code&gt; and &lt;code&gt;B &amp;gt; A&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Our algorithm needs to make us transition from these two extremes by rearranging the elements such that each permutation ‘increases’ the sequence by the minimal amount. The key observation is that we want to look for the longest suffix in &lt;em&gt;non decreasing&lt;/em&gt; order (i.e. that is already the biggest possible). Let’s call it &lt;code&gt;suffix&lt;/code&gt;. In order to make some progress we need to consider all the items in &lt;code&gt;suffix&lt;/code&gt; and the one immediately before it, which we call &lt;code&gt;pivot&lt;/code&gt;. If we start from &lt;code&gt;0125430&lt;/code&gt; we could split the string in &lt;code&gt;prefix = 01&lt;/code&gt;, &lt;code&gt;pivot = 2&lt;/code&gt;, and &lt;code&gt;suffix = 5430&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;We’re looking for the minimal change so we shouldn’t touch &lt;code&gt;prefix&lt;/code&gt;. If we do we’ll get a bigger change than the one we want. We can only move &lt;code&gt;pivot&lt;/code&gt; and the items in &lt;code&gt;suffix&lt;/code&gt;. We also must do that satisfying these two conditions to be able to advance to the next permutation in lexicographical order:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;we need to replace &lt;code&gt;pivot&lt;/code&gt; with the smallest value possible;&lt;/li&gt;
&lt;li&gt;we must reshuffle the items such that the new &lt;code&gt;suffix&lt;/code&gt; is minimal.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We can satisfy the first condition by replacing &lt;code&gt;pivot&lt;/code&gt; with the smallest item in &lt;code&gt;suffix&lt;/code&gt; greater than &lt;code&gt;pivot&lt;/code&gt; itself. Taking a smaller value would mean going backwards, taking a bigger value would mean going too far. In our example we will get &lt;code&gt;prefix = 01&lt;/code&gt;, &lt;code&gt;pivot = 3&lt;/code&gt; and &lt;code&gt;suffix = 5420&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;This is a step in the right direction, but we still have satisfy the second condition. We’ve got a maximal suffix, we can make it minimal by simply reversing it, which has the effect of turning the &lt;em&gt;non-decreasing&lt;/em&gt; order to the &lt;em&gt;non-increasing&lt;/em&gt; order we’re after. In our example we will get &lt;code&gt;prefix = 01&lt;/code&gt;, &lt;code&gt;pivot = 3&lt;/code&gt; and &lt;code&gt;suffix = 0245&lt;/code&gt;. We’re done, the next permutation is &lt;code&gt;0130245&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The algorithm
&lt;/h2&gt;

&lt;p&gt;The algorithm to implement this consists of the following steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;find the largest &lt;code&gt;k&lt;/code&gt; such that &lt;code&gt;a[k] &amp;lt; a[k+1]&lt;/code&gt;. If we cannot find it, the item we’re looking at is already the last in lexicographical order. We could find the next item by just &lt;em&gt;wrap around&lt;/em&gt; and generate the first permutation in lexicographical order.&lt;/li&gt;
&lt;li&gt;Find the largest index &lt;code&gt;l&lt;/code&gt; greater than &lt;code&gt;k&lt;/code&gt; such that &lt;code&gt;a[k] &amp;lt; a[l]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Swap &lt;code&gt;a[k]&lt;/code&gt; and &lt;code&gt;a[l]&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Reverse the sequence from &lt;code&gt;a[k + 1]&lt;/code&gt; up to and including the final element &lt;code&gt;a[n]&lt;/code&gt;.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;In code this looks like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;next_permutation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
  &lt;span class="n"&gt;n&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;len&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;# Find pivot
&lt;/span&gt;  &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]):&lt;/span&gt;
      &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;k&lt;/span&gt; &lt;span class="ow"&gt;is&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
    &lt;span class="c1"&gt;# items is maximal. We need to wrap around
&lt;/span&gt;    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;
  &lt;span class="c1"&gt;# Find new pivot
&lt;/span&gt;  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;):&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]):&lt;/span&gt;
      &lt;span class="n"&gt;l&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt;
  &lt;span class="c1"&gt;# Swap pivot
&lt;/span&gt;  &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;l&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="c1"&gt;# Reverse suffix
&lt;/span&gt;  &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="ow"&gt;in&lt;/span&gt; &lt;span class="nb"&gt;range&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;int&lt;/span&gt;&lt;span class="p"&gt;((&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;+&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)):&lt;/span&gt;
    &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;n&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;items&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we can use it as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight python"&gt;&lt;code&gt;&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;permutation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="o"&gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="n"&gt;permutation&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="bp"&gt;None&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="k"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;permutation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="n"&gt;permutation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;next_permutation&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;permutation&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;...&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h1&gt;
  
  
  Other approaches
&lt;/h1&gt;

&lt;p&gt;This is not the only possible approach to generating permutations. There are in fact &lt;a href="https://en.wikipedia.org/wiki/Permutation#Algorithms_to_generate_permutations"&gt;several other algorithms&lt;/a&gt;. I find &lt;a href="https://en.wikipedia.org/wiki/Heap%27s_algorithm"&gt;Heap’s algorithm&lt;/a&gt; particulary interesting because it manages to generate the next permutation by swapping a single pair of elements.&lt;/p&gt;

&lt;p&gt;Thanks to &lt;a href="https://www.nayuki.io/page/next-lexicographical-permutation-algorithm"&gt;Project Nayuki&lt;/a&gt; for the post that inspired me to look into this algorithm.&lt;/p&gt;

</description>
      <category>python</category>
      <category>algorithms</category>
    </item>
    <item>
      <title>The art of deleting code</title>
      <dc:creator>Mario Sangiorgio</dc:creator>
      <pubDate>Tue, 26 Sep 2017 00:00:00 +0000</pubDate>
      <link>https://forem.com/mariosangiorgio/the-art-of-deleting-code-181</link>
      <guid>https://forem.com/mariosangiorgio/the-art-of-deleting-code-181</guid>
      <description>&lt;p&gt;If you ask developers what their most productive days look like, you’ll surely get many mentions of the mythical days when they contributed &lt;a href="https://twitter.com/search?q=negative%20lines%20of%20code&amp;amp;src=typd"&gt;negative lines of code&lt;/a&gt; to their projects.&lt;/p&gt;

&lt;p&gt;People like to celebrate these days and they do it for good reasons: they likely eliminated some bugs, made the code simpler, cleaned up some technical debt. As a side effect their project compilation and runtime are now faster.&lt;/p&gt;

&lt;p&gt;Where I work, we have a huge monolith that organically evolved and accumulated a huge amount of cruft. Last year we even spent some time reducing our technical debt. I spent that period almost exclusively getting rid of a huge amount of code and since then my coworkers use the expression &lt;em&gt;going Wario&lt;/em&gt; when they are deleting some old code.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I know what to delete?
&lt;/h3&gt;

&lt;p&gt;Deleting code is easy, knowing what to delete is definitely more challenging. The last thing I like to do is to reinstate something I removed because it turns out that something was actually still relying on it. We need some good ways to determine what code is dead with an high degree of confidence.&lt;/p&gt;

&lt;p&gt;A very deep knowledge of the codebase is crucial and is what will allow you to obtain the best results but there are some tools that can be extremely helpful and show you what parts of your application aren’t useful anymore.&lt;/p&gt;

&lt;h3&gt;
  
  
  Know your codebase and you application
&lt;/h3&gt;

&lt;p&gt;Knowing when and why some code was written for in the first place is invaluable and can give the best insights on whether you still need it or not.&lt;/p&gt;

&lt;p&gt;As an example, think of code to read different version of a file format or older version of an HTTP API. In both cases, you cannot guarantee that this code has no uses just by looking at it. But you might know that all the files you care about have been moved to the new format or that all the clients are using the new version of the API. Congratulations, you’ve just identified good candidates for a nice clean up.&lt;/p&gt;

&lt;p&gt;In a legacy codebase you’re likely to have many different ways of doing something. It might be a good idea to uniform your application to always use the latest approach. This will give you access to all the latest features and it will also allow you to retire the code related to the old approaches. Unfortunately, usually knowing how to migrate the new approach is not straightforward, otherwise someone else would have done it already. If that’s the case, you need to understand how the two approaches differ, what is really required by the use case that is still relying on old code and how you can replicate the functionality using the new code. It is usually possible, but it requires a lot of understanding and a fair amount of effort.&lt;/p&gt;

&lt;h3&gt;
  
  
  Static analysis
&lt;/h3&gt;

&lt;p&gt;At work we mainly use C#, so we can leverage static analysis like the one performed by the compiler itself, by &lt;a href="https://www.jetbrains.com/help/resharper/Find_dead_code.html"&gt;ReSharper&lt;/a&gt; and by &lt;a href="https://www.ndepend.com/Default-Rules/webframe.html?Q_Potentially_dead_Methods.html"&gt;ndepend&lt;/a&gt; to identify dead code. Cleaning it up is a good start, but it won’t get us too far: the most of the unused code that can be removed is code that is technically reachable.&lt;/p&gt;

&lt;p&gt;For instance, all the code I mentioned in the previous examples would not be flagged by static analysis tools. For what they know, I might still have an old file around so they must produce conservative results. They assume that if there is a codepath that leads to the execution of a line of code it will eventually be reached.&lt;/p&gt;

&lt;p&gt;That’s a perfectly valid approach: I would be very worried if these tools would give me unsound results.&lt;/p&gt;

&lt;p&gt;Still, static analysis is very useful end extremely effective when, after I found what feature I can eliminate, I want to easily get rid of all its related code. But before we need to find the entry point to that feature using other means. Once that’s deleted all the rest will follow.&lt;/p&gt;

&lt;h3&gt;
  
  
  Dynamic analysis
&lt;/h3&gt;

&lt;p&gt;If we cannot know what code is actually used just by analyzing it, can we get some more information if we instrument so that we can monitor how it’s actually used?&lt;/p&gt;

&lt;p&gt;The answer is yes and there are several approaches that can lead you to achieve very good results, but you need to watch out for false positives. Dynamic analysis is not exhaustive so you need to make sure that you’ve waited long enough before you can declare a piece of code as dead.&lt;/p&gt;

&lt;p&gt;Recording in a database all the command line arguments passed to your application will let you know what is actually in use. There is no point of support the functionality behind a command line switch if nobody ever uses it.&lt;/p&gt;

&lt;p&gt;If you suspect that something is dead, you can use the &lt;a href="https://github.com/scheb/tombstone/blob/master/README.md"&gt;tombstoning&lt;/a&gt; approach, which is a bit more invasive but it’s surely going to give you important information with a better level of detail.&lt;/p&gt;

&lt;p&gt;Once you’ve collected data for a while you will know what is definitely used, what is likely to be unused and when something has been used for the last time. This is precious intelligence and it will be extremely helpful in identifying what you should try to delete next.&lt;/p&gt;

&lt;h3&gt;
  
  
  Conclusion
&lt;/h3&gt;

&lt;p&gt;Deleting code is not always straightforward but with a good knowledge of the application you’re working on, and with the help of some tooling it is possible to achive very good results.&lt;/p&gt;

&lt;p&gt;If you’ve read so far, I’d like to recommend you &lt;a href="https://vimeo.com/108441214"&gt;Greg Young’s The art of destroying software&lt;/a&gt;. It’s not going to teach you how to delete code, but it will give you some ideas on how to &lt;em&gt;optimize for deletability&lt;/em&gt; the new code you’ll write so that deleting it, once you don’t need it anymore, will be as easy as possible.&lt;/p&gt;

</description>
      <category>advice</category>
    </item>
    <item>
      <title>Immutability Changes Everything - Pat Helland</title>
      <dc:creator>Mario Sangiorgio</dc:creator>
      <pubDate>Wed, 30 Aug 2017 23:37:52 +0000</pubDate>
      <link>https://forem.com/mariosangiorgio/immutability-changes-everything---pat-helland</link>
      <guid>https://forem.com/mariosangiorgio/immutability-changes-everything---pat-helland</guid>
      <description>&lt;p&gt;Inspired by &lt;a href="https://twitter.com/adriancolyer"&gt;Adrian Colyer&lt;/a&gt;'s &lt;a href="https://blog.acolyer.org/"&gt;the morning paper&lt;/a&gt; series, &lt;a href="https://twitter.com/rygorous"&gt;Fabian Giesen&lt;/a&gt;'s &lt;a href="https://fgiesen.wordpress.com/category/papers/"&gt;papers I like&lt;/a&gt; posts and the &lt;a href="http://paperswelove.org/"&gt;Papers we love&lt;/a&gt; talks I decided to start writing &lt;a href="https://dev.to/tags/paper/"&gt;posts about interesting papers I read&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Pat Helland's &lt;a href="http://cidrdb.org/cidr2015/Papers/CIDR15_Paper16.pdf"&gt;Immutability Changes Everything&lt;/a&gt; describes why we need immutability and how adopting it now that storage and computational power make it affordable.&lt;/p&gt;

&lt;p&gt;The key concept around immutability is &lt;em&gt;append only computing&lt;/em&gt;: observed facts are recorded and kept forever while the results that can derived from their analysis are computed on demand.&lt;/p&gt;

&lt;h3&gt;
  
  
  Is this new?
&lt;/h3&gt;

&lt;p&gt;It's interesting the this isn't a completely new concept.&lt;br&gt;
A well known example is accounting, which is entirely based on an append only record of transaction.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Accountants don't use erasers or they go to jail.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Pre-telephone "distributed systems" are another historical example.&lt;br&gt;
Messages used to be logged in forms consisting in append only section so that all the participants always had access to the full message history.&lt;/p&gt;

&lt;h3&gt;
  
  
  DataSets and Big Data
&lt;/h3&gt;

&lt;p&gt;The paper define DataSets as a fixed and (semantically) immutable collection of data with a unique identifier.&lt;br&gt;
Immutability is especially important when dealing with &lt;em&gt;Big Data&lt;/em&gt;.&lt;br&gt;
If the amount of that that needs to be processed requires distribution, the only sane way to deal with it is to guarantee that it won't change.&lt;br&gt;
This enable &lt;em&gt;idempotent functional calculations&lt;/em&gt;, which can be distributed and that can adopt a &lt;em&gt;let it fail approach&lt;/em&gt;: if something fails it's ok, it will be restarted.&lt;/p&gt;

&lt;p&gt;It's important to note that the requirement is for immutability to be &lt;em&gt;semantic&lt;/em&gt;: as long as we don't change the content, we can choose to physically arrange the data the way we want.&lt;br&gt;
This allows us to organize the data in the most efficient way for the task and we can also have multiple different representation of the same DataSet.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Normalization is very important in a database designed for update.&lt;br&gt;
The only reason to normalize immutable DataSets may be to reduce the storage necessity for them.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Immutability and evolving data
&lt;/h3&gt;

&lt;p&gt;Sometimes we want to keep track of the evolution of some data.&lt;br&gt;
We can do that in an immutable way, but we need to keep track of all the changes.&lt;br&gt;
One way to do that is to keep track of version history.&lt;br&gt;
This can be done in a strongly consistent way (&lt;em&gt;linear version history&lt;/em&gt;) in an eventual consistent way (&lt;em&gt;directed acyclic graph of version history&lt;/em&gt;, like what you usually work with in Git).&lt;/p&gt;

&lt;p&gt;Versioning techniques have also been adopted to improve the performance of database systems.&lt;br&gt;
With &lt;a href="https://en.wikipedia.org/wiki/Multiversion_concurrency_control"&gt;&lt;em&gt;multi-version concurrency control&lt;/em&gt;&lt;/a&gt; updates don't overwrite existing data.&lt;br&gt;
Instead, they create a new, isolated, version.&lt;br&gt;
This technique has been adopted to allow concurrent access to a database by different transaction while protecting them from observing inconsistent data.&lt;br&gt;
A &lt;a href="https://en.wikipedia.org/wiki/Log-structured_merge-tree"&gt;log-structured merge-tree&lt;/a&gt; records changes by appending them to a log.&lt;br&gt;
This allows for very efficient insertions but would required to keep the whole history around forever and it would cause read performance to be poor.&lt;br&gt;
To get around this, periodically the log gets compacted removing duplicates and reorganizing the data for more efficient reads.&lt;/p&gt;

&lt;h3&gt;
  
  
  Immutability in file-systems
&lt;/h3&gt;

&lt;p&gt;Immutable data has been widely employed to file-systems too.&lt;br&gt;
&lt;a href="https://en.wikipedia.org/wiki/Log-structured_file_system"&gt;Log-structured file-system&lt;/a&gt; treats the disk as a circular log.&lt;br&gt;
This gives very good write performance (especially on magnetic disks) and it offers features like snapshotting and easy recovery from crashes.&lt;br&gt;
Of course, this is not free: as the disk becomes full there is the need to reclaim the blocks that don't contain useful information anymore to make space for new data.&lt;/p&gt;

&lt;p&gt;Distributed file-systems like &lt;a href="https://en.wikipedia.org/wiki/Google_File_System"&gt;GFS&lt;/a&gt; and &lt;a href="https://en.wikipedia.org/wiki/Apache_Hadoop#HDFS"&gt;HDFS&lt;/a&gt; exploit immutability to achieve high availability.&lt;br&gt;
Files are composed of immutable blocks and they have a single writer.&lt;br&gt;
With this design, block-level replication is possible without the need of worry about update anomalies.&lt;/p&gt;

&lt;h3&gt;
  
  
  Immutability in distributed systems
&lt;/h3&gt;

&lt;p&gt;Immutability provides benefit even when working with a distributed datastore using consistent hashing.&lt;br&gt;
If data is mutable we need to settle for eventual consistency while rebalancing.&lt;br&gt;
With immutable data we don't need to worry about stale versions present in different nodes.&lt;br&gt;
If a node has some information, that's the only value it will ever assume.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hardware design
&lt;/h3&gt;

&lt;p&gt;SSD wear leveling algorithms treat blocks as immutable and use copy-on-write to spread more evenly the writes across the whole unit.&lt;br&gt;
Hard disks embrace immutability with an approach similar to log-structured file-systems improve performance and be able to operate at higher density.&lt;/p&gt;

&lt;h3&gt;
  
  
  The dark sides
&lt;/h3&gt;

&lt;p&gt;Immutability is very useful but it isn't a silver bullet.&lt;br&gt;
Embracing it requires us to do some trade-offs.&lt;br&gt;
Denormalization increases the amount of storage required.&lt;br&gt;
Copy-on-write increases disk activity, in a phenomenon called write amplification.&lt;br&gt;
It's important to keep this in mind when designing a system.&lt;/p&gt;

&lt;p&gt;This post originally appeared on &lt;a href="https://mariosangiorgio.github.io/post/immutability-changes-everything/"&gt;my personal blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>paper</category>
      <category>data</category>
      <category>architecture</category>
    </item>
    <item>
      <title>My use-case for Go</title>
      <dc:creator>Mario Sangiorgio</dc:creator>
      <pubDate>Sun, 27 Aug 2017 16:33:21 +0000</pubDate>
      <link>https://forem.com/mariosangiorgio/my-use-case-for-go</link>
      <guid>https://forem.com/mariosangiorgio/my-use-case-for-go</guid>
      <description>

&lt;p&gt;After using a few very good applications written in Go (&lt;a href="https://syncthing.net/"&gt;Syncthing&lt;/a&gt;, &lt;a href="https://www.docker.com"&gt;Docker&lt;/a&gt; and &lt;a href="https://gohugo.io/"&gt;Hugo&lt;/a&gt; are some examples) I wanted to get to learn a bit more about the language.&lt;/p&gt;

&lt;p&gt;I'm very interested in programming languages theory and how it could give developers the tools they need to write software in the best possible way and with as many guarantees as possible on the correctness of the resulting applications.&lt;/p&gt;

&lt;p&gt;To get an idea of where programming languages theory is headed have a look at &lt;a href="http://graydon2.dreamwidth.org/253769.html"&gt;the post&lt;/a&gt; &lt;a href="http://twitter.com/graydon_pub"&gt;Graydon Hoare&lt;/a&gt; (the creator of Rust and now one of Swift's developers) published  discussing possible new research directions for programming languages.&lt;/p&gt;

&lt;p&gt;I obviously wasn't expecting Go to address any of these issues but I find it very interesting that its designers deliberately ignored lots of what I would consider &lt;a href="http://yager.io/programming/go.html"&gt;basics features&lt;/a&gt; in the name of simplicity.&lt;br&gt;
The &lt;a href="https://medium.com/@sameer_74231/go-experience-report-for-generics-google-metrics-api-b019d597aaa4"&gt;lack of generics&lt;/a&gt; is often mentioned in discussions regarding Go.&lt;br&gt;
I would have liked Go to have algebraic data types and immutability by default. I would gladly give &lt;a href="https://www.infoq.com/presentations/Null-References-The-Billion-Dollar-Mistake-Tony-Hoare"&gt;&lt;em&gt;nil&lt;/em&gt;&lt;/a&gt; away to get these features.&lt;/p&gt;

&lt;p&gt;On the positive side, Go has good libraries, good tooling, a common style and a syntax that is extremely easy to pick up. It's fast enough and it has good support for concurrency via &lt;a href="https://tour.golang.org/concurrency/1"&gt;goroutines&lt;/a&gt;. It also produces executables that are very easy to deploy anywhere.&lt;/p&gt;

&lt;p&gt;Given this description, it seems to me that Go is an evolution of C and Python and I decided to give it a try  &lt;a href="https://github.com/mariosangiorgio/dunbar-go"&gt;rewriting a project&lt;/a&gt; originally written in Python I am working on.&lt;/p&gt;

&lt;p&gt;That project is very simple, small and self contained. It interacts with Twitter (a good library is a huge plus), and it analyzes my interactions with the people I follow.&lt;br&gt;
The goal is to find out if I'm following people I am not interacting with much.&lt;br&gt;
I somehow ended up following too many people and I needed to find a way to bring my following to a more manageable number.&lt;/p&gt;

&lt;p&gt;That is admittedly something too simple to draw conclusions, but I think it was still good  enough to get a feeling of the language and I had a good impression.&lt;br&gt;
Picking up the language has been very easy, the library I used is good. With respect to Python I have a type system, albeit limited, and I get an executable I can easily deploy with no additional dependencies.&lt;/p&gt;

&lt;p&gt;Given this experience I believe I'll consider Go again for projects of a similar size and scope or for simple command line applications.&lt;br&gt;
For that use case, I believe it's a much better fit than Python while it's simplicity could make me be more productive than if I were  using other languages.&lt;/p&gt;

&lt;p&gt;Originally posted on &lt;a href="https://mariosangiorgio.github.io/post/my-use-case-for-go/"&gt;mariosangiorgio.github.io&lt;/a&gt;&lt;/p&gt;


</description>
      <category>go</category>
      <category>programminglanguages</category>
    </item>
    <item>
      <title>Designing Data-Intensive Applications</title>
      <dc:creator>Mario Sangiorgio</dc:creator>
      <pubDate>Thu, 09 Mar 2017 00:00:00 +0000</pubDate>
      <link>https://forem.com/mariosangiorgio/designing-data-intensive-applications-dd7</link>
      <guid>https://forem.com/mariosangiorgio/designing-data-intensive-applications-dd7</guid>
      <description>&lt;p&gt;I recently read &lt;a href="http://dataintensive.net"&gt;Designing Data-Intensive Applications&lt;/a&gt; by &lt;a href="https://martin.kleppmann.com"&gt;Martin Kleppmann&lt;/a&gt; and I really appreciated it. I especially liked that the book covers a wide range of topics and I think it’s a very good introduction to the subject. I had a prior exposure to most of the covered topics in some university classes, but the book has been a useful refresher and it surely taught me several new things.&lt;/p&gt;

&lt;p&gt;The book starts with details on data modeling and querying with a comparison of the different models and explaining what kind of tasks they’re suitable for. Going throught that chapter will help you decide when it makes sense for you to use a relational database management system or when a NoSQL database is a better choice, just to name two of the most common paradigms. However, I enjoyed that the book doesn’t stop there: it covers a good variety of approaches and it also puts them in their historical context.&lt;/p&gt;

&lt;p&gt;Once you know how to model your data and your queries, it’s time to dive deeper in the implementation of a data storage system. The book covers with enough details different implementation techniques and the data structure commonly used so you’ll know what properties to expect from a system implemented in a certain way.&lt;/p&gt;

&lt;p&gt;The central part of the book shows how to make a data intensive system with certain properties. Here you’ll discover how speading the load over multiple machines is going to let you scale. And you’ll also learn again that distributed systems are hard. The book focuses on replication and partitioning, transactions (both on a single system and distributed). Finally, the central part of the book ends with a chapter about consistency and consensus.&lt;/p&gt;

&lt;p&gt;Once you got so far into the book you’ll have a clearer idea of how storage systems work and you’ll hopefully be able to pick the one that fits with the problem you want to solve. In the final part, the book discusses common patterns to implement applications on top of a storage systems. Depending on the nature of your data you might want to do &lt;em&gt;batch&lt;/em&gt; or &lt;em&gt;stream&lt;/em&gt; processing. Either way, the book discusses the most common approaches.&lt;/p&gt;

&lt;p&gt;I’d really recommend this book. I think it hits the sweet spot between giving a comphrehensive overview and giving enough details and reference to be actually useful. You won’t learn all the implementation details of a particular system, but you’ll learn enough of how a huge variety of systems work so you’ll find yourself in a good position when you’ll have to choose how to implement your data intensive application.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post was originally published on &lt;a href="http://mariosangiorgio.github.io/post/data-intensive/"&gt;mariosangiorgio.github.io&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Do you realy need a dependency injection container?</title>
      <dc:creator>Mario Sangiorgio</dc:creator>
      <pubDate>Sun, 08 May 2016 00:00:00 +0000</pubDate>
      <link>https://forem.com/mariosangiorgio/do-you-realy-need-a-dependency-injection-container</link>
      <guid>https://forem.com/mariosangiorgio/do-you-realy-need-a-dependency-injection-container</guid>
      <description>

&lt;p&gt;I think dependency injection is a very effective technique to write more modular and generally better structured programs. It vastly improves the design of an application encouraging decoupled and highly testable components.&lt;/p&gt;

&lt;p&gt;What I like less is that often programmers who dependency injection also use a container. They use it to wire all the components up using some sort of magic, usually through reflection.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Magic always comes with a price&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The use of magic is exactly the reason why I don’t like containers. They save you from writing some boilerplate code, which is never the hardest thing you’ll write in an application with a decent architecture, and doing so they’ll make you pay the price of losing several extremely useful features.&lt;/p&gt;

&lt;p&gt;Here are some, just to name a few:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;would you like the compiler to show you an error when you miss something? Sorry, this is not going to happen. The container moved wiring your application up at runtime. You’ll get an exception instead.&lt;/li&gt;
&lt;li&gt;do you like when your IDE helps you finding where constructors are used? I do, but the price for not writing some code is that the IDE cannot help me with that. The code is not used anywhere as far as it can tell.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;a href="http://blog.ploeh.dk/2012/11/06/WhentouseaDIContainer/"&gt;Mark Seeman&lt;/a&gt; shows clearly the trade offs between not using a container at all, using it with explicit registrations and using it by convention. The first case is simple and valuable. The second is quite sophisticated and pointless. He claims that the third is sophisticated but valuable.&lt;/p&gt;

&lt;p&gt;When you use a container in the good way, you get something that is low maintenance at the price of using a technique that is hard to learn and weakly typed. That’s definitely not for me, and that’s the reason why I agree with &lt;a href="http://www.yegor256.com/2014/10/03/di-containers-are-evil.html"&gt;yegor256&lt;/a&gt; when he says that DI-containers are code polluters. I think that there is something wrong with your application if you really need to use a container to save you from the burden of putting all the components of your application together. You probably should have a look at how your application is structured rather than hiding the issues under the carpet and pretending that the problem is not there.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This post was originally published on &lt;a href="http://mariosangiorgio.github.io/post/di-container/"&gt;mariosangiorgio.github.io&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;


</description>
      <category>programming</category>
      <category>dependencyinjection</category>
    </item>
  </channel>
</rss>
