<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>I&#39;ve got the byte on my side</title>
    <link>https://latkin.org/blog/</link>
    <description>Recent content on I&#39;ve got the byte on my side</description>
    <generator>Hugo -- gohugo.io</generator>
    <language>en-us</language>
    <lastBuildDate>Wed, 22 Aug 2018 00:00:00 +0000</lastBuildDate>
    
        <atom:link href="https://latkin.org/blog/index.xml" rel="self" type="application/rss+xml" />
    
    
    <item>
      <title>Poestmortem</title>
      <link>https://latkin.org/blog/2018/08/22/poestmortem/</link>
      <pubDate>Wed, 22 Aug 2018 00:00:00 +0000</pubDate>
      
      <guid>https://latkin.org/blog/2018/08/22/poestmortem/</guid>
      <description>&lt;p&gt;Midnight strikes, I lose the wager, woken by a screeching pager,&lt;br /&gt;
Scarlet hue means issue&amp;rsquo;s major, major OOMing on the node.&lt;br /&gt;
SSH into the victim, tail and grep per playbook&amp;rsquo;s dictum,&lt;br /&gt;
&amp;lsquo;Til revealed is cache eviction as what crumbled &amp;lsquo;neath the load.&lt;br /&gt;
Run a dump of heap and threading, start the steps for shedding load.&lt;br /&gt;
Who hath merged this wretched code?&lt;/p&gt;

&lt;p&gt;Bleary eyes see dashboards healing, weary mind&amp;rsquo;s still looping, reeling,&lt;br /&gt;
Ired at some dev who&amp;rsquo;s stealing hours from my restful mode.&lt;br /&gt;
Fueled by spiteful indignation, trace the clues to bug&amp;rsquo;s location,&lt;br /&gt;
Spot the shabby computation, dismal waster of the node.&lt;br /&gt;
Desperate now to find the root of this nocturnal episode —&lt;br /&gt;
Who hath merged this wretched code?&lt;/p&gt;

&lt;p&gt;&lt;code&gt;git blame&lt;/code&gt;&amp;rsquo;s verdict fast unspools, indictments of the cowboy fools&lt;br /&gt;
Whose feeble floats and clumsy bools charred to ash beneath the load.&lt;br /&gt;
The term&amp;rsquo;nal casts a pallid glare on bloodshot eyes that, squinting, stare&lt;br /&gt;
At guilty method now laid bare and the author who is showed.&lt;br /&gt;
A curse escapes my lips as it&amp;rsquo;s plain to whom this crash is owed —&lt;/p&gt;

&lt;p&gt;It was I who wrote the code.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Originally posted on Twitter (with more emoji)&lt;/em&gt;
&lt;blockquote class=&#34;twitter-tweet&#34;&gt;&lt;p lang=&#34;en&#34; dir=&#34;ltr&#34;&gt;🌔 A Poestmortem 📟&lt;/p&gt;&amp;mdash; Lincoln Atkinson (@LincolnAtkinson) &lt;a href=&#34;https://twitter.com/LincolnAtkinson/status/1031798219964014592?ref_src=twsrc%5Etfw&#34;&gt;August 21, 2018&lt;/a&gt;&lt;/blockquote&gt;
&lt;script async src=&#34;https://platform.twitter.com/widgets.js&#34; charset=&#34;utf-8&#34;&gt;&lt;/script&gt;
&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>When the Scala compiler doesn&#39;t help</title>
      <link>https://latkin.org/blog/2017/05/02/when-the-scala-compiler-doesnt-help/</link>
      <pubDate>Tue, 02 May 2017 00:00:00 +0000</pubDate>
      
      <guid>https://latkin.org/blog/2017/05/02/when-the-scala-compiler-doesnt-help/</guid>
      <description>&lt;p&gt;Much of Scala&amp;rsquo;s power comes from its flexibility and generality as a language. You can
mold it quite extensively to suit your particular problem domain or coding style.&lt;/p&gt;

&lt;p&gt;The downside of this is that Scala can sometimes be permissive and accommodating to a fault.
You often hear Haskell or F# users attest to a sense of &amp;ldquo;if it compiles, it works&amp;rdquo; &amp;ndash; in my experience
this is &lt;em&gt;not&lt;/em&gt; generally the case with Scala.&lt;/p&gt;

&lt;p&gt;To illustrate this point, let&amp;rsquo;s walk through a few examples, all of which are distilled
from honest-to-goodness I-swear-I&amp;rsquo;m-not-making-this-up bugs my team or I have encountered.&lt;/p&gt;

&lt;h3 id=&#34;example-1&#34;&gt;Example 1&lt;/h3&gt;

&lt;h4 id=&#34;setup&#34;&gt;Setup&lt;/h4&gt;

&lt;p&gt;The following nonsensical code compiles with no warnings, no errors:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-scala&#34;&gt;val (a, b, c) =
    if (foo) {
        &amp;quot;bar&amp;quot;
    } else { 
        Some(10)
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&#34;bug&#34;&gt;Bug&lt;/h4&gt;

&lt;p&gt;This will crash with a &lt;code&gt;MatchError&lt;/code&gt; at runtime. Always. It&amp;rsquo;s super broken. Why does
the compiler let it through?&lt;/p&gt;

&lt;p&gt;Because when an expression has multiple return branches, &lt;em&gt;Scala tries to be helpful, by
picking the first common ancestor type of all the branches as the type of the whole expression&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In this case, one branch has type &lt;code&gt;String&lt;/code&gt; and the other has type &lt;code&gt;Option[Int]&lt;/code&gt;, so the compiler
decides that what the developer really wants is for the whole &lt;code&gt;if/else&lt;/code&gt; expression to have type &lt;code&gt;Serializable&lt;/code&gt;,
since that&amp;rsquo;s the most specific type to claim both &lt;code&gt;String&lt;/code&gt; and &lt;code&gt;Option&lt;/code&gt; as descendants.&lt;/p&gt;

&lt;p&gt;And guess what, &lt;code&gt;Tuple3[A, B, C]&lt;/code&gt; is also &lt;code&gt;Serializable&lt;/code&gt;, so as far as the compiler is concerned,
the assignment of the whole mess to &lt;code&gt;(a, b, c)&lt;/code&gt; can&amp;rsquo;t be proven
invalid. So it gets through with nary a warning, destined to fail at runtime.&lt;/p&gt;

&lt;h3 id=&#34;example-2&#34;&gt;Example 2&lt;/h3&gt;

&lt;h4 id=&#34;setup-1&#34;&gt;Setup&lt;/h4&gt;

&lt;p&gt;I had dashed off some tests that more or less boiled down to something like this,
which compiled with no errors or warnings:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;quot;foobar&amp;quot;.toList == List(&#39;f&#39;,&#39;o&#39;,&#39;o&#39;,&#39;b&#39;,&#39;a,&#39;r&#39;)
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&#34;bug-1&#34;&gt;Bug&lt;/h4&gt;

&lt;p&gt;This comparison was, surprisingly, returning &lt;code&gt;false&lt;/code&gt;, and I couldn&amp;rsquo;t figure out why. Can you?&lt;/p&gt;

&lt;p&gt;With syntax highlighting, the problem is clearer:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-scala&#34;&gt;&amp;quot;foobar&amp;quot;.toList == List(&#39;f&#39;,&#39;o&#39;,&#39;o&#39;,&#39;b&#39;,&#39;a,&#39;r&#39;)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You see the character &lt;code&gt;a&lt;/code&gt; in the list? There is a typo &amp;ndash; I meant to type &lt;code&gt;&#39;a&#39;&lt;/code&gt; but I missed a
quotation mark and typed &lt;code&gt;&#39;a&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As it turns out, the syntax &lt;code&gt;&#39;blah&lt;/code&gt; is actually valid in Scala, and represents a &lt;a href=&#34;http://stackoverflow.com/q/3554362/1366219&#34;&gt;symbol literal&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now recall the &amp;ldquo;helpful&amp;rdquo; compiler behavior mentioned in Example 1. Instead of yelling at
me for putting a &lt;code&gt;Symbol&lt;/code&gt; in the middle of my &lt;code&gt;Char&lt;/code&gt; list, the compiler generalizes and assumes
what I really wanted from the start was a &lt;code&gt;List[Any]&lt;/code&gt;, as &lt;code&gt;Any&lt;/code&gt; is the first common ancestor
of &lt;code&gt;Char&lt;/code&gt; and &lt;code&gt;Symbol&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;And comparing a &lt;code&gt;List[Char]&lt;/code&gt; with a &lt;code&gt;List[Any]&lt;/code&gt; also raises no objections, because in theory
it&amp;rsquo;s not impossible for it to work.&lt;/p&gt;

&lt;h3 id=&#34;example-3&#34;&gt;Example 3&lt;/h3&gt;

&lt;h4 id=&#34;setup-2&#34;&gt;Setup&lt;/h4&gt;

&lt;p&gt;Here&amp;rsquo;s a simple method definition on a class. Works fine.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-scala&#34;&gt;class Widget {
    def doTheThing() = 
        synchronized {
            ...
        }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Somebody makes a small change - adds a log line at the start of the method.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-scala&#34;&gt;class Widget {
    def doTheThing() = 
        info(&amp;quot;Doin&#39; that sweet thing&amp;quot;)
        synchronized {
            ...
        }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Jolly good, doesn&amp;rsquo;t get much simpler than that. I think most code reviewers would glaze over it in the middle of a big PR.
The compiler (the best code reviewer) is also 100% happy with this change and raises no objections.&lt;/p&gt;

&lt;h4 id=&#34;bug-2&#34;&gt;Bug&lt;/h4&gt;

&lt;p&gt;Three of Scala&amp;rsquo;s features come into play:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Method bodies without &lt;code&gt;{  }&lt;/code&gt; brackets can only consist of a single expression&lt;/li&gt;
&lt;li&gt;Any statements or expressions in a class definition, outside of member definitions,
 become part of the primary constructor.&lt;/li&gt;
&lt;li&gt;Member definitions and primary constructor content can intermingle with no ordering restrictions.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;So the resulting code really acts like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-scala&#34;&gt;class Widget {
    // executes within Widget constructor
    synchronized {
        ...
    }

    def doTheThing() = {
        info(&amp;quot;Doin&#39; that sweet thing&amp;quot;)
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What was previously the body of the &lt;code&gt;doTheThing&lt;/code&gt; method &lt;em&gt;has been silently bumped into the body
of the primary constructor&lt;/em&gt;. Oops!&lt;/p&gt;

&lt;h3 id=&#34;example-4&#34;&gt;Example 4&lt;/h3&gt;

&lt;h4 id=&#34;setup-3&#34;&gt;Setup&lt;/h4&gt;

&lt;p&gt;Here&amp;rsquo;s another example of &amp;ldquo;I&amp;rsquo;ll just add one thing&amp;rdquo; gone awry.&lt;/p&gt;

&lt;p&gt;Quick background: Scala has a shorthand syntax &lt;code&gt;_&lt;/code&gt; to represent an anonymous argument
in a lambda function. A number of languages (Perl, Mathematica, Powershell to name a few) have a similar capability.&lt;/p&gt;

&lt;p&gt;This allows one to use the following shorthand, which is actually quite nice:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-scala&#34;&gt;val lst = List(1,2,3)

// these lines can be re-written
lst.map { i =&amp;gt; i + 1 }
lst.foreach { i =&amp;gt; println(i) }

// like this
lst.map { _ + 1 }
lst.foreach { println(_) }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;So let&amp;rsquo;s say you come across some code like this, and you want to add one little thing: a counter in the loop.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-scala&#34;&gt;val lst = List(1,2,3)

// let me just add one thing
lst.foreach { println(_) }

// yay
var j = 0
lst.foreach { j += 1; println(_) }
println(s&amp;quot;Looped $j times&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Compiler is happy, looks good right?&lt;/p&gt;

&lt;h4 id=&#34;bug-3&#34;&gt;Bug&lt;/h4&gt;

&lt;p&gt;Not so fast. This code will print the following:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;1
2
3
Looped 1 times
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Why is the counter only incremented once if we are looping over a 3-element list?&lt;/p&gt;

&lt;p&gt;Because &lt;code&gt;{ j += 1; println(_) }&lt;/code&gt; is not a lambda, it is an expression that increments &lt;code&gt;j&lt;/code&gt; then
&lt;em&gt;yields&lt;/em&gt; a lambda, one which does nothing but invoke &lt;code&gt;println&lt;/code&gt;. So the function argument passed to &lt;code&gt;foreach&lt;/code&gt; is just the lambda
that invokes &lt;code&gt;println&lt;/code&gt;, the &lt;code&gt;j += 1&lt;/code&gt; part is only executed once along the way to obtaining this argument.&lt;/p&gt;

&lt;p&gt;In very explicit pseudo-code, this is the equivalent of&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-scala&#34;&gt;var j = 0
val f = {
   j += 1
   return { i =&amp;gt; println(i) }
}
lst.foreach(f)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Note that everything would have worked fine if the shortcut syntax was avoided, because
the &amp;ldquo;full-fledged&amp;rdquo; lambda syntax &lt;em&gt;does&lt;/em&gt; capture the whole of the bracketed code into
the lambda.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-scala&#34;&gt;// works as expected
var j = 0
lst.foreach { i =&amp;gt; j += 1; println(i) }
println(s&amp;quot;Looped $j times&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;example-5&#34;&gt;Example 5&lt;/h3&gt;

&lt;h4 id=&#34;setup-4&#34;&gt;Setup&lt;/h4&gt;

&lt;p&gt;This one&amp;rsquo;s a twofer. Consider the following two test cases, executed with &lt;a href=&#34;http://www.scalatest.org/&#34;&gt;ScalaTest&lt;/a&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-scala&#34;&gt;def bar() {
  &amp;quot;bar&amp;quot;
}

// test 1
(&amp;quot;foo&amp;quot; + bar() + &amp;quot;baz&amp;quot;) should be(&amp;quot;foobarbaz&amp;quot;)

// test 2
&amp;quot;short string&amp;quot; should be
    (&amp;quot;unequal long string that was moved to its own line because it&#39;s long&amp;quot;)
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;For those not familiar with ScalaTest, using &lt;code&gt;should be&lt;/code&gt; matchers just means &amp;ldquo;LHS should be
equal to RHS, fail if not.&amp;rdquo; So given the code above I would think test 1 would pass and test 2 would
fail.&lt;/p&gt;

&lt;h4 id=&#34;bug-4&#34;&gt;Bug&lt;/h4&gt;

&lt;p&gt;If you compile and run this, you will find that exactly the opposite happens: test 1 fails while test 2 passes.&lt;/p&gt;

&lt;p&gt;The cause of both unexpected results is the same &amp;ndash; stray expressions in statement position.&lt;/p&gt;

&lt;p&gt;In test 1, &lt;code&gt;bar()&lt;/code&gt; actually returns &lt;code&gt;Unit&lt;/code&gt;, not &lt;code&gt;String&lt;/code&gt; as you might assume from quick inspection. When you declare a Scala
method without a &lt;code&gt;=&lt;/code&gt; (i.e. &lt;code&gt;def bar() { ...&lt;/code&gt; like in the example, as opposed to &lt;code&gt;def bar() = { ...&lt;/code&gt;) that indicates to
the compiler that the method has &lt;code&gt;Unit&lt;/code&gt; return type (i.e. it&amp;rsquo;s a &amp;ldquo;void&amp;rdquo; method). So the
&lt;code&gt;&amp;quot;bar&amp;quot;&lt;/code&gt; string is simply ignored, &lt;code&gt;Unit&lt;/code&gt; is returned, and the LHS string of the test is in
fact &lt;code&gt;&amp;quot;foo()baz&amp;quot;&lt;/code&gt;. Test fails.&lt;/p&gt;

&lt;p&gt;In test 2, we see another manifestation of the same problem. Due to the implementation details
of ScalaTest and its matchers DSL, the code &lt;code&gt;&amp;quot;short string&amp;quot; should be&lt;/code&gt; actually represents a complete expression,
whose type is some kind of curried lambda function that expects a RHS value. Nonetheless, it&amp;rsquo;s
a complete expression in statement position, so its value just gets thrown away. Similarly, &lt;code&gt;(&amp;quot;unequal long string ...&amp;quot;)&lt;/code&gt; is a
complete, valid string expression, which also gets ignored. Thus this &amp;ldquo;test&amp;rdquo; is really just
two expressions that do nothing, and that&amp;rsquo;s considered a &amp;ldquo;pass.&amp;rdquo; (Also worth noting that
sometimes Scala expressions &lt;em&gt;can&lt;/em&gt; flow across line breaks, so it&amp;rsquo;s not too unreasonable to see this
during a review and assume it works)&lt;/p&gt;

&lt;p&gt;To be fair &amp;ndash; in this example, both the &lt;code&gt;bar&lt;/code&gt; method and the first line of test 2
trigger warnings from the compiler. It&amp;rsquo;s certainly good
that warnings are issued, but I&amp;rsquo;ll explain why that&amp;rsquo;s not enough in the next section.&lt;/p&gt;

&lt;h3 id=&#34;root-causes&#34;&gt;Root causes&lt;/h3&gt;

&lt;p&gt;I see 3 basic themes in these examples, each representing an aspect of Scala I don&amp;rsquo;t
personally care for.&lt;/p&gt;

&lt;h4 id=&#34;the-type-system-feels-very-loose&#34;&gt;The type system feels very loose&lt;/h4&gt;

&lt;p&gt;Due to the kind of automatic generalization
demonstrated above, I never feel fully confident that the compiler has my back. I&amp;rsquo;m always wondering
what I screwed up, type-wise, that the compiler isn&amp;rsquo;t telling me about. Call me old-fashioned,
but isn&amp;rsquo;t type safety supposed to be one of a compiler&amp;rsquo;s strong suits?&lt;/p&gt;

&lt;p&gt;I readily acknowledge that some of the more powerful type system capabilities Scala offers hinge on
this behavior, and that some devs fully rely on it for more advanced usages. I just personally prefer
the safety of something stricter.&lt;/p&gt;

&lt;h4 id=&#34;too-much-syntax-is-optional&#34;&gt;Too much syntax is optional&lt;/h4&gt;

&lt;p&gt;&lt;img src=&#34;https://latkin.org/blog/media/optional-oprah.jpg&#34; alt=&#34;Everything is optional&#34; /&gt;&lt;/p&gt;

&lt;p&gt;On the one hand, Scala&amp;rsquo;s syntax is &amp;ldquo;dynamic&amp;rdquo; and &amp;ldquo;flexible.&amp;rdquo; Scala is great for crafting DSLs,
and it accommodates a wide range of coding styles.&lt;/p&gt;

&lt;p&gt;That sounds nice in theory, but I&amp;rsquo;ve found that in practice it leads to headaches.
In a team setting, everybody ends up writing their own personal brand of Scala code, and it takes
constant policing to maintain a uniform style. With so much variation in syntax, code reviews
become more difficult since the visual patterns you are accustomed to from your own syntactic style
don&amp;rsquo;t neccessarily carry over to what you&amp;rsquo;re reviewing. And the rules are such that mistakes don&amp;rsquo;t
always result in errors - they might just shift you into another supported form.&lt;/p&gt;

&lt;p&gt;Example 3 would have been prevented if methods were simply required to have &lt;code&gt;{ }&lt;/code&gt;, or
if primary constructor content was required to come before method definitions.&lt;/p&gt;

&lt;p&gt;Example 4 would have been prevented if there was a single syntax for lambda functions, or if
the rules for &lt;code&gt;_&lt;/code&gt; , &lt;code&gt;{ }&lt;/code&gt;, and &lt;code&gt;;&lt;/code&gt; weren&amp;rsquo;t so subtle and overloaded.&lt;/p&gt;

&lt;p&gt;The first part of Example 5 would have been easier to catch if return type annotations
and/or the &lt;code&gt;=&lt;/code&gt; in method definitions were required.&lt;/p&gt;

&lt;p&gt;The second part of Example 5 would have been prevented if methods required &lt;code&gt;( )&lt;/code&gt; around
their arguments, or if ScalaTest wasn&amp;rsquo;t inviting people to use a magical DSL that nobody
can actually reason about.&lt;/p&gt;

&lt;h4 id=&#34;there-is-no-scoped-nowarn-pragma&#34;&gt;There is no scoped &amp;ldquo;nowarn&amp;rdquo; pragma&lt;/h4&gt;

&lt;p&gt;Like most languages, Scala has a &amp;ldquo;fatal warnings&amp;rdquo; flag which will promote
warnings into errors. But it doesn&amp;rsquo;t have any way to suppress individual warnings.&lt;/p&gt;

&lt;p&gt;The result is an &amp;ldquo;abstinence only&amp;rdquo; kind of situation &amp;ndash; you either have to commit
to never introducing a single warning of any kind, or else you can&amp;rsquo;t benefit from fatal
warnings at all.&lt;/p&gt;

&lt;p&gt;Here in the real world, it&amp;rsquo;s to be expected that a big project will pick up a warning here,
a deprecation there. These useful warnings that indeed should be fixed,
but for whatever reason the team decides they can&amp;rsquo;t or won&amp;rsquo;t be fixed yet.&lt;/p&gt;

&lt;p&gt;Ideally one could suppress those &lt;em&gt;particular&lt;/em&gt; issues while maintaining the protection
that fatal warnings provide against &lt;em&gt;new&lt;/em&gt; problems. Instead, we are left with a situation
where the build log is already sullied with a bunch of (known) warnings, and nobody notices
when new ones (e.g. Example 5) are introduced.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong&gt;[Update]&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Interesting discussion on &lt;a href=&#34;https://www.reddit.com/r/programming/comments/690fpx/when_the_scala_compiler_doesnt_help/&#34;&gt;reddit&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;There are a number of comments along the lines of &amp;ldquo;just don&amp;rsquo;t rely on type inference,&amp;rdquo;
&amp;ldquo;just use a linter,&amp;rdquo; &amp;ldquo;nobody uses that syntax anyway,&amp;rdquo; etc. I fully agree! We are indeed looking to
implement these kind of things in our CI system and style guide, and I expect those efforts to help.&lt;/p&gt;

&lt;p&gt;These comments are making my broader point for me, though &amp;ndash; you get a remarkably
flexible and powerful language in return, but &lt;em&gt;using Scala safely and confidently means
avoiding flagship language features, opting in to experimental compilation flags,
and maintaining a small constellation of 3rd-party plugins.&lt;/em&gt;&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>1Poshword - PowerShell client for 1Password</title>
      <link>https://latkin.org/blog/2016/09/12/1poshword-powershell-client-for-1password/</link>
      <pubDate>Mon, 12 Sep 2016 00:00:00 +0000</pubDate>
      
      <guid>https://latkin.org/blog/2016/09/12/1poshword-powershell-client-for-1password/</guid>
      <description>&lt;p&gt;I&amp;rsquo;m happy to publicize a little project I&amp;rsquo;ve been working on recently: &lt;em&gt;1Poshword&lt;/em&gt;, a
PowerShell client for the &lt;a href=&#34;https://1password.com/&#34;&gt;1Password&lt;/a&gt; password manager. Code
is available at &lt;a href=&#34;https://github.com/latkin/1poshword&#34;&gt;https://github.com/latkin/1poshword&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;You can read the full details in the project README, but I&amp;rsquo;ve included the demo screencast
and basic bullets below.&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://raw.githubusercontent.com/latkin/1poshword/master/demo.gif&#34; alt=&#34;demo&#34; /&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Cross-platform (Windows/OSX/Linux, PowerShell v3.0+)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;agilekeychain&lt;/code&gt; and &lt;code&gt;opvault&lt;/code&gt; support&lt;/li&gt;
&lt;li&gt;Login, Password, Secure Note, and Generic Account decryption&lt;/li&gt;
&lt;li&gt;Metadata for all entries&lt;/li&gt;
&lt;li&gt;Tab completion (&lt;code&gt;agilekeychain&lt;/code&gt; only)&lt;/li&gt;
&lt;li&gt;Output formats

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;PSCredential&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SecureString&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Plaintext&lt;/li&gt;
&lt;li&gt;Clipboard&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Complete &lt;code&gt;Get-Help&lt;/code&gt; documentation&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Try it out and let me know what you think!&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Better TeX math typesetting in Hugo</title>
      <link>https://latkin.org/blog/2016/08/07/better-tex-math-typesetting-in-hugo/</link>
      <pubDate>Sun, 07 Aug 2016 00:00:00 +0000</pubDate>
      
      <guid>https://latkin.org/blog/2016/08/07/better-tex-math-typesetting-in-hugo/</guid>
      <description>&lt;p&gt;There is a &lt;a href=&#34;https://gohugo.io/tutorials/mathjax/&#34;&gt;page in the Hugo documentation&lt;/a&gt;
that describes how to use &lt;a href=&#34;https://www.mathjax.org/&#34;&gt;MathJax&lt;/a&gt; to embed nicely-typeset mathematics in one&amp;rsquo;s
Hugo-generated site.&lt;/p&gt;

&lt;p&gt;For my own site, I took this as a starting point and made a few improvements. Here&amp;rsquo;s
how I do the math typesetting in this blog.&lt;/p&gt;

&lt;h3 id=&#34;authoring&#34;&gt;Authoring&lt;/h3&gt;

&lt;p&gt;I author my posts in Markdown, where the bulk of the content is plain text. When I
want to include specially-typeset mathematical expressions, I use a custom
&lt;a href=&#34;https://gohugo.io/extras/shortcodes/&#34;&gt;shortcode&lt;/a&gt; to convert &lt;a href=&#34;https://en.wikipedia.org/wiki/TeX&#34;&gt;TeX&lt;/a&gt;-style equation definition
into a snippet of HTML that looks nice when rendered in the browser.&lt;/p&gt;

&lt;p&gt;So when I author a post, I&amp;rsquo;ll write something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-text&#34;&gt;Here&#39;s sum inline math: {{&amp;lt; tex &amp;quot;\sum_{n=1}^{\infty} 2^{-n} = 1&amp;quot; &amp;gt;}}.

Display mode math looks like
    {{&amp;lt; tex display=&amp;quot;\int \frac{1}{x} dx = \ln |x|&amp;quot; &amp;gt;}}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Hugo will process this, apply my shortcode, and generate HTML that ultimately renders like this:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Here&amp;rsquo;s sum inline math: 
&lt;img style=&#34;display:inline;vertical-align:middle;&#34; src=&#34;https://latex.codecogs.com/gif.latex?\inline&amp;space;%5csum_%7bn%3d1%7d%5e%7b%5cinfty%7d%202%5e%7b-n%7d%20%3d%201&#34; title=&#34;\sum_{n=1}^{\infty} 2^{-n} = 1&#34; /&gt;.&lt;/p&gt;

&lt;p&gt;Display mode math looks like
    
&lt;div style=&#34;text-align:center;&#34;&gt;
        &lt;img src=&#34;https://latex.codecogs.com/gif.latex?%5cint%20%5cfrac%7b1%7d%7bx%7d%20dx%20%3d%20%5cln%20%7cx%7c&#34; title=&#34;\int \frac{1}{x} dx = \ln |x|&#34; /&gt;
    &lt;/div&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h3 id=&#34;shortcode-and-supporting-markup&#34;&gt;Shortcode and supporting markup&lt;/h3&gt;

&lt;p&gt;Here&amp;rsquo;s the definition of the shortcode:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-html&#34;&gt;&amp;lt;!-- Hugo TeX shortcode
     usage:
         inline eqn:       {{&amp;lt; tex &amp;quot;eqn here&amp;quot; &amp;gt;}}
         display mode eqn: {{&amp;lt; tex display=&amp;quot;eqn here&amp;quot; &amp;gt;}}
--&amp;gt;
&amp;lt;span class=&amp;quot;jsonly&amp;quot;&amp;gt;
    {{ if .IsNamedParams }} &amp;lt;!-- display mode, wrap eqn with $$ $$--&amp;gt;
        $${{ .Get &amp;quot;display&amp;quot; }}$$
    {{ else }}              &amp;lt;!-- inline mode, wrap eqn with \(  \)--&amp;gt;
        \({{ .Get 0 }}\)
    {{ end }}
&amp;lt;/span&amp;gt;
&amp;lt;noscript&amp;gt;
    {{ if .IsNamedParams }} &amp;lt;!-- display mode --&amp;gt;
        &amp;lt;div style=&amp;quot;text-align:center;&amp;quot;&amp;gt;
            &amp;lt;img src=&amp;quot;https://latex.codecogs.com/gif.latex?{{ .Get &amp;quot;display&amp;quot; }}&amp;quot; title=&amp;quot;{{ .Get &amp;quot;display&amp;quot; }}&amp;quot; /&amp;gt;
        &amp;lt;/div&amp;gt;
    {{ else }}              &amp;lt;!-- inline mode --&amp;gt;
        &amp;lt;img style=&amp;quot;display:inline;vertical-align:middle;&amp;quot; src=&amp;quot;https://latex.codecogs.com/gif.latex?\inline&amp;amp;space;{{ .Get 0 }}&amp;quot; title=&amp;quot;{{ .Get 0 }}&amp;quot; /&amp;gt;
    {{ end }}
&amp;lt;/noscript&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This takes care of inserting the required content and tags for each particular
expression, but that alone isn&amp;rsquo;t enough. Some additional Javascript and CSS are
required in the header and footer of the page, as well.&lt;/p&gt;

&lt;p&gt;In my Hugo page template I conditionally include this extra markup, which will pull down
the CSS and Javascript libraries that do the real typesetting work when someone loads
the page:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-HTML&#34;&gt;&amp;lt;!-- top of page --&amp;gt;
{{ if .GetParam &amp;quot;hasMath&amp;quot;}}
  &amp;lt;link rel=&amp;quot;stylesheet&amp;quot; href=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.6.0/katex.min.css&amp;quot;&amp;gt;
  &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.6.0/katex.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
  &amp;lt;script src=&amp;quot;https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.6.0/contrib/auto-render.min.js&amp;quot;&amp;gt;&amp;lt;/script&amp;gt;
{{ end }}


&amp;lt;!-- bottom of page --&amp;gt;
{{ if .GetParam &amp;quot;hasMath&amp;quot;}}
  &amp;lt;script&amp;gt;renderMathInElement(document.body);&amp;lt;/script&amp;gt;
{{ end }}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;I simply add &lt;code&gt;hasMath: true&lt;/code&gt; to the front matter of any post that has equations,
and everything is taken care of. If a post doesn&amp;rsquo;t contain any mathematics, no
superfluous scripts or CSS are included.&lt;/p&gt;

&lt;p&gt;As you can see above, I am using &lt;a href=&#34;https://khan.github.io/KaTeX/&#34;&gt;KaTeX&lt;/a&gt;, a MathJax
competitor from Khan Academy, as my backend typesetting library. KaTeX renders noticeably
faster than MathJax, but has a more limited feature set. Given the meager sophistication
of the equations appearing in this blog, I don&amp;rsquo;t need the more exotic
features anyway, so KaTeX a pretty clear win.&lt;/p&gt;

&lt;h3 id=&#34;handling-noscript&#34;&gt;Handling noscript&lt;/h3&gt;

&lt;p&gt;I&amp;rsquo;ve also taken care to include a &lt;code&gt;&amp;lt;noscript&amp;gt;&lt;/code&gt; block for each equation, which will
activate when Javascript is disabled.&lt;/p&gt;

&lt;p&gt;In such a case, KaTeX or MathJax won&amp;rsquo;t work, so I fall back to using flat images.
Images don&amp;rsquo;t render as crisply, and won&amp;rsquo;t resize or zoom quite as well as proper
HTML + CSS, but they will do in a pinch.&lt;/p&gt;

&lt;p&gt;There are a few free cloud services available for this, which dynamically
generate math typesetting images. You just embed the equation
you want in the URL query parameters, and the server will create the image on the fly.&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;https://developers.google.com/chart/infographics/docs/formulas&#34;&gt;Google Charts&lt;/a&gt; is
one such service. I&amp;rsquo;m currently using &lt;a href=&#34;https://www.codecogs.com/latex/eqneditor.php&#34;&gt;CodeCogs&lt;/a&gt;,
as I find that its images look better than Google&amp;rsquo;s, and they support both inline and
display-mode image rendering.&lt;/p&gt;

&lt;p&gt;With Javascript disabled, the earlier example will render like this:&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;Here&amp;rsquo;s sum inline math: &lt;img style=&#34;display:inline;vertical-align:middle;&#34; src=&#34;https://latex.codecogs.com/gif.latex?\inline&amp;space;%5csum_%7bn%3d1%7d%5e%7b%5cinfty%7d%202%5e%7b-n%7d%20%3d%201&#34; title=&#34;\sum_{n=1}^{\infty} 2^{-n} = 1&#34; /&gt;.&lt;/p&gt;

&lt;p&gt;Display mode math looks like
&lt;div style=&#34;text-align:center;&#34;&gt;
    &lt;img src=&#34;https://latex.codecogs.com/gif.latex?%5cint%20%5cfrac%7b1%7d%7bx%7d%20dx%20%3d%20%5cln%20%7cx%7c&#34; title=&#34;\int \frac{1}{x} dx = \ln |x|&#34; /&gt;
&lt;/div&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;To prevent the Javascript-only equation markup from appearing &amp;ldquo;raw&amp;rdquo; next to
the images, I include a small bit of CSS in every page to hide such elements:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-HTML&#34;&gt;  &amp;lt;noscript&amp;gt;
    &amp;lt;style&amp;gt;.jsonly { display: none }&amp;lt;/style&amp;gt;
  &amp;lt;/noscript&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;rss-readers&#34;&gt;RSS readers&lt;/h3&gt;

&lt;p&gt;Some people consume my blog through an RSS reader, rather than
visiting my site directly. It would be nice if equations came through in a reasonable
way for for these people, too.&lt;/p&gt;

&lt;p&gt;Javascript is not exposed to RSS at all, so KaTeX and MathJax are out the window,
and I am limited to HTML and inline CSS for formatting. Thankfully, this is exactly
how the &lt;code&gt;noscript&lt;/code&gt; fallback operates, so most of the work is already done.&lt;/p&gt;

&lt;p&gt;After running Hugo to generate all of my site&amp;rsquo;s HTML and RSS content, I run a
post-processing script to fix up the RSS XML slightly. The script does 2 things:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Removes the &lt;code&gt;jsonly&lt;/code&gt; spans entirely, since they aren&amp;rsquo;t useful for RSS and will
be rendered in their ugly raw form.&lt;/li&gt;
&lt;li&gt;Removes the &lt;code&gt;noscript&lt;/code&gt; opening and closing tags, leaving just the inner image content. Some
RSS readers will not render content inside of &lt;code&gt;noscript&lt;/code&gt; tags, so it&amp;rsquo;s important to remove
these.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Here&amp;rsquo;s a snippet of PowerShell that does the trick:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-powershell&#34;&gt;$content = [io.file]::ReadAllText(&#39;index.xml&#39;)

# delete jsonly spans completely
$content = $content -replace &#39;&amp;amp;lt;span class=&amp;amp;#34;jsonly&amp;amp;#34;&amp;amp;gt;\s*.+?\s*&amp;amp;lt;/span&amp;amp;gt;&#39;,&#39;&#39;

# remove &amp;lt;noscript&amp;gt; tags, leaving just the inner content
$content = $content -replace &#39;&amp;amp;lt;noscript&amp;amp;gt;\s*((?:.|\s)+?)\s*&amp;amp;lt;/noscript&amp;amp;gt;&#39;, &#39;$1&#39;

[io.file]::WriteAllText(&#39;index.xml&#39;, $content)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;What&amp;rsquo;s left should look fairly decent in most RSS readers.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Curious behavior when de-duplicating a collection in PowerShell</title>
      <link>https://latkin.org/blog/2016/08/02/curious-behavior-when-de-duplicating-a-collection-in-powershell/</link>
      <pubDate>Tue, 02 Aug 2016 00:00:00 +0000</pubDate>
      
      <guid>https://latkin.org/blog/2016/08/02/curious-behavior-when-de-duplicating-a-collection-in-powershell/</guid>
      <description>&lt;p&gt;This is a bug/curiosity in PowerShell that I stumbled upon a few years ago, but never
wrote up. The behavior hasn&amp;rsquo;t changed significantly in the intervening verions, so now
I&amp;rsquo;m finally getting around to a quick blog post.&lt;/p&gt;

&lt;p&gt;Here&amp;rsquo;s a chart detailing the runtime of 4 different PowerShell approaches to de-duplicate
a collection - i.e. filter an input collection to just its unique elements. Code used
for the benchmark can be found &lt;a href=&#34;https://gist.github.com/latkin/b8c3086210fb5f1fdcdd29cb39bcea3e&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://latkin.org/blog/media/powershell_dedup_comparison_linear.png&#34; alt=&#34;Comparison of de-duplicating cmdlets, linear scale&#34; /&gt;&lt;/p&gt;

&lt;p&gt;Same chart, with log scale so it&amp;rsquo;s a little easier to distinguish the trend lines:&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://latkin.org/blog/media/powershell_dedup_comparison_log.png&#34; alt=&#34;Comparison of de-duplicating cmdlets, log scale&#34; /&gt;&lt;/p&gt;

&lt;p&gt;The solutions being compared are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;$data | select -unique&lt;/code&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://technet.microsoft.com/en-us/library/hh849895.aspx&#34;&gt;Built-in&lt;/a&gt;,
does nothing but de-duplicate the input collection.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;$data | group |% Name&lt;/code&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Composition of built-ins &lt;a href=&#34;https://technet.microsoft.com/en-us/library/hh849907.aspx&#34;&gt;&lt;code&gt;group&lt;/code&gt;&lt;/a&gt;
(which groups together duplicate items) and &lt;a href=&#34;https://technet.microsoft.com/en-us/library/hh849731.aspx&#34;&gt;&lt;code&gt;%&lt;/code&gt;&lt;/a&gt;
(to read off the key from each group)&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;$data | sort -unique&lt;/code&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&#34;https://technet.microsoft.com/en-us/library/hh849912.aspx&#34;&gt;Built-in&lt;/a&gt;,
sorts the input collection and additionally de-duplicates it.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;$data | hashunique&lt;/code&gt;&lt;/strong&gt;

&lt;ul&gt;
&lt;li&gt;Custom cmdlet using simple hashset-based approach. 12 lines,
&lt;a href=&#34;https://gist.github.com/latkin/b8c3086210fb5f1fdcdd29cb39bcea3e#file-benchmark-ps1-L7-L18&#34;&gt;available alongside benchmark code&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I was surprised to see how poorly &lt;code&gt;select -unique&lt;/code&gt; performs. It&amp;rsquo;s part of the core
PowerShell library (presumably authored by experts), implemented as compiled C# code
(not script), and its sole purpose is to solve this exact problem.&lt;/p&gt;

&lt;p&gt;So why is it the slowest option?!&lt;/p&gt;

&lt;p&gt;Specific questions I&amp;rsquo;m still wondering about -&lt;/p&gt;

&lt;h3 id=&#34;why-do-select-and-group-have-quadratic-runtime&#34;&gt;Why do &amp;ldquo;select&amp;rdquo; and &amp;ldquo;group&amp;rdquo; have quadratic runtime?&lt;/h3&gt;

&lt;p&gt;Filtering out duplicates from a collection, or grouping together equivalent items,
can be done in 
&lt;img style=&#34;display:inline;vertical-align:middle;&#34; src=&#34;https://latex.codecogs.com/gif.latex?\inline&amp;space;O%28n%29&#34; title=&#34;O(n)&#34; /&gt; time by utilizing a hash set or hash table, respectively.
The trendline above hints, and a quick &lt;a href=&#34;http://ilspy.net/&#34;&gt;ILSpy&lt;/a&gt; session confirms,
that &lt;code&gt;select&lt;/code&gt; and &lt;code&gt;group&lt;/code&gt; are instead relying on an 
&lt;img style=&#34;display:inline;vertical-align:middle;&#34; src=&#34;https://latex.codecogs.com/gif.latex?\inline&amp;space;O%28n%5e2%29&#34; title=&#34;O(n^2)&#34; /&gt; algorithm
that doesn&amp;rsquo;t use hashing at all.&lt;/p&gt;

&lt;p&gt;My best guess is that somehow PowerShell&amp;rsquo;s object and equality system preclude
efficient, reliable hashing for &lt;em&gt;all&lt;/em&gt; scriptable objects, so they decide not to do
it for &lt;em&gt;any&lt;/em&gt; objects. Perhaps everything just relies on equality.&lt;/p&gt;

&lt;p&gt;But this doesn&amp;rsquo;t quite hold up. Here&amp;rsquo;s a simple example where two items are considered
&lt;em&gt;non-unique&lt;/em&gt; by &lt;code&gt;select&lt;/code&gt;, &lt;code&gt;sort&lt;/code&gt;, and &lt;code&gt;group&lt;/code&gt; yet aren&amp;rsquo;t considered &lt;em&gt;equal&lt;/em&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;PS&amp;gt; &#39;dude&#39; &amp;gt; sweet.txt
PS&amp;gt; $f1 = dir .\sweet.txt
PS&amp;gt; $f2 = dir .\sweet.txt
PS&amp;gt; ($f1, $f2 | select -Unique).Length
1
PS&amp;gt; ($f1, $f2 | sort -Unique).Length
1
PS&amp;gt; ($f1, $f2 | group).Length
1
PS&amp;gt; $f1 -eq $f2
False
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Practically speaking, when I&amp;rsquo;m at the terminal and need to de-duplicate a
collection, 99% of the time it&amp;rsquo;s just going to be strings or numbers. It&amp;rsquo;s a shame
this core use case is left completely unoptimized. Going forward I will just keep
&lt;code&gt;hashunique&lt;/code&gt; in my profile and use that.&lt;/p&gt;

&lt;h3 id=&#34;why-is-group-faster-than-select-unique&#34;&gt;Why is &amp;ldquo;group&amp;rdquo; faster than &amp;ldquo;select -unique&amp;rdquo;?&lt;/h3&gt;

&lt;p&gt;Setting aside asymtotic complexity, how can &lt;code&gt;select -unique&lt;/code&gt; be slower by some constant
factor than piping together &lt;code&gt;group |% Name&lt;/code&gt;? The latter has to carry around a ton of extra
data, and also incurs the cost of an additional pipeline command. This makes
no sense to me.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Git for Windows accidentally creates NTFS alternate data streams</title>
      <link>https://latkin.org/blog/2016/07/20/git-for-windows-accidentally-creates-ntfs-alternate-data-streams/</link>
      <pubDate>Wed, 20 Jul 2016 00:00:00 +0000</pubDate>
      
      <guid>https://latkin.org/blog/2016/07/20/git-for-windows-accidentally-creates-ntfs-alternate-data-streams/</guid>
      <description>&lt;p&gt;As part of the small minority of devs at my company who primarily run Windows,
I&amp;rsquo;m accustomed to working around occasional Unix-specific behaviors in our build
and deployment systems. Cygwin makes most stuff just work, I can fix simple
incompatibilities myself, and as a last resort I can always boot into OSX for a
while if needed.&lt;/p&gt;

&lt;p&gt;One oddity that took me quite some time to diagnose, though, was Git&amp;rsquo;s strange
behavior when dealing with files in our repo whose names contained a colon.&lt;/p&gt;

&lt;h3 id=&#34;what-happens-when-you-sync-a-file-with-a-colon-in-the-filename&#34;&gt;What happens when you sync a file with a colon in the filename?&lt;/h3&gt;

&lt;p&gt;Besides the inital drive prefix (e.g. &lt;code&gt;C:\&lt;/code&gt;), Windows does not permit the colon
character in file or directory paths. Unix has no such restriction. So what
happens if a Git repo of Unix origin contains a file with a colon in the name,
and that repo is cloned on a Windows machine?&lt;/p&gt;

&lt;p&gt;I&amp;rsquo;ve created a sample &lt;a href=&#34;https://github.com/latkin/filetest&#34;&gt;repo&lt;/a&gt; that contains
a single file &lt;code&gt;foo:bar&lt;/code&gt; with the content &lt;code&gt;hello&lt;/code&gt;. Cloning the repo with a
default installation of &lt;a href=&#34;https://git-for-windows.github.io/&#34;&gt;Git for Windows&lt;/a&gt;
you get no errors or warnings:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;C:\src
&amp;gt; git clone https://github.com/latkin/filetest.git
Cloning into &#39;filetest&#39;...
remote: Counting objects: 3, done.
remote: Total 3 (delta 0), reused 0 (delta 0), pack-reused 3
Unpacking objects: 100% (3/3), done.
Checking connectivity... done.
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Instead of a file named &lt;code&gt;foo:bar&lt;/code&gt;, though, you get a file named &lt;code&gt;foo&lt;/code&gt;, with
nothing in it:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;C:\src
&amp;gt; cd .\filetest\
C:\src\filetest
&amp;gt; dir -force

    Directory: C:\src\filetest

Mode                LastWriteTime         Length Name
----                -------------         ------ ----
d--h--        7/17/2016   5:53 PM                .git
-a----        7/17/2016   5:47 PM              0 foo
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That&amp;rsquo;s kind of strange on its own, but even more peculiar is that Git has a
different opinion of what things look like:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;C:\src\filetest
&amp;gt; git status
On branch master
Your branch is up-to-date with &#39;origin/master&#39;.
Untracked files:
  (use &amp;quot;git add &amp;lt;file&amp;gt;...&amp;quot; to include in what will be committed)

        foo

nothing added to commit but untracked files present (use &amp;quot;git add&amp;quot; to track)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Git notices the untracked file &lt;code&gt;foo&lt;/code&gt;, but seems to think &lt;code&gt;foo:bar&lt;/code&gt; is both
present and contains the expected content. How strange&amp;hellip;&lt;/p&gt;

&lt;p&gt;Confusing matters further is that when you enable the Git config option
&lt;a href=&#34;https://github.com/msysgit/msysgit/wiki/Diagnosing-why-Git-is-so-slow#enable-the-filesystem-cache&#34;&gt;&lt;code&gt;core.fscache&lt;/code&gt;&lt;/a&gt;
(which is enabled by default in version 2.8.2 and later), the working set
suddenly changes - now &lt;code&gt;foo:bar&lt;/code&gt; is reported as missing:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;C:\src\filetest
&amp;gt; git config core.fscache true
C:\src\filetest
&amp;gt; git status
On branch master
Your branch is up-to-date with &#39;origin/master&#39;.
Changes not staged for commit:
  (use &amp;quot;git add/rm &amp;lt;file&amp;gt;...&amp;quot; to update what will be committed)
  (use &amp;quot;git checkout -- &amp;lt;file&amp;gt;...&amp;quot; to discard changes in working directory)

        deleted:    foo:bar

Untracked files:
  (use &amp;quot;git add &amp;lt;file&amp;gt;...&amp;quot; to include in what will be committed)

        foo

no changes added to commit (use &amp;quot;git add&amp;quot; and/or &amp;quot;git commit -a&amp;quot;)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That&amp;rsquo;s what we originally would have expected given that only the &lt;code&gt;foo&lt;/code&gt; file
was created when we cloned the repository, but why is it different from
&lt;code&gt;core.fscache = false&lt;/code&gt;? And why was this empty file &lt;code&gt;foo&lt;/code&gt; created in the first
place?&lt;/p&gt;

&lt;h3 id=&#34;alternate-data-streams&#34;&gt;Alternate data streams&lt;/h3&gt;

&lt;p&gt;The root cause of all this is a relatively obscure NTFS feature called
&lt;em&gt;alternate data streams&lt;/em&gt;. Some good summary links &lt;a href=&#34;https://blogs.technet.microsoft.com/askcore/2013/03/24/alternate-data-streams-in-ntfs/&#34;&gt;here&lt;/a&gt;
and &lt;a href=&#34;https://en.wikipedia.org/wiki/NTFS#Alternate_data_streams_.28ADS.29&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Briefly, files in NTFS are not simple buckets of data, but rather a collection
of 1 or more data &lt;em&gt;streams&lt;/em&gt;. What we normally think of as a file&amp;rsquo;s contents is
really the contents of the primary, unnamed stream. One can also create and
add data to alternate, named streams. These streams are directly addressable by
appending &lt;code&gt;:streamname&lt;/code&gt; to the normal file path. e.g. the stream &lt;code&gt;MyStream&lt;/code&gt; in
file &lt;code&gt;qwerty.txt&lt;/code&gt; can be accessed via the path &lt;code&gt;qwerty.txt:MyStream&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So although &lt;code&gt;foo:bar&lt;/code&gt; is not a legal Windows &lt;em&gt;file name&lt;/em&gt;, Windows file APIs are
nonetheless happy to accept it for read and write operations because it is
indeed legal as a &lt;em&gt;path to something in the filesystem&lt;/em&gt;, namely the &lt;code&gt;bar&lt;/code&gt;
alternate stream of the file &lt;code&gt;foo&lt;/code&gt;.&lt;/p&gt;

&lt;h3 id=&#34;what-git-does&#34;&gt;What Git does&lt;/h3&gt;

&lt;p&gt;Once you are aware of alternate data streams, Git&amp;rsquo;s behavior starts to make
sense.&lt;/p&gt;

&lt;p&gt;When cloning, Git naively blasts content into the path &lt;code&gt;foo:bar&lt;/code&gt;. That is
a 100% legal path, so no errors are raised by the OS. The result is a file &lt;code&gt;foo&lt;/code&gt;
with no content in the primary data stream (hence reported as length 0), but 6
bytes in an alternate stream &lt;code&gt;bar&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;C:\src\filetest
&amp;gt; Get-Item .\foo -Stream * | ft Stream,Length

Stream Length
------ ------
:$DATA      0
bar         6

C:\src\filetest
&amp;gt; cat .\foo:bar
hello
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;When checking the status of the working set, Git uses different algorithms
depending on whether &lt;code&gt;core.fscache&lt;/code&gt; is enabled.&lt;/p&gt;

&lt;p&gt;When &lt;code&gt;core.fscache&lt;/code&gt; is &lt;strong&gt;false&lt;/strong&gt;, file metadata checks are done one at a time,
ultimately &lt;a href=&#34;https://github.com/git-for-windows/git/blob/30d5fdc12c4380219f619872afe3bd6a2e3fc2cf/compat/mingw.c#L703-L767&#34;&gt;invoking GetFileAttributesEx&lt;/a&gt;
for each path. Git has no clue it&amp;rsquo;s even dealing with an alternate stream,
because these file APIs behave exactly the same as they would with a normal file
path. Does &lt;code&gt;foo:bar&lt;/code&gt; exist? Yep! Does the last modified time on &lt;code&gt;foo:bar&lt;/code&gt; match
what Git expects? Yep! Is the content of &lt;code&gt;foo:bar&lt;/code&gt; what Git expects? Yep! Well
alright, that file must be unchanged.&lt;/p&gt;

&lt;p&gt;When &lt;code&gt;core.fscache&lt;/code&gt; is &lt;strong&gt;true&lt;/strong&gt;, Git &lt;a href=&#34;https://github.com/git-for-windows/git/blob/30d5fdc12c4380219f619872afe3bd6a2e3fc2cf/compat/win32/fscache.c#L166-L219&#34;&gt;pre-caches file metadata per directory&lt;/a&gt;,
then &lt;a href=&#34;https://github.com/git-for-windows/git/blob/30d5fdc12c4380219f619872afe3bd6a2e3fc2cf/compat/win32/fscache.c#L402-L442&#34;&gt;reads it from the cache&lt;/a&gt;
instead of invoking file APIs directly. This leads to a different view of the
world - when enumerating files in the containing directory, Windows only
mentions &lt;code&gt;foo&lt;/code&gt;, since that&amp;rsquo;s the only file present. Thus the cache, when asked
for the metadata of &lt;code&gt;foo:bar&lt;/code&gt;, believes this file does &lt;em&gt;not&lt;/em&gt; exist.&lt;/p&gt;

&lt;h3 id=&#34;conclusion&#34;&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;In my opinion, this is all rather silly and should never have been allowed to
happen in the first place. Git should simply detect the bogus filename, issue
an error, and never even attempt to write the file to disk. This is how other
valid-in-Unix-but-invalid-in-Windows filenames are handled already (e.g. a file
named &lt;code&gt;\Windows\System32\crypt32.dll&lt;/code&gt; will be blocked). Such files would then
(correctly) be reported as missing from the working set, regardless of
&lt;code&gt;core.fscache&lt;/code&gt; setting.&lt;/p&gt;

&lt;p&gt;I opened a &lt;a href=&#34;https://github.com/git-for-windows/git/issues/679&#34;&gt;bug&lt;/a&gt; against Git
for Windows to track this issue, and provided a &lt;a href=&#34;https://github.com/git-for-windows/git/pull/686&#34;&gt;PR&lt;/a&gt;
with a fix, but these have sat dormant with no feedback for the past 4 months.
This week I&amp;rsquo;m making noise again on the PR, hopefully that will spur some action
by the maintainers.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Moving to a static site generator</title>
      <link>https://latkin.org/blog/2016/06/13/moving-to-a-static-site-generator/</link>
      <pubDate>Mon, 13 Jun 2016 00:00:00 +0000</pubDate>
      
      <guid>https://latkin.org/blog/2016/06/13/moving-to-a-static-site-generator/</guid>
      <description>&lt;p&gt;This blog started on wordpress.com back in February of 2012, then in November 2013
I moved it to a hosted WordPress.org site here at &lt;a href=&#34;http://latkin.org/blog&#34;&gt;latkin.org&lt;/a&gt;.
WordPress is quite nice, but it seemed like it was a bit heavyweight given my
very basic needs. I&amp;rsquo;ve wanted to slim down the site and get more hands-on
for a while, now.&lt;/p&gt;

&lt;p&gt;Over the past few weeks, I&amp;rsquo;ve been migrating the entire blog to the &lt;a href=&#34;https://gohugo.io/&#34;&gt;Hugo&lt;/a&gt;
static site generator. I&amp;rsquo;m pleased to announce that the migration is complete!&lt;/p&gt;

&lt;h3 id=&#34;why-hugo&#34;&gt;Why Hugo?&lt;/h3&gt;

&lt;p&gt;No particular reason. I happened to be reading a blog with a &amp;ldquo;created by Hugo&amp;rdquo; footer
one evening when inspiration struck. Skimming through comparisons of Jekyll, Hugo,
Octopress, Middleman, etc left me with the opinion that they are all capable tools,
especially for a simple personal blog.&lt;/p&gt;

&lt;p&gt;Some nice aspects of Hugo that I have noticed, though, include simplicity, performance, and ease
of use. The entire Hugo platform is just 1 command-line executable, which works great
out of the box with 0 config. It&amp;rsquo;s written in Go so overall it feels pretty snappy.&lt;/p&gt;

&lt;h3 id=&#34;leaner-strike-meaner-strike-kinder&#34;&gt;Leaner, &lt;strike&gt;meaner&lt;/strike&gt; kinder&lt;/h3&gt;

&lt;p&gt;I wanted the site to be much lighter-weight, simple, and portable. Not quite as
barebones as, say, &lt;a href=&#34;http://danluu.com/&#34;&gt;http://danluu.com/&lt;/a&gt;, but something closer to that.&lt;/p&gt;

&lt;p&gt;Where I&amp;rsquo;m at now:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Statically-generated pages&lt;/li&gt;
&lt;li&gt;No custom fonts&lt;/li&gt;
&lt;li&gt;Simple, tame CSS&lt;/li&gt;
&lt;li&gt;Very minimal usage of javascript&lt;/li&gt;
&lt;li&gt;Switched from &lt;a href=&#34;https://www.mathjax.org/&#34;&gt;MathJax&lt;/a&gt; to &lt;a href=&#34;https://github.com/Khan/KaTeX&#34;&gt;KaTeX&lt;/a&gt; for math typesetting&lt;/li&gt;
&lt;li&gt;Dropped embedded GitHub gists for code samples in favor of static HTML (no more JS)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The blog landing page weighs in at about 54KB, which is quite trim. Despite my efforts
to avoid gratuitous javascript, about 90% of that 54K is is external JS (Google
Analytics, Disqus comment counts, KaTeX).&lt;/p&gt;

&lt;p&gt;Disqus comment threads are unfortunately pretty heavyweight, making the posts themselves
chubbier than I&amp;rsquo;d like. My most recent &lt;a href=&#34;https://latkin.org/blog/2016/02/08/benchmarking-ienumerables-in-f-seq-timed/&#34;&gt;post about benchmarking &lt;code&gt;IEnumerables&lt;/code&gt;&lt;/a&gt;
is ~300KB to load, 85% of which is Disqus. That&amp;rsquo;s a real bummer, but I don&amp;rsquo;t know of any
significantly better alternatives. I do enjoy the (infrequent) comments here, so
I&amp;rsquo;d prefer to keep &lt;em&gt;some&lt;/em&gt; kind of commenting system.&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;I&amp;rsquo;ve had fun reworking the site. I am no kind of designer or web dev - certainly there is
room for improvement/optimization - but it&amp;rsquo;s been fun to learn along the way.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Benchmarking IEnumerables in F# - Seq.timed</title>
      <link>https://latkin.org/blog/2016/02/08/benchmarking-ienumerables-in-f-seq-timed/</link>
      <pubDate>Mon, 08 Feb 2016 00:00:00 +0000</pubDate>
      
      <guid>https://latkin.org/blog/2016/02/08/benchmarking-ienumerables-in-f-seq-timed/</guid>
      <description>&lt;p&gt;It&amp;rsquo;s pretty straightforward to do basic benchmarking of a single, self-contained piece of code in .NET. You just make a Stopwatch sandwich (&lt;code&gt;let sw = Stopwatch.StartNew(); &amp;lt;code goes here&amp;gt;; sw.Stop()&lt;/code&gt;), then read off the elapsed time from the Stopwatch.&lt;/p&gt;

&lt;p&gt;What about measuring the throughput of a data pipeline? In this case one is less interested in timing a single block of code from start to finish, and more interested in bulk metrics like computations/sec or milliseconds/item. Oftentimes such pipelines are persistent or very long-running, so a useful benchmark would not be a one-time measurement, but rather something that samples repeatedly.&lt;/p&gt;

&lt;p&gt;Furthermore, it&amp;rsquo;s sometimes difficult to determine where the bottleneck in a chain of computations lies. Is the root data source the culprit? Or is it perhaps an intermediate transformation that&amp;rsquo;s slow, or even the final consumer?&lt;/p&gt;

&lt;p&gt;This kind of problem came up for me recently, so I put together a timing function &lt;code&gt;Seq.timed&lt;/code&gt;. The complete code is at the bottom of the post.&lt;/p&gt;

&lt;h4 id=&#34;seq-timed&#34;&gt;Seq.timed&lt;/h4&gt;

&lt;p&gt;&lt;code&gt;val timed : blockSize:int option -&amp;gt; f:(int -&amp;gt; TimeSpan -&amp;gt; float -&amp;gt; unit) -&amp;gt; source:seq&amp;lt;&#39;t&amp;gt; -&amp;gt; seq&amp;lt;&#39;t&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;blockSize&lt;/code&gt; is the sample size - how many sequence elements should flow in between timing callbacks? Or specify None to only make a single callback when the source is exhausted.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;f&lt;/code&gt; is the timing callback - it is invoked once for every &lt;code&gt;blockSize&lt;/code&gt; items enumerated, and/or when the source sequence is exhausted. It is passed the count of items since the last callback, a &lt;code&gt;TimeSpan&lt;/code&gt; indicating how long it took for that many items to be enumerated, and a float indicating the proportion of that time spent upstream in the source sequence (as opposed to downstream in consumers of the resulting sequence).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;source&lt;/code&gt; is the input sequence.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The idea is that you can simply slip this into an existing F#-style collection-processing pipeline, or tag it on the end of any existing &lt;code&gt;seq/IEnumerable&lt;/code&gt;. The resulting sequence yields exactly the same values as the source, but also keeps track of timing each block of items as they are enumerated, invoking the provided callback for each block.&lt;/p&gt;

&lt;h4 id=&#34;examples&#34;&gt;Examples&lt;/h4&gt;

&lt;p&gt;Here&amp;rsquo;s a small example that benchmarks a toy sequence, showing measurement of overall throughput along with detection of upstream/downstream relative speed:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-fsharp&#34;&gt;open System.Threading

seq{ 1 .. 100 }
|&amp;gt; Seq.timed None Scale.s                // add timing here
|&amp;gt; Seq.map (fun i -&amp;gt; Thread.Sleep(10); i)
|&amp;gt; Seq.map (fun i -&amp;gt; Thread.Sleep(25); i)
|&amp;gt; Seq.iter (fun i -&amp;gt; Thread.Sleep(15))
// output
// 100 items       5.15s      19.43 items/s       0.05 s/item ( 0% upstream | 100% downstream)

seq{ 1 .. 100 }
|&amp;gt; Seq.map (fun i -&amp;gt; Thread.Sleep(10); i)
|&amp;gt; Seq.timed None Scale.s                // move timing to here
|&amp;gt; Seq.map (fun i -&amp;gt; Thread.Sleep(25); i)
|&amp;gt; Seq.iter (fun i -&amp;gt; Thread.Sleep(15))
// output
// 100 items       5.13s      19.51 items/s       0.05 s/item (20% upstream | 80% downstream)

seq{ 1 .. 100 }
|&amp;gt; Seq.map (fun i -&amp;gt; Thread.Sleep(10); i)
|&amp;gt; Seq.map (fun i -&amp;gt; Thread.Sleep(25); i)
|&amp;gt; Seq.timed None Scale.s                // move timing to here
|&amp;gt; Seq.iter (fun i -&amp;gt; Thread.Sleep(15))
// output
// 100 items       5.15s      19.43 items/s       0.05 s/item (70% upstream | 30% downstream)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Here&amp;rsquo;s something a little more realistic - a tiny &lt;code&gt;grep&lt;/code&gt; routine. Where is the time spent here - reading content from the disk or doing the regular expression matching?&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-fsharp&#34;&gt;open System.IO
open System.Text.RegularExpressions

let grep dir files patt =
    Directory.EnumerateFiles(dir, files, SearchOption.AllDirectories)
    |&amp;gt; Seq.collect (File.ReadAllLines)
    |&amp;gt; Seq.timed (Some 100000) Scale.ms
    |&amp;gt; Seq.filter (fun line -&amp;gt; Regex.IsMatch(line, patt))

// a cold search only reads ~150K lines/sec and large
// majority of time is spent reading from disk
grep @&amp;quot;C:\src\visualfsharp&amp;quot; &amp;quot;*.fs*&amp;quot; @&amp;quot;\blet\b&amp;quot; |&amp;gt; Seq.length
// 100000 items     552.14ms     181.11 items/ms       0.01 ms/item (89% upstream | 11% downstream)
// 100000 items     559.99ms     178.58 items/ms       0.01 ms/item (88% upstream | 12% downstream)
// 100000 items     777.57ms     128.61 items/ms       0.01 ms/item (91% upstream |  9% downstream)
// 100000 items     708.15ms     141.21 items/ms       0.01 ms/item (92% upstream |  8% downstream)
// 100000 items    3372.02ms      29.66 items/ms       0.03 ms/item (98% upstream |  2% downstream)
// 100000 items    3788.68ms      26.39 items/ms       0.04 ms/item (98% upstream |  2% downstream)
// 6740 items      75.73ms      89.00 items/ms       0.01 ms/item (95% upstream |  5% downstream)

// but for a second invocation the disk is warm and results are from the cache,
// so the time is more evenly split (and overall throughput is much higher)
grep @&amp;quot;C:\src\visualfsharp&amp;quot; &amp;quot;*.fs*&amp;quot; @&amp;quot;\blet\b&amp;quot; |&amp;gt; Seq.length
// 100000 items      99.67ms    1003.26 items/ms       0.00 ms/item (44% upstream | 56% downstream)
// 100000 items     175.45ms     569.95 items/ms       0.00 ms/item (59% upstream | 41% downstream)
// 100000 items     109.65ms     911.98 items/ms       0.00 ms/item (39% upstream | 61% downstream)
// 100000 items      92.56ms    1080.36 items/ms       0.00 ms/item (35% upstream | 65% downstream)
// 100000 items     193.58ms     516.59 items/ms       0.00 ms/item (70% upstream | 30% downstream)
// 100000 items     217.47ms     459.84 items/ms       0.00 ms/item (73% upstream | 27% downstream)
// 6740 items       8.71ms     774.07 items/ms       0.00 ms/item (49% upstream | 51% downstream)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;How much overhead does &lt;code&gt;Seq.timed&lt;/code&gt; add? That&amp;rsquo;s the real test - can &lt;code&gt;Seq.timed&lt;/code&gt; benchmark itself?&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-fsharp&#34;&gt;// 1000000 items 80442000.00ns       0.01 items/ns      80.44 ns/item (46% upstream | 54% downstream)
Enumerable.Range(1, 1000000)
|&amp;gt; Seq.timed None Scale.ns
|&amp;gt; Seq.length

// 1000000 items 170637400.00ns       0.01 items/ns     170.64 ns/item (81% upstream | 19% downstream)
Enumerable.Range(1, 1000000)
|&amp;gt; Seq.timed None (fun _ _ _ -&amp;gt; ())
|&amp;gt; Seq.timed None Scale.ns
|&amp;gt; Seq.length

// 1000000 items 242433000.00ns       0.00 items/ns     242.43 ns/item (88% upstream | 12% downstream)
Enumerable.Range(1, 1000000)
|&amp;gt; Seq.timed None (fun _ _ _ -&amp;gt; ())
|&amp;gt; Seq.timed None (fun _ _ _ -&amp;gt; ())
|&amp;gt; Seq.timed None Scale.ns
|&amp;gt; Seq.length
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Our baseline is about 80ns/item. Adding in one layer of &lt;code&gt;Seq.timed&lt;/code&gt; slows throughput to 170ns/item, and two layers slows throughput to about 240ns/item. Looking at these deltas and rounding up, we make a rough estimate that &lt;code&gt;Seq.timed&lt;/code&gt; adds a cost of ~100ns per item to a sequence (in my environment). So for data pipelines that are processing fewer than 1M items/sec, &lt;code&gt;Seq.timed&lt;/code&gt; adds less than 1% overhead. For anything faster than that, it starts to stick out a bit.&lt;/p&gt;

&lt;p&gt;Most of the work being done within &lt;code&gt;Seq.timed&lt;/code&gt; is the stopping and starting of timers used to calculate the upstream/downstream ratio. We can speed things up significantly by removing that feature and measuring only the total throughput. I&amp;rsquo;ve called that version &lt;code&gt;Seq.timedSlim&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-fsharp&#34;&gt;// 1000000 items 8791000.00ns       0.11 items/ns       8.79 ns/item
Enumerable.Range(1, 1000000)
|&amp;gt; Seq.timedSlim None Scale.ns
|&amp;gt; Seq.length

// 1000000 items 13693300.00ns       0.07 items/ns      13.69 ns/item
Enumerable.Range(1, 1000000)
|&amp;gt; Seq.timedSlim None (fun _ _ _ -&amp;gt; ())
|&amp;gt; Seq.timedSlim None Scale.ns
|&amp;gt; Seq.length

// 1000000 items 18784500.00ns       0.05 items/ns      18.78 ns/item
Enumerable.Range(1, 1000000)
|&amp;gt; Seq.timedSlim None (fun _ _ _ -&amp;gt; ())
|&amp;gt; Seq.timedSlim None (fun _ _ _ -&amp;gt; ())
|&amp;gt; Seq.timedSlim None Scale.ns
|&amp;gt; Seq.length
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Once again considering the deltas and rounding up, it appears this version is about 10x faster, slowing throughput by only &amp;lt;10ns/item. One needs to be processing 10M items/sec before &lt;code&gt;Seq.timedSlim&lt;/code&gt; makes more than 1% impact.&lt;/p&gt;

&lt;h4 id=&#34;code&#34;&gt;Code&lt;/h4&gt;

&lt;p&gt;Full implementation is below. A few notes/gotchas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The final callback won&amp;rsquo;t be invoked if the downstream consumer stops before the upstream source is finished. e.g. when the sequence is shortened downstream by &lt;code&gt;Seq.take&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Beware of transformations like &lt;code&gt;Seq.sort&lt;/code&gt; which slurp in the entire upstream sequence at full speed before doing any work to contribute downstream.&lt;/li&gt;
&lt;li&gt;Beware of sequences that do their work not in &lt;code&gt;MoveNext()&lt;/code&gt; but in &lt;code&gt;Current&lt;/code&gt;. Whether to assign the cost of &lt;code&gt;Current&lt;/code&gt; to the upstream or downstream sequence is debatable, but I&amp;rsquo;ve left it assigned to downstream.
&lt;br /&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;pre&gt;&lt;code class=&#34;language-fsharp&#34;&gt;open System
open System.Collections
open System.Collections.Generic
open System.Diagnostics

module Seq =
    type private TimedEnumerator&amp;lt;&#39;t&amp;gt;(source : IEnumerator&amp;lt;&#39;t&amp;gt;, blockSize, f) =
        let swUpstream = Stopwatch()
        let swDownstream = Stopwatch()
        let swTotal = Stopwatch()
        let mutable count = 0
        interface IEnumerator&amp;lt;&#39;t&amp;gt; with
            member __.Reset() = failwith &amp;quot;not implemented&amp;quot;
            member __.Dispose() = source.Dispose()
            member __.Current = source.Current
            member __.Current = (source :&amp;gt; IEnumerator).Current
            member __.MoveNext() =
                // downstream consumer has finished processing the previous item
                swDownstream.Stop()

                // start the total throughput timer if this is the first item
                if not swTotal.IsRunning then
                    swTotal.Start()

                // measure upstream MoveNext() call
                swUpstream.Start()
                let result = source.MoveNext()
                swUpstream.Stop()

                if result then
                    count &amp;lt;- count + 1

                // blockSize reached or upstream is complete - invoke callback and reset timers
                if (result &amp;amp;&amp;amp; count = blockSize) || (not result &amp;amp;&amp;amp; count &amp;gt; 0) then
                    swTotal.Stop()
                    let upDownTotal = swUpstream.Elapsed + swDownstream.Elapsed
                    f count swTotal.Elapsed (swUpstream.Elapsed.TotalMilliseconds / upDownTotal.TotalMilliseconds)
                    count &amp;lt;- 0
                    swUpstream.Reset()
                    swDownstream.Reset()
                    swTotal.Restart()

                // clock starts for downstream consumer
                swDownstream.Start()
                result

    type private SlimTimedEnumerator&amp;lt;&#39;t&amp;gt;(source : IEnumerator&amp;lt;&#39;t&amp;gt;, blockSize, f) =
        let swTotal = Stopwatch()
        let mutable count = 0
        interface IEnumerator&amp;lt;&#39;t&amp;gt; with
            member __.Current = source.Current
            member __.Current = (source :&amp;gt; IEnumerator).Current
            member __.Reset() = failwith &amp;quot;not implemented&amp;quot;
            member __.Dispose() = source.Dispose()
            member __.MoveNext() =
                // start the timer on the first MoveNext call
                if not swTotal.IsRunning then
                    swTotal.Start()

                let result = source.MoveNext()
                if result then
                    count &amp;lt;- count + 1

                // blockSize reached or upstream is complete - invoke callback and reset timer
                if (result &amp;amp;&amp;amp; count = blockSize) || (not result &amp;amp;&amp;amp; count &amp;gt; 0) then
                    swTotal.Stop()
                    f count swTotal.Elapsed Double.NaN
                    count &amp;lt;- 0
                    swTotal.Restart()
                result

    let mkTimed blockSize getEnum =
        let block =
            match blockSize with
            | Some(bs) when bs &amp;lt;= 0 -&amp;gt; invalidArg &amp;quot;blockSize&amp;quot; &amp;quot;blockSize must be positive&amp;quot;
            | Some(bs) -&amp;gt; bs
            | None -&amp;gt; -1
        { new IEnumerable&amp;lt;&#39;a&amp;gt; with
              member __.GetEnumerator() = upcast (getEnum block)
          interface IEnumerable with
              member __.GetEnumerator() = upcast (getEnum block) }

    let timed blockSize f (source : seq&amp;lt;&#39;t&amp;gt;) =
        mkTimed blockSize (fun block -&amp;gt; new TimedEnumerator&amp;lt;&#39;t&amp;gt;(source.GetEnumerator(), block, f))

    let timedSlim blockSize f (source : seq&amp;lt;&#39;t&amp;gt;) =
        mkTimed blockSize (fun block -&amp;gt; new SlimTimedEnumerator&amp;lt;&#39;t&amp;gt;(source.GetEnumerator(), block, f))

// sample callbacks that scale time units
module Scale =
    let private stats unitString getUnit blockSize elapsedTotal upstreamRatio =
        let totalScaled = getUnit (elapsedTotal : TimeSpan)
        let itemsPerTime = (float blockSize) / totalScaled
        let timePerItem = totalScaled / (float blockSize)
        let upDownPercentStr =
            if Double.IsNaN(upstreamRatio) then &amp;quot;&amp;quot;
            else sprintf &amp;quot; (%2.0f%% upstream | %2.0f%% downstream)&amp;quot; (100. * upstreamRatio) (100. * (1. - upstreamRatio))

        Console.WriteLine(
            sprintf &amp;quot;%d items %10.2f{0} %10.2f items/{0} %10.2f {0}/item%s&amp;quot;
                blockSize totalScaled itemsPerTime timePerItem upDownPercentStr,
            (unitString : string)
        )

    let s = stats &amp;quot;s&amp;quot; (fun ts -&amp;gt; ts.TotalSeconds)
    let ms = stats &amp;quot;ms&amp;quot; (fun ts -&amp;gt; ts.TotalMilliseconds)
    let μs = stats &amp;quot;μs&amp;quot; (fun ts -&amp;gt; ts.TotalMilliseconds * 1e3)
    let ns = stats &amp;quot;ns&amp;quot; (fun ts -&amp;gt; ts.TotalMilliseconds * 1e6)
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>JNI object lifetimes - quick reference</title>
      <link>https://latkin.org/blog/2016/02/01/jni-object-lifetimes-quick-reference/</link>
      <pubDate>Mon, 01 Feb 2016 00:00:00 +0000</pubDate>
      
      <guid>https://latkin.org/blog/2016/02/01/jni-object-lifetimes-quick-reference/</guid>
      <description>&lt;p&gt;I&amp;rsquo;ve recently had reason to do a bit of work with &lt;a href=&#34;https://en.wikipedia.org/wiki/Java_Native_Interface&#34; target=&#34;_blank&#34;&gt;JNI &lt;/a&gt;.  Throughout the course of this work I had to do quite a lot of Googling in order to figure out how to properly manage the caching of various JNI objects used by my C++ code. Some JNI objects can be safely cached and re-used at any point, while others have limited lifetimes and require special handling. Obtaining JNI objects through JNI APIs is, broadly speaking, fairly expensive, so it&amp;rsquo;s smart to persist those objects which will be re-used in multiple places. You just need to be careful.&lt;/p&gt;

&lt;p&gt;I expected to find a big table somewhere that documented the lifetime restrictions (or lack thereof) for each of the JNI object types, but sadly I was unable to locate one. Instead, I wound up trawling through numerous Stack Overflow replies, blogs, forums, and other documentation to obtain this information.&lt;/p&gt;

&lt;p&gt;This post is my effort to provide to others the missing quick reference I wish I&amp;rsquo;d found. I recommend &lt;a href=&#34;http://developer.android.com/training/articles/perf-jni.html#local_and_global_references&#34; target=&#34;_blank&#34;&gt;this Android documentation&lt;/a&gt; as further reading if you want more details.&lt;/p&gt;

&lt;table style=&#34;width:100%&#34; border=&#34;1&#34;&gt;
    &lt;tr&gt;
        &lt;th&gt;JNI Object&lt;/th&gt;
        &lt;th&gt;Use across JNI calls?&lt;/th&gt;
        &lt;th&gt;Use on different thread?&lt;/th&gt;
        &lt;th&gt;Notes&lt;/th&gt;
    &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;&lt;code&gt;JavaVM&lt;/code&gt;&lt;/td&gt;
    &lt;td&gt;Yes&lt;/td&gt; 
    &lt;td&gt;Yes&lt;/td&gt;
    &lt;td&gt;To obtain an instance of &lt;code&gt;JavaVM&lt;/code&gt;, either:
    &lt;ul&gt;
        &lt;li&gt;Expose a native export &lt;code&gt;jint JNI_OnLoad(JavaVM* vm, void* reserved)&lt;/code&gt;, which will be invoked when &lt;code&gt;LoadLibrary&lt;/code&gt; is called from Java&lt;/li&gt;
        &lt;li&gt;Call &lt;code&gt;pJNIEnv-&gt;GetJavaVM(&amp;pJavaVM)&lt;/code&gt; on a valid &lt;code&gt;JNIEnv&lt;/code&gt;
        &lt;/ul&gt;
    You don&#39;t need to clean up a &lt;code&gt;JavaVM&lt;/code&gt;.
   &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;&lt;code&gt;JNIEnv&lt;/code&gt;&lt;/td&gt;
    &lt;td&gt;Yes&lt;/td&gt; 
    &lt;td&gt;No&lt;/td&gt;
    &lt;td&gt;
A &lt;code&gt;JNIEnv&lt;/code&gt; is valid across JNI calls, but only on its original thread. If you are going to cache a &lt;code&gt;JNIEnv&lt;/code&gt;, consider using a &lt;code&gt;thread_local&lt;/code&gt; or similar.
&lt;p&gt;&lt;p&gt;
If a &lt;code&gt;JNIEnv&lt;/code&gt; is not available for the current thread (e.g. within a native callback), one can be obtained by calling &lt;code&gt;pJavaVM-&gt;AttachCurrentThread(&amp;pJNIEnv, null)&lt;/code&gt;.
           In this case you are responsible for cleaning up with &lt;code&gt;pJavaVM-&gt;DetachCurrentThread()&lt;/code&gt;.
&lt;p&gt;&lt;p&gt;
Otherwise, you don&#39;t need to clean up a &lt;code&gt;JNIEnv&lt;/code&gt;.
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
  &lt;td&gt;Primitive value types&lt;p&gt;&lt;p&gt;
   &lt;code&gt;jboolean&lt;/code&gt;,
    &lt;code&gt;jchar&lt;/code&gt;,
    &lt;code&gt;jshort&lt;/code&gt;,
    &lt;code&gt;jfloat&lt;/code&gt;,
    &lt;code&gt;jdouble&lt;/code&gt;,
    &lt;code&gt;jsize&lt;/code&gt;,
    &lt;code&gt;jint&lt;/code&gt;,
    &lt;code&gt;jlong&lt;/code&gt;,
    &lt;code&gt;jbyte&lt;/code&gt;&lt;/td&gt;
    &lt;td&gt;Yes&lt;/td&gt; 
    &lt;td&gt;Yes&lt;/td&gt;
    &lt;td&gt;These are just aliases for normal native value types, so there are no special lifetime or cleanup considerations.&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
  &lt;td rowspan=&#34;2&#34;&gt;Reference types&lt;p&gt;&lt;p&gt;
   &lt;code&gt;jobject&lt;/code&gt;,
    &lt;code&gt;jclass&lt;/code&gt;,
    &lt;code&gt;jthrowable&lt;/code&gt;,
    &lt;code&gt;jstring&lt;/code&gt;,
    &lt;code&gt;jarray&lt;/code&gt;,
    &lt;code&gt;jbooleanArray&lt;/code&gt;,
    &lt;code&gt;jbyteArray&lt;/code&gt;,
    &lt;code&gt;jcharArray&lt;/code&gt;,
    &lt;code&gt;jshortArray&lt;/code&gt;,
    &lt;code&gt;jintArray&lt;/code&gt;,
    &lt;code&gt;jlongArray&lt;/code&gt;,
    &lt;code&gt;jfloatArray&lt;/code&gt;,
    &lt;code&gt;jdoubleArray&lt;/code&gt;,
    &lt;code&gt;jobjectarray&lt;/code&gt;
    &lt;/td&gt;
    &lt;td&gt;No (local refs)&lt;/td&gt; 
    &lt;td&gt;No (local refs)&lt;/td&gt;
    &lt;td rowspan=&#34;2&#34;&gt;
       If one of these is passed in as an argument to a JNI call, or returned from another JNI API, it is typically a &lt;em&gt;local reference&lt;/em&gt;
       and is only valid for the duration of that JNI call, on that same thread. These do not require any cleanup.
       &lt;p&gt;&lt;p&gt;
       A durable &lt;em&gt;global reference&lt;/em&gt; can be created from any local reference by calling &lt;code&gt;globalJThing = (jthing) pJNIEnv-&gt;NewGlobalRef(localJThing)&lt;/code&gt;. Global references are valid across JNI calls and on any thread.
       Global references must be cleaned up with &lt;code&gt;pJNIEnv-&gt;DeleteGlobalRef(globalJThing)&lt;/code&gt;.
    &lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
    &lt;td&gt;Yes (global refs)&lt;/td&gt; 
    &lt;td&gt;Yes (global refs)&lt;/td&gt;
  &lt;/tr&gt;
  &lt;tr&gt;
  &lt;td&gt;ID types&lt;p&gt;&lt;p&gt;
   &lt;code&gt;jfieldID&lt;/code&gt;,
    &lt;code&gt;jmethodID&lt;/code&gt;
    &lt;/td&gt;
    &lt;td&gt;Yes&lt;/td&gt; 
    &lt;td&gt;Yes&lt;/td&gt;
    &lt;td&gt;These are durable and can be used without restriction. No cleanup is required.&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;</description>
    </item>
    
    <item>
      <title>Pentago</title>
      <link>https://latkin.org/blog/2015/07/01/pentago/</link>
      <pubDate>Thu, 02 Jul 2015 00:00:00 +0000</pubDate>
      
      <guid>https://latkin.org/blog/2015/07/01/pentago/</guid>
      <description>&lt;p&gt;&lt;a href=&#34;https://en.wikipedia.org/wiki/Pentago&#34; target=&#34;_blank&#34;&gt;Pentago&lt;/a&gt; is a favorite board game of mine, which I used to play regularly with coworkers during lunch (and occasionally during not-lunch). The rules are very simple, and casual games can be played in just a few minutes, but it&amp;rsquo;s deep enough to still be satisfying if you&amp;rsquo;re willing to put some thought into your strategy.&lt;/p&gt;

&lt;p&gt;In 2009 I wrote a computer player for Pentago in C#, and even managed to cobble together Silverlight and Windows Phone UIs for it that aren&amp;rsquo;t terrible. The engine uses a &lt;a href=&#34;https://en.wikipedia.org/wiki/Negamax&#34; target=&#34;_blank&#34;&gt;negamax&lt;/a&gt; algorithm with &lt;a href=&#34;https://en.wikipedia.org/wiki/Alpha%E2%80%93beta_pruning&#34; target=&#34;_blank&#34;&gt;alpha-beta pruning&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://latkin.org/blog/wp-content/uploads/2015/07/PentagoAgWinPhone11.gif&#34; alt=&#34;PentagoAgWinPhone&#34; /&gt;&lt;/p&gt;

&lt;p&gt;I put the engine up &lt;a href=&#34;http://pentagoag.codeplex.com/&#34; target=&#34;_blank&#34;&gt;on Codeplex&lt;/a&gt; a long time ago, but never thought to publish the UI projects. This week I moved the whole thing &lt;a href=&#34;https://github.com/latkin/pentagoag&#34; target=&#34;_blank&#34;&gt;to GitHub&lt;/a&gt; (UI projects included) and made sure it builds and runs with VS 2015.&lt;/p&gt;

&lt;p&gt;Things I hope to find time/motivation for in the not-too-distant future:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Re-implement the engine in F#, with various performance and design improvements&lt;/li&gt;
&lt;li&gt;Publish the phone version&lt;/li&gt;
&lt;li&gt;Make an HTML/JS front-end&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;In the meantime, here&amp;rsquo;s the Silverlight version to play with! [Note that if you&amp;rsquo;re using Chrome you&amp;rsquo;ll need to take &lt;a href=&#34;https://support.microsoft.com/en-us/kb/3058254&#34; target=&#34;_blank&#34;&gt;extra steps&lt;/a&gt; to enable Silverlight.]&lt;/p&gt;

&lt;script type=&#34;text/javascript&#34;&gt;
function onSilverlightError(sender, args) {             var appSource = &#34;&#34;;             if (sender != null &amp;#038;&amp;#038; sender != 0) {               appSource = sender.getHost().Source;             }             var errorType = args.ErrorType;             var iErrorCode = args.ErrorCode;             if (errorType == &#34;ImageError&#34; || errorType == &#34;MediaError&#34;) {               return;             }             var errMsg = &#34;Unhandled Error in Silverlight Application &#34; +  appSource + &#34;\n&#34; ;             errMsg += &#34;Code: &#34;+ iErrorCode + &#34;    \n&#34;;             errMsg += &#34;Category: &#34; + errorType + &#34;       \n&#34;;             errMsg += &#34;Message: &#34; + args.ErrorMessage + &#34;     \n&#34;;             if (errorType == &#34;ParserError&#34;) {                 errMsg += &#34;File: &#34; + args.xamlFile + &#34;     \n&#34;;                 errMsg += &#34;Line: &#34; + args.lineNumber + &#34;     \n&#34;;                 errMsg += &#34;Position: &#34; + args.charPosition + &#34;     \n&#34;;             }             else if (errorType == &#34;RuntimeError&#34;) {                            if (args.lineNumber != 0) {                     errMsg += &#34;Line: &#34; + args.lineNumber + &#34;     \n&#34;;                     errMsg += &#34;Position: &#34; +  args.charPosition + &#34;     \n&#34;;                 }                 errMsg += &#34;MethodName: &#34; + args.methodName + &#34;     \n&#34;;             }             throw new Error(errMsg);         }
&lt;/script&gt;&lt;/p&gt;
&lt;form id=&#34;form1&#34; style=&#34;height: 100%;&#34;&gt;
&lt;div id=&#34;silverlightControlHost&#34;&gt;&lt;object type=&#34;application/x-silverlight-2&#34; width=&#34;600&#34; height=&#34;600&#34;&gt;&lt;param name=&#34;source&#34; value=&#34;https://latkin.org/blog/wp-content/uploads/2015/06/PentagoAgUi.xap&#34; /&gt;&lt;param name=&#34;onError&#34; value=&#34;onSilverlightError&#34; /&gt;&lt;param name=&#34;background&#34; value=&#34;white&#34; /&gt;&lt;param name=&#34;minRuntimeVersion&#34; value=&#34;5.0.61118.0&#34; /&gt;&lt;param name=&#34;autoUpgrade&#34; value=&#34;true&#34; /&gt;&lt;a href=&#34;http://go.microsoft.com/fwlink/?LinkID=149156&amp;amp;v=5.0.61118.0&#34; style=&#34;text-decoration:none&#34;&gt; 			  &lt;img src=&#34;http://go.microsoft.com/fwlink/?LinkId=161376&#34; alt=&#34;Get Microsoft Silverlight&#34; style=&#34;border-style:none&#34; /&gt;		  &lt;/a&gt;&lt;/object&gt;&lt;/div&gt;
&lt;/form&gt;</description>
    </item>
    
    <item>
      <title>Null-checking considerations in F# - it&#39;s harder than you think</title>
      <link>https://latkin.org/blog/2015/05/18/null-checking-considerations-in-f-its-harder-than-you-think/</link>
      <pubDate>Mon, 18 May 2015 00:00:00 +0000</pubDate>
      
      <guid>https://latkin.org/blog/2015/05/18/null-checking-considerations-in-f-its-harder-than-you-think/</guid>
      <description>&lt;p&gt;The near-complete obviation of nulls is perhaps the most frequently- (and &lt;a href=&#34;https://twitter.com/tomaspetricek/status/314872258839601152&#34; target=&#34;_blank&#34;&gt;hilariously-&lt;/a&gt;) cited benefit of working in F#, as compared to C#. Nulls certainly still exist in F#, but as a practical matter it really is quite rare that they need to be considered explicitly within an all-F# codebase.&lt;/p&gt;

&lt;p&gt;It turns out this cuts both ways. On those infrequent occasions where one &lt;em&gt;does&lt;/em&gt; need to check for nulls, F# actually makes it surprisingly difficult to do so safely and efficiently.&lt;/p&gt;

&lt;p&gt;In this post I&amp;rsquo;ve tried to aggregate some best practices and pitfalls, in the form of DOs and DON&amp;rsquo;Ts, for F# null-checking.&lt;/p&gt;

&lt;p&gt;Recall that there are a handful of ways that nulls can be introduced into F# code, even for &amp;ldquo;non-nullable&amp;rdquo; F# types:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Affecting all reference types

&lt;ul&gt;
&lt;li&gt;C# or other CLI language consumers passing null&lt;/li&gt;
&lt;li&gt;.NET framework APIs returning null (e.g. LINQ &lt;code&gt;FirstOrDefault&amp;lt;T&amp;gt;()&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;F# &lt;code&gt;Unchecked.defaultof&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;F# &lt;code&gt;Array.zeroCreate&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Affecting only &amp;ldquo;nullable types&amp;rdquo;: non-F# types or F# types marked with &lt;code&gt;[&amp;lt;AllowNullLiteral&amp;gt;]&lt;/code&gt;

&lt;ul&gt;
&lt;li&gt;null literals&lt;/li&gt;
&lt;/ul&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&#34;don-ts&#34;&gt;DON&amp;rsquo;Ts&lt;/h3&gt;

&lt;h4 id=&#34;don-t-use-x-null-or-x-null-&#34;&gt;Don&amp;rsquo;t use &amp;lsquo;x = null&amp;rsquo; or &amp;lsquo;x &amp;lt;&amp;gt; null&amp;rsquo;&lt;/h4&gt;

&lt;p&gt;It&amp;rsquo;s unfortunate that the most obvious approach is not the best. This form is perfectly functional for nullable types, but the generated IL is unoptimized and ends up being quite slow. Standard F# structural/generic comparison is used here, which is a well-known drag on performance.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;F#:&lt;/em&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-fsharp&#34;&gt;let nullCheck01 x = (x = null)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;Codegen (C# equivalent):&lt;/em&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-csharp&#34;&gt;public static bool nullCheck01&amp;lt;a&amp;gt;(a x) where a : class
{
    return LanguagePrimitives.HashCompare.GenericEqualityIntrinsic&amp;lt;a&amp;gt;(x, default(a));
}

// --- F# core library ---

public static bool GenericEqualityIntrinsic&amp;lt;T&amp;gt;(T x, T y)
{
    return LanguagePrimitives.HashCompare.GenericEqualityObj(false, LanguagePrimitives.HashCompare.fsEqualityComparerNoHashingPER, );
}

internal static bool GenericEqualityObj(bool er, IEqualityComparer iec, object xobj, object yobj)
{
    if(xobj == null) return yobj == null;
    if(yobj != null) { /* ... core logic, fairly big, prevents JIT inlining ... */ }
    return false;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;By design, this form is not permitted for non-nullable types, as the compiler will not allow &lt;code&gt;null&lt;/code&gt; to represent an instance of such a type. One workaround is to convert to &lt;code&gt;System.Object&lt;/code&gt; first, i.e. &lt;code&gt;(box x) = null&lt;/code&gt;. This is perfectly functional, even for non-nullable types, but it is still slow.&lt;/p&gt;

&lt;h4 id=&#34;don-t-use-x-unchecked-defaultof-_-&#34;&gt;Don&amp;rsquo;t use x = Unchecked.defaultof&amp;lt;_&amp;gt;&lt;/h4&gt;

&lt;p&gt;When the need arises to null-check a non-nullable type, one might be tempted to compare directly against &lt;code&gt;Unchecked.defaultof&amp;lt;_&amp;gt;&lt;/code&gt;, rather that converting to &lt;code&gt;System.Object&lt;/code&gt; and comparing against a null literal.&lt;/p&gt;

&lt;p&gt;Unfortunately, this approach falls on its face when used with functional-style record or discriminated union types. Due to its baked-in notion of immutability and non-nullability for such types, the compiler assumes that it is always safe to codegen their equality comparisons as simply &lt;code&gt;x.Equals(y)&lt;/code&gt;.  That&amp;rsquo;s fine until x is null, in which case the &lt;em&gt;null-check itself&lt;/em&gt; blows up with a &lt;code&gt;NullReferenceException&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;F#:&lt;/em&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-fsharp&#34;&gt;type Cat = { Name : string; Lives : int }

let nullCheck02 (x : Cat) = (x = Unchecked.defaultof&amp;lt;_&amp;gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;Codegen (C# equivalent):&lt;/em&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-csharp&#34;&gt;public static bool nullCheck02(Cat x)
{
    Cat obj = null;

    // nullref
    return x.Equals(obj, LanguagePrimitives.GenericEqualityComparer);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&#34;don-t-expect-to-catch-nullreferenceexception&#34;&gt;Don&amp;rsquo;t expect to catch NullReferenceException&lt;/h4&gt;

&lt;p&gt;Let&amp;rsquo;s say you decide that you&amp;rsquo;ll mostly ignore the possibility of nulls, and but harden your code by catching &lt;code&gt;NullReferenceException.&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;F#:&lt;/em&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-fsharp&#34;&gt;type Cat = { Name : string; Lives : int }

let ohNoes x =
    try
        if x.Lives &amp;gt; 1 then Some({ x with Lives = x.Lives - 1})
        else None
    with
    | :? NullReferenceException -&amp;gt; None

ohNoes (Unchecked.defaultof&amp;lt;_&amp;gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Most F# developers will be surprised to find that this still fails with an unhandled &lt;code&gt;NullReferenceException&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;How is that possible? &lt;code&gt;NullReferenceException&lt;/code&gt; is clearly handled!&lt;/p&gt;

&lt;p&gt;Due to &lt;code&gt;Cat&lt;/code&gt;&amp;rsquo;s immutability/non-nullability, the compiler believes the contents of the &lt;code&gt;try&lt;/code&gt; block cannot fail. Thus it performs an &amp;ldquo;optimization&amp;rdquo; by &lt;em&gt;removing the try/catch altogether&lt;/em&gt;. Indeed, if you inspect the generated IL, you will find that the try/catch block simply isn&amp;rsquo;t generated:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Codegen (C# equivalent):&lt;/em&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-csharp&#34;&gt;public static FSharpOption&amp;lt;Cat&amp;gt; ohNoes(Cat x)
{
    if (x.Lives &amp;gt; 1)
    {
        return FSharpOption&amp;lt;Cat&amp;gt;.Some(new Cat(x.Name, x.Lives - 1));
    }
    return FSharpOption&amp;lt;Cat&amp;gt;.None;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;FWIW this is an altogether bogus optimization anyway, and has been &lt;a href=&#34;https://github.com/Microsoft/visualfsharp/pull/376&#34; target=&#34;_blank&#34;&gt;removed&lt;/a&gt; in F# 4.0.&lt;/p&gt;

&lt;h3 id=&#34;dos&#34;&gt;DOs&lt;/h3&gt;

&lt;h4 id=&#34;do-pattern-match-against-null&#34;&gt;Do pattern match against null&lt;/h4&gt;

&lt;p&gt;Pattern matching against null results in much better generated IL than comparison with &lt;code&gt;=&lt;/code&gt; or &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;. Nullable types can be matched directly, non-nullable types must be converted to &lt;code&gt;System.Object&lt;/code&gt; first by using &lt;code&gt;box&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;F#:&lt;/em&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-fsharp&#34;&gt;type Cat = { Name : string; Lives : int }

let nullCheck03 x = match x with null -&amp;gt; true | _ -&amp;gt; false
let nullCheck04 (x : Cat) = match box x with null -&amp;gt; true | _ -&amp;gt; false
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;Codegen:&lt;/em&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;// nullCheck04 is identical except generic &amp;quot;a&amp;quot; becomes concrete &amp;quot;Cat&amp;quot;
.method public static bool nullCheck03&amp;lt;class a&amp;gt; (!!a x) cil managed 
{
    .maxstack 8

    IL_0000: ldarg.0
    IL_0001: box !!a
    IL_0006: brfalse.s IL_000a

    IL_0008: ldc.i4.0
    IL_0009: ret

    IL_000a: ldc.i4.1
    IL_000b: ret
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The JIT produces exactly the same native code for both of these functions:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;          ; if x is null, go to 00D50503
00D504FB  test        ecx,ecx
00D504FD  je          00D50503  

          ; set return value to 0 (false)
00D504FF  xor         eax,eax  
          ; return 

          ; set return value to 1 (true)
00D50503  mov         eax,1  
          ; return
&lt;/code&gt;&lt;/pre&gt;

&lt;h4 id=&#34;do-use-object-referenceequals-x-null-&#34;&gt;Do use Object.ReferenceEquals(x, null)&lt;/h4&gt;

&lt;p&gt;Another way to get efficient null-checking is to call the BCL method &lt;code&gt;Object.ReferenceEquals&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;F#:&lt;/em&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-fsharp&#34;&gt;let nullCheck05 (x : &#39;t when &#39;t : null) = System.Object.ReferenceEquals(x, null)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;em&gt;Codegen:&lt;/em&gt;&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-text&#34;&gt;.method public static bool nullCheck05&amp;lt;class t&amp;gt; (!!t x) cil managed
{
    .maxstack 8

    IL_0000: nop
    IL_0001: ldarg.0
    IL_0002: box !!t
    IL_0007: ldnull
    IL_0008: call bool [mscorlib]System.Object::ReferenceEquals(object, object)
    IL_000d: ret
}

 // --- BCL ---

.method public hidebysig static bool ReferenceEquals (object objA, object objB) cil managed 
{
    .maxstack 8

    IL_0000: ldarg.0
    IL_0001: ldarg.1
    IL_0002: ceq
    IL_0004: ret
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;At the IL level this appears to suffer from the overhead of an additional method call, but &lt;code&gt;ReferenceEquals&lt;/code&gt; is small enough that it will be inlined by the JIT. The resulting native code winds up being at least as good as our earlier efforts, perhaps even better:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-text&#34;&gt;          ; if x is null, set the lowest byte of return value to 1
          ; otherwise set it to 0
012404A3  test        ecx,ecx  
012404A5  sete        al  

          ; fill out the rest of return value with 0s
012404A8  movzx       eax,al
          ; return
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;By &lt;a href=&#34;http://stackoverflow.com/a/6818329/1366219&#34; target=&#34;_blank&#34;&gt;some measurements&lt;/a&gt;, &lt;code&gt;Object.ReferenceEquals&lt;/code&gt; (or pattern-matching) is 7-8x faster than comparison with &lt;code&gt;=&lt;/code&gt; or &lt;code&gt;&amp;lt;&amp;gt;&lt;/code&gt;.&lt;/p&gt;

&lt;h4 id=&#34;do-use-isnull&#34;&gt;Do use isNull&lt;/h4&gt;

&lt;p&gt;In F# 4.0, a new helper function &lt;code&gt;isNull&lt;/code&gt; has been &lt;a href=&#34;https://github.com/Microsoft/visualfsharp/blob/fsharp4/src/fsharp/FSharp.Core/prim-types.fs#L3785-L3789&#34; target=&#34;_blank&#34;&gt;added&lt;/a&gt;, which has the same pattern matching implementation as &lt;code&gt;nullCheck03&lt;/code&gt; above. It only applies to nullable types, so you will need to &lt;code&gt;box&lt;/code&gt; non-nullable types first. &lt;code&gt;box&lt;/code&gt; and &lt;code&gt;isNull&lt;/code&gt; are both inline functions, so either way the final JITed code is the same as shown above.&lt;/p&gt;

&lt;h4 id=&#34;do-use-option-ofobj&#34;&gt;Do use Option.ofObj&lt;/h4&gt;

&lt;p&gt;In F# 4.0, a new helper function &lt;code&gt;Option.ofObj&lt;/code&gt; has been &lt;a href=&#34;https://github.com/Microsoft/visualfsharp/blob/fsharp4/src/fsharp/FSharp.Core/option.fs#L62-L63&#34; target=&#34;_blank&#34;&gt;added&lt;/a&gt;, which will convert a nullable object into an option instance, based on whether it&amp;rsquo;s null or not. This adds a bit of perf overhead, but is very handy for when you&amp;rsquo;d prefer to lean on the type system rather than worry about nulls.&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>A handy Powershell filter for converting plain text to objects</title>
      <link>https://latkin.org/blog/2015/05/15/a-handy-powershell-filter-for-converting-plain-text-to-objects/</link>
      <pubDate>Fri, 15 May 2015 00:00:00 +0000</pubDate>
      
      <guid>https://latkin.org/blog/2015/05/15/a-handy-powershell-filter-for-converting-plain-text-to-objects/</guid>
      <description>&lt;p&gt;Working on the command line with Powershell, much of the time I have the luxury of dealing directly with rich .NET objects.  If I need to sort, filter, or otherwise process cmdlet output, I have easy access to typed properties and methods right at the prompt.&lt;/p&gt;

&lt;p&gt;Often, though, I&amp;rsquo;ll need to wrangle plain text, perhaps from a log file or the output of an executable.  In these cases an intermediate step is required in order to extract the typed information (timestamps, substrings, numerical fields, etc) from the plain strings.&lt;/p&gt;

&lt;p&gt;This comes up often enough that I whipped up a handy Powershell filter, &amp;lsquo;ro&amp;rsquo; (for &amp;lsquo;regex object&amp;rsquo;), to make it easy:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-powershell&#34;&gt;# converts text to objects via regex,
#  with properties corresponding to capture groups
filter ro
{
    param($pattern)
    
    if($_ -match $pattern)
    {
        $result = @{}
        $matches.Keys |?{ $_ } |%{
            $raw = $matches[$_]
            $asInt = 0
            $asFloat = 0.0
            $asDate = [datetime]::Now
            if([int]::TryParse($raw, [ref] $asInt)){ $result[$_] = $asInt }
            elseif([double]::TryParse($raw, [ref] $asFloat)){ $result[$_] = $asFloat }
            elseif([datetime]::TryParse($raw, [ref] $asDate)){ $result[$_] = $asDate }
            else{ $result[$_] = $raw }
        }
    [pscustomobject]$result
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This takes each line of text piped to it and attempts to match it with the provided regex pattern. If it matches, an object is created with properties corresponding to capture groups of the match (ignoring group 0, which represents the full match). It will even check if the capture group can be parsed as an int, float, or timestamp, in which case that strongly-typed value is used in favor of the flat string value.&lt;/p&gt;

&lt;p&gt;I get a lot of mileage out of this guy.  As an example, when &lt;a href=&#34;https://twitter.com/LincolnAtkinson/status/575813147145191424&#34; target=&#34;_blank&#34;&gt;producing &lt;/a&gt;the Visual F# and Roslyn contributor mugs, we wanted to etch the username and SHA of each contributor&amp;rsquo;s first commit.&lt;/p&gt;

&lt;p&gt;Using just the basic git tools and &amp;lsquo;ro&amp;rsquo;, this info can be produced in a 1-liner.&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://latkin.org/blog/wp-content/uploads/2015/05/regexobj1.png&#34; alt=&#34;alt&#34; /&gt;&lt;/p&gt;

&lt;p&gt;In this case I got to pick convenient delimiters, so I could be very sloppy with my regex! 🙂&lt;/p&gt;</description>
    </item>
    
    <item>
      <title>Bug with Powershell Get-Date</title>
      <link>https://latkin.org/blog/2015/04/01/bug-with-powershell-get-date/</link>
      <pubDate>Wed, 01 Apr 2015 00:00:00 +0000</pubDate>
      
      <guid>https://latkin.org/blog/2015/04/01/bug-with-powershell-get-date/</guid>
      <description>&lt;p&gt;5 years ago today, I sent the following bug report to the Powershell team.&lt;/p&gt;

&lt;div class=&#34;blockquote&#34;&gt;From: Lincoln Atkinson
Sent: Thursday, April 01, 2010 10:33 PM
To: PowerShell Discussions
Subject: Problem with get-date

Hey experts, maybe you can help me with this issue.

Get-Date seems totally broken for me.  I&amp;#39;ve tried it multiple times with all different parameters, but it&amp;#39;s just not working in my environment.  I&amp;#39;m still single and I haven&amp;#39;t gotten a date in months :-(

Get-Help really wasn&amp;#39;t useful this time.  Funny, since many of the ladies I wanted to Get-Date with specifically suggested I “get-help.”  A few told me to try “get-life” and “get-bent,” as well, but I couldn&amp;#39;t find those cmdlets.  They must be running some V3 beta.

I&amp;#39;ve debugged this a bit, and have eliminated some possibilities:

Localization – I live in Seattle, seems there should be a pretty good social scene there.
Build – I&amp;#39;m average height/weight, don&amp;#39;t see this as holding me back.
Concurrency – In our modern era of tolerance I&amp;#39;d like to think this isn&amp;#39;t a race condition.
Hardware – Not the issue.
Low Resources – Get-Job worked ok for me so I have at least a little money saved.

Any thoughts?  I just want to allocate some memories with someone and maybe attend a few advanced functions.

-Lincoln&lt;/div&gt;

&lt;p&gt;The report was forwarded to the Powershell MVPs, who weighed in with reasoned opinions and sage advice.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Tibor Soós &amp;ndash; &lt;em&gt;And if there is a parent object, he should also use the –confirm switch.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://twitter.com/halr9000&#34;&gt;Hal Rottenberg&lt;/a&gt; &amp;ndash; &lt;em&gt;I do NOT recommend concurrent job scenarios with this cmdlet. I have heard of it being done, but it never ends well.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://twitter.com/halr9000&#34;&gt;Hal Rottenberg&lt;/a&gt; &amp;ndash; &lt;em&gt;I just hope he didn&amp;rsquo;t try the Force parameter. That one has some illegal page fault regression bugs in v2.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://twitter.com/SBSDiva&#34;&gt;Susan Bradley&lt;/a&gt; &amp;ndash; &lt;em&gt;Not to mention you really want to run with antivirus or have some protection in this scenario.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;&lt;a href=&#34;https://twitter.com/oising&#34;&gt;Oisín Grehan&lt;/a&gt; &amp;ndash; &lt;em&gt;His deduction on localization might be flawed: Get-Date typically only works at places where Get-Culture returns a non-null value.&lt;/em&gt; [ouch!]&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Tobias Weltner &amp;ndash; &lt;em&gt;You also want to make sure not to use the undocumented –recurse switch which leads to unexpected results.&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;</description>
    </item>
    
    <item>
      <title>Non-transitive Grime Dice, via Mathematica</title>
      <link>https://latkin.org/blog/2015/01/16/non-transitive-grime-dice-via-mathematica/</link>
      <pubDate>Fri, 16 Jan 2015 00:00:00 +0000</pubDate>
      
      <guid>https://latkin.org/blog/2015/01/16/non-transitive-grime-dice-via-mathematica/</guid>
      <description>&lt;p&gt;For Christmas this year, I got myself a fun mathematical gift: a set of 10 &lt;a href=&#34;http://en.wikipedia.org/wiki/Nontransitive_dice&#34; target=&#34;_blank&#34;&gt;non-transitive dice&lt;/a&gt;, namely &lt;a href=&#34;http://www.singingbanana.com/dice/article.htm&#34; target=&#34;_blank&#34;&gt;Grime Dice&lt;/a&gt;! You can get your own set &lt;a href=&#34;http://mathsgear.co.uk/collections/dice/products/non-transitive-grime-dice&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt;. Behold their dicey splendor:&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://latkin.org/blog/wp-content/uploads/2015/01/WP_20141231_001-300x243.jpg&#34; alt=&#34;grime dice&#34; /&gt;&lt;/p&gt;

&lt;p&gt;These dice possess the fascinating property that their winning relationships (in the sense of &amp;ldquo;winning&amp;rdquo; = &amp;ldquo;rolls a higher number &amp;gt; 50% of the time&amp;rdquo;) are non-transitive. i.e. if die A wins against die B, and die B wins against die C, it actually does *not* hold, in general, that die A wins against die C.  In fact, die C might win against die A!&lt;/p&gt;

&lt;p&gt;If we label the 5 Grime Dice colors Red, Blue, Yellow, Olive, and Magenta, there are 2 primary non-transitive winning cycles&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;By word length:&lt;/strong&gt; Red beats Blue beats Olive beats Yellow beats Magenta beats Red&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Alphabetically:&lt;/strong&gt; Blue beats Magenta beats Olive beats Red beats Yellow beats Blue&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;That&amp;rsquo;s pretty neat and non-intuitive by itself, but things get weirder when you roll two dice of the same color together: the word length cycle &lt;em&gt;reverses&lt;/em&gt;, while the alphabetical cycle (almost) stays intact.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;By word length (doubles):&lt;/strong&gt; Red/Red loses to Blue/Blue loses to Olive/Olive loses to Yellow/Yellow loses to Magenta/Magenta loses to Red/Red&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Alphabetically (doubles):&lt;/strong&gt; Blue/Blue beats Magenta/Magenta beats Olive/Olive loses to Red/Red beats Yellow/Yellow beats Blue/Blue&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Using Mathematica, we can calculate the winning probabilities, and visualize the cycles:&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://latkin.org/blog/wp-content/uploads/2015/01/cycles41.png&#34; alt=&#34;cycles4&#34; /&gt;&lt;/p&gt;

&lt;p&gt;These 4 cycles are the only ones which are advertised, but it turns out there are many more that you can form using just the 10 dice included in the set.&lt;/p&gt;

&lt;p&gt;In fact, there are 298 such cycles! Here are the plots of &lt;a href=&#34;https://latkin.org/blog/wp-content/uploads/2015/01/1cycles_full.png&#34; target=&#34;_blank&#34;&gt;all 1-die cycles&lt;/a&gt;,  &lt;a href=&#34;https://latkin.org/blog/wp-content/uploads/2015/01/2cycles_full.png&#34; target=&#34;_blank&#34;&gt;all 2-dice cycles&lt;/a&gt;, and &lt;a href=&#34;https://latkin.org/blog/wp-content/uploads/2015/01/3cycles_full.png&#34; target=&#34;_blank&#34;&gt;all 3-die cycles&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In this post, we&amp;rsquo;ll walk through the Mathematica code used to create these plots and to compute the complete set of possible cycles.&lt;/p&gt;

&lt;h3 id=&#34;modeling-dice&#34;&gt;Modeling dice&lt;/h3&gt;

&lt;p&gt;The first step is to provide a simple representation of the different dice colors, each of which has a unique pip configuration:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-mathematica&#34;&gt;(* represent the dice, their names, and their face values *)
red = dice[&amp;quot;Red&amp;quot;] = {{&amp;quot;Red&amp;quot;}, {4, 4, 4, 4, 4, 9}};
blue = dice[&amp;quot;Blue&amp;quot;] = {{&amp;quot;Blue&amp;quot;}, {2, 2, 2, 7, 7, 7}};
olive = dice[&amp;quot;Olive&amp;quot;] = {{&amp;quot;Olive&amp;quot;}, {0, 5, 5, 5, 5, 5}};
yellow = dice[&amp;quot;Yellow&amp;quot;] = {{&amp;quot;Yellow&amp;quot;}, {3, 3, 3, 3, 8, 8}};
magenta = dice[&amp;quot;Magenta&amp;quot;] = {{&amp;quot;Magenta&amp;quot;}, {1, 1, 6, 6, 6, 6}};
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To compute which of two dice beats the other, and the odds of that win, we generate every possible roll between the two dice, and see which one comes out on top more often:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-mathematica&#34;&gt;(* compute which of two dice would win, including the odds *)
(* returns {winner -&amp;gt; loser, odds} *)
compareDice[{lName_, lVals_}, {rName_, rVals_}] := (
  rolls = Tuples[{lVals, rVals}];
  winDiff = Total[rolls /. {l_, r_} -&amp;gt; Sign[r - l]];
  odds = 1/2 +  Abs[winDiff]/(2*Length[rolls]);
  {If[winDiff &amp;gt; 0, rName -&amp;gt; lName, lName -&amp;gt; rName], N[odds, 3]}
);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Thus we can see that, for example, Red beats Blue 58% of the time, and Yellow beats Magenta 56% of the time.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-mathematica&#34;&gt;compareDice[red, blue]
compareDice[magenta, yellow]
 
(* output:
    {{&amp;quot;Red&amp;quot;} -&amp;gt; {&amp;quot;Blue&amp;quot;}, 0.583}
    {{&amp;quot;Yellow&amp;quot;} -&amp;gt; {&amp;quot;Magenta&amp;quot;}, 0.556}
*)
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;non-transitive-cycles&#34;&gt;Non-transitive cycles&lt;/h3&gt;

&lt;p&gt;We are already in a position to verify and quantify the primary word-length and alphabetical cycles with single dice:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-mathematica&#34;&gt;byWordLength = {{red, blue}, {blue, olive}, {olive, yellow}, {yellow, magenta}, {magenta, red}};
byAlpha = {{blue, magenta}, {magenta, olive}, {olive, red}, {red, yellow}, {yellow, blue}};

compareDice @@@ byWordLength
compareDice @@@ byAlpha

(* output:
  {{{&amp;quot;Red&amp;quot;} -&amp;gt; {&amp;quot;Blue&amp;quot;}, 0.583}, {{&amp;quot;Blue&amp;quot;} -&amp;gt; {&amp;quot;Olive&amp;quot;}, 0.583}, {{&amp;quot;Olive&amp;quot;} -&amp;gt; {&amp;quot;Yellow&amp;quot;}, 0.556}, {{&amp;quot;Yellow&amp;quot;} -&amp;gt; {&amp;quot;Magenta&amp;quot;}, 0.556}, {{&amp;quot;Magenta&amp;quot;} -&amp;gt; {&amp;quot;Red&amp;quot;}, 0.556}}
  {{{&amp;quot;Blue&amp;quot;} -&amp;gt; {&amp;quot;Magenta&amp;quot;}, 0.667}, {{&amp;quot;Magenta&amp;quot;} -&amp;gt; {&amp;quot;Olive&amp;quot;}, 0.722}, {{&amp;quot;Olive&amp;quot;} -&amp;gt; {&amp;quot;Red&amp;quot;}, 0.694}, {{&amp;quot;Red&amp;quot;} -&amp;gt; {&amp;quot;Yellow&amp;quot;}, 0.722}, {{&amp;quot;Yellow&amp;quot;} -&amp;gt; {&amp;quot;Blue&amp;quot;}, 0.667}}
 *)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We can represent and compare pairs of dice as if they were each one 36-sided die, with each face corresponding to the total from a possible roll of the constituent dice.  This lets us compute the odds of the word-length and alphabetical double dice cycles, too:&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-mathematica&#34;&gt;(* create a new &amp;quot;die&amp;quot; by combining two dice *)
combine[{name1_, vals1_}, {name2_, vals2_}] := {Join[name1, name2], Plus @@@ Tuples[{vals1, vals2}]};
double[die_] := combine[die, die];

compareDice @@@ Map[double, byWordLength, {2}]
compareDice @@@ Map[double, byAlpha, {2}]

(* output
  {{{&amp;quot;Blue&amp;quot;, &amp;quot;Blue&amp;quot;} -&amp;gt; {&amp;quot;Red&amp;quot;, &amp;quot;Red&amp;quot;}, 0.590}, {{&amp;quot;Olive&amp;quot;, &amp;quot;Olive&amp;quot;} -&amp;gt; {&amp;quot;Blue&amp;quot;, &amp;quot;Blue&amp;quot;}, 0.590}, {{&amp;quot;Yellow&amp;quot;, &amp;quot;Yellow&amp;quot;} -&amp;gt; {&amp;quot;Olive&amp;quot;, &amp;quot;Olive&amp;quot;}, 0.691}, {{&amp;quot;Magenta&amp;quot;, &amp;quot;Magenta&amp;quot;} -&amp;gt; {&amp;quot;Yellow&amp;quot;, &amp;quot;Yellow&amp;quot;}, 0.593}, {{&amp;quot;Red&amp;quot;, &amp;quot;Red&amp;quot;} -&amp;gt; {&amp;quot;Magenta&amp;quot;, &amp;quot;Magenta&amp;quot;}, 0.691}}
  {{{&amp;quot;Blue&amp;quot;, &amp;quot;Blue&amp;quot;} -&amp;gt; {&amp;quot;Magenta&amp;quot;, &amp;quot;Magenta&amp;quot;}, 0.556}, {{&amp;quot;Magenta&amp;quot;, &amp;quot;Magenta&amp;quot;} -&amp;gt; {&amp;quot;Olive&amp;quot;, &amp;quot;Olive&amp;quot;}, 0.583}, {{&amp;quot;Red&amp;quot;, &amp;quot;Red&amp;quot;} -&amp;gt; {&amp;quot;Olive&amp;quot;, &amp;quot;Olive&amp;quot;}, 0.518}, {{&amp;quot;Red&amp;quot;, &amp;quot;Red&amp;quot;} -&amp;gt; {&amp;quot;Yellow&amp;quot;, &amp;quot;Yellow&amp;quot;}, 0.583}, {{&amp;quot;Yellow&amp;quot;, &amp;quot;Yellow&amp;quot;} -&amp;gt; {&amp;quot;Blue&amp;quot;, &amp;quot;Blue&amp;quot;}, 0.556}}
*)
&lt;/code&gt;&lt;/pre&gt;

&lt;h3 id=&#34;plotting&#34;&gt;Plotting&lt;/h3&gt;

&lt;p&gt;It&amp;rsquo;s much nicer to visualize the winning relationships between the dice, rather than just printing out the data.  Mathematica has excellent plotting and visualization capabilities, so this is certainly possible.&lt;/p&gt;

&lt;p&gt;&lt;a href=&#34;http://reference.wolfram.com/language/ref/GraphPlot.html&#34; target=&#34;_blank&#34;&gt;GraphPlot&lt;/a&gt; is a good choice here.  Its default visual output isn&amp;rsquo;t very well-suited to this problem, though, so we will need to do some customization. We can take advantage of the various hooks which are exposed by the function, enabling us to specify custom graphical objects to represent the vertices and edges of the relationship graph.&lt;/p&gt;

&lt;p&gt;The below code will create nice graph plots where the vertices are represented by appropriately-colored dice icons, and the edges point from winner -&amp;gt; loser and are labeled with the probability of that win.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-mathematica&#34;&gt;(* keep track of which colors should be used in plots *)
colors[&amp;quot;Red&amp;quot;] = Red;
colors[&amp;quot;Blue&amp;quot;] = Blue;
colors[&amp;quot;Olive&amp;quot;] = Green;
colors[&amp;quot;Yellow&amp;quot;] = Yellow;
colors[&amp;quot;Magenta&amp;quot;] = Purple;

(* plot colored rectangles to represent the dice at a graph vertex *)
getVertex[center_, names_] := (
  numDice = Length@names;
  positions = {-0.08 + #, 0.08 + #} &amp;amp; /@ 
    Range[-0.04*(numDice - 1)/2, 0.04*(numDice - 1)/2, 0.04];
  Transpose[{colors /@ names, Rectangle[center + #1, center + #2, RoundingRadius -&amp;gt; 0.02] &amp;amp; @@@ positions}]
  );

(* plot a nicely-formatted labeled arrow for graph edges *)
getEdge =
  ({Gray, If[#3 == 0.5, Line[#1], Arrow[#1, 0.15]], Black, 
     Inset[#3, Mean[#1], Background -&amp;gt; White]} &amp;amp;);

(* given a list of dice pairs, creates a nicely-formatted plot of
winning relationships and odds *)
plotDice[pairs_] :=
 GraphPlot[compareDice @@@ pairs,
  VertexRenderingFunction -&amp;gt; getVertex,
  EdgeRenderingFunction -&amp;gt; getEdge];
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Let&amp;rsquo;s take a look at the single and double cycles visually:&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://latkin.org/blog/wp-content/uploads/2015/01/cycles12.png&#34; alt=&#34;cycles1&#34; /&gt;&lt;/p&gt;

&lt;p&gt;Pretty neat! Besides various oddities with orientation and ordering, these plots are quite appealing. Exact placement of the vertices can be specified by the VertexCoordinateRules parameter to GraphPlot, but the default layout works well enough for our purposes.&lt;/p&gt;

&lt;h3 id=&#34;more-cycles&#34;&gt;More cycles&lt;/h3&gt;

&lt;p&gt;We have looked at the primary 5-color cycles using both single dice and doubles of the same color. That&amp;rsquo;s just the beginning, though.  For example, besides the 5-color cycles, various smaller cycles also exist:&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://latkin.org/blog/wp-content/uploads/2015/01/cycles22.png&#34; alt=&#34;cycles2&#34; /&gt;&lt;/p&gt;

&lt;p&gt;How many of these smaller cycles exist? What about bigger cycles? And what about cycles involving doubles composed of 2 different colors? Or even cycles consisting of sets of 3 dice? We want to compute &lt;em&gt;every possible cycle&lt;/em&gt; that can be created using the 10 dice from the set.&lt;/p&gt;

&lt;p&gt;Our overall approach to solving this will be to generate directed graphs which encode all of the winning relationships between unique dice sets of a certain size (single dice, pairs, or triples), then search for cycles within those graphs.&lt;/p&gt;

&lt;p&gt;It should be noted (we won&amp;rsquo;t prove it here) that for Grime Dice, any pair of dice beats any single die, and any triple of dice beats any pair or single die.  Thus it is indeed acceptable to split this computation up into separate buckets for single dice, pairs, and triples. There are no heterogeneous cycles with respect to number of competing dice.&lt;/p&gt;

&lt;h3 id=&#34;single-dice&#34;&gt;Single dice&lt;/h3&gt;

&lt;p&gt;One might assume that the cycles of single dice would be the easiest to compute. In fact, single dice pose a couple of unique challenges that pairs and triples do not.  Specifically, in a set of 10 dice, we could potentially find cycles up to size 10.  But since we only have 5 colors, once a cycle becomes length-6 or longer we must necessarily have 2 same-color nodes in the cycle.  We need to make sure to differentiate between the two copies of each color.&lt;/p&gt;

&lt;p&gt;In order to capture the fact that we have 2 copies of each color on hand, we will use a bit of a hack. The &amp;ldquo;second&amp;rdquo; copy of each color will be represented as a combination with a special &amp;ldquo;white&amp;rdquo; die which has 1 face and always rolls 0.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-mathematica&#34;&gt;(* dummy &amp;quot;white&amp;quot; die used to differentiate between 
two instances of the same color die *)
white = dice[&amp;quot;White&amp;quot;] = {{&amp;quot;White&amp;quot;}, {0}};

(* when plotting, just make the white die invisible *)
colors[&amp;quot;White&amp;quot;] = Transparent;

(* all distinct single dice from set of 10 *)
allDice[1] = 
  Join[allColors, combine @@@ Tuples[{allColors, {white}}]];
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;To start building the actual relationship graph, we will define a couple of helper functions.  The first is used to create the &lt;a href=&#34;http://reference.wolfram.com/language/ref/DirectedEdge.html&#34; target=&#34;_blank&#34;&gt;DirectedEdge&lt;/a&gt; values Mathematica consumes when &lt;a href=&#34;http://reference.wolfram.com/language/ref/Graph.html&#34; target=&#34;_blank&#34;&gt;Graph&lt;/a&gt; is called in the second function.  The edges are directed from &amp;ldquo;winning di&amp;copy;e&amp;rdquo; to &amp;ldquo;losing di&amp;copy;e&amp;rdquo;.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-mathematica&#34;&gt;(* Note that we don&#39;t return an edge here if the 2 dice are equally matched *)
getGraphEdge[left_, right_] := (
  {relationship, odds} = compareDice[left, right];
  If[odds != 1/2, relationship /. Rule -&amp;gt; DirectedEdge]
);

(* builds the graph of winning relationships for
n-tuples of dice *)
makeGraph[n_] := 
 Graph[Cases[getGraphEdge @@@ Subsets[allDice[n], {2}], DirectedEdge[__]]];
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We can now generate the full graph of single dice relationships, and have Mathematica compute all cycles up to maximum size of 10.  In the last step, note that we need to deduplicate the cycle list to eliminate those cycles which are unique only due to inclusion of the dummy &amp;ldquo;white&amp;rdquo; die.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-mathematica&#34;&gt;diceGraph[1] = makeGraph[1];

(* built-in function DeleteDuplicatesBy is present only
in Mathematica 10+ *)
deDupeBy[expr_, f_] := Values[GroupBy[expr, f, First]];

(* compute all cycles of single dice that can
be made from the 10 included dice *)
cycles[1] = 
  deDupeBy[FindCycle[diceGraph[1], 10, All], 
   Sort[(# /. {e_, &amp;quot;White&amp;quot;} -&amp;gt; {e})] &amp;amp;];
   
CountsBy[cycles[1], Length]
cycles[1] // Length

(* output:
  &amp;lt;|3 -&amp;gt; 5, 4 -&amp;gt; 5, 5 -&amp;gt; 2, 6 -&amp;gt; 15, 7 -&amp;gt; 20, 8 -&amp;gt; 20, 9 -&amp;gt; 10, 10 -&amp;gt; 3|&amp;gt;
  80
*)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We see that there are a total of 80 unique single-die cycles, with sizes ranging from 3 to 10.&lt;/p&gt;

&lt;h3 id=&#34;pairs-of-dice&#34;&gt;Pairs of dice&lt;/h3&gt;

&lt;p&gt;Dice pairs turn out to be the simplest case.&lt;/p&gt;

&lt;p&gt;With pairs (and above), we do not need to consider the possibility of distinct-yet-identical nodes in the cycle. Proof: Between any two identical nodes, there must be at least 2 other nodes (if there was only one node, it would be simultaneously beating and losing to identical nodes on either side), so a full cycle with identical nodes must have length at least 6 (the 2 identical nodes + 2 separating nodes on each side).  When each node consists of a pair of dice, this requires at least 12 dice.  Since we only have 10 dice, this is impossible.&lt;/p&gt;

&lt;p&gt;This eliminates the need for the dummy die, as well as the de-duplication at the end.&lt;/p&gt;

&lt;p&gt;The only additional wrinkle we need to consider is the possibility for a computed cycle to contain more than 2 dice of a particular color.  Such cycles are invalid in our scenario, since we are only utilizing the 10 dice in the set.  We will update our helpers and add some additional filtering to eliminate such cycles.&lt;/p&gt;

&lt;p&gt;Finally, for pairs, we only need to search for cycles up to length 5.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-mathematica&#34;&gt;(* all unique dice pairs *)
allDice[2] = Flatten[Table[combine @@ allColors[[{i, j}]],
    {i, 1, Length[allColors]},
    {j, i, Length[allColors]}], 1];

(* updated to avoid creating edges between nodes 
that combine to use more than 2 of any color *)
getGraphEdge[left_, right_] :=
 If[FreeQ[Tally[Join[left[[1]], right[[1]]]], {_, count_} /; count &amp;gt; 2],
  {relationship, odds} = compareDice[left, right];
  If[odds != 1/2, relationship /. Rule -&amp;gt; DirectedEdge]
 ];

(* check if a given full cycle uses more than 2 of
any particular color *)
isValidCycle[cyc_] :=
  FreeQ[Tally[Flatten[cyc /. DirectedEdge[a_, _] :&amp;gt; a]], {_, count_} /; count &amp;gt; 2];

(* compute all cycles of pairs of dice that can
be made from the 10 included dice *)
diceGraph[2] = makeGraph[2];
cycles[2] = Select[FindCycle[diceGraph[2], 5, All], isValidCycle];

CountsBy[cycles[2], Length]
cycles[2] // Length
(* output:
  &amp;lt;|3 -&amp;gt; 55, 4 -&amp;gt; 89, 5 -&amp;gt; 25|&amp;gt;
  169
*)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There are 169 unique cycles using pairs of dice.&lt;/p&gt;

&lt;h3 id=&#34;triples-of-dice&#34;&gt;Triples of Dice&lt;/h3&gt;

&lt;p&gt;Triples are the largest sets we need to consider. At least 3 nodes are required to form a cycle, and if those nodes consist of 4 or more dice each, our set of 10 dice will not be sufficient.&lt;/p&gt;

&lt;p&gt;Similarly, we need only search for cycles of length 3 here &amp;ndash; a cycle of 4 triples requires more dice than we have.&lt;/p&gt;

&lt;p&gt;We start by extending our dice-combining function to handle triples, building up all such unique triples, and generating their winning relationship graph. Note that any triples where all 3 dice are the same color are invalid, and should be filtered.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-mathematica&#34;&gt;(* extend to handle triples *)
combine[die1_, die2_, die3_] := combine[die1, combine[die2, die3]];

(* all unique dice triples *)
allDice[3] = Select[
   Flatten[Table[combine @@ allColors[[{i, j, k}]],
     {i, 1, Length[allColors]},
     {j, i, Length[allColors]},
     {k, j, Length[allColors]}], 2],
   Length@Union@#[[1]] != 1 &amp;amp;];

diceGraph[3] = makeGraph[3];
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;From here, computing the triple cycles &lt;em&gt;should&lt;/em&gt; be as simple as calling FindCycle again. Unfortunately, Mathematica spins (seemingly) indefinitely when one tries this.  The relationship graph for triples is 30 nodes and 208 edges - not trivial, but not really &lt;em&gt;that&lt;/em&gt; big. I&amp;rsquo;m not sure why FindCycle has trouble with it.  Oddly enough, FindCycle immediately finds 1 cycle if that&amp;rsquo;s all you ask for, but exhibits the hang if you ask for even just 2 cycles, let alone all of them.&lt;/p&gt;

&lt;p&gt;So we will need to search for the 3-cycles in this graph manually. The below code does the trick.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-mathematica&#34;&gt;(* for each edge in the graph, collect potential second edges
e.g. for edge A -&amp;gt; B, find all pairs {{A -&amp;gt; B, B -&amp;gt; X},{A -&amp;gt; B, B -&amp;gt; Y}, ...} *)
edgePairs = 
  Flatten[EdgeList[diceGraph[3]] /. 
    DirectedEdge[a_, b_] :&amp;gt; ({DirectedEdge[a, b], #} &amp;amp; /@ 
       EdgeList[diceGraph[3], DirectedEdge[b, _]]), 1];

(* find and validate the 3rd and final edge of a 3-cycle.
e.g. given {A -&amp;gt; B, B -&amp;gt; C}, check that C -&amp;gt; A exists, and 
the cycle A -&amp;gt; B -&amp;gt; C -&amp;gt; A is valid *)
completeCycle[DirectedEdge[a_, b_], DirectedEdge[c_, d_]] := (
   lastEdge = DirectedEdge[d, a];
   If[MemberQ[EdgeList[diceGraph[3]], lastEdge], (
     cycle = {DirectedEdge[a, b], DirectedEdge[c, d], lastEdge};
     If[isValidCycle[cycle],
      Sow[cycle]
     ])
   ]
);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This enables us to compute the cycles, though we do need to deduplicate them (unlike FindCycle, our manual code is not smart enough to realize the cycle A -&amp;gt; B -&amp;gt; C -&amp;gt;A is the same as the cycle B -&amp;gt; C -&amp;gt; A -&amp;gt; B).&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-mathematica&#34;&gt;cycles[3] = deDupeBy[Reap[Scan[completeCycle @@ # &amp;amp;, edgePairs]][[2, 1]], Sort];

CountsBy[cycles[3], Length]

(* output:
  &amp;lt;|3 -&amp;gt; 49|&amp;gt;
*)
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There are 49 triple-dice cycles.  This brings the grand total to 298 unique non-transitive cycles in a set of 10 Grime Dice.&lt;/p&gt;

&lt;h3 id=&#34;plot-all-the-cycles&#34;&gt;Plot all the cycles!&lt;/h3&gt;

&lt;p&gt;Finally, the fun part - making giant plots of every possible cycle!&lt;/p&gt;

&lt;p&gt;To plot a single cycle, we just need to massage the data a little bit so that it works with plotDice from earlier.&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-mathematica&#34;&gt;(* &#39;combining&#39; a single die is a no-op *)
combine[{name1_, vals1_}] := {name1, vals1};

(* plot a single non-transitive dice cycle *)
plotCycle[cyc_] :=
  plotDice[cyc /. DirectedEdge[l_, r_] :&amp;gt; {combine @@ (dice /@ l), combine @@ (dice /@ r)}];
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;A couple of example plots:&lt;/p&gt;

&lt;p&gt;&lt;img src=&#34;https://latkin.org/blog/wp-content/uploads/2015/01/cycles31.png&#34; alt=&#34;cycles3&#34; /&gt;&lt;/p&gt;

&lt;p&gt;To generate the full plots, as linked at the top of the post, all we need is&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-mathematica&#34;&gt;(* plot everything! *)
plotCycle /@ cycles[1]
plotCycle /@ cycles[2]
plotCycle /@ cycles[3]
&lt;/code&gt;&lt;/pre&gt;</description>
    </item>
    
    <item>
      <title>Today is Phi Day -- at least, it ought to be</title>
      <link>https://latkin.org/blog/2015/01/06/today-is-phi-day-at-least-it-ought-to-be/</link>
      <pubDate>Tue, 06 Jan 2015 00:00:00 +0000</pubDate>
      
      <guid>https://latkin.org/blog/2015/01/06/today-is-phi-day-at-least-it-ought-to-be/</guid>
      <description>&lt;p&gt;By now, most everyone is aware of &lt;a href=&#34;http://en.wikipedia.org/wiki/Pi_Day&#34; target=&#34;_blank&#34;&gt;Pi Day&lt;/a&gt;, celebrating the famous mathematical constant 
&lt;img style=&#34;display:inline;vertical-align:middle;&#34; src=&#34;https://latex.codecogs.com/gif.latex?\inline&amp;space;%5cpi%20%5capprox%203.14159&#34; title=&#34;\pi \approx 3.14159&#34; /&gt; on &lt;sup&gt;3&lt;/sup&gt;&amp;frasl;&lt;sub&gt;14&lt;/sub&gt;. On this day each year, students and math enthusiasts eat pie and engage in light-hearted 
&lt;img style=&#34;display:inline;vertical-align:middle;&#34; src=&#34;https://latex.codecogs.com/gif.latex?\inline&amp;space;%5cpi&#34; title=&#34;\pi&#34; /&gt;-related activities. Then there is &lt;a href=&#34;http://www.wired.com/2013/02/happy-e-day-what-is-e/&#34; target=&#34;_blank&#34;&gt;e Day&lt;/a&gt;, a day for commemorating the equally-important-if-somewhat-less-famous constant 
&lt;img style=&#34;display:inline;vertical-align:middle;&#34; src=&#34;https://latex.codecogs.com/gif.latex?\inline&amp;space;e%20%5capprox%202.71828&#34; title=&#34;e \approx 2.71828&#34; /&gt; on &lt;sup&gt;2&lt;/sup&gt;&amp;frasl;&lt;sub&gt;7&lt;/sub&gt;. The activities are similar, though it&amp;rsquo;s less clear-cut what food one should eat (a high school teacher of mine insisted that the proper e Day food is waffles, evocative of the Cartesian coordinate system).  Even events like Pi Approximation Day (&lt;sup&gt;22&lt;/sup&gt;&amp;frasl;&lt;sub&gt;7&lt;/sub&gt; in day/month format), and Mole Day (6:02 &lt;sup&gt;10&lt;/sup&gt;&amp;frasl;&lt;sub&gt;23&lt;/sub&gt;) have gained enough momentum to warrant &lt;a href=&#34;https://www.google.com/?#q=pi+approximation+day&#34; target=&#34;_blank&#34;&gt;dedicated&lt;/a&gt; &lt;a href=&#34;https://www.bing.com/search?q=pi+approximation+day&#34; target=&#34;_blank&#34;&gt;results&lt;/a&gt; from both &lt;a href=&#34;https://www.google.com/?#q=mole+day&#34; target=&#34;_blank&#34;&gt;Google&lt;/a&gt; and &lt;a href=&#34;https://www.bing.com/search?q=mole%20day&#34; target=&#34;_blank&#34;&gt;Bing&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So when is Phi Day?&lt;/p&gt;

&lt;p&gt;
&lt;img style=&#34;display:inline;vertical-align:middle;&#34; src=&#34;https://latex.codecogs.com/gif.latex?\inline&amp;space;%5cphi%20%5capprox%201.61803&#34; title=&#34;\phi \approx 1.61803&#34; /&gt;, the &lt;a href=&#34;http://en.wikipedia.org/wiki/Golden_ratio&#34; target=&#34;_blank&#34;&gt;Golden Ratio&lt;/a&gt;, is arguably the 3rd-most &amp;ldquo;pop-famous&amp;rdquo; mathematical constant after 
&lt;img style=&#34;display:inline;vertical-align:middle;&#34; src=&#34;https://latex.codecogs.com/gif.latex?\inline&amp;space;%5cpi&#34; title=&#34;\pi&#34; /&gt; and 
&lt;img style=&#34;display:inline;vertical-align:middle;&#34; src=&#34;https://latex.codecogs.com/gif.latex?\inline&amp;space;e&#34; title=&#34;e&#34; /&gt;. It has enough geek-cred status that you can buy &lt;a href=&#34;http://www.thinkgeek.com/product/9eec/&#34; target=&#34;_blank&#34;&gt;shirts with hundreds of its digits&lt;/a&gt; on the front, arranged into the shape of the 
&lt;img style=&#34;display:inline;vertical-align:middle;&#34; src=&#34;https://latex.codecogs.com/gif.latex?\inline&amp;space;%5cphi&#34; title=&#34;\phi&#34; /&gt; character. So you&amp;rsquo;d think Phi Day, whenever it is, must surely be marked on numberphiles&amp;rsquo; calendars worldwide.&lt;/p&gt;

&lt;p&gt;As it turns out, there are major disagreements over the date on which Phi Day should be held, and this lack on consensus has kind of killed the whole thing before it ever got started. The surprisingly long list of candidate dates has fractured the community such that a critical mass of participation on a single day has never been reached.&lt;/p&gt;

&lt;p&gt;What are these different Phi Day camps?&lt;/p&gt;

&lt;h3 id=&#34;the-digits-division&#34;&gt;The digits division&lt;/h3&gt;

&lt;p&gt;Following the precedent set by Pi Day on &lt;sup&gt;3&lt;/sup&gt;&amp;frasl;&lt;sub&gt;14&lt;/sub&gt; and e Day on &lt;sup&gt;2&lt;/sup&gt;&amp;frasl;&lt;sub&gt;7&lt;/sub&gt;, the most straightforward choice for Phi Day is &lt;span style=&#34;color: #ff00ff;&#34;&gt;&lt;strong&gt;&lt;sup&gt;1&lt;/sup&gt;&amp;frasl;&lt;sub&gt;6&lt;/sub&gt;&lt;/strong&gt;&lt;/span&gt;, based on the leading decimal digits of the constant.  And indeed, there is some support for this date: see &lt;a href=&#34;http://philosfx.blogspot.com/2011/01/phi-day-161803.html&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt;, &lt;a href=&#34;http://yearofthenerd.wordpress.com/2013/01/06/january-6-sherlock-appears-and-phi-day/&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt;, and &lt;a href=&#34;https://sites.google.com/a/rsu5.org/8th-grade-math/home/pictures/phi-day&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Interestingly, the more popular digit-based candidate seems to be &lt;span style=&#34;color: #ff00ff;&#34;&gt;&lt;strong&gt;&lt;sup&gt;6&lt;/sup&gt;&amp;frasl;&lt;sub&gt;18&lt;/sub&gt;&lt;/strong&gt;&lt;/span&gt;. Some basic web searches turn up a number of results, e.g. &lt;a href=&#34;http://www.phiday.org/&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt;, &lt;a href=&#34;http://www.foxnews.com/story/2007/06/18/happy-phi-day-perfect-time-for-some-phinancial-fun/&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt;, &lt;a href=&#34;http://dickstrawser.blogspot.com/2012/06/phi-day-post-about-golden-section.html&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt;, &lt;a href=&#34;http://www.edn.com/electronics-blogs/serious-fun/4375582/Musical-tribute-to-math-for-Phi-Day&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt;, &lt;a href=&#34;http://www.ticalc.org/archives/news/articles/3/35/35979.html&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt;, and &lt;a href=&#34;http://www.dayintechhistory.com/dith/june-18-phi-day-1993-john-scully-apple2007-terry-semel-yahoo-step/&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt;. The standard explanation for this choice is that it matches the first digits &lt;em&gt;after&lt;/em&gt; the decimal point, or that it matches the leading digits of the reciprocal form 
&lt;img style=&#34;display:inline;vertical-align:middle;&#34; src=&#34;https://latex.codecogs.com/gif.latex?\inline&amp;space;%5cPhi%20%3d%201%2f%5cphi%20%5capprox%200.61803&#34; title=&#34;\Phi = 1/\phi \approx 0.61803&#34; /&gt;.&lt;/p&gt;

&lt;h3 id=&#34;the-fraction-faction&#34;&gt;The fraction faction&lt;/h3&gt;

&lt;p&gt;There is another group which argues that picking the date of Phi Day based on decimal digits is passé and should be avoided. Maybe that&amp;rsquo;s good enough for Pi Day and e Day, they say, but with Phi Day we have an opportunity for something more meaningful, man!!&lt;/p&gt;

&lt;p&gt;The idea uniting this faction is to pick Phi Day as the date which divides the year into two parts, where the parts are in proportion matching the Golden Ratio.&lt;/p&gt;

&lt;p&gt;This is actually a neat idea, but sadly even this camp shatters into further subdivisions.&lt;/p&gt;

&lt;p&gt;Taking the year to be 365 days, one gets closest to a division in the ratio of 
&lt;img style=&#34;display:inline;vertical-align:middle;&#34; src=&#34;https://latex.codecogs.com/gif.latex?\inline&amp;space;%5cphi&#34; title=&#34;\phi&#34; /&gt; by taking the 226th day of the year (226/(365 - 226) is about 1.626), which is &lt;span style=&#34;color: #ff00ff;&#34;&gt;&lt;strong&gt;&lt;sup&gt;8&lt;/sup&gt;&amp;frasl;&lt;sub&gt;14&lt;/sub&gt;&lt;/strong&gt;&lt;/span&gt;. See &lt;a href=&#34;http://thefinchandpea.com/2012/08/14/happy-phi-day-2/&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt; and &lt;a href=&#34;http://www.elliottwave.com/freeupdates/archives/2009/08/12/Why-Phi-August-14-Marks-the-Golden-Mean.aspx&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt; for advocacy of this date.&lt;/p&gt;

&lt;p&gt;But what about leap years? In those years there are 366 days, of which 8/14 is the 227th. In this case the previous day, &lt;sup&gt;8&lt;/sup&gt;&amp;frasl;&lt;sub&gt;13&lt;/sub&gt;, is actually a better pick, as 226/(366 - 226) = 1.614 comes closer to the desired ratio than 227/(366 - 227) = 1.633.&lt;/p&gt;

&lt;p&gt;Thus &lt;sup&gt;8&lt;/sup&gt;&amp;frasl;&lt;sub&gt;14&lt;/sub&gt; is rejected by some in favor of the more robust alternative where the shorter division is put first. &lt;span style=&#34;color: #ff00ff;&#34;&gt;&lt;strong&gt;&lt;sup&gt;5&lt;/sup&gt;&amp;frasl;&lt;sub&gt;19&lt;/sub&gt;&lt;/strong&gt;&lt;/span&gt; is the 139th day of standard years, and the 140th day of leap years. Happily, this ends up being the ideal pick for both cases: (365 - 139)/139 = 1.626 and (366 - 140)/140 = 1.614.  See &lt;a href=&#34;http://mathjokes4mathyfolks.wordpress.com/2013/05/17/is-it-phi-day-yet/&#34; target=&#34;_blank&#34;&gt;here&lt;/a&gt; for advocacy of this date.&lt;/p&gt;

&lt;p&gt;Finally, &lt;a href=&#34;http://www.goldenratio.org/phi_day.html&#34; target=&#34;_blank&#34;&gt;this prominent site&lt;/a&gt; catapults the navel-gazing to stunning new heights by condemning the Gregorian calendar itself as too mainstream, declaring that the Phi Day year-division should be measured starting from a more &amp;ldquo;natural&amp;rdquo; delimitation of the annum, namely the vernal equinox.&lt;/p&gt;

&lt;p&gt;But wait, doesn&amp;rsquo;t the Spring equinox occur on different dates in the Northern and Southern Hemisphere? Indeed, this site goes so far as to advocate for &lt;em&gt;two separate Phi Days&lt;/em&gt;: &lt;span style=&#34;color: #ff00ff;&#34;&gt;&lt;strong&gt;&lt;sup&gt;10&lt;/sup&gt;&amp;frasl;&lt;sub&gt;31&lt;/sub&gt;&lt;/strong&gt;&lt;/span&gt; in the Northern Hemisphere, &lt;strong&gt;&lt;span style=&#34;color: #ff00ff;&#34;&gt;&lt;sup&gt;5&lt;/sup&gt;&amp;frasl;&lt;sub&gt;6&lt;/sub&gt;&lt;/span&gt;&lt;/strong&gt; in the Southern Hemisphere (where the dates are computed the same way as &lt;sup&gt;8&lt;/sup&gt;&amp;frasl;&lt;sub&gt;14&lt;/sub&gt;, but starting from the respective equinoxes).&lt;/p&gt;

&lt;h3 id=&#34;keep-it-simple&#34;&gt;Keep it simple&lt;/h3&gt;

&lt;p&gt;My stance is that Phi Day belongs on the obvious choice: &lt;span style=&#34;color: #008000;&#34;&gt;&lt;strong&gt;&lt;sup&gt;1&lt;/sup&gt;&amp;frasl;&lt;sub&gt;6&lt;/sub&gt;&lt;/strong&gt;&lt;/span&gt;. There is strong precedent in Pi Day and e Day, it&amp;rsquo;s easy to remember, and there are no worries about leap years or hemispheres.  It&amp;rsquo;s accessible and easy to explain to anyone.&lt;/p&gt;

&lt;p&gt;&lt;sup&gt;6&lt;/sup&gt;&amp;frasl;&lt;sub&gt;18&lt;/sub&gt; strikes me as an arbitrary choice to ignore digits, or to prefer the secondary, reciprocal form. I just don&amp;rsquo;t see what&amp;rsquo;s gained by that choice. A further disadvantage is that many schools (in the US, at least) are already out for summer break by this time, so this date can&amp;rsquo;t really be used as a fun day for students.&lt;/p&gt;

&lt;p&gt;And all of the year-fraction dates can be dismissed outright, if you ask me. Yes, explaining their position within the year provides a potential teaching opportunity, but that computation (let alone the overall explanation) is just totally inaccessible to most people. I had to break out a bit of code and lean on a date/time library just to verify these dates, and I assume most others would need to do the same.  When there is such a high hurdle to even figure out what date the event is on, there&amp;rsquo;s no way it will ever gain traction outside of fanatics.&lt;/p&gt;

&lt;p&gt;The ultimate goal of these silly &amp;ldquo;math holidays&amp;rdquo; is to provide a fun excuse for enthusiasts to celebrate, but also to create a friendly and inviting opportunity for &lt;em&gt;non&lt;/em&gt;-enthusiasts to learn a little bit and join the fun without feeling intimidated. &lt;sup&gt;1&lt;/sup&gt;&amp;frasl;&lt;sub&gt;6&lt;/sub&gt; seems like the clear choice.&lt;/p&gt;

&lt;p&gt;Happy Phi Day!&lt;/p&gt;</description>
    </item>
    
  </channel>
</rss>