<?xml version='1.0' encoding='utf-8' ?>

<rss version='2.0' xmlns:lj='http://www.livejournal.org/rss/lj/1.0/' xmlns:atom10='http://www.w3.org/2005/Atom'>
<channel>
  <title>Renaissance Grrrl</title>
  <link>https://winterkoninkje.dreamwidth.org/</link>
  <description>Renaissance Grrrl - Dreamwidth Studios</description>
  <lastBuildDate>Sat, 27 Apr 2019 20:07:49 GMT</lastBuildDate>
  <generator>LiveJournal / Dreamwidth Studios</generator>
  <lj:journal>winterkoninkje</lj:journal>
  <lj:journaltype>personal</lj:journaltype>
  <image>
    <url>https://v2.dreamwidth.org/8328681/518115</url>
    <title>Renaissance Grrrl</title>
    <link>https://winterkoninkje.dreamwidth.org/</link>
    <width>100</width>
    <height>86</height>
  </image>

<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/113356.html</guid>
  <pubDate>Sat, 27 Apr 2019 20:07:49 GMT</pubDate>
  <title>Link updates</title>
  <link>https://winterkoninkje.dreamwidth.org/113356.html</link>
  <description>&lt;p&gt;Hello all,&lt;/p&gt;

&lt;p&gt;It looks like my old &lt;s&gt;cl.indiana.edu/~wren&lt;/s&gt; is dead. I&apos;m not sure why exactly (glancing through emails I couldn&apos;t find anything relevant); but it looks like all the non-faculty accounts on that machine have gone away, so I won&apos;t take it personally.&lt;/p&gt;

&lt;p&gt;But fear not, for at long last I have decided to get my own domain: &lt;a href=&quot;https://wrengr.org&quot;&gt;wrengr.org&lt;/a&gt;! I&apos;ve corrected the links on the &lt;a href=&quot;https://winterkoninkje.dreamwidth.org/tag/columbicubiculomania&quot;&gt;columbicubiculomania&lt;/a&gt; posts, so you should be able to get the pdfs again. If you notice any other broken links, please do drop me a line.&lt;/p&gt;

&lt;p&gt;As part of the move I&apos;ve also decided to finalize the switch from Darcs to &lt;a href=&quot;https://github.com/wrengr&quot;&gt;GitHub&lt;/a&gt; for all my Hackage projects. The impedence cost of merging github pullrequests back to darcs has been a bit much, and I&apos;ve been using git at work, so, much as I love darcs and hate git, I think it&apos;s finally time. I&apos;ve pushed out a few package updates already, and will try to get the rest out as soon as I can.&lt;/p&gt;

&lt;p&gt;Ever since &lt;s&gt;community.haskell.org&lt;/s&gt; has died, I&apos;ve defaulted back to using my cpan email for Haskell stuff. This is clearly suboptimal, but I&apos;m one of those old curmudgeons who hates giving out the direct address for their personal email, and cpan seems like the only one still providing forwarding addresses these days. The webhost for my new domainname, alas, doesn&apos;t offer a forwarding-only plan so the only way to use them would be to spring for a full-blown smtp plan, which is a bit pricy for a single forwarding address. I&apos;ll prolly end up doing it eventually, but it&apos;ll take a while to justify to myself. Until then, please bear with the holding pattern of using the cpan address.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=113356&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/113356.html</comments>
  <category>haskell planet</category>
  <category>website update</category>
  <lj:security>public</lj:security>
  <lj:reply-count>1</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/113056.html</guid>
  <pubDate>Fri, 23 Jun 2017 05:37:59 GMT</pubDate>
  <title>&quot;Spring semester&quot; in review</title>
  <link>https://winterkoninkje.dreamwidth.org/113056.html</link>
  <description>&lt;p&gt;Hi all, long time no post. A lot has been going on, but I’m finally starting to get on top of things again. I’ve been meaning to write in a bit more depth about some of this, but that want for perfection has been the enemy of the writing anything at all. So, here’s a quick synopsis of what’s been going on in my neck of the woods.&lt;/p&gt;

&lt;p&gt;Both of L’s parents passed away. &lt;a href=&quot;http://winterkoninkje.dreamwidth.org/111728.html&quot;&gt;We’ve known this was coming&lt;/a&gt;, but it’s still hard of course. L was out there for a bit over a month taking care of her mom. They died very close together, so we ended up having a single combined service. I was out there for about a week helping to wrap things up before whisking L back home.&lt;/p&gt;

&lt;p&gt;I finally got back the results of the genetics test. Turns out I don’t have Loeys–Dietz, or at least not the same genetic variant my mother did. But I definitely have &lt;i&gt;something&lt;/i&gt;. So it’s back to the diagnostic swamp trying to figure out how to give it a name so that doctors’ll take it seriously. Current working hypothesis is hypermobility-type Ehlers–Danlos. Alas, “hypermobility-type” is medical jargon for “we have no idea what this is, but it kinda looks similar to the forms of Ehlers–Danlos we do know stuff about, so let’s call it that.” So, yeah, no medical tests to “prove” that’s what it is; just your usual game of convincing folks you have enough of the symptoms to match the syndrome.&lt;/p&gt;

&lt;p&gt;I’ve been getting used to paying attention to &lt;a href=&quot;http://winterkoninkje.dreamwidth.org/112269.html&quot;&gt;my ADHD&lt;/a&gt; and working with it rather than trying to plow through it. It helps a lot to recognize that it’s not a failing on my part (e.g., that I can’t focus on boring things for as long as other people) but rather just part of how I’m wired. That makes it a lot easier to stop beating myself up over things, and instead figure out better ways to work with my brain rather than trying to force it into a shape it won’t take. As I’ve gotten better at this I’ve finally started getting caught up on a bunch of things that’ve fallen to the wayside over the past few years.&lt;/p&gt;

&lt;p&gt;For example, I’m slowly getting caught up on the backlog of bug reports and feature requests for my various Haskell packages. Mostly been focusing on &lt;a href=&quot;https://github.com/wrengr/logfloat&quot;&gt;logfloat&lt;/a&gt; and &lt;a href=&quot;https://github.com/wrengr/unification-fd&quot;&gt;unification-fd&lt;/a&gt; so far, but will make it around to the others in time. So, if you sent me an email about some bug or feature over the past few years and it seems to have fallen into the void, consider &lt;a href=&quot;https://github.com/wrengr&quot;&gt;filing a ticket&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Still working on getting caught up to where I should be on my dissertation.&lt;/p&gt;

&lt;p&gt;Work has also been going excellently. It’s all seekrit and nonsense, so I can’t say too much about it. But lately I’ve been doing a bunch of work on characterizing families of mathematical objects, and discovering their symmetries so we can exploit them to simplify and optimize things. So lots of mathy goodness going on. It’s a bit more geometric and combinatorial than my usual algebraic fare, but it’s the sort of stuff that arises from algebraic structures so it’s not too far from home base. (If that doesn’t make sense to you, maybe take a look at &lt;a href=&quot;http://ozark.hendrix.edu/~yorgey/pub/thesis.pdf&quot;&gt;Brent Yorgey’s thesis&lt;/a&gt; to see an example of the connection between combinatorics and algebraic data types.) Plus, it helps that I’ve been getting to know some of the hella queer ladies who work in my building :)&lt;/p&gt;

&lt;p&gt;In other health-y news, round about the time I got officially diagnosed with ADHD I had a bunch of friends going on about what the symptoms of allism (aka non-autism) are. Though I have a bunch of autistic friends, I’ve never really known much about what autism’s really like because all the literature is written by allistic folks, for allistic folks, so they’re all “patient has underdeveloped/insufficient blah” and I’m like “according to what baseline? How much blah does it take to count as having ‘sufficient’ blah? What are diagnostic details for measuring how much blah you really have?” So I finally got to hear some details from the autistic side of the fence, where people actually explain shit and elucidate the differences. And based on that: I’m hella not allistic. I can (and should! and have been meaning to!) write a whole separate post on this topic. I’m still not entirely sure I feel comfortable adopting “autistic” label (for reasons which are, themselves, further symptoms of autism), because my experiences don’t match up perfectly with some of the parts of what is traditionally called “autism”, but I’m absolutely non-allistic. I think the spectrum of non-allism is far larger and more diverse than allistic people currently believe, but —again— a post for another time.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=113056&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/113056.html</comments>
  <category>haskell planet</category>
  <category>dissertating</category>
  <category>adhd</category>
  <category>loeys-dietz</category>
  <category>haskell</category>
  <category>personal</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/112435.html</guid>
  <pubDate>Tue, 04 Apr 2017 03:21:19 GMT</pubDate>
  <title>LJ is no more</title>
  <link>https://winterkoninkje.dreamwidth.org/112435.html</link>
  <description>&lt;p&gt;LiveJournal changed their TOS recently and, well, I didn&apos;t really feel like reading it to see what changed so instead I&apos;ve deleted my old LJ account. All the folks I used to follow on LJ have since moved on to other venues or stopped blogging entirely, and I&apos;ve been using DW as my main blog for quite some time now, so it was just a matter of time. In the event you were still following the old LJ account, now&apos;s the time to switch.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=112435&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/112435.html</comments>
  <category>website update</category>
  <category>haskell planet</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/111227.html</guid>
  <pubDate>Sun, 08 Jan 2017 21:25:25 GMT</pubDate>
  <title>ANN: containers 0.5.9.1</title>
  <link>https://winterkoninkje.dreamwidth.org/111227.html</link>
  <description>&lt;h3&gt;containers 0.5.9.1&lt;/h3&gt;

&lt;p&gt;The containers package contains efficient general-purpose implementations of various basic immutable container types.  The declared cost of each operation is either worst-case or amortized, but remains valid even if structures are shared.&lt;/p&gt;

&lt;h3&gt;Changes since 0.5.8.1 (2016-08-31)&lt;/h3&gt;

&lt;p&gt;The headline change is adding &lt;code&gt;merge&lt;/code&gt; and &lt;code&gt;mergeA&lt;/code&gt; for &lt;code&gt;Data.IntMap&lt;/code&gt;. The versions for &lt;code&gt;Data.Map&lt;/code&gt; were introduced in 0.5.8.1, so this change restores parity between the interfaces. With this in place we hope this version will make it into GHC 8.2.&lt;/p&gt;

&lt;p&gt;Other changes include:&lt;ul&gt;
&lt;li&gt;Add instances for &lt;code&gt;Data.Graph.SCC&lt;/code&gt;: &lt;code&gt;Foldable&lt;/code&gt;, &lt;code&gt;Traversable&lt;/code&gt;, &lt;code&gt;Data&lt;/code&gt;, &lt;code&gt;Generic&lt;/code&gt;, &lt;code&gt;Generic1&lt;/code&gt;, &lt;code&gt;Eq&lt;/code&gt;, &lt;code&gt;Eq1&lt;/code&gt;, &lt;code&gt;Show&lt;/code&gt;, &lt;code&gt;Show1&lt;/code&gt;, &lt;code&gt;Read&lt;/code&gt;, and &lt;code&gt;Read1&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Add lifted instances (from &lt;code&gt;Data.Functor.Classes&lt;/code&gt;) for &lt;code&gt;Data.Sequence&lt;/code&gt;, &lt;code&gt;Data.Map&lt;/code&gt;, &lt;code&gt;Data.Set&lt;/code&gt;, &lt;code&gt;Data.IntMap&lt;/code&gt;, and &lt;code&gt;Data.Tree&lt;/code&gt;. (Thanks to Oleg Grenrus for doing a lot of this work.)&lt;/li&gt;
&lt;li&gt;Properly deprecate functions in &lt;code&gt;Data.IntMap&lt;/code&gt; long documented as deprecated.&lt;/li&gt;
&lt;li&gt;Rename several internal modules for clarity. Thanks to esoeylemez for starting this process.&lt;/li&gt;
&lt;li&gt;Make &lt;code&gt;Data.Map.fromDistinctAscList&lt;/code&gt; and &lt;code&gt;Data.Map.fromDistinctDescList&lt;/code&gt; more eager, improving performance.&lt;/li&gt;
&lt;li&gt;Plug space leaks in &lt;code&gt;Data.Map.Lazy.fromAscList&lt;/code&gt; and &lt;code&gt;Data.Map.Lazy.fromDescList&lt;/code&gt; by manually inlining constant functions.&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;lookupMin&lt;/code&gt; and &lt;code&gt;lookupMax&lt;/code&gt; to &lt;code&gt;Data.Set&lt;/code&gt; and &lt;code&gt;Data.Map&lt;/code&gt; as total alternatives to &lt;code&gt;findMin&lt;/code&gt; and &lt;code&gt;findMax&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Add &lt;code&gt;(!?)&lt;/code&gt; to &lt;code&gt;Data.Map&lt;/code&gt; as a total alternative to &lt;code&gt;(!)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Avoid using &lt;code&gt;deleteFindMin&lt;/code&gt; and &lt;code&gt;deleteFindMax&lt;/code&gt; internally, preferring total functions instead. New implementations of said functions lead to slight performance improvements overall.&lt;/li&gt;
&lt;/ul&gt;&lt;/p&gt;


&lt;h3&gt;Links&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Hackage: &lt;a href=&quot;http://hackage.haskell.org/package/containers&quot;&gt;http://hackage.haskell.org/package/containers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;GitHub: &lt;a href=&quot;https://github.com/haskell/containers&quot;&gt;https://github.com/haskell/containers&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;btn-group&quot;&gt;
&lt;a href=&quot;https://twitter.com/share?via=wrengr&amp;amp;url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F111227.html&amp;amp;text=ANN%3A%20containers%200.5.9.1&quot; class=&quot;btn&quot; title=&quot;Share on Twitter&quot; target=&quot;_blank&quot;&gt;Twitter&lt;/a&gt;
&lt;a href=&quot;https://www.facebook.com/sharer/sharer.php?u=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F111227.html&amp;amp;t=ANN%3A%20containers%200.5.9.1&quot; class=&quot;btn&quot; title=&quot;Share on Facebook&quot; target=&quot;_blank&quot;&gt;Facebook&lt;/a&gt;
&lt;a href=&quot;https://plus.google.com/share?url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F111227.html&quot; class=&quot;btn&quot; title=&quot;Share on Google+&quot; target=&quot;_blank&quot;&gt;Google+&lt;/a&gt;
&lt;a href=&quot;http://www.tumblr.com/share/link?url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F111227.html&amp;amp;name=ANN%3A%20containers%200.5.9.1&quot; class=&quot;btn&quot; title=&quot;Share on Tumblr&quot; target=&quot;_blank&quot;&gt;Tumblr&lt;/a&gt;
&lt;a href=&quot;http://wordpress.com/press-this.php?u=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F111227.html&amp;amp;t=ANN%3A%20containers%200.5.9.1&amp;amp;s=&quot; class=&quot;btn&quot; title=&quot;Share on WordPress&quot; target=&quot;_blank&quot;&gt;WordPress&lt;/a&gt;
&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=111227&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/111227.html</comments>
  <category>code release</category>
  <category>haskell planet</category>
  <category>haskell</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/110597.html</guid>
  <pubDate>Tue, 15 Nov 2016 09:53:08 GMT</pubDate>
  <title>Three ineffectual strategies for dealing with trauma and pain</title>
  <link>https://winterkoninkje.dreamwidth.org/110597.html</link>
  <description>&lt;p&gt;The last week has been challenging for all of us. In the depths of my own fear and uncertainty, I reached for one of my favorite books —Pema Chödrön’s &lt;i&gt;Comfortable with Uncertainty&lt;/i&gt;— and opened to a passage at random. On friday, a friend of mine asked how I’ve been able to deal with it all. I told him about the passage, and he (a non-buddhist) found it helpful in dealing with his own pain, so I wanted to share more broadly.&lt;/p&gt;

&lt;p&gt;Before getting to the passage, I think it’s important for people to recognize that this pain we are feeling is a collective &lt;i&gt;trauma&lt;/i&gt;. This is not our day-to-day pain, not our usual suffering. Everyone develops habits and skills for addressing the typical discomforts of life, but those skills are often inapplicable or ineffective for recovering from truly traumatic events. When someone is in a car wreck, or attacked, or raped, or abruptly loses a job or loved one— we recognize these things as traumas. We recognize that these events take some extra work to recover from. In the aftermath of the election I have seen many of the symptoms of trauma in the people around me. Depression, hypervigilance, difficulty concentrating, short tempers, and so on. When trauma hits, our usual coping mechanisms often fail or go haywire. A drink or two to unwind, turns into bleary drunkenness every night. Playing games to let go, turns into escapism to avoid thinking. Solitude, turns into reclusion. A healthy skepticism, turns into paranoia. If we do not recognize traumas for what they are, it becomes all too easy to find ourselves with even worse problems. Recognition is necessary for forming an appropriate response.&lt;/p&gt;

&lt;p&gt;Now, the passage. As humans we have three habitual methods for relating to suffering. All three are ineffectual at reducing that suffering. These three ineffectual strategies are: attacking, indulging, and ignoring. And I’ve seen all three in great quantities in all the OpEd pieces floating around over the past week.&lt;/p&gt;

&lt;p&gt;By “attacking” Pema Chödrön means not just lashing out, attacking Trump’s supporters or their ideals, but also all the ways we attack ourselves: We condemn ourselves, criticize ourselves for any indulgence, pity ourselves to the point of not getting out of bed. This strategy shows up in all those articles criticizing us for not having interpreted the polls correctly, or chastising us for not voting, or condemning the way the internet has formed these echo-chamber bubbles, and so on. But all this self-flagellation, all this beating ourselves up, does nothing to heal our pain. Now we suffer not only from our fears of what’s to come, but also because “it’s all our fault”. We refuse to “let ourselves off easy”, so whenever someone tries to address our pain we attack them and beat them away, protecting our pain because we feel like we deserve it.&lt;/p&gt;

&lt;p&gt;Indulging is just as common. Though we are haunted by self-doubt, we condone our behavior. We say “I don’t deserve this discomfort. I have plenty of reasons to be angry or sleep all day.” We justify our pain to the point of turning it into a virtue and applauding ourselves. This strategy shows up in all those articles that relish in the details of how bad things will become, or congratulating ourselves for saying something like this would happen. But again, by cherishing our pain and presenting it as something to be praised, we are preventing ourselves from healing. Noone wants to give up something they cherish, nor give up on all the attention and sympathy they are lavished with.&lt;/p&gt;

&lt;p&gt;Ignoring is no less common. “Ignoring” means not just refusing to acknowledge our pain and fear, but also pretending it doesn’t exist, dissociating, spacing out, going numb, acting on autopilot, or any of the other ways to try to keep our suffering out of sight and out of mind. This strategy is advocated by all those articles talking about how things actually aren’t that bad, or how this is just business as usual, or how it’ll all get better once the mid-term elections happen. While ignoring seems effective in the short term, it does nothing to address the suffering you feel. In addition to not healing that initial wound, it creates more pain as we inevitably force ourselves into tighter and tighter spaces in order to keep it out of mind.&lt;/p&gt;

&lt;p&gt;There is an alternative to these three futile strategies. The enlightened strategy is to try fully experiencing whatever you’ve been resisting— without exiting in your habitual way. Become inquisitive about your habits. Recognize when you are pushing your suffering away, or embracing it, or denying it. Become inquisitive about your suffering. What is it, exactly, that you are denying? Why does it feel so urgent to push it away? Why does it feel so necessary to cling to it? Stop trying to justify your feelings, stop trying to explain them. Start instead to look at them, to see them for what they really are. Ask why it is they hurt, what part of your ego they compromise, what ideals they belie.&lt;/p&gt;

&lt;p&gt;The passage on the three futile strategies follows a koan about “heaven and hell”. From a buddhist perspective, “hell” is not a place, it is all the feelings of pain and fear and suffering we experience. Nor is “heaven” a place, but rather all our feelings of gratitude and joy and understanding. Thus, the buddhist does not say “hell is bad and heaven is good” nor “get rid of hell and just seek heaven”. Rather, one should approach all things with an open mind, greeting both heaven and hell with that openness. In her words,&lt;/p&gt;

&lt;p&gt;&lt;blockquote&gt;Only with this kind of equanimity can we realize that no matter what comes along, we’re always standing in the middle of a sacred space. Only with equanimity can we see that everything that comes into our circle has come to teach us what we need to know.&lt;/blockquote&gt;&lt;/p&gt;

&lt;p&gt;I find these words powerfully healing. It is healing to remember that no matter where we are or what befalls us, our life is a blessing, and in virtue of that blessing our bodies and the places we move through are sacred spaces. The sacred is not something which exists without us, but something which is created from within. Moreover, it is healing to step away from questions like “what did I do to deserve this?” and instead remember to ask what it is we can learn from the experience.&lt;/p&gt;

&lt;p&gt;I have endured many traumas in my life, and I half expected the election outcome, but still it felt like a kick in the chest. This wound brought back all my darkest habits. Once I recovered from the shock enough to begin the rituals of healing and self-care, I reflected on the question of why this particular wound hurt so bad. In my experience (and not just because I’m buddhist), deep emotional pain always stems from some threat to one’s ego; so what part of my ego is on the line? For me, the reason the election hurt so much is because I had become complacent in believing that the world is steadily becoming a more just place and believing that people are by-and-large fundamentally good. With the election of Obama, the passing of the ACA, the supreme court ruling on Obergefell v. Hodges, and so on, I think a lot of us on the progressive side have been susceptible to those beliefs. The election hurt so much, for me, because it forced the recognition that it’s not just the legacy of systemic institutionalized hatred we must fight, but that over a quarter of the population &lt;i&gt;actively&lt;/i&gt; supports the worst extremes of that hatred. Yes, the election itself was offensive. Yes, I fear for my life and the lives of those close to me. But the real root of the pain itself, the reason it hurt &lt;i&gt;so bad&lt;/i&gt;, is this refutation of those optimistic beliefs about humanity and the path towards justice. Realizing that this was the root cause of my pain did a lot to help me process it and move on. It also gave a healthy way to shift focus from the pain itself, to something actionable. Having experienced the pain, I can accept it. And having learned what it has to teach me, I know what I must do.&lt;/p&gt;

&lt;p&gt;So sit with your pain, and try to experience it fully. Stop pushing it away. Stop embracing it. Stop beating yourself up over it. Approach it with an open mind and let it pass through you. And, finally, ask yourself what you can learn from it.&lt;/p&gt;

&lt;div class=&quot;btn-group&quot;&gt;
&lt;a href=&quot;https://twitter.com/share?text=Three%20ineffectual%20strategies%20for%20dealing%20with%20trauma%20and%20pain&amp;amp;url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F110597.html&amp;amp;via=wrengr&quot; class=&quot;btn&quot; title=&quot;Share on Twitter&quot; target=&quot;_blank&quot;&gt;Twitter&lt;/a&gt;
&lt;a href=&quot;https://www.facebook.com/sharer/sharer.php?u=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F110597.html&amp;amp;t=Three%20ineffectual%20strategies%20for%20dealing%20with%20trauma%20and%20pain&quot; class=&quot;btn&quot; title=&quot;Share on Facebook&quot; target=&quot;_blank&quot;&gt;Facebook&lt;/a&gt;
&lt;a href=&quot;https://plus.google.com/share?url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F110597.html&quot; class=&quot;btn&quot; title=&quot;Share on Google+&quot; target=&quot;_blank&quot;&gt;Google+&lt;/a&gt;
&lt;a href=&quot;http://www.tumblr.com/share/link?url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F110597.html&amp;amp;name=Three%20ineffectual%20strategies%20for%20dealing%20with%20trauma%20and%20pain&quot; class=&quot;btn&quot; title=&quot;Share on Tumblr&quot; target=&quot;_blank&quot;&gt;Tumblr&lt;/a&gt;
&lt;a href=&quot;http://wordpress.com/press-this.php?u=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F110597.html&amp;amp;t=Three%20ineffectual%20strategies%20for%20dealing%20with%20trauma%20and%20pain&amp;amp;s=&quot; class=&quot;btn&quot; title=&quot;Share on WordPress&quot; target=&quot;_blank&quot;&gt;WordPress&lt;/a&gt;
&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=110597&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/110597.html</comments>
  <category>critical praxis</category>
  <category>haskell planet</category>
  <category>racism</category>
  <category>non/violence</category>
  <category>buddhism</category>
  <category>america the beautiful</category>
  <lj:security>public</lj:security>
  <lj:reply-count>1</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/110221.html</guid>
  <pubDate>Fri, 16 Sep 2016 04:39:15 GMT</pubDate>
  <title>Visiting Nara over the next week</title>
  <link>https://winterkoninkje.dreamwidth.org/110221.html</link>
  <description>&lt;p&gt;I announced this on twitter a while back, but tomorrow I&apos;m flying out to Nara Japan. I&apos;ll be out there all week for ICFP and all that jazz. It&apos;s been about a decade since last time I was in the Kansai region, and I can&apos;t wait. &lt;a href=&quot;http://winterkoninkje.dreamwidth.org/tag/traveling&quot;&gt;As I&apos;ve done in the past&lt;/a&gt;, if you want to meet up for lunch or dinner, just comment below (or shoot me a tweet, email, etc).&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=110221&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/110221.html</comments>
  <category>haskell planet</category>
  <category>traveling</category>
  <category>work</category>
  <lj:security>public</lj:security>
  <lj:reply-count>1</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/109574.html</guid>
  <pubDate>Thu, 23 Jun 2016 20:43:11 GMT</pubDate>
  <title>Self-improvement goals, overcoming perfectionism, and dissertating</title>
  <link>https://winterkoninkje.dreamwidth.org/109574.html</link>
  <description>&lt;p&gt;This year&apos;s self-improvement goal was to get back into blogging regularly. Part of that goal was just to get back into &lt;em&gt;writing&lt;/em&gt; regularly; the other part was specifically to publish more regularly.&lt;/p&gt;

&lt;p&gt;I&apos;ve done fairly well on the first half, actually. I&apos;d hoped to do better, but then all year I&apos;ve had to deal with spoon-draining circumstances, so I&apos;ve probably done about as well as I can without sacrificing my health. One of my other self-improvement goals has been to take my health seriously, to listen to my body rather than pushing it beyond its limits. I&apos;m on-track for improving at both of these, I just need to stop beating myself up over it.&lt;/p&gt;

&lt;p&gt;For the second half, the publishing bit, that I&apos;ve done poorly. I&apos;d like to blame the spoon vortex here too, but really I think the biggest problem is my perfectionism. Perfectionism greatly amplifies the problem of lacking spoons: both the editing itself, as well as the emotional fallout of missing the mark or of having taken the entire day to hit it, both of these cost spoons. The real aim behind my goal to publish regularly wasn&apos;t to have more words to my name, but rather to “get out there” more, to be more productive in-and-of-itself rather than to have more products. So I&apos;ve started thinking: the real target for this self-improvement goal should not be publishing regularly, but rather should be (working to) overcome perfectionism.&lt;/p&gt;

&lt;p&gt;If &lt;a href=&quot;http://www.everup.com/2016/05/26/overcome-your-perfectionism/&quot;&gt;perfectionism is a problem of fear&lt;/a&gt;, then the thing I must address is that fear. So how to do it? One of the suggestions in that article is to let yourself fail. Not to lower your unreasonable standards (the party-line for what to do), but rather to allow yourself to not meet those standards. One of my standards is to be thought provoking, and hence to focus overmuch on essays. To try and break free from this, I&apos;m thinking to start posting summaries of my daily dissertation progress. A nanowrimo sort of thing, though without the focus on word-count per se. I&apos;ve read a few articles suggesting one should start their day by summarizing the previous day&apos;s progress, but I&apos;ve never tried it. So &lt;a href=&quot;http://winterkoninkje.dreamwidth.org/tag/dissertating&quot;&gt;here goes nothing&lt;/a&gt; :)&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=109574&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/109574.html</comments>
  <category>self-improvement</category>
  <category>grad school</category>
  <category>dissertating</category>
  <category>haskell planet</category>
  <category>perfectionism</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/109368.html</guid>
  <pubDate>Wed, 15 Jun 2016 07:32:52 GMT</pubDate>
  <title>Off to NYC for July 4th and LICS</title>
  <link>https://winterkoninkje.dreamwidth.org/109368.html</link>
  <description>&lt;p&gt;Over the last few weeks I was &lt;a href=&quot;https://theidentityfunction.wordpress.com/2016/06/10/wren-romano/&quot;&gt;interviewed for the Identity Function&lt;/a&gt;. The process was quite nice and got me thinking on a number of things. Some of them I may well flesh out into blog posts once I get the time. Of course, that likely won&apos;t be until the autumn given everything else going on the next couple months.&lt;/p&gt;

&lt;p&gt;I&apos;ll be in &lt;b&gt;&lt;i&gt;New York from 28 June through 10 July&lt;/i&gt;&lt;/b&gt;. The first couple days are for a PI meeting, then I&apos;ll get a four-day weekend before LICS, NLCS, and LOLA. Originally the plan was to take a quick trip to Sacramento that weekend for a friend&apos;s wedding. (The wedding&apos;s still on, but plans changed.) At least this way I&apos;ll get a chance to relax, rather than running all over the place. Of course this also means I&apos;ll be spending the 4th in NYC. Historically the 4th has been one of my favorite holidays, because it was one I&apos;ve always spent with friends. I don&apos;t know that any of my readers are in NYC, but if you&apos;ll be around drop me a line. Or if you used to live there and know fun things to do that weekend, let me know! (Especially any quiet end-of-Pride things.)&lt;/p&gt;

&lt;p&gt;Me and L set the date for our final move to the Bay Area: 20 July. And then I start at Google on the 25th. Between now and then: dissertating!!&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=109368&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/109368.html</comments>
  <category>traveling</category>
  <category>work</category>
  <category>haskell planet</category>
  <category>grad school</category>
  <lj:security>public</lj:security>
  <lj:reply-count>1</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/108348.html</guid>
  <pubDate>Wed, 27 Apr 2016 22:08:05 GMT</pubDate>
  <title>Hacking projects over the next few months</title>
  <link>https://winterkoninkje.dreamwidth.org/108348.html</link>
  <description>&lt;p&gt;Life’s been really hectic lately, but I’ve been getting (slowly) back into working on my Haskell packages. In particular, since the switch from darcs to github I’ve started getting more comments and feature requests, which is nice. Over the next half-year or so, here’s what I’ll be up to in my free time between work on the dissertation and work on &lt;a href=&quot;https://github.com/hakaru-dev/hakaru&quot;&gt;Hakaru&lt;/a&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/haskell/containers&quot;&gt;&lt;b&gt;&lt;i&gt;containers&lt;/i&gt;&lt;/b&gt;&lt;/a&gt; — I’ve been appointed one of the new co-maintainers of our favorite venerable library. I prolly won’t be doing any major work until autumn (as mentioned when I was appointed), but I’ve had a number of conversations with David Feuer about where to take things in terms of cleaning up some old maintenance cruft.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/wrengr/bytestring-trie&quot;&gt;&lt;b&gt;&lt;i&gt;bytestring-trie&lt;/i&gt;&lt;/b&gt;&lt;/a&gt; — A few years back I started reimplementing my tries to use Bagwell’s Array Mapped Tries in lieu of Okasaki’s Big-Endian Patricia Tries, but then got stalled because life. I’ve started up on it again, and it’s just about ready to be released after a few more tweaks. Also, now that I’m working on it again I can finally clear out the backlog of API requests (sorry folks!).&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/wrengr/exact-combinatorics&quot;&gt;&lt;b&gt;&lt;i&gt;exact-combinatorics&lt;/i&gt;&lt;/b&gt;&lt;/a&gt; — A user recently pointed me towards a new fast implementation of factorial making waves lately. It’s not clear just yet whether it’ll be faster than the current implementation, but should be easy enough to get going and run some benchmarks.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/wrengr/unification-fd&quot;&gt;&lt;b&gt;&lt;i&gt;unification-fd&lt;/i&gt;&lt;/b&gt;&lt;/a&gt; — This one isn’t hacking so much as dissemination. I have a backlog of queries about why things are the way they are, which I need to address; and I’ve been meaning to continue the &lt;a href=&quot;http://winterkoninkje.dreamwidth.org/100478.html&quot;&gt;tutorial&lt;/a&gt; about how to use this library for your unification needs.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/wrengr/logfloat&quot;&gt;&lt;b&gt;&lt;i&gt;logfloat&lt;/i&gt;&lt;b&gt;&lt;/b&gt;&lt;/b&gt;&lt;/a&gt; — We’ve been using this a lot in Hakaru, and there are a few performance tweaks I think I can add. The main optimization area is trying to minimize the conditionals for detecting edge cases. The biggest issue has just been coming up with some decent benchmarks. The problem, of course, is that most programs making use of logfloats do a lot of other work too so it can be tricky to detect the actual effect of changes. I think this is something Hakaru can help a lot with since it makes it easy to construct all sorts of new models.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=108348&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/108348.html</comments>
  <category>haskell</category>
  <category>coding</category>
  <category>haskell planet</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/108092.html</guid>
  <pubDate>Mon, 25 Apr 2016 00:12:55 GMT</pubDate>
  <title>Quantifiers in type theory</title>
  <link>https://winterkoninkje.dreamwidth.org/108092.html</link>
  <description>&lt;p&gt;All this stuff is &quot;well known&quot;, but I want to put it out there for folks who may not have encountered it, or not encountered it all together in one picture.&lt;/p&gt;

&lt;p&gt;The Damas–Hindley–Milner type system (i.e., the type system that Algorithm W is inferring types for) is propositional logic extended with &lt;b&gt;&lt;i&gt;rank-1 second-order universal&lt;/i&gt;&lt;/b&gt; quantifiers. It is interesting because it is so particularly stable with respect to inference, decidability, etc. That is, we can come up with many other algorithms besides Algorithm W and they enjoy nice properties like the fact that adding type signatures won&apos;t cause inference to fail. (It&apos;s worth noting, that Algorithm W is DEXPTIME-complete; so while in practice it&apos;s often linear time, for pathological inputs it can take exponentially long. However, if we put a constant bound on the depth of nested let-bindings, then the upper bound becomes polynomial.)&lt;/p&gt;

&lt;p&gt;The extension of DHM with &lt;b&gt;&lt;i&gt;rank-1 second-order existential&lt;/i&gt;&lt;/b&gt; quantifiers is strictly more powerful. It is interesting because it allows unrestricted use of both of the quantifiers in prenex position; thus, it is the limit/top of the alternating quantifier hierarchy (à la the arithmetical hierarchy) that starts with DHM. Surely there are other interesting properties here, but this system is understudied relative to the ones above and below. &lt;i&gt;Edit:&lt;/i&gt; Although GHC gets by with encoding existentials away, it&apos;s worth noting that MLF allows existentials where the unpacking is implicit rather than requiring an &quot;unseal&quot; or case eliminator &lt;a href=&quot;http://research.microsoft.com/en-us/um/people/daan/download/papers/existentials.pdf&quot;&gt;(Leijen 2006)&lt;/a&gt;; and also that UHC does in fact offer first-class existentials &lt;a href=&quot;http://dspace.library.uu.nl/bitstream/handle/1874/7352/full.pdf?sequence=8&quot;&gt;(Dijkstra 2005)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The extension with &lt;b&gt;&lt;i&gt;rank-2 second-order universals&lt;i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/b&gt; (i.e., where the universal quantifier can appear to the left of one function arrow) is strictly more powerful still. Here we can encode rank-1 existentials, but my point in this whole post is to point out that rank-1 existentials themselves are strictly weaker than the rank-2 universals it takes to encode them! Also, one little-known fact: this type system is interesting because it is the last one in this progression where type inference is decidable &lt;a href=&quot;http://www.cs.bu.edu/techreports/1993-017-finite-rank.ps.Z&quot;&gt;(Kfoury &amp; Wells 1993)&lt;/a&gt;. The decidability of rank-2 universal quantification is part of the reason why GHC distinguishes between &lt;code&gt;-XRank2Types&lt;/code&gt; vs &lt;code&gt;-XRankNTypes&lt;/code&gt;. Alas, although inference is decidable —and thus of mathematical interest— it is not decidable in the same robust way that DHM is. That is, if we care about human factors like good error messages or not breaking when the user adds type signatures, then we don&apos;t get those properties here. Still, the fact that this system is at the cusp of decidable inference is important to know. &lt;i&gt;Edit:&lt;/i&gt; Also of interest, this system has the same typeable terms as simply-typed λ-calculus with &lt;b&gt;&lt;i&gt;rank-2 intersection types&lt;/i&gt;&lt;/b&gt;, and the type inference problem here is fundamentally DEXPTIME-complete &lt;a href=&quot;http://publications.csail.mit.edu/lcs/pubs/pdf/MIT-LCS-TM-531b.pdf&quot;&gt;(Jim 1995)&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Things keep alternating back and forth between existentials and universals of each rank; so far as I&apos;m aware, none of these systems are of any particular interest until we hit the limit: &lt;b&gt;&lt;i&gt;rank-ω (aka: rank-N) second-order quantification&lt;i&gt;&lt;/i&gt;&lt;/i&gt;&lt;/b&gt;. This type system is often called &quot;System F&quot;, but that&apos;s a misnomer. It is important to differentiate between the syntactic system (i.e., actual System F) we&apos;re inferring types for, vs the type system (aka: propositional logic with second-order quantifiers) in which the inferred types live. That is, we can perfectly well have a syntactic system which doesn&apos;t have explicit type abstractions/applications but for which we still ascribe rank-ω types. It so happens that the type inference problem is undecidable for that syntactic system, but it was already undecidable way back at rank-3 so the undecidability isn&apos;t particularly novel.&lt;/p&gt;


&lt;div class=&quot;btn-group&quot;&gt;
&lt;a href=&quot;https://twitter.com/share?text=Quantifiers%20in%20type%20theory&amp;amp;url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F108092.html&amp;amp;via=wrengr&quot; class=&quot;btn&quot; title=&quot;Share on Twitter&quot; target=&quot;_blank&quot;&gt;Twitter&lt;/a&gt;
&lt;a href=&quot;https://www.facebook.com/sharer/sharer.php?u=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F108092.html&amp;amp;t=Quantifiers%20in%20type%20theory&quot; class=&quot;btn&quot; title=&quot;Share on Facebook&quot; target=&quot;_blank&quot;&gt;Facebook&lt;/a&gt;
&lt;a href=&quot;https://plus.google.com/share?url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F108092.html&quot; class=&quot;btn&quot; title=&quot;Share on Google+&quot; target=&quot;_blank&quot;&gt;Google+&lt;/a&gt;
&lt;a href=&quot;http://www.tumblr.com/share/link?url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F108092.html&amp;amp;name=Quantifiers%20in%20type%20theory&quot; class=&quot;btn&quot; title=&quot;Share on Tumblr&quot; target=&quot;_blank&quot;&gt;Tumblr&lt;/a&gt;
&lt;a href=&quot;http://wordpress.com/press-this.php?u=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F108092.html&amp;amp;t=Quantifiers%20in%20type%20theory&amp;amp;s=&quot; class=&quot;btn&quot; title=&quot;Share on WordPress&quot; target=&quot;_blank&quot;&gt;WordPress&lt;/a&gt;
&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=108092&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/108092.html</comments>
  <category>logic</category>
  <category>columbicubiculomania</category>
  <category>haskell planet</category>
  <category>type theory</category>
  <lj:security>public</lj:security>
  <lj:reply-count>2</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/107732.html</guid>
  <pubDate>Thu, 07 Apr 2016 07:09:30 GMT</pubDate>
  <title>Dissertating, ahoy!</title>
  <link>https://winterkoninkje.dreamwidth.org/107732.html</link>
  <description>&lt;p&gt;Usually whenever we think about gradschool we think about the switch from &quot;doing classwork, quals, etc&quot; to &quot;dissertating&quot; is a single-step process, which we call &quot;becoming a PhD candidate&quot; (as opposed to being a PhD &lt;i&gt;student&lt;/i&gt;). In practice there are over half a dozen steps. Filing the paperwork declaring your completion of classwork, quals, etc is just the first few. (Okay, easy enough) Then there&apos;s the prospectus, for the graduate school. (The what for the who now?) Then the forming of your research committee. (Right, okay) Then the proposal. (Wait, how is this different from the other thing?) Then the proposal defense. (Um, okay, but not every department requires this?) Plus a few other steps I&apos;m surely forgetting.&lt;/p&gt;

&lt;p&gt;As of yesterday, I am officially finally totally completely absolutely done with all the paperwork, and can finally get back to actually working on the thesis itself!&lt;p&gt;&lt;/p&gt;&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=107732&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/107732.html</comments>
  <category>grad school</category>
  <category>haskell planet</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/106088.html</guid>
  <pubDate>Wed, 03 Feb 2016 06:43:07 GMT</pubDate>
  <title>It&apos;s official, I&apos;m off to Google</title>
  <link>https://winterkoninkje.dreamwidth.org/106088.html</link>
  <description>&lt;p&gt;It&apos;s official, I&apos;m heading to Google at the end of July to work with Mark Larson on the Chrome OS security team (of all things!). Seems an unlikely match, but Mark was pretty keen on my background (including the gender stuff!) and wasn&apos;t put off by my fusion of linguistics, type-theory, constructive logic/maths, et al. I guess the security team is more concerned with semantic models and constructive correctness than the other teams I talked with. Makes sense, I suppose, but it&apos;s sad that these are still thought of as &quot;security&quot; concerns rather than &quot;everything in programming&quot; concerns.&lt;/p&gt;

&lt;p&gt;I&apos;m totally looking forward to it, but I am still thinking of it as a bit of an experiment. I&apos;m an academic at heart, so I could see myself heading back to academia in a few years. (Wanting to be a professor is, afterall, what motivated me to start gradschool in the first place.) Then again, I&apos;ve never really thought of industry as being interested in the sorts of theory I work on. In any case, I&apos;ll still be around at the various conferences I&apos;ve been frequenting; I won&apos;t just disappear into industry.&lt;/p&gt;

&lt;p&gt;I know a bunch of y&apos;all are in the bay area. I&apos;d love to hear any pointers you have on apartment hunting or on what neighborhoods (nearish Mt View) are nice— i.e., places an artistic disabled radical queer woman might like. Feel free to comment below or get in touch by email, twitter, etc.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=106088&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/106088.html</comments>
  <category>haskell planet</category>
  <category>grad school</category>
  <category>work</category>
  <lj:security>public</lj:security>
  <lj:reply-count>3</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/105646.html</guid>
  <pubDate>Wed, 27 Jan 2016 05:35:46 GMT</pubDate>
  <title>Finding hope</title>
  <link>https://winterkoninkje.dreamwidth.org/105646.html</link>
  <description>&lt;p&gt;Many of us with disabilities have more than one. This multiplicity is invisiblized by the abled community. When our lives are already assumed to be defined by disability, admitting multiplicity risks the hazard of letting the complexities of disabled lives enter one&apos;s mind. But even among the disabled, there&apos;s a tendency to focus on the one or two things which most obviously impact our lives. This is a coping mechanism. To cope with lacking spoons, we are always prioritizing our energies, and there is never enough to solve all the things. But also, ableism being what it is, we must be careful never to &quot;complain too much&quot; lest we loose whatever ears we&apos;ve gained; so we consign our suffering to silence, that we might grasp at crumbs of compassion for hope that when things worsen there may still be someone who&apos;ll listen.&lt;/p&gt;

&lt;p&gt;I have my &quot;one or two things&quot;: &lt;a href=&quot;http://winterkoninkje.dreamwidth.org/tag/depression+is+a+state+of+living&quot;&gt;depression&lt;/a&gt; and &lt;a href=&quot;http://winterkoninkje.dreamwidth.org/tag/cptsd&quot;&gt;cPTSD&lt;/a&gt;. And I&apos;ve mentioned my migraines on occasion, though they&apos;re seldom of bloggable interest. But there&apos;s one I&apos;ve never talked about, one I&apos;ve still not come to terms with myself. That&apos;s the thing about chronic pain. Noone ever teaches us about all the things that shouldn&apos;t hurt, about all the pains most people don&apos;t have. And consequently we come to normalize them, to unsee the ways they make us choose —in small ways at first— to restrict our lives. Last week I met a fabulous girl and we got to talking about disability. And with one sentence she cut through me like a &lt;a href=&quot;https://en.wikipedia.org/wiki/Diamond_Sutra#Title&quot;&gt;thunderbolt&lt;/a&gt;, cut through a silence I hadn&apos;t even realized I&apos;d been spinning for years. Her words, so simple:&lt;/p&gt;

&lt;p&gt;&lt;i&gt;I have a connective tissue disease&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;I&apos;ve suspected it for a couple decades, known it for nearly a decade, but it&apos;s never been something I&apos;ve been allowed to talk about. When a teen complains about joint pain, it is dismissed as an insignificance. When a twentysomething does, everyone older jests and jeers; &quot;just wait till you&apos;re my age,&quot; they say. Sit down. Shut up. Respect your elders. If you&apos;re resilient enough to keep at it, to endure the shame and go to a doctor... well, doctors have ways of silencing things they can&apos;t cure. When I first saw a doctor for my knees, he acted like it was nothing, like I was a stupid kid bitching about nothing— despite saying, with surprise in his voice, how my x-rays looked like someone 15–20 years older. When I pressed, when I refused to be cowed, he told me there was nothing modern science could do: I could use a splint, but that&apos;d weaken the muscles and exacerbate the problem; I could try working out to strengthen the muscles —at least, for as long as I could stand the pain— but that&apos;d only slow the inevitable by a couple years at best; it wasn&apos;t bad enough for surgery, besides that&apos;d just cause even more damage. &quot;You&apos;re young,&quot; he said in flat monotone, like words rehearsed without meaning. Like pointing out something broken or left behind, when you really don&apos;t care if they hear you. Your coffee. Your wallet. Your tail light. You&apos;re young.&lt;/p&gt;

&lt;p&gt;The thing about genetic issues is that they pervade everything. It&apos;s never a singular problem, it&apos;s a cascade of them, a death by ten-thousand papercuts. In my childhood, my mother always had issues with her knees. It was almost a joke how often she went in for surgeries on them; the kind of joke people only mumble and noone laughs at but they tell it anyways because they don&apos;t know what else to do. During my early college years, her shoulders started going out. A few years back my sister died spontaneously, and within a few months a cousin joined her. Aortic ruptures. In the last year or so, my mother had an aortic dissection. She survived, but more from luck than anything. I happened to be in Maryland when she was in the hospital, and I visited. She&apos;d also been having catastrophic spinal problems. My parents didn&apos;t even bother mentioning it until she went in for the first surgery. It didn&apos;t go well. Three followup surgeries later and who knows if any of it did any good. Sitting next to her as she lay in that bed, her hands all locked up in pain, held in mine, I could barely look on her. Because I know I&apos;ll live to be crippled and die twisted in pain. She&apos;s had enough in-patient PT to be released, and is back home now on out-patient PT. Noone talks about it. But at least noone jokes anymore.&lt;/p&gt;

&lt;p&gt;I can&apos;t say if it was her heart or her back that somehow managed to convince some doctor to take a closer look. He&apos;d thought she had Marfan syndrome and ordered a genetic screening. Tests came back negative. Followups found it&apos;s actually &lt;a href=&quot;https://en.wikipedia.org/wiki/Loeys–Dietz_syndrome&quot;&gt;Loeys-Dietz&lt;/a&gt;, something that wasn&apos;t even discovered until ten years ago, and the docs only knew of it because she&apos;d been admitted to the hospital where they discovered it. There&apos;s no point in testing the dead, but there&apos;s little doubt about what did my sister and cousin in. I&apos;ve been checked for aortic problems, and show no symptoms as yet. I&apos;ll have to get checked again every couple years.&lt;/p&gt;

&lt;p&gt;(One of the funniest things about transitioning is how it&apos;s been the healthiest decision I&apos;ve ever made. If I&apos;d&apos;ve known all the minor health issues it&apos;d cure, I would&apos;ve fought harder to do it when I was 18. Among the things it helped was my back. While uncommon, HRT can cause corrections in one&apos;s hips and lower ribs. Thanks to the changes in my hips and my center of gravity, I no longer have chronic back pain. Growing up I could never attain correct posture: it caused pain and felt unnatural; whereas now it comes freely and without thinking.)&lt;/p&gt;

&lt;p&gt;But the litany of little pains isn&apos;t what hurts the most. I used to draw. It used to be my life. The fire in my heart, as maths is the breath in my chest. I&apos;d do it when I wasn&apos;t thinking. I&apos;d do it to focus my thinking. I&apos;d come home and spend hours at it. I&apos;d ignore eating to finish a piece. I won awards. I thought I&apos;d make a vocation of it. By halfway through undergrad I could barely finish a small sketch in the margins of my notes. Many of my friends are artists (&lt;a href=&quot;http://helper-robots.com&quot;&gt;e.g.&lt;/a&gt;), and while I love their work, a hateful demon grows in me every time I see their successes or hear them praised. These days I can barely hold a pencil. My script an ever more illegible shorthand as I try to eke out a few more pages before I resign to sitting behind a computer. (The most creative parts of doing math, for me, needs being written. It is only once I have the sketch of a thing can I put it to pixels.) Just bringing up my art, acknowledging it as something lost rather than as something I lost time for, crushes me.&lt;/p&gt;

&lt;p&gt;That girl, that blessed fabulous girl. A few days after we&apos;d met I asked her about her ring, a beautiful curious thing, like two rings locked together at an angle. Turns out it&apos;s a surgical splint for preventing hyperextension. She told me &lt;a href=&quot;http://www.silverringsplint.com&quot;&gt;where to get one&lt;/a&gt;, and on the bus yesterday I decided to check out their website. Reading through the descriptions of the rings they offer —I don&apos;t even... How do you name that emotion when a pain you&apos;ve had so long you&apos;ve forgotten it exists is suddenly eased, that lift, that release, that letting go. Like when you find someone who shares your very same marginalization, that feeling where you can just talk, can let words free without censor knowing they have already been understood before they are spoken. That sudden finding oneself not alone. That slow creeping into existence of a future worth looking toward. I had to turn off my browser. Can&apos;t be crying on busses. Can&apos;t be weak in public.&lt;/p&gt;


&lt;div class=&quot;btn-group&quot;&gt;
&lt;a href=&quot;https://twitter.com/share?text=I%20know%20I%27ll%20live%20to%20be%20crippled%20and%20die%20twisted%20in%20pain&amp;amp;url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F105646.html&amp;amp;via=wrengr&quot; class=&quot;btn&quot; title=&quot;Share on Twitter&quot; target=&quot;_blank&quot;&gt;Twitter&lt;/a&gt;
&lt;a href=&quot;https://www.facebook.com/sharer/sharer.php?u=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F105646.html&amp;amp;t=I%20know%20I%27ll%20live%20to%20be%20crippled%20and%20die%20twisted%20in%20pain&quot; class=&quot;btn&quot; title=&quot;Share on Facebook&quot; target=&quot;_blank&quot;&gt;Facebook&lt;/a&gt;
&lt;a href=&quot;https://plus.google.com/share?url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F105646.html&quot; class=&quot;btn&quot; title=&quot;Share on Google+&quot; target=&quot;_blank&quot;&gt;Google+&lt;/a&gt;
&lt;a href=&quot;http://www.tumblr.com/share/link?url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F105646.html&amp;amp;name=I%20know%20I%27ll%20live%20to%20be%20crippled%20and%20die%20twisted%20in%20pain&quot; class=&quot;btn&quot; title=&quot;Share on Tumblr&quot; target=&quot;_blank&quot;&gt;Tumblr&lt;/a&gt;
&lt;a href=&quot;http://wordpress.com/press-this.php?u=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F105646.html&amp;amp;t=I%20know%20I%27ll%20live%20to%20be%20crippled%20and%20die%20twisted%20in%20pain&amp;amp;s=&quot; class=&quot;btn&quot; title=&quot;Share on WordPress&quot; target=&quot;_blank&quot;&gt;WordPress&lt;/a&gt;
&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=105646&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/105646.html</comments>
  <category>haskell planet</category>
  <category>loeys-dietz</category>
  <category>on the bus</category>
  <category>personal</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/105452.html</guid>
  <pubDate>Sun, 17 Jan 2016 18:34:49 GMT</pubDate>
  <title>A week of &quot;P&quot;s</title>
  <link>https://winterkoninkje.dreamwidth.org/105452.html</link>
  <description>&lt;p&gt;The next week+ I&apos;ll be in St. Petersburg Florida for PEPM, PADL, POPL, PPS, and PPAML PI (also CPP and OBT). Would&apos;ve mentioned it sooner, but it&apos;s a bit of a last minute thing. I love reconnecting with old friends and meeting new folks, so feel free to come say hi. If you want to meet up for dinner or such, leave a comment with when/where to find you, or just look for the tall gal with the blue streak in her hair.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=105452&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/105452.html</comments>
  <category>traveling</category>
  <category>work</category>
  <category>haskell planet</category>
  <category>grad school</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/104698.html</guid>
  <pubDate>Fri, 30 Oct 2015 05:17:27 GMT</pubDate>
  <title>Limitations of strongly-typed ABTs</title>
  <link>https://winterkoninkje.dreamwidth.org/104698.html</link>
  <description>&lt;p&gt;&lt;a href=&quot;http://winterkoninkje.dreamwidth.org/103978.html&quot;&gt;Last time&lt;/a&gt; I talked a bit about ABTs; in particular, I introduced the notion of strongly-typed ABTs (or &quot;GABTs&quot; if you prefer) and showed how we can extend the basic idea of ABTs to guarantee well-typedness in addition to well-aritiedness. However, I also made a note that ensuring this sort of well-typedness runs counter to what Neel and other CMUers often do. One of my colleagues here at IU noticed the reason, so I thought I&apos;d write a bit more about it.&lt;/p&gt;

&lt;p&gt;The issue at stake here is how general we can make our ABT library, to minimize the amount of boilerplate needed whenever inventing a new language. By encoding object-language type systems into the kinding of the ABT, we restrict the the possible object languages we can use the ABT implementation for (namely those object languages with type systems that can be embedded into whatever kinding the ABT has). To put a finer point on it, using the kinds presented in the previous post you cannot have binders in your type system. (&lt;i&gt;Edit 2016.02.29: &lt;span&gt;&lt;a href=&quot;#104698:fn1&quot; name=&quot;104698:fnref1&quot;&gt;actually the details are more complicated&lt;/a&gt;&lt;/span&gt;.&lt;/i&gt;) This means no System F, and no dependent types. This is unfortunate as the whole point of ABTs is to capture binding structure once and for all!&lt;/p&gt;

&lt;p&gt;However, I&apos;d like to reiterate that, for our purposes in Hakaru this limitation is no restriction. Hakaru is simply-typed, so there are no type-level binders in sight. Moreover, we do &lt;em&gt;a lot&lt;/em&gt; of program transformations in Hakaru. By using GABTs we can have GHC verify that our program transformations will never produce Hakaru code which is ill-typed, and that our program transformations will always produce Hakaru code of an appropriate type (e.g., the same type as the input term, for things like partial evaluation; but we have a number of type-changing transformations too). Thus, even though our GABT library could not be reused for implementing languages with type-level binders, it still provides a substantial benefit for those languages without type-level binders.&lt;/p&gt;

&lt;p&gt;Although our GABTs cannot handle type-level binders, that does not mean we&apos;re restricted to only working with simply typed languages. For example, intersection types are not usually thought of as &quot;simple types&quot;; but they do not require binders and so they&apos;re fine. More generally, &lt;a href=&quot;http://www.indiana.edu/~iulg/moss/&quot;&gt;Larry Moss&lt;/a&gt; is engaged in a research project where he asks, &quot;given infinite time, how far could Aristotle have gotten in logic?&quot; By which he means, given the Aristotelian restriction to syllogistic logics (i.e., ones without the quantifiers introduced by Frege), what are the limits in what we can cover? It turns out that we can cover quite a lot. Some syllogistic logics go beyond the power of the &quot;Peano–Frege&quot; boundary: they can handle comparing cardinality of sets! A good pictorial summary of this line of research is on slide 2 of &lt;a href=&quot;http://www.indiana.edu/~iulg/moss/sizes.pdf&quot;&gt;this talk&lt;/a&gt;; and a bit more about the complexity results is given in &lt;a href=&quot;http://www.indiana.edu/~iulg/moss/beyondAristotle.pdf&quot;&gt;this talk&lt;/a&gt; (the requisite picture is on slide 39).&lt;/p&gt;

&lt;hr /&gt;
&lt;p&gt;&lt;a name=&quot;104698:fn1&quot;&gt;&lt;i&gt;Edit 2016.02.29:&lt;/i&gt;&lt;/a&gt; In actuality, there&apos;s nothing inherent in type theory that prohibits having type-level binders for our object language; it&apos;s a limitation in GHC. In particular, GHC doesn&apos;t allow lifting GADTs into data kinds. If we could lift GADTs, then we could simply use ABTs to define the syntax of object-language type expressions, and lift those to serve as the type indices for using ABTs to define the syntax of object-language term expressions. This stratified approach is sufficient to handle System F and any other non-dependent quantifiers. To go further and handle dependent quantifiers as well, we&apos;d also need to be able to define the object-language&apos;s terms and types in a mutually inductive way.&lt;a href=&quot;#104698:fnref1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;

&lt;div class=&quot;btn-group&quot;&gt;
&lt;a href=&quot;https://twitter.com/share?via=wrengr&amp;amp;url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F104698.html&amp;amp;text=Limitations%20of%20strongly-typed%20ABTs&quot; class=&quot;btn&quot; title=&quot;Share on Twitter&quot; target=&quot;_blank&quot;&gt;Twitter&lt;/a&gt;
&lt;a href=&quot;https://www.facebook.com/sharer/sharer.php?u=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F104698.html&amp;amp;t=Limitations%20of%20strongly-typed%20ABTs&quot; class=&quot;btn&quot; title=&quot;Share on Facebook&quot; target=&quot;_blank&quot;&gt;Facebook&lt;/a&gt;
&lt;a href=&quot;https://plus.google.com/share?url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F104698.html&quot; class=&quot;btn&quot; title=&quot;Share on Google+&quot; target=&quot;_blank&quot;&gt;Google+&lt;/a&gt;
&lt;a href=&quot;http://www.tumblr.com/share/link?url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F104698.html&amp;amp;name=Limitations%20of%20strongly-typed%20ABTs&quot; class=&quot;btn&quot; title=&quot;Share on Tumblr&quot; target=&quot;_blank&quot;&gt;Tumblr&lt;/a&gt;
&lt;a href=&quot;http://wordpress.com/press-this.php?u=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F104698.html&amp;amp;t=Limitations%20of%20strongly-typed%20ABTs&amp;amp;s=&quot; class=&quot;btn&quot; title=&quot;Share on WordPress&quot; target=&quot;_blank&quot;&gt;WordPress&lt;/a&gt;
&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=104698&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/104698.html</comments>
  <category>computer science</category>
  <category>haskell</category>
  <category>hakaru</category>
  <category>dependent types</category>
  <category>haskell planet</category>
  <category>design</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/103978.html</guid>
  <pubDate>Mon, 21 Sep 2015 00:40:51 GMT</pubDate>
  <title>Abstract Binding Trees in Hakaru</title>
  <link>https://winterkoninkje.dreamwidth.org/103978.html</link>
  <description>&lt;p&gt;&lt;i&gt;Edit 2015.10.29: Be sure to also read &lt;a href=&quot;http://winterkoninkje.dreamwidth.org/104698.html&quot;&gt;the followup post&lt;/a&gt; on the benefits and limitations of this approach compared to the usual untyped ABTs.&lt;/i&gt;&lt;/p&gt;

&lt;p&gt;Earlier this year Neel Krishnaswami talked about abstract binding trees (ABTs) &lt;a href=&quot;http://semantic-domain.blogspot.co.uk/2015/03/abstract-binding-trees.html&quot;&gt;[part 1]&lt;/a&gt; &lt;a href=&quot;http://semantic-domain.blogspot.co.uk/2015/03/abstract-binding-trees-addendum.html&quot;&gt;[part 2]&lt;/a&gt;. IMO, the best way to think about ABTs is as a generalization of abstract syntax trees (ASTs), though this is not a perspective sanctioned by the CMUers I’ve talked to. CMUers oppose this way of phrasing things, in part, because the ABT libraries they’re familiar with make crucial use of the design pattern of &lt;a href=&quot;http://web.cecs.pdx.edu/~sheard/papers/JfpPearl.ps&quot;&gt;two-level types&lt;/a&gt;; but I think the essential insights of ABTs and two-level types are quite different, and we ought to keep the benefits of these two techniques distinct.&lt;/p&gt;&lt;p&gt;Over the past year I’ve been working on the inferential language&lt;sup&gt;&lt;a href=&quot;#103978:fn1&quot; name=&quot;103978:fnref1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; &lt;a href=&quot;https://github.com/hakaru-dev/hakaru&quot;&gt;Hakaru&lt;/a&gt;, and in the new version of the compiler we’re using ABTs for our syntax trees. However, contrary to Neel’s stance against using strongly-typed internal representations for syntax, we extend the ABT approach to make use of GADTs to guarantee local well-typedness— since this in turn can be used to guarantee that program transformations are also well-typed. (If you don’t want those guarantees, then take a look at Jon Sterling’s &lt;a href=&quot;http://hackage.haskell.org/package/abt&quot;&gt;abt&lt;/a&gt; library on Hackage&lt;sup&gt;&lt;a href=&quot;#103978:fn2&quot; name=&quot;103978:fnref2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;.) In this post I’m going to present a simplified version of our architecture, and then talk about some of the extra stuff bringing it closer to our production architecture.&lt;/p&gt;&lt;h3&gt;First things first&lt;/h3&gt;&lt;p&gt;Since we want everything to be well-typed, we first must introduce some universe, &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;/code&gt;, of all the types in our language. (In Haskell we can implement such a universe by using the &lt;code&gt;-XDataKinds&lt;/code&gt; extension, so I’ll equivocate between calling &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;/code&gt; a “universe” vs a “kind”.) For the rest of this post it doesn’t actually matter what lives in that universe&lt;sup&gt;&lt;a href=&quot;#103978:fn3&quot; name=&quot;103978:fnref3&quot;&gt;3&lt;/a&gt;&lt;/sup&gt;, just so long as things match up when they need to. Since the choice of universe is irrelevant, we could abstract over &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;/code&gt; by turning on the &lt;code&gt;-XPolyKinds&lt;/code&gt; extension; but I avoid doing so below, just to help keep things more concrete.&lt;/p&gt;&lt;h3&gt;Implementing ASTs&lt;/h3&gt;&lt;p&gt;The simplest way of thinking about well-typed ASTs is that they capture the set of terms generated by a (typed) signature; that is, the fixed point of some &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Σ&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;⭑&lt;/span&gt;&lt;/code&gt;. Unpacking the type for &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Σ&lt;/span&gt;&lt;/code&gt;, we have that every syntactic constructor &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;fv&quot;&gt;s&lt;/span&gt; ∈ &lt;span class=&quot;dt&quot;&gt;Σ&lt;/span&gt;&lt;/code&gt; is associated with some arity (the length of the list), each argument to &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;fv&quot;&gt;s&lt;/span&gt;&lt;/code&gt; has some type in &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;/code&gt; (the elements of the list), and applying &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;fv&quot;&gt;s&lt;/span&gt;&lt;/code&gt; to the right number of ASTs of the right types will generate a new AST with some type in &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;/code&gt; (the second argument to &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Σ&lt;/span&gt;&lt;/code&gt;).&lt;/p&gt;&lt;p&gt;To implement this fixed point we define an &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;AST&lt;/span&gt;&lt;/code&gt; type which is parameterized by its signature. To ensure well-aritiedness (and well-typedness) of our ASTs with respect to that signature, we’ll need to introduce a helper type &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;SArgs&lt;/span&gt;&lt;/code&gt;&lt;sup&gt;&lt;a href=&quot;#103978:fn4&quot; name=&quot;103978:fnref4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;. And to ensure that we obtain the &lt;em&gt;least&lt;/em&gt; fixed-point of the signature, we’ll make everything strict.&lt;/p&gt;&lt;div class=&quot;sourceCode&quot;&gt;&lt;pre class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;kw&quot;&gt;infix&lt;/span&gt;  &lt;span class=&quot;dv&quot;&gt;4&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;:$&lt;/span&gt;
&lt;span class=&quot;kw&quot;&gt;infixr&lt;/span&gt; &lt;span class=&quot;dv&quot;&gt;5&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;:*&lt;/span&gt;

&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SArgs&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;⭑&lt;/span&gt;) &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;⭑&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;dc&quot;&gt;End&lt;/span&gt;  &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SArgs&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;ast&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;[]&lt;/span&gt;

    (&lt;span class=&quot;dc&quot;&gt;:*&lt;/span&gt;) &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;!&lt;/span&gt;(&lt;span class=&quot;bv&quot;&gt;ast&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt;)
         &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;!&lt;/span&gt;(&lt;span class=&quot;dt&quot;&gt;SArgs&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;ast&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;us&lt;/span&gt;)
         &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SArgs&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;ast&lt;/span&gt; (&lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;us&lt;/span&gt;)

&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;AST&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;⭑&lt;/span&gt;) &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;⭑&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;
    (&lt;span class=&quot;dc&quot;&gt;:$&lt;/span&gt;) &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;!&lt;/span&gt;(&lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;us&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt;)
         &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;!&lt;/span&gt;(&lt;span class=&quot;dt&quot;&gt;SArgs&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;AST&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt;) &lt;span class=&quot;bv&quot;&gt;us&lt;/span&gt;)
         &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;AST&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3&gt;Implementing ABTs&lt;/h3&gt;&lt;p&gt;The problem with ASTs is that they have no notion of variables, and thus have no notion of variable binding. Naively we could implement binders like lambda-abstraction by having something like &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dc&quot;&gt;λ&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Σ&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;dc&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;dc&quot;&gt;]&lt;/span&gt; (&lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;:→&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;v&lt;/span&gt;)&lt;/code&gt; but then we’d need to do a post-hoc check to ensure that the first argument to &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dc&quot;&gt;λ&lt;/span&gt;&lt;/code&gt; is in fact a variable. To build that check into the datatype itself we’d have to move &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dc&quot;&gt;λ&lt;/span&gt;&lt;/code&gt; into the definition of &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;AST&lt;/span&gt;&lt;/code&gt; (since the first argument is of type &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Variable&lt;/span&gt; &lt;span class=&quot;fv&quot;&gt;u&lt;/span&gt;&lt;/code&gt; rather than &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;AST&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Σ&lt;/span&gt; &lt;span class=&quot;fv&quot;&gt;u&lt;/span&gt;&lt;/code&gt;). If lambda-abstraction were the only binder we had, that might not be so bad; but any real-world language has a plethora of binders, and this approach doesn’t scale.&lt;/p&gt;&lt;p&gt;The essential idea behind ABTs is to abstract over the notion of binding itself. Given a single uniform definition of what it means to be a binding form, we don’t have to worry about adding a bunch of ad-hoc constructors to our AST datatype. Moreover, we can then provide single uniform definitions for things which mess with variables and are homomorphic over the signature. Things like &lt;a href=&quot;http://semantic-domain.blogspot.co.uk/2015/03/abstract-binding-trees.html&quot;&gt;capture-avoiding substitution&lt;/a&gt; and providing a &lt;a href=&quot;http://comonad.com/reader/2014/fast-circular-substitution/&quot;&gt;HOAS API for our first-order representation&lt;/a&gt;.&lt;/p&gt;&lt;p&gt;The crucial step is to adjust our notion of what a signature contains. The basic signatures used above only contained applicative forms; i.e., things we can apply to locally-closed terms; i.e., what are called “functors” in the logic programming community. For ABTs we’ll want to allow our signatures to include any &lt;a href=&quot;http://plato.stanford.edu/entries/generalized-quantifiers/&quot;&gt;generalized quantifier&lt;/a&gt;. That is, our signatures will now be of type &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Σ&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;×&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;⭑&lt;/span&gt;&lt;/code&gt;. Previously, the arguments were indexed by &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;/code&gt;; now, they’re indexed by &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;×&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;/code&gt;. The length of the list gives the number of variables being bound, the types in the list give the types of those variables, and the second component of the pair gives the type of the whole locally-open expression.&lt;/p&gt;&lt;p&gt;To implement this we need to extend our syntax tree to include variable bindings and variable uses:&lt;/p&gt;&lt;div class=&quot;sourceCode&quot;&gt;&lt;pre class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SArgs&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;⭑&lt;/span&gt;) &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;×&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;⭑&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;dc&quot;&gt;End&lt;/span&gt;  &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SArgs&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;abt&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;[]&lt;/span&gt;

    (&lt;span class=&quot;dc&quot;&gt;:*&lt;/span&gt;) &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;!&lt;/span&gt;(&lt;span class=&quot;bv&quot;&gt;abt&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;vs&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt;)
         &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;!&lt;/span&gt;(&lt;span class=&quot;dt&quot;&gt;SArgs&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;abt&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;vus&lt;/span&gt;)
         &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;SArgs&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;abt&lt;/span&gt; (&lt;span class=&quot;dc&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bv&quot;&gt;vs&lt;/span&gt;&lt;span class=&quot;dc&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;dc&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;vus&lt;/span&gt;)

&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;×&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;⭑&lt;/span&gt;) &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;⭑&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;
    (&lt;span class=&quot;dc&quot;&gt;:$&lt;/span&gt;) &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;!&lt;/span&gt;(&lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;vus&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt;)
         &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;!&lt;/span&gt;(&lt;span class=&quot;dt&quot;&gt;SArgs&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt;) &lt;span class=&quot;bv&quot;&gt;vus&lt;/span&gt;)
         &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt;

    &lt;span class=&quot;dc&quot;&gt;Var&lt;/span&gt;  &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;!&lt;/span&gt;(&lt;span class=&quot;dt&quot;&gt;Variable&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;v&lt;/span&gt;)
         &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;v&lt;/span&gt;

    &lt;span class=&quot;dc&quot;&gt;Bind&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;!&lt;/span&gt;(&lt;span class=&quot;dt&quot;&gt;Variable&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;v&lt;/span&gt;)
         &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;!&lt;/span&gt;(&lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;vs&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt;)
         &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt; (&lt;span class=&quot;bv&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;vs&lt;/span&gt;) &lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Time for an example of how this all fits together. To add lambda-abstraction to our language we’d have &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dc&quot;&gt;λ&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Σ&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dc&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;dc&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt;&lt;span class=&quot;dc&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;dc&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;bv&quot;&gt;v&lt;/span&gt;&lt;span class=&quot;dc&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;dc&quot;&gt;]&lt;/span&gt; (&lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;:→&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;v&lt;/span&gt;)&lt;/code&gt;: that is, the &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dc&quot;&gt;λ&lt;/span&gt;&lt;/code&gt; constructor takes a single argument which is a locally-open term, binding a single variable of type &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;fv&quot;&gt;u&lt;/span&gt;&lt;/code&gt;, and whose body has type &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;fv&quot;&gt;v&lt;/span&gt;&lt;/code&gt;. So given some &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;fv&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Variable&lt;/span&gt; &lt;span class=&quot;fv&quot;&gt;u&lt;/span&gt;&lt;/code&gt; and &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;fv&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Σ&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;fv&quot;&gt;v&lt;/span&gt;&lt;/code&gt; we’d have the AST &lt;code class=&quot;sourceCode haskell&quot;&gt;(&lt;span class=&quot;dc&quot;&gt;λ&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;:$&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;Bind&lt;/span&gt; &lt;span class=&quot;fv&quot;&gt;x&lt;/span&gt; &lt;span class=&quot;fv&quot;&gt;e&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;:*&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;End&lt;/span&gt;) &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Σ&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;[]&lt;/span&gt; (&lt;span class=&quot;fv&quot;&gt;u&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;:→&lt;/span&gt; &lt;span class=&quot;fv&quot;&gt;v&lt;/span&gt;)&lt;/code&gt;.&lt;/p&gt;&lt;h3&gt;“Local” vs “global” well-typedness&lt;/h3&gt;&lt;p&gt;With the &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt;&lt;/code&gt; definition above, every term of type &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Σ&lt;/span&gt; &lt;span class=&quot;fv&quot;&gt;vs&lt;/span&gt; &lt;span class=&quot;fv&quot;&gt;u&lt;/span&gt;&lt;/code&gt; must be locally well-typed according to the signature &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Σ&lt;/span&gt;&lt;/code&gt;. I keep saying “locally” well-typed because we only actually keep track of local binding information. This is an intentional design decision. But only tracking local well-typedness does have some downsides.&lt;/p&gt;&lt;p&gt;So what are the downsides? Where could things go wrong? Given a locally-closed term (i.e., either &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dc&quot;&gt;Var&lt;/span&gt; &lt;span class=&quot;fv&quot;&gt;x&lt;/span&gt;&lt;/code&gt; or &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;fv&quot;&gt;f&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;:$&lt;/span&gt; &lt;span class=&quot;fv&quot;&gt;e&lt;/span&gt;&lt;/code&gt;) any free variables that occur inside will not have their &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;/code&gt;-types tracked by Haskell’s type system. This introduces some room for the compiler writer to break the connection between the types of a variable’s binder and its use. That is, under the hood, every variable is represented by some unique identifier like an integer or a string. Integers and strings aren’t &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;/code&gt;-indexed Haskell types, thus it’s possible to construct a &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Variable&lt;/span&gt; &lt;span class=&quot;fv&quot;&gt;u&lt;/span&gt;&lt;/code&gt; and a &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Variable&lt;/span&gt; &lt;span class=&quot;fv&quot;&gt;v&lt;/span&gt;&lt;/code&gt; with the same unique identifier, even though &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;fv&quot;&gt;u&lt;/span&gt;&lt;/code&gt; and &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;fv&quot;&gt;v&lt;/span&gt;&lt;/code&gt; differ. We could then &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dc&quot;&gt;Bind&lt;/span&gt;&lt;/code&gt; the &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Variable&lt;/span&gt; &lt;span class=&quot;fv&quot;&gt;u&lt;/span&gt;&lt;/code&gt; but &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dc&quot;&gt;Var&lt;/span&gt;&lt;/code&gt; the &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Variable&lt;/span&gt; &lt;span class=&quot;fv&quot;&gt;v&lt;/span&gt;&lt;/code&gt;. In order to ensure global well-typedness we need to ensure this can’t happen.&lt;/p&gt;&lt;p&gt;One way is to keep track of global binding information, as we do in the paper presentation of languages. Unfortunately, to do this we’d need to teach Haskell’s typechecker about the structural rules of our language. Without a type-level implementation of sets/maps which respects all the axioms that sets/maps should, we’d be forced to do things like traverse our ASTs and rebuild them identically, but at different type indices. This is simply too hairy to stomach. Implementing the axioms ourselves is doubly so.&lt;/p&gt;&lt;p&gt;Or we could fake it, using &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;fn&quot;&gt;unsafeCoerce&lt;/span&gt;&lt;/code&gt; to avoid the extraneous traversals or the complicated pattern matching on axioms. But doing this we’d erase all guarantees that adding global binding information has to offer.&lt;/p&gt;&lt;p&gt;A third approach, and the one we take in Hakaru, is compartmentalize the places where variables can be constructed. The variable generation code must be part of our trusted code base, but unlike the &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;fn&quot;&gt;unsafeCoerce&lt;/span&gt;&lt;/code&gt; approach we can keep all the TCB code together in one spot rather than spread out across the whole compiler.&lt;/p&gt;&lt;h3&gt;Stratifying our data types&lt;/h3&gt;&lt;p&gt;The above definition of ABTs is a simplified version of what we actually use in Hakaru. For example, Hakaru has user-defined algebraic data types, so we also need case analysis on those data types. Alas, generic case analysis is not a generalized quantifier, thus we cannot implement it with &lt;code class=&quot;sourceCode haskell&quot;&gt;(&lt;span class=&quot;dc&quot;&gt;:$&lt;/span&gt;)&lt;/code&gt;. We could consider just adding case analysis to the &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt;&lt;/code&gt; definition, but then we’d start running into extensibility issues again. Instead, we can break the &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt;&lt;/code&gt; type apart into two types: one for capturing variable uses and bindings, and the other for whatever syntax we can come up with. Thus,&lt;/p&gt;&lt;div class=&quot;sourceCode&quot;&gt;&lt;pre class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Syntax&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;×&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;⭑&lt;/span&gt;) &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;⭑&lt;/span&gt;) &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;⭑&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;
    (&lt;span class=&quot;dc&quot;&gt;:$&lt;/span&gt;) &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;!&lt;/span&gt;(&lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;vus&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt;)
         &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;!&lt;/span&gt;(&lt;span class=&quot;dt&quot;&gt;SArgs&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;abt&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;vus&lt;/span&gt;)
         &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;Syntax&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;abt&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt;

&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;⭑&lt;/span&gt;) &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;⭑&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;dc&quot;&gt;Syn&lt;/span&gt;  &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;!&lt;/span&gt;(&lt;span class=&quot;dt&quot;&gt;Syntax&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt;) &lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt;)
         &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt;

    &lt;span class=&quot;dc&quot;&gt;Var&lt;/span&gt;  &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;!&lt;/span&gt;(&lt;span class=&quot;dt&quot;&gt;Variable&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;v&lt;/span&gt;)
         &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;v&lt;/span&gt;

    &lt;span class=&quot;dc&quot;&gt;Bind&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;!&lt;/span&gt;(&lt;span class=&quot;dt&quot;&gt;Variable&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;v&lt;/span&gt;)
         &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;!&lt;/span&gt;(&lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;vs&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt;)
         &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt; (&lt;span class=&quot;bv&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;vs&lt;/span&gt;) &lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Of course, since we’re going to be extending &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Syntax&lt;/span&gt;&lt;/code&gt; with all our language-specific details, there’s not a whole lot of benefit to parameterizing over &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt;&lt;/code&gt;. Thus, we can simplify the types considerably by just picking some concrete &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Σ&lt;/span&gt;&lt;/code&gt; to plug in for &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt;&lt;/code&gt;.&lt;/p&gt;&lt;p&gt;By breaking &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Syntax&lt;/span&gt;&lt;/code&gt; apart from &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt;&lt;/code&gt; we can now extend our notion of syntax without worrying about the details of variable binding (which can be defined once and for all on &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt;&lt;/code&gt;). But we could still run into extensibility issues. In particular, often we want to separate the fixed-point portion of recursive types from their generating functor so that we can do things like add annotations at every node in the recursive data type. A prime example of such annotations is keeping track of free variables, as in Neel’s original post. To allow this form of extensibility we need to break up the &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt;&lt;/code&gt; type into two parts: the recursion, and the &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dc&quot;&gt;Syn&lt;/span&gt;&lt;/code&gt;/&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dc&quot;&gt;Var&lt;/span&gt;&lt;/code&gt;/&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dc&quot;&gt;Bind&lt;/span&gt;&lt;/code&gt; view of the ABT.&lt;/p&gt;&lt;div class=&quot;sourceCode&quot;&gt;&lt;pre class=&quot;sourceCode haskell&quot;&gt;&lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;⭑&lt;/span&gt;) &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;⭑&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;dc&quot;&gt;Unview&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;!&lt;/span&gt;(&lt;span class=&quot;dt&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt;) &lt;span class=&quot;bv&quot;&gt;vs&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt;) &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;vs&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt;

&lt;span class=&quot;fn&quot;&gt;view&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;vs&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt;) &lt;span class=&quot;bv&quot;&gt;vs&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt;
&lt;span class=&quot;fn&quot;&gt;view&lt;/span&gt; (&lt;span class=&quot;dc&quot;&gt;Unview&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;e&lt;/span&gt;) &lt;span class=&quot;ot&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;e&lt;/span&gt;

&lt;span class=&quot;kw&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; (&lt;span class=&quot;dt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;⭑&lt;/span&gt;) &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;pt&quot;&gt;⭑&lt;/span&gt; &lt;span class=&quot;kw&quot;&gt;where&lt;/span&gt;
    &lt;span class=&quot;dc&quot;&gt;Syn&lt;/span&gt;  &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;!&lt;/span&gt;(&lt;span class=&quot;dt&quot;&gt;Syntax&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;abt&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt;)
         &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;abt&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt;

    &lt;span class=&quot;dc&quot;&gt;Var&lt;/span&gt;  &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;!&lt;/span&gt;(&lt;span class=&quot;dt&quot;&gt;Variable&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;v&lt;/span&gt;)
         &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;abt&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;[]&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;v&lt;/span&gt;

    &lt;span class=&quot;dc&quot;&gt;Bind&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;∷&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;!&lt;/span&gt;(&lt;span class=&quot;dt&quot;&gt;Variable&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;v&lt;/span&gt;)
         &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;ot&quot;&gt;!&lt;/span&gt;(&lt;span class=&quot;dt&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;abt&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;vs&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt;)
         &lt;span class=&quot;pt&quot;&gt;→&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;View&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;σ&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;abt&lt;/span&gt; (&lt;span class=&quot;bv&quot;&gt;v&lt;/span&gt; &lt;span class=&quot;dc&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;bv&quot;&gt;vs&lt;/span&gt;) &lt;span class=&quot;bv&quot;&gt;u&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, to allow arbitrary annotations we’ll replace the data type &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt;&lt;/code&gt; with an equivalent type class. Each instance of the &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt;&lt;/code&gt; class defines some sort of annotations, and we can use the &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;fn&quot;&gt;view&lt;/span&gt;&lt;/code&gt; and &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;fn&quot;&gt;unview&lt;/span&gt;&lt;/code&gt; methods to move between the instance and the concrete &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;View&lt;/span&gt;&lt;/code&gt; type.&lt;/p&gt;&lt;p&gt;There’s one last form of extensibility we may want to add. Using fixed point combinators gives us a way of describing complete trees. A different way of introducing recursion is with free monads. The free-monad combinator is just like the fixed-point combinator, except that we have an additional type parameter for metavariables and we have a data constructor for using those metavariables instead of requiring the recursion to ground out with a complete syntax tree. The reasons why this might be nice to do are beyond the scope of this post, but the point is we might want to do that so we need to split the &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;ABT&lt;/span&gt;&lt;/code&gt; class into two parts: one for the recursion itself, and another for the annotations.&lt;/p&gt;&lt;p&gt;In the end, we have a four-level type: the &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;Syntax&lt;/span&gt;&lt;/code&gt;, the &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;View&lt;/span&gt;&lt;/code&gt;, the annotations, and the recursion.&lt;/p&gt;

&lt;hr /&gt;
&lt;p&gt;&lt;a name=&quot;103978:fn1&quot;&gt;[1]&lt;/a&gt; In the accepted/current parlance, Hakaru is a “probabilistic programming language”; but I and a number of other folks working on such languages have become disaffected with that term of late, since it’s not entirely clear what should and should not count as a “probabilistic” PL. Over the course of a number of discussions on the topic, I’ve settled on “inferential” PL as describing what is (or, at least what &lt;em&gt;I&lt;/em&gt; find) interesting about “probabilistic” PL. I’ve been meaning to write a post about the subject, and hopefully this footnote will remind me to do so.&lt;a href=&quot;#103978:fnref1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a name=&quot;103978:fn2&quot;&gt;[2]&lt;/a&gt; N.B., the indexing used in that package is what we get if we erase/compactify the universe &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;/code&gt;. That is: the erasure of &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;/code&gt; is a singleton set; the erasure of &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;]&lt;/span&gt;&lt;/code&gt; is isomorphic to the Peano numbers; the erasure of &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;×&lt;/span&gt; &lt;span class=&quot;dt&quot;&gt;U&lt;/span&gt;&lt;span class=&quot;dt&quot;&gt;]&lt;/span&gt;&lt;/code&gt; is isomorphic to a list of Peano numbers; etc.&lt;a href=&quot;#103978:fnref2&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a name=&quot;103978:fn3&quot;&gt;[3]&lt;/a&gt; Though at one point I assume we have functions, &lt;code class=&quot;sourceCode haskell&quot;&gt;(&lt;span class=&quot;dc&quot;&gt;:→&lt;/span&gt;)&lt;/code&gt;, just for the sake of an example.&lt;a href=&quot;#103978:fnref3&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a name=&quot;103978:fn4&quot;&gt;[4]&lt;/a&gt; Ideally we’d be able to flatten this type to avoid all the overhead of the linked list implementation. In fact, the entire AST node of &lt;code class=&quot;sourceCode haskell&quot;&gt;(&lt;span class=&quot;dc&quot;&gt;:$&lt;/span&gt;)&lt;/code&gt; together with its &lt;code class=&quot;sourceCode haskell&quot;&gt;&lt;span class=&quot;dt&quot;&gt;SArgs&lt;/span&gt;&lt;/code&gt; should be flattened. These nodes have the same general layout as the heap objects in the STG machine: a record with a pointer to the data constructor (i.e., element of the signature) followed by an appropriate number of arguments; and so in principle we ought to be able to implement them directly with a single STG heap object.&lt;a href=&quot;#103978:fnref4&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;

&lt;div class=&quot;btn-group&quot;&gt;
&lt;a href=&quot;https://twitter.com/share?via=wrengr&amp;amp;url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F103978.html&amp;amp;text=Abstract%20Binding%20Trees%20in%20Hakaru&quot; class=&quot;btn&quot; title=&quot;Share on Twitter&quot; target=&quot;_blank&quot;&gt;Twitter&lt;/a&gt;
&lt;a href=&quot;https://www.facebook.com/sharer/sharer.php?u=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F103978.html&amp;amp;t=Abstract%20Binding%20Trees%20in%20Hakaru&quot; class=&quot;btn&quot; title=&quot;Share on Facebook&quot; target=&quot;_blank&quot;&gt;Facebook&lt;/a&gt;
&lt;a href=&quot;https://plus.google.com/share?url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F103978.html&quot; class=&quot;btn&quot; title=&quot;Share on Google+&quot; target=&quot;_blank&quot;&gt;Google+&lt;/a&gt;
&lt;a href=&quot;http://www.tumblr.com/share/link?url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F103978.html&amp;amp;name=Abstract%20Binding%20Trees%20in%20Hakaru&quot; class=&quot;btn&quot; title=&quot;Share on Tumblr&quot; target=&quot;_blank&quot;&gt;Tumblr&lt;/a&gt;
&lt;a href=&quot;http://wordpress.com/press-this.php?u=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F103978.html&amp;amp;t=Abstract%20Binding%20Trees%20in%20Hakaru&amp;amp;s=&quot; class=&quot;btn&quot; title=&quot;Share on WordPress&quot; target=&quot;_blank&quot;&gt;WordPress&lt;/a&gt;
&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=103978&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/103978.html</comments>
  <category>hakaru</category>
  <category>dependent types</category>
  <category>haskell planet</category>
  <category>design</category>
  <category>computer science</category>
  <category>coding</category>
  <category>haskell</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/103538.html</guid>
  <pubDate>Sat, 12 Sep 2015 03:34:53 GMT</pubDate>
  <title>What do we mean when we say &quot;the Haskell community&quot;?</title>
  <link>https://winterkoninkje.dreamwidth.org/103538.html</link>
  <description>&lt;p&gt;One of the folks I&apos;ve chatted with a bunch online and finally got to meet in-person this year was Gershom. Towards the end of the symposium, he mentioned the post I linked to last time about &lt;a href=&quot;http://winterkoninkje.dreamwidth.org/97625.html&quot;&gt;my pulling away from Haskell communities&lt;/a&gt;. But the way he phrased it really struck me. And I wanted to comment on that.&lt;/p&gt;

&lt;p&gt;I guess the crux of it comes down to, what do we mean when we say &quot;the Haskell community&quot;? What I meant when writing that post over a year ago was the online community of Haskell learners/practitioners (i.e., the folks who dominate spaces like reddit). But what Gershom&apos;s comment suggested was the academic community of FP researchers who work on/with Haskell (i.e., the folks who dominate spaces like ICFP). These two communities have always been intertwined, but as Haskell gains popularity they feel more and more distinct.&lt;/p&gt;

&lt;p&gt;FWIW, I do still feel welcome as part of the academic community. There are some things I could comment on, sure, but those have more to do (i think) the general issue of being a woman in tech than they do with Haskell per se. Of course, this only underscores the concern of my original post. The free exchange between academics and practitioners was always a big part of what I&apos;ve loved about the (general) Haskell community. Were not for that exchange, the spark planted by Mark Jones would never have fanned into the flame of my current research. As that free exchange unravels, this pathway from interested novice to researcher is cut off. And that pathway is crucial for the vibrancy of the community, as well as for addressing those general issues of being a minority in tech.&lt;/p&gt;

&lt;div class=&quot;btn-group&quot;&gt;
&lt;a href=&quot;https://twitter.com/share?text=What%20do%20we%20mean%20when%20we%20say%20%22the%20Haskell%20community%22%3F&amp;amp;url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F103538.html&amp;amp;via=wrengr&quot; class=&quot;btn&quot; title=&quot;Share on Twitter&quot; target=&quot;_blank&quot;&gt;Twitter&lt;/a&gt;
&lt;a href=&quot;https://www.facebook.com/sharer/sharer.php?u=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F103538.html&amp;amp;t=What%20do%20we%20mean%20when%20we%20say%20%22the%20Haskell%20community%22%3F&quot; class=&quot;btn&quot; title=&quot;Share on Facebook&quot; target=&quot;_blank&quot;&gt;Facebook&lt;/a&gt;
&lt;a href=&quot;https://plus.google.com/share?url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F103538.html&quot; class=&quot;btn&quot; title=&quot;Share on Google+&quot; target=&quot;_blank&quot;&gt;Google+&lt;/a&gt;
&lt;a href=&quot;http://www.tumblr.com/share/link?url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F103538.html&amp;amp;name=What%20do%20we%20mean%20when%20we%20say%20%22the%20Haskell%20community%22%3F&quot; class=&quot;btn&quot; title=&quot;Share on Tumblr&quot; target=&quot;_blank&quot;&gt;Tumblr&lt;/a&gt;
&lt;a href=&quot;http://wordpress.com/press-this.php?u=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F103538.html&amp;amp;t=What%20do%20we%20mean%20when%20we%20say%20%22the%20Haskell%20community%22%3F&amp;amp;s=&quot; class=&quot;btn&quot; title=&quot;Share on WordPress&quot; target=&quot;_blank&quot;&gt;WordPress&lt;/a&gt;
&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=103538&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/103538.html</comments>
  <category>haskell planet</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/103352.html</guid>
  <pubDate>Fri, 11 Sep 2015 07:38:53 GMT</pubDate>
  <title>Back home from ICFP</title>
  <link>https://winterkoninkje.dreamwidth.org/103352.html</link>
  <description>&lt;p&gt;Got back from Vancouver a couple days ago. The return flight was hell, but other than that the trip was pretty good. Got to meet a whole bunch of folks who read my blog (hi!), which was super cool. It always gives me warm fuzzies to know people are actually interested in my stuff. (You&apos;d think I&apos;d get used to it after a while, but no, evidently childhood scars still remain years after developing a solid sense of self-esteem. Go fig.) Of course, now I feel bad about not having written much of late. I have a few posts I&apos;ve been meaning to write —mostly technical ones—, and I&apos;m thinking I might should try to kick those out as a way to get back into the daily writing habit needed for finishing up my dissertation.&lt;/p&gt;

&lt;p&gt;Since handing out my card at ICFP, I&apos;ve been hacking around on &lt;a href=&quot;http://cl.indiana.edu/~wren&quot;&gt;my website&lt;/a&gt;. I&apos;m still working on getting my publications/presentations to be properly formatted, and the timestamps in the footers on a couple pages are busted, but other than that I think it&apos;s in pretty good shape. I also took part in a keysigning party for the purpose of building a WoT as part of the developing story for how we securely deliver packages in Haskell. My key is up on &lt;a href=&quot;https://keybase.io/wrengr&quot;&gt;Keybase&lt;/a&gt; as well as on my website (&lt;a href=&quot;http://cl.indiana.edu/~wren/#contact&quot;&gt;along with all my other contact info&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;After a week of great talks, too much drinking, and too little sleep, I met up with a dear friend from undergrad. It&apos;s been far far too long since we&apos;ve had a chance to hang out (alas, he couldn&apos;t make the wedding last year), but he&apos;s one of those friends you can just fall right back into. It&apos;s funny how much can change and yet stay the same. In one of our ambling walks I dragged him into a clothing store —something I never would&apos;ve done pre-transition. He didn&apos;t seem to mind. He just went along like it&apos;s the sort of thing we&apos;ve always done. And it felt to me like the sort of thing we could&apos;ve always done. Recently he&apos;s been ref&apos;ing for roller derby up in Victoria, and after talking about it I&apos;m thinking I might try my hand at it. Sounds like a lot of fun. We have a team in Bloomington, and they&apos;re doing a training/recruiting thing, though alas I&apos;ll miss it since I&apos;ll be in Mountain View on the 14th. I&apos;ll see if I can&apos;t find some other way to get introduced.&lt;/p&gt;


&lt;div class=&quot;btn-group&quot;&gt;
&lt;a href=&quot;https://twitter.com/share?text=Back%20home%20from%20ICFP&amp;amp;url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F103352.html&amp;amp;via=wrengr&quot; class=&quot;btn&quot; title=&quot;Share on Twitter&quot; target=&quot;_blank&quot;&gt;Twitter&lt;/a&gt;
&lt;a href=&quot;https://www.facebook.com/sharer/sharer.php?u=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F103352.html&amp;amp;t=Back%20home%20from%20ICFP&quot; class=&quot;btn&quot; title=&quot;Share on Facebook&quot; target=&quot;_blank&quot;&gt;Facebook&lt;/a&gt;
&lt;a href=&quot;https://plus.google.com/share?url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F103352.html&quot; class=&quot;btn&quot; title=&quot;Share on Google+&quot; target=&quot;_blank&quot;&gt;Google+&lt;/a&gt;
&lt;a href=&quot;http://www.tumblr.com/share/link?url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F103352.html&amp;amp;name=Back%20home%20from%20ICFP&quot; class=&quot;btn&quot; title=&quot;Share on Tumblr&quot; target=&quot;_blank&quot;&gt;Tumblr&lt;/a&gt;
&lt;a href=&quot;http://wordpress.com/press-this.php?u=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F103352.html&amp;amp;t=Back%20home%20from%20ICFP&amp;amp;s=&quot; class=&quot;btn&quot; title=&quot;Share on WordPress&quot; target=&quot;_blank&quot;&gt;WordPress&lt;/a&gt;
&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=103352&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/103352.html</comments>
  <category>website update</category>
  <category>haskell planet</category>
  <category>personal</category>
  <category>traveling</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/103089.html</guid>
  <pubDate>Sun, 30 Aug 2015 06:36:08 GMT</pubDate>
  <title>(Re)meeting folks at ICFP</title>
  <link>https://winterkoninkje.dreamwidth.org/103089.html</link>
  <description>&lt;p&gt;In the spirit of &lt;a href=&quot;https://byorgey.wordpress.com/2015/08/29/meeting-new-people-at-icfp/&quot;&gt;Brent&apos;s post&lt;/a&gt;, I figure I&apos;ll make a public announcement that I&apos;m in Vancouver all week attending HOPE, ICFP, and the Haskell Symposium. I love reconnecting with old friends, as well as meeting new folks. Even if I&apos;ve met you at past ICFPs, feel free to re-introduce yourself as &lt;a href=&quot;http://winterkoninkje.dreamwidth.org/90012.html&quot;&gt;...things have changed over the past few years.&lt;/a&gt; I know I&apos;ve been &lt;a href=&quot;http://winterkoninkje.dreamwidth.org/97625.html&quot;&gt;pretty quiet of late on Haskell cafe&lt;/a&gt; as well as here, but word on the street is folks still recognize my name around places. So if you want to meet up, leave a comment with when/where to find you, or just look for the tall gal with the blue streak in her hair.&lt;/p&gt;

&lt;p&gt;Unlike Brent, and unlike in years past, I might should note that I &lt;em&gt;am&lt;/em&gt; looking to &quot;advance my career&quot;. &lt;b&gt;&lt;i&gt;As of this fall, I am officially on the market for research and professorship positions.&lt;/i&gt;&lt;/b&gt; So if you&apos;re interested in having a linguistically-minded constructive mathematician help work on your problems, come say hi. For those not attending ICFP, you can check out &lt;a href=&quot;http://cl.indiana.edu/~wren/&quot;&gt;my professional site&lt;/a&gt;; I need to fix my script for generating the publications page, but you can find a brief background/research statement there along with the other usuals like CV, recent projects, and classes taught.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=103089&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/103089.html</comments>
  <category>work</category>
  <category>traveling</category>
  <category>grad school</category>
  <category>haskell planet</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/102451.html</guid>
  <pubDate>Sun, 07 Jun 2015 01:04:43 GMT</pubDate>
  <title>ANN: bytestring-lexing 0.5.0</title>
  <link>https://winterkoninkje.dreamwidth.org/102451.html</link>
  <description>&lt;h3&gt;bytestring-lexing 0.5.0&lt;/h3&gt;

&lt;p&gt;The bytestring-lexing package offers extremely efficient bytestring parsers for some common lexemes: namely integral and fractional numbers. In addition, it provides efficient serializers for (some of) the formats it parses.&lt;/p&gt;

&lt;p&gt;As of version 0.3.0, bytestring-lexing offers the best-in-show parsers for integral values. (According to the Warp web server&apos;s benchmark of parsing the Content-Length field of HTTP headers.) And as of this version (0.5.0) it offers (to my knowledge) the best-in-show parser for fractional/floating numbers.&lt;/p&gt;

&lt;h3&gt;Changes since 0.4.3 (2013-03-21)&lt;/h3&gt;

&lt;p&gt;I&apos;ve completely overhauled the parsers for fractional numbers.&lt;/p&gt;

&lt;p&gt;The old &lt;code&gt;Data.ByteString.Lex.Double&lt;/code&gt; and &lt;code&gt;Data.ByteString.Lex.Lazy.Double&lt;/code&gt; modules have been removed, as has their reliance on Alex as a build tool. I know some users were reluctant to use bytestring-lexing because of that dependency, and forked their own version of bytestring-lexing-0.3.0&apos;s integral parsers. This is no longer an issue, and those users are requested to switch over to using bytestring-lexing.&lt;/p&gt;

&lt;p&gt;The old modules are replaced by the new &lt;code&gt;Data.ByteString.Lex.Fractional&lt;/code&gt; module. This module provides two variants of the primary parsers. The &lt;code&gt;readDecimal&lt;/code&gt; and &lt;code&gt;readExponential&lt;/code&gt; functions are very simple and should suffice for most users&apos; needs. The &lt;code&gt;readDecimalLimited&lt;/code&gt; and &lt;code&gt;readExponentialLimited&lt;/code&gt; are variants which take an argument specifying the desired precision limit (in decimal digits). With care, the limited-precision parsers can perform far more efficiently than the unlimited-precision parsers. Performance aside, they can also be used to intentionally restrict the precision of your program&apos;s inputs.&lt;/p&gt;

&lt;h3&gt;Benchmarks&lt;/h3&gt;

&lt;p&gt;The Criterion output of the benchmark discussed below, &lt;a href=&quot;http://community.haskell.org/~wren/bytestring-lexing/bench/html/readExponential-0.5.0_ereshkigal.html&quot;&gt;can be seen here&lt;/a&gt;. The main competitors we compare against are &lt;a href=&quot;http://hackage.haskell.org/package/bytestring-lexing-0.4.3.3&quot;&gt;the previous version of bytestring-lexing&lt;/a&gt; (which already surpassed text and attoparsec/scientific) and &lt;a href=&quot;https://hackage.haskell.org/package/bytestring-read-0.3.0&quot;&gt;bytestring-read&lt;/a&gt; which was the previous best-in-show.&lt;/p&gt;

&lt;p&gt;The unlimited-precision parsers provide 3.3× to 3.9× speedup over the &lt;code&gt;readDouble&lt;/code&gt; function from bytestring-lexing-0.4.3.3, as well as being polymorphic over all &lt;code&gt;Fractional&lt;/code&gt; values. For &lt;code&gt;Float&lt;/code&gt;/&lt;code&gt;Double&lt;/code&gt;: these functions have essentially the same performance as bytestring-read on reasonable inputs (1.07× to 0.89×), but for inputs which have far more precision than &lt;code&gt;Float&lt;/code&gt;/&lt;code&gt;Double&lt;/code&gt; can handle these functions are much slower than bytestring-read (0.30× &apos;speedup&apos;). However, for &lt;code&gt;Rational&lt;/code&gt;: these functions provide 1.26× to 1.96× speedup compared to bytestring-read.&lt;/p&gt;

&lt;p&gt;The limited-precision parsers do even better, but require some care to use properly. For types with infinite precision (e.g., &lt;code&gt;Rational&lt;/code&gt;) we can pass in an &apos;infinite&apos; limit by passing the length of the input string plus one. For &lt;code&gt;Rational&lt;/code&gt;: doing so provides 1.5× speedup over the unlimited-precision parsers (and 1.9× to 3× speedup over bytestring-read), because we can avoid intermediate renormalizations. Whether other unlimited precision types would see the same benefit remains an open question.&lt;/p&gt;

&lt;p&gt;For types with inherently limited precision (e.g., &lt;code&gt;Float&lt;/code&gt;/&lt;code&gt;Double&lt;/code&gt;), we could either pass in an &apos;infinite&apos; limit or we could pass in the actual inherent limit. For types with inherently limited precision, passing in an &apos;infinite&apos; limit degrades performance compared to the unlimited-precision parsers (0.51× to 0.8× &apos;speedup&apos;). Whereas, passing in the actual inherent limit gives 1.3× to 4.5× speedup over the unlimited-precision parsers. They also provide 1.2× to 1.4× speedup over bytestring-read; for a total of 5.1× to 14.4× speedup over bytestring-lexing-0.4.3.3!&lt;/p&gt;

&lt;h3&gt;Links&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Homepage: &lt;a href=&quot;http://code.haskell.org/~wren/&quot;&gt;http://code.haskell.org/~wren/&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;Hackage: &lt;a href=&quot;http://hackage.haskell.org/package/bytestring-lexing&quot;&gt;http://hackage.haskell.org/package/bytestring-lexing&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;Darcs: &lt;a href=&quot;http://community.haskell.org/~wren/bytestring-lexing&quot;&gt;http://community.haskell.org/~wren/bytestring-lexing&lt;/a&gt;&lt;/li&gt;

&lt;li&gt;Haddock: &lt;a href=&quot;http://community.haskell.org/~wren/bytestring-lexing/dist/doc/html/bytestring-lexing/&quot;&gt;Darcs version&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;btn-group&quot;&gt;
&lt;a href=&quot;https://twitter.com/share?via=wrengr&amp;amp;url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F102451.html&amp;amp;text=ANN%3A%20bytestring-lexing%200.5.0&quot; class=&quot;btn&quot; title=&quot;Share on Twitter&quot; target=&quot;_blank&quot;&gt;Twitter&lt;/a&gt;
&lt;a href=&quot;https://www.facebook.com/sharer/sharer.php?u=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F102451.html&amp;amp;t=ANN%3A%20bytestring-lexing%200.5.0&quot; class=&quot;btn&quot; title=&quot;Share on Facebook&quot; target=&quot;_blank&quot;&gt;Facebook&lt;/a&gt;
&lt;a href=&quot;https://plus.google.com/share?url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F102451.html&quot; class=&quot;btn&quot; title=&quot;Share on Google+&quot; target=&quot;_blank&quot;&gt;Google+&lt;/a&gt;
&lt;a href=&quot;http://www.tumblr.com/share/link?url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F102451.html&amp;amp;name=ANN%3A%20bytestring-lexing%200.5.0&quot; class=&quot;btn&quot; title=&quot;Share on Tumblr&quot; target=&quot;_blank&quot;&gt;Tumblr&lt;/a&gt;
&lt;a href=&quot;http://wordpress.com/press-this.php?u=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F102451.html&amp;amp;t=ANN%3A%20bytestring-lexing%200.5.0&amp;amp;s=&quot; class=&quot;btn&quot; title=&quot;Share on WordPress&quot; target=&quot;_blank&quot;&gt;WordPress&lt;/a&gt;
&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=102451&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/102451.html</comments>
  <category>haskell</category>
  <category>haskell planet</category>
  <category>code release</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/102394.html</guid>
  <pubDate>Sat, 30 May 2015 03:15:42 GMT</pubDate>
  <title>Migrating emails etc</title>
  <link>https://winterkoninkje.dreamwidth.org/102394.html</link>
  <description>&lt;p&gt;I&apos;ve been working on culling a bunch of my old email addresses and unifying my username across the internet. I&apos;ve mentioned a number of these changes before, but every few months I run into folks who&apos;ve missed the memo. So, for those who keep up with my blog or follow Haskell Planet, here&apos;s the latest rundown:&lt;/p&gt;

&lt;dl&gt;
&lt;dt&gt;&lt;b&gt;Emails&lt;/b&gt;&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;
&lt;li&gt;&amp;#119;&amp;#114;&amp;#101;&amp;#110;&amp;#064;&amp;#102;&amp;#114;&amp;#101;&amp;#101;&amp;#103;&amp;#101;&amp;#101;&amp;#107;&amp;#046;&amp;#111;&amp;#114;&amp;#103; —&lt;b&gt;&lt;i&gt;is dead&lt;/i&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&amp;#119;&amp;#114;&amp;#110;&amp;#116;&amp;#104;&amp;#111;&amp;#114;&amp;#110;&amp;#064;&amp;#105;&amp;#110;&amp;#100;&amp;#105;&amp;#097;&amp;#110;&amp;#097;&amp;#046;&amp;#101;&amp;#100;&amp;#117; —&lt;b&gt;&lt;i&gt;is dead&lt;/i&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&amp;#112;&amp;#104;&amp;#114;&amp;#101;&amp;#101;&amp;#108;&amp;#097;&amp;#110;&amp;#099;&amp;#101;&amp;#064;&amp;#121;&amp;#097;&amp;#104;&amp;#111;&amp;#111;&amp;#046;&amp;#099;&amp;#111;&amp;#109; —&lt;b&gt;&lt;i&gt;will soon be dead&lt;/i&gt;&lt;/b&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;i&gt;My Perl forwarding address lives&lt;/i&gt;&lt;/b&gt;— &amp;#119;&amp;#114;&amp;#101;&amp;#110;&amp;#064;&amp;#099;&amp;#112;&amp;#097;&amp;#110;&amp;#046;&amp;#111;&amp;#114;&amp;#103;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;i&gt;My Haskell forwarding address lives&lt;/i&gt;&lt;/b&gt;— &amp;#119;&amp;#114;&amp;#101;&amp;#110;&amp;#064;&amp;#099;&amp;#111;&amp;#109;&amp;#109;&amp;#117;&amp;#110;&amp;#105;&amp;#116;&amp;#121;&amp;#046;&amp;#104;&amp;#097;&amp;#115;&amp;#107;&amp;#101;&amp;#108;&amp;#108;&amp;#046;&amp;#111;&amp;#114;&amp;#103;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;&lt;i&gt;My current work address is&lt;/i&gt;&lt;/b&gt;— &amp;#119;&amp;#114;&amp;#101;&amp;#110;&amp;#103;&amp;#114;&amp;#064;&amp;#105;&amp;#110;&amp;#100;&amp;#105;&amp;#097;&amp;#110;&amp;#097;&amp;#046;&amp;#101;&amp;#100;&amp;#117;&lt;/li&gt;
&lt;li&gt;My personal email at gmail.com is also lives&lt;/li&gt;
&lt;/ul&gt;&lt;/dd&gt;
&lt;dt&gt;&lt;b&gt;Code Hosting &amp;amp; Other User Names&lt;/b&gt;&lt;/dt&gt;&lt;dd&gt;&lt;ul&gt;
&lt;li&gt;My &lt;b&gt;&lt;i&gt;BitBucket&lt;/i&gt;&lt;/b&gt; username has changed from winterkoninkje to &lt;a href=&quot;https://bitbucket.org/wrengr&quot;&gt;wrengr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;My &lt;b&gt;&lt;i&gt;GitHub&lt;/i&gt;&lt;/b&gt; username has changed from winterkoninkje to &lt;a href=&quot;https://github.com/wrengr&quot;&gt;wrengr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;My &lt;b&gt;&lt;i&gt;IRC&lt;/i&gt;&lt;/b&gt; username has changed from koninkje to wrengr&lt;/li&gt;
&lt;/ul&gt;&lt;/dd&gt;&lt;/dl&gt;


&lt;div class=&quot;btn-group&quot;&gt;
&lt;a href=&quot;https://twitter.com/share?text=Migrating%20emails%20etc&amp;amp;url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F102394.html&amp;amp;via=wrengr&quot; class=&quot;btn&quot; title=&quot;Share on Twitter&quot; target=&quot;_blank&quot;&gt;Twitter&lt;/a&gt;
&lt;a href=&quot;https://www.facebook.com/sharer/sharer.php?u=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F102394.html&amp;amp;t=Migrating%20emails%20etc&quot; class=&quot;btn&quot; title=&quot;Share on Facebook&quot; target=&quot;_blank&quot;&gt;Facebook&lt;/a&gt;
&lt;a href=&quot;https://plus.google.com/share?url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F102394.html&quot; class=&quot;btn&quot; title=&quot;Share on Google+&quot; target=&quot;_blank&quot;&gt;Google+&lt;/a&gt;
&lt;a href=&quot;http://www.tumblr.com/share/link?url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F102394.html&amp;amp;name=Migrating%20emails%20etc&quot; class=&quot;btn&quot; title=&quot;Share on Tumblr&quot; target=&quot;_blank&quot;&gt;Tumblr&lt;/a&gt;
&lt;a href=&quot;http://wordpress.com/press-this.php?u=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F102394.html&amp;amp;t=Migrating%20emails%20etc&amp;amp;s=&quot; class=&quot;btn&quot; title=&quot;Share on WordPress&quot; target=&quot;_blank&quot;&gt;WordPress&lt;/a&gt;
&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=102394&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/102394.html</comments>
  <category>website update</category>
  <category>contact info</category>
  <category>haskell planet</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/102088.html</guid>
  <pubDate>Sat, 23 May 2015 03:14:26 GMT</pubDate>
  <title>New Website</title>
  <link>https://winterkoninkje.dreamwidth.org/102088.html</link>
  <description>&lt;p&gt;I have a new academic/professional website: &lt;a href=&quot;http://cl.indiana.edu/~wren/&quot;&gt;http://cl.indiana.edu/~wren/&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;There are still a few unfinished areas (e.g., my publications page), but hopefully I&apos;ll be finished with them shortly. The new site it built with &lt;a href=&quot;http://jaspervdj.be/hakyll&quot;&gt;Hakyll&lt;/a&gt; instead of &lt;a href=&quot;http://pbwdm.sourceforge.net/&quot;&gt;my old Google-Summer-of-Code static website generator&lt;/a&gt;. I&apos;m still learning how to implement my old workflow in Hakyll, and if I get the chance I&apos;ll write a few posts on how I&apos;ve set things up. Reading through other folks&apos; posts on how they use Hakyll have been very helpful, and I&apos;d like to give back to the community. I&apos;ve already issued a pull request for adding &lt;a href=&quot;https://github.com/jaspervdj/hakyll/pull/350&quot;&gt;two new combinators for defining template fields&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the meantime, if you notice any broken links from my old blog posts, please let me know.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=102088&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/102088.html</comments>
  <category>haskell planet</category>
  <category>website update</category>
  <category>academia</category>
  <lj:security>public</lj:security>
  <lj:reply-count>1</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/101420.html</guid>
  <pubDate>Thu, 02 Apr 2015 21:37:29 GMT</pubDate>
  <title>An introduction to recursive types</title>
  <link>https://winterkoninkje.dreamwidth.org/101420.html</link>
  <description>&lt;p&gt;The past couple weeks I&apos;ve been teaching about recursive types and their encodings in B522. Here&apos;s a short annotated bibliography for followup reading:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;For a basic intro to recursive types, and for the set-theoretic metatheory: see section IV, chapters 20 and 21.
	&lt;ul&gt;&lt;li&gt;Benjamin C. Pierce (2002) &lt;i&gt;Types and Programming Languages.&lt;/i&gt; MIT Press.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;The proof of logical inconsistency and non-termination is &quot;well-known&quot;. For every type &lt;code&gt;τ&lt;/code&gt; we can define a fixed-point combinator and use that to exhibit an inhabitant of the type:
	&lt;ul&gt;&lt;li&gt;&lt;code&gt;fix&lt;sub&gt;τ&lt;/sub&gt; = λf:(τ→τ). let e = λx:(μα.α→τ). f (x (unroll x)) in e (roll&lt;sub&gt;(μα.α→τ)&lt;/sub&gt; e)&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;⊥&lt;sub&gt;τ&lt;/sub&gt; = fix&lt;sub&gt;τ&lt;/sub&gt; (λx:τ. x)&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;A category-theoretic proof that having fixed-points causes inconsistency
	&lt;ul&gt;&lt;li&gt;Hagen Huwig and Axel Poigné (1990) &lt;a href=&quot;http://www.sciencedirect.com/science/article/pii/030439759090165E&quot;&gt;&lt;i&gt;A note on inconsistencies caused by fixpoints in a Cartesian Closed Category.&lt;/i&gt;&lt;/a&gt; Theoretical Computer Science, 73:101–112.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;The proof of Turing-completeness is &quot;well-known&quot;. Here&apos;s a translation from the untyped λ-calculus to STLC with fixed-points:
	&lt;ul&gt;&lt;li&gt;&lt;code&gt;(x)&lt;sup&gt;*&lt;/sup&gt; = x&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;(λx. e)&lt;sup&gt;*&lt;/sup&gt; = roll&lt;sub&gt;(μα.α→α)&lt;/sub&gt; (λx:(μα.α→α). e&lt;sup&gt;*&lt;/sup&gt;)&lt;/code&gt;&lt;/li&gt;&lt;li&gt;&lt;code&gt;(f e)&lt;sup&gt;*&lt;/sup&gt; = unroll (f&lt;sup&gt;*&lt;/sup&gt;) (e&lt;sup&gt;*&lt;/sup&gt;)&lt;/code&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Knaster–Tarski (1955): For any monotone function, &lt;code&gt;f&lt;/code&gt;, (a) the least fixed-point of &lt;code&gt;f&lt;/code&gt; is the intersection of all &lt;code&gt;f&lt;/code&gt;-closed sets, and (b) the greatest fixed-point of &lt;code&gt;f&lt;/code&gt; is the union of all &lt;code&gt;f&lt;/code&gt;-consistent sets.
	&lt;ul&gt;&lt;li&gt;Alfred Tarski (1955) &lt;a href=&quot;http://projecteuclid.org/euclid.pjm/1103044538&quot;&gt;&lt;i&gt;A lattice-theoretical fixpoint theorem and its applications.&lt;/i&gt;&lt;/a&gt; Pacific Journal of Mathematics 5(2):285–309.&lt;/li&gt;
	&lt;li&gt;Bronisław Knaster (1928) &lt;i&gt;Un théorème sur les fonctions d&apos;ensembles.&lt;/i&gt; Annales de la Société Polonaise de Mathématique, 6:133–134.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;For a quick introduction to category theory, a good place to start is:
	&lt;ul&gt;&lt;li&gt;Benjamin C. Pierce (1991) &lt;i&gt;Basic Category Theory for Computer Scientists.&lt;/i&gt; MIT Press.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;For a more thorough introduction to category theory, consider:
	&lt;ul&gt;&lt;li&gt;Jiří Adámek, Horst Herrlich, and George Strecker (1990) &lt;a href=&quot;http://katmat.math.uni-bremen.de/acc/&quot;&gt;&lt;i&gt;Abstract and Concrete Categories: The Joy of Cats.&lt;/i&gt;&lt;/a&gt; John Wiley and Sons.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;The Boehm–Berarducci encoding 
	&lt;ul&gt;&lt;li&gt;Oleg Kiselyov (2012) &lt;a href=&quot;http://okmij.org/ftp/tagless-final/course/Boehm-Berarducci.html&quot;&gt;&lt;i&gt;Beyond Church encoding: Boehm–Berarducci isomorphism of algebraic data types and polymorphic lambda-terms&lt;/i&gt;&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;Corrado Boehm and Alessandro Berarducci (1985) &lt;i&gt;Automatic Synthesis of Typed Lambda-Programs on Term Algebras.&lt;/i&gt; Theoretical Computer Science, v39:135–154&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Under βη-equivalence, Church/Boehm–Berarducci encodings are only weakly initial (hence, can define functions by recursion but can&apos;t prove properties by induction)
	&lt;ul&gt;&lt;li&gt;Herman Geuvers (1992) &lt;a href=&quot;http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.35.9758&quot;&gt;&lt;i&gt;Inductive and Coinductive types with Iteration and Recursion.&lt;/i&gt;&lt;/a&gt; Proceedings of the 1992 Workshop on Types for Proofs and Programs, pp. 193–217&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;However, using contextual equivalence, Church/Boehm–Berarducci encodings are (strongly) initial
	&lt;ul&gt;&lt;li&gt;Neel Krishnaswami (2009) &lt;a href=&quot;https://golem.ph.utexas.edu/category/2009/12/syntax_semantics_and_structura_1.html#c030257&quot;&gt;mentions in passing&lt;/a&gt; [Better citation needed]&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Surjective pairing cannot be encoded in STLC (i.e., the implicational fragment of intuitionistic propositional logic): see p.155
	&lt;ul&gt;&lt;li&gt;Morten H. Sørensen and Paweł Urzyczyn (2006) &lt;i&gt;Lectures on the Curry–Howard isomorphism.&lt;/i&gt; Studies in Logic and the Foundations of Mathematics, v.149.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;However, adding it is a conservative extension
	&lt;ul&gt;&lt;li&gt;Roel de Vrijer (1987) &lt;i&gt;Surjective Pairing and Strong Normalization: Two themes in lambda calculus.&lt;/i&gt; dissertation, University of Amsterdam.&lt;/li&gt;
	&lt;li&gt;Roel de Vrijer (1989) &lt;i&gt;Extending the lambda calculus with surjective pairing is conservative.&lt;/i&gt; 4th LICS, pp.204–215.&lt;/li&gt;
	&lt;li&gt;Kristian Støvring (2005) &lt;a href=&quot;http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.164.3706&quot;&gt;&lt;i&gt;Extending the Extensional Lambda Calculus with Surjective Pairing is Conservative.&lt;/i&gt;&lt;/a&gt; BRICS.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Boehm–Berarducci encoded pairs is not surjective pairing: the η-rule for Boehm–Berarducci encoding of pairs cannot be derived in System F. (The instances for closed terms can be, just not the general rule.)
	&lt;ul&gt;&lt;li&gt;Peter Selinger &lt;a href=&quot;http://www.mathstat.dal.ca/~selinger/papers/lambdanotes.pdf&quot;&gt;mentions in passing (p.77)&lt;/a&gt; [Better citation needed]&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Compiling data types with Scott encodings
	&lt;ul&gt;&lt;li&gt;Jan Martin Jansen, Pieter Koopman, and Rinus Plasmeijer (200X) &lt;a href=&quot;http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.76.5557&quot;&gt;&lt;i&gt;Data Types and Pattern Matching by Function Application.&lt;/i&gt;&lt;/a&gt;&lt;/li&gt;
	&lt;li&gt;Jan Martin Jansen, Pieter Koopman, and Rinus Plasmeijer (2006) &lt;a href=&quot;http://www.nlda-tw.nl/janmartin/papers/jmjansenTFP2006.pdf&quot;&gt;&lt;i&gt;Efficient Interpretation by Transforming Data Types and Patterns to Functions.&lt;/i&gt;&lt;/a&gt; Trends in Functional Programming.&lt;/li&gt;
	&lt;li&gt;Jan Martin Jansen, Rinus Plasmeijer, and Pieter Koopman (2010) &lt;a href=&quot;http://hbo-kennisbank.uvt.nl/cgi/nda/show.cgi?fid=2381&quot;&gt;&lt;i&gt;Comprehensive Encoding of Data Types and Algorithms in the λ-Calculus.&lt;/i&gt;&lt;/a&gt; J. Functional Programming.&lt;/li&gt;
	&lt;li&gt;Pieter Koopman, Rinus Plasmeijer, and Jan Martin Jansen (2014) &lt;a href=&quot;https://ifl2014.github.io/submissions/ifl2014_submission_13.pdf&quot;&gt;&lt;i&gt;Church encoding of data types considered harmful for implementations.&lt;/i&gt;&lt;/a&gt; IFL submission&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;For more on the difference between Scott and Mogensten–Scott encodings:
	&lt;ul&gt;&lt;li&gt;Aaron Stump (2009) &lt;a href=&quot;http://homepage.cs.uiowa.edu/~astump/classes/185/archon.pdf&quot;&gt;&lt;i&gt;Directly Reflective Meta-Programming.&lt;/i&gt;&lt;/a&gt; J. Higher Order and Symbolic Computation, 22(2):115–144.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Parigot encodings
	&lt;ul&gt;&lt;li&gt;M. Parigot (1988) &lt;i&gt;Programming with proofs: A second-order type theory.&lt;/i&gt; ESOP, LNCS 300, pp.145–159. Springer.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;Parigot encoding of natural numbers is not canonical (i.e., there exist terms of the correct type which do not represent numbers); though both Church/Boehm–Berarducci and Scott encoded natural numbers are.
	&lt;ul&gt;&lt;li&gt;Herman Geuvers (2014) &lt;a href=&quot;http://www.cs.ru.nl/~herman/talk-Types2014Paris-May_ChurchScott.pdf&quot;&gt;mentions in passing&lt;/a&gt; [Better citation needed]&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;For more on catamorphisms, anamorphisms, paramorphisms, and apomorphisms
	&lt;ul&gt;&lt;li&gt;Varmo Vene and Tarmo Uustalu (1998) &lt;a href=&quot;http://cs.ioc.ee/~tarmo/papers/nwpt97-peas.pdf&quot;&gt;&lt;i&gt;Functional programming with apomorphisms (corecursion).&lt;/i&gt;&lt;/a&gt; In Proc. Estonian Acad. Sci. Phys. Math., 47:147–161&lt;/li&gt;
	&lt;li&gt;Erik Meijer, Maarten Fokkinga, and Ross Paterson (1991) &lt;a href=&quot;http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125&quot;&gt;&lt;i&gt;Functional Programming with Bananas, Lenses, Envelopes, and Barbed Wire.&lt;/i&gt;&lt;/a&gt; In Proc. 5th ACM conference on Functional programming languages and computer architecture, pp.124–144
		&lt;ul&gt;&lt;li&gt;&lt;a href=&quot;http://blog.ezyang.com/2010/05/bananas-lenses-envelopes-and-barbed-wire-a-translation-guide/&quot;&gt;A translation of Squiggol into Haskell by Edward Yang.&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;build/foldr list fusion
	&lt;ul&gt;&lt;li&gt;Andy Gill, John Launchbury, and Simon Peyton Jones (1993) &lt;a href=&quot;http://dl.acm.org/citation.cfm?doid=165180.165214&quot;&gt;&lt;i&gt;A short cut to deforestation.&lt;/i&gt;&lt;/a&gt; In Proc. Functional Programming Languages and Computer Architecture, pp.223–232.&lt;/li&gt;
	&lt;li&gt;Many more links at the bottom of &lt;a href=&quot;https://wiki.haskell.org/Correctness_of_short_cut_fusion&quot;&gt;this page&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;For another general introduction along the lines of what we covered in class
	&lt;ul&gt;&lt;li&gt;Philip Wadler (1990) &lt;a href=&quot;http://homepages.inf.ed.ac.uk/wadler/papers/free-rectypes/free-rectypes.txt&quot;&gt;&lt;i&gt;Recursive types for free!&lt;/i&gt;&lt;/a&gt;&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;&quot;Iterators&quot; vs &quot;recursors&quot; in Heyting arithmetic and Gödel&apos;s System T: see ch.10:
	&lt;ul&gt;&lt;li&gt;Morten H. Sørensen and Paweł Urzyczyn (2006) &lt;i&gt;Lectures on the Curry–Howard isomorphism&lt;/i&gt; Studies in Logic and the Foundations of Mathematics, v.149.&lt;/li&gt;&lt;/ul&gt;&lt;/li&gt;
&lt;li&gt;There are a great many more papers by Tarmo Uustalu, Varmo Vene, Ralf Hinze, and Jeremy Gibbons on all this stuff; just google for it.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&quot;btn-group&quot;&gt;
&lt;a href=&quot;https://twitter.com/share?via=wrengr&amp;amp;url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F101420.html&amp;amp;text=An%20introduction%20to%20recursive%20types&quot; class=&quot;btn&quot; title=&quot;Share on Twitter&quot; target=&quot;_blank&quot;&gt;Twitter&lt;/a&gt;
&lt;a href=&quot;https://www.facebook.com/sharer/sharer.php?u=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F101420.html&amp;amp;t=An%20introduction%20to%20recursive%20types&quot; class=&quot;btn&quot; title=&quot;Share on Facebook&quot; target=&quot;_blank&quot;&gt;Facebook&lt;/a&gt;
&lt;a href=&quot;https://plus.google.com/share?url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F101420.html&quot; class=&quot;btn&quot; title=&quot;Share on Google+&quot; target=&quot;_blank&quot;&gt;Google+&lt;/a&gt;
&lt;a href=&quot;http://www.tumblr.com/share/link?url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F101420.html&amp;amp;name=An%20introduction%20to%20recursive%20types&quot; class=&quot;btn&quot; title=&quot;Share on Tumblr&quot; target=&quot;_blank&quot;&gt;Tumblr&lt;/a&gt;
&lt;a href=&quot;http://wordpress.com/press-this.php?u=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F101420.html&amp;amp;t=An%20introduction%20to%20recursive%20types&amp;amp;s=&quot; class=&quot;btn&quot; title=&quot;Share on WordPress&quot; target=&quot;_blank&quot;&gt;WordPress&lt;/a&gt;
&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=101420&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/101420.html</comments>
  <category>grad school</category>
  <category>type theory</category>
  <category>haskell planet</category>
  <category>category theory</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/100615.html</guid>
  <pubDate>Tue, 20 Jan 2015 05:39:59 GMT</pubDate>
  <title>Back in action</title>
  <link>https://winterkoninkje.dreamwidth.org/100615.html</link>
  <description>&lt;p&gt;I don&apos;t think I ever mentioned it here but, last semester I took a much-needed sabbatical. The main thing was to take a break from all the pressures of work and grad school and get back into a healthy headspace. Along the way I ended up pretty much dropping off the internet entirely. So if you&apos;ve been missing me from various mailing lists and online communities, that&apos;s why. I&apos;m back now. If you&apos;ve tried getting in touch by email, irc, etc, and don&apos;t hear from me in the next few weeks, feel free ping me again.&lt;/p&gt;

&lt;p&gt;This semester I&apos;m teaching &lt;a href=&quot;http://homes.soic.indiana.edu/classes/spring2015/csci/b522-jsiek/&quot;&gt;foundations of programming language theory&lt;/a&gt; with &lt;a href=&quot;http://siek.blogspot.com/&quot;&gt;Jeremy Siek&lt;/a&gt;, and work on the dissertation continues apace. Over the break I had a few breakthrough moments thinking about the type system for chiastic lambda-calculi— which should help to clean up the normal forms for terms, as well as making room for extending the theory to include eta-conversion. Once the dust settles a bit I&apos;ll write some posts about it, as well as continuing the &lt;code&gt;unification-fd&lt;/code&gt; tutorial I started last month.&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=100615&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/100615.html</comments>
  <category>personal</category>
  <category>haskell planet</category>
  <category>grad school</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
<item>
  <guid isPermaLink='true'>https://winterkoninkje.dreamwidth.org/100478.html</guid>
  <pubDate>Fri, 12 Dec 2014 21:22:07 GMT</pubDate>
  <title>Unification-fd tutorial (part 1/n)</title>
  <link>https://winterkoninkje.dreamwidth.org/100478.html</link>
  <description>&lt;p&gt;A while back I released the &lt;i&gt;unification-fd&lt;/i&gt; library, which gives a generic implementation of first-order unification of non-cyclic terms. I&apos;ve given a few talks on how the library is implemented and what optimizations it performs, but that&apos;s not the topic for today. Today, I&apos;m going to talk about how to &lt;i&gt;use&lt;/i&gt; it.&lt;/p&gt;

&lt;p&gt;Unification is a widely useful operation and, consequently, comes in many different flavors. The version currently supported by the library is the sort used by logic programming languages like Prolog, Curry, Dyna, and MiniKanren; which is the same sort that&apos;s used for unification-based type inference algorithms like Hindley–Damas–Milner. Of these two examples, the logic programming example is the simpler one to discuss— at least for folks who&apos;ve used a language like Prolog before. So let&apos;s start from there.&lt;/p&gt;

&lt;p&gt;&lt;i&gt;Caveat Emptor:&lt;/i&gt; This post is something of a stream of consciousness. I&apos;ve gotten a few requests for tutorials on how to use the library, but the requests weren&apos;t terribly specific about what problems people&apos;ve had or what&apos;s been difficult to figure out. So I&apos;m shooting in the dark as far as what folks need and how much background they have. I&apos;m going to assume you&apos;re familiar with Prolog and the basics of what unification is and does.&lt;/p&gt;

&lt;p&gt;&lt;i&gt;Preemptive apology:&lt;/i&gt; I started writing this post months and months (and months) ago, but unintentionally dropped it after running into a certain issue and then getting distracted and moving onto other things. Actually, this happened at least twice. I&apos;m terribly sorry about that. So, apologies for not tackling the disjunction issue in this post. I&apos;ll come back to it later, but figured this post really needs to get out the door already.&lt;/p&gt;

&lt;h3&gt;Logic Terms&lt;/h3&gt;

&lt;p&gt;A &lt;b&gt;&lt;i&gt;term&lt;/i&gt;&lt;/b&gt;, in Prolog, is just a fancy name for a value of some algebraic data type. In most variants of Prolog there&apos;s no explicit definition of the ADT, no restriction on what the constructors are, and no type checking to ensure that subterms have a particular shape. That is, Prolog is what&apos;s called a single-sorted logic; in other words, Prolog is an untyped/unityped language. With &lt;i&gt;unification-fd&lt;/i&gt; we can implement multi-sorted (aka typed) logics, but for this tutorial we&apos;re going to stick with Prolog&apos;s single-sorted approach.&lt;/p&gt;

&lt;p&gt;Opening up &lt;code&gt;Control.Unification&lt;/code&gt; we&apos;ll see a handful of types and type classes, followed by a bunch of operators. The &lt;code&gt;UTerm&lt;/code&gt; data type captures the recursive structure of logic terms. (&lt;code&gt;UTerm&lt;/code&gt; is the free monad, if you&apos;re familiar with that terminology.) That is, given some functor &lt;code&gt;t&lt;/code&gt; which describes the constructors of our logic terms, and some type &lt;code&gt;v&lt;/code&gt; which describes our logic variables, the type &lt;code&gt;UTerm t v&lt;/code&gt; is the type of logic terms: trees with multiple layers of &lt;code&gt;t&lt;/code&gt; structure and leaves of type &lt;code&gt;v&lt;/code&gt;. For our single-sorted logic, here&apos;s an implementation of &lt;code&gt;t&lt;/code&gt;:&lt;/p&gt;

&lt;blockquote&gt;&lt;code&gt;&lt;pre&gt;data T a = T String [a]&lt;/pre&gt;&lt;/code&gt;&lt;/blockquote&gt;

&lt;p&gt;The &lt;code&gt;String&lt;/code&gt; gives the name of the term constructor, and the list gives the ordered sequence of subterms. Thus, the Prolog term &lt;code&gt;foo(bar,baz(X))&lt;/code&gt; would be implemented as &lt;code&gt;UTerm$T &quot;foo&quot; [UTerm$T &quot;bar&quot; [], UTerm$T &quot;baz&quot; [UVar x]]&lt;/code&gt;. If we&apos;re going to be building these terms directly, then we probably want to define some smart constructors to reduce the syntactic noise:&lt;/p&gt;

&lt;blockquote&gt;&lt;code&gt;&lt;pre&gt;foo x y = UTerm$T &quot;foo&quot; [x,y]
bar     = UTerm$T &quot;bar&quot; []
baz x   = UTerm$T &quot;baz&quot; [x]&lt;/pre&gt;&lt;/code&gt;&lt;/blockquote&gt;

&lt;p&gt;Now, we can implement the Prolog term as &lt;code&gt;foo bar (baz x)&lt;/code&gt;. If you prefer a more Prolog-like syntax, you can use uncurried definitions for smart constructors that take more than one argument.&lt;/p&gt;

&lt;h3&gt;Unifiable&lt;/h3&gt;

&lt;p&gt;In order to use our &lt;code&gt;T&lt;/code&gt; data type with the rest of the API, we&apos;ll need to give a &lt;code&gt;Unifiable&lt;/code&gt; instance for it. Before we do that we&apos;ll have to give &lt;code&gt;Functor&lt;/code&gt;, &lt;code&gt;Foldable&lt;/code&gt;, and &lt;code&gt;Traversable&lt;/code&gt; instances. These are straightforward and can be automatically derived with the appropriate language pragmas.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Unifiable&lt;/code&gt; class gives one step of the unification process. Just as we only need to specify one level of the ADT (i.e., &lt;code&gt;T&lt;/code&gt;) and then we can use the library&apos;s &lt;code&gt;UTerm&lt;/code&gt; to generate the recursive ADT, so too we only need to specify one level of the unification (i.e., &lt;code&gt;zipMatch&lt;/code&gt;) and then we can use the library&apos;s operators to perform the recursive unification, subsumption, etc.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;zipMatch&lt;/code&gt; function takes two arguments of type &lt;code&gt;t a&lt;/code&gt;. The abstract &lt;code&gt;t&lt;/code&gt; will be our concrete &lt;code&gt;T&lt;/code&gt; type. The abstract &lt;code&gt;a&lt;/code&gt; is polymorphic, which ensures that we can&apos;t mess around with more than one level of the term at once. If we abandon that guarantee, then you can think of it as if &lt;code&gt;a&lt;/code&gt; is &lt;code&gt;UTerm T v&lt;/code&gt;. Thus,&lt;code&gt;t a&lt;/code&gt; means &lt;code&gt;T (UTerm T v)&lt;/code&gt;; and &lt;code&gt;T (UTerm T v)&lt;/code&gt; is essentially the type &lt;code&gt;UTerm T v&lt;/code&gt; with the added guarantee that the values aren&apos;t in fact variables. Thus, the arguments to &lt;code&gt;zipMatch&lt;/code&gt; are non-variable terms.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;zipMatch&lt;/code&gt; method has the rather complicated return type: &lt;code&gt;Maybe (t (Either a (a,a)))&lt;/code&gt;. Let&apos;s unpack this a bit by thinking about how unification works. When we try to unify two terms, first we look at their head constructors. If the constructors are different, then the terms aren&apos;t unifiable, so we return &lt;code&gt;Nothing&lt;/code&gt; to indicate that unification has failed. Otherwise, the constructors match, so we have to recursively unify their subterms. Since the &lt;code&gt;T&lt;/code&gt; structures of the two terms match, we can return &lt;code&gt;Just t0&lt;/code&gt; where &lt;code&gt;t0&lt;/code&gt; has the same &lt;code&gt;T&lt;/code&gt; structure as both input terms. Where we still have to recursively unify subterms, we fill &lt;code&gt;t0&lt;/code&gt; with &lt;code&gt;Right(l,r)&lt;/code&gt; values where &lt;code&gt;l&lt;/code&gt; is a subterm of the left argument to &lt;code&gt;zipMatch&lt;/code&gt; and &lt;code&gt;r&lt;/code&gt; is the corresponding subterm of the right argument. Thus, &lt;code&gt;zipMatch&lt;/code&gt; is a generalized zipping function for combining the shared structure and pairing up substructures. And now, the implementation:&lt;/p&gt;

&lt;blockquote&gt;&lt;code&gt;&lt;pre&gt;instance Unifiable T where
    zipMatch (T m ls) (T n rs)
        | m /= n    = Nothing
        | otherwise =
            T n &amp;lt;$&amp;gt; pairWith (\l r -&amp;gt; Right(l,r)) ls rs&lt;/pre&gt;&lt;/code&gt;&lt;/blockquote&gt;

&lt;p&gt;Where &lt;a href=&quot;http://hackage.haskell.org/package/list-extras-0.4.1.3/docs/Data-List-Extras-Pair.html&quot;&gt;&lt;code&gt;list-extras:Data.List.Extras.Pair.pairWith&lt;/code&gt;&lt;/a&gt; is a version of &lt;code&gt;zip&lt;/code&gt; which returns &lt;code&gt;Nothing&lt;/code&gt; if the lists have different lengths. So, if the names &lt;code&gt;m&lt;/code&gt; and &lt;code&gt;n&lt;/code&gt; match, and if the two arguments have the same number of subterms, then we pair those subterms off in order; otherwise, either the names or the lengths don&apos;t match, so we return &lt;code&gt;Nothing&lt;/code&gt;.&lt;/p&gt;

&lt;h3&gt;Feature Structures&lt;/h3&gt;

&lt;p&gt;For the &lt;code&gt;T&lt;/code&gt; example, we don&apos;t need to worry about the &lt;code&gt;Left&lt;/code&gt; option. The reason it&apos;s there is to support feature structures and other sparse representations of terms. That is, consider the following type:&lt;/p&gt;

&lt;blockquote&gt;&lt;code&gt;&lt;pre&gt;newtype FS k a = FS (Map k a)&lt;/pre&gt;&lt;/code&gt;&lt;/blockquote&gt;

&lt;p&gt;Using this type, our logic terms are sets of key–subterm pairs. When unifying maps like these, what do we do if one argument has a binding for a particular key but the other argument does not? In the &lt;code&gt;T&lt;/code&gt; example we assumed that subterms which couldn&apos;t be paired together (because the lists were different lengths) meant the unification must fail. But for &lt;code&gt;FS&lt;/code&gt; it makes more sense to assume that terms which can&apos;t be paired up automatically succeed! That is, we&apos;d like to assume that all the keys which are not explicitly present in the &lt;code&gt;Map k a&lt;/code&gt; are implicitly present and each one is bound to a unique logic variable. Since the unique logic variables are implicit, there&apos;s no need to actually keep track of them, we&apos;ll just implicitly unify them with the subterm that can&apos;t be paired off.&lt;/p&gt;

&lt;p&gt;This may make more sense if you see the &lt;code&gt;Unifiable&lt;/code&gt; instance:&lt;/p&gt;

&lt;blockquote&gt;&lt;code&gt;&lt;pre&gt;instance (Ord k) =&amp;gt; Unifiable (FS k) where
    zipMatch (FS ls) (FS rs) =
        Just . FS $
            unionWith (\(Left l) (Left r) -&amp;gt; Right(l,r))
                (fmap Left ls)
                (fmap Left rs)&lt;/pre&gt;&lt;/code&gt;&lt;/blockquote&gt;

&lt;p&gt;We start off by mapping &lt;code&gt;Left&lt;/code&gt; over both the &lt;code&gt;ls&lt;/code&gt; and the &lt;code&gt;rs&lt;/code&gt;. We then call &lt;code&gt;unionWith&lt;/code&gt; to pair things up. For any given key, if both &lt;code&gt;ls&lt;/code&gt; and &lt;code&gt;rs&lt;/code&gt; specify a subterm, then these subterms will be paired up as &lt;code&gt;Right(l,r)&lt;/code&gt;. If we have extra subterms from either &lt;code&gt;ls&lt;/code&gt; or &lt;code&gt;rs&lt;/code&gt;, however, then we keep them around as &lt;code&gt;Left l&lt;/code&gt; or &lt;code&gt;Left r&lt;/code&gt;. Thus, the &lt;code&gt;Unifiable&lt;/code&gt; instance for &lt;code&gt;FS&lt;/code&gt; performs a union of the &lt;code&gt;FS&lt;/code&gt; structure, whereas the instance for &lt;code&gt;T&lt;/code&gt; performs an intersection of &lt;code&gt;T&lt;/code&gt; structure.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;Left&lt;/code&gt; option can be used in any situation where you can immediately resolve the unification of subterms, whereas the &lt;code&gt;Right&lt;/code&gt; option says you still have work to do.&lt;sup&gt;&lt;a href=&quot;#100478:fn1&quot; name=&quot;100478:fnref1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;h3&gt;Logic Variables&lt;/h3&gt;

&lt;p&gt;The library ships with two implementations of logic variables. The &lt;code&gt;IntVar&lt;/code&gt; implementation uses &lt;code&gt;Int&lt;/code&gt; as the names of variables, and uses an &lt;code&gt;IntMap&lt;/code&gt; to keep track of the environment. The &lt;code&gt;STVar&lt;/code&gt; implementation uses &lt;code&gt;STRef&lt;/code&gt;s, so we can use actual mutation for binding logic variables, rather than keeping an explicit environment around. Of course, mutation complicates things, so the two implementations have different pros and cons.&lt;/p&gt;

&lt;p&gt;Performing unification has the side effect of binding logic variables to terms. Thus, we&apos;ll want to use a monad in order to keep track of these effects. The &lt;code&gt;BindingMonad&lt;/code&gt; type class provides the definition of what we need from our ambient monad. In particular, we need to be able to generate fresh logic variables, to bind logic variables, and to lookup what our logic variables are bound to. The library provides the necessary instances for both &lt;code&gt;IntVar&lt;/code&gt; and &lt;code&gt;STVar&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;You can, of course, provide your own implementations of &lt;code&gt;Variable&lt;/code&gt; and &lt;code&gt;BindingMonad&lt;/code&gt;. However, doing so is beyond the scope of the current tutorial. For simplicity, we&apos;ll use the &lt;code&gt;IntVar&lt;/code&gt; implementation below.&lt;/p&gt;

&lt;h3&gt;Example Programs&lt;/h3&gt;

&lt;p&gt;When embedding Prolog programs into Haskell, the main operators we want to consider are those in the section titled &quot;Operations on two terms&quot;. These are structural equality (i.e., equality modulo substitution), structural equivalence (i.e., structural equality modulo alpha-variance), unification, and subsumption.&lt;/p&gt;

&lt;p&gt;Consider the following Horn clause in Prolog:&lt;/p&gt;

&lt;blockquote&gt;&lt;code&gt;&lt;pre&gt;example1(X,Y,Z) :- X = Y, Y = Z.&lt;/pre&gt;&lt;/code&gt;&lt;/blockquote&gt;

&lt;p&gt;To implement this in Haskell we want a function which takes in three arguments, unifies the first two, and then unifies the second two. Thus,&lt;sup&gt;&lt;a href=&quot;#100478:fn2&quot; name=&quot;100478:fnref2&quot;&gt;2&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;blockquote&gt;&lt;code&gt;&lt;pre&gt;example1 x y z = do
    x =:= y
    y =:= z&lt;/pre&gt;&lt;/code&gt;&lt;/blockquote&gt;

&lt;p&gt;To run this program we&apos;d use one of the functions &lt;code&gt;runIntBindingT&lt;/code&gt;, &lt;code&gt;evalIntBindingT&lt;/code&gt;, or &lt;code&gt;execIntBindingT&lt;/code&gt;, depending on whether we care about the binding state, the resulting logic term, or both. Of course, since the unifications may fail, we also need to run the underlying error monad, using something like &lt;code&gt;runErrorT&lt;/code&gt;&lt;sup&gt;&lt;a href=&quot;#100478:fn3&quot; name=&quot;100478:fnref3&quot;&gt;3&lt;/a&gt;,&lt;/sup&gt;&lt;sup&gt;&lt;a href=&quot;#100478:fn4&quot; name=&quot;100478:fnref4&quot;&gt;4&lt;/a&gt;&lt;/sup&gt;. And since these are both monad transformers, we&apos;ll need to use &lt;code&gt;runIdentity&lt;/code&gt; or the like in order to run the base monad. Thus, the functions to execute the entire monad stack will look like:&lt;/p&gt;

&lt;blockquote&gt;&lt;code&gt;&lt;pre&gt;-- Aliases to simplify our type signatures. N.B., the
-- signatures are not actually required to get things
-- to typecheck.
type PrologTerm           = UTerm T IntVar 
type PrologFailure        = UnificationFailure T IntVar
type PrologBindingState   = IntBindingState T

-- N.B., the @FallibleBindingMonad@ isn&apos;t yet a monad
-- for Prolog because it doesn&apos;t support backtracking.
type FallibleBindingMonad =
    ErrorT PrologFailure (IntBindingT T Identity)

-- N.B., this definition runs into certain issues.
type PrologMonad =
    ErrorT PrologFailure (IntBindingT T Logic)

runFBM
    :: FallibleBindingMonad a
    -&amp;gt; (Either PrologFailure a, PrologBindingState)
runFBM = runIdentity . runIntBindingT . runErrorT&lt;/pre&gt;&lt;/code&gt;&lt;/blockquote&gt;

&lt;p&gt;Here are some more examples:&lt;/p&gt;

&lt;blockquote&gt;&lt;code&gt;&lt;pre&gt;-- A helper function to reduce boilerplate. First we get
-- a free variable, then we embed it into @PrologTerm@,
-- and then we embed it into some error monad (for
-- capturing unification failures).
getFreeVar = lift (UVar &amp;lt;$&amp;gt; freeVar)

-- example2(X,Z) :- X = Y, Y = Z.
example2 x z = do
    y &amp;lt;- getFreeVar
    x =:= y
    y =:= z

-- example3(X,Z) :- example1(X,Y,Z).
example3 x z = do
    y &amp;lt;- getFreeVar
    example1 x y z

-- example4(X) :- X = bar; X = backtrack.
example4 x = (x =:= bar) &amp;lt;|&amp;gt; (x =:= atom &quot;backtrack&quot;)
&lt;/pre&gt;&lt;/code&gt;&lt;/blockquote&gt;

&lt;p&gt;The complete code for this post can be found &lt;a href=&quot;http://community.haskell.org/~wren/unification-fd/test/tutorial/tutorial1.hs&quot;&gt;here online&lt;/a&gt;, or at &lt;code&gt;./test/tutorial/tutorial1.hs&lt;/code&gt; in the Darcs repo. Notably, there are some complications about the semantics of &lt;code&gt;example4&lt;/code&gt;; it doesn&apos;t mean what you think it should mean. We&apos;ll tackle that problem and fix it later on in the tutorial series (in part 4 or thereabouts).&lt;/p&gt;

&lt;h3&gt;Term Factoring and Clause Resolution Automata (CRAs)&lt;/h3&gt;

&lt;p&gt;Note that for the above examples, the Haskell functions only execute the right-hand side of the Horn clause. In Prolog itself, there&apos;s also a process of searching through all the Horn clauses in a program and deciding which one to execute next. A naive way to implement that search process would be to have a list of all the Horn clauses and walk through it, trying to unify the goal with the left-hand side of each clause and executing the right-hand side if it matches. A more efficient way would be to compile all the right-hand sides into a single automaton, allowing us to match the goal against all the right-hand sides at once. (The idea here is similar to compiling a bunch of strings together into a trie or regex.)&lt;/p&gt;

&lt;p&gt;Constructing optimal CRAs is NP-complete in general, though it&apos;s feasible if we have an arbitrary ordering of clauses (e.g., Prolog&apos;s top–down order for trying each clause). The &lt;i&gt;unification-fd&lt;/i&gt; library does not implement any support for CRAs at present, though it&apos;s something I&apos;d like to add in the future. For more information on this topic, see &lt;a href=&quot;http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.49.6932&quot;&gt;Dawson et al. (1995) &lt;i&gt;Optimizing Clause Resolution: Beyond Unification Factoring&lt;/i&gt;&lt;/a&gt; and &lt;a href=&quot;http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.56.2895&quot;&gt;Dawson et al. (1996) &lt;i&gt;Principles and Practice of Unification Factoring&lt;/i&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;Other operators&lt;/h3&gt;

&lt;p&gt;In addition to unification itself, it&apos;s often helpful to have various other operators on hand.&lt;/p&gt;

&lt;p&gt;One such operator is the subsumption operator. Whereas unification looks for a most-general substitution which when applied to both arguments yields terms which are structurally equal (i.e., &lt;code&gt;l =:= r&lt;/code&gt; computes the most general &lt;code&gt;s&lt;/code&gt; such that &lt;code&gt;s l === s r&lt;/code&gt;), subsumption applies the substitution to only one side. That is, &lt;code&gt;l&lt;/code&gt; subsumes &lt;code&gt;r&lt;/code&gt; just in case &lt;code&gt;r&lt;/code&gt; is a substitution instance of &lt;code&gt;l&lt;/code&gt; (i.e., there exists a substitution &lt;code&gt;s&lt;/code&gt; such that &lt;code&gt;s l === r&lt;/code&gt;). The symbolic name &lt;code&gt;(&amp;lt;:=)&lt;/code&gt; comes from the fact that when &lt;code&gt;l&lt;/code&gt; subsumes &lt;code&gt;r&lt;/code&gt; we also say that &lt;code&gt;l&lt;/code&gt; is less defined&lt;sup&gt;&lt;a href=&quot;#100478:fn5&quot; name=&quot;100478:fnref5&quot;&gt;5&lt;/a&gt;&lt;/sup&gt; than &lt;code&gt;r&lt;/code&gt;. Subsumption shows up in cases where we have to hold &lt;code&gt;r&lt;/code&gt; fixed for some reason, such as when implementing polymorphism or subtyping.&lt;/p&gt;

&lt;p&gt;Other operators work on just one term, such as determining the free variables of a term, explicitly applying the ambient substitution to obtain a pure term, or cloning a term to make a copy where all the free variables have been renamed to fresh variables. These sorts of operators aren&apos;t used very often in logic programming itself, but are crucial for implementing logic programming languages.&lt;/p&gt;

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

&lt;p&gt;Hopefully that gives a quick idea of how the library&apos;s API is set up. Next time I&apos;ll walk through an implementation of Hindley–Damas–Milner type inference, and then higher-ranked polymorphism à la &lt;a href=&quot;http://research.microsoft.com/en-us/um/people/simonpj/papers/higher-rank/putting.pdf&quot;&gt;Peyton Jones et al. (2011) &lt;i&gt;Practical type inference for arbitrary-rank types&lt;/i&gt;&lt;/a&gt;. After that, I&apos;ll discuss the complications about backtracking choice I noticed when writing this post, and walk through how to fix them. If there&apos;s still interest after that, I can get into some of the guts of the library&apos;s implementation— like ranked path compression, maximal structure sharing, and so on.&lt;/p&gt;

&lt;p&gt;If you have any particular questions you&apos;d like me to address, drop me a line.&lt;/p&gt;

&lt;hr /&gt;
&lt;p&gt;&lt;a name=&quot;100478:fn1&quot;&gt;[1]&lt;/a&gt; Older versions of the library used the type &lt;code&gt;zipMatch :: forall a b. t a -&amp;gt; t b -&amp;gt; Maybe (t (a,b))&lt;/code&gt; in order to ensure that we did in fact properly pair up subterms from the two arguments. Unfortunately I had to relax that guarantee in order to add support for feature structures. &lt;a href=&quot;#100478:fnref1&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;100478:fn2&quot;&gt;[2]&lt;/a&gt; N.B., a more efficient implementation is:&lt;/p&gt;

&lt;blockquote&gt;&lt;code&gt;&lt;pre&gt;example1&apos; x y z = do
    y&apos; &amp;lt;- x =:= y
    y&apos; =:= z&lt;/pre&gt;&lt;/code&gt;&lt;/blockquote&gt;

&lt;p&gt;The unification operator returns a new term which guarantees maximal structure sharing with both of its arguments. The implementation of unification makes use of observable structure sharing, so by capturing &lt;code&gt;y&apos;&lt;/code&gt; and using it in lieu of &lt;code&gt;y&lt;/code&gt;, the subsequent unifications can avoid redundant work. &lt;a href=&quot;#100478:fnref2&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;100478:fn3&quot;&gt;[3]&lt;/a&gt; The &lt;code&gt;ErrorT&lt;/code&gt; transformer was deprecated by &lt;i&gt;transformers-0.4.1.0&lt;/i&gt;, though it still works for this tutorial. Unfortunately, the preferred &lt;code&gt;ExceptT&lt;/code&gt; does not work since &lt;code&gt;UnificationFailure&lt;/code&gt; doesn&apos;t have a &lt;code&gt;Monoid&lt;/code&gt; instance as of &lt;i&gt;unification-fd-0.9.0&lt;/i&gt;. The definition of &lt;code&gt;UnificationFailure&lt;/code&gt; already contains a hack to get it to work with &lt;code&gt;ErrorT&lt;/code&gt;, but future versions of the library will remove that hack and will require users to specify their own monoid for combining errors. The &lt;code&gt;First&lt;/code&gt; monoid captures the current behavior, though one may prefer to use other monoids such as a monoid that gives a trace of the full execution path, or witnesses for all the backtracks, etc. &lt;a href=&quot;#100478:fnref3&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;100478:fn4&quot;&gt;[4]&lt;/a&gt; To be honest, I don&apos;t entirely recall why I had the error monad explicitly separated out as a monad transformer over the binding monad, rather than allowing these two layers to be combined. Since it&apos;s so awkward, I&apos;m sure there was some reason behind it, I just failed to make note of why. If there turns out to be no decent reason for it, future versions of the library may remove this fine-grain distinction. &lt;a href=&quot;#100478:fnref4&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a name=&quot;100478:fn5&quot;&gt;[5]&lt;/a&gt; The symbolic name for subsumption is chosen to reflect the meaning of more/less defined (rather than more/less grounded) so that the subsumption ordering coincides with the domain ordering (think of logic variables as being bottom). This is the standard direction for looking at subsumption; though, of course, we could always consider the dual ordering instead. &lt;a href=&quot;#100478:fnref5&quot;&gt;↩&lt;/a&gt;&lt;/p&gt;


&lt;div class=&quot;btn-group&quot;&gt;
&lt;a href=&quot;https://twitter.com/share?via=wrengr&amp;amp;url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F100478.html&amp;amp;text=Unification-fd%20tutorial%20(part%201%2Fn)&quot; class=&quot;btn&quot; title=&quot;Share on Twitter&quot; target=&quot;_blank&quot;&gt;Twitter&lt;/a&gt;
&lt;a href=&quot;https://www.facebook.com/sharer/sharer.php?u=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F100478.html&amp;amp;t=Unification-fd%20tutorial%20(part%201%2Fn)&quot; class=&quot;btn&quot; title=&quot;Share on Facebook&quot; target=&quot;_blank&quot;&gt;Facebook&lt;/a&gt;
&lt;a href=&quot;https://plus.google.com/share?url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F100478.html&quot; class=&quot;btn&quot; title=&quot;Share on Google+&quot; target=&quot;_blank&quot;&gt;Google+&lt;/a&gt;
&lt;a href=&quot;http://www.tumblr.com/share/link?url=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F100478.html&amp;amp;name=Unification-fd%20tutorial%20(part%201%2Fn)&quot; class=&quot;btn&quot; title=&quot;Share on Tumblr&quot; target=&quot;_blank&quot;&gt;Tumblr&lt;/a&gt;
&lt;a href=&quot;http://wordpress.com/press-this.php?u=http%3A%2F%2Fwinterkoninkje.dreamwidth.org%2F100478.html&amp;amp;t=Unification-fd%20tutorial%20(part%201%2Fn)&amp;amp;s=&quot; class=&quot;btn&quot; title=&quot;Share on WordPress&quot; target=&quot;_blank&quot;&gt;WordPress&lt;/a&gt;
&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;img src=&quot;https://www.dreamwidth.org/tools/commentcount?user=winterkoninkje&amp;ditemid=100478&quot; width=&quot;30&quot; height=&quot;12&quot; alt=&quot;comment count unavailable&quot; style=&quot;vertical-align: middle;&quot;/&gt; comments</description>
  <comments>https://winterkoninkje.dreamwidth.org/100478.html</comments>
  <category>haskell planet</category>
  <category>haskell</category>
  <category>unification</category>
  <lj:security>public</lj:security>
  <lj:reply-count>0</lj:reply-count>
</item>
</channel>
</rss>
