<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>kms</title>
    <link href="http://kyle.marek-spartz.org/atom.xml" rel="self" />
    <link href="http://kyle.marek-spartz.org" />
    <id>http://kyle.marek-spartz.org/atom.xml</id>
    <author>
        <name>Kyle Marek-Spartz</name>
        <email>kyle.marek.spartz@gmail.com</email>
    </author>
    <updated>2015-12-05T00:00:00Z</updated>
    <entry>
    <title>Decisions and the long term</title>
    <link href="http://kyle.marek-spartz.org/posts/2015-12-05-decisions-and-the-long-term.html" />
    <id>http://kyle.marek-spartz.org/posts/2015-12-05-decisions-and-the-long-term.html</id>
    <published>2015-12-05T00:00:00Z</published>
    <updated>2015-12-05T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>When making business decisions, people often use initial or fixed costs to justify their decision. While being difficult to estimate, they still are much easier to estimate than maintenance and marginal costs. However, in the long term, maintenance and marginal costs will outweigh initial and fixed costs, so careful attention must be paid to marginal maintenance costs.</p>
<figure>
<img src="/images/marginal-maintenance-costs.png" alt="Long term costs increase for marginal or maintenance costs, and increase significantly for marginal maintenance costs." /><figcaption>Long term costs increase for marginal or maintenance costs, and increase significantly for marginal maintenance costs.</figcaption>
</figure>
<p>Let’s consider each combination. While a given cost isn’t categorically in one quadrant, these dimensions can be used to conceptualize relative costs of alternatives under consideration.</p>
<h3 id="fixed-initial-costs">Fixed initial costs</h3>
<p>These are one time costs that are always necessary to take a given path, even in an ideal world.</p>
<h3 id="marginal-initial-costs">Marginal initial costs</h3>
<p>These are inefficiencies in implementing a decision that are included each time you make similar decisions. Bureaucracy, redundant efforts, and technical debt are three examples.</p>
<h3 id="fixed-maintenance-costs">Fixed maintenance costs</h3>
<p>These are the base recurring costs that you must incur as a consequence of your decision. Flat membership or licensing fees are a good example.</p>
<h3 id="marginal-maintenance-costs">Marginal maintenance costs</h3>
<p>These are recurring costs that grow proportionally to the number of customers are affected the outcome of your decision. Hiring people or paying for more computers are examples of this. Minimizing these costs has more benefit than reducing the other three types because they are recurring and growing.</p>
<hr />
<p>See also: <a href="http://www.codesimplicity.com/post/the-equation-of-software-design/">The Equation of Software Design</a></p>]]></summary>
</entry>
<entry>
    <title>Themes as Goals</title>
    <link href="http://kyle.marek-spartz.org/posts/2015-11-25-themes-as-goals.html" />
    <id>http://kyle.marek-spartz.org/posts/2015-11-25-themes-as-goals.html</id>
    <published>2015-11-25T00:00:00Z</published>
    <updated>2015-11-25T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>When defining goals, I’ve found themes to be more effective than particular achievements. Themes give clarity of purpose and direction, even when the day to day tactical priorities change. Does my plan for the day fit into my theme?</p>
<p>On the other hand, measuring progress against a theme is difficult. Instead of measuring directly, we have to use proxies. Choose proxies carefully. Be comfortable changing your proxy measurements even when you maintain the theme.</p>]]></summary>
</entry>
<entry>
    <title>Moving to monorepos without losing history</title>
    <link href="http://kyle.marek-spartz.org/posts/2015-11-17-moving-to-monorepos-without-losing-history.html" />
    <id>http://kyle.marek-spartz.org/posts/2015-11-17-moving-to-monorepos-without-losing-history.html</id>
    <published>2015-11-17T00:00:00Z</published>
    <updated>2015-11-17T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>If you’d like to merge two (or more) git repositories together and preserve the commit histories of both, here’s the script for you:</p>
<div class="sourceCode"><pre class="sourceCode bash"><code class="sourceCode bash"><span class="kw">cd</span> some-repo

<span class="kw">git</span> remote add other-repo git@other-repo.com:other-repo/other-repo.git
<span class="kw">git</span> fetch other-repo
<span class="kw">git</span> checkout other-repo/master

<span class="kw">git</span> checkout -b merge-other-repo
<span class="kw">mkdir</span> other-repo

<span class="kw">for</span> <span class="kw">f</span> in *<span class="kw">;</span> <span class="kw">do</span>
  <span class="kw">git</span> mv <span class="ot">$f</span> other-repo
<span class="kw">done</span>

<span class="co"># If you&#39;re making a merge request:</span>

<span class="kw">git</span> merge master --allow-unrelated-histories

<span class="kw">git</span> push origin merge-other-repo

<span class="co"># Then make a merge request</span>

<span class="co"># If you&#39;re pushing directly to master:</span>

<span class="kw">git</span> checkout master

<span class="kw">git</span> merge merge-other-repo

<span class="kw">git</span> push origin master</code></pre></div>]]></summary>
</entry>
<entry>
    <title>Concurrent implementation of the Daytime Protocol in Rust</title>
    <link href="http://kyle.marek-spartz.org/posts/2015-11-16-concurrent-implementation-of-the-daytime-protocol-in-rust.html" />
    <id>http://kyle.marek-spartz.org/posts/2015-11-16-concurrent-implementation-of-the-daytime-protocol-in-rust.html</id>
    <published>2015-11-16T00:00:00Z</published>
    <updated>2015-11-16T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>When learning a language, I rewrite small programs I’ve previously written to jumpstart my learning. Implementing a concurrent <a href="https://en.wikipedia.org/wiki/Daytime_Protocol">Daytime</a> server has proved particularly useful because it uses both sockets and threads. If a language has good socket and threading libraries, it is likely a good language.</p>
<p>Previously, I <a href="http://kyle.marek-spartz.org/posts/2014-08-26-concurrent-implementation-of-the-daytime-protocol-in-haskell.html">demonstrated</a> a Haskell implementation. Here’s an example in Rust:</p>
<div class="sourceCode"><pre class="sourceCode rust"><code class="sourceCode rust"><span class="kw">extern</span> <span class="kw">crate</span> time;

<span class="kw">use</span> std::time::Duration;
<span class="kw">use</span> std::io::Write;
<span class="kw">use</span> std::net::{TcpListener, TcpStream};
<span class="kw">use</span> std::thread;

<span class="kw">fn</span> handle_client(<span class="kw">mut</span> stream: TcpStream) {
    <span class="kw">let</span> date = time::strftime(<span class="st">&quot;%F %T</span><span class="sc">\n</span><span class="st">&quot;</span>, &amp;time::now_utc()).unwrap().to_string();
    <span class="kw">let</span> _ = stream.write(date.as_bytes());
}

<span class="kw">fn</span> main() {
    <span class="kw">let</span> listener = TcpListener::bind(<span class="st">&quot;127.0.0.1:13&quot;</span>).unwrap();

    <span class="kw">for</span> stream <span class="kw">in</span> listener.incoming() {
        <span class="kw">match</span> stream {
            <span class="cn">Ok</span>(stream) =&gt;  {
                thread::spawn(<span class="kw">move</span> || {
                    <span class="co">// connection succeeded</span>
                    thread::sleep(Duration::new(<span class="dv">1</span>,<span class="dv">0</span>));
                    handle_client(stream)
                });
            }
            <span class="cn">Err</span>(_) =&gt; { <span class="co">/* connection failed */</span> },
        }
    }

    drop(listener);
}</code></pre></div>]]></summary>
</entry>
<entry>
    <title>Eventual consistency for SQL: Normalization</title>
    <link href="http://kyle.marek-spartz.org/posts/2015-10-14-eventual-consistency-for-sql-normalization.html" />
    <id>http://kyle.marek-spartz.org/posts/2015-10-14-eventual-consistency-for-sql-normalization.html</id>
    <published>2015-10-14T00:00:00Z</published>
    <updated>2015-10-14T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p><em>Previously, I <a href="http://kyle.marek-spartz.org/posts/2015-09-08-eventual-consistency-for-sql-databases.html">introduced</a> eventual consistency for SQL. This post illustrates how to normalize an eventually consistent SQL database.</em></p>
<p>To demonstrate how to normalize for eventual consistency, let’s design a database for a Twitter clone, consisting of users and statuses. A traditional schema for a Twitter looks like:</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">CREATE</span> <span class="kw">TABLE</span> Users (
  username <span class="dt">VARCHAR</span>(<span class="dv">255</span>) <span class="kw">PRIMARY</span> <span class="kw">KEY</span>,
  email <span class="dt">VARCHAR</span>(<span class="dv">255</span>),
  phone <span class="dt">VARCHAR</span>(<span class="dv">255</span>),
  location <span class="dt">VARCHAR</span>(<span class="dv">255</span>),
  confirmed <span class="dt">BOOLEAN</span> <span class="kw">NOT</span> <span class="kw">NULL</span>,
  salt <span class="dt">VARCHAR</span>(<span class="dv">255</span>) <span class="kw">NOT</span> <span class="kw">NULL</span>,
  hashed_password <span class="dt">VARCHAR</span>(<span class="dv">255</span>) <span class="kw">NOT</span> <span class="kw">NULL</span>
);

<span class="kw">CREATE</span> <span class="kw">TABLE</span> Statuses (
  content <span class="dt">VARCHAR</span>(<span class="dv">140</span>) <span class="kw">NOT</span> <span class="kw">NULL</span>,
  created_at <span class="dt">DATE</span> <span class="kw">DEFAULT</span> ( <span class="fu">SYSDATE</span> ) <span class="kw">NOT</span> <span class="kw">NULL</span>,
  username <span class="dt">VARCHAR</span>(<span class="dv">255</span>) <span class="kw">REFERENCES</span> Users (username) <span class="kw">NOT</span> <span class="kw">NULL</span>,
) <span class="kw">PRIMARY</span> <span class="kw">KEY</span> (content, created_at, user_id);

<span class="kw">CREATE</span> <span class="kw">TABLE</span> Follows (
  follower_username <span class="dt">VARCHAR</span>(<span class="dv">255</span>) <span class="kw">REFERENCES</span> Users (username) <span class="kw">NOT</span> <span class="kw">NULL</span>,
  followee_username <span class="dt">VARCHAR</span>(<span class="dv">255</span>) <span class="kw">REFERENCES</span> Users (username) <span class="kw">NOT</span> <span class="kw">NULL</span>
) <span class="kw">PRIMARY</span> <span class="kw">KEY</span> (follower_username, followee_username);</code></pre></div>
<p>The first step in normalizing for eventual consistency is to identify state changes in your data. For example, a user becomes confirmed after clicking a link in an email or text message. Under the schema above, the following <code>UPDATE</code> statement would get executed:</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">UPDATE</span> Users
<span class="kw">SET</span> confirmed = <span class="kw">true</span>
<span class="kw">WHERE</span> username = <span class="st">&#39;kmarekspartz&#39;</span>;</code></pre></div>
<p>However, since we’re avoiding <code>UPDATE</code>, this will not work. Instead, let’s normalize this mutation out of our database.<a href="#fn1" class="footnoteRef" id="fnref1"><sup>1</sup></a></p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">CREATE</span> <span class="kw">TABLE</span> Confirmations (
  username <span class="dt">VARCHAR</span>(<span class="dv">255</span>) <span class="kw">REFERENCES</span> Users (username) <span class="kw">NOT</span> <span class="kw">NULL</span>
);

<span class="kw">INSERT</span> <span class="kw">INTO</span> Confirmations
<span class="kw">SELECT</span> username
<span class="kw">FROM</span> Users
<span class="kw">WHERE</span> confirmed = <span class="kw">true</span>;

<span class="kw">ALTER</span> <span class="kw">TABLE</span> Users
<span class="kw">DROP</span> <span class="kw">COLUMN</span> confirmed;

<span class="kw">INSERT</span> <span class="kw">INTO</span> Confirmations <span class="kw">VALUES</span> (<span class="st">&#39;kmarekspartz&#39;</span>);

<span class="kw">SELECT</span> Users.*, IS_NULL(Confirmations.username) <span class="kw">AS</span> confirmed
<span class="kw">FROM</span> Users
<span class="kw">LEFT</span> <span class="kw">OUTER</span> <span class="kw">JOIN</span> Confirmations
<span class="kw">ON</span> Users.username = Confirmations.username;</code></pre></div>
<p>Applying this normalization to the rest of the schema would lead to a new schema:</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">CREATE</span> <span class="kw">TABLE</span> Users (
  username <span class="dt">VARCHAR</span>(<span class="dv">255</span>) <span class="kw">PRIMARY</span> <span class="kw">KEY</span>,
  salt <span class="dt">VARCHAR</span>(<span class="dv">255</span>) <span class="kw">NOT</span> <span class="kw">NULL</span>,
  hashed_password <span class="dt">VARCHAR</span>(<span class="dv">255</span>) <span class="kw">NOT</span> <span class="kw">NULL</span>
);

<span class="kw">CREATE</span> <span class="kw">TABLE</span> Confirmations (
  username <span class="dt">VARCHAR</span>(<span class="dv">255</span>) <span class="kw">REFERENCES</span> Users (username) <span class="kw">NOT</span> <span class="kw">NULL</span>
);

<span class="kw">CREATE</span> <span class="kw">TABLE</span> Emails (
  email <span class="dt">VARCHAR</span>(<span class="dv">255</span>) <span class="kw">PRIMARY</span> <span class="kw">KEY</span>
);

<span class="kw">CREATE</span> <span class="kw">TABLE</span> UserEmails (
  username <span class="dt">VARCHAR</span>(<span class="dv">255</span>) <span class="kw">REFERENCES</span> Users (username) <span class="kw">NOT</span> <span class="kw">NULL</span>,
  email <span class="dt">VARCHAR</span>(<span class="dv">255</span>) <span class="kw">REFERENCES</span> Emails (email) <span class="kw">NOT</span> <span class="kw">NULL</span>
) <span class="kw">PRIMARY</span> <span class="kw">KEY</span> (username, email);

<span class="kw">CREATE</span> <span class="kw">TABLE</span> Phones (
  phone <span class="dt">VARCHAR</span>(<span class="dv">255</span>) <span class="kw">PRIMARY</span> <span class="kw">KEY</span>
);

<span class="kw">CREATE</span> <span class="kw">TABLE</span> UserPhones (
  username <span class="dt">VARCHAR</span>(<span class="dv">255</span>) <span class="kw">REFERENCES</span> Users (username) <span class="kw">NOT</span> <span class="kw">NULL</span>,
  phone <span class="dt">VARCHAR</span>(<span class="dv">255</span>) <span class="kw">REFERENCES</span> Phones (phone) <span class="kw">NOT</span> <span class="kw">NULL</span>
) <span class="kw">PRIMARY</span> <span class="kw">KEY</span> (username, phone);

<span class="kw">CREATE</span> <span class="kw">TABLE</span> Locations (
  location <span class="dt">VARCHAR</span>(<span class="dv">255</span>) <span class="kw">PRIMARY</span> <span class="kw">KEY</span>
);

<span class="kw">CREATE</span> <span class="kw">TABLE</span> UserLocations (
  user_location_id <span class="kw">PRIMARY</span> <span class="kw">KEY</span> AUTOINCREMENT
  username <span class="dt">VARCHAR</span>(<span class="dv">255</span>) <span class="kw">REFERENCES</span> Users (username) <span class="kw">NOT</span> <span class="kw">NULL</span>,
  location <span class="dt">VARCHAR</span>(<span class="dv">255</span>) <span class="kw">REFERENCES</span> Locations (location) <span class="kw">NOT</span> <span class="kw">NULL</span>
);

<span class="kw">CREATE</span> <span class="kw">TABLE</span> UserLocationDeletions (
  user_location_id <span class="kw">REFERENCES</span> UserLocations (user_location_id) <span class="kw">NOT</span> <span class="kw">NULL</span>
);

<span class="kw">CREATE</span> <span class="kw">TABLE</span> Statuses (
  content <span class="dt">VARCHAR</span>(<span class="dv">140</span>) <span class="kw">NOT</span> <span class="kw">NULL</span>,
  created_at <span class="dt">DATE</span> <span class="kw">DEFAULT</span> ( <span class="fu">SYSDATE</span> ) <span class="kw">NOT</span> <span class="kw">NULL</span>,
  username <span class="dt">VARCHAR</span>(<span class="dv">255</span>) <span class="kw">REFERENCES</span> Users (username) <span class="kw">NOT</span> <span class="kw">NULL</span>,
) <span class="kw">PRIMARY</span> <span class="kw">KEY</span> (content, created_at, user_id);

<span class="kw">CREATE</span> <span class="kw">TABLE</span> Follows (
  follow_id <span class="kw">PRIMARY</span> <span class="kw">KEY</span> AUTOINCREMENT,
  follower_username <span class="dt">VARCHAR</span>(<span class="dv">255</span>) <span class="kw">REFERENCES</span> Users (username) <span class="kw">NOT</span> <span class="kw">NULL</span>,
  followee_username <span class="dt">VARCHAR</span>(<span class="dv">255</span>) <span class="kw">REFERENCES</span> Users (username) <span class="kw">NOT</span> <span class="kw">NULL</span>
);

<span class="kw">CREATE</span> <span class="kw">TABLE</span> FollowDeletions (
  follow_id <span class="kw">REFERENCES</span> Follows (follow_id) <span class="kw">NOT</span> <span class="kw">NULL</span>
);</code></pre></div>
<p>I’ve turned most properties into many-to-many relationships, and added deletion tables for the join tables. This is because many-to-many relationships are easier to merge than one-to-one. With a many-to-many, you can use <code>UNION</code> as your merge strategy. With one-to-one, there’s not a deterministic way to choose a winner. This will result in temporary inconsistencies, but if you have each user interact with a particular host or shard, you can minimize those inconsistencies. In a mobile environment, the user is interacting with their phone, and we can guarantee that their phone is in a consistent state at any given time. In a server environment, we can route that user’s interactions to a particular host, failing over to an in sync replica if that host is down.</p>
<p>One thing that doesn’t work well with a many-to-many relationship is passwords. I left it as one-to-one, but passwords aren’t needed anymore, particularly when there is an email address or a phone number available. Instead of asking a user for a password, we can send them a link with a token to sign in. This is one-factor authentication, but uses what is commonly a second factor in two-factor authentication. Removing passwords from this schema would make eventual consistency possible.</p>
<hr />
<p>I like to call this method of normalization ‘log normalization’ but that gets <a href="https://en.wikipedia.org/wiki/Log-normal_distribution">confusing</a>. It is too bad we have unique constraints on technical terms. If there’s a better name for this, let <script type="text/javascript">
<!--
h='&#x67;&#x6d;&#x61;&#x69;&#108;&#46;&#x63;&#x6f;&#x6d;';a='&#64;';n='&#x6b;&#x79;&#108;&#x65;&#46;&#x6d;&#x61;&#114;&#x65;&#x6b;&#46;&#x73;&#112;&#x61;&#114;&#116;&#122;';e=n+a+h;
document.write('<a h'+'ref'+'="ma'+'ilto'+':'+e+'" clas'+'s="em' + 'ail">'+'&#x6d;&#x65;'+'<\/'+'a'+'>');
// -->
</script><noscript>&#x6d;&#x65;&#32;&#40;&#x6b;&#x79;&#108;&#x65;&#46;&#x6d;&#x61;&#114;&#x65;&#x6b;&#46;&#x73;&#112;&#x61;&#114;&#116;&#122;&#32;&#x61;&#116;&#32;&#x67;&#x6d;&#x61;&#x69;&#108;&#32;&#100;&#x6f;&#116;&#32;&#x63;&#x6f;&#x6d;&#x29;</noscript> know!</p>
<section class="footnotes">
<hr />
<ol>
<li id="fn1"><p>I’m going to assume offline migrations for simplicity, but these migrations can be achieved in a zero-downtime environment, too. You would create both places for the data reside, deploy a version of the application to read from both, deploy a version of the application to write to both, run a backfill migration (like in the example), then deploy a version which only reads and writes the new place, then drop the old place. Fun!<a href="#fnref1">↩</a></p></li>
</ol>
</section>]]></summary>
</entry>
<entry>
    <title>Eventual consistency for SQL databases</title>
    <link href="http://kyle.marek-spartz.org/posts/2015-09-08-eventual-consistency-for-sql-databases.html" />
    <id>http://kyle.marek-spartz.org/posts/2015-09-08-eventual-consistency-for-sql-databases.html</id>
    <published>2015-09-08T00:00:00Z</published>
    <updated>2015-09-08T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p><a href="https://en.wikipedia.org/wiki/Eventual_consistency">Eventual consistency</a> is typically thought of as a property of certain NoSQL databases. However, SQL databases can achieve eventual consistency with adequate planning.</p>
<p>Eventual consistency is particularly useful for horizontally scaling web services, as each node does not need the full, up to date picture. Another use case is synchronizing mobile applications with intermittent network connectivity. In both cases, partitioning or <a href="https://en.wikipedia.org/wiki/Shard_%28database_architecture%29">sharding</a> allows each user or client to maintain a consistent view.</p>
<p>A data structure is considered eventually consistent if two instances can reach a consistent state given the same unordered set of state changes. Two databases are eventually consistent if all actions taken in one propagate to the other.</p>
<p>Strong eventual consistency can be achieved if state changes are <a href="https://en.wikipedia.org/wiki/Commutative_property">commutative</a>, <a href="https://en.wikipedia.org/wiki/Associative_property">associative</a>, and <a href="https://en.wikipedia.org/wiki/Idempotence">idempotent</a>.</p>
<p>State changes are commutative if swapping two operations yields the same state. For example, these two operations can apply in either order to yield a logically equivalent table:</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">INSERT</span> <span class="kw">INTO</span> some_table (some_column) <span class="kw">VALUES</span> (<span class="dv">1</span>);
<span class="kw">INSERT</span> <span class="kw">INTO</span> some_table (some_column) <span class="kw">VALUES</span> (<span class="dv">2</span>);</code></pre></div>
<p>Similarly, state changes are associative if three operations can be paired either way yielding the same state. For example, three databases each with one of the following operations can be merged as (1 + 2) + 3 or 1 + (2 + 3) to yield a logically equivalent table:</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">INSERT</span> <span class="kw">INTO</span> some_table (some_column) <span class="kw">VALUES</span> (<span class="dv">1</span>);
<span class="kw">INSERT</span> <span class="kw">INTO</span> some_table (some_column) <span class="kw">VALUES</span> (<span class="dv">2</span>);
<span class="kw">INSERT</span> <span class="kw">INTO</span> some_table (some_column) <span class="kw">VALUES</span> (<span class="dv">3</span>);</code></pre></div>
<p>Not all <a href="https://en.wikipedia.org/wiki/Data_manipulation_language">SQL DML</a> can be commutative or associative:</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">UPDATE</span> some_table <span class="kw">SET</span> a = <span class="dv">1</span>;
<span class="kw">UPDATE</span> some_table <span class="kw">SET</span> a = <span class="dv">2</span>;
<span class="kw">UPDATE</span> some_table <span class="kw">SET</span> a = <span class="dv">3</span>;</code></pre></div>
<p>Depending on the order of these operations, the resulting database would be in different states.</p>
<p><code>DELETE</code>s also cause problems. Given two databases, where one has ran a deletion and one has not, merging them would re-insert the deleted row in the database with the deletion:</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">DELETE</span> <span class="kw">FROM</span> some_table <span class="kw">WHERE</span> some_column = <span class="dv">4</span>;</code></pre></div>
<p>We can limit DML to <code>SELECT</code>s and <code>INSERT</code>s to avoid using other synchronization methods. Avoiding updates and deletes provides <a href="https://en.wikipedia.org/wiki/Immutable_object">immutability</a>, which guarantees a row will not change or disappear from our databases.</p>
<p>By staying <code>INSERT</code>-only, we treat our database as a <a href="https://en.wikipedia.org/wiki/Persistent_data_structure">persistent data structure</a>, or an append-only commit log.</p>
<p>Immutability and persistence helps with eventual consistency, but they are not sufficient. We also need idempotence. State changes are idempotent if repeatedly applying the same state change yields the same state. Our previous example, <code>INSERT INTO some_table (some_column) VALUES (1)</code> is not idempotent, unless we de-duplicate rows at query time:</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> <span class="kw">DISTINCT</span> some_column
<span class="kw">FROM</span> some_table;</code></pre></div>
<p>Another way to achieve idempotence is to use a unique constraint to prevent duplicates from being inserted and ignore unique constraint violations upon insertion. We can also manually check for duplicates during an insert:</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">INSERT</span> <span class="kw">INTO</span> some_table (some_column)
<span class="kw">SELECT</span> <span class="dv">4</span>
<span class="kw">WHERE</span> <span class="kw">NOT</span> <span class="kw">EXISTS</span> (
  <span class="kw">SELECT</span> <span class="dv">1</span>
  <span class="kw">FROM</span> some_table
  <span class="kw">WHERE</span> some_column = <span class="dv">4</span>
);</code></pre></div>
<p>How can we delete an item from our database without using SQL <code>DELETE</code>? <a href="https://en.wikipedia.org/wiki/Tombstone_%28data_store%29">Tombstones</a> provide our answer. Instead of <code>DELETE</code>ing the row, we can create a marker in another table that says an object is deleted.</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">INSERT</span> <span class="kw">INTO</span> some_table_deletions (some_table_id)
<span class="kw">VALUES</span> (<span class="dv">123456</span>);</code></pre></div>
<p>Queries for undeleted rows then become:</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">SELECT</span> some_table.*
<span class="kw">FROM</span> some_table
<span class="kw">WHERE</span> <span class="kw">id</span> <span class="kw">NOT</span> <span class="kw">IN</span> (
  <span class="kw">SELECT</span> some_table_id
  <span class="kw">FROM</span> some_table_deletions
);</code></pre></div>
<p>If we want to support deletion and re-adding of the same value, we cannot use a unique constraint for idempotence since the unique constraint would prevent the addition of the new row. Instead, either de-duplicate at query time using <code>DISTINCT</code> or prevent duplicates from getting inserted without using a unique constraint:</p>
<div class="sourceCode"><pre class="sourceCode sql"><code class="sourceCode sql"><span class="kw">INSERT</span> <span class="kw">INTO</span> some_table (some_column)
<span class="kw">SELECT</span> <span class="dv">4</span>
<span class="kw">WHERE</span> <span class="kw">NOT</span> <span class="kw">EXISTS</span> (
  <span class="kw">SELECT</span> <span class="dv">1</span>
  <span class="kw">FROM</span> some_table
  <span class="kw">WHERE</span> some_column = <span class="dv">4</span>
  <span class="kw">AND</span> <span class="kw">id</span> <span class="kw">NOT</span> <span class="kw">IN</span> (
    <span class="kw">SELECT</span> some_table_id
    <span class="kw">FROM</span> some_table_deletions
  )
);</code></pre></div>
<p>At this point it looks like we’ll need to <a href="https://en.wikipedia.org/wiki/Database_normalization">normalize</a> our database, or structure our data in a particular way in order to satisfy these properties. In my next blog post, I’ll demonstrate how to normalize a database to achieve eventual consistency.</p>]]></summary>
</entry>
<entry>
    <title>cons, car, and cdr need not be primitive</title>
    <link href="http://kyle.marek-spartz.org/posts/2015-03-16-cons-car-and-cdr-need-not-be-primitive.html" />
    <id>http://kyle.marek-spartz.org/posts/2015-03-16-cons-car-and-cdr-need-not-be-primitive.html</id>
    <published>2015-03-16T00:00:00Z</published>
    <updated>2015-03-16T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>A <a href="https://en.wikipedia.org/wiki/Lisp_(programming_language)">lisp</a> can be implemented using a small set of primitives from which other lisp features can be derived. The set is not fixed; different lisps use different primitives. <code>cons</code>, <code>car</code>, and <code>cdr</code> are often primitives, but they do not need to be.</p>
<h3 id="primitive-cons-car-and-cdr">Primitive <code>cons</code>, <code>car</code>, and <code>cdr</code></h3>
<p>Typical implementations of <code>cons</code>, <code>car</code>, and <code>cdr</code> use an underlying array representations in their host environment. In a JavaScript host environment, this could look like:</p>
<div class="sourceCode"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="kw">var</span> cons <span class="op">=</span> <span class="kw">function</span> (head<span class="op">,</span> tail) <span class="op">{</span>
  <span class="cf">return</span> [head<span class="op">,</span> tail]<span class="op">;</span>
<span class="op">};</span>

<span class="kw">var</span> car <span class="op">=</span> <span class="kw">function</span> (pair) <span class="op">{</span>
  <span class="cf">return</span> pair[<span class="dv">0</span>]<span class="op">;</span>
<span class="op">};</span>

<span class="kw">var</span> cdr <span class="op">=</span> <span class="kw">function</span> (pair) <span class="op">{</span>
  <span class="cf">return</span> pair[<span class="dv">1</span>]<span class="op">;</span>
<span class="op">};</span></code></pre></div>
<h3 id="derived-cons-car-and-cdr">Derived <code>cons</code>, <code>car</code>, and <code>cdr</code></h3>
<p>To implement <code>cons</code>, <code>car</code>, and <code>cdr</code> as derived features, the lisp should only need function definitions and lambdas as features (either derived or primitive).</p>
<div class="sourceCode"><pre class="sourceCode scheme"><code class="sourceCode scheme">(<span class="kw">define</span><span class="fu"> </span>(<span class="kw">cons</span> head tail)
  (<span class="kw">lambda</span> (f) (f head tail))

(<span class="kw">define</span><span class="fu"> </span>(<span class="kw">car</span> pair)
  (pair (<span class="kw">lambda</span> (head tail) head)))

(<span class="kw">define</span><span class="fu"> </span>(<span class="kw">cdr</span> pair)
  (pair (<span class="kw">lambda</span> (head tail) tail)))</code></pre></div>
<p>This could compile down into:</p>
<div class="sourceCode"><pre class="sourceCode javascript"><code class="sourceCode javascript"><span class="kw">var</span> cons <span class="op">=</span> <span class="kw">function</span> (head<span class="op">,</span> tail) <span class="op">{</span>
  <span class="cf">return</span> <span class="kw">function</span> (f) <span class="op">{</span>
    <span class="cf">return</span> <span class="at">f</span>(head<span class="op">,</span> tail)<span class="op">;</span>
  <span class="op">};</span>
<span class="op">};</span>

<span class="kw">var</span> car <span class="op">=</span> <span class="kw">function</span> (pair) <span class="op">{</span>
  <span class="cf">return</span> <span class="at">pair</span>(
    <span class="kw">function</span> (head<span class="op">,</span> tail) <span class="op">{</span> <span class="cf">return</span> head<span class="op">;</span> <span class="op">}</span>
  )<span class="op">;</span>
<span class="op">};</span>

<span class="kw">var</span> cdr <span class="op">=</span> <span class="kw">function</span> (pair) <span class="op">{</span>
  <span class="cf">return</span> <span class="at">pair</span>(
    <span class="kw">function</span> (head<span class="op">,</span> tail) <span class="op">{</span> <span class="cf">return</span> tail<span class="op">;</span> <span class="op">}</span>
  )<span class="op">;</span>
<span class="op">};</span></code></pre></div>
<p><em>See also:</em> <a href="https://mitpress.mit.edu/sicp/full-text/book/book-Z-H-14.html#%25_thm_2.4">SICP Exercise 2.4</a></p>]]></summary>
</entry>
<entry>
    <title>Review Checklists</title>
    <link href="http://kyle.marek-spartz.org/posts/2015-01-20-review-checklists.html" />
    <id>http://kyle.marek-spartz.org/posts/2015-01-20-review-checklists.html</id>
    <published>2015-01-20T00:00:00Z</published>
    <updated>2015-01-20T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>Review, reflection, and refinement should be part of your routine. I’m a loose follower of <a href="http://gettingthingsdone.com/">GTD</a> and a heavy user of <a href="http://culturedcode.com/things/guide/">Things</a> (though I don’t always use it in the way they suggest), but I’ve struggled to make reviews part of my routine. I made these checklists to lower the barrier of entry. In addition, I’ve created <a href="https://www.beeminder.com/">Beeminder</a> goals to keep me on track.</p>
<p>Unlike most blog posts, this is a living document. I expect it to change. When It does, I plan to make notes of the changes at the bottom.</p>
<h3 id="daily-review">Daily Review</h3>
<p><label><input type="checkbox"/> What do I want to get done today?</label><br> <label><input type="checkbox"/> Check calendar.</label><br> <label><input type="checkbox"/> Review and archive all emails in inboxes, creating next actions as needed.</label><br> <label><input type="checkbox"/> Review next actions in Things, moving to today as needed.</label><br> <label><input type="checkbox"/> Review due today actions in Outlook.</label><br> <label><input type="checkbox"/> Choose one important thing to get done first tomorrow.</label><br></p>
<h3 id="weekly-review">Weekly Review</h3>
<p><label><input type="checkbox"/> What went well last week?</label><br> <label><input type="checkbox"/> What didn’t go well last week?</label><br> <label><input type="checkbox"/> What do I want to get done this week?</label><br> <label><input type="checkbox"/> Review someday actions in Things, moving to next as needed.</label><br> <label><input type="checkbox"/> Review unscheduled actions in Outlook, scheduling as needed.</label><br> <label><input type="checkbox"/> Do I have appointments to make?</label><br></p>
<h3 id="monthly-review">Monthly Review</h3>
<p><label><input type="checkbox"/> What went well last month?</label><br> <label><input type="checkbox"/> What didn’t go well last month?</label><br> <label><input type="checkbox"/> What do I want to get done this month?</label><br> <label><input type="checkbox"/> What events are this month?</label><br> <label><input type="checkbox"/> What projects are my focus this month?</label><br> <label><input type="checkbox"/> Are all recurring items being <a href="https://www.beeminder.com/">minded</a>?</label><br></p>
<h3 id="annual-review">Annual Review</h3>
<p><label><input type="checkbox"/> What went well last year?</label><br> <label><input type="checkbox"/> What didn’t go well last year?</label><br> <label><input type="checkbox"/> What do I want to get done this year?</label><br> <label><input type="checkbox"/> Where do I want to be next year, and how do I get there?</label><br> <label><input type="checkbox"/> What are my priorities for the next year?</label><br></p>
<h3 id="updates">Updates:</h3>
<ol type="1">
<li>Added “What went well” and “didn’t” checkpoints. Added backlog reviews.</li>
<li>Added calendar check. Changed email process from keeping actionable to creating actions.</li>
</ol>]]></summary>
</entry>
<entry>
    <title>Your Turn</title>
    <link href="http://kyle.marek-spartz.org/posts/2015-01-19-your-turn.html" />
    <id>http://kyle.marek-spartz.org/posts/2015-01-19-your-turn.html</id>
    <published>2015-01-19T00:00:00Z</published>
    <updated>2015-01-19T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>This week I’ll be participating in the <a href="http://yourturnchallenge.strikingly.com/">Your Turn Challenge</a>. Participants have promised each other to make at least one blog post each day this week. The challenge combats <a href="https://en.wikipedia.org/wiki/Impostor_syndrome">impostor syndrome</a> and gets a routine going.</p>
<h3 id="impostor-syndrome">Impostor Syndrome</h3>
<p>Impostor syndrome is the fear of claiming you are something you are not. Most often, I see people struggle with it in programming, but personally I have had it when becoming a business owner and with writing.</p>
<blockquote>
<p>“I’m terrible at it.”</p>
</blockquote>
<p>I’ve noticed people with impostor syndrome often have high standards. People get to a point where they can recognize the good from the bad. However, their standards cause them to notice issues in their work that others would gloss over.</p>
<p>These standards are often a reflection of the breadth of their experience. They would not have these standards if they were true impostors.</p>
<blockquote>
<p>“What if I fail?”</p>
</blockquote>
<p>We hear about others’ successes, but usually not about the failures that lead to their eventual successes. Even with failure, we learn. Sometimes the best lessons are learned when we fail. Embrace failure and jump in.</p>
<blockquote>
<p>“What if I say the wrong thing?”</p>
</blockquote>
<p>With many things in life, you have to claim it before growth can happen. This is the “fake it until you make it” strategy. If you are waiting to be qualified, you’ll have missed your opportunity. Qualification comes through experience; your qualifications will catch up.</p>
<h3 id="habit-routine-ritual">Habit, routine, ritual</h3>
<p>We improve when we iterate and reflect. Each program, business opportunity, and blog post is an opportunity to start again. Get in a habit of reflecting on lessons learned in previous iterations. Build a routine of trying something new. Make starting a ritual.</p>]]></summary>
</entry>
<entry>
    <title>Hakyll CSS Template Compiler</title>
    <link href="http://kyle.marek-spartz.org/posts/2014-12-09-hakyll-css-template-compiler.html" />
    <id>http://kyle.marek-spartz.org/posts/2014-12-09-hakyll-css-template-compiler.html</id>
    <published>2014-12-09T00:00:00Z</published>
    <updated>2014-12-09T00:00:00Z</updated>
    <summary type="html"><![CDATA[<p>Google wasn’t happy with how many render-blocking resources I was loading from pages on this site. It suggested that I inline render-blocking CSS.</p>
<p>I’m not sold that this is ideal. Previously, if a client requested a resource they already had, they wouldn’t necessarily need to re-download the resource. The CSS being used across pages could be cached, so each request would only get the necessary unique data. Other than the initial fetch which would get all the resources, the amount of information exchanged is minimal.</p>
<p>With the CSS inline, this content cannot be cached (across pages), and therefore it is downloaded for each page. While there are fewer requests needed to get a single page, there is redundant information being included in each request.</p>
<p>Anyway, I thought I’d try it out. <a href="http://jaspervdj.be/hakyll/">Hakyll</a> provides a <a href="https://github.com/jaspervdj/hakyll/blob/59b6f01218eb2fbd36cb9fec6a3413093171ccda/src/Hakyll/Web/CompressCss.hs#L24">CSS compiler</a> which compresses CSS by removing whitespace, comments, and redundant punctuation. It also provides a <a href="https://github.com/jaspervdj/hakyll/blob/59b6f01218eb2fbd36cb9fec6a3413093171ccda/src/Hakyll/Web/Template.hs#L147">template compiler</a>, which allows variable substitution and nesting of templates. However, it doesn’t provide a way to compress CSS inside a template. I took the definition of it’s template compiler and its CSS compiler and combined them:</p>
<div class="sourceCode"><pre class="sourceCode haskell"><code class="sourceCode haskell"><span class="ot">cssTemplateCompiler ::</span> <span class="dt">Compiler</span> (<span class="dt">Item</span> <span class="dt">Template</span>)
cssTemplateCompiler <span class="fu">=</span> cached <span class="st">&quot;Hakyll.Web.Template.cssTemplateCompiler&quot;</span> <span class="fu">$</span>
    fmap (readTemplate <span class="fu">.</span> compressCss) <span class="fu">&lt;$&gt;</span> getResourceString</code></pre></div>
<p>I made a <a href="https://github.com/zeckalpha/kyle.marek-spartz.org/commit/802be82df158a17e4e68615af661e89c4d4829ed">few other changes</a> in order to make this work. I needed to <a href="https://github.com/zeckalpha/kyle.marek-spartz.org/commit/802be82df158a17e4e68615af661e89c4d4829ed#diff-65cfe7d4cb9e2a84b335aee2b8c9fd61R1">combine my CSS files</a>, and then <a href="https://github.com/zeckalpha/kyle.marek-spartz.org/commit/802be82df158a17e4e68615af661e89c4d4829ed#diff-456a69052615a663e52659628e6583a8R10">include</a> the combined CSS as a partial template in my default template.</p>
<p>I did have one CSS file that I couldn’t inline like this, since it specifies additional resources to fetch (fonts), but this is a Google hosted file, so hopefully they won’t hold it against me. Google suggested that I create a link to this file after rendering, using JavaScript, so <a href="https://github.com/zeckalpha/kyle.marek-spartz.org/commit/802be82df158a17e4e68615af661e89c4d4829ed#diff-456a69052615a663e52659628e6583a8R52">that</a>’s in my changes, too.</p>]]></summary>
</entry>

</feed>
