<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
    <title>Lawrence Kesteloot&#x27;s writings</title>
    <link>https://www.teamten.com/lawrence/writings/</link>
    <description>Lawrence Kesteloot&#x27;s writings</description>
    <language>en-us</language>
    <copyright>Copyright 1993-2015 Lawrence Kesteloot.</copyright>
    <managingEditor>lk@teamten.com (Lawrence Kesteloot)</managingEditor>
    <atom:link href="https://www.teamten.com/lawrence/writings/rss.xml" rel="self" type="application/rss+xml"/>

    <item>
        <title><![CDATA[Base 10 Is Not a Good Base]]></title>
        <link>https://www.teamten.com/lawrence/writings/base-10-is-not-a-good-base.html</link>
        <author>lk@teamten.com (Lawrence Kesteloot)</author>
        <guid isPermaLink="true">https://www.teamten.com/lawrence/writings/base-10-is-not-a-good-base.html</guid>
        <pubDate>Sat, 17 Feb 2024 08:00:00 -0000</pubDate>
        <description><![CDATA[<p>I thought of another reason I don’t really like the metric system: Base 10 is
not a good base. You want your base to either be a power of 2 so that you can
keep dividing by two (like a gallon has 128 fluid ounces) or have a bunch of
useful factors (like a foot has 12 inches, so you can easily get ⅓ or ¼; and a
minute has 60 seconds). Base 10’s factors are not great; you rarely want to
divide anything by 5.</p>
<p>Some alien race has eight fingers, and when they visit here they understand
<em>why</em> we use base 10, but it must be striking to them how bad of a base it is.
Like you have 100 grams and you can divide it by 2 twice and after that you can
only divide it by 5. Who needs to divide by 5? Especially in cooking.</p>
<p>It’d be like if we found an alien species that used base 14 for everything. One
unit, then 14, then 196?! If you have 196 grams, you can divide it by 2 twice
and then you can only divide it by 7? Bad base! Use 12 or 8 or something.</p>
<p>Metric’s entire foundation is a bad base.</p>]]></description>
    </item>

    <item>
        <title><![CDATA[Dimension vs. Rank]]></title>
        <link>https://www.teamten.com/lawrence/writings/dimension-vs-rank.html</link>
        <author>lk@teamten.com (Lawrence Kesteloot)</author>
        <guid isPermaLink="true">https://www.teamten.com/lawrence/writings/dimension-vs-rank.html</guid>
        <pubDate>Fri, 09 Sep 2022 07:00:00 -0000</pubDate>
        <description><![CDATA[<p>I&rsquo;ve long been confused by the two definitions of the word <em>dimension</em>.
Sometimes we talk about a 3-dimensional array:</p>
<div class="codehilite"><pre><span></span><code><span class="kt">float</span><span class="w"> </span><span class="n">a</span><span class="p">[</span><span class="mi">5</span><span class="p">][</span><span class="mi">6</span><span class="p">][</span><span class="mi">7</span><span class="p">];</span>
</code></pre></div>

<p>and sometimes we talk about a 3-dimensional vector:</p>
<div class="codehilite"><pre><span></span><code><span class="kt">float</span><span class="w"> </span><span class="n">v</span><span class="p">[</span><span class="mi">3</span><span class="p">];</span>
</code></pre></div>

<p>I finally figured out that the word is only correctly used in the second
example above. In the first example, the term should be <em>rank</em>, as in,
&ldquo;a rank-3 array&rdquo;.</p>
<p>So <em>rank</em> is the <em>number of indices</em> that you need to get to a scalar. In
the first example you need three indices to get a float:</p>
<div class="codehilite"><pre><span></span><code><span class="n">x</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">a</span><span class="p">[</span><span class="n">i</span><span class="p">][</span><span class="n">j</span><span class="p">][</span><span class="n">k</span><span class="p">];</span>
</code></pre></div>

<p>Each of these indices has a range of valid values, and this is the <em>dimension</em>
of that index. Again with the first example, the dimension of the first index
is 5, of the second is 6, and of the third is 7. This is why it&rsquo;s correct to
call the second example &ldquo;a 3 dimensional vector&rdquo;. It has rank 1 and its only
index can have three values (0, 1, and 2). Vectors are always rank 1 and
matrices are always rank 2.</p>
<p>Looks like this terminology has always been used in mathematics. I wonder why
in programming we misappropriated <em>dimension</em> to mean <em>rank</em>.</p>
<p class="cover-credit">(Cover image credit: Midjourney, &ldquo;photorealistic large infinite matrices in
space hypercube 3d multidimensional&rdquo;)</p>]]></description>
    </item>

    <item>
        <title><![CDATA[Roe v. Wade]]></title>
        <link>https://www.teamten.com/lawrence/writings/roe-v-wade.html</link>
        <author>lk@teamten.com (Lawrence Kesteloot)</author>
        <guid isPermaLink="true">https://www.teamten.com/lawrence/writings/roe-v-wade.html</guid>
        <pubDate>Fri, 15 Jul 2022 07:00:00 -0000</pubDate>
        <description><![CDATA[<p>I’m not thrilled about the overruling of <em>Roe v. Wade</em>, but let’s try to look for upsides.</p>
<p>(Background: In 1973 the U.S. Supreme Court ruled that abortion was a
constitutionally-guaranteed fundamental right, due to the 14th Amendment’s Due
Process clause’s “right to privacy”. In 2022 this was overruled, again by the
U.S. Supreme Court, mostly on the grounds that abortion was not a historical
right in the U.S. This returned the issue to statutory law, where states and
other jurisdictions can pass abortion-restricting laws without limits.)</p>
<p>When <em>Roe</em> passed,
<a href="https://en.wikipedia.org/wiki/Abortion_in_the_United_States#Roe_v._Wade">46 states</a>
either fully (30) or mostly (16) banned abortions. The Supreme Court wielded a
huge amount of power in invalidating important
laws in the supermajority of states. Giving that kind of power to an
institution is asking for trouble, since that institution might some day be
controlled by the opposition. A Supreme Court packed with Scalia types might
ban abortions nationwide, perhaps quoting the same 14th Amendment: “nor shall
any State deprive any person of life”. I suspect pro-choice citizens would
suddenly decide that courts should not adjudicate abortion rights! It might be
best if we all agreed that such issues shouldn’t be decided by the courts,
since its members’ appointments are long-lived and mostly disconnected from
voter preferences. The U.S. Supreme Court is especially prone to shaky and
fickle interpretations of the Constitution. A small undemocratic fickle group
is hardly the best source for a policy so important to nearly every American!</p>
<p>Not only that, but these decisions shouldn’t be decided at the national level,
as Biden (through executive orders) and Congress are currently trying to do.
Again we can imagine a conservative president or Congress that bans abortions
nationwide. As terrible as it is for women in abortion-banned states to have to
travel to other states, it would be worse if they didn’t even have that option.
The more local the decision, the less they’d have to travel. Every red state
has large blue cities within a few hours’ drive. I think it’s unlikely we’d
actually decide these things at the city or county level, but perhaps we should
agree to aim for that and away from nationwide decisions and statutes.</p>
<p>For the same reason, perhaps we shouldn’t try to pass a constitutional
amendment to guarantee abortion rights. It might backfire and ban them!
Whatever power you’re tempted to give to an institution, first imagine the
opposition controlling that institution. This doesn’t argue against giving any
institution power — only that you should be okay with the opposition also
controlling that institution, and whatever repercussions that might have.
Typically this works best when the institution has checks and balances, and has
effective error correction mechanisms (such as recalls). As a gut check, if the
idea of an amendment banning abortion terrifies you, then, as a matter of
principle, perhaps don’t look to amendments as a solution to abortion rights.</p>
<p>There may be a more subtle silver lining. It’s been a mystery for a while,
that, when polled, a solid majority of American voters would prefer abortion to
remain legal. (It’s
<a href="https://en.wikipedia.org/wiki/Abortion_in_the_United_States#By_educational_level">between 54% and 70%</a>
depending on education level.) How
are red states even able to pass these laws? How are pro-life politicians even
elected? Here’s one possible explanation. Imagine a voter who is (say) fiscally
conservative and pro-choice. They can choose between a Democrat and a
Republican candidate. They know the Republican is pro-life, but they also know
that this is irrelevant, since <em>Roe v. Wade</em> guarantees that this candidate won’t
be able to actually curtail abortion rights. This person can vote Republican
and get both of their preferences.</p>
<p>Without <em>Roe v. Wade</em>, though, this voter must choose between their fiscally
conservative preference and their pro-choice preference. I don’t know how many
such voters there are, but some of these voters will switch from voting
Republican to voting Democrat. If the effect is large enough, it’ll put
pressure on <em>some</em> Republican politicians to moderate their abortion stance.
Again this effect will be greatest on a local level; another reason to push
decisions that way.</p>
<p>The opposite combination might exist too (a voter who is fiscally liberal but
pro-life and currently votes Democrat, but switches to Republican), though
presumably there are fewer of those, given the above polling statistics.</p>
<p>So, overall I think the reversal is a loss for the pro-choice movement, but
perhaps the Democratic Party will pick up some voters along the way. At the
very least we’ll see how many of these pro-life voters and politicians are
truly willing to curtail abortion rights, and how many were bluffing.</p>
<p class="cover-credit">(Cover image credit: DALL-E, &ldquo;Painting of nine judges surrounding a sad
pregnant woman.&rdquo;)</p>]]></description>
    </item>

    <item>
        <title><![CDATA[Pronouncing Hex]]></title>
        <link>https://www.teamten.com/lawrence/writings/pronouncing-hex.html</link>
        <author>lk@teamten.com (Lawrence Kesteloot)</author>
        <guid isPermaLink="true">https://www.teamten.com/lawrence/writings/pronouncing-hex.html</guid>
        <pubDate>Wed, 08 Jun 2022 07:00:00 -0000</pubDate>
        <description><![CDATA[<p>In the show <em>Silicon Valley</em> T.J. Miller&rsquo;s character, Erlich Bachman,
asks someone &ldquo;&hellip; what nine times F is. It&rsquo;s fleventy-five.&rdquo;</p>
<p><iframe width="640" height="480" src="https://www.youtube.com/embed/_zTpwNR5Bf4?rel=0" frameborder="0" allowfullscreen></iframe></p>

<p>The answer is <code>0x87</code>. It sounds like it should
be <code>0xF5</code>, so Tim Babb took this and made a
<a href="https://www.bzarg.com/p/how-to-pronounce-hexadecimal/">whole scheme</a>
for pronouncing hex numbers.
Before that, <code>0xF5</code> would have been &ldquo;fimtek five&rdquo; in
<a href="http://www.intuitor.com/hex/words.html">S.R. Rogers&rsquo; 2007 scheme</a>,
&ldquo;fytonsu&rdquo; in
<a href="https://www.futilitycloset.com/2020/02/28/the-tonal-system/">John W. Nystrom&rsquo;s 1859 scheme</a>,
and &ldquo;frosty five&rdquo; in
<a href="https://en.wikipedia.org/wiki/Hexadecimal#Verbal_and_digital_representations">Robert Magnusson&rsquo;s 1968 scheme</a>:</p>
<p><img alt="Robert Magnusson hex scheme" src="hex.jpeg" /></p>
<p>None of these took off, which is just fine, but I still want to
know whether to pronounce <code>0x10</code> as &ldquo;ten&rdquo; or &ldquo;one zero&rdquo;.
I can&rsquo;t tell if &ldquo;eleven&rdquo; means two written <code>1</code>s, or if
it always means the abstract number that&rsquo;s represented in decimal as <code>11</code>.
Most would probably say &ldquo;eleven hex&rdquo; for <code>0x11</code>, but then is <code>0b11</code> &ldquo;eleven binary&rdquo;?
That seems completely wrong.</p>
<p>Rogers used &ldquo;ten&rdquo;, &ldquo;eleven&rdquo;, and &ldquo;twelve&rdquo; to mean their decimal value,
so he used those for <code>0xA</code>, <code>0xB</code>, and <code>0xC</code>. After that he made up other
names, like &ldquo;draze&rdquo; for <code>0xD</code>. Maybe that&rsquo;s because &ldquo;eleven&rdquo; and &ldquo;twelve&rdquo;
don&rsquo;t have a &ldquo;ten&rdquo; or &ldquo;teen&rdquo; in their name, so they can be decoupled
from base ten. Except that the &ldquo;tw&rdquo; of &ldquo;twelve&rdquo;
<a href="https://www.etymonline.com/word/twelve">comes from &ldquo;two&rdquo;</a>!</p>
<p>I had a friend once argue that &ldquo;sixteen&rdquo; clearly means six plus ten, so <code>0x10</code>
should be pronounced &ldquo;sixteen&rdquo; (or &ldquo;one zero hex&rdquo;) and <code>0x16</code> should not. But
that depends on you defining &ldquo;ten&rdquo; to be decimal <code>10</code> and not <code>0x10</code>. It would
be internally consistent to define <code>0x10</code> as &ldquo;ten&rdquo; and <code>0x46</code> &ldquo;forty six hex&rdquo;.
You&rsquo;d just need to spell out the letters if they appear, like &ldquo;forty eff&rdquo;
for <code>0x4F</code> and &ldquo;eff five&rdquo; for <code>0xF5</code>.</p>
<p>In the end I think it&rsquo;s too awkward to think of &ldquo;ten&rdquo; as just decimal <code>10</code>. That
means <code>0xA</code> is &ldquo;ten&rdquo; and <code>0x10</code> is, what, &ldquo;hex one zero&rdquo;? Then <code>0x4000</code> is
&ldquo;hex four zero zero zero&rdquo;? I&rsquo;ll stick with what I&rsquo;ve seen most people do,
which is to re-use the decimal labels and just say &ldquo;hex&rdquo; in front:
&ldquo;hex four thousand&rdquo;. After all, bases are just ways of <em>writing</em> numbers,
and speech can just tag along with that instead of pretending that spoken
numbers are always magically in decimal.</p>]]></description>
    </item>

    <item>
        <title><![CDATA[Homeschooling]]></title>
        <link>https://www.teamten.com/lawrence/writings/homeschooling.html</link>
        <author>lk@teamten.com (Lawrence Kesteloot)</author>
        <guid isPermaLink="true">https://www.teamten.com/lawrence/writings/homeschooling.html</guid>
        <pubDate>Wed, 17 Feb 2021 08:00:00 -0000</pubDate>
        <description><![CDATA[<p>When Milo was in kindergarten, I read Seth Godin&rsquo;s
<a href="https://medium.com/@thisissethsblog/stop-stealing-dreams-4116c7dbff7b">Stop Stealing Dreams</a>,
which argues that schools are no longer the appropriate way to educate
children. The essay haunted me for years, as I sent Milo to public school,
to sit in a chair all day and have uninteresting (to him) information
pushed on him.</p>
<p>Two months into Milo&rsquo;s 7th grade, Jen and I decided to pull him out for two
years. Reasons included:</p>
<ul>
<li>His middle school was pretty bad.</li>
<li>He was still young enough to enjoy spending time with us. We knew this wouldn&rsquo;t last.</li>
<li>This was our last chance to truly spend quality time with him.</li>
<li>We were in a unique situation to do this, since both of us worked at home.</li>
</ul>
<p>The experience was such a surprise that I think it&rsquo;s worth writing it up for
those who are considering it.</p>
<p>Initially we found a few homeschooling books and online classes (such as
<a href="https://outschool.com/]">Outschool</a>) and made a token
effort to help him through them. Of course as a 13-year-old boy, all he wanted
to do was play video games, and he&rsquo;d race through whatever worksheets he&rsquo;d been
assigned so he could get back to Minecraft.</p>
<p>This got tiring, so I eventually told him that since his friends get out of school at
3:30pm, before that he can&rsquo;t play games no matter what, and after that he
doesn&rsquo;t have to do any schoolwork and can play all he wants, just like his friends.
In addition, since the books and online classes we&rsquo;d given him didn&rsquo;t fill up all
his hours before 3:30pm, he could spend the extra time doing anything at all
as long as he was learning.</p>
<p>I would walk into his room at 3:29pm and find him counting down the seconds
to launching Minecraft. This happened week after week. He&rsquo;d fill the first half
of his day with assigned work, or he&rsquo;d find some YouTube tutorial that interested
him, but he stopped the minute he could.</p>
<p>Then one day I walked in at 4pm and he was still following some online
tutorial, I think for how to do something in Photoshop. I quietly walked back
out. A week later I found him still doing learning-related work at 5pm. Then
a few weeks later at 6pm. Within six months he was aggressively learning
seven days per week, every hour of the day. He played a few hours of
video games per week.</p>
<p>The learning was entirely self-driven. He&rsquo;d wake up and think, &ldquo;Hey, I wonder
how they pull green screens for visual effects,&rdquo; watch five YouTube tutorials
on it, shoot some video against a green sheet, and spend the rest of the day
pulling green screens in Photoshop and After Effects. The next day he&rsquo;d get
inspired to make a weird gear mechanism, model it in Fusion 360, 3D print it,
and iterate until it worked well. The day after that he&rsquo;d write a video
game in Pico-8.</p>
<p>Jen and I found this so great that we backed off on the material we asked him
to do. We had read about &ldquo;unschooling&rdquo;,
<a href="http://daviddfriedman.blogspot.com/2007/12/home-unschooling-theory.html">especially from David Friedman</a>,
and while it&rsquo;d seemed crazy to us at the time, here we were effectively doing it.
The second year, Jen spent an hour or so per day teaching him French (from her high school
textbook!), and I spent 30 minute per week teaching him pre-algebra. (Yes, per week,
it was an <a href="https://www.amazon.com/Everything-You-Need-Math-Notebook/dp/0761160965">excellent 50-chapter book</a> and each chapter was only a few pages.)</p>
<p>During that time he slowly lost contact with his friends and made fewer
attempts to meet them after school. This worried us somewhat, and for various reasons
we put him back into public school for freshman year. Despite having spent nearly no
time learning math for two years, and zero time learning any other academic
subject, he found himself at the top of his grade in math and sailed through the
year with straight As. This also surprised us&mdash;we had expected him to need remedial work.</p>
<p>So, what happened? Why did it take six months for him to get into the self-learning
groove? I now make a distinction between <em>education</em> and <em>learning</em>. With education
someone else decides what they&rsquo;re going to teach you, and they <em>push</em> it onto you.
With learning you get interested in a questions and <em>pull</em> the answer from books,
people, videos, and other resources, and the information sticks.</p>
<p>I don&rsquo;t think there&rsquo;s much overlap between education and learning. Rarely a student
will be interested in what the teacher is teaching (by coincidence or
because the teacher is good at generating interest), and when that happens, the
information sticks. But most of the time the two are unrelated and the student
remembers little.</p>
<p>We&rsquo;re all told that education and learning are the same&mdash;if education is happening,
then learning is happening. And students go through years of education. No wonder
they think that learning is something to be avoided! They&rsquo;ve rarely actually
experienced it. We all figure out that education (and, incorrectly, learning) is
a game where the teacher tries to get you to remember something and you try
to do as little work as possible while getting acceptable grades.</p>
<p>When Milo started homeschooling, he was still in that mindset. He&rsquo;d do whatever
minimal work he needed to check off his assignment so he could get back to
what he knew he&rsquo;d enjoy: video games. It took months for him to detox and
realize the education and learning are mostly unrelated, and that it&rsquo;s possible
(and fun!) to be inspired to learn something.</p>
<p>When Covid caused the schools to close, it took about two weeks to detox
again&mdash;much faster than the first time.</p>
<p>It&rsquo;s important to give the student near-complete control over what they&rsquo;re learning.
We told him he could do anything as long as he was learning. (Not &ldquo;as long as it&rsquo;s
educational&rdquo; &mdash; avoid education!) He could have cheated and said that Minecraft
was learning (and in many ways I would have agreed!), but he took it more
seriously and pursued interests that weren&rsquo;t about playing games. (He did
end up spending quite a bit of time learning how to program them.)</p>
<p>If you decide to homeschool, the most common question you&rsquo;ll get from friends
is, &ldquo;What curriculum are you going to follow?&rdquo; As soon as you use the word
&ldquo;curriculum&rdquo;, you&rsquo;ve already lost. You&rsquo;re doing education, not learning, because
the student isn&rsquo;t pulling information they&rsquo;re excited about, they&rsquo;re having
your curriculum pushed on them.</p>
<p>When we&rsquo;ve described this process to friends, some have told us that it would
never work for their children. Their children would never adapt to learning.
They may be right, but they certainly won&rsquo;t know until they try. You can&rsquo;t
guess, even knowing your own kid, what will happen when they&rsquo;re free (and
encouraged) to learn. No one does &mdash; it&rsquo;s probably not happened since
preschool. I suspect these same parents would never stand for a mostly hands-off
approach anyway. They&rsquo;d probably succumb to picking and enforcing a curriculum,
dooming the whole experiment to failure from the start. We already know
education doesn&rsquo;t work, there&rsquo;s no point in trying it some more!</p>
<p>Freshman year turned out mostly like we expected: No learning happened (except
between classes when Milo programmed his TI-84 graphing calculator to make
games), and Jen and I felt awful about it. Every week we offered to take him
home again, and every week he told us that the social interactions at lunch
made it all worthwhile. It was killing us, though, that the years of his life
most amenable to learning were the years where the least learning was
happening.</p>
<p>School was still remote for Sophomore year because of Covid, and the teachers
were hopelessly unable to get any teaching done over Zoom. Six weeks into it
he asked to be pulled out. We gave him various choices, and he opted for
an online high school. The high school doesn&rsquo;t ask much of him, and he spends
much of his day playing and writing video games.</p>
<p>So, are we &ldquo;unschooling&rdquo; him if we&rsquo;re sending him to an online high school?
&ldquo;Schooling&rdquo; is forcing the child to go to a school, &ldquo;homeschooling&rdquo; is forcing
them to be educated at home, but &ldquo;unschooling&rdquo; is <em>not</em> forcing them to not be
educated. Unschooling means not forcing them at all &mdash; giving them the choice.
If they want to write video games, they can. If they want to go to an online
high school, they can. And if they want to return to their local public high
school because their lunch group is fun, they can.</p>
<p class="cover-credit">(Cover image credit: Midjourney, &ldquo;Impressionist painting of a teenager building
a robot in their bedroom.&rdquo;)</p>]]></description>
    </item>

    <item>
        <title><![CDATA[Static Type Annotation vs. The Entire World of Contemporary Web Development]]></title>
        <link>https://www.teamten.com/lawrence/writings/static-typing.html</link>
        <author>lk@teamten.com (Lawrence Kesteloot)</author>
        <guid isPermaLink="true">https://www.teamten.com/lawrence/writings/static-typing.html</guid>
        <pubDate>Fri, 17 Jan 2020 08:00:00 -0000</pubDate>
        <description><![CDATA[<p>This is a guest post, written by my friend Dan Collens in 2011.</p>
<p>There are two references below to “short beards”. Pictures of Dennis Ritchie
and Ken Thompson usually show them with a long beard. These programmers
understood software from top to bottom and wrote software in a fundamentally
different way than most of today’s web &amp; mobile app programmers (whom we
derisively refer to as “short beards”). Long beards are often the older and
more experienced programmers, but there are plenty of young long beards, too.</p>
<hr />
<p>People often ask me why I prefer Java to PHP.</p>
<p>It’s not that I prefer Java to PHP. It’s that PHP belongs to a class of
languages I view as thoroughly unsuitable for large projects, while Java
belongs to a class of languages I do not view as such.</p>
<p>The primary objection I have to PHP (and other languages which lack static type
annotations permitting a rigorous static analysis pass at compile-time,
including Python, Ruby, Perl, etc.) is that I do not believe such languages are
effective for software projects whose scope extends non-trivially in time,
quantity of code, and number of people. Anyone can reasonably convince
themselves of the correctness of a page or two of carefully-written code,
annotated with static types or not. But once you have thousands of pages of
code, written over a period of years, by people who don’t even work on the
project anymore, it is enormously hard to reason successfully about the code.</p>
<p>Static type annotations help you here because they permit automated
verification of things such as:</p>
<ul>
<li>does this variable have a method of this name at this point in the program?</li>
<li>does this method take exactly this many parameters?</li>
<li>does this method take a parameter of this type at this position in its argument list?</li>
<li>and dozens of similar questions…</li>
</ul>
<p>Furthermore, static type annotations serve as a form of explicit (human- and
machine-readable, and compile-time checked) documentation for the code. They
are far more effective and expressive than comments (which eventually become
inscrutable or false after enough time passes and enough changes accumulate to
the code), or unit tests (which are hopeless for reasons I will get to
shortly), or external documentation (which quickly diverges from the reality of
the code under the competitive pressure to add features). They force the
programmer to write down his assumptions and expectations explicitly, so that
other programmers can read them, and so that the compiler can check and enforce
them.</p>
<p>For a few quick examples, think about what happens in a language that lacks
static type annotations if you want to rename a method. You need to find all
the call sites to that method. If you miss one, you’ve introduced a bug that
won’t be found until it actually breaks a test case, is caught in QA, or makes
it out to the field. In a language with static type annotations, you simply
recompile, and the compiler will tell you where you missed (or, in most Java
IDEs, you’ll get a real-time report of the remaining places you haven’t fixed,
or better still, you use the IDE’s automated refactoring command to rename all
the references to the method as well as its declaration, all rigorously
correctly due to the type annotations). You may think this is a trivial matter,
but it’s not. To find these cases yourself, you have to search the source tree.
You’d better not miss any files (what about generated files, or files that
someone else is working on, and checks in after your rename, still referring to
the old name). And don’t forget to send out an email to the team, because all
your team members need to know not to call the old method name anymore in new
code, because it won’t get caught by the compiler if they do.</p>
<p>Even if you do find all the files and all the references, some may not actually
be referring to the method you renamed. For example, if you have two kinds of
object in your system that both have a <code>foo()</code> method, but you’re only renaming
the <code>foo()</code> method in one of those two objects, then you need to be careful to
find only the <code>foo()</code> calls that are operating on the objects of the correct
variety. Worse yet, you may have written some code that ambiguously accepts
either kind of object, so now you can’t rename the <code>foo()</code> call at those sites,
because the method you need to call now depends on the runtime type of the
object passed in. Are you sure now that you’re always renaming the right method
calls at the right place? To do this robustly, you’d have to trace through the
entire program to convince yourself which type of objects can appear in which
contexts (essentially trying to do whole-program type inference… in your head).</p>
<p>The identical problem arises if you wish to simply change the number of
parameters that a method takes, or change the order of some of the parameters
to a method, or even just adjust the assumptions on a particular method’s
runtime type (e.g. now you expect argument 3 of this method to be an object
which has a <code>foo()</code> call, when it used to expect an object with a <code>bar()</code> call). In
each of these cases, in a large program with hundreds of thousands of lines of
code, written over a period of years, by dozens of people, most of whom are no
longer working on the project, it is a real challenge to prevent bugs from
being introduced. And there are much more subtle cases than these — I’m just
scratching the surface for a few easily-explained examples.</p>
<p>After explaining this once to a young man in his 20s who was using Python for
his web app, he said “Oh, I just assumed that you’d never rename any methods in
Python… just always add new ones”. This is, in a word, appalling. Imagine what
the code will look like over time. Basically, in such languages, you’re
building a brittle house of cards that will eventually fall in on you.</p>
<p>Now I hear the short-beards crying out, “But wait! unit tests will save us!”
This is wrong on at least two levels. First of all, a lot of what people do
when they write unit tests for software written in languages lacking static
type annotations is to write tests that effectively document the runtime type
assumptions of the packages they’re testing. In short, it’s a tedious,
error-prone way of trying to recapture the lost value of static type
annotations, but in a bumbling way in a separate place from the code itself.
There are cases where unit tests are helpful — specifically when you have no
satisfactory way to prove the correctness of the program, and the type system
is too weak to express the guarantees you want, then you can write some tests
to shore up your beliefs (and indeed, I’ve done that for my Java code from time
to time).</p>
<p>But there are very strict limits to what you can learn from passing a test
suite. Edsger Dijkstra was a famous and brilliant computer scientist (and
winner of the Turing Award), and he has this to say on the topic: “Program
testing can be used to show the presence of bugs, but never to show their
absence!” What this means is that when you write a test, and run it, and the
program fails the test, you know there is a bug that needs to be fixed. But
when the program passes the test, you have only proven an absence of bugs in an
infinitesimally tiny subset of the possible execution states of the program.</p>
<p>For a contrived example to illustrate what is meant by this remark, consider a
function <code>add(a,b)</code> which returns the sum of <code>a</code> and <code>b</code>. If you test that
<code>add(1,1)=2</code>, you know that it works for 1+1, but you know nothing of any other
cases. You’d have to test every possible set of values to be certain it worked.
But actually even then you’d be wrong, because what if <code>add()</code> uses some internal
state that can be modified over the course of running the program? For example,
let’s say it maintains an internal cache of previously-computed values (assume
for the moment that addition is very expensive on this computer). Then it
matters how many <code>add()</code> calls you do in a row, it matters what order you do them
in, it matters what other things are using heap space in the system, it matters
what other threads are calling <code>add()</code>, and so forth. For testing to rigorously
establish the correctness of a piece of code, it has to not just cover every
line of code, but every line of code must be covered in every possible program
state (the program state space is essentially the vector space of the entire
set of bits in the static data, stack variables and heap of the program, so its
size is exponential in the number of bits of data/stack/heap state). This is an
intractable computation for all but the tiniest of programs.</p>
<p>What’s needed instead are proofs of correctness. When I was Director of
Engineering at a start-up I used to tell new hires that I wanted the code,
first and foremost, to be correct. Testing was deemed neither necessary nor
sufficient. This is precisely because of the above argument, nicely summarized
by Dijkstra’s quote.</p>
<p>The first line of defence in programming is to write code that is so simple,
elegant, and clear, that you are personally certain it is correct before you
even run it. The second line of defence is static type analysis done by the
compiler (which is a form of automated theorem-proving on a formal system
defined by the static type annotations in the program). As you may know from
incompleteness results in math and computer science, no consistent formal
system can prove all true theorems, so there is an infinite class of
correctness proofs which lie outside the reach of conventional static type
analysis, but at least we know that everything inside that scope is correct
once compilation succeeds. (Some languages like Haskell, ML, and their
relatives seek to extend the type system much further to allow even more
aggressive automated correctness proofs by the compiler, with some really
beautiful results, but there are diminishing returns where getting each
successive win in proof power costs ever greater amounts of complexity in the
software’s type annotations.) Finally, one relies on testing as a third-string
approach to sanity-check a few isolated points in the program’s immense
state-space which lie outside the domain of the static type system’s
theorem-prover.</p>
<p>In short, unit tests are no substitute for static analysis, and indeed there is
no known substitute in the arsenal of the software engineer today. This is why
I am appalled that in 2011, over 40 years since Dijkstra’s pithy remarks on the
subject, we find ourselves in a whirlwind of breathless hype and excitement
over a collection of web frameworks based on languages such as PHP, Python,
Ruby, and JavaScript — all of which lack any form of static type annotations!
It’s bad enough that the browser platform (such as it is) forces us to use one
such language (JavaScript), but then to have people willingly propagate this
atrocity onto the server-side (e.g. node.js) in the name of progress is almost
more than I can bear. If it was just that though, I’d probably cope, but I
often read about these short-bearded Y Combinator startups that are “language
agnostic” only to find out that what they mean by this is that they don’t just
use one but all of the languages lacking static type annotations, and do so
more or less willy-nilly throughout their stack.</p>
<p>So as to not end on a bitter note, let me present by contrast the set of
languages with (acceptably) sound static type annotation systems, and stable,
broadly-available tools and runtimes, used widely in the field, with many
practitioners from which to hire staff: C, C++, C#, Java, and maybe Scala if
you’re feeling like a gambling man. (It looks like Go will likely join this
party soon, but it’s still too immature to use in production.) Of these
languages, only C#, Java, and Scala are also garbage-collected, and
pointer-safe (i.e. no wild or uninitialized pointers). I personally avoid
Microsoft’s products because of all the proprietary lock-in, and single-source
vendor problems, but C# is otherwise a perfectly great language. So that leaves
Java and Scala, and Java is the simpler, more conservative of the two.</p>
<p>I actually think Java is missing tons of great things, and could be vastly
improved, but trying to do so by first discarding static type analysis is pure
folly.</p>
<p>I didn’t want to muddy the waters of the above discussion, but amongst
languages in common use for web development today which lack static type
annotations, PHP is the second worst designed (ahead of only Perl). Its runtime
library is woefully inconsistent, with many conflicting naming conventions,
duplicate routines with slightly different names and subtly different
semantics, etc. The syntax choices are equally appalling, e.g. “\” as a
namespace scoping operator, etc. In short, it was designed by
<a href="http://en.wikiquote.org/wiki/Rasmus_Lerdorf">someone who (literally) hates programming</a>,
and it shows. By comparison, languages such as
Java were carefully designed by a group of thoughtful people of great
intellect, experience, and wisdom.</p>]]></description>
    </item>

    <item>
        <title><![CDATA[Acceleration]]></title>
        <link>https://www.teamten.com/lawrence/writings/acceleration.html</link>
        <author>lk@teamten.com (Lawrence Kesteloot)</author>
        <guid isPermaLink="true">https://www.teamten.com/lawrence/writings/acceleration.html</guid>
        <pubDate>Sun, 03 Nov 2019 07:00:00 -0000</pubDate>
        <description><![CDATA[<p>Paul Graham <a href="http://www.paulgraham.com/addiction.html">argues</a> that technology
can take things we like and concentrate them to make them more addictive. As
technology improves, this process will accelerate.</p>
<p>Here are two quotes from his post: &ldquo;No one doubts this process is accelerating&rdquo;
and &ldquo;the world will get more addictive in the next 40 years than it did in the
last 40&rdquo;. I want to push back on this.</p>
<p>This only looks at one force: the technological force. And that&rsquo;s clearly
increasing. But it ignores the opposing force: that making something addictive
is (probably) getting harder. The stuff that was easy to make addictive, like
opium into heroin, people figured out long ago. We&rsquo;ve done the low-hanging
fruits and now we need higher ladders.</p>
<p>More generally, exponential growth (or a positive feedback loop) on one side
of an arms race doesn&rsquo;t necessarily mean that side will win. You have to
consider the other side too.</p>
<p>A few more examples:</p>
<ul>
<li>
<p>All tools can help you make better tools. If that were the only force, tool
  quality and capability would have improved exponentially, but this ignores
  the other force: that making better tools gets harder once you&rsquo;ve made the
  obvious initial improvements.</p>
</li>
<li>
<p>It&rsquo;s said that technology will replace jobs exponentially faster. Technology
  is one force, but there&rsquo;s another: replacing jobs is getting harder. We&rsquo;ve
  replaced the easy ones. These forces balance out so that job replacement has
  been roughly linear for the last 20 years.
  (<a href="https://twitter.com/robinhanson/status/1184533592690561029">Source</a>)</p>
</li>
<li>
<p>One fear about AGI is that once an AI can improve itself, that will start an
  exponential explosion of improvements and the AI will be unimaginably smarter
  very quickly. But this ignores the other force: that making AI improvements
  will probably become exponentially more difficult.</p>
</li>
<li>
<p>Our ability to do science hasn&rsquo;t significantly improved, but it&rsquo;s getting
  harder to discover new things. The predictable outcome is that it takes many
  more scientists to make the same number of discoveries than it used to.
  (<a href="https://twitter.com/michael_nielsen/status/1063417043372859392">Source</a>)</p>
</li>
</ul>
<p>Exponential technology doesn&rsquo;t imply that we&rsquo;ll pick exponentially more apples,
if those apples are harder to get.</p>]]></description>
    </item>

    <item>
        <title><![CDATA[Competence]]></title>
        <link>https://www.teamten.com/lawrence/writings/competence.html</link>
        <author>lk@teamten.com (Lawrence Kesteloot)</author>
        <guid isPermaLink="true">https://www.teamten.com/lawrence/writings/competence.html</guid>
        <pubDate>Fri, 12 Oct 2018 07:00:00 -0000</pubDate>
        <description><![CDATA[<p>Three thoughts on competence.</p>
<p><em>I.</em></p>
<p>When someone is less skilled than you are, it&rsquo;s pretty easy to estimate just
how much better you are. But when someone&rsquo;s better than you, it&rsquo;s very
difficult to estimate how much better <em>they</em> are. If they beat you in every
chess game you play, are they twice as good? Ten times? One hundred? Those
might look the same to you.</p>
<p>Most skills can&rsquo;t even be compared so easily. How much better is another
computer programmer, manager, interior designer, or scientist? And this
also applies to knowledge and talent. Most people underestimate how much better
someone else is than they are, if only to protect their ego.</p>
<p>I think this is one of the most fundamental problems, because it causes the
opinions, recommendations, teachings, and wisdom of more-competent people
to be underappreciated. One common manifestation is non-scientists ignoring
the recommendations of scientists.</p>
<p><em>II.</em></p>
<p>You&rsquo;re a software manager with two reports. One frequently runs into problems,
sometimes delivers software late, and their code is sometimes buggy. The
second quietly delivers working software on time. There are two explanations for the
difference:</p>
<ul>
<li>They&rsquo;re working on equally-difficult problems, but the first employee is less
  competent than the second.</li>
<li>They&rsquo;re equally competent, but the first employee works on much harder
  problems than the second.</li>
</ul>
<p>You don&rsquo;t know enough about the problems or the employees to tell the
difference. Which explanation do you pick? In my experience, managers
usually pick the second, whereas the real explanation is more often
the first. This is partly because problem #1 above leads managers to
underestimate engineering skill variance, but mostly because it&rsquo;s
unpleasant to realize that you have an incompetent report.</p>
<p>In the worst case I&rsquo;ve seen, an engineer who was significantly less competent
than their peers got a bonus of several hundred thousand dollars because
management interpreted their struggles as an indication of the difficulty of
their task (and thus their contribution to the company).</p>
<p><em>III.</em></p>
<p>When an artistically talented (but unskilled) person first
makes art, they think it sucks. They
have great artistic sense but no skill to make great art.
Their skill eventually catches up to their sense,
but before that happens they may quit, believing
that they are inherently incapable of creating great art.</p>
<p>This is less of a problem for artistically untalented people,
who don&rsquo;t have the sense to know that they (initially) have
no artistic skill. So they&rsquo;re less likely to drop out.</p>
<p>You&rsquo;d therefore expect there to be a disproportionate number
of artists who have poor artistic sense.</p>
<p>And if you&rsquo;re a new artist and think you suck and are tempted
to quit, maybe you just have great artistic sense and you
should stick it out.</p>]]></description>
    </item>

    <item>
        <title><![CDATA[Those Who Study History Are Doomed To Repeat It]]></title>
        <link>https://www.teamten.com/lawrence/writings/repeating-history.html</link>
        <author>lk@teamten.com (Lawrence Kesteloot)</author>
        <guid isPermaLink="true">https://www.teamten.com/lawrence/writings/repeating-history.html</guid>
        <pubDate>Fri, 12 Oct 2018 07:00:00 -0000</pubDate>
        <description><![CDATA[<p>It&rsquo;s said that &ldquo;Those who don&rsquo;t study history are doomed to repeat it.&rdquo;
I agree. I think people who <em>do</em> study history <em>also</em> repeat it.</p>
<p>The original implies that by studying history you&rsquo;ll learn lessons you can
use when faced with a similar situation, but no two situations are <em>identical</em>,
only <em>similar</em>. There&rsquo;s always enough wiggle room for you to convince
yourself that <em>this</em> time the lesson doesn&rsquo;t apply, if the lesson is
inconvenient.</p>
<p>You think Hitler didn&rsquo;t know about Napoleon&rsquo;s foray into Russia? That Bush
didn&rsquo;t know about Russia&rsquo;s decade in Afghanistan? <em>This time it&rsquo;s different</em>,
they all said, after spending a lot of time studying history.</p>
<p>So studying history never helps, because it either advises that you
should do what you already wanted to do, or it advises the opposite and
you can talk yourself out of it.</p>]]></description>
    </item>

    <item>
        <title><![CDATA[Fox and Rabbit Products]]></title>
        <link>https://www.teamten.com/lawrence/writings/fox-and-rabbit-products.html</link>
        <author>lk@teamten.com (Lawrence Kesteloot)</author>
        <guid isPermaLink="true">https://www.teamten.com/lawrence/writings/fox-and-rabbit-products.html</guid>
        <pubDate>Fri, 05 Oct 2018 07:00:00 -0000</pubDate>
        <description><![CDATA[<p>Old question:</p>
<blockquote>
<p>Q: Why does the rabbit run faster than the fox?</p>
<p>A: Because the fox is running for his dinner, but the rabbit is running for his life.</p>
</blockquote>
<p>Some products are running for their dinner, and some are running for their lives:</p>
<ul>
<li>If Android shut down tomorrow, Google would be sad. If iOS shut down
  tomorrow, Apple would be dead.</li>
<li>GitHub used to run for its life. Now that it&rsquo;s been bought by Microsoft, it&rsquo;s
  running for its dinner.</li>
<li>Everything from Microsoft that&rsquo;s not Windows or Office is running for its dinner.</li>
<li>Everything from Google that&rsquo;s not search is running for its dinner.</li>
<li>Why did macOS and the MacBook Pro suffer in quality over the last decade?
  Because the growth of iOS meant they went from rabbit products to fox products.</li>
</ul>
<p>In general, as a customer you&rsquo;ll do better with products that are running for
their lives, for the same reason that the rabbit runs faster. Prefer AWS over
Google Cloud Platform, Spotify over Apple Music, and Slack over Hangouts.</p>]]></description>
    </item>

</channel>
</rss>
