<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

  <title><![CDATA[Detail oriented]]></title>
  <link href="https://blog.edfine.io//atom.xml" rel="self"/>
  <link href="https://blog.edfine.io//"/>
  <updated>2017-10-03T15:28:09+00:00</updated>
  <id>https://blog.edfine.io//</id>
  <author>
    <name><![CDATA[Ed Fine]]></name>
    
  </author>
  <generator uri="http://octopress.org/">Octopress</generator>

  
  <entry>
    <title type="html"><![CDATA[Irma L'acide]]></title>
    <link href="https://blog.edfine.io//blog/2017/09/07/irma-lacide/"/>
    <updated>2017-09-07T20:13:22+00:00</updated>
    <id>https://blog.edfine.io//blog/2017/09/07/irma-lacide</id>
    <content type="html"><![CDATA[<h2 id="tampa-bay-hurricane-irma-blog">Tampa Bay Hurricane Irma blog</h2>

<p>It’s not <a href="https://en.m.wikipedia.org/wiki/Irma_la_Douce">Irma La Douce</a>; it’s <em>Irma L’Acide</em> (excuse my French). Nothing sweet about <em>this</em> Irma.</p>

<h3 id="monday-september-11-2017-0040-edt">Monday September 11, 2017 0040 EDT</h3>

<p>The remnants of the northern eyewall of the Category 2 hurricane hammered Lakeland and Bartow with 100+ mph winds and very heavy rain, moving more or less NNW.</p>

<p>Here in northwestern Hillsborough county, the heavy rain and winds have just passed us by, thankfully and almost unbelievably without known damage - we’ll see in the morning.</p>

<p>Here’s a radar image from Fox 13’s SkyTower radar app showing the tail end of the storm near us, and Lakeland due east in the danger zone of the Category 2 hurricane. Our thoughts are with those in the path of that eyewall.</p>

<p><img src="https://blog.edfine.io//images/weather-radar-2017-09-11-0045.jpg" /></p>

<p>Signing off until the morning for some well-earned sleep.</p>

<hr />

<h3 id="sunday-september-10-2017-1842-edt">Sunday September 10, 2017 1842 EDT</h3>

<p>Irma is expected to weaken to a Category 1 hurricane by the time it hits Tampa Bay. One of the reasons given is shear: winds blowing from east to west is pushing Irma to the west (again), disorganizing its circular pattern.</p>

<p>This is in addition to the weakening from having its heat engine removed by being over land.</p>

<p>But like Paul Dellagatto of Fox 13 says, you can’t just look at a number and know what a hurricane is going to do locally. Irma still has an eyewall that is on its way. Anything in its path is going to have a tough time. There are also bands of high, gusty winds and heavy rain to deal with.</p>

<p>Irma is a very unusual hurricane.</p>

<p>It has rain bands that span the entire state.</p>

<p>People who have lived in Tampa for multiple generations have never seen the water in the bay recede as far and fast as they did.</p>

<p>In fact, they receded so fast that some manatees around Sarasota were stranded. We saw video of people dragging a manatee on a tarpaulin into the water, where it swam off.</p>

<p>Residents of those areas near the coast are apprehensive about the return of the waters, which come rushing back fast enough to drown unfortunate people who underestimated the speed with which the storm surge travelled.</p>

<p>Irma is also causing flooding along the entire east coast of Florida and beyond, even though the eye is on the west coast. The winds were high enough in Miami to destroy the anemometers measuring then.</p>

<p>Here in Tampa, we didn’t exactly dodge a bullet: We dodged a cannon shell, but a smaller yet dangerous bullet is still on its way.</p>

<p>I feel much more optimistic than I did 24 hours ago. Then, I was fearing a catastrophic Category 4 storm; now I am expecting a Category 1. Speaking of which, the rain is picking up now, and I think the outer bands are arriving.</p>

<p>Updates here may be delayed when power and communications go out.</p>

<hr />

<h3 id="sunday-september-10-2017-1635-edt">Sunday September 10, 2017 1635 EDT</h3>

<p>Irma made landfall at Marco Island near Naples, at 130 mph. That’s really bad for Marco Island and Naples, and we should spare a thought for their misfortune.</p>

<p>Hurricanes seem to be zero-sum entities. Marco Island’s misfortune has improved our outlook in Tampa Bay. Its landfall is much further south than expected, meaning it is expected to weaken as it travels over land towards us. At the moment (and hurricanes are capricious things, so this is not cast in concrete), it is expected to be a Category 1 or maybe 2 when it gets here.</p>

<p>That’s a lot better than 4 or 5.</p>

<p>Irma is a hurricane of <em>epic</em> proportions.</p>

<p>It is so widespread that at the precise instant Irma made first landfall, Miami, <strong>91 miles away</strong> from the eyewall of Irma, on the other coast of Florida, was getting 90+ mph winds and large storm surge, putting entire streets underwater and blowing over two cranes (hint: not birds) that were previously believed safe.</p>

<p>It is so big that it is causing heavy rain in Georgia - beyond the northern border of our state.</p>

<p>It’s still expected to dump 10-12 inches of rain over Tampa, and winds will still be a sustained 60+ mph, so it’s no picnic, and we will still be without power for anywhere from hours to days or weeks, but our outlook is much better.</p>

<p>Right now, anyway.</p>

<p>We’re waiting anxiously for midnight, the expected peak of the storm, but we are feeling more cheerful about our prospects.</p>

<hr />

<h3 id="saturday-september-9-2017-1934-edt">Saturday September 9, 2017 1934 EDT</h3>

<p>Well, at least Irma is not tracking directly over our house anymore, although the eye is so big it doesn’t make that much difference.</p>

<p>I’ve been talking to our neighbors and my wife about going to a shelter, and also looking on TV at the people who are going to the shelters. Many shelters are already full, and most of the people there seem to be those who live in mandatory evacuation areas and mobile or manufactured or structurally unsafe homes, or are elderly or unable to take care of themselves.</p>

<p>I also heard a response by the meteorologist to questions asked on Facebook to Fox 13 that asked: is it safe to shelter in place in a house that has no storm shutters or window protection?</p>

<p>The answer was unequivocally that, as long as you are not near windows, in an interior room with no windows on the lower floor (we will be - our laundry room), and the house has concrete block construction (it does), and is not in an evacuation zone (it is not), it will be ok.</p>

<p>None of our neighbors are leaving, even those who have no window protection. They are hunkering down in a windowless room and riding out the storm. They are not stupid people - the ones I talked to are intelligent professionals.</p>

<p>We’ve prepared as best as we can. We have flashlights and lots of batteries for them, charged battery packs for the cell phones, food and water for a while. I’ve uploaded insurance photos of the house and possessions, and most of our important documents, to the cloud. The computers in the house are all off and my work is now on a cloud server. My personal data is on a WD MyBook, which is too big to backup to the cloud, so it’s in my backpack with my MacBook and critical things.</p>

<p>Here’s the bottom line: given that we have a well-built, newer house, and enough drinking water and food for 3 days, we are better off than many people in our region who need shelter and would be displaced by us if we went and we didn’t <strong>absolutely</strong> have to.</p>

<p>And that is ultimately unacceptable.</p>

<p>As stupid as it might sound, it’s a calculated risk (in an admittedly very uncertain threat model), so we’re going to ride it out. We’ve told our neighbors where we’re going to be, and of course anyone reading this blog knows, too.</p>

<p>It is going to be really rough, with no power, no running water, no cooling, 4 people being stuck in a small room for at least 12 hours and maybe more, and a massive hurricane blowing outside.</p>

<p>It is what it is.</p>

<p>I’ll update as power and communications allows.</p>

<hr />

<h3 id="friday-september-8-2017-2050-edt">Friday September 8, 2017 2050 EDT</h3>

<p>For Tampa Bay, the current storm track has worsened the local outlook considerably. No longer going up the middle of the state, the track has moved westwards, threatening the Gulf Coast. From storm winds earlier expected to top out at under 60 mph, the forecast has increased to maxima just under 90 mph, and conditions which were recently unfavorable for tornadoes have become favorable.</p>

<p>People in our neighborhood looked uneasily at my next door neighbor, who had had the foresight to have plywood shutters made (probably long ago), nailing them onto his home’s windows. Like us, they probably wished they had thought of that, too, but too late.</p>

<p>Being from southern Africa, where the only natural disasters are flood and famine, this is terra incognita for me (and there’s much terra).</p>

<p>A grim outlook indeed unless the track swings further away from the west coast out to sea, which seems unlikely.</p>

<p><img src="https://blog.edfine.io//images/irma-201709082108-0400.jpg" /></p>

<hr />

<h3 id="friday-september-8-2017-1300-edt">Friday September 8, 2017 1300 EDT</h3>

<p>All SunCoast CU branches closed until further notice:</p>

<blockquote>
  <p>Due to the effects of Hurricane Irma and the safety of our employees, ALL Suncoast Credit Union branches and the Members Care Center will be closed at 1:00 PM on Friday, September 8th through Monday, September 11, 2017. We will reopen on Tuesday, weather permitting; however, this may change based upon the storm’s progression and emergency management recommendations.</p>
</blockquote>

<hr />

<h3 id="friday-september-8-2017-1100-edt">Friday September 8, 2017 1100 EDT</h3>

<p>Irma’s track has shifted west around 11 PM EDT last night so that it drives up the middle of Florida. This is a worst-case scenario because nobody walks away unscathed. It all hinges on precisely when Irma makes its right turn, and what the conditions are at that time.</p>

<p><img src="https://blog.edfine.io//images/irma-201709081118-0400.png" /></p>

<hr />

<h3 id="thursday-september-7-2017">Thursday September 7, 2017</h3>

<p>I have friends and relatives around the world who would appreciate knowing
my family’s status as Hurricane Irma approaches, and hopefully bypasses, Florida.
This blog seems like a good way to publish our status.</p>

<hr />

<h2 id="boring-technical-stuff">Boring Technical Stuff</h2>

<p>I’ve set up my blog so that it lives on Amazon S3 and is replicated by Amazon
Cloudfront. My blog source is on a private hosted <a href="https://git-scm.com/">git</a> repository, and my
publishing software (<a href="https://github.com/imathis/octopress">Octopress</a>) is installed on a <a href="https://www.linode.com/">Linode</a> that has read-only
access to the <a href="https://git-scm.com/">git</a> repo.</p>

<p>I have <a href="https://workingcopyapp.com/">Working Copy</a> and <a href="https://bywordapp.com/">Byword</a> on my iPad, so I can pull the <a href="https://git-scm.com/">git</a> repo,
update the blog and push it back to the <a href="https://git-scm.com/">git</a> repo (if I have any Internet
access).</p>

<p>To publish to S3, I’ll ssh to the <a href="https://www.linode.com/">Linode</a> using <a href="https://panic.com/prompt/">Prompt</a>, pull the <a href="https://git-scm.com/">git</a> repo,
and run <a href="https://github.com/imathis/octopress">Octopress</a> to generate the update and push it to S3.</p>

<p>It’s probably overkill for a blog that almost nobody reads, but it’s good
practice for me.</p>

<!-- Links -->

<!--
vim: set ts=4 sts=4 sw=4 et tw=79:
-->
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How VMware's Ovftool Password Handling Gave Me a Headache]]></title>
    <link href="https://blog.edfine.io//blog/2017/05/02/how-vmwares-ovftool-gave-me-a-headache/"/>
    <updated>2017-05-02T22:23:32+00:00</updated>
    <id>https://blog.edfine.io//blog/2017/05/02/how-vmwares-ovftool-gave-me-a-headache</id>
    <content type="html"><![CDATA[<p><code>ovftool</code> is a <a href="https://www.vmware.com/support/developer/ovf/" title="VMware ovftool page">command-line utility from VMware</a> that lets one do useful things
with VMs on ESXi and vSphere remote systems.</p>

<p>I had installed <code>ovftool</code> and was trying to use it copy a VM between two ESXi
servers, based on <a href="http://www.virtuallyghetto.com/2012/06/how-to-copy-vms-directly-between-esxi.html" title="virtuallyGhetto">this useful post from virtuallyGhetto</a>. For various
reasons, it’s often a better idea to use <code>ovftool</code> for copying VMs than by just
using <code>scp</code> on the raw files.</p>

<p>Immediately, I ran into a WTF? moment.</p>

<pre><code>$ ovftool vi://root@10.1.2.3/
Enter login information for source vi://10.1.2.3/
Username: root
Password: *******
Error: Could not lookup host: root
</code></pre>

<p><code>Error: Could not lookup host: root</code>???</p>

<p>This confused the living daylights out of me. This has <em>nothing at all</em> to do with looking up a host.</p>

<p>Right?</p>

<p>Wrong.</p>

<h3 id="and-the-answer-is-drum-roll">And the answer is… drum roll…</h3>

<p>Locators. At least, the URI-flavored ones. A locator points to different
resource types like VMs or hosts.</p>

<p>When <code>ovftool</code> gets a URI, it’s more or less of the form
<code>protocol://username:password@host:port/</code> or <code>protocol://username@host:port/</code></p>

<p>(<code>protocol</code> can be one of the standard schemes like <code>https</code> or <code>file</code>, or
VMware-specific ones like <code>vi</code> or <code>vcloud</code>.)</p>

<p>If <code>ovftool</code> gets a URI without the password - which I would imagine most
security conscious people would prefer - it quite sensibly prompts for a
password and captures it without displaying it.</p>

<p>At this point, it appears that <code>ovftool</code> forms the full URI - <em>including</em>
password - and uses that to authenticate with the remote system.</p>

<p>You can see where this is going.</p>

<p>The <code>ovftool</code> <a href="https://www.vmware.com/support/developer/ovf/ovf420/ovftool-420-userguide.pdf" title="ovftool PDF user guide">PDF manual</a> clearly notes (but not clearly enough, in my view):</p>

<pre><code>Encoding Special Characters in URL Locators

When you use URIs as locators, you must escape special characters using %
followed by their ASCII hex value.  For instance, if you use a “@” in your
password, it must be escaped with %40 as in vi://foo:b%40r@hostname, and a
slash in a Windows domain name (\) can be specified as %5c.
</code></pre>

<p><em>Now</em> I get it.</p>

<ol>
  <li><code>ovftool</code> captures the password from stdin and does <strong>not</strong> urlencode it.</li>
  <li><code>ovftool</code> forms the URI with the unencoded password, and does <strong>not</strong> check
it for validity.</li>
  <li><code>ovftool</code> uses the URI to contact the remote system.</li>
  <li>The malformed URI is interpreted such that the user name - <code>root</code> in this
case - is considered to be the remote system’s host name.</li>
  <li>The connection attempt dies with the oh-so-misleading message, <code>Error:
Could not lookup host: root</code>.</li>
  <li>I get a headache.</li>
</ol>

<p>This hypothesis can be proven as follows.</p>

<ul>
  <li>urlencode the failing password;</li>
  <li>Feed the encoded password to <code>ovftool</code> at the <code>Password:</code> prompt;</li>
  <li>…</li>
  <li>Profit!!</li>
</ul>

<h3 id="what-i-think-ovftool-does-wrong">What I think <code>ovftool</code> does wrong</h3>

<ol>
  <li><code>ovftool</code> violates <strong>The principle of Least Astonishment</strong>. When a tool
accepts a password for input, it is expected that the tool does any
necessary transformations to it prior to using it. <code>ovftool</code> must urlencode
the password if it obtains it via a password prompt.</li>
  <li><code>ovftool</code> fails to check that the URI is well-formed. The characters that
must be urlencoded in the various parts of a URI are well-known, and it
should be fairly easy to test this.</li>
  <li>A more minor, yet valid quibble, is that <code>ovftool</code> echoes asterisks once the
password has been entered, which is ok, except that it echoes <strong>the same
number of asterisks</strong> as the number of characters in the password. Exact
password length can give a useful clue to a would-be attacker (who would
need to be looking over your shoulder, but still, it’s so easy to avoid
this mistake).</li>
</ol>

<h3 id="a-simple-workaround">A simple workaround</h3>

<p>A simple workaround is to urlencode the password yourself on the command line.
If you have access to a clipboard-copy-paste utility, the entire thing can be
done without displaying the password.</p>

<p>Let’s say that your password is <code>my@random pass/+?$#%^&amp;*()-_+={}[]\|;:'”,/?</code>.</p>

<p>This code snippet will prompt for the unencoded password, urlencode it, and put
it into the clipboard, ready for pasting. The advantage of using this over the
various command-line urlencoding utilities - that might or might not be
available - is that Python is available just about everywhere these days. If
not, there’s always Perl.</p>

<pre><code>python -c 'import urllib; import getpass; print(urllib.quote_plus(getpass.getpass()))' | $CLIPUTIL
</code></pre>

<h4 id="clipboard-utilities">Clipboard utilities</h4>

<p>Possible values of <code>$CLIPUTIL</code> include</p>

<ul>
  <li>Windows 10: <code>clip</code> (or redirect to <code>/dev/clipboard</code> in older versions)</li>
  <li>macOS: <code>pbcopy</code></li>
  <li>Linux (X): <code>xclip -selection c</code></li>
</ul>

<!--
  --
-->
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Git Submodule Cheat Sheet]]></title>
    <link href="https://blog.edfine.io//blog/2017/03/16/git-submodules-cheatsheet/"/>
    <updated>2017-03-16T17:03:58+00:00</updated>
    <id>https://blog.edfine.io//blog/2017/03/16/git-submodules-cheatsheet</id>
    <content type="html"><![CDATA[<p><code>git submodule</code> is powerful, error-prone, and often confusing unless it’s used pretty much daily.</p>

<p>Having a cheat sheet can be pretty useful, so here you go.</p>

<p>This cheat sheet is based on a <a href="https://medium.com/@porteneuve/mastering-git-submodules-34c65e940407#.3lh3wf1z8">post</a> by Christophe Porteneuve (many thanks).</p>

<!-- more -->

<h3 id="configuration-settings">Configuration settings</h3>

<ul>
  <li><code>diff.submodule = log</code> (so you get clearer container diffs when referenced submodule commits changed).</li>
  <li><code>fetch.recurseSubmodules = on-demand</code> (so you are confident new referenced commits for known submodules get fetched with container updates).</li>
  <li><code>status.submoduleSummary = true</code> (so git status gets useful again when a referenced submodule commit changed).</li>
</ul>

<h3 id="adding-or-cloning">Adding or cloning</h3>

<ul>
  <li>Initial add: <code>git submodule add &lt;url&gt; &lt;path&gt;</code></li>
  <li>Initial container clone: <code>git clone --recursive &lt;url&gt; [&lt;path&gt;]</code></li>
</ul>

<h3 id="grabbing-updates-inside-a-submodule">Grabbing updates inside a submodule</h3>

<pre><code>cd path/to/module
git fetch
git checkout -q &lt;commit-sha1&gt;
cd -
git commit -am “Updated submodule X to: blah blah”
</code></pre>

<h3 id="grabbing-container-updates">Grabbing container updates</h3>

<pre><code>git pull
git submodule sync --recursive
git submodule update --init --recursive
</code></pre>

<h3 id="updating-a-submodule-inside-container-code">Updating a submodule inside container code</h3>

<pre><code>git submodule update --remote --rebase -- path/to/module
cd path/to/module
</code></pre>

<h3 id="local-work-testing-eventually-staging">Local work, testing, eventually staging</h3>

<pre><code>git commit -am “Update to central submodule: blah blah”
git push
cd -
git commit -am “Updated submodule X to: blah blah”
</code></pre>

<h3 id="permanently-removing-a-submodule-178">Permanently removing a submodule (1.7.8+)</h3>

<pre><code>git submodule deinit path/to/module
git rm path/to/module
git commit -am “Removed submodule X”
</code></pre>
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Erlang's Internal Data Representation]]></title>
    <link href="https://blog.edfine.io//blog/2016/06/28/erlang-data-representation/"/>
    <updated>2016-06-28T21:12:15+00:00</updated>
    <id>https://blog.edfine.io//blog/2016/06/28/erlang-data-representation</id>
    <content type="html"><![CDATA[<p>I find it interesting how the Erlang BEAM engine represents data in memory.</p>

<h2 id="quick-look-an-erlang-list">Quick look: An Erlang list</h2>

<p>This is the in-memory layout of the Erlang list <code>"phi"</code>.</p>

<p><code>[112, 104, 105]</code></p>

<p><img src="https://blog.edfine.io//images/list.png" /></p>

<!-- more -->

<p>As a reminder, Erlang treats a string as a list of small integers; <code>'p'</code>, for
instance, is <code>112</code>. Don’t worry too much about the bitwise details of the diagram
- we’ll cover those later on.</p>

<p><code>CAR</code> and <code>CDR</code> denote the head and tail of the list, respectively (the Erlang
‘C’ source defines <code>CAR</code> and <code>CDR</code> macros, so I’ve adopted the same Lisp-y
terminology).</p>

<p>Each of <code>CAR</code>, <code>CDR</code>, and <code>NIL</code> occupies one word in memory. A word is 4 bytes
on a 32-bit system, and 8 bytes on a 64-bit system, so “phi” uses <code>2 + 2 + 2 +
1 = 7</code> words (28 bytes on 32-bit, and 56 bytes on 64-bit).</p>

<p>That’s right: <em>56 bytes for a 3-character string</em> on 64-bit systems.</p>

<p>This is why Erlang developers routinely store strings as Erlang binaries.
For more information, see the <a href="http://erlang.org/doc/efficiency_guide/advanced.html#id70525">Erlang Efficiency Guide</a>.</p>

<p>Let’s dig a little deeper into the memory layout.</p>

<h2 id="tagged-erlang-term-eterm">Tagged Erlang term (Eterm)</h2>

<p>Erlang data is represented internally by a <code>typedef</code> named <code>Eterm</code>.</p>

<p>An <code>Eterm</code> (a “tagged Erlang term”) is a data type defined in the Erlang
emulator C code in <a href="https://github.com/erlang/otp/blob/maint/erts/emulator/beam/sys.h#L324"><code>sys.h</code></a>. It is an unsigned integer that is chosen to
be at least as large as a pointer on the architecture for which the Erlang
emulator was compiled.</p>

<p>Tagged values are a clever way of saving memory by taking advantage of memory
alignment rules, and using a word as either an <em>immediate value</em> or a pointer,
depending on its <em>tag</em>.</p>

<p>An <em>immediate value</em> is a value that is in the word itself, as opposed to one
obtained through pointer indirection.</p>

<p>A <em>tag</em> is a fixed number of least significant bits in the word, which are
reserved for identifying attributes of the tagged data. Although this reduces
the size of the data that can be stored in the word, it more than makes up for
it by avoiding or reducing the overhead of pointers and descriptors.</p>

<h3 id="sidebar-tagged-values">Sidebar: Tagged values</h3>

<p>On many CPU architectures, performance is penalized if access is made to data
that is not aligned on a word boundary, that is, a 4 byte boundary on a 32-bit
system, and an 8-byte boundary on a 64-bit system. This fact often drives
designers of memory allocators to place data on word boundaries.</p>

<p>Addresses on word boundaries are even numbers that are multiples of the word
size (e.g. 4, 8, 12, … on 32 bits, 8, 16, 24, … on 64 bits). This means that
the addresses will have binary zeroes in their least significant bits: the
least-significant 2 bits on a 32-bit system, and 3 bits on a 64-bit system.
(This is because 4 in binary is 100 and 8 in binary is 1000).</p>

<p>Taking advantage of this, system programmers use these zero-bits to store
information about the data, which could be an actual value like an integer, or
it could be a pointer. When using a word, the bits are set at the time its data
type is decided. If it’s a pointer type, those bits are masked off (zeroed)
when the word is used (otherwise it would point to the wrong address).</p>

<h2 id="eterms-in-depth">Eterms in depth</h2>

<p>There are 4 primary kinds of <code>Eterm</code>:</p>

<ul>
  <li><strong>Header</strong> - If the data cannot fit into a word, the <code>Eterm</code> becomes a
header, which is a descriptor of the data, followed by the variable-length
data.</li>
  <li><strong>List</strong> - This is a pointer either to the first node of a list, or to the
immediate value NIL. A node is a two-word array to hold <code>CAR</code> and <code>CDR</code>.
<code>CDR</code> points either to the first node of the tail of the list, or <code>NIL</code>.
<code>CAR</code>, being an <code>Eterm</code>, can be a List, Immediate, or Boxed value.</li>
  <li><strong>Boxed</strong> - A boxed <code>Eterm</code> is a pointer to a Header.</li>
  <li><strong>Immediate</strong> - If the data is small enough to fit into a word (minus the
space used by the tag bits), it is called an <em>immediate</em> value.</li>
</ul>

<p>Here’s my view of what the various flavors of <code>Eterm</code> look like for a 32-bit
version of Erlang.</p>

<p><img src="https://blog.edfine.io//images/term.png" /></p>

<p>Note the 4 primary types we just mentioned, namely <strong>Header</strong>, <strong>List</strong>,
<strong>Boxed</strong>, and <strong>Immediate</strong>.  They are identified by the 2 least significant
bits (for example, <strong>Header</strong> is binary <code>00</code>, and <strong>Immediate</strong> is binary
<code>11</code>).</p>

<ul>
  <li>The <strong>Header</strong> type uses an extra 4 tag bits to identify 16 subtypes (only 15
are shown in the image, but <code>BIGNUM</code> has a sign bit, so it really has two
header types).</li>
  <li>The <strong>Immediate</strong> type is broken down into 4 subtypes, but one of those
subtypes is called <strong>Immediate2</strong>, which is not shown but uses an extra two
bits, which extends the number of immediate subtypes and sub-subtypes from 4
to 6, with one spare. The immediate types include a 28-bit small integer,
which gives a signed integer range of <code>-134217729 &lt; i &lt; 134217728</code>. This is
the data type used to represent a character in strings, which is why using
binaries to store long strings is much more space-efficient.</li>
</ul>

<h2 id="basic-erlang-data-types">Basic Erlang Data Types</h2>

<p>We’ve already seen Erlang’s list and small integer, so let’s look at some
other basic data types.</p>

<h3 id="tuple">Tuple</h3>

<p>A tuple is a fixed-size collection of values, somewhat like a <code>struct</code> in ‘C’.</p>

<p>A tuple is also a <em>boxed value</em>, so it consists of a Boxed pointer (1 word) to
an <code>ARITYVAL</code> header (1 word), after which appear the elements of the tuple.</p>

<p>The arity part of the <code>ARITYVAL</code> header is a 26-bit (on a 32-bit system)
integer value containing the number of elements in the tuple. It follows that
the size of a tuple is 2 words + the size of the data following the header.</p>

<p>This is illustrated by this tuple of characters (integers, really).</p>

<p><code>{$H, $e, $l, $l, $o}</code></p>

<p><img src="https://blog.edfine.io//images/tuple.png" /></p>

<hr />

<h3 id="binary">Binary</h3>

<p>A binary is an interesting Erlang data type, because there is more than one flavor:</p>

<ul>
  <li><strong>Heap</strong>: A binary that is up to 64 bytes long is created on the process heap
and is not reference counted.</li>
  <li><strong>Refc</strong>: A binary that is longer than 64 bytes is created in a shared heap,
and is reference counted.</li>
  <li><strong>Sub</strong>: A sub-binary is a descriptor that references a part of a binary. Two
sub-binaries are created when, for example, splitting a binary.</li>
</ul>

<h3 id="heap-binary">Heap binary</h3>

<p>A heap binary uses this data structure:</p>

<figure class="code"><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
</pre></td><td class="code"><pre><code class=""><span class="line">typedef struct erl_heap_bin {
</span><span class="line">    Eterm thing_word;		/* Subtag HEAP_BINARY_SUBTAG. */
</span><span class="line">    Uint size;			/* Binary size in bytes. */
</span><span class="line">    Eterm data[1];		/* The data in the binary. */
</span><span class="line">} ErlHeapBin;</span></code></pre></td></tr></table></div></figure>

<p><code>&lt;&lt;"0123456789ABCDEF"&gt;&gt;</code></p>

<p><img src="https://blog.edfine.io//images/heap_bin.png" /></p>

<h3 id="pid">Pid</h3>

<p>There are two types of <code>pid</code>: internal and external. An internal <code>pid</code> refers
to processes on the local node, while an external <code>pid</code> identifies processes on
remote nodes.</p>

<h4 id="internal-pid">Internal pid</h4>

<p><img src="https://blog.edfine.io//images/pid.png" /></p>

<h4 id="external-pid">External pid</h4>

<p>TODO</p>

<hr />

<h3 id="port">Port</h3>

<p>There are two types of port: internal and external. An internal port refers to
a port on the local node, while an external port identifies those on remote
nodes.</p>

<h4 id="internal-port">Internal port</h4>

<p><img src="https://blog.edfine.io//images/port.png" /></p>

<h4 id="external-port">External port</h4>

<p>TODO</p>

<hr />

<h3 id="combined-data-types">Combined data types</h3>

<p>It gets interesting when we combine the data types. We’ll look at a tuple of
lists, and a list of tuples.</p>

<h4 id="tuple-of-lists">Tuple of lists</h4>

<p><code>{"phi", "eta", "rho"}</code></p>

<p><img src="https://blog.edfine.io//images/tuple_of_lists.png" /></p>

<hr />

<h4 id="list-of-tuples">List of tuples</h4>

<p><code>[{$p,$h,$i}, {$e,$t,$a}, {$r,$h,$o}]</code></p>

<p><img src="https://blog.edfine.io//images/list_of_tuples.png" /></p>

<hr />

<p><strong>Disclaimer</strong></p>

<p>This information is based on an analysis I did of the Erlang C source code on
github circa June 2016. In particular, I looked at <a href="https://github.com/erlang/otp/blob/maint/erts/emulator/beam/erl_term.h"><code>erl_term.h</code></a> and
<a href="https://github.com/erlang/otp/blob/maint/erts/emulator/beam/sys.h"><code>sys.h</code></a>. I did my best to avoid mistakes, but I’m not an expert on
Erlang internals, so YMMV.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Graphviz Org Chart From LDAP]]></title>
    <link href="https://blog.edfine.io//blog/2016/01/05/graphviz-org-chart-from-ldap/"/>
    <updated>2016-01-05T16:14:32+00:00</updated>
    <id>https://blog.edfine.io//blog/2016/01/05/graphviz-org-chart-from-ldap</id>
    <content type="html"><![CDATA[<p>I wrote a simple Python utility, <a href="https://github.com/traviscross/ldap-ad-utils/blob/master/gen-orgchart">gen-orgchart</a>, to pull down
organizational information from an LDAP server and generate an org
chart in Graphviz DOT format.</p>

<!-- more -->

<p>The org chart hierarchy is based on the <code>manager</code> LDAP attribute.
Required LDAP attributes are, by supported schema:</p>

<table>
  <thead>
    <tr>
      <th style="text-align: left">inetOrgPerson</th>
      <th style="text-align: left">Active Directory</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td style="text-align: left"><code>departmentNumber</code></td>
      <td style="text-align: left"><code>department</code></td>
    </tr>
    <tr>
      <td style="text-align: left"><code>displayName</code></td>
      <td style="text-align: left"><code>displayName</code></td>
    </tr>
    <tr>
      <td style="text-align: left"><code>manager</code></td>
      <td style="text-align: left"><code>manager</code></td>
    </tr>
    <tr>
      <td style="text-align: left"><code>o</code></td>
      <td style="text-align: left"><code>company</code></td>
    </tr>
    <tr>
      <td style="text-align: left"><code>title</code></td>
      <td style="text-align: left"><code>title</code></td>
    </tr>
  </tbody>
</table>

<p>The sections below summarize how to use this utility.</p>

<h3 id="usage">Usage</h3>

<figure class="code"><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
</pre></td><td class="code"><pre><code class=""><span class="line">gen-orgchart [options] &lt;ldapuri&gt; &lt;basedn&gt;</span></code></pre></td></tr></table></div></figure>

<h3 id="prerequisites">Prerequisites</h3>

<ul>
  <li>Python 2.x (&gt;= 2.7)</li>
  <li><a href="https://pypi.python.org/pypi/docopt/">docopt</a></li>
  <li><a href="https://pypi.python.org/pypi/jinja2/">jinja2</a></li>
  <li><a href="https://pypi.python.org/pypi/python-ldap/">python-ldap</a></li>
</ul>

<h3 id="comments">Comments</h3>

<ul>
  <li>There’s no real attempt at a pretty layout, but it does the job.</li>
  <li>It would be useful to be able to specify an LDAP filter.
Currently, it includes everything under the base DN, which is not
ideal if the directory is complex.</li>
  <li>It’s useful to pipe the output to a renderer like <code>xdot</code>.</li>
  <li>It’s only been tested on Debian/Ubuntu.</li>
</ul>

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

<figure class="code"><figcaption><span>Getting help </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
</pre></td><td class="code"><pre><code class="bash"><span class="line">gen-orgchart --help
</span></code></pre></td></tr></table></div></figure>

<figure class="code"><figcaption><span>Generate an org chart (long options) </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
<span class="line-number">5</span>
<span class="line-number">6</span>
</pre></td><td class="code"><pre><code class="bash"><span class="line"><span class="c"># Generate an org chart from an Active Directory server at</span>
</span><span class="line"><span class="c"># ldaps://ad.example.com, binding as me@example.com and prompting</span>
</span><span class="line"><span class="c"># for a password.</span>
</span><span class="line">gen-orgchart <span class="se">\</span>
</span><span class="line">    --binddn me@example.com --askpass <span class="se">\</span>
</span><span class="line">    ldaps://ad.example.com <span class="nv">ou</span><span class="o">=</span>people,dc<span class="o">=</span>example,dc<span class="o">=</span>com <span class="p">|</span> xdot -
</span></code></pre></td></tr></table></div></figure>

<figure class="code"><figcaption><span>Generate an org chart (short options) </span></figcaption>
<div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class="line-number">1</span>
<span class="line-number">2</span>
<span class="line-number">3</span>
<span class="line-number">4</span>
</pre></td><td class="code"><pre><code class="bash"><span class="line"><span class="c"># As above, but with short options</span>
</span><span class="line">gen-orgchart <span class="se">\</span>
</span><span class="line">    -D me@example.com -W <span class="se">\</span>
</span><span class="line">    ldaps://ad.example.com <span class="nv">ou</span><span class="o">=</span>people,dc<span class="o">=</span>example,dc<span class="o">=</span>com <span class="p">|</span> xdot -
</span></code></pre></td></tr></table></div></figure>

<!--
ex: ft=markdown ts=4 sts=4 sw=4 et tw=68:
-->
]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[How BofA Froze My Account for Supporting My Children]]></title>
    <link href="https://blog.edfine.io//blog/2015/12/20/how-bofa-froze-my-account-for-money-laundering-because-i-pay-child-support/"/>
    <updated>2015-12-20T19:49:37+00:00</updated>
    <id>https://blog.edfine.io//blog/2015/12/20/how-bofa-froze-my-account-for-money-laundering-because-i-pay-child-support</id>
    <content type="html"><![CDATA[<h3 id="my-open-dear-jane-letter-to-bank-of-america">My open Dear Jane letter to Bank of America</h3>

<p>Dear Bank of America,</p>

<p>Your MSB department believes I am a wicked money launderer or something, so you froze my personal account. If I hadn’t been paying attention, it could have been very nasty indeed, but I drained my accounts and left you only $27.08 in the one you subsequently froze. Don’t spend it all at once.</p>

<!-- more -->

<p>Apparently, my evil scheme was sending monthly child support to my kids in South Africa through XETrade. (By the way, I’ve been doing that since 2005. Oh! The humanity! This is an act that will live in infamy.)</p>

<p>I tried to tell you. I wrote, I called, but you simply ignored the facts.</p>

<p>So, goodbye. I’m breaking it off with you after 17 years. I’ve closed all my accounts with you, not just my personal one. Don’t call, don’t write. I’m not angry or hurt, I just can’t leave my money with you because I can’t trust you any more.</p>

<p>Regards,
Me.</p>

<h3 id="the-sinister-operation-choke-point">The sinister Operation Choke Point</h3>

<p>How, you may ask, were my nefarious activities (pfft!) finally exposed after a decade or so?</p>

<p>A new Bank of America computer system, I was told. And I learned about the strong arm tactics of the United States Department of Justice. And the sinister <a href="https://www.washingtonpost.com/news/volokh-conspiracy/wp/2014/05/24/operation-choke-point/">Operation Choke Point</a>.</p>

<p>And… well, if you have the time and interest, here’s the back story.</p>

<h3 id="the-back-story">The back story</h3>

<p>I develop software for a living. Have done for 30 years or so, and I love it. In 1997 my dream of living and working in the USA came true, and I left South Africa together with my wife and child.</p>

<p>One of the first things I did when I got here was open a checking account with Bank of America. What a great name - it’s America’s Bank, right? My heart swelled with pride.</p>

<p>Fast-forward to late 2003. We all get our permanent residence cards, but my marriage is sadly over (amongst other things, immigration is hard on families). My wife and I negotiate a marital separation agreement in which I commit to sending monthly child support payments, helping with medical expenses, and so on. She heads back to South Africa with our two children. It is a sad time.</p>

<h3 id="wire-transfers-tedious-in-2003">Wire transfers tedious in 2003</h3>

<p>Initially I pay using wire transfers, but to do this, I need to go into my Bank of America branch every month and fill out a form. It also costs more than I think reasonable.</p>

<p>But the Internet quickly matures and in mid-2005, I sign up for XETrade. Now I can send my child support payments online at any time, for less money, at my convenience. I get better forex rates, which is good for my kids. XETrade gets paid via direct debit from my Bank of America personal checking account.</p>

<p>From 2005 to 2015 I send payments through XETrade every month. I also send extra money for things like birthdays and Christmas; to pay for nursing care for my late mother; and for my elder son’s college costs.</p>

<p>Everything is copacetic. And then it isn’t.</p>

<h3 id="the-bank-loses-its-mind">The bank loses its mind</h3>

<p>In November 2015 I get a form letter from Bank of America. My personal account activities apparently include some that are “consistent with activity commonly associated with that of a Money Services Business (MSB).”</p>

<p>I don’t know about you, but I’d never even heard the term “Money Services Business” until then.</p>

<p>The letter goes on to warn that unless the innocuously-named 8-page <em>Customer Data Form for MSBs</em> is filled in and returned within 30 days, my account will be frozen and closed.</p>

<h3 id="i-lose-my-mind">I lose my mind</h3>

<p>At that instant, I take the letter seriously. Actually, I kind of lose my shit. For good reason, as it turns out.</p>

<p>The <em>Customer Data Form for MSBs</em> makes no sense to me. It asks questions about “the business” which, of course, I cannot answer, because “the business” does not exist.</p>

<p>I call MSB Customer Service and speak to a “Kim”. I explain that I have no clue what they are talking about and can’t fill in the form, and why are they targeting me like this?</p>

<p>Kim tells me that my account has transactions with Custom House, which apparently raises flags.</p>

<p>“Custom House…?” I rack my brains. Then it hits me: XETrade is a DBA of Custom House. No problem! I can explain everything, and it will All Be Ok(tm).</p>

<p>I describe how I use XETrade to pay child support to my boys in South Africa. I ask how I am supposed to fill in a form to which there are no answers, and she instructs me exactly which boxes to fill in and what to put in there.</p>

<p>I write a covering letter and fax the whole 10-page shebang to the MSB Fax Line. I fax it at least 3 times to make sure it doesn’t get lost.</p>

<h3 id="whisky-tango-foxtrot-extended-edition">Whisky Tango Foxtrot, Extended Edition</h3>

<p>I get a letter from Bank of America dated November 17 2015, thanking me for the documentation and inexplicably, mind-numbingly, stupefyingly, jaw-droppingly concluding that: “your business activities qualify, under federal guidelines, as a Money Services Business”. Did they literally not get the memo?</p>

<p>It includes a page from my completed data form, advising that I need to provide some extra information, failing which they will freeze my account.</p>

<p>I mean, wtf, right? Wtf,f,f,f,f?!!</p>

<p>At this point I realize that I have already lost the battle. Nothing I say or do that doesn’t involve an army of high-priced lawyers and Scrooge McDuck’s bank vault full of $$$ is going to make any difference.</p>

<p>I go into damage control mode.</p>

<p>I immediately open personal and business accounts at a local credit union and transfer most of my money from Bank of America to the new accounts. I leave only enough to pay outstanding bills and upcoming ACH transactions, and start the tedious process of changing all the ACH details, bill payments, and so on, to use my new accounts.</p>

<p>Now I wait to see what Bank of America does. I fully expect it will freeze my account without further notice.</p>

<p>It doesn’t disappoint me.</p>

<h3 id="baby-its-cold-in-my-account">Baby, it’s cold in my account!</h3>

<p>On Friday, December 18, I get notified via email that my Bill Pay on my personal account has been suspended. I assume this is because my account has been frozen, as threatened. There is no other notice that my account is frozen. Nothing.</p>

<p>The next day, I call Bank of America customer service. The representative confirms that my account is frozen until I return the required documentation. I politely and calmly tell the representative that it will stay frozen until the end of time, because I am never sending in the documentation. I explain the situation and decline all offers to “fix” it - it’s just blowing smoke up my ass, anyway.</p>

<p>I close all my Bank of America accounts and agree to let them mail me cashier’s checks for anything left in the accounts. I don’t care even if they take it all; it’s worth the remaining $100 to me to have the satisfaction of ending the relationship on my terms. I know Bank of America doesn’t really care about my tiny little account, compared to the impending wrath of the mighty US Department of Justice should they not kick me to the kerb.</p>

<h3 id="the-mighty-us-department-of-justice-flexes-its-muscles">The Mighty US Department of Justice Flexes Its Muscles</h3>

<p>Why did it take Bank of America more than 10 years to catch me in the unforgivable act of paying my child support every month? And why is it doing this in the first place?</p>

<p>It turns out that Bank of America recently installed a new computer system that flags “suspicious activities” in customer’s accounts. According to what I read, it was effectively strong-armed into doing this by the US Department of Justice (and <a href="https://www.fincen.gov/">FinCEN</a>).</p>

<p>Which brings me to the sinister <a href="https://www.washingtonpost.com/news/volokh-conspiracy/wp/2014/05/24/operation-choke-point/">Operation Choke Point</a>.</p>

<h3 id="operation-choke-point">Operation Choke Point</h3>

<p>Operation Choke Point is</p>

<blockquote>
  <p>…the U.S. Department of Justice using pressure on the financial system to conduct “a massive government overreach into private businesses that are operating within the law.” <a href="http://www.bizzyblog.com/2014/05/02/establishment-press-virtually-ignored-dojs-pernicious-operation-choke-point/">bizzyblog</a></p>
</blockquote>

<blockquote>
  <p>Let’s not mince words: a program that was built upon the goals of stopping financial fraud has devolved into a massive government overreach into private businesses that are operating within the law. … The intention of the government, it would seem, is to make the banks unwilling to deal with the government harassment and simply cut anyone in those industries off from the financial institutions. Nobody is happy about this. <a href="https://www.techdirt.com/articles/20140430/12191027079/chase-bank-slutshaming-might-only-be-them-dancing-to-dojs-twisted-puppet-strings.shtml">techdirt</a></p>
</blockquote>

<p>Which legal private businesses are targeted? Those in “high-risk merchant categories”.</p>

<h4 id="high-risk-merchant-categories">“High-risk” merchant categories</h4>

<p>This is the DOJ’s shit list. Where do you think I fit in to this?</p>

<ul>
  <li>Ammunition Sales</li>
  <li>Cable Box De-scramblers</li>
  <li>Coin Dealers</li>
  <li>Credit Card Schemes</li>
  <li>Credit Repair Services</li>
  <li>Dating Services</li>
  <li>Debt Consolidation Scams</li>
  <li>Drug Paraphernalia</li>
  <li>Escort Services</li>
  <li>Firearms Sales</li>
  <li>Fireworks Sales</li>
  <li>Get Rich Products</li>
  <li>Government Grants</li>
  <li>Home-Based Charities</li>
  <li>Life-Time Guarantees</li>
  <li>Life-Time Memberships</li>
  <li>Lottery Sales</li>
  <li>Mailing Lists/Personal Info</li>
  <li><strong>Money Transfer Networks</strong></li>
  <li>On-line Gambling</li>
  <li>PayDay Loans</li>
  <li>Pharmaceutical Sales</li>
  <li>Ponzi Schemes</li>
  <li>Pornography</li>
  <li>Pyramid-Type Sales</li>
  <li>Racist Materials</li>
  <li>Surveillance Equipment</li>
  <li>Telemarketing</li>
  <li>Tobacco Sales</li>
  <li>Travel Clubs</li>
</ul>

<h3 id="money-transfer-networks-considered-harmful-by-doj">Money transfer networks considered harmful (by DOJ)</h3>

<p>Yep - Money Transfer Networks. I committed the cardinal sin of using a Money Transfer Network to send support payments to South Africa, namely Custom House (DBA XETrade), a Canadian company. It seems that Custom House’s operations in the USA are handled by Western Union.</p>

<p>But… but… so what??</p>

<p>According to an informed source, it’s <em>guilt by assocation</em>. I was told that shady underworld types linger around Money Transfer Networks, such as Western Union (Custom House’s US partner). Hey, I’m not knocking Western Union, just passing on what I was told.</p>

<h3 id="steaming-pile-of-crap">Steaming pile of crap</h3>

<p>What <em>should</em> I have done? According to the same informed source, what other “respectable” people do: send money using the bank’s own wire transfer services. So that’s what I am doing now via my new credit union. I have to phone the credit union and give the details of my ex-wife’s bank account number, SWIFT code, and so on, <strong>every time</strong>. What - can’t they just save the information? Isn’t that why we have, you know, computers? The response was that it’s policy to have me call in and repeat all that data, every time, and have the phone call recorded.</p>

<p>Isn’t this a steaming pile of crap?</p>

<h3 id="a-cautionary-conclusion">A cautionary conclusion</h3>

<p>Who knew about all this? I certainly didn’t. But even so, I should be able to send my (legitimate) money to my (legitimate) family overseas any way I like, right? The land of the free and all that?</p>

<p>But if I do it again, the same crap will come down on me, so I dare not.</p>

<p>I have been warned, and hopefully, so have you, dear reader.</p>

<hr />

<p>Bank of America MSB Customer Service: 1 (800) 213-0236</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[The Myth of the Fungible Resource]]></title>
    <link href="https://blog.edfine.io//blog/2015/01/16/the-myth-of-the-fungible-resource/"/>
    <updated>2015-01-16T02:25:27+00:00</updated>
    <id>https://blog.edfine.io//blog/2015/01/16/the-myth-of-the-fungible-resource</id>
    <content type="html"><![CDATA[<p>There is a pervasive myth amongst software development management types: the existence of the fungible resource.</p>

<p>A fungible resource is a human cog that managers and executives believe they can drop into a business machine to replace an existing cog. In other words, when developers part ways with a company, many managers believe that their replacements can quickly get up to speed and take over where their predecessors left off.</p>

<!-- more -->

<p>This is rarely true in any substantial development effort.</p>

<p>In his paper, <a href="https://www.dropbox.com/s/n0nud2xp2a9bxjo/Programming%20as%20Theory%20Building.pdf?dl=0" title="Programming as Theory Building">Programming as Theory Building (PDF)</a> Peter Naur - the “Naur” in “Backus-Naur Form” (BNF) - explains that as a program or system is built, the person or team that develops it builds a “theory” of the system. The theory embraces a dimension of software architecture beyond the well-known structural and behavioral views. This dimension cannot adequately be documented, a little like the <a href="http://www.munnecke.com/islands/qwan.htm" title="Quality Without A Name">“Quality Without A Name”</a> cannot be described. No, it’s not <a href="http://rationalwiki.org/wiki/Woo" title="woo">woo</a>. Every great developer understands this intuitively. (The paper is highly recommended reading for the patient and detail-oriented).</p>

<p>Naur describes how engineers who took over the development or maintenance of a system would modify it in ways that “make no use of the facilities that were not only inherent in the structure of the existing [software] but were discussed at length in its documentation, and to be based instead on additions to that structure in the form of patches that effectively destroyed its power and simplicity.”</p>

<p>He goes on to write that</p>

<p>“The conclusion seems inescapable that at least with certain kinds of large programs, the continued adaption, modification, and correction of errors in them, is essentially dependent on a certain kind of knowledge possessed by a group of programmers who are closely and continuously connected with them.”</p>

<p>Basically, you can’t throw away the old cog without steadily increasing grinding noises and smoke emanating from the gearbox as the system dies from the thousand cuts of unguided maintenance.</p>

<p>“The death of a program happens when the programmer team possessing its theory is dissolved…. The actual state of death becomes visible when demands for modifications of the program cannot be intelligently answered”.</p>

<p>Sounds familiar.</p>

<p>Does this mean projects are doomed when they lose their “theoreticians”?</p>

<p>Not necessarily. One way to soften the blow is to retain their services in a mentoring and advisory capacity. A caveat here is that if the advisors do not keep closely connected with the project as it changes, they will lose their special knowledge. Even more importantly, teams need to swallow their pride and actually take the advice of the old guard. This needs no small measure of maturity and humility, qualities which are conspicuously lacking in some developers.</p>

<p>So don’t be so quick to let core developers go. They are not fungible resources.</p>

]]></content>
  </entry>
  
  <entry>
    <title type="html"><![CDATA[Pale Blue Dot]]></title>
    <link href="https://blog.edfine.io//blog/2014/04/05/pale-blue-dot/"/>
    <updated>2014-04-05T14:34:43+00:00</updated>
    <id>https://blog.edfine.io//blog/2014/04/05/pale-blue-dot</id>
    <content type="html"><![CDATA[<p>Let’s put things in perspective: we’re not all <em>that</em> in the grand scheme of things.</p>

<!-- more -->

<p><img src="https://upload.wikimedia.org/wikipedia/commons/7/71/PaleBlueDot.jpg" alt="The Earth as seen by Voyager from 6 billion km" title="Earth at 6 billion km" /></p>

<p>This text is an excerpt from Carl Sagan’s book, Pale Blue Dot: A Vision of the Human Future in Space, 1997 reprint, pp. xv–xvi. The photo was taken by Voyager 1 from the edge of the solar system.</p>

<p>From this distant vantage point, the Earth might not seem of any particular interest. But for us, it’s different. Consider again that dot. That’s here. That’s home. That’s us. On it everyone you love, everyone you know, everyone you ever heard of, every human being who ever was, lived out their lives. The aggregate of our joy and suffering, thousands of confident religions, ideologies, and economic doctrines, every hunter and forager, every hero and coward, every creator and destroyer of civilization, every king and peasant, every young couple in love, every mother and father, hopeful child, inventor and explorer, every teacher of morals, every corrupt politician, every “superstar,” every “supreme leader,” every saint and sinner in the history of our species lived there – on a mote of dust suspended in a sunbeam.</p>

<p>The Earth is a very small stage in a vast cosmic arena. Think of the rivers of blood spilled by all those generals and emperors so that in glory and triumph they could become the momentary masters of a fraction of a dot. Think of the endless cruelties visited by the inhabitants of one corner of this pixel on the scarcely distinguishable inhabitants of some other corner. How frequent their misunderstandings, how eager they are to kill one another, how fervent their hatreds. Our posturings, our imagined self-importance, the delusion that we have some privileged position in the universe, are challenged by this point of pale light. Our planet is a lonely speck in the great enveloping cosmic dark. In our obscurity – in all this vastness – there is no hint that help will come from elsewhere to save us from ourselves.</p>

<p>The Earth is the only world known, so far, to harbor life. There is nowhere else, at least in the near future, to which our species could migrate. Visit, yes. Settle, not yet. Like it or not, for the moment, the Earth is where we make our stand. It has been said that astronomy is a humbling and character-building experience. There is perhaps no better demonstration of the folly of human conceits than this distant image of our tiny world. To me, it underscores our responsibility to deal more kindly with one another and to preserve and cherish the pale blue dot, the only home we’ve ever known.</p>

]]></content>
  </entry>
  
</feed>
