<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>ezyang's blog</title><link>https://blog.ezyang.com/</link><description>Recent content on ezyang's blog</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Fri, 17 Apr 2026 10:31:05 -0400</lastBuildDate><atom:link href="https://blog.ezyang.com/feed.xml" rel="self" type="application/rss+xml"/><item><title>OSS code review, in the era of LLMs</title><link>https://blog.ezyang.com/2026/04/oss-code-review-in-the-era-of-llms/</link><pubDate>Fri, 17 Apr 2026 10:31:05 -0400</pubDate><guid>https://blog.ezyang.com/2026/04/oss-code-review-in-the-era-of-llms/</guid><description>&lt;p>In &lt;a href="https://blog.ezyang.com/2025/12/code-review-as-human-alignment-in-the-era-of-llms/">Code review as human alignment, in the era of LLMs&lt;/a>, I talked about how we should approach code review with other team members, where you have a pre-existing relationship and care about building human-to-human alignment over time. However, popular open source projects also need to account for drive-by contributions from external contributors, where it is unclear if you want to invest in a long term relationship with these people. In the era of LLMs, it has never been easier to submit a pull request to a project, and consequently, many OSS projects have described being overwhelmed by a wave of slop AI pull requests. Some projects have responded by &lt;a href="https://github.com/tldraw/tldraw/issues/7695">simply refusing all external contributions&lt;/a>, while others have resorted to &lt;a href="https://github.com/ghostty-org/ghostty/blob/main/AI_POLICY.md">banning bad actors&lt;/a> with a quick trigger finger.&lt;/p></description></item><item><title>Autograd and Mutation</title><link>https://blog.ezyang.com/2026/03/autograd-and-mutation/</link><pubDate>Sat, 28 Mar 2026 23:23:32 -0400</pubDate><guid>https://blog.ezyang.com/2026/03/autograd-and-mutation/</guid><description>&lt;p>How does PyTorch autograd deal with mutation? In particular, what happens when a mutation occurs on a view, which aliases with some other tensor? In 2017, Sam Gross implemented support for &lt;a href="https://github.com/pytorch/pytorch/pull/3384">in-place operations on views&lt;/a>, but the details of which have never been described in plain English&amp;hellip; until now.&lt;/p>
&lt;h3 id="autograd-the-simple-case" id="autograd-the-simple-case">
 &lt;a class="heading-link" href="https://blog.ezyang.com/2026/03/autograd-and-mutation/#autograd-the-simple-case">Autograd, the simple case&lt;span class="heading-anchor" aria-label="Anchor">¶&lt;/span>&lt;/a>
&lt;/h3>
&lt;p>We all know that autograd operates by constructing a backwards graph as you execute the forwards of your model. Every time you execute an operation &lt;code>Op&lt;/code>, we generate an autograd node &lt;code>OpBackward&lt;/code> and record it on the &lt;code>grad_fn&lt;/code> of the resulting tensor. A diagram here is helpful. Consider this program:&lt;/p></description></item><item><title>Read Less, Steer More</title><link>https://blog.ezyang.com/2026/03/read-less-steer-more/</link><pubDate>Wed, 18 Mar 2026 15:26:58 -0400</pubDate><guid>https://blog.ezyang.com/2026/03/read-less-steer-more/</guid><description>&lt;p>I was coaching some juniors on effective use of AI coding agents (like, looking over their shoulder as they were prompting the LLMs) and one reoccurring theme was that the AI agents were demanding a lot more of their &lt;strong>reading code&lt;/strong> skills, compared to how they used to operate before. &amp;ldquo;How,&amp;rdquo; they asked, &amp;ldquo;can we get better at reading code?&amp;rdquo;&lt;/p>
&lt;p>I had to think about my answer to this, because even before AI, it&amp;rsquo;s always been difficult to make the jump from &amp;ldquo;I mostly write code&amp;rdquo; to &amp;ldquo;I spend all my time reviewing code other people have written.&amp;rdquo; There is some intrinsic difficulty about this; there has always been a shortage in the number of code reviewers, even without LLMs exacerbating the problem!&lt;/p></description></item><item><title>Parallel Agents ❤️ Sapling</title><link>https://blog.ezyang.com/2026/03/parallel-agents-heart-sapling/</link><pubDate>Fri, 13 Mar 2026 11:00:47 -0400</pubDate><guid>https://blog.ezyang.com/2026/03/parallel-agents-heart-sapling/</guid><description>&lt;p>Previously in &lt;a href="https://blog.ezyang.com/2026/03/ai-assisted-programming-for-spmd-types/">AI-assisted programming for spmd_types&lt;/a>, I mentioned that I have been enjoying using Sapling (the version control system Meta uses internally) to manage parallel agents on worktrees. In this post, I want to describe this workflow in more detail. The basic development flow here is I have three work streams going in parallel:&lt;/p>
&lt;ol>
&lt;li>I am working on enabling an end-to-end use case; in this case, enabling strict type-checking on a realistic codebase.&lt;/li>
&lt;li>I am adding new features and fixing bugs to the core library itself, as identified by (1).&lt;/li>
&lt;li>I am addressing code review comments and CI failures for the diffs produced by (2).&lt;/li>
&lt;/ol>
&lt;p>All of this is in the context of a single stack, the bottom of which is the feature diffs, and the top of which is the enablement diffs. I have multiple worktrees: one at the top for E2E enablement, one or more at the top of the feature diffs to add new features, and one or more inside the stack to address code review and fix CI. All of these are going in parallel, and so the problem is how to coordinate these parallel changes on a single source-of-truth stack. Git does terribly at this, but if you know the trick, Sapling does really well!&lt;/p></description></item><item><title>AI-assisted programming for spmd_types</title><link>https://blog.ezyang.com/2026/03/ai-assisted-programming-for-spmd-types/</link><pubDate>Tue, 10 Mar 2026 21:11:43 -0400</pubDate><guid>https://blog.ezyang.com/2026/03/ai-assisted-programming-for-spmd-types/</guid><description>&lt;p>&lt;a href="https://github.com/ezyang/spmd_types/tree/main/sixlib/spmd_types">spmd_types&lt;/a> is a type checker for distributed PyTorch programs. I&amp;rsquo;ll write a blog post about the system itself as it gets closer to completion, but in this post I want to talk about my workflow for AI-assisted programming in the project. In particular, &lt;code>spmd_types&lt;/code> is my first greenfield project that both:&lt;/p>
&lt;ol>
&lt;li>I have written it entirely with AI, and&lt;/li>
&lt;li>I am comfortable being accountable for it (in the same way I am accountable for my handwritten code).&lt;/li>
&lt;/ol>
&lt;p>I have encouraged others to also use AI as the primary mechanism of writing code for the codebase, but I have noticed that people get different outcomes (in terms of diff volume and number of review cycles), so I wanted to write down my workflow in case it was helpful for somebody.&lt;/p></description></item><item><title>Silent BC Breaking Changes</title><link>https://blog.ezyang.com/2026/03/silent-bc-breaking-changes/</link><pubDate>Mon, 02 Mar 2026 22:45:08 -0500</pubDate><guid>https://blog.ezyang.com/2026/03/silent-bc-breaking-changes/</guid><description>&lt;p>A &lt;strong>silent BC breaking change&lt;/strong> is a change of semantics in an API that is not immediately obvious; e.g., the old usages of the broken behavior won&amp;rsquo;t raise a compile or runtime error on upgrade. If you are a project that cares about backwards compatibility, it&amp;rsquo;s generally a bad idea to ship silent BC breaking changes, because they manifest as users getting silently incorrect results and having to painfully root cause the difference to a particular version upgrade. However, many bug fixes technically are silent BC breaking changes, especially when the old buggy behavior could conceivably be useful in certain circumstances. Load bearing bugs are often the reason why sometimes bug-for-bug compatibility is required.&lt;/p></description></item><item><title>Vibe Coding Design Study: tlparse</title><link>https://blog.ezyang.com/2026/02/vibe-coding-design-study-tlparse/</link><pubDate>Tue, 03 Feb 2026 22:35:59 -0500</pubDate><guid>https://blog.ezyang.com/2026/02/vibe-coding-design-study-tlparse/</guid><description>&lt;p>I recently received the following question about vibe-coding for &lt;a href="https://github.com/meta-pytorch/tlparse">tlparse&lt;/a>, a structured log parser for &lt;code>torch.compile&lt;/code> (slightly edited for ease of reading):&lt;/p>
&lt;blockquote>
&lt;p>Hi Ed, I have some thoughts on vibe-coding tlparse and I&amp;rsquo;m curious what your opinions are. I think it&amp;rsquo;s fairly easy to vibe code and improve tlparse, but it&amp;rsquo;s hard to find people who know Rust or HTML or JavaScript well to properly review the vibe-coded stuff. The Rust PRs are not impossible to review, but the JavaScript ones are certainly hard&amp;hellip; YOLO-landing PRs that we can&amp;rsquo;t review is certainly bad, I guess one option is just not landing any changes, and tell people to vibe-code themselves&amp;hellip;?&lt;/p></description></item><item><title>Replicate Forwards, Partial Backwards</title><link>https://blog.ezyang.com/2026/02/replicate-forwards-partial-backwards/</link><pubDate>Tue, 03 Feb 2026 10:10:25 -0500</pubDate><guid>https://blog.ezyang.com/2026/02/replicate-forwards-partial-backwards/</guid><description>&lt;p>A central thesis of &lt;a href="https://blog.ezyang.com/2026/01/jax-sharding-type-system/">sharding in types&lt;/a> is that the backward sharding can be directly computed from the forward sharding. This is not true for DTensor today, e.g., as seen in &lt;a href="https://blog.ezyang.com/2026/02/dtensor-erasure/#appendix">sum to Partial&lt;/a>, and it leads to confusion where users cannot easily predict what the sharding of tensors are in their program. The question now arises: given a forward sharding, what should its backward sharding be? There are some easy cases to fill in:&lt;/p></description></item><item><title>DTensor erasure</title><link>https://blog.ezyang.com/2026/02/dtensor-erasure/</link><pubDate>Sun, 01 Feb 2026 23:20:12 -0500</pubDate><guid>https://blog.ezyang.com/2026/02/dtensor-erasure/</guid><description>&lt;p>DTensor has famously terrible eager mode performance; for example, &lt;a href="https://arxiv.org/abs/2509.07003v1">this paper&lt;/a> measured a 35-60% slowdown in end-to-end training performance with and without DTensor (with DTensor operations taking at least 7x longer than actually running the computation for real). While it is possible to alleviate some of this slowdown via optimizations (in the paper, veScale shows fast bypass of sharding propagation, improved cache lookups and C++ code can take dispatch overhead to 30us), this is still too high for some settings.&lt;/p></description></item><item><title>The JAX sharding type system</title><link>https://blog.ezyang.com/2026/01/jax-sharding-type-system/</link><pubDate>Wed, 28 Jan 2026 09:00:50 -0500</pubDate><guid>https://blog.ezyang.com/2026/01/jax-sharding-type-system/</guid><description>&lt;p>Conventionally, a type system is something that classifies values into data types like &lt;code>float32&lt;/code> or &lt;code>int64&lt;/code>. However, fancy type systems go beyond data types, allowing us to talk about potentially arbitrary invariants on data; for example, if we were to talk about the &amp;ldquo;type&amp;rdquo; of a array, it would cover not only its data type, but also its shape, e.g., &lt;code>f32[40, 20]&lt;/code>. JAX&amp;rsquo;s type system of abstract values (avals) goes further than just data types and shapes and is equipped to reason about sharding related invariants. However, this type system is poorly documented, especially recent additions like reduced/unreduced axes (circa June 2025). In this blog post, I want to give a consolidated description of the sharding related aspects of JAX&amp;rsquo;s typing in explicit sharding mode, as of 2026. Disclaimer: I am not a JAX developer, and there may potentially be mistakes in this presentation; please let me know about errors in Twitter. I will assume that you have some knowledge about how to work with JAX sharding in the frontend; please refer to &lt;a href="https://docs.jax.dev/en/latest/notebooks/Distributed_arrays_and_automatic_parallelization.html">Distributed arrays and automatic parallelization&lt;/a>, &lt;a href="https://docs.jax.dev/en/latest/notebooks/explicit-sharding.html">Explicit sharding&lt;/a> and &lt;a href="https://docs.jax.dev/en/latest/notebooks/shard_map.html">Manual parallelism with shard_map&lt;/a> for a refresher on these topics.&lt;/p></description></item><item><title>Global vs Local SPMD</title><link>https://blog.ezyang.com/2026/01/global-vs-local-spmd/</link><pubDate>Tue, 27 Jan 2026 14:36:28 -0500</pubDate><guid>https://blog.ezyang.com/2026/01/global-vs-local-spmd/</guid><description>&lt;p>&lt;strong>Global SPMD&lt;/strong> (also known as the &amp;ldquo;global view&amp;rdquo;, exposed by code using &lt;a href="https://docs.pytorch.org/docs/stable/distributed.tensor.html">DTensor&lt;/a> or &lt;a href="https://docs.jax.dev/en/latest/notebooks/Distributed_arrays_and_automatic_parallelization.html">jax.Array&lt;/a>) refers to writing multi-device code as if it was on a single device, with an orthogonal mechanism for expressing how these full tensors are distributed over multiple devices (this mechanism can be implicit or explicit, e.g., as seen in &lt;a href="https://docs.jax.dev/en/latest/notebooks/explicit-sharding.html#using-a-mixture-of-sharding-modes">this table&lt;/a>).&lt;/p>
&lt;p>&lt;strong>Local SPMD&lt;/strong> (also known as &amp;ldquo;per-device view&amp;rdquo;, and exposed by &lt;a href="https://docs.pytorch.org/docs/stable/distributed.tensor.html#torch.distributed.tensor.experimental.local_map">local_map&lt;/a> and &lt;a href="https://docs.jax.dev/en/latest/notebooks/shard_map.html">shard_map&lt;/a>, and also traditional PyTorch distributed code operating on plain Tensors, e.g., Megatron-style) refers to writing code from the &amp;ldquo;local&amp;rdquo; view on a single device, with explicit collectives when communicating across devices.&lt;/p></description></item><item><title>Megatron via shard_map</title><link>https://blog.ezyang.com/2026/01/megatron-via-shard-map/</link><pubDate>Mon, 26 Jan 2026 08:34:34 -0500</pubDate><guid>https://blog.ezyang.com/2026/01/megatron-via-shard-map/</guid><description>&lt;p>In &lt;a href="https://blog.ezyang.com/2026/01/computing-sharding-with-einsum/">Computing sharding with einsum&lt;/a>, we worked an example of Megatron style tensor parallelism where we discover that the ordinary backwards formula for linear results in a pending reduction on &lt;code>grad_input&lt;/code>, even though the &lt;code>input&lt;/code> was replicated and no communications happened in forwards. In Megatron, which is implemented with plain Tensors and manual collectives, you just have to &lt;em>know&lt;/em> that this reduction is necessary and manually insert it with a custom autograd function.&lt;/p></description></item><item><title>Computing sharding with einsum</title><link>https://blog.ezyang.com/2026/01/computing-sharding-with-einsum/</link><pubDate>Sun, 25 Jan 2026 00:05:03 -0500</pubDate><guid>https://blog.ezyang.com/2026/01/computing-sharding-with-einsum/</guid><description>&lt;p>Mental arithmetic in grade school (e.g., memorizing your times tables) is typically justified on the grounds that facility in basic calculations makes it easier to focus on higher-level problems that require being able to do these manipulations. When working on DTensor, I have also found it important to be able to quickly calculate what shardings you get when you do matrix multiplies on sharded tensors. Without being able to do this quickly and accurately, working through examples becomes a slog. I&amp;rsquo;ve also found that while diagrammatic approaches (e.g., drawing a matrix and slicing it into shards) are intuitive, they are slow and unwieldy to do calculations with.&lt;/p></description></item><item><title>Hugo Migration</title><link>https://blog.ezyang.com/2026/01/hugo-migration/</link><pubDate>Sun, 04 Jan 2026 09:12:54 -0500</pubDate><guid>https://blog.ezyang.com/2026/01/hugo-migration/</guid><description>&lt;p>This blog has lived on WordPress since it was &lt;a href="https://blog.ezyang.com/2009/12/iron-blogger/">initially created&lt;/a> during a social challenge at MIT to write a blog post a week or pay up with beer. I remember a very important piece of advice I had been given at that time: don&amp;rsquo;t fuck around with your blog authoring software, just do the minimum viable thing (use WordPress) and focus on writing posts.&lt;/p>
&lt;p>It&amp;rsquo;s 2026 now, the world is different, and in particular the existence of coding agents means that this particular advice falls flat now: it has never been easier to vibe code your own blog software and be done in an afternoon of token generation. Similarly, over the years, I had been increasingly unhappy about my WordPress setup (too hard to add images, ancient version of WordPress, Markdown has taken over the world why am I still writing in ReST, I love scripts.mit.edu but I definitely don&amp;rsquo;t want to use it to host serious things). So I typed this into ChatGPT and Claude and asked it what I should migrate too.&lt;/p></description></item><item><title>The gap between a Helpful Assistant and a Senior Engineer</title><link>https://blog.ezyang.com/2026/01/the-gap-between-a-helpful-assistant-and-a-senior-engineer/</link><pubDate>Sun, 04 Jan 2026 05:41:00 +0000</pubDate><guid>https://blog.ezyang.com/2026/01/the-gap-between-a-helpful-assistant-and-a-senior-engineer/</guid><description>&lt;p>Let&amp;rsquo;s suppose you asked an AI coding agent to &amp;ldquo;implement a CLI calculator&amp;rdquo;.
Imagine if, instead of only writing short Python script, it also started
building an automated test suite, a crash reporting mechanism and a telemetry
subsystem. You&amp;rsquo;d be like, &amp;ldquo;What the fuck is this?&amp;rdquo;&lt;/p>
&lt;p>But now let&amp;rsquo;s say that you were planning to release this project to users. It
would be clearly negligent to not have an automated test suite. A crash
reporting mechanism might be overkill for a simple calculator, but for more
complicated CLIs interacting with the real world, it may not always be
feasible to have reproducer, in which case crash logs are essential.
Similarly, a telemetry subsystem would be wildly inappropriate for an open
source local-only calculator, but it could make sense for a networked
application or a corporate tool of all consenting users. One of the important
functions of a senior engineer is to be able to evaluate the context a
software project lives in and figure out if we need to do something, even if
it isn&amp;rsquo;t explicitly asked for. This is contrast to a helpful assistant, who
is first and foremost obligated to &lt;em>follow the user&amp;rsquo;s instructions.&lt;/em> This
leads to a gap between a Helpful Assistant and a Senior Engineer.&lt;/p></description></item><item><title>Code review as human alignment, in the era of LLMs</title><link>https://blog.ezyang.com/2025/12/code-review-as-human-alignment-in-the-era-of-llms/</link><pubDate>Sat, 20 Dec 2025 17:48:45 +0000</pubDate><guid>https://blog.ezyang.com/2025/12/code-review-as-human-alignment-in-the-era-of-llms/</guid><description>&lt;p>I&amp;rsquo;ve recently been doing a lot of both submitting and reviewing pull requests to PyTorch that were authored with substantial LLM assistance. This is a big difference from earlier this year, where it was clear LLMs worked well for greenfield projects but the code was too hopelessly sloppy for a production codebase. Here are &lt;a href="https://github.com/pytorch/pytorch/pulls?q=is%3Apr+author%3Aezyang+claude+code+is%3Aclosed+label%3AMerged">my merged PRs&lt;/a> that mention claude code in their description; Jason Ansel has also had a similar experience (&lt;a href="https://fb.workplace.com/groups/257735836456307/posts/997873152442568">Meta only link&lt;/a>, here is the &lt;a href="https://gist.github.com/ezyang/ece0a1976366a959372740b3173da816">list of issues&lt;/a> he referenced in his writeup). There already has been increasing discourse (&lt;a href="https://simonwillison.net/2025/Dec/18/code-proven-to-work/">Simon Willison&lt;/a>, &lt;a href="https://discourse.llvm.org/t/our-ai-policy-vs-code-of-conduct-and-vs-reality/88300?utm_source=chatgpt.com">LLVM&lt;/a>) on how code review should adapt to this new era of LLMs. My contribution to this discourse is this: within teams, code review should change to being primarily be a &lt;strong>human alignment&lt;/strong> mechanism.&lt;/p></description></item><item><title>Learning to love mesh-oriented sharding</title><link>https://blog.ezyang.com/2025/12/learning-to-love-mesh-oriented-sharding/</link><pubDate>Mon, 08 Dec 2025 00:35:13 +0000</pubDate><guid>https://blog.ezyang.com/2025/12/learning-to-love-mesh-oriented-sharding/</guid><description>&lt;p>Famously, PyTorch and JAX don&amp;rsquo;t agree on how shardings should be represented: PyTorch takes a mesh-dim oriented view, where for each dimension in your device mesh, you specify what sharding should be applied; JAX takes a tensor-dim oriented view, where for each dimension on your tensor, you say which mesh dimensions (potentially multiple!) shard it. Among my Twitter followers, it is generally agreed that the &lt;a href="https://x.com/ezyang/status/1960188772554846236">JAX formulation is more intuitive&lt;/a> from a user perspective. OK, fine; if you prefer one representation over another, it&amp;rsquo;s easy enough to translate between the two representations (in easy situations, at least!) In this post, I want to talk more about the framework implementation side: what is the better &lt;em>internal&lt;/em> representation of sharding? I don&amp;rsquo;t claim to have all the answers, but my motivation for writing this post is to help explain where I currently stand and how I evaluate proposals for evolving DTensor and sharding in PyTorch.&lt;/p></description></item><item><title>Draw high dimensional tensors as a matrix of matrices</title><link>https://blog.ezyang.com/2025/10/draw-high-dimensional-tensors-as-a-matrix-of-matrices/</link><pubDate>Sat, 25 Oct 2025 12:55:10 +0000</pubDate><guid>https://blog.ezyang.com/2025/10/draw-high-dimensional-tensors-as-a-matrix-of-matrices/</guid><description>&lt;p>I have recently needed to draw the contents of high-dimensional (e.g., 4D and up) tensors where it is important to ensure that is clear how to identify each of the dimensions in the representation. Common strategies I&amp;rsquo;ve seen people do in this situation include printing a giant list 2D slices (what the default PyTorch printer will do) or flattening the Tensor in some way back down to a 2D tensor. However, if you have a lot of horizontal space, there is a strategy that I like that makes it easy to identify all the axes of the higher dimensional tensor: draw it as a matrix of matrices.&lt;/p></description></item><item><title>So you want to control flow in PT2</title><link>https://blog.ezyang.com/2025/09/so-you-want-to-control-flow-in-pt2/</link><pubDate>Fri, 05 Sep 2025 10:01:23 +0000</pubDate><guid>https://blog.ezyang.com/2025/09/so-you-want-to-control-flow-in-pt2/</guid><description>&lt;p>&lt;em>With contributions from Richard Zou.&lt;/em>&lt;/p>
&lt;p>PT2’s dominant internal representation, FX graphs, do not directly support control flow (if statements, while loops): they only represent straight-line basic blocks. Most of our graph capture mechanisms are tracing based (&lt;code>fx.symbolic_trace&lt;/code>, &lt;code>make_fx&lt;/code>, Dynamo), which means that we expect to be able to linearize all conditionals we encounter into a straight line program. Sometimes, you want to work with code that has control flow while working the compiler stack. There is no silver bullet, instead there are a lot of different options with different tradeoffs.&lt;/p></description></item><item><title>The Parallelism Mesh Zoo</title><link>https://blog.ezyang.com/2025/08/the-parallelism-mesh-zoo/</link><pubDate>Sat, 30 Aug 2025 23:20:01 +0000</pubDate><guid>https://blog.ezyang.com/2025/08/the-parallelism-mesh-zoo/</guid><description>&lt;p>When training large scale LLMs, there is a large assortment of parallelization strategies which you can employ to scale your training runs to work on more GPUs. There are already a number of good resources for understanding how to parallelize your models: I particularly recommend &lt;a href="https://jax-ml.github.io/scaling-book/">How To Scale Your Model&lt;/a> and &lt;a href="https://huggingface.co/spaces/nanotron/ultrascale-playbook">The Ultra-Scale Playbook&lt;/a>. The purpose of this blog post is to discuss parallelization strategies in a more &lt;em>schematic&lt;/em> way by focusing only on how they affect your &lt;strong>device mesh&lt;/strong>. The device mesh is an abstraction used by both PyTorch and JAX that takes your GPUs (however many of them you&amp;rsquo;ve got in your cluster!) and organizes them into a N-D tensor that expresses how the devices communicate with each other. When we parallelize computation, we shard a tensor along one dimension of the mesh, and then do collectives along that dimension when there are nontrivial dependencies between shards. Being able to explain why a device mesh is set up the way it is for a collection of parallelization strategies is a good check for seeing if you understand how the parallelization strategies work in the first place! (Credit: This post was influenced by &lt;a href="https://main-horse.github.io/posts/visualizing-6d/">Visualizing 6D Mesh Parallelism&lt;/a>.)&lt;/p></description></item><item><title>You could have invented CuTe hierarchical layout (but maybe not the rest of it?)</title><link>https://blog.ezyang.com/2025/08/you-could-have-invented-cute-hierarchical-layout-but-maybe-not-the-rest-of-it/</link><pubDate>Fri, 22 Aug 2025 02:48:48 +0000</pubDate><guid>https://blog.ezyang.com/2025/08/you-could-have-invented-cute-hierarchical-layout-but-maybe-not-the-rest-of-it/</guid><description>&lt;p>CuTe is a C++ library that aims to make dealing with complicated indexing easier. A key part of how it does this is by defining a &lt;a href="https://docs.nvidia.com/cutlass/media/docs/cpp/cute/01_layout.html">Layout&lt;/a> type, which specifies how to map from logical coordinates to physical locations (CuTe likes to say layouts are &amp;ldquo;functions from integers to integers.&amp;rdquo;) In fact, CuTe layouts are a generalization of PyTorch strides, which say you always do this mapping by multiplying each coordinate with its respective stride and summing them together, e.g., &lt;code>i0 * s0 + i1 * s1 + ...&lt;/code>. Although NVIDIA&amp;rsquo;s docs don&amp;rsquo;t spell it out, the CuTe&amp;rsquo;s generalization here is actually very natural, and in this blog post I&amp;rsquo;d like to explain how you could have invented it (on a good day).&lt;/p></description></item><item><title>State of torch.compile for training (August 2025)</title><link>https://blog.ezyang.com/2025/08/state-of-torch-compile-august-2025/</link><pubDate>Wed, 13 Aug 2025 22:33:58 +0000</pubDate><guid>https://blog.ezyang.com/2025/08/state-of-torch-compile-august-2025/</guid><description>&lt;p>The purpose of this post is to sum up, in one place, the state of torch.compile for training as of August 2025. Nothing in here isn&amp;rsquo;t something you might not already know about from elsewhere on the Internet, but we rarely put everything together in one place. The target audience for this document are teams who are evaluating the use of torch.compile for large scale training runs.&lt;/p>
&lt;p>First, the basics. torch.compile (also known as PT2) is a compiler for PyTorch eager programs for both inference and training workloads. Speedups from 1.5-2x compared to eager code are typical, and torch.compile also makes it possible to do global optimizations for memory (e.g., automatic activation checkpointing) and distributed communications (e.g., async tensor parallelism).&lt;/p></description></item><item><title>Vibe coding case study: ScubaDuck</title><link>https://blog.ezyang.com/2025/06/vibe-coding-case-study-scubaduck/</link><pubDate>Mon, 02 Jun 2025 00:31:25 +0000</pubDate><guid>https://blog.ezyang.com/2025/06/vibe-coding-case-study-scubaduck/</guid><description>&lt;p>A lot of strong engineers that I know haven&amp;rsquo;t really taken a serious look at AI coding; they&amp;rsquo;ve used LLMs to ask questions or write simple scripts and appreciate that it is a useful tool, but haven&amp;rsquo;t actually tried building a nontrivial application entirely from scratch in vibe coding style (here, I use the term in its original meaning: when you do AI coding without carefully reviewing the output). This is understandable: if you&amp;rsquo;re not working on a green field project, there aren&amp;rsquo;t that many opportunities to write code in this style&amp;ndash;standard practice for established projects is that someone else needs to review all of the code you write: this is a bad match for vibe coding! So in this post, I want to give a concrete case study of a nontrivial system that was entirely vibe coded (ScubaDuck), to argue the following claims:&lt;/p></description></item><item><title>Why you should maintain a personal LLM coding benchmark</title><link>https://blog.ezyang.com/2025/04/why-you-should-maintain-a-personal-llm-coding-benchmark/</link><pubDate>Fri, 04 Apr 2025 03:05:46 +0000</pubDate><guid>https://blog.ezyang.com/2025/04/why-you-should-maintain-a-personal-llm-coding-benchmark/</guid><description>&lt;p>Do you use an LLM for coding? Do you maintain a personal benchmark based on problems you have posed the LLM? The purpose of this blog post is to convince you &lt;em>should&lt;/em> do this: that you can do so with &lt;em>marginal&lt;/em> effort on top of your day-to-day vibe coding and that you will get both &lt;em>short and long term benefits&lt;/em> from making your own personal benchmark exist.&lt;/p>
&lt;hr>
&lt;p>I started thinking about benchmarks for coding in part with my frustration with the discourse around LLMs in the public squares I frequent (Reddit and Twitter). People often want to know &amp;ldquo;what&amp;rsquo;s the best model&amp;rdquo; or &amp;ldquo;what&amp;rsquo;s the best coding IDE&amp;rdquo;? One might imagine that the way to answer this question would be to test the models on a variety of problems from real world uses of the LLM for coding, and then compare how well various systems do on this. Indeed, whenever a new SOTA model releases, the lab will usually tell you about the model&amp;rsquo;s performance against a few well known coding benchmarks. Problem solved?&lt;/p></description></item><item><title>New Years resolutions for PyTorch in 2025</title><link>https://blog.ezyang.com/2025/01/new-years-resolutions-for-pytorch-in-2025/</link><pubDate>Thu, 09 Jan 2025 15:50:08 +0000</pubDate><guid>https://blog.ezyang.com/2025/01/new-years-resolutions-for-pytorch-in-2025/</guid><description>&lt;p>In my previous two posts &amp;ldquo;`Ways to use torch.compile &amp;lt;http://blog.ezyang.com/2024/11/ways-to-use-torch-compile/&amp;gt;`_&amp;rdquo; and &amp;ldquo;`Ways to use torch.export &amp;lt;http://blog.ezyang.com/2024/12/ways-to-use-torch-export/&amp;gt;`_&amp;rdquo;, I often said that PyTorch would be good for a use case, but there might be some downsides. Some of the downsides are foundational and difficult to remove. But some&amp;hellip; just seem like a little something is missing from PyTorch. In this post, here are some things I hope we will end up shipping in 2025!&lt;/p></description></item><item><title>Ways to use torch.export</title><link>https://blog.ezyang.com/2024/12/ways-to-use-torch-export/</link><pubDate>Mon, 23 Dec 2024 23:28:23 +0000</pubDate><guid>https://blog.ezyang.com/2024/12/ways-to-use-torch-export/</guid><description>&lt;p>Previously, I discussed the &lt;a href="http://blog.ezyang.com/2024/11/ways-to-use-torch-compile/">value proposition of torch.compile&lt;/a>. While doing so, I observed a number of downsides (long compile time, complicated operational model, lack of packaging) that were intrinsic to torch.compile&amp;rsquo;s API contract, which emphasized being able to work on Python code as is, with minimal intervention from users. torch.export occupies a different spot in the tradeoff space: in exchange for more upfront work making a model exportable, it allows for use of PyTorch models in environments where using torch.compile as is would be impossible.&lt;/p></description></item><item><title>Ways to use torch.compile</title><link>https://blog.ezyang.com/2024/11/ways-to-use-torch-compile/</link><pubDate>Tue, 05 Nov 2024 10:11:52 +0000</pubDate><guid>https://blog.ezyang.com/2024/11/ways-to-use-torch-compile/</guid><description>&lt;p>On the surface, the value proposition of torch.compile is simple: compile your PyTorch model and it runs X% faster. But after having spent a lot of time helping users from all walks of life use torch.compile, I have found that actually understanding how this value proposition applies to your situation can be quite subtle! In this post, I want to walk through the ways to use torch.compile, and within these use cases, what works and what doesn&amp;rsquo;t. By the way, some of these gaps are either served by export, or by missing features we are actively working on, those will be some other posts!&lt;/p></description></item><item><title>Tensor programming for databases, with first class dimensions</title><link>https://blog.ezyang.com/2024/10/tensor-programming-for-databases-with-first-class-dimensions/</link><pubDate>Mon, 14 Oct 2024 01:07:14 +0000</pubDate><guid>https://blog.ezyang.com/2024/10/tensor-programming-for-databases-with-first-class-dimensions/</guid><description>&lt;p>Tensor libraries like PyTorch and JAX have developed compact and accelerated APIs for manipulating n-dimensional arrays. N-dimensional arrays are kind of similar to tables in database, and this results in the logical question which is could you setup a Tensor-like API to do queries on databases that would be normally done with SQL? We have two challenges:&lt;/p>
&lt;ul>
&lt;li>Tensor computation is typically uniform and data-independent. But SQL relational queries are almost entirely about filtering and joining data in a data-dependent way.&lt;/li>
&lt;li>JOINs in SQL can be thought of as performing outer joins, which is not a very common operation in tensor computation.&lt;/li>
&lt;/ul>
&lt;p>However, we have a secret weapon: &lt;a href="https://github.com/facebookresearch/torchdim/blob/main/torchdim.ipynb">first class dimensions&lt;/a> were primarily designed to as a new frontend syntax that made it easy to express einsum, batching and tensor indexing expressions. They might be good for SQL too.&lt;/p></description></item><item><title>What's different this time? LLM edition</title><link>https://blog.ezyang.com/2024/10/whats-different-this-time-llm-edition/</link><pubDate>Fri, 04 Oct 2024 00:30:09 +0000</pubDate><guid>https://blog.ezyang.com/2024/10/whats-different-this-time-llm-edition/</guid><description>&lt;p>One of the things that I learned in grad school is that even if you&amp;rsquo;ve picked an important and unsolved problem, you need &lt;em>some&lt;/em> reason to believe it is solvable&amp;ndash;especially if people have tried to solve it before! In other words, &amp;ldquo;What&amp;rsquo;s different this time?&amp;rdquo; This is perhaps a dreary way of shooting down otherwise promising research directions, but you can flip it around: when the world changes, you can ask, &amp;ldquo;What can I do now that I couldn&amp;rsquo;t do before?&amp;rdquo;&lt;/p></description></item><item><title>Interactive scraping with Jupyter and Puppeteer</title><link>https://blog.ezyang.com/2021/11/interactive-scraping-with-jupyter-and-puppeteer/</link><pubDate>Tue, 23 Nov 2021 09:28:07 +0000</pubDate><guid>https://blog.ezyang.com/2021/11/interactive-scraping-with-jupyter-and-puppeteer/</guid><description>&lt;p>One of the annoying things about scraping websites is bouncing back and forth between the browser where you are using Dev Tools to work out what selectors you should be using to scrape out data, and your actual scraping script, which is usually some batch program that may have to take a few steps before the step you are debugging. A batch script is fine once your scraper is up and running, but while developing, it&amp;rsquo;s really handy to pause the scraping process at some page and fiddle around with the DOM to see what to do.&lt;/p></description></item><item><title>PyTorch Developer Podcast</title><link>https://blog.ezyang.com/2021/05/pytorch-developer-podcast/</link><pubDate>Wed, 05 May 2021 11:26:42 +0000</pubDate><guid>https://blog.ezyang.com/2021/05/pytorch-developer-podcast/</guid><description>&lt;p>I&amp;rsquo;m launching a new podcast, the &lt;a href="https://pytorch-dev-podcast.simplecast.com/">PyTorch Developer Podcast&lt;/a>. The idea is to be a place for the PyTorch dev team to do bite sized (10-20 min) topics about all sorts of internal development topics in PyTorch. For now, it&amp;rsquo;s just me monologuing for fifteen minutes about whatever topic I decide. The plan is to release an episode daily, five days a week, until I run out of things to say (probably not for a while, I have SO MANY THINGS TO SAY). I don&amp;rsquo;t edit the podcasts and do minimal planning, so they&amp;rsquo;re a bit easier to do than blog posts. Check it out! There&amp;rsquo;s two episodes out already, one about how we do Python bindings for our C++ objects and another about history and constraints of the dispatcher. If there are any topics you&amp;rsquo;d like me to cover, give a shout.&lt;/p></description></item><item><title>Rage bug reporting</title><link>https://blog.ezyang.com/2021/04/rage-bug-reporting/</link><pubDate>Sun, 25 Apr 2021 00:03:41 +0000</pubDate><guid>https://blog.ezyang.com/2021/04/rage-bug-reporting/</guid><description>&lt;p>At Facebook, we have an internal convention for tooling called &amp;ldquo;rage&amp;rdquo;. When something goes wrong and you want to report a bug, the tool developer will typically ask you to give them a rage. For a command line tool, this can be done by running a rage subcommand, which will ask about which previous CLI invocation you&amp;rsquo;d like to report, and then giving you a bundle of logs to send to the developer.&lt;/p></description></item><item><title>The PyTorch open source process</title><link>https://blog.ezyang.com/2021/01/pytorch-open-source-process/</link><pubDate>Wed, 06 Jan 2021 11:56:33 +0000</pubDate><guid>https://blog.ezyang.com/2021/01/pytorch-open-source-process/</guid><description>&lt;p>PyTorch is a fairly large and active open source project, and sometimes we have people come to us and ask if there are any lessons from how we run PyTorch that they could apply to their own projects. This post is an attempt to describe some of the processes as of 2021 that help PyTorch operate effectively as an open source project. I won&amp;rsquo;t claim that everything we do necessarily the best way to go about doing things, but at the very least, everything I describe here is working in practice.&lt;/p></description></item><item><title>The hidden problem(?) with basic block procedures in SSA</title><link>https://blog.ezyang.com/2020/10/the-hidden-problem-with-basic-block-procedures-in-ssa/</link><pubDate>Sat, 24 Oct 2020 19:34:21 +0000</pubDate><guid>https://blog.ezyang.com/2020/10/the-hidden-problem-with-basic-block-procedures-in-ssa/</guid><description>&lt;p>Years ago, Nadav Rotem related to me this story about why basic block procedures in Swift are not as good as they seem. Nelson Elhage reminded me about this &lt;a href="https://twitter.com/nelhage/status/1319785483153494016">on Twitter&lt;/a> and so I thought this should be put into the public record.&lt;/p>
&lt;p>Basic block procedures make certain optimizations more difficult. Consider this program:&lt;/p>
&lt;pre>&lt;code>block j3 (%y1, %y2) { ... }
block j1 () { jump j3(%x1, %x2) }
block j2 () { jump j3(%x3, %x4) }
&lt;/code>&lt;/pre>
&lt;p>Is this program easier or more difficult to optimize than the traditional SSA with phi-nodes formulation?&lt;/p></description></item><item><title>Idiomatic algebraic data types in Python with dataclasses and Union</title><link>https://blog.ezyang.com/2020/10/idiomatic-algebraic-data-types-in-python-with-dataclasses-and-union/</link><pubDate>Wed, 14 Oct 2020 14:08:54 +0000</pubDate><guid>https://blog.ezyang.com/2020/10/idiomatic-algebraic-data-types-in-python-with-dataclasses-and-union/</guid><description>&lt;p>&lt;strong>Greetings from 2024!&lt;/strong> An official pattern matching PEP has been accepted &lt;a href="https://peps.python.org/pep-0636/">https://peps.python.org/pep-0636/&lt;/a> and is available in Python 3.10. Class patterns are tested using isinstance, with no inheritance structure necessary, making the pattern described in this post 100% forward compatible to real pattern matching.&lt;/p>
&lt;hr>
&lt;p>One of the features I miss most in non-Haskell programming languages is algebraic data types (ADT). ADTs fulfill a similar role to objects in other languages, but with more restrictions: objects are an open universe, where clients can implement new subclasses that were not known at definition time; ADTs are a closed universe, where the definition of an ADT specifies precisely all the cases that are possible. We often think of restrictions of a bad thing, but in the case of ADTs, the restriction of being a closed universe makes programs easier to understand (a fixed set of cases to understand, as opposed to a potentially infinite set of cases) and allows for new modes of expression (pattern matching). ADTs make it really easy to accurately model your data structures; they encourage you to go for precise types that make illegal states unrepresentable. Still, it is generally not a good idea to try to manually reimplement your favorite Haskell language feature in every other programming language you use, and so for years I&amp;rsquo;ve suffered in Python under the impression that ADTs were a no go.&lt;/p></description></item><item><title>Let's talk about the PyTorch dispatcher</title><link>https://blog.ezyang.com/2020/09/lets-talk-about-the-pytorch-dispatcher/</link><pubDate>Thu, 10 Sep 2020 14:29:05 +0000</pubDate><guid>https://blog.ezyang.com/2020/09/lets-talk-about-the-pytorch-dispatcher/</guid><description>&lt;p>&lt;img src="https://blog.ezyang.com/img/pytorch-dispatcher/slide-01.png" alt="image">&lt;/p>
&lt;p>If this is your first time reading about PyTorch internals, you might want to check out my &lt;a href="http://blog.ezyang.com/2019/05/pytorch-internals/">PyTorch internals&lt;/a> post first. In this post, I want to talk about one particular part of PyTorch&amp;rsquo;s internals: the &lt;a href="https://pytorch.org/tutorials/advanced/dispatcher.html">dispatcher&lt;/a>. At a first glance, the dispatcher is just a glorified if statement: based on some information about the tensor inputs, decide what piece of code should be called. So why should we care about the dispatcher?&lt;/p></description></item><item><title>Dynamic scoping is an effect, implicit parameters are a coeffect</title><link>https://blog.ezyang.com/2020/08/dynamic-scoping-is-an-effect-implicit-parameters-are-a-coeffect/</link><pubDate>Thu, 27 Aug 2020 01:51:36 +0000</pubDate><guid>https://blog.ezyang.com/2020/08/dynamic-scoping-is-an-effect-implicit-parameters-are-a-coeffect/</guid><description>&lt;p>For the longest time, I thought of &lt;a href="https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#implicit-parameters">implicit parameters&lt;/a> and dynamic scoping were basically the same thing, since they both can be used to solve similar problems (e.g., the so called &amp;ldquo;configuration problem&amp;rdquo; where you need to plumb down some configuration deep into a nested body of function definitions without defining them all explicitly). But implicit parameters have a reputation of being &lt;a href="https://www.reddit.com/r/haskell/comments/6gz4w5/whats_wrong_with_implicitparams/">something you shouldn&amp;rsquo;t use&lt;/a> (&lt;a href="https://www.reddit.com/r/haskell/comments/5xqozf/implicit_parameters_vs_reflection/dek9eqg/">use reflection instead&lt;/a>), whereas dynamic scoping via the reader monad is a useful and well understood construct (except for the bit where you have to monadify everything). Why the difference?&lt;/p></description></item><item><title>A brief taxonomy of PyTorch operators by shape behavior</title><link>https://blog.ezyang.com/2020/05/a-brief-taxonomy-of-pytorch-operators-by-shape-behavior/</link><pubDate>Wed, 06 May 2020 11:56:43 +0000</pubDate><guid>https://blog.ezyang.com/2020/05/a-brief-taxonomy-of-pytorch-operators-by-shape-behavior/</guid><description>&lt;p>I&amp;rsquo;ve recently been working on a revamp of how we specify tensor shape formulas in PyTorch. As part of this process, I classified &lt;em>every single operator&lt;/em> in PyTorch by its shaping behavior; yes, that&amp;rsquo;s all 1364 of them (this includes each variant of an operator; e.g., inplace and &lt;code>out=&lt;/code> keyword variants). During the process, I tried to come up with categories to help classify what operators did. One of the surprises from the process was discovering that shaping behaviors that I previously thought were uncommon, actually showed up a bit more often than one might have expected.&lt;/p></description></item><item><title>vmap in Haskell</title><link>https://blog.ezyang.com/2020/01/vmap-in-haskell/</link><pubDate>Wed, 29 Jan 2020 14:14:34 +0000</pubDate><guid>https://blog.ezyang.com/2020/01/vmap-in-haskell/</guid><description>&lt;p>&lt;a href="https://github.com/google/jax#auto-vectorization-with-vmap">vmap&lt;/a> is an interface popularized by JAX which offers you a vectorizing map. Semantically, a vmap is exactly equivalent to a map in Haskell; the key difference is that operations run under a vmap are vectorized. If you map a convolution and a matrix multiply, you will have one big loop which repeatedly calls convolution and matrix multiply for each entry in your batch. If you &lt;em>vmap&lt;/em> a convolution and matrix multiply, you&amp;rsquo;ll call the batched versions of convolution and matrix multiply once. Unless you have a fuser, on most modern deep learning frameworks, calling the batched implementations of these operations will be much faster.&lt;/p></description></item><item><title>PyTorch internals</title><link>https://blog.ezyang.com/2019/05/pytorch-internals/</link><pubDate>Thu, 16 May 2019 22:11:22 +0000</pubDate><guid>https://blog.ezyang.com/2019/05/pytorch-internals/</guid><description>&lt;p>This post is a long form essay version of a talk about PyTorch internals, that I gave at the PyTorch NYC meetup on May 14, 2019.&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/pytorch-internals/slide-01.png" alt="image">&lt;/p>
&lt;p>Hi everyone! Today I want to talk about the internals of &lt;a href="https://pytorch.org/">PyTorch&lt;/a>.&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/pytorch-internals/slide-02.png" alt="image">&lt;/p>
&lt;p>This talk is for those of you who have used PyTorch, and thought to yourself, &amp;ldquo;It would be great if I could contribute to PyTorch,&amp;rdquo; but were scared by PyTorch&amp;rsquo;s behemoth of a C++ codebase. I&amp;rsquo;m not going to lie: the PyTorch codebase can be a bit overwhelming at times. The purpose of this talk is to put a map in your hands: to tell you about the basic conceptual structure of a &amp;ldquo;tensor library that supports automatic differentiation&amp;rdquo;, and give you some tools and tricks for finding your way around the codebase. I&amp;rsquo;m going to assume that you&amp;rsquo;ve written some PyTorch before, but haven&amp;rsquo;t necessarily delved deeper into how a machine learning library is written.&lt;/p></description></item><item><title>A short note about functional linear maps</title><link>https://blog.ezyang.com/2019/05/a-short-note-about-functional-linear-maps/</link><pubDate>Wed, 15 May 2019 17:42:10 +0000</pubDate><guid>https://blog.ezyang.com/2019/05/a-short-note-about-functional-linear-maps/</guid><description>&lt;p>Some notes collected from a close read of Conal Elliot&amp;rsquo;s &lt;a href="http://conal.net/papers/compiling-to-categories/compiling-to-categories.pdf">Compiling to Categories&lt;/a> and &lt;a href="https://arxiv.org/pdf/1804.00746.pdf">The Simple Essence of Automatic Differentiation&lt;/a>.&lt;/p>
&lt;p>A colleague of mine was trying to define a &amp;ldquo;tree structure&amp;rdquo; of tensors, with the hope of thereby generalizing the concept to also work with tensors that have &amp;ldquo;ragged dimensions.&amp;rdquo; Let&amp;rsquo;s take a look:&lt;/p>
&lt;p>Suppose we have a &lt;code>(2, 3)&lt;/code> matrix:&lt;/p>
&lt;pre>&lt;code>tensor([[1, 2, 3],
 [4, 5, 6]])
&lt;/code>&lt;/pre>
&lt;p>One way to think about this is that we have a &amp;ldquo;tree&amp;rdquo; of some sort, where the root of the tree branches to two subnodes, and then each subnode branches to three nodes:&lt;/p></description></item><item><title>Microsoft Surface Book 2</title><link>https://blog.ezyang.com/2019/03/microsoft-surface-book-2/</link><pubDate>Sun, 17 Mar 2019 21:59:52 +0000</pubDate><guid>https://blog.ezyang.com/2019/03/microsoft-surface-book-2/</guid><description>&lt;p>Long time readers of mine may be aware that I used a ThinkPad X61T for the past decade. After the hinge on my second instance of the machine, I decided it was finally time to get a new laptop. And I had one particular model on my eye, after Simon Peyton Jones showed me his new laptop at the last Haskell Implementor&amp;rsquo;s Workshop: the Microsoft Surface Book 2. It fits my primary requirement for a laptop: it&amp;rsquo;s a convertible laptop into tablet mode with a digitizer pen. The pen is not Wacom branded but it has an eraser end and can magnetically attach to the laptop (no enclosure for the pen, but I think that for modern hardware that constraint is unsatisfiable.) Furthermore, there is a &lt;a href="https://github.com/jakeday/linux-surface/">Linux enthusiast community&lt;/a> around the device, which made me feel that it would be more likely I could get Linux to work. So a few weeks ago, I took the plunge, and laid down three grand for my own copy. It has worked out well, but in the classic Linux style, not without a little bit of elbow grease.&lt;/p></description></item><item><title>HIW'18: Let’s Go Mainstream with Eta!</title><link>https://blog.ezyang.com/2018/09/hiw18-lets-go-mainstream-with-eta/</link><pubDate>Sun, 23 Sep 2018 11:02:53 +0000</pubDate><guid>https://blog.ezyang.com/2018/09/hiw18-lets-go-mainstream-with-eta/</guid><description>&lt;p>My name is Rahul Muttineni, CTO of TypeLead, working on building services around a language named Eta. To get started, I'll give an overview of how the project started, and where it is now.&lt;/p>

&lt;p>It started as a HSOC project. It was called GHCVM; back then we had plans of making it both on JVM and CLR... we don't think about CLR anymore. I was mentored by Edward Kmett. We got pretty good response on this, so Jo and I decided to take the risk and work on this full time.&lt;/p></description></item><item><title>A year into Backpack</title><link>https://blog.ezyang.com/2018/07/a-year-into-backpack/</link><pubDate>Sat, 14 Jul 2018 19:34:16 +0000</pubDate><guid>https://blog.ezyang.com/2018/07/a-year-into-backpack/</guid><description>&lt;p>It&amp;rsquo;s been a year since I got my hood and gown and joined Facebook (where I&amp;rsquo;ve been working on PyTorch), but while I&amp;rsquo;ve been at Facebook Backpack hasn&amp;rsquo;t been sleeping; in fact, there&amp;rsquo;s been plenty of activity, more than I could have ever hoped for. I wanted to summarize some of the goings on in this blog post.&lt;/p>
&lt;h3 id="libraries-using-backpack" id="libraries-using-backpack">
 &lt;a class="heading-link" href="https://blog.ezyang.com/2018/07/a-year-into-backpack/#libraries-using-backpack">Libraries using Backpack&lt;span class="heading-anchor" aria-label="Anchor">¶&lt;/span>&lt;/a>
&lt;/h3>
&lt;p>There&amp;rsquo;s been some really interesting work going on in the libraries using Backpack space. Here are the two biggest ones I&amp;rsquo;ve seen from the last few months:&lt;/p></description></item><item><title>A compile-time debugger that helps you write tensor shape checks</title><link>https://blog.ezyang.com/2018/04/a-compile-time-debugger-that-helps-you-write-tensor-shape-checks/</link><pubDate>Fri, 06 Apr 2018 23:49:53 +0000</pubDate><guid>https://blog.ezyang.com/2018/04/a-compile-time-debugger-that-helps-you-write-tensor-shape-checks/</guid><description>&lt;p>A run-time debugger allows you to see concrete values in a program, make changes to them, and continue running your program. A &lt;strong>compile-time debugger&lt;/strong> allows you to see symbolic values in a program, reason about them, and write the rest of your program, e.g. filling in missing tensor size checks, for example.&lt;/p>
&lt;p>Here&amp;rsquo;s an example of a compiler-time debugger in action.&lt;/p>
&lt;p>Let&amp;rsquo;s suppose you are writing a simple program to read a pair of tensors from two files and do a matrix multiply on them. &amp;ldquo;Easy,&amp;rdquo; you think, while writing the following program:&lt;/p></description></item><item><title>Online/offline continuous integration</title><link>https://blog.ezyang.com/2018/03/online-offline-continuous-integration/</link><pubDate>Mon, 12 Mar 2018 22:52:29 +0000</pubDate><guid>https://blog.ezyang.com/2018/03/online-offline-continuous-integration/</guid><description>&lt;p>Raise your hand if you&amp;rsquo;ve ever put one of these commands in your continuous integration scripts:&lt;/p>
&lt;ul>
&lt;li>&lt;code>apt install somepackage&lt;/code>&lt;/li>
&lt;li>&lt;code>pip install -r requirements.txt&lt;/code> or &lt;code>pip install somepkg&lt;/code>&lt;/li>
&lt;li>&lt;code>conda install blah&lt;/code>&lt;/li>
&lt;li>&lt;code>cabal update&lt;/code> or &lt;code>cabal install blah&lt;/code>&lt;/li>
&lt;li>&lt;code>git clone https://github.com/someguy/somerepo&lt;/code>&lt;/li>
&lt;li>&lt;code>wget http://some-website/thingy-latest.tgz&lt;/code>&lt;/li>
&lt;/ul>
&lt;p>Can you tell what the problem is? These commands are not reproducible: depending on when you run them, they may give different results. More insidiously, &lt;em>most&lt;/em> of the time they give you the same result (or, perhaps, a different result that still works for your use case).&lt;/p></description></item><item><title>Semantic Import Versioning in the wild</title><link>https://blog.ezyang.com/2018/02/semantic-import-versioning-in-the-wild/</link><pubDate>Fri, 23 Feb 2018 00:06:00 +0000</pubDate><guid>https://blog.ezyang.com/2018/02/semantic-import-versioning-in-the-wild/</guid><description>&lt;p>&lt;em>The best and worst thing about semantic import versioning is that it makes BC-breaking changes hard.&lt;/em>&lt;/p>
&lt;p>In the past few days, Russ Cox has made a splash in a series of white papers describing &lt;a href="https://research.swtch.com/vgo">Go and Versioning&lt;/a>. In them, he coins a new term, &lt;a href="https://research.swtch.com/vgo-import">Semantic Import Versioning&lt;/a>, distilling it to the following principle:&lt;/p>
&lt;blockquote>
&lt;p>If an old package and a new package have the same import path, the new package must be backwards compatible with the old package.&lt;/p></description></item><item><title>Systems ML workshop panel</title><link>https://blog.ezyang.com/2017/12/systems-ml-workshop-panel/</link><pubDate>Fri, 08 Dec 2017 21:17:08 +0000</pubDate><guid>https://blog.ezyang.com/2017/12/systems-ml-workshop-panel/</guid><description>&lt;ul>
&lt;li>JG: Joseph Gonzalez&lt;/li>
&lt;li>GG: Garth Gibson (CMU)&lt;/li>
&lt;li>DS: Dawn Song (UC Berkeley)&lt;/li>
&lt;li>JL: John Langford (Microsoft NY)j&lt;/li>
&lt;li>YQ: Yangqing Jia (Facebook)&lt;/li>
&lt;li>SB: Sarah Bird&lt;/li>
&lt;li>M: Moderator&lt;/li>
&lt;li>A: Audience&lt;/li>
&lt;/ul>
&lt;p>M: This workshop is bringing together ML and systems. Can you put your place on that spectrum? Who is your home community?&lt;/p>
&lt;p>YJ: Right in the middle. I&amp;rsquo;d like to move more towards systems side, but Berkeley Parallel Labs kicked me out. ML is my home base.&lt;/p></description></item><item><title>Accelerating Persistent Neural Networks at Datacenter Scale (Daniel Lo)</title><link>https://blog.ezyang.com/2017/12/accelerating-persistent-neural-networks-at-datacenter-scale-daniel-lo/</link><pubDate>Fri, 08 Dec 2017 15:08:44 +0000</pubDate><guid>https://blog.ezyang.com/2017/12/accelerating-persistent-neural-networks-at-datacenter-scale-daniel-lo/</guid><description>&lt;p>The below is a transcript of a talk by &lt;a href="https://www.microsoft.com/en-us/research/people/dlo/">Daniel Lo&lt;/a> on &lt;a href="https://www.microsoft.com/en-us/research/blog/microsoft-unveils-project-brainwave/">BrainWave&lt;/a>, at the &lt;a href="https://nips.cc/Conferences/2017/Schedule?showEvent=8774">ML Systems Workshop&lt;/a> at NIPS'17.&lt;/p>
&lt;hr>
&lt;p>Deploy and serve accelerated DNNs at cloud scale. As we&amp;rsquo;ve seen, DNNs have enabled amazing applications. Architectures achieve SoTA on computer vision, language translation and speech recognition. But this is challenging to serve in large-scale interactive because there are latency, cost and power constraints. Also, DNNs are growing larger in size and complexity.&lt;/p></description></item><item><title>MOCHA: Federated Multi-Tasks Learning (Virginia Smith)</title><link>https://blog.ezyang.com/2017/12/mocha-federated-multi-tasks-learning-virginia-smith/</link><pubDate>Fri, 08 Dec 2017 13:15:32 +0000</pubDate><guid>https://blog.ezyang.com/2017/12/mocha-federated-multi-tasks-learning-virginia-smith/</guid><description>&lt;p>The below is a transcript of a talk by &lt;a href="https://people.eecs.berkeley.edu/~vsmith/">Virginia Smith&lt;/a> on &lt;a href="https://arxiv.org/abs/1705.10467">MOCHA&lt;/a>, at the &lt;a href="https://nips.cc/Conferences/2017/Schedule?showEvent=8774">ML Systems Workshop&lt;/a> at NIPS'17.&lt;/p>
&lt;hr>
&lt;p>The motivation for this work comes from the way we think about solving ML problems in practice is changing. The typical ML workflow looks like this. You start iwth dataset and problem to solve. Say you want to build a classifier to identify high quality news articles. Next step is to select an ML model to solve the problem. Under the hood, to fit the model to your data, you have to select an optimization algorithm. The goal is to find an optimal model that minimizes some function over your data.&lt;/p></description></item><item><title>A Machine Learning Approach to Database Indexes (Alex Beutel)</title><link>https://blog.ezyang.com/2017/12/a-machine-learning-approach-to-database-indexes-alex-beutel/</link><pubDate>Fri, 08 Dec 2017 13:11:02 +0000</pubDate><guid>https://blog.ezyang.com/2017/12/a-machine-learning-approach-to-database-indexes-alex-beutel/</guid><description>&lt;p>The below is a transcript of a talk by &lt;a href="http://alexbeutel.com/">Alex Beutel&lt;/a> on &lt;a href="https://arxiv.org/abs/1712.01208">machine learning database indexes&lt;/a>, at the &lt;a href="https://nips.cc/Conferences/2017/Schedule?showEvent=8774">ML Systems Workshop&lt;/a> at NIPS'17.&lt;/p>
&lt;hr>
&lt;p>DB researchers think about there research differently. You have a system that needs to work for all cases. Where as in ML, we have a unique circumstance, I&amp;rsquo;ll build a model that works well. In DB, you have to fit all.&lt;/p>
&lt;p>To give an example of this is a B-tree. A B-tree works for range queries. We have records, key, we want to find all records for range of keys. 0-1000, you build tree on top of sorted array. To quickly look up starting point in range. What if all my data, all of the keys, from zero to million&amp;hellip; it becomes clear, you don&amp;rsquo;t need the whole tree above. You can use the key itself as an offset into the array. Your lookup is O(1), O(1) memory, no need for extra data structure.&lt;/p></description></item><item><title>Ray: A Distributed Execution Framework for Emerging AI Applications (Ion Stoica)</title><link>https://blog.ezyang.com/2017/12/ray-a-distributed-execution-framework-for-emerging-ai-applications-ion-stoica/</link><pubDate>Fri, 08 Dec 2017 13:07:16 +0000</pubDate><guid>https://blog.ezyang.com/2017/12/ray-a-distributed-execution-framework-for-emerging-ai-applications-ion-stoica/</guid><description>&lt;p>The below is a transcript of a talk by &lt;a href="https://people.eecs.berkeley.edu/~istoica/">Ion Stoica&lt;/a> on &lt;a href="https://github.com/ray-project/ray">Ray&lt;/a>, at the &lt;a href="https://nips.cc/Conferences/2017/Schedule?showEvent=8774">ML Systems Workshop&lt;/a> at NIPS'17.&lt;/p>
&lt;hr>
&lt;p>We&amp;rsquo;ve been working on it at Berkeley for more than one year. Over the past years, there&amp;rsquo;s been tremendous progress in AI. Ad targeting, image&amp;amp;speech, many more. Many applications are based on supervised learning with DNNs. Supervised plus unsupervised are the two dominant approaches.&lt;/p>
&lt;p>However, the next generation of AI applications will be very different. They&amp;rsquo;re deployed in mission critical scenarios, need to continually learn from a rapidly changing env. Robotics, self driving cars, unmanned drones, dialogue systems. Implementing this new generation of AI applications requires a broader range of techniques. Stochastic optimization, parallel simulations, many more.&lt;/p></description></item><item><title>Backpack for deep learning</title><link>https://blog.ezyang.com/2017/08/backpack-for-deep-learning/</link><pubDate>Thu, 17 Aug 2017 22:05:03 +0000</pubDate><guid>https://blog.ezyang.com/2017/08/backpack-for-deep-learning/</guid><description>&lt;p>&lt;em>This is a guest post by Kaixi Ruan.&lt;/em>&lt;/p>
&lt;p>&lt;a href="https://ghc.haskell.org/trac/ghc/wiki/Backpack">Backpack&lt;/a> is a module system for Haskell, released recently in &lt;a href="https://ghc.haskell.org/trac/ghc/blog/ghc-8.2.11-released">GHC 8.2.1&lt;/a>. As this is a new feature, I wanted to know how people use it. So I searched Twitter every day, and the other day I saw &lt;a href="https://twitter.com/Profpatsch/status/897993951852015616">this tweet&lt;/a>:&lt;/p>
&lt;blockquote>
&lt;p>Are there other examples than String/Bytestring/Text? So far I haven’t seen any; it seems like backpack is just for glorified string holes.&lt;/p>&lt;/blockquote>
&lt;p>There were a number of &lt;a href="https://twitter.com/ezyang/status/897999430196101120">good responses&lt;/a>, but I want to give another use case from deep learning.&lt;/p></description></item><item><title>Proposal: Suggest explicit type application for Foldable length and friends</title><link>https://blog.ezyang.com/2017/03/proposal-suggest-explicit-type-application-for-foldable-length/</link><pubDate>Tue, 21 Mar 2017 19:50:13 +0000</pubDate><guid>https://blog.ezyang.com/2017/03/proposal-suggest-explicit-type-application-for-foldable-length/</guid><description>&lt;p>&lt;strong>tl;dr&lt;/strong> &lt;em>If you use a Foldable function like length or null, where instance selection is solely determined by the input argument, you should make your code more robust by introducing an explicit type application specifying which instance you want. This isn&amp;rsquo;t necessary for a function like fold, where the return type can cross-check if you&amp;rsquo;ve gotten it right or not. If you don&amp;rsquo;t provide this type application, GHC should give a warning suggesting you annotate it explicitly, in much the same way it suggests adding explicit type signatures to top-level functions.&lt;/em>&lt;/p></description></item><item><title>Prio: Private, Robust, and Scalable Computation of Aggregate Statistics</title><link>https://blog.ezyang.com/2017/03/prio-private-robust-and-scalable-computation-of-aggregate-statistics/</link><pubDate>Fri, 17 Mar 2017 19:35:48 +0000</pubDate><guid>https://blog.ezyang.com/2017/03/prio-private-robust-and-scalable-computation-of-aggregate-statistics/</guid><description>&lt;p>I want to take the opportunity to advertise some new work from a colleague of mine, &lt;a href="https://www.henrycg.com/">Henry Corrigan-Gibbs&lt;/a> (in collaboration with the venerable Dan Boneh) on the subject of preserving privacy when collecting aggregate statistics. Their new system is called &lt;a href="https://www.henrycg.com/pubs/nsdi17prio/">Prio&lt;/a> and will be appearing at this year&amp;rsquo;s NSDI.&lt;/p>
&lt;p>The basic problem they tackle is this: suppose you&amp;rsquo;re Google and you want to collect some statistics on your users to compute some aggregate metrics, e.g., averages or a linear regression fit:&lt;/p></description></item><item><title>Designing the Backpack signature ecosystem</title><link>https://blog.ezyang.com/2017/03/designing-the-backpack-signature-ecosystem/</link><pubDate>Sat, 11 Mar 2017 06:40:42 +0000</pubDate><guid>https://blog.ezyang.com/2017/03/designing-the-backpack-signature-ecosystem/</guid><description>&lt;p>Suppose you are a library writer interested in using Backpack. Backpack says that you can replace a direct dependency on a function, type or package with one or more &lt;em>signatures&lt;/em>. You typecheck against a signature and your end user picks how they want to eventually implement the signature.&lt;/p>
&lt;p>Sounds good right? But there&amp;rsquo;s a dirty little secret: to get all of this goodness, you have to &lt;em>write&lt;/em> a signature&amp;ndash;you know, a type signature for each function and type that you want to use in your library. And we all know how much Haskellers &lt;a href="https://ghc.haskell.org/trac/ghc/ticket/1409">hate writing signatures&lt;/a>. But Backpack has a solution to this: rather than repeatedly rewrite signatures for all your packages, a conscientious user can put a signature in a package for reuse in other packages.&lt;/p></description></item><item><title>How to integrate GHC API programs with Cabal</title><link>https://blog.ezyang.com/2017/02/how-to-integrate-ghc-api-programs-with-cabal/</link><pubDate>Wed, 08 Feb 2017 19:45:00 +0000</pubDate><guid>https://blog.ezyang.com/2017/02/how-to-integrate-ghc-api-programs-with-cabal/</guid><description>&lt;p>GHC is not just a compiler: it is also a library, which provides a variety of functionality that anyone interested in doing any sort of analysis on Haskell source code. Haddock, hint and ghc-mod are all packages which use the GHC API.&lt;/p>
&lt;p>One of the challenges for any program that wants to use the GHC API is integration with Cabal (and, transitively, cabal-install and Stack). The most obvious problem that, when building against packages installed by Cabal, GHC needs to be passed appropriate flags telling it which package databases and actual packages should be used. At this point, people tend to adopt &lt;a href="https://groups.google.com/forum/#!topic/haskell-cafe/3ZgLB2khhcI">some hacky strategy&lt;/a> to get these flags, and hope for the best. For commonly used packages, this strategy will get the job done, but for the rare package that needs something extra&amp;ndash;preprocessing, extra GHC flags, building C sources&amp;ndash;it is unlikely that it will be handled correctly.&lt;/p></description></item><item><title>Try Backpack: Cabal packages</title><link>https://blog.ezyang.com/2017/01/try-backpack-cabal-packages/</link><pubDate>Tue, 17 Jan 2017 23:17:21 +0000</pubDate><guid>https://blog.ezyang.com/2017/01/try-backpack-cabal-packages/</guid><description>&lt;p>This post is part two of a series about how you can try out Backpack, a new mixin package system for Haskell. In the &lt;a href="http://blog.ezyang.com/2016/10/try-backpack-ghc-backpack/">previous post&lt;/a>, we described how to use a new &lt;code>ghc --backpack&lt;/code> mode in GHC to quickly try out Backpack&amp;rsquo;s new signature features. Unfortunately, there is no way to distribute the input files to this mode as packages on Hackage. So in this post, we walk through how to assemble equivalent Cabal packages which have the same functionality.&lt;/p></description></item><item><title>A tale of backwards compatibility in ASTs</title><link>https://blog.ezyang.com/2016/12/a-tale-of-backwards-compatibility-in-asts/</link><pubDate>Sat, 31 Dec 2016 23:35:33 +0000</pubDate><guid>https://blog.ezyang.com/2016/12/a-tale-of-backwards-compatibility-in-asts/</guid><description>&lt;p>Those that espouse the value of backwards compatibility often claim that backwards compatibility is simply a matter of never &lt;em>removing&lt;/em> things. But anyone who has published APIs that involve data structures know that the story is not so simple. I&amp;rsquo;d like to describe my thought process on a recent BC problem I&amp;rsquo;m grappling with on the Cabal file format. As usual, I&amp;rsquo;m always interested in any insights and comments you might have.&lt;/p></description></item><item><title>Backpack and the PVP</title><link>https://blog.ezyang.com/2016/12/backpack-and-the-pvp/</link><pubDate>Fri, 30 Dec 2016 01:32:31 +0000</pubDate><guid>https://blog.ezyang.com/2016/12/backpack-and-the-pvp/</guid><description>&lt;p>In the &lt;a href="http://pvp.haskell.org/">PVP&lt;/a>, you increment the minor version number if you add functions to a module, and the major version number if you remove function to a module. Intuitively, this is because adding functions is a backwards compatible change, while removing functions is a breaking change; to put it more formally, if the new interface is a &lt;em>subtype&lt;/em> of the older interface, then only a minor version number bump is necessary.&lt;/p></description></item><item><title>Left-recursive parsing of Haskell imports and declarations</title><link>https://blog.ezyang.com/2016/12/left-recursive-parsing-of-haskell-imports-and-declarations/</link><pubDate>Wed, 21 Dec 2016 20:24:11 +0000</pubDate><guid>https://blog.ezyang.com/2016/12/left-recursive-parsing-of-haskell-imports-and-declarations/</guid><description>&lt;p>Suppose that you want to parse a list separated by newlines, but you want to automatically ignore extra newlines (just in the same way that &lt;code>import&lt;/code> declarations in a Haskell file can be separated by one or more newlines.) Historically, GHC has used a curious grammar to perform this parse (here, semicolons represent newlines):&lt;/p>
&lt;pre>&lt;code>decls : decls ';' decl
 | decls ';'
 | decl
 | {- empty -}
&lt;/code>&lt;/pre>
&lt;p>It takes a bit of squinting, but what this grammar does is accept a list of decls, interspersed with one or more semicolons, with zero or more leading/trailing semicolons. For example, &lt;code>;decl;;decl;&lt;/code> parses as:&lt;/p></description></item><item><title>The problem of reusable and composable specifications</title><link>https://blog.ezyang.com/2016/12/the-problem-of-reusable-and-composable-specifications/</link><pubDate>Sat, 17 Dec 2016 05:54:31 +0000</pubDate><guid>https://blog.ezyang.com/2016/12/the-problem-of-reusable-and-composable-specifications/</guid><description>&lt;p>It&amp;rsquo;s not too hard to convince people that version bounds are poor approximation for a particular API that we depend on. What do we mean when we say &lt;code>&amp;gt;= 1.0 &amp;amp;&amp;amp; &amp;lt; 1.1&lt;/code>? A version bound is a proxy some set of modules and functions with some particular semantics that a library needs to be built. Version bounds are imprecise; what does a change from 1.0 to 1.1 mean? Clearly, we should instead write down the actual specification (either types or contracts) of what we need.&lt;/p></description></item><item><title>Thoughts about Spec-ulation (Rich Hickey)</title><link>https://blog.ezyang.com/2016/12/thoughts-about-spec-ulation-rich-hickey/</link><pubDate>Fri, 16 Dec 2016 19:26:00 +0000</pubDate><guid>https://blog.ezyang.com/2016/12/thoughts-about-spec-ulation-rich-hickey/</guid><description>&lt;p>Rich Hickey recently gave a &lt;a href="https://www.youtube.com/watch?v=oyLBGkS5ICk">keynote&lt;/a> at Clojure/conj 2016, meditating on the problems of versioning, specification and backwards compatibility in language ecosystems. In it, Rich considers the &lt;a href="http://blog.ezyang.com/2012/11/extremist-programming/">&amp;ldquo;extremist&amp;rdquo; view&lt;/a>, &lt;em>what if we built a language ecosystem, where you never, ever broke backwards compatibility.&lt;/em>&lt;/p>
&lt;p>A large portion of the talk is spent grappling with the ramifications of this perspective. For example:&lt;/p>
&lt;ol>
&lt;li>Suppose you want to make a backwards-compatibility breaking change to a function. Don&amp;rsquo;t &lt;em>mutate&lt;/em> the function, Richard says, give the function another name.&lt;/li>
&lt;li>OK, but how about if there is some systematic change you need to apply to many functions? That&amp;rsquo;s still not an excuse: create a new namespace, and put all the functions there.&lt;/li>
&lt;li>What if there&amp;rsquo;s a function you really don&amp;rsquo;t like, and you really want to get rid of it? No, don&amp;rsquo;t remove it, create a new namespace with that function absent.&lt;/li>
&lt;li>Does this sound like a lot of work to remove things? Yeah. So don&amp;rsquo;t remove things!&lt;/li>
&lt;/ol>
&lt;p>In general, Rich wants us to avoid breakage by turning all changes into &lt;em>accretion&lt;/em>, where the old and new can coexist. &amp;ldquo;We need to bring functional programming [immutability] to the library ecosystem,&amp;rdquo; he says, &amp;ldquo;dependency hell is just mutability hell.&amp;rdquo; And to do this, there need to be tools for you to make a commitment to what it is that a library provides and requires, and not accidentally breaking this commitment when you release new versions of your software.&lt;/p></description></item><item><title>Try Backpack: &lt;code>ghc --backpack&lt;/code></title><link>https://blog.ezyang.com/2016/10/try-backpack-ghc-backpack/</link><pubDate>Mon, 10 Oct 2016 04:39:14 +0000</pubDate><guid>https://blog.ezyang.com/2016/10/try-backpack-ghc-backpack/</guid><description>&lt;p>&lt;a href="https://ghc.haskell.org/trac/ghc/wiki/Backpack">Backpack&lt;/a>, a new system for mix-in packages in Haskell, has been released with GHC 8.2. Although Backpack is closely integrated with the Cabal package system, it&amp;rsquo;s still possible to play around with toy examples using a new command &lt;code>ghc --backpack&lt;/code>. Before you get started, make sure you have a &lt;a href="https://ghc.haskell.org/trac/ghc/blog/ghc-8.2.11-released">recent enough version of GHC&lt;/a>:&lt;/p>
&lt;pre>&lt;code>ezyang@sabre:~$ ghc-8.2 --version
The Glorious Glasgow Haskell Compilation System, version 8.2.1
&lt;/code>&lt;/pre>
&lt;p>By the way, if you want to jump straight into Backpack for real (with Cabal packages and everything), skip this tutorial and jump to &lt;a href="http://blog.ezyang.com/2017/01/try-backpack-cabal-packages/">Try Backpack: Cabal packages&lt;/a>.&lt;/p></description></item><item><title>Seize the Means of Production (of APIs)</title><link>https://blog.ezyang.com/2016/09/seize-the-means-of-production-of-apis/</link><pubDate>Tue, 13 Sep 2016 01:09:52 +0000</pubDate><guid>https://blog.ezyang.com/2016/09/seize-the-means-of-production-of-apis/</guid><description>&lt;p>There&amp;rsquo;s a shitty API and it&amp;rsquo;s ruining your day. What do you do?&lt;/p>
&lt;ul>
&lt;li>Maybe you&amp;rsquo;re Dropbox: Apple&amp;rsquo;s privileges API isn&amp;rsquo;t giving you the knobs you need, so you&amp;rsquo;re like, &amp;ldquo;Fuck this, we&amp;rsquo;re going to &lt;a href="https://news.ycombinator.com/item?id=12463338">edit the privileges SQL database directly&lt;/a>.&amp;rdquo;&lt;/li>
&lt;li>Maybe you&amp;rsquo;re Adam Belay: POSIX isn&amp;rsquo;t letting you write high performance networking code, so you&amp;rsquo;re like &amp;ldquo;Fuck this, we&amp;rsquo;re going to &lt;a href="https://www.usenix.org/system/files/conference/osdi14/osdi14-paper-belay.pdf">redesign the operating system to support high throughput applications&lt;/a>.&amp;rdquo;&lt;/li>
&lt;/ul>
&lt;p>Without making a moral judgment, I want to remark that there is something very different about these two approaches. In Dropbox&amp;rsquo;s case, Dropbox has no (direct) influence on what APIs Apple provides for its operating system. So it has no choice but to work &lt;em>within the boundaries&lt;/em> of the existing API. (When Apple says jump, you say, &amp;ldquo;How high?&amp;rdquo;) But in Adam&amp;rsquo;s case, POSIX is implemented by an open source project Linux, and with some &lt;a href="http://dune.scs.stanford.edu/">good ideas&lt;/a>, Adam could implement his new interface &lt;em>on top&lt;/em> of Linux (avoiding the necessity of writing an operating system from scratch.)&lt;/p></description></item><item><title>The Base of a String Theory for Haskell</title><link>https://blog.ezyang.com/2016/09/the-base-of-a-string-theory-for-haskell/</link><pubDate>Wed, 07 Sep 2016 02:22:53 +0000</pubDate><guid>https://blog.ezyang.com/2016/09/the-base-of-a-string-theory-for-haskell/</guid><description>&lt;p>One of the early posts from this blog, from 2010, was on the subject of &lt;a href="http://blog.ezyang.com/2010/08/strings-in-haskell/">how to pick your string library in Haskell&lt;/a>. Half a decade later, the Haskell ecosystem is still largely in the same situation as it was half a decade ago, where most of the boot libraries shipped with GHC (e.g., &lt;code>base&lt;/code>) still use the &lt;code>String&lt;/code> type, despite the existence of superior string types. The problem is twofold:&lt;/p></description></item><item><title>The Edit-Recompile Manager</title><link>https://blog.ezyang.com/2016/09/the-edit-recompile-manager/</link><pubDate>Fri, 02 Sep 2016 20:40:43 +0000</pubDate><guid>https://blog.ezyang.com/2016/09/the-edit-recompile-manager/</guid><description>&lt;p>A common claim I keep seeing repeated is that there are too many language-specific package managers, and that we should use a distribution&amp;rsquo;s package manager instead. As an example, I opened the most recent &lt;a href="https://news.ycombinator.com/item?id=12187888">HN discussion&lt;/a> related to package managers, and sure enough the &lt;a href="https://news.ycombinator.com/item?id=12189483">third comment&lt;/a> was on this (very) dead horse. (&lt;a href="https://news.ycombinator.com/item?id=12026745">But&lt;/a> &lt;a href="https://news.ycombinator.com/item?id=11469315">wait!&lt;/a> &lt;a href="https://news.ycombinator.com/item?id=11088125">There&amp;rsquo;s&lt;/a> &lt;a href="https://news.ycombinator.com/item?id=10662927">more&lt;/a>.) But it rarely feels like there is any forward progress on these threads. Why?&lt;/p>
&lt;p>Here is my hypothesis: these two camps of people are talking past each other, because the term &amp;ldquo;package manager&amp;rdquo; has been overloaded to mean two things:&lt;/p></description></item><item><title>Backpack and separate compilation</title><link>https://blog.ezyang.com/2016/09/backpack-and-separate-compilation/</link><pubDate>Thu, 01 Sep 2016 02:26:40 +0000</pubDate><guid>https://blog.ezyang.com/2016/09/backpack-and-separate-compilation/</guid><description>&lt;p>When building a module system which supports parametrizing code over multiple implementations (i.e., functors), you run into an important implementation question: how do you &lt;em>compile&lt;/em> said parametric code? In existing language implementations are three major schools of thought:&lt;/p>
&lt;ol>
&lt;li>The &lt;strong>separate compilation&lt;/strong> school says that you should compile your functors independently of their implementations. This school values compilation time over performance: once a functor is built, you can freely swap out implementations of its parameters without needing to rebuild the functor, leading to fast compile times. Pre-Flambda OCaml works this way. The downside is that it&amp;rsquo;s not possible to optimize the functor body based on implementation knowledge (unless, perhaps, you have a just-in-time compiler handy).&lt;/li>
&lt;li>The &lt;strong>specialize at use&lt;/strong> school says, well, you can get performance by inlining functors at their use-sites, where the implementations are known. If the functor body is not too large, you can transparently get good performance benefits without needing to change the architecture of your compiler in major ways. &lt;a href="https://blogs.janestreet.com/flambda/">Post-FLambda OCaml&lt;/a> and C++ templates in &lt;a href="https://gcc.gnu.org/onlinedocs/gcc/Template-Instantiation.html">the Borland model&lt;/a> both work this way. The downside is that the code must be re-optimized at each use site, and there may end up being substantial duplication of code (this can be reduced at link time)&lt;/li>
&lt;li>The &lt;strong>repository of specializations&lt;/strong> school says that it&amp;rsquo;s dumb to keep recompiling the instantiations: instead, the compiled code for each instantiation should be cached somewhere globally; the next time the same instance is needed, it should be reused. C++ templates in the Cfront model and Backpack work this way.&lt;/li>
&lt;/ol>
&lt;p>The repository perspective sounds nice, until you realize that it requires major architectural changes to the way your compiler works: most compilers &lt;em>don&amp;rsquo;t&lt;/em> try to write intermediate results into some shared cache, and adding support for this can be quite complex and error-prone.&lt;/p></description></item><item><title>cabal new-build is a package manager</title><link>https://blog.ezyang.com/2016/08/cabal-new-build-is-a-package-manager/</link><pubDate>Mon, 29 Aug 2016 17:32:36 +0000</pubDate><guid>https://blog.ezyang.com/2016/08/cabal-new-build-is-a-package-manager/</guid><description>&lt;p>An old article I occasionally see cited today is &lt;a href="https://ivanmiljenovic.wordpress.com/2010/03/15/repeat-after-me-cabal-is-not-a-package-manager/">Repeat after me: &amp;ldquo;Cabal is not a Package Manager&amp;rdquo;&lt;/a>. Many of the complaints don&amp;rsquo;t apply to cabal-install 1.24&amp;rsquo;s new &lt;a href="http://blog.ezyang.com/2016/05/announcing-cabal-new-build-nix-style-local-builds/">Nix-style local builds&lt;/a>. Let&amp;rsquo;s set the record straight.&lt;/p>
&lt;h3 id="fact-cabal-new-build-doesnt-handle-non-haskell-dependencies" id="fact-cabal-new-build-doesnt-handle-non-haskell-dependencies">
 &lt;a class="heading-link" href="https://blog.ezyang.com/2016/08/cabal-new-build-is-a-package-manager/#fact-cabal-new-build-doesnt-handle-non-haskell-dependencies">Fact: cabal new-build doesn&amp;rsquo;t handle non-Haskell dependencies&lt;span class="heading-anchor" aria-label="Anchor">¶&lt;/span>&lt;/a>
&lt;/h3>
&lt;p>OK, so this is one thing that hasn&amp;rsquo;t changed since Ivan&amp;rsquo;s article. Unlike Stack, &lt;code>cabal new-build&lt;/code> will not handle downloading and installing GHC for you, and like Stack, it won&amp;rsquo;t download and install system libraries or compiler toolchains: you have to do that yourself. This is definitely a case where you should lean on your system package manager to bootstrap a working installation of Cabal and GHC.&lt;/p></description></item><item><title>Optimizing incremental compilation</title><link>https://blog.ezyang.com/2016/08/optimizing-incremental-compilation/</link><pubDate>Sat, 27 Aug 2016 06:03:03 +0000</pubDate><guid>https://blog.ezyang.com/2016/08/optimizing-incremental-compilation/</guid><description>&lt;p>When you run &lt;code>make&lt;/code> to build software, you expect a build on software that has been previously built to take less time than software we are building from scratch. The reason for this is &lt;strong>incremental compilation&lt;/strong>: by caching the intermediate results of ahead-of-time compilation, the only parts of a program that must be recompiled are those that depend on the changed portions of the dependency graph.&lt;/p>
&lt;p>The term incremental compilation doesn&amp;rsquo;t say much about how the dependency graph is set up, which can lead to some confusion about the performance characteristics of &amp;ldquo;incremental compilers.&amp;rdquo; For example, the &lt;a href="https://en.wikipedia.org/wiki/Incremental_compiler">Wikipedia article on incremental compilation&lt;/a> claims that incremental compilers cannot easily optimize the code that it compiles. This is wrong: it depends entirely on &lt;em>how&lt;/em> your dependency graph is set up.&lt;/p></description></item><item><title>What Template Haskell gets wrong and Racket gets right</title><link>https://blog.ezyang.com/2016/07/what-template-haskell-gets-wrong-and-racket-gets-right/</link><pubDate>Mon, 18 Jul 2016 11:19:37 +0000</pubDate><guid>https://blog.ezyang.com/2016/07/what-template-haskell-gets-wrong-and-racket-gets-right/</guid><description>&lt;p>Why are &lt;a href="https://stackoverflow.com/questions/10857030/whats-so-bad-about-template-haskell">macros in Haskell&lt;/a> terrible, but macros in Racket great? There are certainly many small problems with GHC&amp;rsquo;s Template Haskell support, but I would say that there is one fundamental design point which Racket got right and Haskell got wrong: Template Haskell does not sufficiently distinguish between &lt;em>compile-time&lt;/em> and &lt;em>run-time&lt;/em> phases. Confusion between these two phases leads to strange claims like “Template Haskell doesn’t work for cross-compilation” and stranger features like &lt;code>-fexternal-interpreter&lt;/code> (whereby the cross-compilation problem is “solved” by shipping the macro code to the target platform to be executed).&lt;/p></description></item><item><title>Debugging tcIfaceGlobal errors in GHC: a study in interpreting trace output</title><link>https://blog.ezyang.com/2016/05/debugging-tcifaceglobal-errors-in-ghc-a-study-in-interpreting-trace-output/</link><pubDate>Sun, 15 May 2016 18:02:52 +0000</pubDate><guid>https://blog.ezyang.com/2016/05/debugging-tcifaceglobal-errors-in-ghc-a-study-in-interpreting-trace-output/</guid><description>&lt;p>I recently solved a bug where GHC was being insufficiently lazy (yes, &lt;em>more&lt;/em> laziness needed!) I thought this might serve as a good blog post for how I solve these sorts of laziness bugs, and might engender a useful conversation about how we can make debugging these sorts of problems easier for people.&lt;/p>
&lt;h3 id="hark-a-bug" id="hark-a-bug">
 &lt;a class="heading-link" href="https://blog.ezyang.com/2016/05/debugging-tcifaceglobal-errors-in-ghc-a-study-in-interpreting-trace-output/#hark-a-bug">Hark! A bug!&lt;span class="heading-anchor" aria-label="Anchor">¶&lt;/span>&lt;/a>
&lt;/h3>
&lt;p>Our story begins with an &lt;a href="https://phabricator.haskell.org/D2213">inflight patch&lt;/a> for some related changes I’d been working on. The contents of the patch are not really important—it just fixed a bug where &lt;code>ghc --make&lt;/code> did not have the same behavior as &lt;code>ghc -c&lt;/code> in programs with &lt;code>hs-boot&lt;/code> files.&lt;/p></description></item><item><title>Announcing cabal new-build: Nix-style local builds</title><link>https://blog.ezyang.com/2016/05/announcing-cabal-new-build-nix-style-local-builds/</link><pubDate>Mon, 02 May 2016 12:45:01 +0000</pubDate><guid>https://blog.ezyang.com/2016/05/announcing-cabal-new-build-nix-style-local-builds/</guid><description>&lt;p>&lt;code>cabal new-build&lt;/code>, also known as “Nix-style local builds”, is a new command inspired by Nix that comes with cabal-install 1.24. Nix-style local builds combine the best of non-sandboxed and sandboxed Cabal:&lt;/p>
&lt;ol>
&lt;li>Like sandboxed Cabal today, we build sets of independent local packages deterministically and independent of any global state. new-build will never tell you that it can&amp;rsquo;t build your package because it would result in a “dangerous reinstall.” Given a particular state of the Hackage index, your build is completely reproducible. For example, you no longer need to compile packages with profiling ahead of time; just request profiling and new-build will rebuild all its dependencies with profiling automatically.&lt;/li>
&lt;li>Like non-sandboxed Cabal today, builds of external packages are cached globally, so that a package can be built once, and then reused anywhere else it is also used. No need to continually rebuild dependencies whenever you make a new sandbox: dependencies which can be shared, are shared.&lt;/li>
&lt;/ol>
&lt;p>Nix-style local builds work with all versions of GHC supported by cabal-install 1.24, which currently is GHC 7.0 and later. Additionally, cabal-install is on a different release cycle than GHC, so we plan to be pushing bugfixes and updates on a faster basis than GHC&amp;rsquo;s yearly release cycle.&lt;/p></description></item><item><title>Hindley-Milner with top-level existentials</title><link>https://blog.ezyang.com/2016/04/hindley-milner-with-top-level-existentials/</link><pubDate>Sun, 24 Apr 2016 04:05:09 +0000</pubDate><guid>https://blog.ezyang.com/2016/04/hindley-milner-with-top-level-existentials/</guid><description>&lt;p>&lt;em>Content advisory: This is a half-baked research post.&lt;/em>&lt;/p>
&lt;p>&lt;strong>Abstract.&lt;/strong> Top-level unpacking of existentials are easy to integrate into Hindley-Milner type inference. Haskell should support them. It&amp;rsquo;s possible this idea can work for internal bindings of existentials as well (ala F-ing modules) but I have not worked out how to do it.&lt;/p>
&lt;p>&lt;strong>Update.&lt;/strong> And UHC did it first!&lt;/p>
&lt;p>&lt;strong>Update 2.&lt;/strong> And rank-2 type inference is decidable (and rank-1 existentials are an even weaker system), although the algorithm for rank-2 inference requires semiunification.&lt;/p></description></item><item><title>ghc-shake: Reimplementing ghc -&amp;#8203;-make</title><link>https://blog.ezyang.com/2016/01/ghc-shake-reimplementing-ghc-make/</link><pubDate>Thu, 07 Jan 2016 12:59:32 +0000</pubDate><guid>https://blog.ezyang.com/2016/01/ghc-shake-reimplementing-ghc-make/</guid><description>&lt;p>&lt;code>ghc --make&lt;/code> is a useful mode in GHC which automatically determines what modules need to be compiled and compiles them for you. Not only is it a convenient way of building Haskell projects, its single-threaded performance is good too, by reusing the work of reading and deserializing external interface files. However, the are a number of downsides to &lt;code>ghc --make&lt;/code>:&lt;/p>
&lt;ol>
&lt;li>Projects with large module graphs have a hefty latency before recompilation begins. This is because &lt;code>ghc --make&lt;/code> (re)computes the full module graph, parsing each source file&amp;rsquo;s header, before actually doing any work. If you have a preprocessor, &lt;a href="https://ghc.haskell.org/trac/ghc/ticket/1290">it&amp;rsquo;s even worse&lt;/a>.&lt;/li>
&lt;li>It&amp;rsquo;s a monolithic build system, which makes it hard to integrate with other build systems if you need something more fancy than what GHC knows how to do. (For example, GHC&amp;rsquo;s painstakingly crafted build system knows how to build in parallel across package boundaries, which Cabal has no idea how to do.)&lt;/li>
&lt;li>It doesn&amp;rsquo;t give you any insight into the performance of your build, e.g. what modules take a long time to build or what the big &amp;ldquo;blocker&amp;rdquo; modules are.&lt;/li>
&lt;/ol>
&lt;p>&lt;a href="https://github.com/ezyang/ghc-shake">ghc-shake&lt;/a> is a reimplementation of &lt;code>ghc --make&lt;/code> using the &lt;a href="http://shakebuild.com/">Shake build system&lt;/a>. It is a drop-in replacement for &lt;code>ghc&lt;/code>. ghc-shake sports the following features:&lt;/p></description></item><item><title>The convergence of compilers, build systems and package managers</title><link>https://blog.ezyang.com/2015/12/the-convergence-of-compilers-build-systems-and-package-managers/</link><pubDate>Mon, 07 Dec 2015 01:50:28 +0000</pubDate><guid>https://blog.ezyang.com/2015/12/the-convergence-of-compilers-build-systems-and-package-managers/</guid><description>&lt;p>Abstract. &lt;em>The traditional abstraction barriers between compiler, build system and package manager are increasingly ill-suited for IDEs, parallel build systems, and modern source code organization. Recent compilers like go and rustc are equipped with a fully-fledged build systems; semantic build systems like Bazel and Gradle also expect to manage the packaging of software. Does this mean we should jettison these abstraction barriers? It seems worthwhile to look for new interfaces which can accommodate these use-cases.&lt;/em>&lt;/p></description></item><item><title>What is Stateless User Interface?</title><link>https://blog.ezyang.com/2015/11/what-is-stateless-user-interface/</link><pubDate>Fri, 27 Nov 2015 01:53:49 +0000</pubDate><guid>https://blog.ezyang.com/2015/11/what-is-stateless-user-interface/</guid><description>&lt;p>The essence of stateless user interface is that actions you take with a program should not depend on implicit state. Stateless interfaces are easier to understand, because an invocation of a command with some arguments will &lt;em>always&lt;/em> do the same thing, whereas in a stateful interface, the command may do some different than it did yesterday, because that implicit state has changed and is influencing the meaning of your program.&lt;/p></description></item><item><title>Is no-reinstall Cabal coming to GHC 8.0?</title><link>https://blog.ezyang.com/2015/09/is-no-reinstall-cabal-coming-to-ghc-8/</link><pubDate>Fri, 18 Sep 2015 23:15:47 +0000</pubDate><guid>https://blog.ezyang.com/2015/09/is-no-reinstall-cabal-coming-to-ghc-8/</guid><description>&lt;p>You might be wondering: with the &lt;a href="http://blog.ezyang.com/2015/08/help-us-beta-test-no-reinstall-cabal/">beta release of no-reinstall Cabal&lt;/a>, is this functionality be coming to GHC 8.0? (Or even a new release of Cabal, since the no-reinstall feature works with GHC 7.10). Unfortunately, there is a split among the Cabal developers over whether or not the actual no-reinstall behavior should go into Cabal by default as is. Duncan Coutts, in particular, has argued that it&amp;rsquo;s a bad idea to enable no-reinstall without other (unimplemented) changes to Cabal. Since the extra needed changes are not fully implemented yet, it&amp;rsquo;s unclear if Duncan will manage them for GHC 8.0.&lt;/p></description></item><item><title>Help us beta test "no-reinstall Cabal"</title><link>https://blog.ezyang.com/2015/08/help-us-beta-test-no-reinstall-cabal/</link><pubDate>Sat, 29 Aug 2015 00:31:15 +0000</pubDate><guid>https://blog.ezyang.com/2015/08/help-us-beta-test-no-reinstall-cabal/</guid><description>&lt;p>Over this summer, Vishal Agrawal has been working on a GSoC project to &lt;a href="https://ghc.haskell.org/trac/ghc/wiki/Commentary/GSoC_Cabal_nix">move Cabal to more Nix-like package management system&lt;/a>. More simply, he is working to make it so that you&amp;rsquo;ll never get one of these errors from &lt;span class="title-ref">cabal-install&lt;/span> again:&lt;/p>
&lt;pre>&lt;code>Resolving dependencies...
In order, the following would be installed:
directory-1.2.1.0 (reinstall) changes: time-1.4.2 -&amp;gt; 1.5
process-1.2.1.0 (reinstall)
extra-1.0 (new package)
cabal: The following packages are likely to be broken by the reinstalls:
process-1.2.0.0
hoogle-4.2.35
haskell98-2.0.0.3
ghc-7.8.3
Cabal-1.22.0.0
...
&lt;/code>&lt;/pre>
&lt;p>However, these patches change a nontrivial number of moving parts in Cabal and cabal-install, so it would be very helpful to have willing guinea pigs to help us iron out some bugs before we merge it into Cabal HEAD. As your prize, you&amp;rsquo;ll get to run &amp;ldquo;no-reinstall Cabal&amp;rdquo;: Cabal should &lt;strong>never&lt;/strong> tell you it can&amp;rsquo;t install a package because some reinstalls would be necessary.&lt;/p></description></item><item><title>Ubuntu Vivid upgrade (Xmonad)</title><link>https://blog.ezyang.com/2015/05/ubuntu-vivid-upgrade-xmonad/</link><pubDate>Fri, 29 May 2015 14:09:30 +0000</pubDate><guid>https://blog.ezyang.com/2015/05/ubuntu-vivid-upgrade-xmonad/</guid><description>&lt;p>Another half year, another Ubuntu upgrade. This upgrade went essentially smoothly: the only things that stopped working were my xbindkeys bindings for volume and suspend, which were easy to fix.&lt;/p>
&lt;h3 id="volume-up-and-down" id="volume-up-and-down">
 &lt;a class="heading-link" href="https://blog.ezyang.com/2015/05/ubuntu-vivid-upgrade-xmonad/#volume-up-and-down">Volume up and down&lt;span class="heading-anchor" aria-label="Anchor">¶&lt;/span>&lt;/a>
&lt;/h3>
&lt;p>If you previously had:&lt;/p>
&lt;pre>&lt;code>#Volume Up
&amp;quot;pactl set-sink-volume 0 -- +5%&amp;quot;
 m:0x10 + c:123
 Mod2 + XF86AudioRaiseVolume 
&lt;/code>&lt;/pre>
&lt;p>this syntax no longer works: you must place the double dash earlier in the command, as so:&lt;/p></description></item><item><title>Width-adaptive XMonad layout</title><link>https://blog.ezyang.com/2015/05/width-adaptive-xmonad-layout/</link><pubDate>Sat, 02 May 2015 00:36:55 +0000</pubDate><guid>https://blog.ezyang.com/2015/05/width-adaptive-xmonad-layout/</guid><description>&lt;p>My usual laptop setup is I have a wide monitor, and then I use my laptop screen as a secondary monitor. For a long time, I had two XMonad layouts: one full screen layout for my laptop monitor (I use big fonts to go easy on the eyes) and a two-column layout when I&amp;rsquo;m on the big screen.&lt;/p>
&lt;p>But I had an irritating problem: if I switched a workspace from the small screen to the big screen, XMonad would still be using the full screen layout, and I would have to Alt-Tab my way into the two column layout. To add insult to injury, if I moved it back, I&amp;rsquo;d have to Alt-Tab once again.&lt;/p></description></item><item><title>An Eq instance for non de Bruijn terms</title><link>https://blog.ezyang.com/2015/01/an-eq-instance-for-non-de-bruijn-terms/</link><pubDate>Fri, 30 Jan 2015 21:14:10 +0000</pubDate><guid>https://blog.ezyang.com/2015/01/an-eq-instance-for-non-de-bruijn-terms/</guid><description>&lt;p>&lt;strong>tl;dr&lt;/strong> &lt;em>A non-nameless term equipped with a map specifying a de Bruijn numbering can support an efficient equality without needing a helper function. More abstractly, quotients are not just for proofs: they can help efficiency of programs too.&lt;/em>&lt;/p>
&lt;p>&lt;strong>The cut.&lt;/strong> You&amp;rsquo;re writing a small compiler, which defines expressions as follows:&lt;/p>
&lt;pre>&lt;code>type Var = Int
data Expr = Var Var
 | App Expr Expr
 | Lam Var Expr
&lt;/code>&lt;/pre>
&lt;p>Where &lt;code>Var&lt;/code> is provided from some globally unique supply. But while working on a common sub-expression eliminator, you find yourself needing to define &lt;em>equality&lt;/em> over expressions.&lt;/p></description></item><item><title>Unintended consequences: Bound threads and unsafe FFI calls</title><link>https://blog.ezyang.com/2014/12/unintended-consequences-bound-threads-and-unsafe-ffi-calls/</link><pubDate>Mon, 08 Dec 2014 19:09:33 +0000</pubDate><guid>https://blog.ezyang.com/2014/12/unintended-consequences-bound-threads-and-unsafe-ffi-calls/</guid><description>&lt;p>A while ago, I wrote a post describing how &lt;a href="http://blog.ezyang.com/2010/07/safety-first-ffi-and-threading/">unsafe FFI calls could block your entire system&lt;/a>, and gave the following example of this behavior:&lt;/p>
&lt;pre>&lt;code>/* cbit.c */
#include &amp;lt;stdio.h&amp;gt;
int bottom(int a) {
 while (1) {printf(&amp;quot;%d\n&amp;quot;, a);sleep(1);}
 return a;
}

/* cbit.h */
int bottom(int a);

/* UnsafeFFITest.hs */
{-# LANGUAGE ForeignFunctionInterface #-}

import Foreign.C
import Control.Concurrent

main = do
 forkIO $ do
 safeBottom 1
 return ()
 yield
 print &amp;quot;Pass (expected)&amp;quot;
 forkIO $ do
 unsafeBottom 2
 return ()
 yield
 print &amp;quot;Pass (not expected)&amp;quot;

foreign import ccall &amp;quot;cbit.h bottom&amp;quot; safeBottom :: CInt -&amp;gt; IO CInt
foreign import ccall unsafe &amp;quot;cbit.h bottom&amp;quot; unsafeBottom :: CInt -&amp;gt; IO CInt
&lt;/code>&lt;/pre>
&lt;p>In the post, I explained that the reason this occurs is that unsafe FFI calls are not preemptible, so when unsafeBottom loops forever, the Haskell thread can&amp;rsquo;t proceed.&lt;/p></description></item><item><title>Ubuntu Utopic upgrade (Xmonad)</title><link>https://blog.ezyang.com/2014/12/ubuntu-utopic-upgrade-xmonad/</link><pubDate>Thu, 04 Dec 2014 18:48:19 +0000</pubDate><guid>https://blog.ezyang.com/2014/12/ubuntu-utopic-upgrade-xmonad/</guid><description>&lt;p>I finally got around to upgrading to Utopic. &lt;a href="http://blog.ezyang.com/2013/10/xmonad-and-media-keys-on-saucy/">A year ago&lt;/a> I reported that gnome-settings-daemon no longer provided keygrabbing support. This was eventually reverted for Trusty, which kept everyone&amp;rsquo;s media keys.&lt;/p>
&lt;p>I&amp;rsquo;m sorry to report that in Ubuntu Utopic, the legacy keygrabber is no more:&lt;/p>
&lt;pre>&lt;code>------------------------------------------------------------
revno: 4015 [merge]
author: William Hua &amp;lt;william.hua@canonical.com&amp;gt;
committer: Tarmac
branch nick: trunk
timestamp: Tue 2014-02-18 18:22:53 +0000
message:
 Revert the legacy key grabber. Fixes: https://bugs.launchpad.net/bugs/1226962.
&lt;/code>&lt;/pre>
&lt;p>It appears that the Unity team has forked gnome-settings-daemon into unity-settings-daemon (actually this fork happened in Trusty), and as of Utopic gnome-settings-daemon and gnome-control-center &lt;a href="https://bugs.launchpad.net/ubuntu/+source/gnome-settings-daemon/+bug/1318539">have been gutted&lt;/a> in favor of unity-settings-daemon and unity-control-center. Which puts us back in the same situation as a year ago.&lt;/p></description></item><item><title>Tomatoes are a subtype of vegetables</title><link>https://blog.ezyang.com/2014/11/tomatoes-are-a-subtype-of-vegetables/</link><pubDate>Fri, 14 Nov 2014 21:00:36 +0000</pubDate><guid>https://blog.ezyang.com/2014/11/tomatoes-are-a-subtype-of-vegetables/</guid><description>&lt;p>&lt;img src="https://blog.ezyang.com/img/vegetables/st1.png" alt="image">&lt;/p>
&lt;p>Subtyping is one of those concepts that seems to makes sense when you first learn it (“Sure, convertibles are a subtype of vehicles, because all convertibles are vehicles but not all vehicles are convertibles”) but can quickly become confusing when function types are thrown into the mix. For example, if &lt;code>a&lt;/code> is a subtype of &lt;code>b&lt;/code>, is &lt;code>(a -&amp;gt; r) -&amp;gt; r&lt;/code> a subtype of &lt;code>(b -&amp;gt; r) -&amp;gt; r&lt;/code>? (If you know the answer to this question, this blog post is not for you!) When we asked our students this question, invariably some were lead astray. True, you can mechanically work it out using the rules, but what’s the intuition?&lt;/p></description></item><item><title>Haskell Implementor's Workshop '14</title><link>https://blog.ezyang.com/2014/09/haskell-implementors-workshop-14/</link><pubDate>Sun, 07 Sep 2014 09:05:02 +0000</pubDate><guid>https://blog.ezyang.com/2014/09/haskell-implementors-workshop-14/</guid><description>&lt;p>This year at ICFP, we had some blockbuster attendance to the &lt;a href="http://www.haskell.org/haskellwiki/HaskellImplementorsWorkshop/2014">Haskell Implementor&amp;rsquo;s Workshop&lt;/a> (at times, it was standing room only). I had the pleasure of presenting the work I had done over the summer on Backpack.&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/backpack-ufo.png" alt="image">&lt;/p>
&lt;p>You can &lt;a href="http://web.mit.edu/~ezyang/Public/hiw14-backpack-slides.pdf">grab the slides&lt;/a> or &lt;a href="https://www.youtube.com/watch?v=0dF9zuwTSTc">view the presentation itself&lt;/a> (thank you ICFP organizers for being incredibly on-the-ball with videos this year!) The talk intersects a little bit with my blog post &lt;a href="http://blog.ezyang.com/2014/08/a-taste-of-cabalized-backpack/">A taste of Cabalized Backpack&lt;/a>, but there are more pictures, and I also emphasize (perhaps a little too much) the long term direction we are headed in.&lt;/p></description></item><item><title>Open type families are not modular</title><link>https://blog.ezyang.com/2014/09/open-type-families-are-not-modular/</link><pubDate>Thu, 04 Sep 2014 18:12:23 +0000</pubDate><guid>https://blog.ezyang.com/2014/09/open-type-families-are-not-modular/</guid><description>&lt;p>One of the major open problems for building a module system in Haskell is the treatment of type classes, which I have &lt;a href="http://blog.ezyang.com/2014/07/type-classes-confluence-coherence-global-uniqueness/">discussed previously&lt;/a> on this blog. I&amp;rsquo;ve noted how the current mode of use in type classes in Haskell assume “global uniqueness”, which is inherently anti-modular; breaking this assumption risks violating the encapsulation of many existing data types.&lt;/p>
&lt;p>As if we have a choice.&lt;/p>
&lt;p>In fact, our hand is forced by the presence of &lt;strong>open type families&lt;/strong> in Haskell, which are feature many similar properties to type classes, but with the added property that global uniqueness is &lt;em>required&lt;/em> for type safety. We don&amp;rsquo;t have a choice (unless we want type classes with associated types to behave differently from type classes): we have to figure out how to reconcile the inherent non-modularity of type families with the Backpack module system.&lt;/p></description></item><item><title>A taste of Cabalized Backpack</title><link>https://blog.ezyang.com/2014/08/a-taste-of-cabalized-backpack/</link><pubDate>Tue, 26 Aug 2014 18:01:48 +0000</pubDate><guid>https://blog.ezyang.com/2014/08/a-taste-of-cabalized-backpack/</guid><description>&lt;p>&lt;strong>Update.&lt;/strong> Want to know more about Backpack? Read the &lt;a href="https://github.com/ezyang/ghc-proposals/blob/backpack/proposals/0000-backpack.rst">specification&lt;/a>&lt;/p>
&lt;p>So perhaps you&amp;rsquo;ve &lt;a href="http://blog.ezyang.com/2014/08/whats-a-module-system-good-for-anyway/">bought into modules and modularity&lt;/a> and want to get to using Backpack straightaway. How can you do it? In this blog post, I want to give a tutorial-style taste of how to program Cabal in the Backpack style. These examples are executable, but you&amp;rsquo;ll have to build custom versions of &lt;a href="https://github.com/ezyang/ghc/tree/ghc-backpack">GHC&lt;/a> and &lt;a href="https://github.com/ezyang/cabal/tree/backpack">Cabal&lt;/a> to build them. Comments and suggestions would be much appreciated; while the design here is theoretically well-founded, for obvious reasons, we don&amp;rsquo;t have much on-the-ground programmer feedback yet.&lt;/p></description></item><item><title>The fundamental problem of programming language package management</title><link>https://blog.ezyang.com/2014/08/the-fundamental-problem-of-programming-language-package-management/</link><pubDate>Thu, 21 Aug 2014 09:02:53 +0000</pubDate><guid>https://blog.ezyang.com/2014/08/the-fundamental-problem-of-programming-language-package-management/</guid><description>&lt;p>Why are there so many goddamn package managers? They sprawl across both operating systems (apt, yum, pacman, Homebrew) as well as for programming languages (Bundler, Cabal, Composer, CPAN, CRAN, CTAN, EasyInstall, Go Get, Maven, npm, NuGet, OPAM, PEAR, pip, RubyGems, etc etc etc). &amp;ldquo;It is a truth universally acknowledged that a programming language must be in want of a package manager.&amp;rdquo; What is the fatal attraction of package management that makes programming language after programming language jump off this cliff? Why can&amp;rsquo;t we just, you know, &lt;a href="http://www.standalone-sysadmin.com/blog/2014/03/just-what-we-need-another-package-manager/">reuse&lt;/a> an existing package manager?&lt;/p></description></item><item><title>What's a module system good for anyway?</title><link>https://blog.ezyang.com/2014/08/whats-a-module-system-good-for-anyway/</link><pubDate>Sat, 09 Aug 2014 19:21:19 +0000</pubDate><guid>https://blog.ezyang.com/2014/08/whats-a-module-system-good-for-anyway/</guid><description>&lt;p>This summer, I&amp;rsquo;ve been working at Microsoft Research implementing &lt;a href="http://plv.mpi-sws.org/backpack/">Backpack&lt;/a>, a module system for Haskell. Interestingly, Backpack is not really a single monolothic feature, but, rather, an agglomeration of small, infrastructural changes which combine together in an interesting way. In this series of blog posts, I want to talk about what these individual features are, as well as how the whole is greater than the sum of the parts.&lt;/p>
&lt;p>But first, there&amp;rsquo;s an important question that I need to answer: &lt;strong>What&amp;rsquo;s a module system good for anyway?&lt;/strong> Why should you, an average Haskell programmer, care about such nebulous things as &lt;em>module systems&lt;/em> and &lt;em>modularity&lt;/em>. At the end of the day, you want your tools to solve specific problems you have, and it is sometimes difficult to understand what problem a module system like Backpack solves. As &lt;a href="http://www.reddit.com/r/haskell/comments/28v6c9/backpack_an_mllike_module_system_for_haskell/cierxc1">tomejaguar puts it&lt;/a>: &amp;ldquo;Can someone explain clearly the precise problem that Backpack addresses? I&amp;rsquo;ve read the paper and I know the problem is &amp;lsquo;modularity&amp;rsquo; but I fear I am lacking the imagination to really grasp what the issue is.&amp;rdquo;&lt;/p></description></item><item><title>New theme!</title><link>https://blog.ezyang.com/2014/07/new-theme/</link><pubDate>Sat, 26 Jul 2014 09:58:27 +0000</pubDate><guid>https://blog.ezyang.com/2014/07/new-theme/</guid><description>&lt;p>Hello loyal readers: Inside 206-105 has a new theme! I’m retiring &lt;a href="http://themes.jimbarraud.com/manifest/">Manifest&lt;/a>, which was a pretty nice theme but (1) the text size was too small and (2) I decided I didn’t really like the fonts, I’ve reskinned my blog with a theme based on Brent Jackson’s &lt;a href="http://jxnblk.com/ashley/">Ashley&lt;/a>, but ported to work on Wordpress. I hope you like it, and please report any rendering snafus you might notice on older pages. Thanks!&lt;/p></description></item><item><title>Type classes: confluence, coherence and global uniqueness</title><link>https://blog.ezyang.com/2014/07/type-classes-confluence-coherence-global-uniqueness/</link><pubDate>Fri, 11 Jul 2014 12:07:53 +0000</pubDate><guid>https://blog.ezyang.com/2014/07/type-classes-confluence-coherence-global-uniqueness/</guid><description>&lt;p>Today, I&amp;rsquo;d like to talk about some of the core design principles behind type classes, a wildly successful feature in Haskell. The discussion here is closely motivated by the work we are doing at MSRC to support type classes in Backpack. While I was doing background reading, I was flummoxed to discover widespread misuse of the terms &amp;ldquo;confluence&amp;rdquo; and &amp;ldquo;coherence&amp;rdquo; with respect to type classes. So in this blog post, I want to settle the distinction, and propose a new term, &amp;ldquo;global uniqueness of instances&amp;rdquo; for the property which people have been colloquially referred to as confluence and coherence.&lt;/p></description></item><item><title>Parsec: "try a &amp;lt;|&amp;gt; b" considered harmful</title><link>https://blog.ezyang.com/2014/05/parsec-try-a-or-b-considered-harmful/</link><pubDate>Sat, 17 May 2014 21:46:52 +0000</pubDate><guid>https://blog.ezyang.com/2014/05/parsec-try-a-or-b-considered-harmful/</guid><description>&lt;div class="container center">
&lt;p>&lt;em>tl;dr The scope of backtracking try should be minimized, usually by placing it inside the definition of a parser.&lt;/em>&lt;/p>
&lt;/div>
&lt;p>Have you ever written a Parsec parser and gotten a really uninformative error message? :&lt;/p>
&lt;pre>&lt;code>&amp;quot;test.txt&amp;quot; (line 15, column 7):
unexpected 'A'
expecting end of input
&lt;/code>&lt;/pre>
&lt;p>The line and the column are randomly somewhere in your document, and you&amp;rsquo;re pretty sure you should be in the middle of some stack of parser combinators. But wait! Parsec has somehow concluded that the document should be ending immediately. You noodle around and furthermore discover that the true error is some ways &lt;em>after&lt;/em> the actually reported line and column.&lt;/p></description></item><item><title>GHC and mutable arrays: a DIRTY little secret</title><link>https://blog.ezyang.com/2014/05/ghc-and-mutable-arrays-a-dirty-little-secret/</link><pubDate>Fri, 09 May 2014 02:34:46 +0000</pubDate><guid>https://blog.ezyang.com/2014/05/ghc-and-mutable-arrays-a-dirty-little-secret/</guid><description>&lt;p>Brandon Simmon recently &lt;a href="http://www.haskell.org/pipermail/glasgow-haskell-users/2014-May/024976.html">made a post&lt;/a> to the glasgow-haskell-users mailing list asking the following question:&lt;/p>
&lt;blockquote>
&lt;p>I&amp;rsquo;ve been looking into &lt;a href="http://stackoverflow.com/questions/23462004/code-becomes-slower-as-more-boxed-arrays-are-allocated/23557704#23557704">an issue&lt;/a> in a library in which as more mutable arrays are allocated, GC dominates (I think I verified this?) and all code gets slower in proportion to the number of mutable arrays that are hanging around.&lt;/p>&lt;/blockquote>
&lt;p>&amp;hellip;to which I replied:&lt;/p>
&lt;blockquote>
&lt;p>In the current GC design, mutable arrays of pointers are always placed on the mutable list. The mutable list of generations which are not being collected are always traversed; thus, the number of pointer arrays corresponds to a linear overhead for minor GCs.&lt;/p></description></item><item><title>Elimination with a Motive (in Coq)</title><link>https://blog.ezyang.com/2014/05/elimination-with-a-motive-in-coq/</link><pubDate>Wed, 07 May 2014 23:13:15 +0000</pubDate><guid>https://blog.ezyang.com/2014/05/elimination-with-a-motive-in-coq/</guid><description>&lt;p>Elimination rules play an important role in computations over datatypes in proof assistants like Coq. In his paper &amp;ldquo;Elimination with a Motive&amp;rdquo;, Conor McBride argued that &amp;ldquo;we should exploit a hypothesis not in terms of its immediate consequences, but in terms of the leverage it exerts on an arbitrary goal: we should give elimination a motive.&amp;rdquo; In other words, proofs in a refinement setting (backwards reasoning) should use their goals to guide elimination.&lt;/p></description></item><item><title>The cost of weak pointers and finalizers in GHC</title><link>https://blog.ezyang.com/2014/05/the-cost-of-weak-pointers-and-finalizers-in-ghc/</link><pubDate>Sun, 04 May 2014 04:55:36 +0000</pubDate><guid>https://blog.ezyang.com/2014/05/the-cost-of-weak-pointers-and-finalizers-in-ghc/</guid><description>&lt;p>&lt;a href="http://community.haskell.org/~simonmar/papers/weak.pdf">Weak pointers and finalizers&lt;/a> are a very convenient feature for many types of programs. Weak pointers are useful for implementing memotables and solving certain classes of memory leaks, while finalizers are useful for fitting &amp;ldquo;allocate/deallocate&amp;rdquo; memory models into a garbage-collected language. Of course, these features don’t come for free, and so one might wonder what the &lt;em>cost&lt;/em> of utilizing these two (closely related) features are in GHC. In this blog post, I want to explain how weak pointers and finalizers are implemented in the GHC runtime system and characterize what extra overheads you incur by using them. These post assumes some basic knowledge about how the runtime system and copying garbage collection work.&lt;/p></description></item><item><title>Calculating Shanten in Mahjong</title><link>https://blog.ezyang.com/2014/04/calculating-shanten-in-mahjong/</link><pubDate>Tue, 01 Apr 2014 04:20:46 +0000</pubDate><guid>https://blog.ezyang.com/2014/04/calculating-shanten-in-mahjong/</guid><description>&lt;p>Move aside, poker! While the probabilities of various poker hands are well understood and tabulated, the Chinese game of chance &lt;a href="http://en.wikipedia.org/wiki/Mahjong">Mahjong&lt;/a> [1] enjoys a far more intricate structure of expected values and probabilities. [2] This is largely due in part to the much larger variety of tiles available (136 tiles, as opposed to the standard playing card deck size of 52), as well as the turn-by-turn game play, which means there is quite a lot of strategy involved with what is ostensibly a game of chance. In fact, the subject is so intricate, I’ve decided to write my PhD thesis on it. This blog post is a condensed version of one chapter of my thesis, considering the calculation of &lt;em>shanten&lt;/em>, which we will define below. I’ll be using Japanese terms, since my favorite variant of mahjong is Riichi Mahjong; you can consult the &lt;a href="http://en.wikipedia.org/wiki/Japanese_Mahjong">Wikipedia article&lt;/a> on the subject if you need to translate.&lt;/p></description></item><item><title>Haskell for Coq programmers</title><link>https://blog.ezyang.com/2014/03/haskell-for-coq-programmers/</link><pubDate>Mon, 17 Mar 2014 02:06:47 +0000</pubDate><guid>https://blog.ezyang.com/2014/03/haskell-for-coq-programmers/</guid><description>&lt;p>So you may have heard about this popular new programming language called Haskell. What&amp;rsquo;s Haskell? Haskell is a non-dependently typed programming language, sporting general recursion, type inference and built-in side-effects. It is true that dependent types are considered an essential component of modern, expressive type systems. However, giving up dependence can result in certain benefits for other aspects of software engineering, and in this article, we&amp;rsquo;d like to talk about the omissions that Haskell makes to support these changes.&lt;/p></description></item><item><title>Equality, roughly speaking</title><link>https://blog.ezyang.com/2014/01/equality-roughly-speaking/</link><pubDate>Thu, 30 Jan 2014 00:05:03 +0000</pubDate><guid>https://blog.ezyang.com/2014/01/equality-roughly-speaking/</guid><description>&lt;p>In Software Foundations, equality is &lt;a href="http://www.cis.upenn.edu/~bcpierce/sf/Logic.html#lab220">defined in this way&lt;/a>:&lt;/p>
&lt;blockquote>
&lt;p>Even Coq&amp;rsquo;s equality relation is not built in. It has (roughly) the following inductive definition. :&lt;/p>
&lt;pre>&lt;code>Inductive eq0 {X:Type} : X -&amp;gt; X -&amp;gt; Prop :=
 refl_equal0 : forall x, eq0 x x.
&lt;/code>&lt;/pre>&lt;/blockquote>
&lt;p>&lt;em>Why the roughly?&lt;/em> Well, as it turns out, Coq defines equality a little differently (reformatted to match the Software Foundations presentation):&lt;/p>
&lt;pre>&lt;code>Inductive eq1 {X:Type} (x:X) : X -&amp;gt; Prop :=
 refl_equal1 : eq1 x x.
&lt;/code>&lt;/pre>
&lt;p>What’s the difference? The trick is to look at the induction principles that Coq generates for each of these:&lt;/p></description></item><item><title>How to maintain a pristine copy of your configuration files</title><link>https://blog.ezyang.com/2014/01/how-to-maintain-a-pristine-copy-of-your-configuration-files/</link><pubDate>Mon, 20 Jan 2014 19:02:31 +0000</pubDate><guid>https://blog.ezyang.com/2014/01/how-to-maintain-a-pristine-copy-of-your-configuration-files/</guid><description>&lt;p>&lt;a href="http://joeyh.name/code/etckeeper/">etckeeper&lt;/a> is a pretty good tool for keeping your /etc under version control, but one thing that it won’t tell you is what the diff between your configuration and a pristine version of your configuration (if you installed the same packages on the system, but didn’t change any configuration). &lt;a href="https://blueprints.launchpad.net/ubuntu/+spec/foundations-q-dpkg-pristine-conffiles">People have wanted this&lt;/a>, but I couldn’t find anything that actually did this. A month ago, I figured out a nice, easy way to achieve this under etckeeper with a Git repository. The idea is to maintain a pristine branch, and when an upgrade occurs, automatically apply the patch (automatically generated) to a pristine branch. This procedure works best on a fresh install, since I don’t have a good way of reconstructing history if you haven’t been tracking the pristine from the start.&lt;/p></description></item><item><title>PEPM'14: The HERMIT in the Stream</title><link>https://blog.ezyang.com/2014/01/pepm14-the-hermit-in-the-stream/</link><pubDate>Fri, 17 Jan 2014 02:36:41 +0000</pubDate><guid>https://blog.ezyang.com/2014/01/pepm14-the-hermit-in-the-stream/</guid><description>&lt;p>POPL is almost upon us! I’ll be &lt;a href="http://ezyang.tumblr.com/">live-Tumblr-ing&lt;/a> it when the conference comes upon us proper, but in the meantime, I thought I’d write a little bit about one paper in the colocated PEPM'14 program: &lt;a href="http://www.ittc.ku.edu/~afarmer/concatmap-pepm14.pdf">The HERMIT in the Stream&lt;/a>, by Andrew Farmer, Christian Höner zu Sierdissen and Andy Gill. This paper presents an implementation of an optimization scheme for fusing away use of the concatMap combinator in the &lt;a href="http://citeseer.ist.psu.edu/viewdoc/summary?doi=10.1.1.104.7401">stream fusion framework&lt;/a>, which was developed using the &lt;a href="http://www.ittc.ku.edu/csdl/fpg/software/hermit.html">HERMIT optimization framework&lt;/a>. The HERMIT project has been chugging along for some time now, and a stream of papers of various applications of the framework have been trickling out (as anyone who was at the Haskell implementors workshop can attest.)&lt;/p></description></item><item><title>Ott ⇔ PLT Redex</title><link>https://blog.ezyang.com/2014/01/ott-iff-plt-redex/</link><pubDate>Mon, 13 Jan 2014 19:11:39 +0000</pubDate><guid>https://blog.ezyang.com/2014/01/ott-iff-plt-redex/</guid><description>&lt;p>&lt;a href="http://www.cl.cam.ac.uk/~pes20/ott/">Ott&lt;/a> and &lt;a href="http://redex.racket-lang.org/">PLT Redex&lt;/a> are a pair of complimentary tools for the working semanticist. Ott is a tool for writing definitions of programming languages in a nice ASCII notation, which then can be typeset in LaTeX or used to generate definitions for a theorem prover (e.g. Coq). PLT Redex is a tool for specifying and debugging operational semantics. Both tools are easy to install, which is a big plus. Since the tools are quite similar, I thought it might be interesting to do a comparison of how various common tasks are done in both languages. (Also, I think the Redex manual is pretty terrible.)&lt;/p></description></item><item><title>When a lock is better than an MVar</title><link>https://blog.ezyang.com/2014/01/when-a-lock-is-better-than-an-mvar/</link><pubDate>Tue, 07 Jan 2014 18:47:26 +0000</pubDate><guid>https://blog.ezyang.com/2014/01/when-a-lock-is-better-than-an-mvar/</guid><description>&lt;p>MVars are an amazingly flexible synchronization primitive, which can serve as locks, one-place channels, barriers, etc. or be used to form higher-level abstractions. As far as flexibility is concerned, MVars are the superior choice of primitive for the runtime system to implement—as opposed to just implementing, say, a lock.&lt;/p>
&lt;p>However, I was recently thinking about &lt;a href="http://blog.ezyang.com/2011/07/blockedindefinitelyonmvar/">GHC&amp;rsquo;s BlockedIndefinitelyOnMVar exception&lt;/a>, and it occurred to me that a native implementation of locks could allow &lt;em>perfect&lt;/em> deadlock detection, as opposed to the approximate detection for MVars we currently provide. (I must emphasize, however, that here, I define deadlock to mean a circular waits-for graph, and not “thread cannot progress further.”)&lt;/p></description></item><item><title>So you want to add a new concurrency primitive to GHC...</title><link>https://blog.ezyang.com/2014/01/so-you-want-to-add-a-new-concurrency-primitive-to-ghc/</link><pubDate>Wed, 01 Jan 2014 10:37:00 +0000</pubDate><guid>https://blog.ezyang.com/2014/01/so-you-want-to-add-a-new-concurrency-primitive-to-ghc/</guid><description>&lt;p>One of the appealing things about GHC is that the compiler is surprisingly hackable, even when you don’t want to patch the compiler itself. This hackability comes from &lt;a href="http://www.haskell.org/ghc/docs/latest/html/users_guide/compiler-plugins.html">compiler plugins&lt;/a>, which let you write custom optimization passes on Core, as well as &lt;a href="https://ghc.haskell.org/trac/ghc/wiki/Commentary/PrimOps#Foreignout-of-linePrimOpsandforeignimportprim">foreign primops&lt;/a>, which let you embed low-level C&amp;ndash; to manipulate the low-level representation of various primitives. These hooks let people implement and distribute features that would otherwise be to unstable or speculative to put into the compiler proper.&lt;/p></description></item><item><title>Two bugs in the borrow checker every Rust developer should know about</title><link>https://blog.ezyang.com/2013/12/two-bugs-in-the-borrow-checker-every-rust-developer-should-know-about/</link><pubDate>Tue, 17 Dec 2013 07:57:31 +0000</pubDate><guid>https://blog.ezyang.com/2013/12/two-bugs-in-the-borrow-checker-every-rust-developer-should-know-about/</guid><description>&lt;p>&lt;em>Apologies in advance: this post assumes familiarity with&lt;/em> &lt;a href="http://www.rust-lang.org/">Rust&lt;/a>.&lt;/p>
&lt;p>Anyone who has done some coding in Rust may be familiar with the dreaded &lt;em>borrow checker&lt;/em>, famous for obstructing the compilation of otherwise “perfectly reasonable code.” In many cases, the borrow checker is right: you’re writing your code wrong, and there is another, clearer way to write your code that will appease the borow checker. But sometimes, even after you’ve skimmed the &lt;a href="http://static.rust-lang.org/doc/master/tutorial.html">tutorial&lt;/a>, memorized the mantra &lt;a href="http://smallcultfollowing.com/babysteps/blog/2012/11/18/imagine-never-hearing-the-phrase-aliasable/">“a &amp;amp;mut pointer is the only way to mutate the thing that it points at”&lt;/a> and re-read the &lt;a href="http://static.rust-lang.org/doc/master/tutorial-borrowed-ptr.html">borrowed pointers tutorial&lt;/a>, the borrow-checker might still stubbornly refuse to accept your code.&lt;/p></description></item><item><title>Visualizing a block allocator</title><link>https://blog.ezyang.com/2013/10/visualizing-a-block-allocator/</link><pubDate>Wed, 30 Oct 2013 21:48:02 +0000</pubDate><guid>https://blog.ezyang.com/2013/10/visualizing-a-block-allocator/</guid><description>&lt;p>GHC’s &lt;a href="http://ghc.haskell.org/trac/ghc/wiki/Commentary/Rts/Storage/BlockAlloc">block allocator&lt;/a> is a pretty nifty piece of low-level infrastructure. It offers a much more flexible way of managing a heap, rather than trying to jam it all in one contiguous block of memory, and is probably something that should be of general interest to anyone who is implementing low-level code like a runtime. The core idea behind it is quite old (BIBOP: Big Bag of Pages), and is useful for any situation where you have a number of objects that are tagged with the same descriptor, and you don’t want to pay the cost of the tag on each object.&lt;/p></description></item><item><title>Xmonad and media keys on Saucy</title><link>https://blog.ezyang.com/2013/10/xmonad-and-media-keys-on-saucy/</link><pubDate>Sun, 27 Oct 2013 16:30:39 +0000</pubDate><guid>https://blog.ezyang.com/2013/10/xmonad-and-media-keys-on-saucy/</guid><description>&lt;p>Ubuntu continues on its rampage of breaking perfectly good software, and on my most recent upgrade to Saucy Salamander, I discovered to my dismay that my media keys (e.g. volume keys, fn (function) keys, suspend button, etc) had stopped working. Of course, it worked fine if I logged into my user using Unity, but who wants to use a silly window manager like that&amp;hellip;&lt;/p>
&lt;p>The root problem, according to &lt;a href="https://bbs.archlinux.org/viewtopic.php?pid=1262471">these Arch Linux forum posts&lt;/a> is that Gnome has moved media-key support out of &lt;code>gnome-settings-daemon&lt;/code> (which any self-respecting Xmonad user is sure to spawn) and into their window manager proper. Which, of course, is no good because I don’t want to use their window manager!&lt;/p></description></item><item><title>If you're using lift, you're doing it wrong (probably)</title><link>https://blog.ezyang.com/2013/09/if-youre-using-lift-youre-doing-it-wrong-probably/</link><pubDate>Thu, 26 Sep 2013 15:03:42 +0000</pubDate><guid>https://blog.ezyang.com/2013/09/if-youre-using-lift-youre-doing-it-wrong-probably/</guid><description>&lt;p>David Darais asked me to make this public service announcement: &lt;em>If you&amp;rsquo;re using lift, you&amp;rsquo;re doing it wrong.&lt;/em> This request was prompted by several talks at ICFP about alternatives to monad transformers in Haskell, which all began their talk with the motivation, &amp;ldquo;Everyone hates lifting their operations up the monad stack; therefore, we need another way of organizing effects.&amp;rdquo; This &lt;a href="http://stackoverflow.com/questions/9054731/avoiding-lift-with-monad-transformers">StackOverflow question&lt;/a> describes the standard technique that &lt;code>mtl&lt;/code> uses to remove the use of lift in most monadic code.&lt;/p></description></item><item><title>Of Monadic Fixpoints and Heap Offsets</title><link>https://blog.ezyang.com/2013/09/of-monadic-fixpoints-and-heap-offsets/</link><pubDate>Tue, 24 Sep 2013 22:20:57 +0000</pubDate><guid>https://blog.ezyang.com/2013/09/of-monadic-fixpoints-and-heap-offsets/</guid><description>&lt;p>Here at ICFP, sometimes the so-called “hallway track” is sometimes just as important as the ordinary track. Johan Tibell was wanting to avoid an out-of-line call to &lt;code>allocate&lt;/code> function in GHC when a small array of statically known size was allocated. But he found the way that GHC&amp;rsquo;s new code generator handles heap allocation a bit confusing, and so we skipped out of one session today to work it out. In this post, I would like to explain how the code generation monad figures out what the heap offsets in the code are, by way of a kind of cute (and also slightly annoying) trick involving a “monadic” fixpoint.&lt;/p></description></item><item><title>Induction and logical relations</title><link>https://blog.ezyang.com/2013/09/induction-and-logical-relations/</link><pubDate>Wed, 18 Sep 2013 19:35:37 +0000</pubDate><guid>https://blog.ezyang.com/2013/09/induction-and-logical-relations/</guid><description>&lt;p>Logical relations are a proof technique which allow you to prove things such as normalization (&lt;em>all programs terminate&lt;/em>) and program equivalence (&lt;em>these two programs are observationally equivalent under all program contexts&lt;/em>). If you haven&amp;rsquo;t ever encountered these before, I highly recommend &lt;a href="http://www.cs.uoregon.edu/research/summerschool/summer13/curriculum.html">Amal Ahmed&amp;rsquo;s OPLSS lectures&lt;/a> on the subject; you can find videos and notes from yours truly. (You should also be able to access her lectures from previous years.) This post is an excuse to talk about &lt;a href="https://github.com/ezyang/lr-agda/blob/master/STLC-CBV.agda">a formalization of two logical relations proofs in Agda&lt;/a> I worked on during OPLSS and the weeks afterwards. I&amp;rsquo;m not going to walk through the code, but I do want expand on two points about logical relations:&lt;/p></description></item><item><title>Cost semantics for STG in modern GHC</title><link>https://blog.ezyang.com/2013/09/cost-semantics-for-stg-in-modern-ghc/</link><pubDate>Sat, 07 Sep 2013 16:54:51 +0000</pubDate><guid>https://blog.ezyang.com/2013/09/cost-semantics-for-stg-in-modern-ghc/</guid><description>&lt;p>One of the problems with academic publishing is that it’s hard to keep old papers up-to-date. This is the certainly case for this &lt;a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.43.6277">1995 Sansom paper on profiling non-strict, higher-order functional languages&lt;/a>. While the basic ideas of the paper still hold, the actual implementation of cost centers in GHC has changed quite a bit, perhaps the most dramatic change being the introduction of cost center stacks. So while the old paper is good for giving you the basic idea of how profiling in GHC works, if you really want to know the details, the paper offers little guidance.&lt;/p></description></item><item><title>Blame Trees</title><link>https://blog.ezyang.com/2013/08/blame-trees/</link><pubDate>Mon, 12 Aug 2013 14:55:28 +0000</pubDate><guid>https://blog.ezyang.com/2013/08/blame-trees/</guid><description>&lt;p>I just presented &lt;em>Blame Trees&lt;/em> at the &lt;a href="http://www.wads.org/">13th Algorithms and Data Structures Symposium&lt;/a>. Blame trees are a functional data structure which support an efficient merge operation by incorporating information about the “blame” (think &lt;code>git blame&lt;/code>) of any given part of the structure. It’s a theory paper, so the constant factors are not so good, but the asymptotics are much better than traditional merge algorithms used by modern VCSes.&lt;/p>
&lt;p>This was joint work with &lt;a href="http://web.mit.edu/dwilson/www/">David A. Wilson&lt;/a>, &lt;a href="http://pavpanchekha.com/">Pavel Panchekha&lt;/a> and &lt;a href="http://erikdemaine.org/">Erik D. Demaine&lt;/a>. You can view the &lt;a href="http://ezyang.com/papers/demaine13-blametrees.pdf">paper&lt;/a> or check out the &lt;a href="http://ezyang.com/slides/ezyang13-blametrees-slides.pdf">slides.&lt;/a> I also have a slightly older version of the talk recorded on &lt;a href="http://youtu.be/f8e-QE6Gus8">YouTube (20 minutes)&lt;/a> which I had used to help get feedback from my out-of-town collaborators before actually giving the talk. Thanks also to David Mazières for giving useful comments on the presentation in person.&lt;/p></description></item><item><title>OPLSS lecture notes</title><link>https://blog.ezyang.com/2013/07/oplss-lecture-notes/</link><pubDate>Mon, 29 Jul 2013 00:02:10 +0000</pubDate><guid>https://blog.ezyang.com/2013/07/oplss-lecture-notes/</guid><description>&lt;p>I write in from sunny Oregon, where the sun floods into your room at seven in the morning and the &lt;a href="http://www.cs.uoregon.edu/research/summerschool/summer13/index.html">Oregon Programming Languages Summer School&lt;/a> is in session. So far, it’s been a blast—with lectures covering Coq, Agda, homotopy type theory, linear logic, logical relations—and we’ve still got another week to go!&lt;/p>
&lt;p>If you were not able to make it, fear not: you can go to the &lt;a href="http://www.cs.uoregon.edu/research/summerschool/summer13/curriculum.html">curriculum&lt;/a> page and pick up not only videos (I hear they are still quite large; we’ve been trying to convince the organizers to upload them to YouTube) but &lt;strong>lecture notes&lt;/strong> from yours truly. (&lt;a href="http://www.cs.uoregon.edu/research/summerschool/summer13/lectures/ahmed-1.pdf">Sample from the logical relations lectures&lt;/a>.) The earlier notes are a little iffy, but I get a bit more detailed on the later ones.&lt;/p></description></item><item><title>No grammar? No problem!</title><link>https://blog.ezyang.com/2013/07/no-grammar-no-problem/</link><pubDate>Tue, 02 Jul 2013 22:17:02 +0000</pubDate><guid>https://blog.ezyang.com/2013/07/no-grammar-no-problem/</guid><description>&lt;p>One day, you’re strolling along fields of code, when suddenly you spot a syntax construct that you don’t understand.&lt;/p>
&lt;p>Perhaps you’d ask your desk-mate, who’d tell you in an instant what it was.&lt;/p>
&lt;p>Perhaps your programming toolchain can tell you. (Perhaps the IDE would you mouse over the construct, or you’re using Coq which let’s you &lt;code>Locate&lt;/code> custom notations.)&lt;/p>
&lt;p>Perhaps you’d pull up the manual (or, more likely, one of many tutorials) and scan through looking for the syntax construct in question.&lt;/p></description></item><item><title>HoTT exercises in Coq (in progress)</title><link>https://blog.ezyang.com/2013/07/hott-exercises-in-coq-in-progress/</link><pubDate>Mon, 01 Jul 2013 16:21:18 +0000</pubDate><guid>https://blog.ezyang.com/2013/07/hott-exercises-in-coq-in-progress/</guid><description>&lt;p>I spent some of my plane ride yesterday working on Coq versions of the exercises in &lt;a href="http://homotopytypetheory.org/book/">The HoTT book&lt;/a>. I got as far as 1.6 (yeah, not very far, perhaps I should make a GitHub repo if other folks are interested in contributing skeletons. Don&amp;rsquo;t know what to do about the solutions though). All of these have been test solved.&lt;/p>
&lt;p>You will need HoTT/coq in order to run this development; instructions on &lt;a href="https://github.com/HoTT/HoTT/blob/master/INSTALL.txt">how to install it are here.&lt;/a>&lt;/p></description></item><item><title>(Homotopy) Type Theory: Chapter One</title><link>https://blog.ezyang.com/2013/06/homotopy-type-theory-chapter-one/</link><pubDate>Mon, 24 Jun 2013 18:56:27 +0000</pubDate><guid>https://blog.ezyang.com/2013/06/homotopy-type-theory-chapter-one/</guid><description>&lt;p>In what is old news by now, the folks at the Institute for Advanced Study have released &lt;a href="http://homotopytypetheory.org/book/">Homotopy Type Theory: Univalent Foundations of Mathematics&lt;/a>. There has been some (meta)commentary (&lt;a href="https://plus.google.com/107913314994758123748/posts/VzWAsojiifE">Dan Piponi&lt;/a>, &lt;a href="http://existentialtype.wordpress.com/2013/06/22/whats-the-big-deal-with-hott/">Bob Harper&lt;/a>, &lt;a href="http://math.andrej.com/2013/06/20/the-hott-book/">Andrej Bauer&lt;/a>, &lt;a href="http://dorais.org/archives/1425">François G. Dorais&lt;/a>, &lt;a href="http://homotopytypetheory.org/2013/06/20/the-hott-book/">Steve Awodey&lt;/a>, &lt;a href="http://www.carloangiuli.com/blog/homotopy-type-theory-univalent-foundations-of-mathematics/">Carlo Angiuli&lt;/a>, &lt;a href="http://golem.ph.utexas.edu/category/2013/06/the_hott_book.html">Mike Shulman&lt;/a>, &lt;a href="https://plus.google.com/117663015413546257905/posts/cm1sKge8qxX">John Baez&lt;/a>) on the Internet, though, of course, it takes time to read a math textbook, so don’t expect detailed technical commentary from non-authors for a while.&lt;/p>
&lt;p>Of course, being a puny grad student, I was, of course, most interested in the book’s contribution of &lt;em>yet another Martin-Löf intuitionistic type theory introduction&lt;/em>, e.g. chapter one. The classic introduction is, of course, the papers that Martin Löf wrote (nota bene: there were many iterations of this paper, so it’s a little hard to find the right one, though it seems Giovanni Sambin’s notes are the easiest to find), but an introduction of type theory for &lt;em>homotopy type theory&lt;/em> has to make certain adjustments, and this makes for some novel presentation. In particular, the chapter’s discussion of &lt;em>identity types&lt;/em> is considerably more detailed than I have seen elsewhere (this is not surprising, since identity is of central importance to homotopy type theory). There is also a considerable bit of pedantry/structure in the discussion of the types that make up the theory, reminiscent of the &lt;a href="http://existentialtype.wordpress.com/2012/12/03/pfpl-is-out/">PFPL&lt;/a> (though I believe that this particular chapter was mostly written by others). And, of course, there are many little variations in how the theory is actually put together, expounded upon in some detail in the chapter notes.&lt;/p></description></item><item><title>The AST Typing Problem</title><link>https://blog.ezyang.com/2013/05/the-ast-typing-problem/</link><pubDate>Tue, 28 May 2013 07:25:03 +0000</pubDate><guid>https://blog.ezyang.com/2013/05/the-ast-typing-problem/</guid><description>&lt;p>This &lt;a href="http://lambda-the-ultimate.org/node/4170">Lambda the Ultimate post (dated 2010)&lt;/a> describes a rather universal problem faced by compiler writers: how does one go about adding “extra information” (e.g. types) to an AST? (The post itself divides the problem into three components: adding the information to the data types, using the information to inform the construction of the node, and using the information to inform the destruction of a node—but I’m really only interested in the question of how you define your data type, not do things to it.) In this post, I want to sum up ways of solving the problem which were described in this post, and also take a look at what some real world compilers do. The running example lambda calculus looks like the following:&lt;/p></description></item><item><title>Anatomy of an MVar operation</title><link>https://blog.ezyang.com/2013/05/anatomy-of-an-mvar-operation/</link><pubDate>Sun, 19 May 2013 20:00:37 +0000</pubDate><guid>https://blog.ezyang.com/2013/05/anatomy-of-an-mvar-operation/</guid><description>&lt;p>Adam Belay (of &lt;a href="http://dune.scs.stanford.edu/">Dune&lt;/a> fame) was recently wondering why Haskell’s MVars are so slow. “Slow?” I thought, “aren’t Haskell’s MVars supposed to be really fast?” So I did some digging around how MVars worked, to see if I could explain.&lt;/p>
&lt;p>Let’s consider the operation of the function &lt;code>takeMVar&lt;/code> in &lt;a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Concurrent-MVar.html#v:takeMVar">Control.Concurrent.MVar&lt;/a>. This function is very simple, it unpacks &lt;code>MVar&lt;/code> to get the underlying &lt;code>MVar#&lt;/code> primitive value, and then calls the primop &lt;code>takeMVar#&lt;/code>:&lt;/p>
&lt;pre>&lt;code>takeMVar :: MVar a -&amp;gt; IO a
takeMVar (MVar mvar#) = IO $ \ s# -&amp;gt; takeMVar# mvar# s#
&lt;/code>&lt;/pre>
&lt;p>&lt;a href="http://hackage.haskell.org/trac/ghc/wiki/Commentary/PrimOps">Primops&lt;/a> result in the invocation of &lt;code>stg_takeMVarzh&lt;/code> in &lt;code>PrimOps.cmm&lt;/code>, which is where the magic happens. For simplicity, we consider only the &lt;em>multithreaded&lt;/em> case.&lt;/p></description></item><item><title>HotOS "Unconference" report:&lt;br />Verifying Systems</title><link>https://blog.ezyang.com/2013/05/hotos-unconference-reportverifying-systems/</link><pubDate>Tue, 14 May 2013 00:58:40 +0000</pubDate><guid>https://blog.ezyang.com/2013/05/hotos-unconference-reportverifying-systems/</guid><description>&lt;p>&lt;a href="http://www.eecs.berkeley.edu/~asrabkin/">Ariel Rabkin&lt;/a> has some code he&amp;rsquo;d like to verify, and at this year’s HotOS he appealed to participants of one “unconference” (informal breakout sessions to discuss various topics) to help him figure out what was really going on as far as formal verification went.&lt;/p>
&lt;p>He had three questions: &amp;ldquo;What can we verify? What is impossible to verify? How can we tell that the verification is correct?&amp;rdquo; They seemed like impossibly large questions, so we drilled in a little bit, and found that Ariel had the very understandable question, &amp;ldquo;Say I have some C++ code implementing a subtle network protocol, and I&amp;rsquo;d like to prove that the protocol doesn&amp;rsquo;t deadlock; how do I do that?&amp;rdquo;&lt;/p></description></item><item><title>Category theory for loop optimizations</title><link>https://blog.ezyang.com/2013/05/category-theory-for-loop-optimizations/</link><pubDate>Sun, 12 May 2013 00:25:40 +0000</pubDate><guid>https://blog.ezyang.com/2013/05/category-theory-for-loop-optimizations/</guid><description>&lt;p>Christopher de Sa and I have been working on a category theoretic approach to optimizing MapReduce-like pipelines. Actually, we didn’t start with any category theory—we were originally trying to impose some structure on some of the existing loop optimizations that the &lt;a href="http://stanford-ppl.github.io/Delite/">Delite compiler&lt;/a> performed, and along the way, we rediscovered the rich relationship between category theory and loop optimization.&lt;/p>
&lt;p>On the one hand, I think the approach is pretty cool; but on the other hand, there’s a lot of prior work in the area, and it’s tough to figure out where one stands on the research landscape. As John Mitchell remarked to me when I was discussing the idea with him, “Loop optimization, can’t you just solve it using a table lookup?” We draw a lot of inspiration from existing work, especially the &lt;em>program calculation&lt;/em> literature pioneered by Bird, Meertens, Malcom, Meijer and others in the early 90s. The purpose of this blog post is to air out some of the ideas we’ve worked out and get some feedback from you, gentle reader.&lt;/p></description></item><item><title>The Difference between Recursion &amp; Induction</title><link>https://blog.ezyang.com/2013/04/the-difference-between-recursion-induction/</link><pubDate>Sat, 27 Apr 2013 03:30:17 +0000</pubDate><guid>https://blog.ezyang.com/2013/04/the-difference-between-recursion-induction/</guid><description>&lt;p>Recursion and induction are closely related. When you were first taught recursion in an introductory computer science class, you were probably told to use induction to prove that your recursive algorithm was correct. (For the purposes of this post, let us exclude hairy recursive functions like the one in the &lt;a href="http://en.wikipedia.org/wiki/Collatz_conjecture">Collatz conjecture&lt;/a> which do not obviously terminate.) Induction suspiciously resembles recursion: the similarity comes from the fact that the inductive hypothesis looks a bit like the result of a “recursive call” to the theorem you are proving. If an ordinary recursive computation returns plain old values, you might wonder if an “induction computation” returns proof terms (which, by the Curry-Howard correspondence, could be thought of as a value).&lt;/p></description></item><item><title>Kindle is not good for textbooks</title><link>https://blog.ezyang.com/2013/04/kindle-is-not-good-for-textbooks/</link><pubDate>Mon, 15 Apr 2013 19:52:20 +0000</pubDate><guid>https://blog.ezyang.com/2013/04/kindle-is-not-good-for-textbooks/</guid><description>&lt;p>Having attempted to read a few textbooks on my Kindle, I have solemnly concluded that the Kindle is in fact a terrible device for reading textbooks. The fundamental problem is that, due to technological limitations, the Kindle is optimized for &lt;em>sequential&lt;/em> reading. This can be seen in many aspects:&lt;/p>
&lt;ul>
&lt;li>Flipping a page in the Kindle is not instantaneous (I don&amp;rsquo;t have a good setup to time how long the screen refresh takes, but there is definitely a perceptible lag before when you swipe, and when the Kindle successfully redraws the screen—and it’s even worse if you try to flip backwards).&lt;/li>
&lt;li>Rapidly flipping through pages in order to scan for a visual feature compounds the delay problem.&lt;/li>
&lt;li>There is no way to take the “finger” approach to random access (i.e. wedge your finger between two pages to rapidly switch between them); jumping between bookmarks requires &lt;em>four&lt;/em> presses with the current Kindle interface!&lt;/li>
&lt;li>The screen size of the Kindle is dramatically smaller than that of an average textbook, which reduces the amount of information content that can be placed on one screen and further exacerbates slow page turns.&lt;/li>
&lt;/ul>
&lt;p>A textbook cannot be read as a light novel. So, while the Kindle offers the tantalizing possibility of carrying a stack of textbooks with you everywhere, in fact, you’re better off getting the actual dead tree version if you’re planning on doing some serious studying from it. That is not to say textbook ebooks are not useful; in fact, having a searchable textbook on your laptop is seriously awesome—but this is when you’re using the textbook as a reference material, and &lt;em>not&lt;/em> when you’re trying to actually learn the material.&lt;/p></description></item><item><title>A Zerocoin puzzle</title><link>https://blog.ezyang.com/2013/04/a-zerocoin-puzzle/</link><pubDate>Thu, 11 Apr 2013 18:54:02 +0000</pubDate><guid>https://blog.ezyang.com/2013/04/a-zerocoin-puzzle/</guid><description>&lt;p>I very rarely post linkspam, but given that I’ve written on the subject of &lt;a href="http://blog.ezyang.com/2012/07/secure-multiparty-bitcoin-anonymization/">anonymizing Bitcoins&lt;/a> in the past, this link seems relevant: &lt;a href="http://blog.cryptographyengineering.com/2013/04/zerocoin-making-bitcoin-anonymous.html">Zerocoin: making Bitcoin anonymous&lt;/a>. Their essential innovation is to have a &lt;em>continuously operating&lt;/em> mixing pool built into the block chain itself; they pull this off using zero-knowledge proofs. Nifty!&lt;/p>
&lt;p>Here is a puzzle for the readers of this blog. Suppose that I am a user who wants to anonymize some Bitcoins, and I am willing to wait expected time &lt;em>N&lt;/em> before redeeming my Zerocoins. What is the correct probability distribution for me to pick my wait time from? Furthermore, suppose a population of Zerocoin participants, all of which are using this probability distribution. Furthermore, suppose that each participant has some utility function trading off anonymity and expected wait time (feel free to make assumptions that make the analysis easy). Is this population in Nash equilibrium?&lt;/p></description></item><item><title>A classical logic fairy tale</title><link>https://blog.ezyang.com/2013/04/a-classical-logic-fairy-tale/</link><pubDate>Sun, 07 Apr 2013 17:52:08 +0000</pubDate><guid>https://blog.ezyang.com/2013/04/a-classical-logic-fairy-tale/</guid><description>&lt;blockquote>
&lt;p>(Selinger) Here is a fairy tale: The evil king calls the poor shepherd and gives him these orders. “You must bring me the philosophers stone, or you have to find a way to turn the philosopher’s stone to gold. If you don’t, your head will be taken off tomorrow!” What can the poor shepherd do to save his life?&lt;/p>&lt;/blockquote>
&lt;p>Hat tip to &lt;a href="http://www.cs.cmu.edu/~cmartens/">Chris&lt;/a> for originally telling me a different variant of this story. Unfortunately, this quote from &lt;em>Lectures on the Curry-Howard Isomorphism&lt;/em> was the only reference I could find. What should the shepherd do? Is there something a little odd about this story?&lt;/p></description></item><item><title>NDSEG</title><link>https://blog.ezyang.com/2013/04/ndseg/</link><pubDate>Fri, 05 Apr 2013 22:40:31 +0000</pubDate><guid>https://blog.ezyang.com/2013/04/ndseg/</guid><description>&lt;p>Humbly presented for your consideration: &lt;a href="http://web.mit.edu/~ezyang/Public/ndseg-goals.pdf">Exhibit A&lt;/a>, an NDSEG essay that did not get accepted; &lt;a href="http://web.mit.edu/~ezyang/Public/ndseg2012-4.pdf">Exhibit B&lt;/a>, an NDSEG essay that did get accepted. It’s pretty cool what making a statement more focused can do. (See also &lt;a href="http://www.pgbovine.net/fellowship-tips.htm">Philip Guo’s page on the topic.&lt;/a>)&lt;/p></description></item><item><title>Resource limits for Haskell</title><link>https://blog.ezyang.com/2013/04/resource-limits-for-haskell/</link><pubDate>Tue, 02 Apr 2013 16:36:40 +0000</pubDate><guid>https://blog.ezyang.com/2013/04/resource-limits-for-haskell/</guid><description>&lt;p>Last week, I made my very first submission to ICFP! The topic? An old flame of mine: how to bound space usage of Haskell programs.&lt;/p>
&lt;blockquote>
&lt;p>We describe the first iteration of a resource limits system for Haskell, taking advantage of the key observation that resource limits share semantics and implementation strategy with profiling. We pay special attention to the problem of limiting resident memory usage: we describe a simple implementation technique for carrying out incremental heap censuses and describe a novel information-flow control solution for handling forcible resource reclamation. This system is implemented as a set of patches to GHC.&lt;/p></description></item><item><title>The single export pattern</title><link>https://blog.ezyang.com/2013/03/the-single-export-pattern/</link><pubDate>Sun, 31 Mar 2013 20:39:41 +0000</pubDate><guid>https://blog.ezyang.com/2013/03/the-single-export-pattern/</guid><description>&lt;div class="container center">
&lt;p>&lt;em>From the files of the ECMAScript TC39 proceedings&lt;/em>&lt;/p>
&lt;/div>
&lt;p>&lt;strong>Single export&lt;/strong> refers to a design pattern where a module identifier is overloaded to also represent a function or type inside the module. As far as I can tell, the term “single export” is not particularly widely used outside the ECMAScript TC39 committee; however, the idea shows up in other contexts, so I’m hoping to popularize this particular name (since names are powerful).&lt;/p></description></item><item><title>The duality of weak maps and private symbols</title><link>https://blog.ezyang.com/2013/03/duality-of-weak-maps-and-private-symbols/</link><pubDate>Tue, 19 Mar 2013 00:12:16 +0000</pubDate><guid>https://blog.ezyang.com/2013/03/duality-of-weak-maps-and-private-symbols/</guid><description>&lt;div class="container center">
&lt;p>&lt;em>From the files of the ECMAScript TC39 proceedings&lt;/em>&lt;/p>
&lt;/div>
&lt;p>I want to talk about an interesting duality pointed out by Mark Miller between two otherwise different language features: weak maps and private symbols. Modulo implementation differences, they are the same thing!&lt;/p>
&lt;p>A &lt;a href="http://wiki.ecmascript.org/doku.php?id=harmony:weak_maps">weak map&lt;/a> is an ordinary associative map, with the twist that if the key for any entry becomes unreachable, then the value becomes unreachable too (though you must remember to ignore references to the key from the value itself!) Weak maps have a variety of use-cases, including memoization, where we’d like to remember results of a computation, but only if it will ever get asked for again! A weak map supports &lt;code>get(key)&lt;/code> and &lt;code>set(key, value)&lt;/code> operations.&lt;/p></description></item><item><title>What is a membrane?</title><link>https://blog.ezyang.com/2013/03/what-is-a-membran/</link><pubDate>Fri, 15 Mar 2013 03:49:08 +0000</pubDate><guid>https://blog.ezyang.com/2013/03/what-is-a-membran/</guid><description>&lt;p>If you hang out long enough with a certain crowd (in my case, it was the &lt;a href="http://wiki.ecmascript.org/doku.php">ECMAScript TC39 committee&lt;/a>), you will probably hear the term &lt;strong>membrane&lt;/strong> tossed around. And eventually, you will start to wonder, “Well, what &lt;em>is&lt;/em> a membrane, anyway?”&lt;/p>
&lt;p>As is the case with many clever but simple ideas, membranes were first introduced as a footnote [1] in &lt;a href="http://www.erights.org/talks/thesis/">a PhD thesis.&lt;/a> Suppose that you are building distributed system, in which you pass references to objects between two separate nodes. If I want to pass a reference to &lt;code>foo&lt;/code> in process &lt;code>A&lt;/code> to process &lt;code>B&lt;/code>, I can hardly just hand over an address—the memory spaces are not the same! So instead, I need to create a wrapper object &lt;code>wrappedFoo&lt;/code> representing &lt;code>foo&lt;/code> in &lt;code>B&lt;/code>, which knows how to access the original object in &lt;code>A&lt;/code>. So far so good.&lt;/p></description></item><item><title>Kindle Paperwhite notes</title><link>https://blog.ezyang.com/2013/01/kindle-paperwhite-notes/</link><pubDate>Wed, 30 Jan 2013 09:00:17 +0000</pubDate><guid>https://blog.ezyang.com/2013/01/kindle-paperwhite-notes/</guid><description>&lt;p>Along with a &lt;a href="http://blog.ezyang.com/2012/12/googl-nexus-7-setup-notes/">Nexus 7&lt;/a>, I also acquired a &lt;a href="http://www.amazon.com/Kindle-Paperwhite-Touch-light/dp/B007OZNZG0">Kindle Paperwhite&lt;/a> over winter break. (Wi-Fi only) I have been quite pleased by this purchase, though in an unexpected way: while I have not increased the number of books I read, the Kindle has materially changed how I read &lt;em>articles on the Internet.&lt;/em> Not via their web browser, which is essentially unusable except for the simplest tasks, but via tools which take articles on the Internet and convert them into ebook form.&lt;/p></description></item><item><title>The GHC scheduler</title><link>https://blog.ezyang.com/2013/01/the-ghc-scheduler/</link><pubDate>Mon, 28 Jan 2013 03:00:48 +0000</pubDate><guid>https://blog.ezyang.com/2013/01/the-ghc-scheduler/</guid><description>&lt;p>I’d like to talk about some nitty-gritty details of GHC’s thread scheduling, discovered over the course of working on stride scheduling for GHC. Most of these choices are merely &lt;em>implementation&lt;/em> details and are not part of any specification. While these choices shouldn’t be relied upon, they are worth knowing, since many of these details were accreted over the course of many performance bugs, benchmark tests and other battles. In this post, I’ll attempt to give some historical insight into why many choices were made. These insights should generalize to any system that would like to implement &lt;em>green threads&lt;/em>, lightweight threads that use less memory than traditional operating system threads. For space reasons, I’m not going to talk about STM or sparks (though they are also quite interesting).&lt;/p></description></item><item><title>NLP: the missing framework</title><link>https://blog.ezyang.com/2013/01/nlp-the-missing-framework/</link><pubDate>Wed, 02 Jan 2013 00:00:30 +0000</pubDate><guid>https://blog.ezyang.com/2013/01/nlp-the-missing-framework/</guid><description>&lt;p>So you want to make a web app. In today’s world, there is a panoply of software to assist you: you can use an all-in-one framework, or you can grab libraries to deal with the common needs of templating, database access, interactivity, etc. These libraries unify common functionality and take care of edge-cases you might otherwise not have the resources to deal with.&lt;/p>
&lt;p>But there is one tool which is conspicuously absent: the &lt;em>natural language processing&lt;/em> library.&lt;/p></description></item><item><title>Google Nexus 7 setup notes</title><link>https://blog.ezyang.com/2012/12/googl-nexus-7-setup-notes/</link><pubDate>Mon, 31 Dec 2012 21:19:30 +0000</pubDate><guid>https://blog.ezyang.com/2012/12/googl-nexus-7-setup-notes/</guid><description>&lt;p>I acquired a Google Nexus 7 (Wi-Fi only) over winter break. I don’t really like getting new devices: they invariably require a lot of work to setup to my liking. Here are some notes:&lt;/p>
&lt;ul>
&lt;li>Jailbreaking the device from Linux is still fiddly. Ultimately, it’s probably easiest to just find a Windows box and use the &lt;a href="http://www.wugfresh.com/nrt/">Nexus Root Toolkit&lt;/a>. The tool is somewhat racy; try the detection code again if it fails the first time.&lt;/li>
&lt;li>Transferring files to/from Linux is a pain in the ass. I have SCP over SSHDroid working; I also tried both DropBear SSH Servers but they did not come with scp binaries and were thus fairly useless for the purpose of file transfer. SSHDroid didn’t work out of the box: I needed to apply &lt;a href="http://code.google.com/p/droidsshd/issues/detail?id=2#c14">comment 14&lt;/a> to make the real scp binaries get picked up in the path. By default, these apps are configured to accept password-authentication (not even keyboard-interactive!) with extremely weak default passwords: make sure you disable that. Still looking for a good rsync implementation. On the USB side, Ubuntu/Gnome/Nautilus natively recognised Nexus in PTP mode but when I tried copying files it hung. MTP is fairly unsupported by Ubuntu 12.10, but go-mtpfs works decently well given a sufficiently modern libmtp. Adam Glasgall has &lt;a href="https://launchpad.net/~aglasgall/+archive/libmtp">packaged libmtp for Quantal&lt;/a>, so go add his PPA, and then &lt;a href="https://github.com/hanwen/go-mtpfs">follow the installation instructions of go-mtpfs&lt;/a>. &lt;strong>Update:&lt;/strong> Transferring files directly to removable media has also worked reasonably well.&lt;/li>
&lt;li>The tablet really does feel like a phone, courtesy of both being on the Android platform. But no 3G means offline is a lot more important, and the larger screen makes certain types of applications a lot more pleasant to use (&lt;strong>Update:&lt;/strong> I’ve settled on MX Player as my video player of choice, since it supports Advanced SubStation Alpha subtitling and MKV files. Unfortunately, it doesn&amp;rsquo;t support deep color (e.g. 10-bit).)&lt;/li>
&lt;li>Micro USB to USB OTG cable is really handy, esp. for hooking up keyboards or external media. I’d dare say, it’s a more essential accessory than a cover. Note that the micro-USB port isn’t able to power USB devices with high power requirements (e.g. spinning platter external disks), so you’ll need a powered USB hub to connect them. (One symptom of this is if you try to mount an under-powered hard drive, the directory listing will persistently come up empty. It may also may make clicking noises: probably not good for the drive.) I use USB-OTG to perform mounting.&lt;/li>
&lt;li>I tried to get my paper database on Mendeley mirrored onto my tablet, but it&amp;rsquo;s been pretty tough. I’ve been trying to use Referey, which is a Mendeley-client for Android, but it requires me to somehow propagate my Mendeley SQLite database and all of my PDFs. Dropbox seems like a good match here, except that the official Dropbox client doesn&amp;rsquo;t support keeping entire folders synced (only favorite files). If you’re like me, and you don&amp;rsquo;t know exactly what papers you are going to be reading, you have to use something different, e.g. Dropsync. (BTW, if you, like me, have the clever idea of putting the SQLite database with your PDFs, so they all get synced in one folder, don’t ever &amp;ldquo;Tidy Up&amp;rdquo;: Mendeley will happily delete your SQLite database as a “foreign object”.) Mendeley and Dropbox seem to interact poorly with each other in various ways (case-sensitivity; also, Mendeley likes to make filenames that are too long, and Dropbox will stupidly and happily accept them).&lt;/li>
&lt;li>The “open windows” button doesn’t appear to properly respect when an application is closed through its own volition (i.e. through an exit button natively supported by the aplication.) This is a bit annoying.&lt;/li>
&lt;/ul>
&lt;p>Oh yeah, and Happy New Year. :)&lt;/p></description></item><item><title>Metro Maps of the News</title><link>https://blog.ezyang.com/2012/12/metro-maps-of-the-news/</link><pubDate>Thu, 13 Dec 2012 04:44:40 +0000</pubDate><guid>https://blog.ezyang.com/2012/12/metro-maps-of-the-news/</guid><description>&lt;p>Metro maps are a visual metaphor for complex, interdependent story lines developed by &lt;a href="http://www.cs.cmu.edu/~dshahaf/">Dafna Shahaf&lt;/a>. Dafna’s thesis involved techniques for automatically taking a corpus of news articles and extracting a coherent narratives that covered the overall space. For our final &lt;a href="https://graphics.stanford.edu/wikis/cs448b-12-fall/">CS448b&lt;/a> project, we took one of the narratives Dafna had generated and created &lt;a href="http://metro.ezyang.com">a system for displaying the maps.&lt;/a> (The demo is best viewed on a large monitor.)&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/metromap.png" alt="image">&lt;/p>
&lt;p>We only had enough time to get the viewer aspect polished, but we think that it would not be too difficult to extend this framework for the &lt;em>construction&lt;/em> of metro maps (in case you don’t have access to Dafna’s algorithm).&lt;/p></description></item><item><title>Maildir synchronizing Sup</title><link>https://blog.ezyang.com/2012/12/maildir-synchronizing-sup/</link><pubDate>Sat, 01 Dec 2012 18:33:38 +0000</pubDate><guid>https://blog.ezyang.com/2012/12/maildir-synchronizing-sup/</guid><description>&lt;p>On the prompting of Steven Hum, I&amp;rsquo;ve put some finishing touches on my Sup patchset and am “releasing” it to the world (more on what I mean by “release” shortly.) The overall theme of this patchset is that it integrates as much Sup metadata it can with Maildir data. In particular:&lt;/p>
&lt;ul>
&lt;li>It merges Damien Leone’s sync-back patchset with the latest Sup mainline. The sync-back patchset synchronizes flags such as “Read” or “Trashed” to the Maildir, which can then be propagated back to your IMAP server using OfflineIMAP.&lt;/li>
&lt;li>Furthermore, this patchset has the ability to synchronize arbitrary labels, with a simple set of rules of what folder a message should be moved to depending on what labels it has. For example, inbox and archived messages can be kept in separate folders, so that non-Sup clients can usefully access mail you care about. (Trust me: this is really awesome.) This is coupled with a bonus OfflineIMAP patch which implements fast remote message moving.&lt;/li>
&lt;li>It implements inotify on Maildir, so a full directory scan is no longer necessary to retrieve new messages. The bottleneck for polling is now strictly OfflineIMAP.&lt;/li>
&lt;li>It implements the ability to save sent and draft messages to Maildir, so they show up in third-party clients.&lt;/li>
&lt;li>Finally, it has a number of miscellaneous bugfixes and extra hooks which I have personally found useful.&lt;/li>
&lt;/ul>
&lt;p>There is at least a high probability the patchset will work for you, since I’ve been using it actively for a while. Sup will sometimes crash; if it doesn&amp;rsquo;t happen reproduceably or cause data loss, I probably won’t investigate too hard. Some of my patches are a bit sketchy (especially those labeled &lt;code>HACK&lt;/code>: I’ve attempted to document all the skeevy bits in commit messages and code comments.) So, how supported is this version of Sup? Well:&lt;/p></description></item><item><title>Why can't I just be a little lazy?</title><link>https://blog.ezyang.com/2012/11/why-cant-i-just-be-a-little-lazy/</link><pubDate>Mon, 26 Nov 2012 09:00:28 +0000</pubDate><guid>https://blog.ezyang.com/2012/11/why-cant-i-just-be-a-little-lazy/</guid><description>&lt;p>You can. Imagine a version of Haskell where every constructor was strict, e.g. every field had a &lt;code>!&lt;/code> prefix. The semantics of this language are well defined; and in fact, the fine folks at CMU have known about this for some time:&lt;/p>
&lt;blockquote>
&lt;p>Up to this point we have frequently encountered arbitrary choices in the dynamics of various language constructs. For example, when specifying the dynamics of pairs, we must choose, rather arbitrarily, between the lazy dynamics, in which all pairs are values regardless of the value status of their components, and the eager dynamics, in which a pair is a value only if its components are both values. We could even consider a half-eager (or, equivalently, half-lazy) dynamics, in which a pair is a value only if, say, the first component is a value, but without regard to the second.&lt;/p></description></item><item><title>Functional Encryption</title><link>https://blog.ezyang.com/2012/11/functional-encryption/</link><pubDate>Sun, 25 Nov 2012 15:24:20 +0000</pubDate><guid>https://blog.ezyang.com/2012/11/functional-encryption/</guid><description>&lt;p>Joe Zimmerman recently shared with me a cool new way of thinking about various encryption schemes called &lt;em>functional encryption.&lt;/em> It’s expounded upon in more depth in a very accessible &lt;a href="http://eprint.iacr.org/2010/543.pdf">recent paper by Dan Boneh et al.&lt;/a>. I’ve reproduced the first paragraph of the abstract below:&lt;/p>
&lt;blockquote>
&lt;p>We initiate the formal study of functional encryption by giving precise definitions of the concept and its security. Roughly speaking, functional encryption supports restricted secret keys that enable a key holder to learn a specific function of encrypted data, but learn nothing else about the data. For example, given an encrypted program the secret key may enable the key holder to learn the output of the program on a specific input without learning anything else about the program.&lt;/p></description></item><item><title>Extremist Programming</title><link>https://blog.ezyang.com/2012/11/extremist-programming/</link><pubDate>Tue, 20 Nov 2012 16:15:06 +0000</pubDate><guid>https://blog.ezyang.com/2012/11/extremist-programming/</guid><description>&lt;div class="container center">
&lt;p>&lt;em>Functions are awesome. What if we made a PL that only had functions?&lt;/em>&lt;/p>
&lt;p>&lt;em>Objects are awesome. What if we made a PL where everything was an object?&lt;/em>&lt;/p>
&lt;p>&lt;em>Lazy evaluation is awesome. What if we made a PL where every data type was lazy?&lt;/em>&lt;/p>
&lt;/div>
&lt;p>&lt;strong>Extremist programming&lt;/strong> (no relation to extreme programming) is the act of taking some principle, elevating it above everything else and applying it everywhere. After the dust settles, people often look at this extremism and think, “Well, that was kind of interesting, but using X in Y was clearly inappropriate. You need to use the right tool for the job!”&lt;/p></description></item><item><title>Plan 9 mounts and dependency injection</title><link>https://blog.ezyang.com/2012/11/plan-9-mounts-and-dependency-injection/</link><pubDate>Thu, 08 Nov 2012 19:45:57 +0000</pubDate><guid>https://blog.ezyang.com/2012/11/plan-9-mounts-and-dependency-injection/</guid><description>&lt;p>“Everything is a file.” [1] This was the design philosophy taken to its logical extreme in &lt;a href="http://en.wikipedia.org/wiki/Plan_9_from_Bell_Labs">Plan 9&lt;/a>. Any interface you could imagine was represented as a file. Network port, pixel buffers, kernel interfaces—all were unified under a common API: the file operations (&lt;code>open&lt;/code>, &lt;code>read&lt;/code>, &lt;code>write&lt;/code>&amp;hellip;) Plan 9 used this to eliminate most of its system calls: it had only thirty-nine, in contrast to modern Linux&amp;rsquo;s sprawling three hundred and twenty-six.&lt;/p></description></item><item><title>hp/D3.js: an interactive heap profile viewer</title><link>https://blog.ezyang.com/2012/11/hpd3-js-an-interactive-heap-profile-viewer/</link><pubDate>Fri, 02 Nov 2012 02:42:18 +0000</pubDate><guid>https://blog.ezyang.com/2012/11/hpd3-js-an-interactive-heap-profile-viewer/</guid><description>&lt;p>I&amp;rsquo;m taking a &lt;a href="https://graphics.stanford.edu/wikis/cs448b-12-fall/">Data Visualization&lt;/a> course this fall, and one of our assignments was to create an interactive visualization. So I thought about the problem for a little bit, and realized, “Hey, wouldn’t it be nice if we had a version of hp2ps that was both interactive and accessible from your browser?” (&lt;code>hp2any&lt;/code> fulfills this niche partially, but as a GTK application).&lt;/p>
&lt;p>A week of hacking later: &lt;a href="http://heap.ezyang.com/">hp/D3.js&lt;/a>, the interactive heap profile viewer for GHC heaps. Upload your &lt;code>hp&lt;/code> files, share them with friends! Our hope is that the next time you need to share a heap profile with someone, instead of running &lt;code>hp2ps&lt;/code> on it and sending your colleague the &lt;code>ps&lt;/code> file, you’ll just upload the &lt;code>hp&lt;/code> file here and send a colleague your link. We’ve tested it on recent Firefox and Chrome, it probably will work on any sufficiently modern browser, it definitely won’t work with Internet Explorer.&lt;/p></description></item><item><title>Ubuntu Quantal upgrade (Thinkpad/Xmonad)</title><link>https://blog.ezyang.com/2012/10/ubuntu-quantal-upgrade-thinkpadxmonad/</link><pubDate>Wed, 24 Oct 2012 11:00:01 +0000</pubDate><guid>https://blog.ezyang.com/2012/10/ubuntu-quantal-upgrade-thinkpadxmonad/</guid><description>&lt;p>October has come, and with it, another Ubuntu release (12.10). I finally gave in and reinstalled my system as 64-bit land (so long 32-bit), mostly because graphics were broken on my upgraded system. As far as I could tell, lightdm was dying immediately after starting up, and I couldn&amp;rsquo;t tell where in my copious configuration I had messed it up. I also started encrypting my home directory.&lt;/p>
&lt;ul>
&lt;li>All &lt;a href="http://askubuntu.com/questions/193524/how-to-hide-bind-mounts-in-nautilus">fstab mount entries&lt;/a> now show up in Nautilus. The correct fix appears to be not putting these mounts in &lt;code>/media&lt;/code>, &lt;code>/mnt&lt;/code> or &lt;code>/home/&lt;/code>, and then they won’t be picked up.&lt;/li>
&lt;li>Fonts continue to be an exquisite pain in rxvt-unicode. I had to switch from &lt;code>URxvt.letterSpace: -1&lt;/code> to &lt;code>URxvt.letterSpace: -2&lt;/code> to keep things working, and the fonts still look inexplicably different. (I haven&amp;rsquo;t figured out why, but the new world order isn&amp;rsquo;t a &lt;em>complete&lt;/em> eyesore so I&amp;rsquo;ve given up for now.) There’s also &lt;a href="http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=628167">a patch&lt;/a> which fixes this problem (hat tip &lt;a href="https://bugs.freedesktop.org/show_bug.cgi?id=47178">this libxft2 bug&lt;/a> bug) but I found that at least for DejaVu the letterSpace hack was equivalent.&lt;/li>
&lt;li>When you manually suspend your laptop and close the lid too rapidly, Ubuntu also registers the close laptop event, so when you resume, it will re-suspend! Fortunately, this is pretty harmless; if you press the power-button again, it will resume properly. You can also work around this by turning off resume on close lid in your power settings.&lt;/li>
&lt;li>On resume, the network manager applet no longer accurately reflects what network you are connected to (it thinks you&amp;rsquo;re connected, but doesn&amp;rsquo;t know to what, or what signal strength it is). It&amp;rsquo;s mostly harmless but kind of annoying; if anyone&amp;rsquo;s figured this one out please let me know!&lt;/li>
&lt;li>Hibernate continues not to work, though I haven’t tried too hard to get it working.&lt;/li>
&lt;li>Firefox was being &lt;em>really&lt;/em> slow, so I &lt;a href="http://support.mozilla.org/en-US/kb/reset-preferences-fix-problems">reset it&lt;/a>. And then it was fast again. Holy smoke! Worth a try if you’ve found Firefox to be really slow.&lt;/li>
&lt;li>GHC is now 7.4.2, so you’ll need to rebuild. &amp;ldquo;When do we get our 7.6 shinies!&amp;rdquo;&lt;/li>
&lt;/ul>
&lt;p>My labmates continue to tease me for not switching to Arch. We’ll see&amp;hellip;&lt;/p></description></item><item><title>ACM XRDS: Jeff Dean profile</title><link>https://blog.ezyang.com/2012/10/acm-xrds-jeff-dean-profile/</link><pubDate>Mon, 22 Oct 2012 10:00:04 +0000</pubDate><guid>https://blog.ezyang.com/2012/10/acm-xrds-jeff-dean-profile/</guid><description>&lt;p>I was wandering through the Gates building when the latest issue of the ACM XRDS, a student written magazine, caught my eye.&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/bigdata/cover.png" alt="image">&lt;/p>
&lt;p>“Oh, didn’t I write an article for this issue?” Yes, I had!&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/bigdata/article.png" alt="image">&lt;/p>
&lt;p>The online version &lt;a href="http://xrds.acm.org/article.cfm?aid=2331062">is here&lt;/a>, though I hear it’s behind a paywall, so I’ve copypasted a draft version of the article below. Fun fact: The first version of this article had a Jeff Dean fact, but we got rid of it because we weren’t sure if everyone knew what &lt;a href="http://www.quora.com/What-are-all-the-Jeff-Dean-facts">Jeff Dean facts&lt;/a> were&amp;hellip;&lt;/p></description></item><item><title>Duality for Haskellers</title><link>https://blog.ezyang.com/2012/10/duality-for-haskellers/</link><pubDate>Fri, 19 Oct 2012 11:00:50 +0000</pubDate><guid>https://blog.ezyang.com/2012/10/duality-for-haskellers/</guid><description>&lt;p>&lt;em>This post is the spiritual predecessor to&lt;/em> &lt;a href="http://blog.ezyang.com/2010/07/flipping-arrows-in-coburger-king/">Flipping Burgers in coBurger King&lt;/a>.&lt;/p>
&lt;p>What does it mean for something to be &lt;em>dual&lt;/em>? A category theorist would say, “It’s the same thing, but with all the arrows flipped around.” This answer seems frustratingly vague, but actually it’s quite precise. The only thing missing is knowing &lt;em>what&lt;/em> arrows flip around! If you know the arrows, then you know how to dualize. In this post, I’d like to take a few structures that are well known to Haskellers, describe what the arrows for this structure look like, and then show that when we flip the arrows, we get a dual concept.&lt;/p></description></item><item><title>Hails: Protecting Data Privacy in Untrusted Web Applications</title><link>https://blog.ezyang.com/2012/10/hails-protecting-data-privacy-in-untrusted-web-applications/</link><pubDate>Tue, 16 Oct 2012 11:00:33 +0000</pubDate><guid>https://blog.ezyang.com/2012/10/hails-protecting-data-privacy-in-untrusted-web-applications/</guid><description>&lt;p>&lt;em>This post is adapted from the talk which Deian Stefan gave for Hails at OSDI 2012.&lt;/em>&lt;/p>
&lt;p>It is a truth universally acknowledged that any website (e.g. Facebook) is in want of a web platform (e.g. the Facebook API). Web platforms are &lt;em>awesome&lt;/em>, because they allow third-party developers to build apps which operate on our personal data.&lt;/p>
&lt;p>But web platforms are also &lt;em>scary&lt;/em>. After all, they allow &lt;em>third-party&lt;/em> developers to build apps which operate on our &lt;em>personal&lt;/em> data. For all we know, they could be selling our email addresses to spamlords or snooping on our personal messages. With the ubiquity of third-party applications, it’s nearly trivial to steal personal data. Even if we assumed that all developers had our best interests at heart, we&amp;rsquo;d still have to worry about developers who don&amp;rsquo;t understand (or care about) security.&lt;/p></description></item><item><title>Visualizing satisfiability, validity &amp; entailment</title><link>https://blog.ezyang.com/2012/10/visualizing-satisfiability-validity-and-entailment/</link><pubDate>Mon, 15 Oct 2012 11:00:51 +0000</pubDate><guid>https://blog.ezyang.com/2012/10/visualizing-satisfiability-validity-and-entailment/</guid><description>&lt;p>So you’re half bored to death working on your propositional logic problem set (after all, you know what AND and OR are, being a computer scientist), and suddenly the problem set gives you a real stinker of a question:&lt;/p>
&lt;blockquote>
&lt;p>Is it true that Γ ⊢ A implies that Γ ⊢ ¬A is false?&lt;/p>&lt;/blockquote>
&lt;p>and you think, “Double negation, no problem!” and say “Of course!” Which, of course, is wrong: right after you turn it in, you think, “Aw crap, if Γ contains a contradiction, then I can prove both A and ¬A.” And then you wonder, “Well crap, I have no intuition for this shit at all.”&lt;/p></description></item><item><title>GET /browser.exe</title><link>https://blog.ezyang.com/2012/10/get-browser-exe/</link><pubDate>Fri, 12 Oct 2012 14:26:17 +0000</pubDate><guid>https://blog.ezyang.com/2012/10/get-browser-exe/</guid><description>&lt;p>&lt;a href="http://research.microsoft.com/en-us/people/howell/">Jon Howell&lt;/a> dreams of a new Internet. In this new Internet, cross-browser compatibility checking is a distant memory and new features can be unilaterally be added to browsers without having to convince the world to upgrade first. The idea which makes this Internet possible is so crazy, it just might work.&lt;/p>
&lt;p>&lt;em>What if a web request didn’t just download a web page, but the browser too?&lt;/em>&lt;/p>
&lt;p>“That’s stupid,” you might say, “No way I’m running random binaries from the Internet!” But you’d be wrong: Howell knows how to do this, and furthermore, how to do so in a way that is &lt;em>safer&lt;/em> than the JavaScript your browser regularly receives and executes. The idea is simple: the code you’re executing (be it native, bytecode or text) is not important, rather, it is the &lt;em>system API&lt;/em> exposed to the code that determines the safety of the system.&lt;/p></description></item><item><title>Generalizing the programmable semicolon</title><link>https://blog.ezyang.com/2012/10/generalizing-the-programmable-semicolon/</link><pubDate>Wed, 03 Oct 2012 17:49:28 +0000</pubDate><guid>https://blog.ezyang.com/2012/10/generalizing-the-programmable-semicolon/</guid><description>&lt;p>&lt;em>Caveat emptor: half-baked research ideas ahead.&lt;/em>&lt;/p>
&lt;p>What is a monad? One answer is that it is a way of sequencing actions in a non-strict language, a way of saying “this should be executed before that.” But another answer is that it is programmable semicolon, a way of implementing custom side-effects when doing computation. These include bread and butter effects like state, control flow and nondeterminism, to more exotic ones such as &lt;a href="http://hackage.haskell.org/package/lio">labeled IO&lt;/a>. Such functionality is useful, even if you don’t need monads for sequencing!&lt;/p></description></item><item><title>Template project for GHC plugins</title><link>https://blog.ezyang.com/2012/09/template-project-for-ghc-plugins/</link><pubDate>Fri, 28 Sep 2012 18:56:20 +0000</pubDate><guid>https://blog.ezyang.com/2012/09/template-project-for-ghc-plugins/</guid><description>&lt;p>There is a bit of scaffolding involved with making Core-to-Core transforming GHC plugins, so I made a little project, based off of &lt;a href="https://github.com/thoughtpolice/strict-ghc-plugin">Max Bolingbroke’s examples&lt;/a>, which is a nice, clean template project which you can use to create your own GHC plugins. In particular, it has documentation and pointers to the GHC source as well as a handy-dandy shell script &lt;code>rename.sh MyProjectName&lt;/code> which will let you easily rename the template project into whatever name you want. You can &lt;a href="https://github.com/ezyang/ghc-plugin-template">find it on GitHub&lt;/a>. I’ll probably be adding more to it as I go along; let me know about any bugs too.&lt;/p></description></item><item><title>"This is really the End."</title><link>https://blog.ezyang.com/2012/09/feit-thompson-true/</link><pubDate>Mon, 24 Sep 2012 09:00:12 +0000</pubDate><guid>https://blog.ezyang.com/2012/09/feit-thompson-true/</guid><description>&lt;p>&lt;em>Done.&lt;/em> This adjective rarely describes any sort of software project—there are always more bugs to fix, more features to add. But on September 20th, early one afternoon in France, Georges Gonthier did just that: he slotted in the last component of a six year project, with the laconic commit message, &amp;ldquo;This is really the End.&amp;rdquo;&lt;/p>
&lt;p>It was complete: &lt;a href="http://www.msr-inria.inria.fr/events-news/feit-thompson-proved-in-coq">the formalization of the Feit-Thompson theorem.&lt;/a>&lt;/p>
&lt;p>If you’re not following the developments in interactive theorem proving or the formalization of mathematics, this achievement may leave you scratching your head a little. What is the Feit-Thompson theorem? What does it mean for it to have been formalized? What was the point of this exercise? Unlike the &lt;a href="http://en.wikipedia.org/wiki/Four_color_theorem">four coloring theorem&lt;/a> which Gonthier and his team tackled previously in 2005, the Feit-Thompson theorem (also known as the odd order theorem) is not easily understandable by non-mathematician without a background in group theory (I shall not attempt to explain it). Nor are there many working mathematicians whose lives will be materially impacted by the formalization of this particular theorem. But there is a point; one that can be found between the broad motivation behind the computer-assisted theorem proving and the fascinating social context surrounding the Feit-Thompson theorem.&lt;/p></description></item><item><title>Unintuitive facts about Safe Haskell</title><link>https://blog.ezyang.com/2012/09/common-misconceptions-about-safe-haskell/</link><pubDate>Mon, 17 Sep 2012 20:34:45 +0000</pubDate><guid>https://blog.ezyang.com/2012/09/common-misconceptions-about-safe-haskell/</guid><description>&lt;p>&lt;a href="http://www.haskell.org/ghc/docs/7.4.2/html/users_guide/safe-haskell.html">Safe Haskell&lt;/a> is a new language pragma for GHC which allows you to run untrusted code on top of a trusted code base. There are some common misconceptions about how Safe Haskell works in practice. In this post, I’d like to help correct some of these misunderstandings.&lt;/p>
&lt;h3 id="system-rm--rf---io-exitcode-is-accepted-by-safe-haskell" id="system-rm--rf---io-exitcode-is-accepted-by-safe-haskell">
 &lt;a class="heading-link" href="https://blog.ezyang.com/2012/09/common-misconceptions-about-safe-haskell/#system-rm--rf---io-exitcode-is-accepted-by-safe-haskell">[&lt;code>system 'rm -Rf /' :: IO ExitCode&lt;/code>] is accepted by Safe Haskell&lt;span class="heading-anchor" aria-label="Anchor">¶&lt;/span>&lt;/a>
&lt;/h3>
&lt;p>Although an IO action here is certainly unsafe, it is not rejected by Safe Haskell per se, because the type of this expression clearly expresses the fact that the operation may have arbitrary side effects. Your obligation in the trusted code base is to not run untrusted code in the IO monad! If you need to allow limited input/output, you must define a restricted IO monad, which is described in the manual.&lt;/p></description></item><item><title>The Y Combinator and strict positivity</title><link>https://blog.ezyang.com/2012/09/y-combinator-and-strict-positivity/</link><pubDate>Wed, 12 Sep 2012 18:52:23 +0000</pubDate><guid>https://blog.ezyang.com/2012/09/y-combinator-and-strict-positivity/</guid><description>&lt;p>One of the most mind-bending features of the untyped lambda calculus is the fixed-point combinator, which is a function &lt;code>fix&lt;/code> with the property that &lt;code>fix f == f (fix f)&lt;/code>. Writing these combinators requires nothing besides lambdas; one of the most famous of which is the Y combinator &lt;code>λf.(λx.f (x x)) (λx.f (x x))&lt;/code>.&lt;/p>
&lt;p>Now, if you’re like me, you saw this and tried to implement it in a typed functional programming language like Haskell:&lt;/p></description></item><item><title>So you want to hack on IMAP...</title><link>https://blog.ezyang.com/2012/08/so-you-want-to-hack-on-imap/</link><pubDate>Fri, 31 Aug 2012 10:00:34 +0000</pubDate><guid>https://blog.ezyang.com/2012/08/so-you-want-to-hack-on-imap/</guid><description>&lt;p>(Last IMAP themed post for a while, I promise!)&lt;/p>
&lt;p>Well, first off, you’re horribly misinformed: you do not &lt;em>actually&lt;/em> want to hack on IMAP. But supposing, for some masochistic reason, you need to dig in the guts of your mail synchronizer and fix a bug or add some features. There are a few useful things to know before you start your journey&amp;hellip;&lt;/p>
&lt;ul>
&lt;li>Read your RFCs. &lt;a href="http://tools.ietf.org/html/rfc3501">RFC 3501&lt;/a> is the actual specification, while &lt;a href="http://tools.ietf.org/html/rfc2683">RFC 2683&lt;/a> gives a lot of helpful tips for working around the hairy bits of the many IMAP servers out there in practice. You should also know about the UIDPLUS extension, &lt;a href="http://tools.ietf.org/html/rfc4315">RFC 4315&lt;/a>, which is fairly well supported and makes a client implementor’s life &lt;em>a lot&lt;/em> easier.&lt;/li>
&lt;li>IMAP is fortunately a text-based protocol, so you can and should play around with it on the command line. A great tool to use for this is &lt;code>imtest&lt;/code>, which has all sorts of fancy features such as SASL authentication. (Don’t forget to &lt;code>rlwrap&lt;/code> it!) Make sure you prefix your commands with an identifier (&lt;code>UID&lt;/code> is a valid identifier, so typing &lt;code>UID FETCH ...&lt;/code> will &lt;em>not&lt;/em> do what you want.)&lt;/li>
&lt;li>It is generally a better idea to use UIDs over sequence numbers, since they are more stable, but be careful: as per the specification, &lt;code>UID&lt;/code> prefixed commands &lt;em>never fail&lt;/em>, so you will need to check untagged data in the response to see if anything actually happened. (If you have a shitty IMAP library, it may not clear out untagged data between requests, so watch out for stale data!) Oh, and look up &lt;code>UIDVALIDITY&lt;/code>.&lt;/li>
&lt;li>There exist a lot of software that interfaces with IMAP, all of which has accreted special cases for buggy IMAP servers over the years. It is well worth sourcediving a few to get a sense for what kinds of things you will need to handle.&lt;/li>
&lt;/ul></description></item><item><title>OfflineIMAP sucks</title><link>https://blog.ezyang.com/2012/08/offlineimap-sucks/</link><pubDate>Thu, 30 Aug 2012 01:07:58 +0000</pubDate><guid>https://blog.ezyang.com/2012/08/offlineimap-sucks/</guid><description>&lt;p>I am going to share a dirty little secret with you, a secret that only someone who uses and hacks on OfflineIMAP could reasonably know: OfflineIMAP sucks. Of course, you can still use software that sucks (I do all the time), but it’s useful to know what some of its deficiencies are, so that you can decide if you’re willing to put up with the suckage. So why does OfflineIMAP suck?&lt;/p></description></item><item><title>How OfflineIMAP works</title><link>https://blog.ezyang.com/2012/08/how-offlineimap-works/</link><pubDate>Mon, 27 Aug 2012 10:00:33 +0000</pubDate><guid>https://blog.ezyang.com/2012/08/how-offlineimap-works/</guid><description>&lt;p>As software engineers, we are trained to be a little distrustful of marketing copy like this:&lt;/p>
&lt;blockquote>
&lt;p>OfflineIMAP is SAFE; it uses an algorithm designed to prevent mail loss at all costs. Because of the design of this algorithm, even programming errors should not result in loss of mail. I am so confident in the algorithm that I use my own personal and work accounts for testing of OfflineIMAP pre-release, development, and beta releases.&lt;/p></description></item><item><title>The Monad Reader: Issue 20</title><link>https://blog.ezyang.com/2012/08/the-monad-reader-issue-20/</link><pubDate>Sat, 25 Aug 2012 23:39:18 +0000</pubDate><guid>https://blog.ezyang.com/2012/08/the-monad-reader-issue-20/</guid><description>&lt;p>After a long delay and a lot of editing, &lt;a href="http://themonadreader.wordpress.com/2012/08/25/issue-20/">Issue 20 of The Monad Reader&lt;/a> is finally out. Check it out!&lt;/p></description></item><item><title>Applicative functors</title><link>https://blog.ezyang.com/2012/08/applicative-functors/</link><pubDate>Thu, 16 Aug 2012 05:34:30 +0000</pubDate><guid>https://blog.ezyang.com/2012/08/applicative-functors/</guid><description>&lt;div class="container center">
&lt;p>&lt;em>On the importance of primary sources.&lt;/em>&lt;/p>
&lt;/div>
&lt;p>(Introductory material ahead.) Most readers of this blog should have at least a passing familiarity with &lt;a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Applicative.html">applicative functors&lt;/a>:&lt;/p>
&lt;pre>&lt;code>class Applicative f where
 pure :: a -&amp;gt; f a
 (&amp;lt;*&amp;gt;) :: f (a -&amp;gt; b) -&amp;gt; f a -&amp;gt; f b
&lt;/code>&lt;/pre>
&lt;p>This interface is quite convenient for day-to-day programming (in particular, it makes for the nice &lt;code>f &amp;lt;$&amp;gt; a &amp;lt;*&amp;gt; b &amp;lt;*&amp;gt; c&lt;/code> idiom), but the laws it obeys are quite atrocious:&lt;/p></description></item><item><title>Practical Foundations for Programming Languages (first impressions)</title><link>https://blog.ezyang.com/2012/08/practical-foundations-for-programming-languages/</link><pubDate>Wed, 15 Aug 2012 01:00:31 +0000</pubDate><guid>https://blog.ezyang.com/2012/08/practical-foundations-for-programming-languages/</guid><description>&lt;p>&lt;a href="http://www.cs.cmu.edu/~rwh/">Robert Harper&lt;/a> has (somewhat) recently released a &lt;a href="http://www.cs.cmu.edu/~rwh/plbook/book.pdf">pre-print of a book (PDF)&lt;/a> that he has been working on, &lt;em>Practical Foundations for Programming Languages&lt;/em>. I downloaded a copy when it initially came out, but I was guilty of putting off actually digging into the book’s 590-some pages. It was only until Harper successfully baited me with &lt;a href="http://existentialtype.wordpress.com/2012/08/14/haskell-is-exceptionally-unsafe/">one of his most recent blog posts&lt;/a> that I finally sat down and skimmed it a bit more thoroughly.&lt;/p></description></item><item><title>Is Haskell liberal or conservative?</title><link>https://blog.ezyang.com/2012/08/is-haskell-liberal-or-conservative/</link><pubDate>Fri, 10 Aug 2012 09:12:50 +0000</pubDate><guid>https://blog.ezyang.com/2012/08/is-haskell-liberal-or-conservative/</guid><description>&lt;p>Steve Yegge has posted a &lt;a href="https://plus.google.com/u/0/110981030061712822816/posts/KaSKeg4vQtz">fun article&lt;/a> attempting to apply the liberal and conservative labels to software engineering. It is, of course, a gross oversimplification (which Yegge admits). For example, he concludes that Haskell must be “extreme conservative”, mostly pointing at its extreme emphasis on safety. This completely misses one of the best things about Haskell, which is that &lt;em>we do crazy shit that no one in their right mind would do without Haskell’s safety features.&lt;/em>&lt;/p></description></item><item><title>Two ways of representing perfect binary trees</title><link>https://blog.ezyang.com/2012/08/statically-checked-perfect-binary-trees/</link><pubDate>Sat, 04 Aug 2012 11:04:33 +0000</pubDate><guid>https://blog.ezyang.com/2012/08/statically-checked-perfect-binary-trees/</guid><description>&lt;p>A common simplification when discussing many divide and conquer algorithms is the assumption that the input list has a size which is a power of two. As such, one might wonder: &lt;em>how do we encode lists that have power of two sizes&lt;/em>, in a way that lists that don’t have this property are unrepresentable? One observation is that such lists are &lt;em>perfect binary trees&lt;/em>, so if we have an encoding for perfect binary trees, we also have an encoding for power of two lists. Here are two well-known ways to do such an encoding in Haskell: one using GADTs and one using nested data-types. We claim that the nested data-types solution is superior.&lt;/p></description></item><item><title>Polymorphic variants in Ur/Web</title><link>https://blog.ezyang.com/2012/07/polymorphic-variants-in-urweb/</link><pubDate>Sun, 29 Jul 2012 01:33:18 +0000</pubDate><guid>https://blog.ezyang.com/2012/07/polymorphic-variants-in-urweb/</guid><description>&lt;p>This document explains how &lt;strong>polymorphic variants&lt;/strong> in &lt;a href="http://www.impredicative.com/ur/">Ur/Web&lt;/a> work. It was written because the &lt;a href="http://www.impredicative.com/ur/tutorial/">official tutorial&lt;/a> has no mention of them, the manual only devotes a paragraph to the topic, and there are some useful tricks for dealing with them that I picked up while wrangling with them in &lt;a href="http://logitext.mit.edu/main">Logitext&lt;/a>.&lt;/p>
&lt;h3 id="what-are-polymorphic-variants" id="what-are-polymorphic-variants">
 &lt;a class="heading-link" href="https://blog.ezyang.com/2012/07/polymorphic-variants-in-urweb/#what-are-polymorphic-variants">What are polymorphic variants?&lt;span class="heading-anchor" aria-label="Anchor">¶&lt;/span>&lt;/a>
&lt;/h3>
&lt;p>Polymorphic variants may be &lt;a href="http://caml.inria.fr/pub/docs/manual-ocaml/manual006.html">familiar to OCaml users&lt;/a>: they permit you to use the tags of variants in multiple types, and not just in the original algebraic data type a constructor was defined in. Instead having to keep names unique:&lt;/p></description></item><item><title>Managing the server/client split in Ur/Web</title><link>https://blog.ezyang.com/2012/07/managing-the-server-client-split-in-ur-web/</link><pubDate>Wed, 25 Jul 2012 01:17:14 +0000</pubDate><guid>https://blog.ezyang.com/2012/07/managing-the-server-client-split-in-ur-web/</guid><description>&lt;p>The holy grail of web application development is a &lt;em>single language&lt;/em> which runs on both the server side and the client side. The reasons for this are multifarious: a single language promotes reuse of components that no longer need to be reimplemented in two languages and allows for much more facile communication between the server and the client. Web frameworks that explicitly strive to handle both the server and client include &lt;a href="http://www.meteor.com/">Meteor&lt;/a>, &lt;a href="http://www.impredicative.com/ur/">Ur/Web&lt;/a>, &lt;a href="http://opalang.org/">Opa&lt;/a> and &lt;a href="https://developers.google.com/web-toolkit/overview">Google Web Toolkit&lt;/a>.&lt;/p></description></item><item><title>Secure multiparty Bitcoin anonymization</title><link>https://blog.ezyang.com/2012/07/secure-multiparty-bitcoin-anonymization/</link><pubDate>Fri, 20 Jul 2012 11:42:13 +0000</pubDate><guid>https://blog.ezyang.com/2012/07/secure-multiparty-bitcoin-anonymization/</guid><description>&lt;blockquote>
&lt;p>&lt;em>Abstract.&lt;/em> We describe how secure multi-party sorting can serve as the basis for a Bitcoin anonymization protocol which improves over current centralized “mixing” designs.&lt;/p>&lt;/blockquote>
&lt;p>Bitcoin is a &lt;a href="https://en.bitcoin.it/wiki/Anonymity">pseudonymous protocol&lt;/a>: while Bitcoin addresses are in principle completely anonymous, all traffic into and out of a wallet is publicly visible. With some &lt;a href="http://anonymity-in-bitcoin.blogspot.com/2011/07/bitcoin-is-not-anonymous.html">simple network analysis&lt;/a> collections of addresses can be linked together and identified.&lt;/p>
&lt;p>The current state of the art for anonymizing Bitcoins is a &lt;a href="https://en.bitcoin.it/wiki/Mixing_service">mixing service&lt;/a>, which is trusted third-party wallet which accepts incoming transactions, and in random increments scheduled at random times in the future, transfers a corresponding quantity to a new wallet of your choice. The result is given any Bitcoin that is distributed from this service, there exist a large number of identities from whom the Bitcoin may have originated.&lt;/p></description></item><item><title>Why verification results in higher quality code</title><link>https://blog.ezyang.com/2012/06/why-verification-results-in-higher-quality-code/</link><pubDate>Sat, 23 Jun 2012 00:40:11 +0000</pubDate><guid>https://blog.ezyang.com/2012/06/why-verification-results-in-higher-quality-code/</guid><description>&lt;p>Correctness is overrated. After all, no one knows what it means for any reasonably complicated system to be &amp;ldquo;correct&amp;rdquo;, and even when we do, the mileposts move around on a daily basis. With the &lt;em>raison d&amp;rsquo;être&lt;/em> of formal verification stripped away, can we still consider it a worthy goal?&lt;/p>
&lt;p>Perhaps verification results in higher quality code. But this is not obviously true: correctness is not quality. We might hope that high quality code is readable and easily understood, that it should be as self-contained and independent from the rest of the system, that it is efficient and economical. There is no a priori reason to believe that verification would grant us any of these properties. No matter how horrible some code is, as long as it is correct, there exists a proof which vouches for its correctness.&lt;/p></description></item><item><title>Thoughts on gamifying textbooks</title><link>https://blog.ezyang.com/2012/05/thoughts-on-gamifying-textbooks/</link><pubDate>Thu, 24 May 2012 19:10:57 +0000</pubDate><guid>https://blog.ezyang.com/2012/05/thoughts-on-gamifying-textbooks/</guid><description>&lt;p>Earlier this year, Woodie Flowers wrote this &lt;a href="http://web.mit.edu/fnl/volume/243/flowers.html">criticism of MITx&lt;/a>:&lt;/p>
&lt;blockquote>
&lt;p>We seem to have decided to offer “courses” rather than participate in the exciting new process of replacing textbooks with more effective training tools.&lt;/p>&lt;/blockquote>
&lt;p>&lt;a href="http://logitext.ezyang.scripts.mit.edu/logitext.fcgi/tutorial">Logitext&lt;/a>, true to its name, was intended to explore what a chapter from a next-generation textbook on formal logic might look like. But if you asked anyone what subjects the most important textbooks of this century would be about, I doubt logic would be particularly high on anyone’s list. In terms of relevance, Logitext misses the mark. But I do think there are some design principles that Logitext helps elucidate.&lt;/p></description></item><item><title>An Interactive Tutorial of the Sequent Calculus</title><link>https://blog.ezyang.com/2012/05/an-interactive-tutorial-of-the-sequent-calculus/</link><pubDate>Tue, 22 May 2012 09:00:28 +0000</pubDate><guid>https://blog.ezyang.com/2012/05/an-interactive-tutorial-of-the-sequent-calculus/</guid><description>&lt;p>You can view it here: &lt;a href="http://logitext.ezyang.scripts.mit.edu/logitext.fcgi/tutorial">An Interactive Tutorial of the Sequent Calculus&lt;/a>. This is the &amp;ldquo;system in three languages&amp;rdquo; that I was referring to in &lt;a href="http://blog.ezyang.com/2012/05/what-happens-when-you-mix-three-research-programming-languages-together/">this blog post&lt;/a>. You can also use the system in a more open ended fashion from &lt;a href="http://logitext.ezyang.scripts.mit.edu/logitext.fcgi/main">this page&lt;/a>. Here&amp;rsquo;s the blurb:&lt;/p>
&lt;blockquote>
&lt;p>&lt;em>This interactive tutorial will teach you how to use the sequent calculus, a simple set of rules with which you can use to show the truth of statements in first order logic. It is geared towards anyone with some background in writing software for computers, with knowledge of basic boolean logic.&lt;/em>&lt;/p></description></item><item><title>Ubuntu Precise upgrade (Thinkpad/Xmonad)</title><link>https://blog.ezyang.com/2012/05/ubuntu-precise-upgrade-thinkpad-xmonad/</link><pubDate>Fri, 18 May 2012 20:51:12 +0000</pubDate><guid>https://blog.ezyang.com/2012/05/ubuntu-precise-upgrade-thinkpad-xmonad/</guid><description>&lt;p>It is once again time for Ubuntu upgrades. I upgraded from Ubuntu Oneiric Ocelot to Ubuntu Precise Pangolin (12.04), which is an LTS release. Very few things broke (hooray!)&lt;/p>
&lt;ul>
&lt;li>The Monospace font changed to something new, with very wide glyph size. The old font was DejaVuSansMono, which I switched back to.&lt;/li>
&lt;li>Xournal stopped compiling; somehow the linker behavior changed and you need to specify the linker flags manually.&lt;/li>
&lt;li>&lt;a href="https://bugs.launchpad.net/ubuntu/+source/gnome-keyring/+bug/932177">gnome-keyring&lt;/a> isn&amp;rsquo;t properly starting up for us non-Unity folks. The underlying problem appears to be &lt;a href="http://lists.debian.org/debian-lint-maint/2009/07/msg00129.html">packaging errors by Gnome&lt;/a>, but adding &lt;code>eval `gnome-keyring-daemon -s&lt;/code>&lt;span class="title-ref"> to my &lt;/span>&lt;span class="title-ref">.xsession&lt;/span>` cleared things up.&lt;/li>
&lt;li>The battery icon went away! I assume some daemon is failing to get run, but since I have a very nice xmobar display I&amp;rsquo;m not mourning its loss.&lt;/li>
&lt;li>Default GHC is GHC 7.4.1! Time to rebuild; no Haskell Platform yet. (Note that GHC 7.4.1 doesn&amp;rsquo;t support the gold linker; this is the &lt;code>chunk-size&lt;/code> error.)&lt;/li>
&lt;/ul>
&lt;p>I also upgraded my desktop from the previous LTS Lucid Lynx.&lt;/p></description></item><item><title>What happens when you mix three research programming languages together</title><link>https://blog.ezyang.com/2012/05/what-happens-when-you-mix-three-research-programming-languages-together/</link><pubDate>Wed, 16 May 2012 02:54:22 +0000</pubDate><guid>https://blog.ezyang.com/2012/05/what-happens-when-you-mix-three-research-programming-languages-together/</guid><description>&lt;p>“&amp;hellip;so that’s what we’re going to build!”&lt;/p>
&lt;p>“Cool! What language are you going to write it in?”&lt;/p>
&lt;p>“Well, we were thinking we were going to need three programming languages&amp;hellip;”&lt;/p>
&lt;p>“&amp;hellip;three?”&lt;/p>
&lt;p>“&amp;hellip;and they’ll be research programming languages too&amp;hellip;”&lt;/p>
&lt;p>“Are you out of your mind?”&lt;/p>
&lt;hr>
&lt;p>This was the conversation in streaming through my head when I decided that I would be writing my latest software project in Coq, Haskell and Ur/Web. I had reasonably good reasons for the choice: I wanted Coq because I didn’t actually want to implement a theorem prover from scratch, I wanted Ur/Web because I didn’t actually want to hand write JavaScript to get an AJAX interface, and I wanted Haskell because I didn’t want to write a bucket of C to get Ur/Web and Coq to talk to each other. But taken altogether the whole thing seemed a bit ludicrous, like an unholy fusion of a trinity of research programming languages.&lt;/p></description></item><item><title>Some thoughts about literature review</title><link>https://blog.ezyang.com/2012/05/some-thoughts-about-literature-review/</link><pubDate>Sun, 13 May 2012 19:03:00 +0000</pubDate><guid>https://blog.ezyang.com/2012/05/some-thoughts-about-literature-review/</guid><description>&lt;p>While working on my senior thesis, I had to write a prior work section, which ended up being a minisurvey for the particular subfield my topic was in. In the process, a little bird told me some things&amp;hellip;&lt;/p>
&lt;ul>
&lt;li>If you can, ask someone who might know a little bit about the subject to give you the rundown: there&amp;rsquo;s a lot of knowledge in people&amp;rsquo;s heads which never got written down. But also be aware that they will probably have their blind spots.&lt;/li>
&lt;li>It is better to do the literature review later rather than earlier, after you have started digging into the topic. I have been told if you read the literature too early, you will get spoiled and stop thinking novel thoughts. But I also think there is also a little bit of &amp;ldquo;you&amp;rsquo;ll understand the literature better&amp;rdquo; if you&amp;rsquo;ve already thought about the topic on your own. Plus, it&amp;rsquo;s easy to think that everything has been done before: it&amp;rsquo;s simply not true! (But if you think this, you will get needlessly discouraged.)&lt;/li>
&lt;li>Don&amp;rsquo;t indiscriminately add papers to your database. You should have something you want to do with it: is it an important paper that you have to cite because everyone knows about it? Is it directly addressing the issue you&amp;rsquo;re dealing with? Does it happen to be particularly well written? Is it something that you could see yourself reading more carefully later? Don&amp;rsquo;t be afraid to toss the paper out; if it actually was important, you&amp;rsquo;ll run into it again later.&lt;/li>
&lt;li>Every researcher is a historian. When you look at a paper, you&amp;rsquo;re not just looking at what is written inside it, but its social context. There&amp;rsquo;s a reason why &amp;ldquo;prior work&amp;rdquo; is so important to academics. If you don&amp;rsquo;t understand a paper&amp;rsquo;s context, it&amp;rsquo;s unlikely you&amp;rsquo;ll understand the paper.&lt;/li>
&lt;li>Researchers don&amp;rsquo;t necessarily talk to each other. Pay attention to who they cite; it says a little bit about what community they&amp;rsquo;re in.&lt;/li>
&lt;li>Researchers are happy to send you copies of papers they have written (so fear not the paywall that your university hasn&amp;rsquo;t subscribed to). They may even volunteer extra information which may come in handy.&lt;/li>
&lt;li>Be methodical. You&amp;rsquo;re doing a search, and this means carefully noting down which papers you skimmed, and what you got out of them, and keeping track of other veins of research that you need to follow up on. It&amp;rsquo;s like chasing a rabbit down a hole, but if you have some clearly defined search criteria, eventually you&amp;rsquo;ll bottom out. You can prune the uninteresting papers later; the point here is to avoid duplicating work.&lt;/li>
&lt;li>Read papers critically. Not everything that is published is good; that&amp;rsquo;s the point of research!&lt;/li>
&lt;/ul>
&lt;p>What are your favorite maxims to keep in mind while you&amp;rsquo;re surveying the literature?&lt;/p></description></item><item><title>How Ur/Web records work and what it might mean for Haskell</title><link>https://blog.ezyang.com/2012/04/how-urweb-records-work-and-what-it-might-mean-for-haskell/</link><pubDate>Fri, 20 Apr 2012 01:24:41 +0000</pubDate><guid>https://blog.ezyang.com/2012/04/how-urweb-records-work-and-what-it-might-mean-for-haskell/</guid><description>&lt;p>&lt;a href="http://www.impredicative.com/ur/">Ur&lt;/a> is a programming language, which among other things, has a rather interesting record system. Record systems are a topic of rather &lt;a href="http://hackage.haskell.org/trac/ghc/wiki/Records">intense debate&lt;/a> in the Haskell community, and I noticed that someone had remarked “[Ur/Web has a &lt;a href="http://www.impredicative.com/ur/tutorial/tlc.html">http://www.impredicative.com/ur/tutorial/tlc.html&lt;/a> very advanced records system]. If someone could look at the UR implementation paper and attempt to distill a records explanation to a Haskell point of view that would be very helpful!” This post attempts to perform that distillation, based off my experiences interacting with the Ur record system and one of its primary reasons for existence: metaprogramming. (Minor nomenclature note: Ur is the base language, while Ur/Web is a specialization of the base language for web programming, that also happens to actually have a compiler. For the sake of technical precision, I will refer to the language as Ur throughout this article.)&lt;/p></description></item><item><title>Use the source, don't read it</title><link>https://blog.ezyang.com/2012/04/use-the-source-dont-read-it/</link><pubDate>Tue, 17 Apr 2012 12:51:49 +0000</pubDate><guid>https://blog.ezyang.com/2012/04/use-the-source-dont-read-it/</guid><description>&lt;p>&lt;img src="https://blog.ezyang.com/img/use-the-source.png" alt="image">&lt;/p></description></item><item><title>Reduce Ubuntu latency by disabling mDNS</title><link>https://blog.ezyang.com/2012/03/reduce-ubuntu-latency-by-disabling-mdns/</link><pubDate>Sat, 24 Mar 2012 15:56:04 +0000</pubDate><guid>https://blog.ezyang.com/2012/03/reduce-ubuntu-latency-by-disabling-mdns/</guid><description>&lt;p>This is a very quick and easy fix that has made latency on Ubuntu servers I maintain go from &lt;em>three to four seconds&lt;/em> to instantaneous. If you&amp;rsquo;ve noticed that you have high latency on ssh or scp (or even other software like remctl), and you have control over your server, try this on the server: &lt;code>aptitude remove libnss-mdns&lt;/code>. It turns out that multicast DNS on Ubuntu has a &lt;a href="https://bugs.launchpad.net/ubuntu/+source/nss-mdns/+bug/94940">longstanding bug&lt;/a> on Ubuntu where they didn&amp;rsquo;t correctly tune the timeouts, which results in extremely bad performance on reverse DNS lookups when an IP has no name.&lt;/p></description></item><item><title>Visit month: Princeton</title><link>https://blog.ezyang.com/2012/03/visit-month-princeton/</link><pubDate>Tue, 20 Mar 2012 09:00:46 +0000</pubDate><guid>https://blog.ezyang.com/2012/03/visit-month-princeton/</guid><description>&lt;p>&lt;em>If you haven&amp;rsquo;t noticed, these are coming in the order of the visit days.&lt;/em>&lt;/p>
&lt;p>Whereas the weather at UPenn was nice and sunny, the NJ Transit dinghy rolled into a very misty Princeton. Fortunately, I had properly registered for this visit day, so the hotel was in order. I was a bit early, so I met up with an old friend who had recently penned &lt;a href="http://clarkesworldmagazine.com/yu_04_11/">this short story&lt;/a> and we talked about various bits and bobs (&amp;ldquo;I hear you&amp;rsquo;re up for a Hugo!&amp;rdquo;) before I meandered over to the computer science building.&lt;/p></description></item><item><title>Is it better to teach formalism or intuition?</title><link>https://blog.ezyang.com/2012/03/is-it-better-to-teach-formalism-or-intuition/</link><pubDate>Sun, 18 Mar 2012 16:51:31 +0000</pubDate><guid>https://blog.ezyang.com/2012/03/is-it-better-to-teach-formalism-or-intuition/</guid><description>&lt;p>&lt;em>Note: this is not a discussion of Hilbert&amp;rsquo;s formalism versus Brouwer&amp;rsquo;s intuitionism; I&amp;rsquo;m using formalism and intuition in a more loose sense, where formalism represents symbols and formal systems which we use to rigorously define arguments (though not logic: a sliding scale of rigor is allowed here), while intuition represents a hand-wavy argument, the mental model mathematicians actually carry in their head.&lt;/em>&lt;/p>
&lt;p>Formalism and intuition should be taught together.&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/intuition-formalism.png" alt="image">&lt;/p></description></item><item><title>Visit month: University of Pennsylvania</title><link>https://blog.ezyang.com/2012/03/visit-month-upen/</link><pubDate>Fri, 16 Mar 2012 01:59:16 +0000</pubDate><guid>https://blog.ezyang.com/2012/03/visit-month-upen/</guid><description>&lt;p>&lt;em>I&amp;rsquo;m hoping that this will be the beginning of a series of posts describing all of the visit days/open houses that I attended over the past month. Most of the information is being sucked out of the notes I took during the visits, so it&amp;rsquo;s very stream of consciousness style. It&amp;rsquo;s kind of personal, and I won&amp;rsquo;t be offended if you decide not to read. You&amp;rsquo;ve been warned!&lt;/em>&lt;/p>
&lt;p>I arrive at the Inn at Penn shortly before midnight, and check in. Well, attempt it; they appear to have no reservation on hand. It appears that I hadn&amp;rsquo;t actually registered for the visit weekend. &lt;em>Oops.&lt;/em>&lt;/p></description></item><item><title>You could have invented fractional cascading</title><link>https://blog.ezyang.com/2012/03/you-could-have-invented-fractional-cascading/</link><pubDate>Mon, 05 Mar 2012 01:30:22 +0000</pubDate><guid>https://blog.ezyang.com/2012/03/you-could-have-invented-fractional-cascading/</guid><description>&lt;p>Suppose that you have &lt;em>k&lt;/em> sorted arrays, each of size &lt;em>n&lt;/em>. You would like to search for single element in each of the &lt;em>k&lt;/em> arrays (or its predecessor, if it doesn&amp;rsquo;t exist).&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/fractional-cascading/intro.png" alt="image">&lt;/p>
&lt;p>Obviously you can binary search each array individually, resulting in a $O(k\lg n)$ runtime. But we might think we can do better that: after all, we&amp;rsquo;re doing the same search &lt;em>k&lt;/em> times, and maybe we can &amp;ldquo;reuse&amp;rdquo; the results of the first search for later searches.&lt;/p></description></item><item><title>Visualizing range trees</title><link>https://blog.ezyang.com/2012/02/visualizing-range-trees/</link><pubDate>Sun, 26 Feb 2012 03:41:40 +0000</pubDate><guid>https://blog.ezyang.com/2012/02/visualizing-range-trees/</guid><description>&lt;p>&lt;strong>Range trees&lt;/strong> are a data structure which lets you efficiently query a set of points and figure out what points are in some bounding box. They do so by maintaining nested trees: the first level is sorted on the x-coordinate, the second level on the y-coordinate, and so forth. Unfortunately, due to their fractal nature, range trees a bit hard to visualize. (In the higher dimensional case, this is definitely a “Yo dawg, I heard you liked trees, so I put a tree in your tree in your tree in your&amp;hellip;”) But we’re going to attempt to visualize them anyway, by taking advantage of the fact that a &lt;em>sorted list&lt;/em> is basically the same thing as a balanced binary search tree. (We’ll also limit ourselves to two-dimensional case for sanity’s sake.) I’ll also describe a nice algorithm for building range trees.&lt;/p></description></item><item><title>Anatomy of "You could have invented..."</title><link>https://blog.ezyang.com/2012/02/anatomy-of-you-could-have-invented/</link><pubDate>Thu, 23 Feb 2012 14:42:04 +0000</pubDate><guid>https://blog.ezyang.com/2012/02/anatomy-of-you-could-have-invented/</guid><description>&lt;p>The &lt;em>You could have invented&amp;hellip;&lt;/em> article follows a particular scheme:&lt;/p>
&lt;ol>
&lt;li>Introduce an easy to understand problem,&lt;/li>
&lt;li>Attempt to solve the problem, but get stuck doing it the &amp;ldquo;obvious&amp;rdquo; way,&lt;/li>
&lt;li>Introduce an easy to understand insight,&lt;/li>
&lt;li>Methodically work out the rest of the details, arriving at the final result.&lt;/li>
&lt;/ol>
&lt;p>Why does framing the problem this way help?&lt;/p>
&lt;ul>
&lt;li>While the details involved in step 4 result in a structure which is not necessarily obvious (thus giving the impression that the concept is hard to understand), the insight is very easy to understand and the rest is just &amp;ldquo;monkey-work&amp;rdquo;. The &lt;em>method of deriving the solution&lt;/em> is more compressible than the &lt;em>solution itself&lt;/em>, so it is easier to learn.&lt;/li>
&lt;li>Picking a very specific, easy-to-understand problem helps ground us in a concrete example, whereas the resulting structure might be too general to get a good intuition off of.&lt;/li>
&lt;/ul>
&lt;p>It&amp;rsquo;s very important that the problem is easy to understand, and the process of &amp;ldquo;working out the details&amp;rdquo; is simple. Otherwise, the presentation feels contrived. This method is also inappropriate when the audience is in fact smart enough to just look at the end-result and understand on an intuitive level what is going on. Usually, this is because they have &lt;em>already seen the examples.&lt;/em> But for the rest of us, it is a remarkably effective method of pedagogy.&lt;/p></description></item><item><title>Transcript of "Inventing on Principle"</title><link>https://blog.ezyang.com/2012/02/transcript-of-inventing-on-principleb/</link><pubDate>Mon, 20 Feb 2012 16:23:10 +0000</pubDate><guid>https://blog.ezyang.com/2012/02/transcript-of-inventing-on-principleb/</guid><description>&lt;p>&lt;a href="https://github.com/ezyang/cusec2012-victor/blob/master/transcript.md">Here is a full transcript to Github&lt;/a> of Bret Victor&amp;rsquo;s &lt;a href="https://vimeo.com/36579366">&amp;ldquo;Inventing on Principle&amp;rdquo;&lt;/a>. It was transcribed by me, An Yu and Tal Benisty.&lt;/p>
&lt;p>Below is a copy of the transcript which I will endeavor to keep up to date with the Github copy. The original content was licensed under &lt;a href="http://creativecommons.org/licenses/by/3.0/">CC-BY&lt;/a>.&lt;/p>
&lt;hr>
&lt;p>[[0:07]] So, unlike the previous session, I don&amp;rsquo;t have any prizes to give out. I&amp;rsquo;m just going to tell you how to live your life.&lt;/p></description></item><item><title>Travel: Spring 2012 Edition</title><link>https://blog.ezyang.com/2012/02/travel-spring-2012-edition/</link><pubDate>Sat, 18 Feb 2012 10:55:15 +0000</pubDate><guid>https://blog.ezyang.com/2012/02/travel-spring-2012-edition/</guid><description>&lt;p>For various reasons (mostly PhD-related) I will be traveling a bit over the next month.&lt;/p>
&lt;ul>
&lt;li>February 29 to March 2 in &lt;strong>Princeton, NJ&lt;/strong>&lt;/li>
&lt;li>March 5 to March 7 in &lt;strong>Pittsburgh, PA&lt;/strong>&lt;/li>
&lt;li>March 9 to March 12 in &lt;strong>Palo Alto, CA&lt;/strong>&lt;/li>
&lt;/ul>
&lt;p>Let me know if you&amp;rsquo;re any of these areas and want to say hi!&lt;/p></description></item><item><title>How to build DRM you can trust</title><link>https://blog.ezyang.com/2012/02/how-to-build-drm-you-can-trust/</link><pubDate>Wed, 15 Feb 2012 16:49:19 +0000</pubDate><guid>https://blog.ezyang.com/2012/02/how-to-build-drm-you-can-trust/</guid><description>&lt;p>&lt;em>Abstract.&lt;/em> &lt;a href="http://en.wikipedia.org/wiki/Proof-carrying_code">Proof-carrying code&lt;/a> can be used to implement a &lt;a href="http://en.wikipedia.org/wiki/Digital_rights_management">digital-rights management scheme&lt;/a>, in the form of a proof-verifying CPU. We describe how this scheme would work and argue that DRM implemented this way is both desirable and superior to &lt;a href="http://en.wikipedia.org/wiki/Trusted_Computing">trusted (“treacherous”) computing&lt;/a> schemes. This scheme permits users to retain control over their own machines, while allowing for specific limitations on software capabilities. The ability to impose these limitations will become especially important when 3D printers and biosynthesis machines become ubiquitous. This essay assumes some technical knowledge, although no background in formal methods is required. (If you know how proof-carrying code works, go away; this essay is not for you.)&lt;/p></description></item><item><title>POPL</title><link>https://blog.ezyang.com/2012/01/popl/</link><pubDate>Sat, 28 Jan 2012 08:30:59 +0000</pubDate><guid>https://blog.ezyang.com/2012/01/popl/</guid><description>&lt;p>Last night, I returned from my very first POPL, very exhausted, and very satisfied. It was great putting faces to names, chatting with potential PhD supervisors (both from the US and in the UK), and reveling in the atmosphere.&lt;/p>
&lt;p>Highlights from my files:&lt;/p>
&lt;ul>
&lt;li>Tony Hoare, on being awarded the ACM SIGPLAN Programming Languages Achievement Award, even though he has received so many other awards, “&amp;hellip;it makes me feel a little guilty. I didn’t ask for it!”&lt;/li>
&lt;li>Hoare: “I &lt;em>like&lt;/em> mistakes; if I find it’s my fault, I can rectify it. If it’s someone else’s fault, there’s not much you can do.”&lt;/li>
&lt;li>Hoare: “Simplicity is &lt;em>not&lt;/em> an engineering goal.”&lt;/li>
&lt;li>Tony had just described how he retracted an accepted paper because the reasoning on it was intricate, and he didn’t think it presented program proving in a good light. The interviewer complimented him for his principles, saying that if he had a paper accepted which he didn’t think was up to snuff, he probably wouldn’t have the courage to retract it. It was “so brave.” To which Tony replies, “Well, I wish you could!” [laughter] “Unfortunately, the pressure to publish has increased. We feel obliged to publish every year, and the quality of the average paper is not improved.”&lt;/li>
&lt;li>One recurring theme: Tony Hoare mentioned that proofs and tests were not rivals, really they were just the same thing&amp;hellip; just different. In the “Run your Research” talk, these theme came up again, where this time the emphasis was executable papers (the “run” in “Run your Research”).&lt;/li>
&lt;li>“Don’t just &lt;em>support&lt;/em> local reasoning, &lt;em>demand&lt;/em> it!” (Brute force proofs not allowed!)&lt;/li>
&lt;li>On JavaScript: “null is sort of object-y, while undefined is sort of primitive-y.”&lt;/li>
&lt;li>The next set come from the invited speaker from the computer networks community. “During 9/11, on average, the Internet was more stable. The reason for this was the NetOps &lt;em>went home&lt;/em>.” (on the causes of network outages in practice.)&lt;/li>
&lt;li>“Cisco routers have twenty million lines of code: there’s actually an Ada interpreter in there, as well as a Lisp interpreter.”&lt;/li>
&lt;li>“It used to be acceptable to go down for 100ms&amp;hellip; now we have video games.”&lt;/li>
&lt;li>Speaker: “I am the walrus.” (Goo goo g&amp;rsquo; joob.)&lt;/li>
&lt;li>“I believe we do not reuse theorems. We reuse proof methods, but not the actual theorems. When we write papers, we create very shallow models, and we don’t build on previous work. It’s OK. It’s the design. It doesn’t matter too much. The SML standard was distributed with a bug report, with 100+ mistakes in the original definition. Doesn’t detract from its impact.”&lt;/li>
&lt;li>“Put on the algebraic goggles.”&lt;/li>
&lt;li>“The Navy couldn’t install it [a system for detecting when classified words were being transmitted on insecure channels], because doing so would be admitting there was a mistake.”&lt;/li>
&lt;li>“Move to something really modern, like Scheme!” (It’s like investing one trillion, and moving from the thirteenth century to the fourteenth.)&lt;/li>
&lt;li>Strother Moore (co-creator of ACL2): “After retirement, I’ll work more on ACL2, and then I’ll die.”&lt;/li>
&lt;li>“What’s the best way to make sure your C program is conforming?” “Write deterministic code.” [laughter]&lt;/li>
&lt;/ul></description></item><item><title>Modelling IO: MonadIO and beyond</title><link>https://blog.ezyang.com/2012/01/modelling-io/</link><pubDate>Tue, 24 Jan 2012 13:31:06 +0000</pubDate><guid>https://blog.ezyang.com/2012/01/modelling-io/</guid><description>&lt;p>The MonadIO problem is, at the surface, a simple one: we would like to take some function signature that contains &lt;code>IO&lt;/code>, and replace all instances of &lt;code>IO&lt;/code> with some other IO-backed monad &lt;code>m&lt;/code>. The MonadIO typeclass itself allows us to transform a value of form &lt;code>IO a&lt;/code> to &lt;code>m a&lt;/code> (and, by composition, any function with an &lt;code>IO a&lt;/code> as the result). This interface is uncontroversial and quite flexible; it’s been in the bootstrap libraries ever since it was &lt;a href="https://github.com/ghc/packages-base/commit/7f1f4e7a695c402ddd3a1dc2cc7114e649a78ebc">created in 2001&lt;/a> (originally in base, though it migrated to transformers later). However, it was soon discovered that when there were many functions with forms like &lt;code>IO a -&amp;gt; IO a&lt;/code>, which we wanted to convert into &lt;code>m a -&amp;gt; m a&lt;/code>; MonadIO had no provision for handling arguments in the &lt;em>negative&lt;/em> position of functions. This was particularly troublesome in the case of exception handling, where these higher-order functions were &lt;em>primitive&lt;/em>. Thus, the community began searching for a new type class which captured more of IO.&lt;/p></description></item><item><title>monad-control is tricky</title><link>https://blog.ezyang.com/2012/01/monadbasecontrol-is-unsound/</link><pubDate>Mon, 23 Jan 2012 12:39:00 +0000</pubDate><guid>https://blog.ezyang.com/2012/01/monadbasecontrol-is-unsound/</guid><description>&lt;p>&lt;em>Editor&amp;rsquo;s note.&lt;/em> I&amp;rsquo;ve toned down some of the rhetoric in this post. The original title was &amp;ldquo;monad-control is unsound&amp;rdquo;.&lt;/p>
&lt;p>MonadBaseControl and MonadTransControl, from the &lt;a href="http://hackage.haskell.org/package/monad-control">monad-control&lt;/a> package, specify an appealing way to automatically lift functions in IO that take &amp;ldquo;callbacks&amp;rdquo; to arbitrary monad stacks based on IO. Their appeal comes from the fact that they seem to offer a more general mechanism than the alternative: picking some functions, lifting them, and then manually reimplementing generic versions of all the functions built on top of them.&lt;/p></description></item><item><title>Mystery Hunt and the Scientific Endeavour</title><link>https://blog.ezyang.com/2012/01/mystery-hunt-and-the-scientific-endeavour/</link><pubDate>Mon, 16 Jan 2012 16:12:52 +0000</pubDate><guid>https://blog.ezyang.com/2012/01/mystery-hunt-and-the-scientific-endeavour/</guid><description>&lt;p>It can be hard to understand the appeal of spending three days, without sleep, solving what some have called “&lt;a href="http://www.thisamericanlife.org/radio-archives/episode/326/quiz-show?act=2">the hardest recreational puzzles in the world,&lt;/a>”; but over this weekend, hundreds of people converged on the MIT campus to do just that, as part of &lt;a href="http://web.mit.edu/puzzle/www/">MIT Mystery Hunt&lt;/a>. To celebrate the finding of the coin, I&amp;rsquo;d like to share this little essay that I found in my files, which compares Mystery Hunt and the scientific endeavour. (If you are not familiar with Mystery Hunt, I recommend listening to the linked &lt;em>This American Life&lt;/em> program.)&lt;/p></description></item><item><title>Problem Set: The Codensity Transformation</title><link>https://blog.ezyang.com/2012/01/problem-set-the-codensity-transformation/</link><pubDate>Sat, 07 Jan 2012 03:00:20 +0000</pubDate><guid>https://blog.ezyang.com/2012/01/problem-set-the-codensity-transformation/</guid><description>&lt;p>Have you ever wondered how the &lt;em>codensity transformation&lt;/em>, a surprisingly general trick for speeding up the execution of certain types of monads, worked, but never could understand the paper or Edward Kmett&amp;rsquo;s blog posts on the subject?&lt;/p>
&lt;p>Look no further: below is a &lt;em>problem set&lt;/em> for learning how this transformation works.&lt;/p>
&lt;p>The idea behind these exercises is to get you comfortable with the types involved in the codensity transformation, achieved by using the types to guide yourself to the only possible implementation. We warm up with the classic concrete instance for leafy trees, and then generalize over all free monads (don&amp;rsquo;t worry if you don&amp;rsquo;t know what that is: we&amp;rsquo;ll define it and give some warmup exercises).&lt;/p></description></item><item><title>Why iteratees are hard to understand</title><link>https://blog.ezyang.com/2012/01/why-iteratees-are-hard-to-understand/</link><pubDate>Wed, 04 Jan 2012 08:00:26 +0000</pubDate><guid>https://blog.ezyang.com/2012/01/why-iteratees-are-hard-to-understand/</guid><description>&lt;p>There are two primary reasons why the low-level implementations of iteratees, enumerators and enumeratees tend to be hard to understand: &lt;em>purely functional implementation&lt;/em> and &lt;em>inversion of control&lt;/em>. The strangeness of these features is further exacerbated by the fact that users are encouraged to think of iteratees as sinks, enumerators as sources, and enumeratees as transformers. This intuition works well for clients of iteratee libraries but confuses people interested in digging into the internals.&lt;/p></description></item><item><title>Bugs and Battleships</title><link>https://blog.ezyang.com/2011/12/bugs-and-battleships/</link><pubDate>Mon, 19 Dec 2011 11:04:51 +0000</pubDate><guid>https://blog.ezyang.com/2011/12/bugs-and-battleships/</guid><description>&lt;p>&lt;img src="https://blog.ezyang.com/img/testing/battleship.png" alt="image">&lt;/p>
&lt;p>Do you remember your first computer program? When you had finished writing it, what was the first thing you did? You did the simplest possible test: you ran it.&lt;/p>
&lt;p>As programs increase in size, so do the amount of possible tests. It’s worth considering which tests we actually end up running: imagine the children’s game Battleship, where the ocean is the space of all possible program executions, the battleships are the bugs that you are looking for, and each individual missile you fire is a test you run (white if the test passes, red if the test fails.) You don’t have infinite missiles, so you have to decide where you are going to send them.&lt;/p></description></item><item><title>How to build i686 glibc on Ubuntu</title><link>https://blog.ezyang.com/2011/12/how-to-build-i686-glibc-on-ubuntu/</link><pubDate>Sun, 18 Dec 2011 18:03:44 +0000</pubDate><guid>https://blog.ezyang.com/2011/12/how-to-build-i686-glibc-on-ubuntu/</guid><description>&lt;p>An “easy”, two-step process:&lt;/p>
&lt;ol>
&lt;li>&lt;a href="http://www.eglibc.org/archives/patches/msg00073.html">Apply this patch for i686&lt;/a>. (Why they haven&amp;rsquo;t fixed this in the trunk, I have no idea.)&lt;/li>
&lt;li>Configure with &lt;code>CFLAGS=&amp;quot;-U_FORTIFY_SOURCE -fno-stack-protector -O2&amp;quot;&lt;/code> (this disables fortify source and stack protection which Ubuntu enables by default but interferes with glibc. You need to keep optimizations on, because glibc won&amp;rsquo;t build without it.) You’ll need to do the usual extra dance of creating a separate build directory and specifying a prefix.&lt;/li>
&lt;/ol>
&lt;p>Hope this helps someone else. In case you were wondering why I was building glibc, it&amp;rsquo;s because I was reporting these two bugs in iconv:&lt;/p></description></item><item><title>Interactive Demo of Zero-Knowledge Proofs</title><link>https://blog.ezyang.com/2011/12/interactive-demo-of-zero-knowledge-proofs/</link><pubDate>Sat, 17 Dec 2011 13:56:39 +0000</pubDate><guid>https://blog.ezyang.com/2011/12/interactive-demo-of-zero-knowledge-proofs/</guid><description>&lt;p>For the final project in our &lt;a href="http://stellar.mit.edu/S/course/6/fa11/6.893/index.html">theoretical computer science and philosophy class&lt;/a> taught by &lt;a href="http://www.scottaaronson.com/blog/">Scott Aaronson&lt;/a>, &lt;a href="https://plus.google.com/104657582733825681275">Karen Sittig&lt;/a> and I decided to create an interactive demonstration of zero-knowledge proofs. (Sorry, the picture below is not clickable.)&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/interactive-zk.png" alt="image">&lt;/p>
&lt;p>For the &lt;em>actually&lt;/em> interactive demonstration, click here: &lt;a href="http://web.mit.edu/~ezyang/Public/graph/svg.html">http://web.mit.edu/~ezyang/Public/graph/svg.html&lt;/a> (you will need a recent version of Firefox or Chrome, since we did our rendering with SVG.)&lt;/p></description></item><item><title>Accessing lazy structures from C</title><link>https://blog.ezyang.com/2011/12/accessing-lazy-structures-from/</link><pubDate>Thu, 15 Dec 2011 17:18:27 +0000</pubDate><guid>https://blog.ezyang.com/2011/12/accessing-lazy-structures-from/</guid><description>&lt;p>Someone &lt;a href="http://comments.gmane.org/gmane.comp.lang.haskell.beginners/9109">recently asked on haskell-beginners&lt;/a> how to access an lazy (and potentially infinite) data structure in C. I failed to find some example code on how to do this, so I wrote some myself. May this help you in your C calling Haskell endeavours!&lt;/p>
&lt;p>The main file &lt;code>Main.hs&lt;/code>:&lt;/p>
&lt;pre>&lt;code>{-# LANGUAGE ForeignFunctionInterface #-}

import Foreign.C.Types
import Foreign.StablePtr
import Control.Monad

lazy :: [CInt]
lazy = [1..]

main = do
 pLazy &amp;lt;- newStablePtr lazy
 test pLazy -- we let C deallocate the stable pointer with cfree

chead = liftM head . deRefStablePtr
ctail = newStablePtr . tail &amp;lt;=&amp;lt; deRefStablePtr
cfree = freeStablePtr

foreign import ccall test :: StablePtr [CInt] -&amp;gt; IO ()
foreign export ccall chead :: StablePtr [CInt] -&amp;gt; IO CInt
foreign export ccall ctail :: StablePtr [CInt] -&amp;gt; IO (StablePtr [CInt])
foreign export ccall cfree :: StablePtr a -&amp;gt; IO ()
&lt;/code>&lt;/pre>
&lt;p>The C file &lt;code>export.c&lt;/code>:&lt;/p></description></item><item><title>Transparent xmobar</title><link>https://blog.ezyang.com/2011/11/transparent-xmobar/</link><pubDate>Mon, 28 Nov 2011 05:09:32 +0000</pubDate><guid>https://blog.ezyang.com/2011/11/transparent-xmobar/</guid><description>&lt;p>Things I should be working on: &lt;em>graduate school personal statements.&lt;/em>&lt;/p>
&lt;p>What I actually spent the last five hours working on: &lt;em>transparent xmobar.&lt;/em>&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/transparent-xmobar.png" alt="image">&lt;/p>
&lt;p>It uses the horrible “grab Pixmap from root X window” hack. You can grab the &lt;a href="https://github.com/ezyang/xmobar/">patch here&lt;/a> but I haven’t put in enough effort to actually make this a configurable option; if you just compile that branch, you’ll get an xmobar that is at 100/255 transparency, tinted black. (The algorithm needs a bit of work to generalize over different tints properly; suggestions solicted!) Maybe someone else will cook up a more polished patch. (Someone should also drum up a more complete set of XRender bindings!)&lt;/p></description></item><item><title>Ubuntu Oneiric upgrade (Thinkpad/Xmonad)</title><link>https://blog.ezyang.com/2011/11/ubuntu-oneiric-thinkpad-xmonad/</link><pubDate>Thu, 24 Nov 2011 03:59:50 +0000</pubDate><guid>https://blog.ezyang.com/2011/11/ubuntu-oneiric-thinkpad-xmonad/</guid><description>&lt;p>I upgraded from Ubuntu Natty Narwhal to Oneiric Ocelot (11.10) today. Lots of things broke. In order:&lt;/p>
&lt;ul>
&lt;li>“Could not calculate the upgrade.” No indication of what the error might be; in my case, the error ended up being old orphan OpenAFS kernel modules (for whom no kernel modules existed). I also took the opportunity to clean up my PPAs.&lt;/li>
&lt;li>“Reading changelogs.” &lt;code>apt-listchanges&lt;/code> isn’t particularly useful, and I don’t know why I installed it. But it’s really painful when it’s taking more time to read changelogs than to install your software. Geoffrey suggested &lt;code>gdb -p `pgrep apt-listchanges&lt;/code>&lt;span class="title-ref"> and then forcing it to call &lt;/span>&lt;span class="title-ref">exit(0)&lt;/span>`, which worked like a charm. Had to do this several times; thought it was infinitely looping.&lt;/li>
&lt;li>Icons didn’t work, menus ugly. Go to “System Settings &amp;gt; Appearance” and go set a new theme; in all likelihood your old theme went away. This &lt;a href="http://askubuntu.com/questions/59791/how-do-i-fix-my-theme">AskUbuntu&lt;/a> question gave a clue.&lt;/li>
&lt;li>Network Manager stopped working. For some inscrutable reason the default NetworkManager config file &lt;code>/etc/NetworkManager/NetworkManager.conf&lt;/code> has &lt;code>managed=false&lt;/code> for &lt;code>ifupdown&lt;/code>. Flip back to true.&lt;/li>
&lt;li>New window manager, new defaults to dunk you in Unity at least once. Just make sure you pick the right window manager from the little gear icon.&lt;/li>
&lt;li>&lt;code>gnome-power-manager&lt;/code> went away. If you fix icons a not-so-useful icon will show up anyway when you load &lt;code>gnome-settings-daemon&lt;/code>.&lt;/li>
&lt;li>“Waiting for network configuration.” There were lots of suggestions here. My &lt;code>/var/run&lt;/code> and &lt;code>/var/lock&lt;/code> were borked so I &lt;a href="http://uksysadmin.wordpress.com/2011/10/14/upgrade-to-ubuntu-11-10-problem-waiting-for-network-configuration-then-black-screen-solution/">did these instructions&lt;/a>, I also hear that you should punt &lt;code>wlan0&lt;/code> from &lt;code>/etc/network/interfaces&lt;/code> and remove it from &lt;code>/etc/udev/rules.d70-persistent-net.rules&lt;/code>. I also commented out the sleeps in &lt;code>/init/failsafe.conf&lt;/code> for good measure.&lt;/li>
&lt;li>Default GHC is 7.0.3! Blow away your &lt;code>.cabal&lt;/code> (but hold onto &lt;code>.cabal/config&lt;/code>) and go reinstall Haskell Platform. Don’t forget to make sure you install profiling libraries, and grab &lt;code>xmonad&lt;/code> and &lt;code>xmonad-contrib&lt;/code>. Note that previous haskell-platform installs will be rather broken, on account of missing GHC 6 binaries (you can reinstall them, but it looks like they get replaced.)&lt;/li>
&lt;li>ACPI stopped knowing about X, so if you have scripts for handling rotation, source &lt;code>/usr/share/acpi-support/power-funcs&lt;/code> and run &lt;code>getXuser&lt;/code> and &lt;code>getXconsole&lt;/code>&lt;/li>
&lt;li>DBUS didn’t start. This is due to leftover pid and socket files, see &lt;a href="https://bugs.launchpad.net/ubuntu/+source/dbus/+bug/811441">this bug&lt;/a>&lt;/li>
&lt;li>Was mysteriously fscking my root drive on every boot. Check your &lt;code>pass&lt;/code> param in &lt;code>/etc/fstab&lt;/code>; should be &lt;code>0&lt;/code>.&lt;/li>
&lt;li>Redshift mysteriously was being reset by xrandr calls; worked around by calling it oneshot immediately after running xrandr.&lt;/li>
&lt;li>Not sure if this was related to the upgrade, but fixed an annoyance where suspend-checking (in case you are coming out of hibernate) was taking a really long time in boot. Set &lt;code>resume&lt;/code> to right swap in &lt;code>/etc/initramfs-tools/conf.d/resume&lt;/code> and &lt;code>update-initramfs -u&lt;/code> with great prejudice).&lt;/li>
&lt;/ul>
&lt;p>Unresolved annoyances: &lt;a href="https://bugs.launchpad.net/ubuntu/+source/dbus/+bug/812940">X11 autolaunching in DBUS&lt;/a>, the power icon doesn’t always properly show AC information and is too small in stalonetray, xmobar doesn’t support percentage battery and AC coloring simultaneously (I have a patch), a totem built from scratch segfaults.&lt;/p></description></item><item><title>How to read Haskell like Python</title><link>https://blog.ezyang.com/2011/11/how-to-read-haskell/</link><pubDate>Mon, 14 Nov 2011 09:00:26 +0000</pubDate><guid>https://blog.ezyang.com/2011/11/how-to-read-haskell/</guid><description>&lt;p>&lt;strong>tl;dr&lt;/strong> — Save this page for future reference.&lt;/p>
&lt;p>Have you ever been in the situation where you need to quickly understand what a piece of code in some unfamiliar language does? If the language looks a lot like what you’re comfortable with, you can usually guess what large amounts of the code does; even if you may not be completely familiar how all the language features work.&lt;/p>
&lt;p>For Haskell, this is a little more difficult, since Haskell syntax looks very different from traditional languages. But there&amp;rsquo;s no really deep difference here; you just have to squint at it just right. Here is a fast, mostly incorrect, and hopefully useful guide for interpreting Haskell code like a Pythonista. By the end, you should be able to interpret this fragment of Haskell (some code elided with &lt;code>...&lt;/code>):&lt;/p></description></item><item><title>The new Reflections on Trusting Trust</title><link>https://blog.ezyang.com/2011/10/the-new-reflections-on-trusting-trust/</link><pubDate>Fri, 28 Oct 2011 09:00:57 +0000</pubDate><guid>https://blog.ezyang.com/2011/10/the-new-reflections-on-trusting-trust/</guid><description>&lt;p>In his classic essay &lt;a href="http://cm.bell-labs.com/who/ken/trust.html">Reflections on Trusting Trust&lt;/a>, Ken Thompson describes a self-replicating compiler bug which is undetectable by source code inspection. The self-replication is made possible by the fact that most compilers are self-compiling: old versions of a compiler are used to compile new ones, and if the old version is malicious, it can slip the same bug when it detects it is compiling itself.&lt;/p>
&lt;p>A new trend is precisely this self-hosting process, but for &lt;a href="http://research.microsoft.com/en-us/projects/fstar/">self-certifying typecheckers&lt;/a>: typecheckers which are used to prove their own correctness. (Note that these are powerful typecheckers, close to being able to check arbitrary theorems about code.) This may seem a little odd, since I could write a trivial typechecker which always claimed it was correct. In order to work around this, we must bootstrap the correctness proof by proving the typechecker correct in another language (in the case of F*, this language is Coq). Once this has been done, we can then use this verified typechecker to check a specification of itself. This process is illustrated below.&lt;/p></description></item><item><title>Obviously Correct</title><link>https://blog.ezyang.com/2011/10/obviously-correct/</link><pubDate>Mon, 24 Oct 2011 09:00:34 +0000</pubDate><guid>https://blog.ezyang.com/2011/10/obviously-correct/</guid><description>&lt;p>What do automatic memory management, static types and purity have in common? They are methods which take advantage of the fact that we can make programs &lt;em>obviously correct&lt;/em> (for some partial definition of correctness) upon visual inspection. Code using automatic memory management is &lt;em>obviously correct&lt;/em> for a class of memory bugs. Code using static types is &lt;em>obviously correct&lt;/em> for a class of type bugs. Code using purity (no mutable references or side effects) is &lt;em>obviously correct&lt;/em> for a class of concurrency bugs. When I take advantage of any of these techniques, I don’t have to &lt;em>prove&lt;/em> my code has no bugs: it just is, automatically!&lt;/p></description></item><item><title>Polyglot programming</title><link>https://blog.ezyang.com/2011/10/polyglot-programming/</link><pubDate>Wed, 12 Oct 2011 22:22:54 +0000</pubDate><guid>https://blog.ezyang.com/2011/10/polyglot-programming/</guid><description>&lt;p>Being back in town over MIT&amp;rsquo;s &lt;em>Infinite Activities Period&lt;/em> is making me think about what kind of short lecture I want to try teaching. I&amp;rsquo;ve been turning over the idea of a polyglot programming class in my head: the idea is that while most people feel really comfortable with only one or two programming languages, you can learn how to make this knowledge work for you in almost any programming language you could possible language.&lt;/p></description></item><item><title>Why you shouldn't do a PhD in systems</title><link>https://blog.ezyang.com/2011/09/do-not-phd-in-systems/</link><pubDate>Mon, 26 Sep 2011 02:41:39 +0000</pubDate><guid>https://blog.ezyang.com/2011/09/do-not-phd-in-systems/</guid><description>&lt;p>&lt;em>The opinions presented in this post are not necessarily mine. I&amp;rsquo;m just one very confused undergraduate senior with a lot of soul searching to do.&lt;/em>&lt;/p>
&lt;p>When I tell my friends, “I’m going to get a PhD,” I sometimes get the response, “Good for you!” But other times, I get the response, “Why would you want to do that?” as if I was some poor, misguided soul, brainwashed by a society which views research as the “highest calling”, the thing that the best go to, while the rest go join industry. “If you’re a smart hacker and you join industry,” they say, “you will have more fun immediately, making more impact and more money.”&lt;/p></description></item><item><title>Let's play a game</title><link>https://blog.ezyang.com/2011/09/lets-play-a-game/</link><pubDate>Mon, 05 Sep 2011 04:04:46 +0000</pubDate><guid>https://blog.ezyang.com/2011/09/lets-play-a-game/</guid><description>&lt;p>Ever wondered how Haskellers are magically able to figure out the implementation of functions just by looking at their type signature? Well, now you can learn this ability too. Let’s play a game.&lt;/p>
&lt;p>You are an inventor, world renowned for your ability to make machines that transform things into other things. You are a &lt;strong>proposer&lt;/strong>.&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/cont-game/proposer.png" alt="image">&lt;/p>
&lt;p>But there are many who would doubt your ability to invent such things. They are the &lt;strong>verifiers&lt;/strong>.&lt;/p></description></item><item><title>8 ways to report errors in Haskell revisited</title><link>https://blog.ezyang.com/2011/08/8-ways-to-report-errors-in-haskell-revisited/</link><pubDate>Mon, 29 Aug 2011 12:30:02 +0000</pubDate><guid>https://blog.ezyang.com/2011/08/8-ways-to-report-errors-in-haskell-revisited/</guid><description>&lt;p>In 2007, Eric Kidd wrote a quite popular article named &lt;a href="http://www.randomhacks.net/articles/2007/03/10/haskell-8-ways-to-report-errors/">8 ways to report errors in Haskell&lt;/a>. However, it has been four years since the original publication of the article. Does this affect the veracity of the original article? Some names have changed, and some of the original advice given may have been a bit&amp;hellip; dodgy. We’ll take a look at each of the recommendations from the original article, and also propose a new way of conceptualizing all of Haskell’s error reporting mechanisms.&lt;/p></description></item><item><title>Joseph and the Amazing Technicolor Box</title><link>https://blog.ezyang.com/2011/08/joseph-and-the-amazing-technicolor-box/</link><pubDate>Tue, 23 Aug 2011 03:46:58 +0000</pubDate><guid>https://blog.ezyang.com/2011/08/joseph-and-the-amazing-technicolor-box/</guid><description>&lt;p>Consider the following data type in Haskell:&lt;/p>
&lt;pre>&lt;code>data Box a = B a
&lt;/code>&lt;/pre>
&lt;p>How many computable functions of type &lt;code>Box a -&amp;gt; Box a&lt;/code> are there? If we strictly use denotational semantics, there are seven:&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/technicolor.png" alt="image">&lt;/p>
&lt;p>But if we furthermore distinguish the &lt;em>source&lt;/em> of the bottom (a very operational notion), some functions with the same denotation have more implementations&amp;hellip;&lt;/p>
&lt;ol>
&lt;li>&lt;em>Irrefutable pattern match:&lt;/em> &lt;code>f ~(B x) = B x&lt;/code>. No extras.&lt;/li>
&lt;li>&lt;em>Identity:&lt;/em> &lt;code>f b = b&lt;/code>. No extras.&lt;/li>
&lt;li>&lt;em>Strict:&lt;/em> &lt;code>f (B !x) = B x&lt;/code>. No extras.&lt;/li>
&lt;li>&lt;em>Constant boxed bottom:&lt;/em> Three possibilities: &lt;code>f _ = B (error &amp;quot;1&amp;quot;)&lt;/code>; &lt;code>f b = B (case b of B _ -&amp;gt; error &amp;quot;2&amp;quot;)&lt;/code>; and &lt;code>f b = B (case b of B !x -&amp;gt; error &amp;quot;3&amp;quot;)&lt;/code>.&lt;/li>
&lt;li>&lt;em>Absent:&lt;/em> Two possibilities: &lt;code>f (B _) = B (error &amp;quot;4&amp;quot;)&lt;/code>; and &lt;code>f (B x) = B (x `seq` error &amp;quot;5&amp;quot;)&lt;/code>.&lt;/li>
&lt;li>&lt;em>Strict constant boxed bottom:&lt;/em> &lt;code>f (B !x) = B (error &amp;quot;6&amp;quot;)&lt;/code>.&lt;/li>
&lt;li>&lt;em>Bottom:&lt;/em> Three possibilities: &lt;code>f _ = error &amp;quot;7&amp;quot;&lt;/code>; &lt;code>f (B _) = error &amp;quot;8&amp;quot;&lt;/code>; and &lt;code>f (B !x) = error &amp;quot;9&amp;quot;&lt;/code>.&lt;/li>
&lt;/ol>
&lt;p>List was ordered by colors of the rainbow. If this was hieroglyphics to you, may I interest you in &lt;a href="http://blog.ezyang.com/2010/12/gin-and-monotonic/">this blog post?&lt;/a>&lt;/p></description></item><item><title>Diskless Paxos crash recovery</title><link>https://blog.ezyang.com/2011/08/diskless-paxos-crash-recovery/</link><pubDate>Sun, 14 Aug 2011 00:41:30 +0000</pubDate><guid>https://blog.ezyang.com/2011/08/diskless-paxos-crash-recovery/</guid><description>&lt;p>&lt;em>This is an edited version of an email I sent last week. Unfortunately, it does require you to be familiar with the original Paxos correctness proof, so I haven’t even tried to expand it into something appropriate for a lay audience. The algorithm is probably too simple to be in the literature, except maybe informally mentioned—however, if it is wrong, I would love to know, since real code depends on it.&lt;/em>&lt;/p></description></item><item><title>First impressions of module programming</title><link>https://blog.ezyang.com/2011/08/first-impressions-of-module-programming/</link><pubDate>Fri, 05 Aug 2011 09:00:21 +0000</pubDate><guid>https://blog.ezyang.com/2011/08/first-impressions-of-module-programming/</guid><description>&lt;p>During my time at Jane Street, I’ve done a fair bit of programming involving modules. I’ve touched functors, type and module constraints, modules in modules, even first class modules (though only peripherally). Unfortunately, the chapter on modules in &lt;em>Advanced Topics in Types and Programming Languages&lt;/em> made my eyes glaze over, so I can’t really call myself &lt;em>knowledgeable&lt;/em> in module systems yet, but I think I have used them enough to have a few remarks about them. (All remarks about convention should be taken to be indicative of Jane Street style. Note: they’ve &lt;a href="http://ocaml.janestreet.com/?q=node/13">open sourced&lt;/a> a bit of their software, if you actually want to look at some of the stuff I’m talking about.)&lt;/p></description></item><item><title>In-program GC stats redux</title><link>https://blog.ezyang.com/2011/08/in-program-gc-stats-redux/</link><pubDate>Wed, 03 Aug 2011 09:00:08 +0000</pubDate><guid>https://blog.ezyang.com/2011/08/in-program-gc-stats-redux/</guid><description>&lt;p>Hac Phi was quite productive (since I managed to get two blog posts out of it!) On Saturday I committed a new module &lt;code>GHC.Stats&lt;/code> to base which implemented a modified subset of &lt;a href="http://blog.ezyang.com/2011/07/in-program-gc-stats-for-ghc/">the API I proposed previously.&lt;/a> Here is the API; to use it you’ll need to compile GHC from Git. Please test and let me know if things should get changed or clarified!&lt;/p>
&lt;pre>&lt;code>-- | Global garbage collection and memory statistics.
data GCStats = GCStats
 { bytes_allocated :: Int64 -- ^ Total number of bytes allocated
 , num_gcs :: Int64 -- ^ Number of garbage collections performed
 , max_bytes_used :: Int64 -- ^ Maximum number of live bytes seen so far
 , num_byte_usage_samples :: Int64 -- ^ Number of byte usage samples taken
 -- | Sum of all byte usage samples, can be used with
 -- 'num_byte_usage_samples' to calculate averages with
 -- arbitrary weighting (if you are sampling this record multiple
 -- times).
 , cumulative_bytes_used :: Int64
 , bytes_copied :: Int64 -- ^ Number of bytes copied during GC
 , current_bytes_used :: Int64 -- ^ Current number of live bytes
 , current_bytes_slop :: Int64 -- ^ Current number of bytes lost to slop
 , max_bytes_slop :: Int64 -- ^ Maximum number of bytes lost to slop at any one time so far
 , peak_megabytes_allocated :: Int64 -- ^ Maximum number of megabytes allocated
 -- | CPU time spent running mutator threads. This does not include
 -- any profiling overhead or initialization.
 , mutator_cpu_seconds :: Double
 -- | Wall clock time spent running mutator threads. This does not
 -- include initialization.
 , mutator_wall_seconds :: Double
 , gc_cpu_seconds :: Double -- ^ CPU time spent running GC
 , gc_wall_seconds :: Double -- ^ Wall clock time spent running GC
 -- | Number of bytes copied during GC, minus space held by mutable
 -- lists held by the capabilities. Can be used with
 -- 'par_max_bytes_copied' to determine how well parallel GC utilized
 -- all cores.
 , par_avg_bytes_copied :: Int64
 -- | Sum of number of bytes copied each GC by the most active GC
 -- thread each GC. The ratio of 'par_avg_bytes_copied' divided by
 -- 'par_max_bytes_copied' approaches 1 for a maximally sequential
 -- run and approaches the number of threads (set by the RTS flag
 -- @-N@) for a maximally parallel run.
 , par_max_bytes_copied :: Int64
 } deriving (Show, Read)

-- | Retrieves garbage collection and memory statistics as of the last
-- garbage collection. If you would like your statistics as recent as
-- possible, first run a 'performGC' from &amp;quot;System.Mem&amp;quot;.
getGCStats :: IO GCStats
&lt;/code>&lt;/pre></description></item><item><title>Changes to IntMap</title><link>https://blog.ezyang.com/2011/08/changes-to-intmap/</link><pubDate>Mon, 01 Aug 2011 09:00:27 +0000</pubDate><guid>https://blog.ezyang.com/2011/08/changes-to-intmap/</guid><description>&lt;p>As it stands, it is impossible to define certain value-strict operations on &lt;a href="http://hackage.haskell.org/packages/archive/containers/0.4.0.0/doc/html/Data-IntMap.html">IntMaps&lt;/a> with the current containers API. The reader is invited, for example, to try efficiently implementing &lt;code>map :: (a -&amp;gt; b) -&amp;gt; IntMap a -&amp;gt; IntMap b&lt;/code>, in such a way that for a non-bottom and non-empty map &lt;code>m&lt;/code>, &lt;code>Data.IntMap.map (\_ -&amp;gt; undefined) m == undefined&lt;/code>.&lt;/p>
&lt;p>Now, we could have just added a lot of apostrophe suffixed operations to the existing API, which would have greatly blown it up in size, but &lt;a href="http://www.haskell.org/pipermail/libraries/2011-May/016362.html">following conversation on libraries@haskell.org&lt;/a>, we’ve decided we will be splitting up the module into two modules: &lt;code>Data.IntMap.Strict&lt;/code> and &lt;code>Data.IntMap.Lazy&lt;/code>. For backwards compatibility, &lt;code>Data.IntMap&lt;/code> will be the lazy version of the module, and the current value-strict functions residing in this module will be deprecated.&lt;/p></description></item><item><title>Food-related functional humor</title><link>https://blog.ezyang.com/2011/07/food-related-functional-humor/</link><pubDate>Fri, 29 Jul 2011 09:00:18 +0000</pubDate><guid>https://blog.ezyang.com/2011/07/food-related-functional-humor/</guid><description>&lt;p>Fall is coming, and with it come hoards of ravenous Freshmen arriving on MIT’s campus. I’ll be doing three food events&amp;hellip; all of them functional programming puns. Whee!&lt;/p>
&lt;h3 id="dumpling-hylomorphism" id="dumpling-hylomorphism">
 &lt;a class="heading-link" href="https://blog.ezyang.com/2011/07/food-related-functional-humor/#dumpling-hylomorphism">Dumpling Hylomorphism&lt;span class="heading-anchor" aria-label="Anchor">¶&lt;/span>&lt;/a>
&lt;/h3>
&lt;p>Anamorphism: the building up of a structure. Catamorphism: the consumption of a structure. Hylomorphism: both an anamorphism and a catamorphism. This event? A hylomorphism on dumplings. Come learn the basic fold, or just perform a metabolic reduction on food.&lt;/p></description></item><item><title>BlockedIndefinitelyOnMVar</title><link>https://blog.ezyang.com/2011/07/blockedindefinitelyonmvar/</link><pubDate>Wed, 27 Jul 2011 09:00:08 +0000</pubDate><guid>https://blog.ezyang.com/2011/07/blockedindefinitelyonmvar/</guid><description>&lt;p>&lt;em>This post was adapted from a post I made to the glasgow-haskell-users list.&lt;/em>&lt;/p>
&lt;p>According to &lt;a href="http://haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/Control-Exception.html#t%3ABlockedIndefinitelyOnMVar">Control.Exception&lt;/a>, the &lt;code>BlockedIndefinitelyOnMVar&lt;/code> exception (and related exception &lt;code>BlockedIndefinitelyOnSTM&lt;/code>) is thrown when “the thread is blocked on an MVar, but there are no other references to the MVar so it can&amp;rsquo;t ever continue.” The description is actually reasonably precise, but it is easy to misinterpret. Fully understanding how this exception works requires some extra documentation from &lt;a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Concurrent.html">Control.Concurrent&lt;/a> as well as an intuitive feel for how garbage collection in GHC works with respects to Haskell’s green threads.&lt;/p></description></item><item><title>From data type definitions to code</title><link>https://blog.ezyang.com/2011/07/data-type-definitions-to-code/</link><pubDate>Mon, 25 Jul 2011 09:00:48 +0000</pubDate><guid>https://blog.ezyang.com/2011/07/data-type-definitions-to-code/</guid><description>&lt;p>What do these problems have in common: recursive equality/ordering checks, printing string representations, serializing/unserializing binary protocols, hashing, generating getters/setters? They are repetitive boilerplate pieces of code that have a strong dependence on the structure of the data they operate over. Since programmers love automating things away, various schools of thought have emerged on how to do this:&lt;/p>
&lt;ol>
&lt;li>Let your IDE generate this boilerplate for you. You right-click on the context menu, click “Generate &lt;code>hashCode()&lt;/code>”, and your IDE does the necessary program analysis for you;&lt;/li>
&lt;li>Create a custom metadata format (usually XML), which you then run another program on which converts this description into code;&lt;/li>
&lt;li>Add sufficiently strong macro/higher-order capabilities to your language, so you can write programs which generate implementations in-program;&lt;/li>
&lt;li>Add sufficiently strong reflective capabilities to your language, so you can write a fully generic dynamic implementation for this functionality;&lt;/li>
&lt;li>Be a compiler and do static analysis over abstract syntax trees in order to figure out how to implement the relevant operations.&lt;/li>
&lt;/ol>
&lt;p>It hadn’t struck me how prevalent the fifth option was until I ran into wide scale use of one particular facet of the &lt;a href="http://caml.inria.fr/pub/old_caml_site/camlp4/index.html">camlp4&lt;/a> system. While it describes itself as a “macro system,” in &lt;a href="http://caml.inria.fr/cgi-bin/hump.en.cgi?contrib=474">sexplib&lt;/a> and &lt;a href="http://caml.inria.fr/cgi-bin/hump.en.cgi?contrib=642">bin-prot&lt;/a>, the macros being used are not those of the C tradition (which would be good for implementing 3), rather, they are in the Lisp tradition, including access to the full syntax tree of OCaml and the ability to modify OCaml’s grammar. Unlike most Lisps, however, camlp4 has access to the abstract syntax tree of &lt;em>data type definitions&lt;/em> (in untyped languages these are usually implicit), which it can use to transform into code.&lt;/p></description></item><item><title>Variant types and GADTs</title><link>https://blog.ezyang.com/2011/07/variant-types-and-gadts/</link><pubDate>Fri, 22 Jul 2011 09:00:21 +0000</pubDate><guid>https://blog.ezyang.com/2011/07/variant-types-and-gadts/</guid><description>&lt;p>OCaml supports anonymous variant types, of the form &lt;code>type a = [`Foo of int | `Bar of bool]&lt;/code>, with the appropriate subtyping relations. Subtyping is, in general, kind of tricky, so I have been using these variant types fairly conservatively. (Even if a feature gives you too much rope, it can be manageable and useful if you use discipline.) Indeed, they are remarkably handy for one particular use-case for which I would have normally deployed GADTs. This is the “Combining multiple sum types into a single sum type” use-case.&lt;/p></description></item><item><title>In-program GC stats for GHC</title><link>https://blog.ezyang.com/2011/07/in-program-gc-stats-for-ghc/</link><pubDate>Wed, 20 Jul 2011 09:00:00 +0000</pubDate><guid>https://blog.ezyang.com/2011/07/in-program-gc-stats-for-ghc/</guid><description>&lt;p>I’ll be at this year’s &lt;a href="http://www.haskell.org/haskellwiki/Hac_%CF%86">Hac Phi&lt;/a> (coming up in a week and a half), and I am planning on working on in-program garbage collector statistics for GHC. There is nothing really technically difficult about this task (we just need to expose some functions in the RTS), but it’s not been done yet and I know quite a few performance-minded and long-running-server-minded folks who would love to see this functionality.&lt;/p>
&lt;p>My question for you is this: what would you like such an API to look like? What things should it offer, how would you like to interact with it?&lt;/p></description></item><item><title>Synthetic Git merges</title><link>https://blog.ezyang.com/2011/07/synthetic-git-merges/</link><pubDate>Mon, 18 Jul 2011 09:00:14 +0000</pubDate><guid>https://blog.ezyang.com/2011/07/synthetic-git-merges/</guid><description>&lt;p>In theory, Git supports custom, low-level merge drivers with the &lt;code>merge&lt;/code> configuration properties. In practice, no one actually wants to write their own merge driver from scratch. Well, for many cases where a custom merge driver would come in handy, you don’t have to write your merge driver from scratch! Consider these cases:&lt;/p>
&lt;ul>
&lt;li>You want to merge files which have differing newline styles,&lt;/li>
&lt;li>You want to merge files where one had lots of trailing whitespace removed,&lt;/li>
&lt;li>You want to merge files one branch has replaced certain strings with custom strings (for example, a configuration file which instantiated &lt;code>PASSWORD&lt;/code>, or a file that needs to be anonymized if there is a merge conflict),&lt;/li>
&lt;li>You want to merge a binary file that has a stable textual format, or&lt;/li>
&lt;li>You want to merge with knowledge about specific types of conflicts and how to resolve them (a super-smart &lt;code>rerere&lt;/code>).&lt;/li>
&lt;/ul>
&lt;p>For all of these cases, you can instead perform a &lt;em>synthetic Git merge&lt;/em> by modifying the input files (constructing synthetic merge inputs), calling Git’s &lt;code>git merge-file&lt;/code> to do the actual merge, and then possibly editing the result, before handing it back off to the original invoker of your merge driver. It’s really simple. Here’s an example driver that handles files with differing newline styles by canonicalizing them to UNIX:&lt;/p></description></item><item><title>Parallelism to plug space leaks</title><link>https://blog.ezyang.com/2011/07/parallelism-to-plug-space-leaks/</link><pubDate>Fri, 15 Jul 2011 09:00:26 +0000</pubDate><guid>https://blog.ezyang.com/2011/07/parallelism-to-plug-space-leaks/</guid><description>&lt;p>It is &lt;a href="http://blog.ezyang.com/2010/11/is-multiply-carry-strongly-universal/">not too difficult (scroll to “Non sequitur”)&lt;/a> to create a combinator which combines two folds into a single fold that operates on a single input list in one pass. This is pretty important if your input list is pretty big, since doing the folds separately could result in a space leak, as might be seen in the famous “average” space leak:&lt;/p>
&lt;pre>&lt;code>import Data.List
big = [1..10000000]
sum' = foldl' (+) 0
average xs = fromIntegral (sum' xs) / fromIntegral (length xs)
main = print (average big)
&lt;/code>&lt;/pre>
&lt;p>(I’ve redefined &lt;code>sum&lt;/code> so we don’t stack overflow.) I used to think combining functions for folds were pretty modular, since they had a fairly regular interface, could be combined together, and really represented the core notion of when it was possible to eliminate such a space leak: obviously, if you have two functions that require random access to elements of the list, they’ll retain the entirety of it all the way through.&lt;/p></description></item><item><title>Facebook support for BarnOwl</title><link>https://blog.ezyang.com/2011/07/facebook-support-for-barnowl/</link><pubDate>Wed, 13 Jul 2011 09:00:15 +0000</pubDate><guid>https://blog.ezyang.com/2011/07/facebook-support-for-barnowl/</guid><description>&lt;p>This one&amp;rsquo;s for the MIT crowd. This morning, I finished my &lt;a href="https://github.com/ezyang/barnowl">Facebook module for BarnOwl&lt;/a> to my satisfaction (my satisfaction being asynchronous support for Facebook API calls, i.e. no more random freezing!) Getting it to run on Linerva was a bit involved, however, so here is the recipe.&lt;/p>
&lt;ol>
&lt;li>Setup a local CPAN installation using the &lt;a href="http://sipb.mit.edu/doc/cpan/">instructions at sipb.mit.edu&lt;/a>, using &lt;code>local::lib&lt;/code>. Don’t forget to add the setup code to &lt;code>.bashrc.mine&lt;/code>, not &lt;code>.bashrc&lt;/code>, and then source them. Don&amp;rsquo;t forget to follow prerequisites: otherwise, CPAN will give a lot of prompts.&lt;/li>
&lt;li>Install all of the CPAN dependencies you need. For the Facebook module, this means &lt;code>Facebook::Graph&lt;/code> and &lt;code>AnyEvent::HTTP&lt;/code>. I suggest using &lt;code>notest&lt;/code>, since &lt;code>Any::Moose&lt;/code> seems to fail a harmless test on Linerva. &lt;code>Facebook::Graph&lt;/code> fails several tests, but don&amp;rsquo;t worry about it since we&amp;rsquo;ll be using a pre-packaged version. If you want to use other modules, you will need to install them in CPAN as well.&lt;/li>
&lt;li>Clone BarnOwl to a local directory (&lt;code>git clone git://github.com/ezyang/barnowl.git barnowl&lt;/code>), &lt;code>./autogen.sh&lt;/code>, &lt;code>configure&lt;/code> and &lt;code>make&lt;/code>.&lt;/li>
&lt;li>Run using &lt;code>./barnowl&lt;/code>, and then type the command &lt;code>:facebook-auth&lt;/code> and follow the instructions!&lt;/li>
&lt;/ol>
&lt;p>Happy Facebooking!&lt;/p></description></item><item><title>Grad School, Oh My</title><link>https://blog.ezyang.com/2011/07/grad-school-oh-my/</link><pubDate>Mon, 11 Jul 2011 09:00:07 +0000</pubDate><guid>https://blog.ezyang.com/2011/07/grad-school-oh-my/</guid><description>&lt;p>It still feels a little strange how this happened. Not a year ago, I was pretty sure I was going to do the Masters of Engineering program at MIT, to make up for a “missed year” that was spent abroad (four years at MIT plus one at Cambridge, not a bad deal.)&lt;/p>
&lt;p>But a combination of conversations with various researchers whom I greatly respect, nagging from my Dad, and an inability to really figure out who I would actually do my Master’s thesis under while at MIT meant that at some point about a month and a half ago, I decided to go for the graduate school admissions cycle this fall. Oh my. It feels like undergraduate admissions all over again (which was not really a pleasant experience), though this time around, what I need to write is the “Research Statement.”&lt;/p></description></item><item><title>Cambridge retrospective: History and Philosophy of Science</title><link>https://blog.ezyang.com/2011/07/cambridge-hps/</link><pubDate>Fri, 08 Jul 2011 09:00:02 +0000</pubDate><guid>https://blog.ezyang.com/2011/07/cambridge-hps/</guid><description>&lt;p>I recently concluded a year long study-abroad program at the University of Cambridge. You can read my &lt;a href="http://blog.ezyang.com/2010/10/why-i-m-in-cambridge/">original reasons and first impressions here&lt;/a>.&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/hps/basket.png" alt="image">&lt;/p>
&lt;p>It is the Sunday before the beginning of exams, and the weather is spectacular. Most students (except perhaps the pure historians) are dourly inside, too busy revising to take advantage of it. But I am thrust out of my den, constructed of piles of notes and past exam questions, in order to go to one final revision with our history supervisor, Mirjam. I cycle down Grange road, park my bicycle outside Ridley Hall, and am greeted to a pleasant surprise: Mirjam has elected to hold the revision outside on a cluster of park benches flanked everywhere by grass and trees, and has brought a wickerbasket containing fresh fruit, small cupcakes and other treats, and also sparkling wine and beer (perhaps not the best drink for what is ostensibly a revision, but we avail ourselves of it anyway.)&lt;/p></description></item><item><title>A new vision for Mendeley</title><link>https://blog.ezyang.com/2011/07/a-new-vision-for-mendeley/</link><pubDate>Wed, 06 Jul 2011 09:00:54 +0000</pubDate><guid>https://blog.ezyang.com/2011/07/a-new-vision-for-mendeley/</guid><description>&lt;p>&lt;a href="http://blog.ezyang.com/2010/11/reflexivity-qed/">I use Mendeley&lt;/a> because it lets me easily search for papers I care about. Unfortunately, that seems to be all Mendeley has been doing for me&amp;hellip; and that’s a damn shame. Maybe it’s because I’m an undergraduate, still dipping my toe into an ocean of academic research. Mendeley was aimed at practicing researchers, but not people like me, who are stilll aiming for breadth not depth. I can count on two hands the number of technical papers I’ve really dug into—I’m trying to figure out what it is exactly that I want to specialize in.&lt;/p></description></item><item><title>IVar leaks</title><link>https://blog.ezyang.com/2011/07/ivar-leaks/</link><pubDate>Mon, 04 Jul 2011 09:00:17 +0000</pubDate><guid>https://blog.ezyang.com/2011/07/ivar-leaks/</guid><description>&lt;p>&lt;img src="https://blog.ezyang.com/img/ivar-leak/flow.png" alt="image">&lt;/p>
&lt;p>The first thing to convince yourself of is that there actually is a problem with &lt;a href="http://blog.ezyang.com/2011/07/scheduling-ivar/">the code I posted last week.&lt;/a> Since this is a memory leak, we need to keep track of &lt;em>creations&lt;/em> and &lt;em>accesses&lt;/em> of IVars. An IVar allocation occurs in the following cases for our example:&lt;/p>
&lt;ol>
&lt;li>Invocation of &lt;code>return&lt;/code>, which returns a full IVar,&lt;/li>
&lt;li>Invocation of &lt;code>tick&lt;/code>, which returns an empty IVar and schedules a thread to fill this IVar, and&lt;/li>
&lt;li>Invocation of &lt;code>&amp;gt;&amp;gt;=&lt;/code>, which returns an empty IVar and a reference to this IVar in the callback attached to the left-hand IVar.&lt;/li>
&lt;/ol>
&lt;p>An IVar access occurs when we dereference an IORef, add a callback or fill the IVar. This occurs in these cases:&lt;/p></description></item><item><title>Scheduling IVars</title><link>https://blog.ezyang.com/2011/07/scheduling-ivar/</link><pubDate>Fri, 01 Jul 2011 09:00:20 +0000</pubDate><guid>https://blog.ezyang.com/2011/07/scheduling-ivar/</guid><description>&lt;p>One downside to the stupid scheduler I mentioned in the previous &lt;a href="http://blog.ezyang.com/2011/06/the-iva-monad/">IVar monad post&lt;/a> was that it would easily stack overflow, since it stored all pending operations on the stack. We can explicitly move all of these pending callbacks to the heap by reifying the execution schedule. This involves adding &lt;code>Schedule&lt;/code> state to our monad (I’ve done so with &lt;code>IORef Schedule&lt;/code>). Here is a only slightly more clever scheduler (I&amp;rsquo;ve also simplified some bits of code, and added a new &lt;code>addCallback&lt;/code> function):&lt;/p></description></item><item><title>The IVar monad</title><link>https://blog.ezyang.com/2011/06/the-iva-monad/</link><pubDate>Wed, 29 Jun 2011 08:57:31 +0000</pubDate><guid>https://blog.ezyang.com/2011/06/the-iva-monad/</guid><description>&lt;p>An IVar is an &lt;a href="http://blog.ezyang.com/2011/05/reified-laziness/">immutable variable&lt;/a>; you write once, and read many times. In the &lt;code>Par&lt;/code> monad framework, we use a prompt monad style construction in order to encode various operations on IVars, which deterministic parallel code in this framework might use. The question I&amp;rsquo;m interested in this post is an alternative encoding of this functionality, which supports nondeterministic concurrency and shows up in other contexts such as Python Twisted, node.js, any JavaScript UI library and LWT. &lt;a href="http://amix.dk/blog/post/19509">Numerous bloggers&lt;/a> &lt;a href="http://matthew.yumptious.com/2009/04/javascript/dojo-deferred-is-a-monad/">have commented&lt;/a> &lt;a href="http://www.reddit.com/r/programming/comments/mjcf/the_monad_laws/cmobm">on this&lt;/a>. But despite all of the monad mania surrounding what are essentially glorified callbacks, no one actually &lt;em>uses&lt;/em> this monad when it comes to Haskell. Why not? For one reason, Haskell has cheap and cheerful preemptive green threads, so we can write our IO in synchronous style in lots of threads. But another reason, which I will be exploring in a later blog post, is that naively implementing bind in this model space leaks! (Most event libraries have worked around this bug in some way or another, which we will also be investigating.)&lt;/p></description></item><item><title>Debugging compilers with optimization fuel</title><link>https://blog.ezyang.com/2011/06/debugging-compilers-with-optimization-fuel/</link><pubDate>Mon, 27 Jun 2011 09:00:49 +0000</pubDate><guid>https://blog.ezyang.com/2011/06/debugging-compilers-with-optimization-fuel/</guid><description>&lt;p>Today I would like to describe how I pin down compiler bugs, specifically, bugs tickled by optimizations, using a neat feature that Hoopl has called &lt;em>optimization fuel.&lt;/em> Unfortunately, this isn’t a particularly Googleable term, so hopefully this post will get some Google juice too. Optimization fuel was originally introduced by David Whalley in 1994 in a paper &lt;em>Automatic isolation of compiler errors.&lt;/em> The basic idea is that all optimizations performed by the compiler can be limited (e.g. by limiting the fuel), so when we suspect the optimizer is misbehaving, we binary search to find the maximum amount of fuel we can give the compiler before it introduces the bug. We can then inspect the offending optimization and fix the bug. Optimization fuel is a feature of the new code generator, and is only available if you pass &lt;code>-fuse-new-codegen&lt;/code> to GHC.&lt;/p></description></item><item><title>Multi-monitor xmobar placement on Gnome</title><link>https://blog.ezyang.com/2011/06/multi-monitor-xmobar-placement-on-nome/</link><pubDate>Fri, 24 Jun 2011 09:00:57 +0000</pubDate><guid>https://blog.ezyang.com/2011/06/multi-monitor-xmobar-placement-on-nome/</guid><description>&lt;p>This post describes how to change which monitor xmobar shows up on in a multi-monitor setup. This had always been an annoyance for me, since on an initial switch to multi-monitor, xmobar would be living on the correct monitor, but if I ever restarted XMonad thereafter, it would migrate to my other monitor, much to my annoyance. Note that a monitor is different from an X screen, which &lt;em>can&lt;/em> be directly configured from xmobar using the &lt;code>-x&lt;/code> command line.&lt;/p></description></item><item><title>A Year of Notebooking (Part 2)</title><link>https://blog.ezyang.com/2011/06/a-year-of-notebooking-part-2/</link><pubDate>Wed, 22 Jun 2011 09:00:50 +0000</pubDate><guid>https://blog.ezyang.com/2011/06/a-year-of-notebooking-part-2/</guid><description>&lt;p>This is notebook two.&lt;/p>
&lt;h3 id="max-schäfer-refactoring-java" id="max-schäfer-refactoring-java">
 &lt;a class="heading-link" href="https://blog.ezyang.com/2011/06/a-year-of-notebooking-part-2/#max-sch%c3%a4fer-refactoring-java">Max Schäfer: Refactoring Java&lt;span class="heading-anchor" aria-label="Anchor">¶&lt;/span>&lt;/a>
&lt;/h3>
&lt;p>Most Java refactoring tools built into IDEs like Eclipse are little more than glorified text manipulation macros. There are no guarantees that the result of your refactoring will have the same behavior as the original: you can even refactor code that doesn’t even compile! To prevent this, most refactorings require heavy and hard-to-understand preconditions for refactoring. Max brings two ideas to the table:&lt;/p></description></item><item><title>A Year of Notebooking (Part 1)</title><link>https://blog.ezyang.com/2011/06/a-year-of-notebooking-part-1/</link><pubDate>Mon, 20 Jun 2011 09:13:29 +0000</pubDate><guid>https://blog.ezyang.com/2011/06/a-year-of-notebooking-part-1/</guid><description>&lt;p>Over the year, I’ve accumulated three notebooks worth of miscellaneous notes and musings. Since these notebooks are falling apart, I’ve decided to transfer their contents here. Warning: they might be slightly incoherent! This is the first of three notebooks. I recommend skimming the section headers and seeing if any of them pop out.&lt;/p>
&lt;h3 id="tony-hoare-abstract-separation-algebra" id="tony-hoare-abstract-separation-algebra">
 &lt;a class="heading-link" href="https://blog.ezyang.com/2011/06/a-year-of-notebooking-part-1/#tony-hoare-abstract-separation-algebra">Tony Hoare: Abstract Separation Algebra&lt;span class="heading-anchor" aria-label="Anchor">¶&lt;/span>&lt;/a>
&lt;/h3>
&lt;p>Tony Hoare wants to leverage “the hard work [that] is already solved” by placing the formalism of separation logic (e.g. Hoare triples) into an abstract algebra. The idea is that by encoding things in pairs, not triples, we can take advantage of the numerous results in algebra. The basic idea is we take a traditional triple &lt;code>{p} q {r}&lt;/code> and convert it into a ordered semigroup relation &lt;code>p; q &amp;lt;= r&lt;/code>, where &lt;code>;&lt;/code> is a monoidal operation. In the end we end up with a separation algebra, which is a monoidal lattice with an extra star operator. The choice of axioms is all: “This is abstract algebra, so you should be willing to take these axioms without having any model in mind.” (Scribbled here: “Inception as a metaphor for mathematical multi-level thinking.”) We have a homomorphism (not isomorphism) between implementations and specifications (the right direction is simplification, the left direction is a Galois connection.) In fact, as a commenter in the audience points out, this is known as the Stone Dualities—something like how two points determine a line—with contravariant points and properties. I believe Tony’s been thinking about this topic a bit since I went to this talk at the very beginning of this year, so its likely some or all of this has been superseded by later discoveries. C&amp;rsquo;est la vie!&lt;/p></description></item><item><title>A pattern for increasing sharing</title><link>https://blog.ezyang.com/2011/06/a-pattern-for-increasing-sharing/</link><pubDate>Fri, 17 Jun 2011 12:55:32 +0000</pubDate><guid>https://blog.ezyang.com/2011/06/a-pattern-for-increasing-sharing/</guid><description>&lt;p>I recently encountered the following pattern while writing some Haskell code, and was surprised to find there was not really any support for it in the standard libraries. I don’t know what it’s called (neither did Simon Peyton-Jones, when I mentioned it to him), so if someone does know, please shout out. The pattern is this: many times an endomorphic map (the map function is &lt;code>a -&amp;gt; a&lt;/code>) will not make very many changes to the underlying data structure. If we implement the map straight-forwardly, we will have to reconstruct the entire spine of the recursive data structure. However, if we use instead the function &lt;code>a -&amp;gt; Maybe a&lt;/code>, we can reuse old pieces of the map if there were no changes to it. (Regular readers of my blog may recognize this situation from &lt;a href="http://blog.ezyang.com/2011/06/pinpointing-space-leaks-in-big-programs/">this post.&lt;/a>) So what is such an alternative map &lt;code>(a -&amp;gt; Maybe a) -&amp;gt; f a -&amp;gt; Maybe (f a)&lt;/code> called?&lt;/p></description></item><item><title>On type synonyms</title><link>https://blog.ezyang.com/2011/06/on-type-synonyms/</link><pubDate>Wed, 15 Jun 2011 12:22:05 +0000</pubDate><guid>https://blog.ezyang.com/2011/06/on-type-synonyms/</guid><description>&lt;p>I recently had to remove a number of type synonyms from the GHC code base which were along the lines of &lt;code>type CmmActuals = [CmmActual]&lt;/code>. The process made me wonder a little about &lt;em>when&lt;/em> type synonyms are appropriate for Haskell code. The &lt;a href="http://en.wikibooks.org/wiki/Haskell/Type_declarations">Wikibooks article&lt;/a> says type synonyms are “for making the roles of types clearer or providing an alias to, for instance, a complicated list or tuple type” and &lt;a href="http://learnyouahaskell.com/making-our-own-types-and-typeclasses">Learn You a Haskell&lt;/a> says they “make more sense to someone reading our code and documentation.” But under what circumstances is this actually true?&lt;/p></description></item><item><title>A Taxonomy of Socialization on the Internet</title><link>https://blog.ezyang.com/2011/06/taxonomy-of-socialization-on-the-internet/</link><pubDate>Mon, 13 Jun 2011 11:19:01 +0000</pubDate><guid>https://blog.ezyang.com/2011/06/taxonomy-of-socialization-on-the-internet/</guid><description>&lt;p>There’s &lt;em>networking&lt;/em>, and then there’s &lt;em>socialization.&lt;/em> Networking is establishing the link, knowing how to find and talk to the person if the need arises. Socialization is communication for the sake of communication; it strengthens networks and keeps people in touch. In many ways, it is the utility a social networking site provides. Trouble is, there are so many different ways to communicate on the Internet these days. In this blog post, I try to explain the essential differences of socialization over the Internet. I believe what is called &lt;em>one-to-many socialization&lt;/em> is the fundamental characteristic of the newest social patterns (facilitated by Facebook and Twitter), and describe some of the challenges in designing methods for consuming and aggregating this information.&lt;/p></description></item><item><title>Pinpointing space leaks in big programs</title><link>https://blog.ezyang.com/2011/06/pinpointing-space-leaks-in-big-programs/</link><pubDate>Fri, 10 Jun 2011 09:00:53 +0000</pubDate><guid>https://blog.ezyang.com/2011/06/pinpointing-space-leaks-in-big-programs/</guid><description>&lt;p>What is the biggest possible Haskell program that you could try debugging a space leak in? One very good choice is GHC, weighing in nearly a 100k lines of code (though, thankfully, 25% of that figure is comments.) Today, I’m going to describe one such space leak that I have fixed in GHC. This is not a full story: my code was ultimately the culprit, so not covered is how to debug code you did not write. However, I still like to think this story will cover some of the major points:&lt;/p></description></item><item><title>Measurement, quantification and reduction</title><link>https://blog.ezyang.com/2011/06/measurement-quantification-and-reduction/</link><pubDate>Wed, 08 Jun 2011 09:00:26 +0000</pubDate><guid>https://blog.ezyang.com/2011/06/measurement-quantification-and-reduction/</guid><description>&lt;p>Today we continue the theme, “What can Philosophy of Science say for Software Engineering,” by looking at some topics taken from the Philosophy of Physical Sciences.&lt;/p>
&lt;h3 id="measurement-and-quantification" id="measurement-and-quantification">
 &lt;a class="heading-link" href="https://blog.ezyang.com/2011/06/measurement-quantification-and-reduction/#measurement-and-quantification">Measurement and quantification&lt;span class="heading-anchor" aria-label="Anchor">¶&lt;/span>&lt;/a>
&lt;/h3>
&lt;p>Quantification is an activity that is embedded in modern society. We live by numbers, whether they are temperature readings, velocity, points of IQ, college rankings, safety ratings, etc. Some of these are uncontroversial, others, very much so, and a software engineer must always be careful about numbers they deal in, for quantification is a very tricky business.&lt;/p></description></item><item><title>What Philosophy of Science Can Say for Software Engineers</title><link>https://blog.ezyang.com/2011/06/philosophy-of-software-engineering/</link><pubDate>Mon, 06 Jun 2011 09:00:05 +0000</pubDate><guid>https://blog.ezyang.com/2011/06/philosophy-of-software-engineering/</guid><description>&lt;p>I spent part of my year in Cambridge reading the History and Philosophy of Science course. It has been a thrilling and enlightening course, and I cannot recommend it highly enough for anyone lucky enough to take the HPS strand at Cambridge. Of course, I was a bit of an odd one out, since the course is designed for Natural Science majors, and I am, of course, a Computer Scientist.&lt;/p></description></item><item><title>The Cryptography of Bitcoin</title><link>https://blog.ezyang.com/2011/06/the-cryptography-of-bitcoin/</link><pubDate>Fri, 03 Jun 2011 09:00:11 +0000</pubDate><guid>https://blog.ezyang.com/2011/06/the-cryptography-of-bitcoin/</guid><description>&lt;p>It is actually surprisingly difficult for a layperson to find out precisely what cryptography Bitcoin uses, without consulting the source of Bitcoin directly. For example, the &lt;a href="https://en.bitcoin.it/wiki/OP_CHECKSIG">opcode OP_CHECKSIG&lt;/a>, ostensibly checks the signature of something&amp;hellip; but there is no indication what kind of signature it checks! (What are opcodes in Bitcoin? Well it turns out that the protocol has a really neat scripting system built in for building transactions. &lt;a href="https://en.bitcoin.it/wiki/Script">You can read more about it here.&lt;/a>) So in fact, I managed to get some factual details wrong on my post &lt;a href="http://blog.ezyang.com/2011/06/bitcoin-is-not-decentralized/">Bitcoin is not decentralized&lt;/a>, which I realized when commenter cruzer claimed that a break in the cryptographic hash would only reduce mining difficulty, and not allow fake transactions.&lt;/p></description></item><item><title>Bitcoin is not decentralized</title><link>https://blog.ezyang.com/2011/06/bitcoin-is-not-decentralized/</link><pubDate>Wed, 01 Jun 2011 07:00:52 +0000</pubDate><guid>https://blog.ezyang.com/2011/06/bitcoin-is-not-decentralized/</guid><description>&lt;p>Bitcoin was designed by Satoshi Nakamoto, and the primary client is developed by a bunch of folks at &lt;a href="http://bitcoin.org/">bitcoin.org&lt;/a>. Do you care who these people are? In theory, you shouldn’t: all they do is develop an open source client for an open source protocol. Anyone else can develop their own client (and some people have) and no one, save the agreement of everyone in the Bitcoin network, can change the protocol. This is because the Bitcoin network is designed to be decentralized.&lt;/p></description></item><item><title>Chain Rule + Dynamic Programming &lt;br />= Neural Networks</title><link>https://blog.ezyang.com/2011/05/neural-networks/</link><pubDate>Mon, 30 May 2011 09:00:24 +0000</pubDate><guid>https://blog.ezyang.com/2011/05/neural-networks/</guid><description>&lt;p>(Guess what Edward has in a week: Exams! The theming of these posts might have something to do with that&amp;hellip;)&lt;/p>
&lt;p>At this point in my life, I’ve taken a course on introductory artificial intelligence twice. (Not my fault: I happened to have taken MIT’s version before going to Cambridge, which also administers this material as part of the year 2 curriculum.) My first spin through 6.034 was a mixture of disbelief at how simple the algorithms were, indignation at their examination methods, and the vague sense at the end that I really should have paid more attention. My second time through, I managed to distill a lot more algorithmic content out of the course, since I wasn’t worrying as much about the details.&lt;/p></description></item><item><title>An insufficiently lazy map</title><link>https://blog.ezyang.com/2011/05/an-insufficiently-lazy-map/</link><pubDate>Fri, 27 May 2011 09:00:58 +0000</pubDate><guid>https://blog.ezyang.com/2011/05/an-insufficiently-lazy-map/</guid><description>&lt;p>Another common thunk leak arises from mapping functions over containers, which do not execute their combining function strictly. The usual fix is to instead use a strict version of the function, ala &lt;code>foldl'&lt;/code> or &lt;code>insertWith'&lt;/code>, or perhaps using a completely strict version of the structure. In today’s post, we’ll look at this situation more closely. In particular, the questions I want to answer are as follows:&lt;/p>
&lt;ol>
&lt;li>Why do we need to create strict and lazy versions of these functions—why can’t these leaks be fixed by the user adding appropriate bang-patterns to some functions?&lt;/li>
&lt;li>Though introducing a stricter API is usually the correct fix, in some circumstances, the problem is not that the API is insufficiently strict, but that the data structure is too insufficiently lazy (that is, inappropriately spine strict.) That is to say, what do I mean by an insufficiently lazy map?&lt;/li>
&lt;li>For data structures in which spine-strictness is necessary, is there any reason that this strictness should not extend to the values themselves? I want to argue that in fact, all spine strict data structures should also be value strict. This may be a bit controversial.&lt;/li>
&lt;/ol>
&lt;h3 id="example" id="example">
 &lt;a class="heading-link" href="https://blog.ezyang.com/2011/05/an-insufficiently-lazy-map/#example">Example&lt;span class="heading-anchor" aria-label="Anchor">¶&lt;/span>&lt;/a>
&lt;/h3>
&lt;p>Our example is a very simple data structure, the spine-strict linked list:&lt;/p></description></item><item><title>If it has lots of comments, it's probably buggy</title><link>https://blog.ezyang.com/2011/05/byron-cook-sla/</link><pubDate>Wed, 25 May 2011 09:00:04 +0000</pubDate><guid>https://blog.ezyang.com/2011/05/byron-cook-sla/</guid><description>&lt;p>Yesterday we had guest speaker &lt;a href="http://research.microsoft.com/en-us/people/bycook/">Byron Cook&lt;/a> come in to give a talk about &lt;a href="http://research.microsoft.com/en-us/projects/slam/">SLAM&lt;/a>, a nice real-world example of theorem proving technology being applied to device drivers.&lt;/p>
&lt;p>Having worked in the trenches, Byron had some very hilarious (and interesting) quips about device driver development. After all, when a device driver crashes, it&amp;rsquo;s not the device driver writer that gets blamed: it’s Microsoft. He pointed out that, in a hardware company, “If you’re not so smart, you get assigned to write software drivers. The smart people go work on hardware”, and that when you’re reading device driver code, “If there are a lot of comments and they’re misspelled, there’s probably a bug.” Zing! We’re always used to extolling the benefits of commenting your code, but it certainly is indisputable that writing comments can help clarify confusing code to yourself, whereas if the code wasn’t confusing in the first place you wouldn’t have felt the need to write comments anyway. Thus, one situation is some guru from the days of yore wrote very clever code, and then you came along and weren’t quite clever enough to fully understand what was going on, so you wrote lots of comments to explain the code to yourself as you went along. Well, it’s not the comment’s fault, but the fact that the code was too clever for you probably means you introduced a bug when you made your modifications.&lt;/p></description></item><item><title>Tail recursion makes your loops cleaner</title><link>https://blog.ezyang.com/2011/05/tail-recursion-makes-your-loops-cleaner/</link><pubDate>Mon, 23 May 2011 09:00:04 +0000</pubDate><guid>https://blog.ezyang.com/2011/05/tail-recursion-makes-your-loops-cleaner/</guid><description>&lt;p>Recursion is one of those things that functional programming languages shine at—but it seems a bit disappointing that in many cases, you have to convert your beautiful recursive function back into iterative form. After all, iteration is what imperative languages do best, right?&lt;/p>
&lt;p>Actually, explicitly tail-recursive functions in functional programming languages can be fairly beautiful: in fact, in the cases of complicated loops, they can be even prettier than their imperative counterparts. Take this midpoint line-drawing algorithm as an example:&lt;/p></description></item><item><title>Computing function composition</title><link>https://blog.ezyang.com/2011/05/computing-function-composition/</link><pubDate>Fri, 20 May 2011 09:00:50 +0000</pubDate><guid>https://blog.ezyang.com/2011/05/computing-function-composition/</guid><description>&lt;p>This is an addendum to my second example in &lt;a href="http://blog.ezyang.com/2011/05/anatomy-of-a-thunk-leak/">Anatomy of a thunk leak&lt;/a>, in which I’d like to propose another solution to the space leak, involving computing the composition of all of these thunks. This solution is particularly notable because it preserves the denotation of the original function, that is, that &lt;code>f l (undefined, undefined) = (undefined, undefined)&lt;/code>. This should be surprising, because I claimed that it would be impossible for GHC to optimize a function with that had this denotation into one without the space leak by more eagerly evaluating some thunks. There is no contradiction: the optimization we would like to apply here is one of partial evaluation. Didn’t understand that? Don’t worry, a concrete example is coming soon.&lt;/p></description></item><item><title>Anatomy of a thunk leak</title><link>https://blog.ezyang.com/2011/05/anatomy-of-a-thunk-leak/</link><pubDate>Wed, 18 May 2011 08:29:19 +0000</pubDate><guid>https://blog.ezyang.com/2011/05/anatomy-of-a-thunk-leak/</guid><description>&lt;p>In this post, we discuss the characteristics of a thunk leak, the leak that has come to symbolize the difficulties of “reasoning about space usage” in Haskell. I’ll consider a few examples of this type of leak and argue that these leaks are actually &lt;em>trivial&lt;/em> to fix. Rather, the difficulty is when a thunk leak gets confused with other types of leaks (which we will cover in later posts).&lt;/p>
&lt;h3 id="description" id="description">
 &lt;a class="heading-link" href="https://blog.ezyang.com/2011/05/anatomy-of-a-thunk-leak/#description">Description&lt;span class="heading-anchor" aria-label="Anchor">¶&lt;/span>&lt;/a>
&lt;/h3>
&lt;p>I’ll be describing the various leaks in two ways: I will first give an informal, concrete description using &lt;a href="http://blog.ezyang.com/2011/04/the-haskell-heap/">the metaphor I developed in the Haskell Heap series&lt;/a>, and then I will give a more direct, clinical treatment at the end. If you can’t stand one form of explanation or the other, feel free to skip around.&lt;/p></description></item><item><title>Space leak zoo</title><link>https://blog.ezyang.com/2011/05/space-leak-zoo/</link><pubDate>Mon, 16 May 2011 09:00:28 +0000</pubDate><guid>https://blog.ezyang.com/2011/05/space-leak-zoo/</guid><description>&lt;p>A big thanks to everyone who everyone who &lt;a href="http://blog.ezyang.com/2011/05/calling-all-space-leaks/">sent in space leak specimens&lt;/a>. All of the leaks have been inspected and cataloged by our experts, and we are quite pleased to open the doors of the space leak zoo to the public!&lt;/p>
&lt;p>There are a few different types of space leak here, but they are quite different and a visitor would do well not to confuse them (the methods for handling them if encountered in the wild vary, and using the wrong technique could exacerbate the situation).&lt;/p></description></item><item><title>Reified laziness</title><link>https://blog.ezyang.com/2011/05/reified-laziness/</link><pubDate>Fri, 13 May 2011 21:45:11 +0000</pubDate><guid>https://blog.ezyang.com/2011/05/reified-laziness/</guid><description>&lt;p>Short post, longer ones in progress.&lt;/p>
&lt;p>One of the really neat things about the &lt;a href="http://hackage.haskell.org/packages/archive/monad-par/0.1.0.1/doc/html/Control-Monad-Par.html">Par monad&lt;/a> is how it explicitly reifies laziness, using a little structure called an &lt;code>IVar&lt;/code> (also known in the literature as &lt;em>I-structures&lt;/em>). An &lt;code>IVar&lt;/code> is a little bit like an &lt;code>MVar&lt;/code>, except that once you’ve put a value in one, you can never take it out again (and you’re not allowed to put another value in.) In fact, this precisely corresponds to lazy evaluation.&lt;/p></description></item><item><title>Calling all space leaks</title><link>https://blog.ezyang.com/2011/05/calling-all-space-leaks/</link><pubDate>Wed, 11 May 2011 16:00:15 +0000</pubDate><guid>https://blog.ezyang.com/2011/05/calling-all-space-leaks/</guid><description>&lt;p>I’m currently collecting non-stack-overflow space leaks, in preparation for a future post in the Haskell Heap series. If you have any interesting space leaks, especially if they’re due to laziness, send them my way.&lt;/p>
&lt;p>Here’s what I have so far (unverified: some of these may not leak or may be stack overflows. I’ll be curating them soon).&lt;/p>
&lt;pre>&lt;code>import Control.Concurrent.MVar

-- http://groups.google.com/group/fa.haskell/msg/e6d1d5862ecb319b
main1 = do file &amp;lt;- getContents
 putStrLn $ show (length $ lines file) ++ &amp;quot; &amp;quot; ++
 show (length $ words file) ++ &amp;quot; &amp;quot; ++
 show (length file) 

-- http://www.haskell.org/haskellwiki/Memory_leak
main2 = let xs = [1..1000000::Integer]
 in print (sum xs * product xs)

-- http://hackage.haskell.org/trac/ghc/ticket/4334
leaky_lines :: String -&amp;gt; [String]
leaky_lines &amp;quot;&amp;quot; = []
leaky_lines s = let (l, s') = break (== '\n') s
 in l : case s' of
 [] -&amp;gt; []
 (_:s'') -&amp;gt; leaky_lines s''

-- http://stackoverflow.com/questions/5552433/how-to-reason-about-space-complexity-in-haskell
data MyTree = MyNode [MyTree] | MyLeaf [Int]

makeTree :: Int -&amp;gt; MyTree
makeTree 0 = MyLeaf [0..99]
makeTree n = MyNode [ makeTree (n - 1)
 , makeTree (n - 1) ]

count2 :: MyTree -&amp;gt; MyTree -&amp;gt; Int
count2 r (MyNode xs) = 1 + sum (map (count2 r) xs)
count2 r (MyLeaf xs) = length xs

-- http://stackoverflow.com/questions/2777686/how-do-i-write-a-constant-space-length-function-in-haskell
leaky_length xs = length' xs 0
 where length' [] n = n
 length' (x:xs) n = length' xs (n + 1)

-- http://stackoverflow.com/questions/3190098/space-leak-in-list-program
leaky_sequence [] = [[]]
leaky_sequence (xs:xss) = [ y:ys | y &amp;lt;- xs, ys &amp;lt;- leaky_sequence xss ]

-- http://hackage.haskell.org/trac/ghc/ticket/917
initlast :: (()-&amp;gt;[a]) -&amp;gt; ([a], a)
initlast xs = (init (xs ()), last (xs ()))

main8 = print $ case initlast (\()-&amp;gt;[0..1000000000]) of
 (init, last) -&amp;gt; (length init, last)

-- http://hackage.haskell.org/trac/ghc/ticket/3944
waitQSem :: MVar (Int,[MVar ()]) -&amp;gt; IO ()
waitQSem sem = do
 (avail,blocked) &amp;lt;- takeMVar sem
 if avail &amp;gt; 0 then
 putMVar sem (avail-1,[])
 else do
 b &amp;lt;- newEmptyMVar
 putMVar sem (0, blocked++[b])
 takeMVar b

-- http://hackage.haskell.org/trac/ghc/ticket/2607
data Tree a = Tree a [Tree a] deriving Show
data TreeEvent = Start String
 | Stop
 | Leaf String
 deriving Show
main10 = print . snd . build $ Start &amp;quot;top&amp;quot; : cycle [Leaf &amp;quot;sub&amp;quot;]
type UnconsumedEvent = TreeEvent -- Alias for program documentation
build :: [TreeEvent] -&amp;gt; ([UnconsumedEvent], [Tree String])
build (Start str : es) =
 let (es', subnodes) = build es
 (spill, siblings) = build es'
 in (spill, (Tree str subnodes : siblings))
build (Leaf str : es) =
 let (spill, siblings) = build es
 in (spill, Tree str [] : siblings)
build (Stop : es) = (es, [])
build [] = ([], [])
&lt;/code>&lt;/pre></description></item><item><title>Bindings and CAFs on the Haskell Heap</title><link>https://blog.ezyang.com/2011/05/bindings-and-cafs-on-the-haskell-heap/</link><pubDate>Mon, 09 May 2011 11:23:43 +0000</pubDate><guid>https://blog.ezyang.com/2011/05/bindings-and-cafs-on-the-haskell-heap/</guid><description>&lt;div class="container center">
&lt;p>New to the series? Go &lt;a href="http://blog.ezyang.com/2011/04/the-haskell-heap/">to the beginning.&lt;/a>&lt;/p>
&lt;/div>
&lt;p>Today, we discuss how presents on the Haskell Heap are &lt;em>named&lt;/em>, whether by top-level bindings, let-bindings or arguments. We introduce the Expression-Present Equivalent Exchange, which highlights the fact that expressions are also thunks on the Haskell heap. Finally, we explain how this let-bindings inside functions can result in the creation of more presents, as opposed to constant applicative forms (CAFs) which exist on the Haskell Heap from the very beginning of execution.&lt;/p></description></item><item><title>How Aristotle got it Wrong&lt;br />On the importance of conceptual frameworks</title><link>https://blog.ezyang.com/2011/05/how-aristotle-got-it-wrongon-the-importance-of-conceptual-frameworks/</link><pubDate>Fri, 06 May 2011 09:00:35 +0000</pubDate><guid>https://blog.ezyang.com/2011/05/how-aristotle-got-it-wrongon-the-importance-of-conceptual-frameworks/</guid><description>&lt;p>One of the persistent myths about Aristotelean physics—the physics that was proposed by the Ancient Greeks and held up until Newton and Galileo came along—is that Aristotle thought that “heavier objects fall more quickly than light objects”, the canonical example being that of a cannon ball and feather. Although some fraction of contemporary human society may indeed believe this “fact,” Aristotle had a far more subtle and well-thought out view on the matter. If you don’t believe me, &lt;a href="http://classics.mit.edu/Aristotle/physics.4.iv.html">an English translation of his original text (Part 8)&lt;/a> adequately gives off this impression. Here is a relevant quote (emphasis mine):&lt;/p></description></item><item><title>Unraveling the mystery of the IO monad</title><link>https://blog.ezyang.com/2011/05/unraveling-the-mystery-of-the-io-monad/</link><pubDate>Wed, 04 May 2011 09:00:24 +0000</pubDate><guid>https://blog.ezyang.com/2011/05/unraveling-the-mystery-of-the-io-monad/</guid><description>&lt;p>When we teach beginners about Haskell, one of the things we handwave away is how the IO monad works. Yes, it’s a monad, and yes, it does IO, but it’s not something you can implement in Haskell itself, giving it a somewhat magical quality. In today’s post, I’d like to unravel the mystery of the IO monad by describing how GHC implements the IO monad internally in terms of primitive operations and the real world token. After reading this post, you should be able to understand the &lt;a href="http://hackage.haskell.org/trac/ghc/ticket/5129">resolution of this ticket&lt;/a> as well as the Core output of this Hello World! program:&lt;/p></description></item><item><title>Haskell: Not pure enough?</title><link>https://blog.ezyang.com/2011/05/haskell-not-pure-enough/</link><pubDate>Mon, 02 May 2011 09:00:06 +0000</pubDate><guid>https://blog.ezyang.com/2011/05/haskell-not-pure-enough/</guid><description>&lt;p>It is well known that &lt;code>unsafePerformIO&lt;/code> is an evil tool by which impure effects can make their way into otherwise pristine Haskell code. But is the rest of Haskell really that pure? Here are a few questions to ask:&lt;/p>
&lt;ol>
&lt;li>What is the value of &lt;code>maxBound :: Int&lt;/code>?&lt;/li>
&lt;li>What is the value of &lt;code>\x y -&amp;gt; x / y == (3 / 7 :: Double)&lt;/code> with &lt;code>3&lt;/code> and &lt;code>7&lt;/code> passed in as arguments?&lt;/li>
&lt;li>What is the value of &lt;code>os :: String&lt;/code> from &lt;code>System.Info&lt;/code>?&lt;/li>
&lt;li>What is the value of &lt;code>foldr (+) 0 [1..100] :: Int&lt;/code>?&lt;/li>
&lt;/ol>
&lt;p>The answers to each of these questions are ill-defined—or you might say they’re well defined, but you need a little extra information to figure out what the actual result is.&lt;/p></description></item><item><title>How the Grinch stole the Haskell Heap</title><link>https://blog.ezyang.com/2011/04/how-the-grinch-stole-the-haskell-heap/</link><pubDate>Fri, 29 Apr 2011 07:31:26 +0000</pubDate><guid>https://blog.ezyang.com/2011/04/how-the-grinch-stole-the-haskell-heap/</guid><description>&lt;div class="container center">
&lt;p>New to the series? Go &lt;a href="http://blog.ezyang.com/2011/04/the-haskell-heap/">to the beginning.&lt;/a>&lt;/p>
&lt;/div>
&lt;p>Today, we introduce the Grinch.&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/heap/grinch.png" alt="image">&lt;/p>
&lt;p>A formerly foul and unpleasant character, the Grinch has reformed his ways. He still has a penchant for stealing presents, but these days he does it ethically: he only takes a present if no one cares about it anymore. He is the &lt;em>garbage collector&lt;/em> of the Haskell Heap, and he plays a very important role in keeping the Haskell Heap small (and thus our memory usage low)—especially since functional programs generate &lt;em>a lot&lt;/em> of garbage. We’re not a particularly eco-friendly bunch.&lt;/p></description></item><item><title>Functions produce the Haskell Heap</title><link>https://blog.ezyang.com/2011/04/functions-produce-the-haskell-heap/</link><pubDate>Wed, 27 Apr 2011 11:18:38 +0000</pubDate><guid>https://blog.ezyang.com/2011/04/functions-produce-the-haskell-heap/</guid><description>&lt;div class="container center">
&lt;p>New to the series? Go &lt;a href="http://blog.ezyang.com/2011/04/the-haskell-heap/">to the beginning.&lt;/a>&lt;/p>
&lt;/div>
&lt;p>We’ve talked about how we open (evaluate) presents (thunks) in the Haskell Heap: we use IO. But where do all of these presents come from? Today we introduce where all these presents come from, the Ghost-o-matic machine (a function in a Haskell program).&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/heap/function.png" alt="image">&lt;/p>
&lt;p>Using a function involves three steps.&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/heap/function-howto.png" alt="image">&lt;/p>
&lt;p>We can treat the machine as a black box that takes present labels and pops out presents, but you can imagine the inside as having an unlimited supply of identical ghosts and empty present boxes: when you run the machine, it puts a copy of the ghost in the box.&lt;/p></description></item><item><title>Implementing the Haskell Heap in Python, v1</title><link>https://blog.ezyang.com/2011/04/implementing-the-haskell-heap-in-python-v1/</link><pubDate>Mon, 25 Apr 2011 09:00:47 +0000</pubDate><guid>https://blog.ezyang.com/2011/04/implementing-the-haskell-heap-in-python-v1/</guid><description>&lt;div class="container center">
&lt;p>New to the series? Go &lt;a href="http://blog.ezyang.com/2011/04/the-haskell-heap/">to the beginning.&lt;/a>&lt;/p>
&lt;/div>
&lt;p>Here is a simple implementation of all of the parts of the Haskell heap we have discussed up until now, ghosts and all.&lt;/p>
&lt;pre>&lt;code>heap = {} # global

# ---------------------------------------------------------------------#

class Present(object): # Thunk
 def __init__(self, ghost):
 self.ghost = ghost # Ghost haunting the present
 self.opened = False # Evaluated?
 self.contents = None
 def open(self):
 if not self.opened:
 # Hey ghost! Give me your present!
 self.contents = self.ghost.disturb()
 self.opened = True
 self.ghost = None
 return self.contents

class Ghost(object): # Code and closure
 def __init__(self, *args):
 self.tags = args # List of names of presents (closure)
 def disturb(self):
 raise NotImplemented

class Inside(object):
 pass
class GiftCard(Inside): # Constructor
 def __init__(self, name, *args):
 self.name = name # Name of gift card
 self.items = args # List of presents on heap you can redeem!
 def __str__(self):
 return &amp;quot; &amp;quot;.join([self.name] + map(str, self.items))
class Box(Inside): # Boxed, primitive data type
 def __init__(self, prim):
 self.prim = prim # Like an integer
 def __str__(self):
 return str(self.prim)

# ---------------------------------------------------------------------#

class IndirectionGhost(Ghost):
 def disturb(self):
 # Your present is in another castle!
 return heap[self.tags[0]].open()
class AddingGhost(Ghost):
 def disturb(self):
 # Gotta make your gift, be back in a jiffy!
 item_1 = heap[self.tags[0]].open()
 item_2 = heap[self.tags[1]].open()
 result = item_1.prim + item_2.prim
 return Box(result)
class UnsafePerformIOGhost(Ghost):
 def disturb(self):
 print &amp;quot;Fire ze missiles!&amp;quot;
 return heap[self.tags[0]].open()
class PSeqGhost(Ghost):
 def disturb(self):
 heap[self.tags[0]].open() # Result ignored!
 return heap[self.tags[1]].open()
class TraceGhost(Ghost):
 def disturb(self):
 print &amp;quot;Tracing %s&amp;quot; % self.tags[0]
 return heap[self.tags[0]].open()
class ExplodingGhost(Ghost):
 def disturb(self):
 print &amp;quot;Boom!&amp;quot;
 raise Exception

# ---------------------------------------------------------------------#

def evaluate(tag):
 print &amp;quot;&amp;gt; evaluate %s&amp;quot; % tag
 heap[tag].open()

def makeOpenPresent(x):
 present = Present(None)
 present.opened = True
 present.contents = x
 return present

# Let's put some presents in the heap (since we can't make presents
# of our own yet.)

heap['bottom'] = Present(ExplodingGhost())
heap['io'] = Present(UnsafePerformIOGhost('just_1'))
heap['just_1'] = makeOpenPresent(GiftCard('Just', 'bottom'))
heap['1'] = makeOpenPresent(Box(1))
heap['2'] = makeOpenPresent(Box(2))
heap['3'] = makeOpenPresent(Box(3))
heap['traced_1']= Present(TraceGhost('1'))
heap['traced_2']= Present(TraceGhost('2'))
heap['traced_x']= Present(TraceGhost('x'))
heap['x'] = Present(AddingGhost('traced_1', '3'))
heap['y'] = Present(PSeqGhost('traced_2', 'x'))
heap['z'] = Present(IndirectionGhost('traced_x'))

print &amp;quot;&amp;quot;&amp;quot;$ cat src.hs
import Debug.Trace
import System.IO.Unsafe
import Control.Parallel
import Control.Exception

bottom = error &amp;quot;Boom!&amp;quot;
io = unsafePerformIO (putStrLn &amp;quot;Fire ze missiles&amp;quot; &amp;gt;&amp;gt; return (Just 1))
traced_1 = trace &amp;quot;Tracing 1&amp;quot; 1
traced_2 = trace &amp;quot;Tracing 2&amp;quot; 2
traced_x = trace &amp;quot;Tracing x&amp;quot; x
x = traced_1 + 3
y = pseq traced_2 x
z = traced_x

main = do
 putStrLn &amp;quot;&amp;gt; evaluate 1&amp;quot;
 evaluate 1
 putStrLn &amp;quot;&amp;gt; evaluate z&amp;quot;
 evaluate z
 putStrLn &amp;quot;&amp;gt; evaluate z&amp;quot;
 evaluate z
 putStrLn &amp;quot;&amp;gt; evaluate y&amp;quot;
 evaluate y
 putStrLn &amp;quot;&amp;gt; evaluate io&amp;quot;
 evaluate io
 putStrLn &amp;quot;&amp;gt; evaluate io&amp;quot;
 evaluate io
 putStrLn &amp;quot;&amp;gt; evaluate bottom&amp;quot;
 evaluate bottom
$ runghc src.hs&amp;quot;&amp;quot;&amp;quot;

# Evaluating an already opened present doesn't do anything
evaluate('1')

# Evaluating an indirection ghost forces us to evaluate another present
evaluate('z')

# Once a present is opened, it stays opened
evaluate('z')

# Evaluating a pseq ghost may mean extra presents get opened
evaluate('y')

# unsafePerformIO can do anything, but maybe only once..
evaluate('io')
evaluate('io')

# Exploding presents may live in the heap, but they're only dangerous
# if you evaluate them...
evaluate('bottom')
&lt;/code>&lt;/pre>
&lt;p>&lt;em>Technical notes.&lt;/em> You can already see some resemblance of the ghosts’ Python implementations and the actual Core GHC might spit out. Here’s an sample for pseq:&lt;/p></description></item><item><title>IO evaluates the Haskell Heap</title><link>https://blog.ezyang.com/2011/04/io-evaluates-the-haskell-heap/</link><pubDate>Sun, 24 Apr 2011 12:36:46 +0000</pubDate><guid>https://blog.ezyang.com/2011/04/io-evaluates-the-haskell-heap/</guid><description>&lt;div class="container center">
&lt;p>New to the series? Go &lt;a href="http://blog.ezyang.com/2011/04/the-haskell-heap/">to the beginning.&lt;/a>&lt;/p>
&lt;/div>
&lt;p>In today’s post, we focus on &lt;em>you&lt;/em>, the unwitting person rooting around the Haskell heap to open a present. After all, presents in the Haskell heap do not spontaneously unwrap themselves.&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/heap/sleeping-heap.png" alt="image">&lt;/p>
&lt;p>Someone has to open the first present.&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/heap/woken-heap.png" alt="image">&lt;/p>
&lt;p>If the Haskell heap doesn’t interact with the outside world, no presents need to be opened: thus IO functions are the ones that will open presents. What presents they will open is not necessarily obvious for many functions, so we’ll focus on one function that makes it particularly obvious: &lt;code>evaluate&lt;/code>. Which tells you to&amp;hellip;&lt;/p></description></item><item><title>Evaluation on the Haskell Heap</title><link>https://blog.ezyang.com/2011/04/evaluation-on-the-haskell-heap/</link><pubDate>Wed, 20 Apr 2011 16:41:00 +0000</pubDate><guid>https://blog.ezyang.com/2011/04/evaluation-on-the-haskell-heap/</guid><description>&lt;div class="container center">
&lt;p>New to the series? Go &lt;a href="http://blog.ezyang.com/2011/04/the-haskell-heap/">to the beginning.&lt;/a>&lt;/p>
&lt;/div>
&lt;p>&lt;img src="https://blog.ezyang.com/img/heap/ghost.png" alt="image">&lt;/p>
&lt;div class="container center">
&lt;p>&lt;em>The Ghost of the Christmas Present&lt;/em>&lt;/p>
&lt;/div>
&lt;p>In today’s post, we’ll do a brief survey of the various things that can happen when you open haunted presents in the Haskell heap. Asides from constants and things that have already been evaluated, mostly everything on the Haskell heap is haunted. The real question is what the ghost haunting the present does.&lt;/p>
&lt;p>In the simplest case, almost nothing!&lt;/p></description></item><item><title>The Haskell Heap</title><link>https://blog.ezyang.com/2011/04/the-haskell-heap/</link><pubDate>Mon, 18 Apr 2011 09:00:46 +0000</pubDate><guid>https://blog.ezyang.com/2011/04/the-haskell-heap/</guid><description>&lt;p>&lt;img src="https://blog.ezyang.com/img/heap/title.png" alt="image">&lt;/p>
&lt;p>The Haskell heap is a rather strange place. It’s not like the heap of a traditional, strictly evaluated language&amp;hellip;&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/heap/traditional-heap.png" alt="image">&lt;/p>
&lt;p>&amp;hellip;which contains a lot of junk! (Plain old data.)&lt;/p>
&lt;p>In the Haskell heap, every item is wrapped up nicely in a box: the Haskell heap is a heap of &lt;em>presents&lt;/em> (thunks).&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/heap/present.png" alt="image">&lt;/p>
&lt;p>When you actually want what’s inside the present, you &lt;em>open it up&lt;/em> (evaluate it).&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/heap/evaluated.png" alt="image">&lt;/p>
&lt;p>Presents tend to have names, and sometimes when you open a present, you get a &lt;em>gift card&lt;/em> (data constructor). Gift cards have two traits: they have a name (the &lt;code>Just&lt;/code> gift card or the &lt;code>Right&lt;/code> gift card), and they tell you where the rest of your presents are. There might be more than one (the tuple gift card), if you’re a lucky duck!&lt;/p></description></item><item><title>Mailbox: Advice for a sup first-timer</title><link>https://blog.ezyang.com/2011/04/mailbox-advice-for-a-sup-first-timer/</link><pubDate>Sat, 16 Apr 2011 13:48:54 +0000</pubDate><guid>https://blog.ezyang.com/2011/04/mailbox-advice-for-a-sup-first-timer/</guid><description>&lt;blockquote>
&lt;p>&lt;em>What is the Mailbox?&lt;/em> It&amp;rsquo;s a selection of interesting email conversations from my mailbox, which I can use in place of writing original content when I’m feeling lazy. I got the idea from Matt Might, who has a set of wonderful &lt;a href="http://matt.might.net/articles/how-to-blog-as-an-academic/">suggestions for low-cost academic blogging&lt;/a>.&lt;/p>&lt;/blockquote>
&lt;p>&lt;em>From: Brent Yorgey&lt;/em>&lt;/p>
&lt;p>I see you are a contributor to the &lt;a href="http://sup.rubyforge.org/">sup mail client&lt;/a>. At least I assume it is you, I doubt there are too many Edward Z. Yangs in the world. =) I&amp;rsquo;m thinking of switching from mutt. Do you still use sup? Any thoughts/encouragements/cautions to share?&lt;/p></description></item><item><title>Tracing the compilation of Hello Factorial!</title><link>https://blog.ezyang.com/2011/04/tracing-the-compilation-of-hello-factorial/</link><pubDate>Wed, 13 Apr 2011 12:27:18 +0000</pubDate><guid>https://blog.ezyang.com/2011/04/tracing-the-compilation-of-hello-factorial/</guid><description>&lt;p>It is often said that the &lt;em>factorial function&lt;/em> is the “Hello World!” of the functional programming language world. Indeed, factorial is a singularly useful way of testing the pattern matching and recursive facilities of FP languages: we don’t bother with such “petty” concerns as input-output. In this blog post, we’re going to trace the compilation of factorial through the bowels of GHC. You’ll learn how to read Core, STG and Cmm, and hopefully get a taste of what is involved in the compilation of functional programs. Those who would like to play along with the GHC sources can check out the &lt;a href="http://hackage.haskell.org/trac/ghc/wiki/Commentary/Compiler/HscMain">description of the compilation of one module on the GHC wiki.&lt;/a> We won’t compile with optimizations to keep things simple; perhaps an optimized factorial will be the topic of another post!&lt;/p></description></item><item><title>Bugs from using the wrong variable</title><link>https://blog.ezyang.com/2011/04/bugs-from-using-the-wrong-variable/</link><pubDate>Mon, 11 Apr 2011 09:00:44 +0000</pubDate><guid>https://blog.ezyang.com/2011/04/bugs-from-using-the-wrong-variable/</guid><description>&lt;p>I was supposed to have another post about Hoopl today, but it got scuttled when an example program I had written triggered what I think is a bug in Hoopl (if it’s not a bug, then my mental model of how Hoopl works internally is seriously wrong, and I ought not write about it anyway.) So today’s post will be about the alleged bug Hoopl was a victim of: bugs from using the wrong variable.&lt;/p></description></item><item><title>Hoopl: Dataflow analysis</title><link>https://blog.ezyang.com/2011/04/hoopl-dataflow-analysis/</link><pubDate>Fri, 08 Apr 2011 21:07:34 +0000</pubDate><guid>https://blog.ezyang.com/2011/04/hoopl-dataflow-analysis/</guid><description>&lt;p>Once you’ve determined what &lt;a href="http://blog.ezyang.com/2011/04/hoopl-dataflow-lattices/">dataflow facts&lt;/a> you will be collecting, the next step is to write the &lt;em>transfer function&lt;/em> that actually performs this analysis for you!&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/hoopl.png" alt="image">&lt;/p>
&lt;p>Remember what your dataflow facts mean, and this step should be relatively easy: writing a transfer function usually involves going through every possible statement in your language and thinking about how it changes your state. We’ll walk through the transfer functions for constant propagation and liveness analysis.&lt;/p></description></item><item><title>Type Kata: Local data type</title><link>https://blog.ezyang.com/2011/04/type-kata-local-data-type/</link><pubDate>Tue, 05 Apr 2011 06:20:52 +0000</pubDate><guid>https://blog.ezyang.com/2011/04/type-kata-local-data-type/</guid><description>&lt;p>&lt;em>The imperative.&lt;/em> When should you create a custom data type, as opposed to reusing pre-existing data types such as &lt;code>Either&lt;/code>, &lt;code>Maybe&lt;/code> or tuples? Here are some reasons you should reuse a generic type:&lt;/p>
&lt;ul>
&lt;li>It saves typing (both in declaration and in pattern matching), making it good for one-off affairs,&lt;/li>
&lt;li>It gives you a library of predefined functions that work with that type,&lt;/li>
&lt;li>Other developers have expectations about what the type does that make understanding quicker.&lt;/li>
&lt;/ul>
&lt;p>On the flip side of the coin:&lt;/p></description></item><item><title>Hoopl: Dataflow lattices</title><link>https://blog.ezyang.com/2011/04/hoopl-dataflow-lattices/</link><pubDate>Mon, 04 Apr 2011 09:00:31 +0000</pubDate><guid>https://blog.ezyang.com/2011/04/hoopl-dataflow-lattices/</guid><description>&lt;p>The essence of dataflow optimization is &lt;em>analysis&lt;/em> and &lt;em>transformation&lt;/em>, and it should come as no surprise that once you’ve defined your intermediate representation, the majority of your work with Hoopl will involve defining analysis and transformations on your graph of basic blocks. Analysis itself can be further divided into the specification of the &lt;em>dataflow facts&lt;/em> that we are computing, and how we derive these dataflow facts during analysis. In part 2 of this &lt;a href="http://blog.ezyang.com/2011/04/hoopl-guided-tour-base-system/">series on Hoopl&lt;/a>, we look at the fundamental structure backing analysis: the &lt;em>dataflow lattice&lt;/em>. We discuss the theoretical reasons behind using a lattice and give examples of lattices you may define for optimizations such as constant propagation and liveness analysis.&lt;/p></description></item><item><title>Hoopl guided tour: Base system</title><link>https://blog.ezyang.com/2011/04/hoopl-guided-tour-base-system/</link><pubDate>Fri, 01 Apr 2011 09:00:44 +0000</pubDate><guid>https://blog.ezyang.com/2011/04/hoopl-guided-tour-base-system/</guid><description>&lt;p>&lt;a href="http://hackage.haskell.org/package/hoopl">Hoopl&lt;/a> is a higher-order optimization library. We think it’s pretty cool! This series of blog post is meant to give a tutorial-like introduction to this library, supplementing &lt;a href="http://research.microsoft.com/en-us/um/people/simonpj/papers/c--/">the papers&lt;/a> and the source code. I hope this series will also have something for people who aren’t interested in writing optimization passes with Hoopl, but are interested in the design of higher-order APIs in Haskell. By the end of this tutorial, you will be able to understand references in code to names such as &lt;code>analyzeAndRewriteFwd&lt;/code> and &lt;code>DataflowLattice&lt;/code>, and make decode such type signatures as:&lt;/p></description></item><item><title>GHC migrating to Git</title><link>https://blog.ezyang.com/2011/03/ghc-migrating-to-git/</link><pubDate>Wed, 30 Mar 2011 09:00:46 +0000</pubDate><guid>https://blog.ezyang.com/2011/03/ghc-migrating-to-git/</guid><description>&lt;p>From &lt;code>cvs-ghc@haskell.org&lt;/code>:&lt;/p>
&lt;pre>&lt;code>Hi all,

We now plan to do the git switchover this Thursday, 31 March.

Thanks
Ian
&lt;/code>&lt;/pre>
&lt;p>There are some things that I will miss from Darcs (&lt;code>darcs send&lt;/code> and the cases where &amp;ldquo;everything is a patch&amp;rdquo; actually does work well), but all and all I’m quite pleased to see GHC moving to Git.&lt;/p></description></item><item><title>HTML Purifier 4.3.0 released</title><link>https://blog.ezyang.com/2011/03/html-purifier-4-3-0-released/</link><pubDate>Mon, 28 Mar 2011 09:00:39 +0000</pubDate><guid>https://blog.ezyang.com/2011/03/html-purifier-4-3-0-released/</guid><description>&lt;p>The release cycle gets longer and longer&amp;hellip; probably to the delight of all those downstream, anyway.&lt;/p>
&lt;hr>
&lt;p>&lt;a href="http://htmlpurifier.org">HTML Purifier&lt;/a> 4.3.0 is a major security release addressing various security vulnerabilities related to user-submitted code and legitimate client-side scripts. It also contains an accumulation of new features and bugfixes over half a year. New configuration options include %CSS.Trusted, %CSS.AllowedFonts and %Cache.SerializerPermissions. There is a backwards-incompatible API change for customized raw definitions, see &lt;a href="http://htmlpurifier.org/docs/enduser-customize.html#optimized">the customization documentation&lt;/a> for details.&lt;/p></description></item><item><title>Ely Cycles</title><link>https://blog.ezyang.com/2011/03/ely-cycles/</link><pubDate>Fri, 25 Mar 2011 09:00:00 +0000</pubDate><guid>https://blog.ezyang.com/2011/03/ely-cycles/</guid><description>&lt;p>Yesterday I cycled from Cambridge to Ely, and back again. The route is a glorious 38 miles (round trip) of British towns and countryside. The cycling around Cambridge is quite good, because there aren’t very many hills, and in the farmland areas you get to see the tractors rolling by. The longest I’d ever cycled before was the Springwater Corridor in Portland, the segment of which I did was only about 10 miles.&lt;/p></description></item><item><title>Interleaving stream processors</title><link>https://blog.ezyang.com/2011/03/interleaving-stream-processor/</link><pubDate>Wed, 23 Mar 2011 09:00:36 +0000</pubDate><guid>https://blog.ezyang.com/2011/03/interleaving-stream-processor/</guid><description>&lt;div class="container center">
&lt;p>&lt;em>Ghost in the state machine&lt;/em>&lt;/p>
&lt;/div>
&lt;p>A long time ago (circa 2007-2008), I wrote perhaps the single most complicated piece of code in HTML Purifier—one of those real monsters that you don’t think anyone else could ever understand and that you are really grateful you have a comprehensive test suite for. The idea was this: I had a state machine that modified a stream of tokens (since this was a stream of HTML tags and text, the state machine maintained information such as the current nesting stack), and I wanted to allow users to add extra functionality on top of this stream processor (the very first processor inserted paragraph tags when double-newlines were encountered) in a modular way.&lt;/p></description></item><item><title>The return of Hellenistic reasoning</title><link>https://blog.ezyang.com/2011/03/the-return-of-hellenistic-reasonin/</link><pubDate>Mon, 21 Mar 2011 09:00:42 +0000</pubDate><guid>https://blog.ezyang.com/2011/03/the-return-of-hellenistic-reasonin/</guid><description>&lt;p>I recently attended a talk which &lt;a href="http://talks.cam.ac.uk/talk/index/29335">discussed extending proof assistants with diagrammatic reasoning support&lt;/a> , helping to break the hegemony of symbolic systems that is predominant in this field. While the work is certainly novel in some respects, I can&amp;rsquo;t also but help think that we&amp;rsquo;ve come back full circle to the Ancient Greeks, who were big fans of geometry, and its correspondingly visual form of reasoning. The thought came up again while I was reading a mathematics text and marveling at the multiple methods of presenting a single concept. In this essay, I&amp;rsquo;d like to look at this return to older, more &amp;ldquo;intuitive&amp;rdquo; forms of reasoning: I&amp;rsquo;ve called it &amp;ldquo;Hellenistic reasoning&amp;rdquo; because geometry and the Socratic method nicely sum up visual and interactive reasoning that I&amp;rsquo;d like to discuss. I argue that this resurgence is a good thing, and that though these forms of reasoning may not be as powerful or general as symbolic reasoning, they will be critical to the application and communication of abstract mathematical results.&lt;/p></description></item><item><title>Spring Reading: 2011 edition</title><link>https://blog.ezyang.com/2011/03/spring-reading-2011-edition/</link><pubDate>Fri, 18 Mar 2011 18:29:11 +0000</pubDate><guid>https://blog.ezyang.com/2011/03/spring-reading-2011-edition/</guid><description>&lt;p>Books are expensive, but by the power of higher-education (also expensive, but differently so), vast oceans of books are available to an enterprising compsci. Here’s my reading list for the spring break lending period (many of which were recommended on &lt;code>#haskell&lt;/code>:&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/spring-2011-reading.jpg" alt="image">&lt;/p>
&lt;ul>
&lt;li>&lt;em>Concepts, Techniques, and Models of Computer Programming&lt;/em> by Peter Van Roy and Seif Haridi. Wonderfully iconoclastic book, and probably one of the easier reads on the list.&lt;/li>
&lt;li>&lt;em>Types and Programming Languages&lt;/em> by Benjamin Pierce. I’ve been working on this one for a while; this break I’m focusing on the proof strategies for preservation, progress and safety, and also using it to complement a self-study course summed up by the next book.&lt;/li>
&lt;li>&lt;em>Lectures on the Curry-Howard Isomorphism&lt;/em> by M.H. Sørensen and P. Urzycyzn. Very good, I’ve skimmed the first three chapters and I’m working on the exercises in chapter 2. I’ve been prone to making silly mis-assertions about the Curry-Howard Isomorphism (or is it?), so I’m looking forward to more firmly grounding my understanding of this correspondence. The sections on intuitionistic logic has already been very enlightening.&lt;/li>
&lt;li>&lt;em>Type Theory and Functional Programming&lt;/em> by Simon Thompson. Haven’t looked at it yet, but fits into the general course of the previous two books.&lt;/li>
&lt;li>&lt;em>Purely Functional Data Structures&lt;/em> by Chris Okasaki. Also one I’ve been working on a while. Working on compressing all the information mentally.&lt;/li>
&lt;li>&lt;em>Basic Category Theory for Computer Scientists&lt;/em> by Benjamin Pierce. I’ve got two items on category theory; I got this one on a whim. Haven’t looked at it yet.&lt;/li>
&lt;li>&lt;em>Pearls of Functional Algorithm Design&lt;/em> by Richard Bird. Something like a collection of puzzles. I think I will enjoy reading through them and working out the subtleties. I probably won’t get to the information compression stage this time around.&lt;/li>
&lt;li>&lt;em>Category Theory&lt;/em> by Steve Awodey. I was working on the exercises in this textbook, and think I might get past the first chapter.&lt;/li>
&lt;/ul></description></item><item><title>On expressivity</title><link>https://blog.ezyang.com/2011/03/on-expressivity/</link><pubDate>Wed, 16 Mar 2011 09:00:12 +0000</pubDate><guid>https://blog.ezyang.com/2011/03/on-expressivity/</guid><description>&lt;div class="container center">
&lt;p>&lt;em>Wherein I make fun of functional programming advocates.&lt;/em>&lt;/p>
&lt;/div>
&lt;p>In this essay, I’d like to discuss the ideologies of “imperative programming” and “functional programming” in terms of the language features they lean on: in particular, the mechanisms by which they allow developers to express themselves in less code. I propose that the set of features that make up imperative programming constitute a dominant programming monoculture that is partially incompatible with functional programming’s favored features, requiring functional programming advocates to do funny things to gain the attention of the programmers.&lt;/p></description></item><item><title>Someone is wrong on the Internet</title><link>https://blog.ezyang.com/2011/03/someone-is-wrong-on-the-internet/</link><pubDate>Mon, 14 Mar 2011 09:00:01 +0000</pubDate><guid>https://blog.ezyang.com/2011/03/someone-is-wrong-on-the-internet/</guid><description>&lt;div class="container center">
&lt;p>&lt;em>The perverse incentive structure of the Internet&lt;/em>&lt;/p>
&lt;/div>
&lt;p>Suppose you have a Random Question™ that you would like answered. For example, “Did Sir Francis Galton have any children?” It’s the type of thing you’d type into Google.&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/wrong-on-the-internet/google.png" alt="image">&lt;/p>
&lt;p>Answers.com is not a terribly good source, but it is something to at least see if you can scrounge up some extra information on. So suppose you dig a little deeper and discover that Francis Galton only &lt;a href="http://galton.org/cgi-bin/searchImages/search/pearson/vol2/pages/vol2_0320.htm">married once and that this marriage was barren&lt;/a>. So unless some historian’s account of Galton suffering from venereal disease (Kevles 12) indicates that he knocked up some ladies in Syria and managed to pop out four offspring, who happened to conveniently be named “Francis, Harriet, Matilda and Mark,” Answers.com is wrong.&lt;/p></description></item><item><title>Many-valued logics and bottom</title><link>https://blog.ezyang.com/2011/03/many-valued-logics-and-bottom/</link><pubDate>Fri, 11 Mar 2011 09:00:05 +0000</pubDate><guid>https://blog.ezyang.com/2011/03/many-valued-logics-and-bottom/</guid><description>&lt;p>I was flipping through &lt;em>An Introduction to Non-Classical Logic&lt;/em> by Graham Priest and the section on many-valued logics caught my eye. Many-valued logics are logics with more than the usual two truth values &lt;em>true&lt;/em> and &lt;em>false&lt;/em>. The (strong) Kleene 3-valued logic, sets up the following truth table with 0, 1 and x (which is thought to be some value that is neither true nor false):&lt;/p>
&lt;pre>&lt;code>NOT
 1 0
 x x
 0 1

AND
 1 x 0
 1 1 x 0
 x x x 0
 0 0 0 0

OR
 1 x 0
 1 1 1 1
 x 1 x x
 0 1 x 0

IMPLICATION
 1 x 0
 1 1 x 0
 x 1 x x
 0 1 1 1
&lt;/code>&lt;/pre>
&lt;p>I’ve always thought many-valued logics were a bit of a “hack” to deal with the self-referentiality paradoxes, but in fact, Kleene invented his logic by thinking about what happened with partial functions where applied with values that they were not defined for: a sort of denotation failure. So it&amp;rsquo;s not surprising that these truth tables correspond to the &lt;a href="http://blog.ezyang.com/2010/12/gin-and-monotonic/">parallel-or and and operators predicted by denotational semantics&lt;/a>.&lt;/p></description></item><item><title>Killer mutants attack (mutation gone wrong)</title><link>https://blog.ezyang.com/2011/03/killer-mutants-attack-mutation-gone-wrong/</link><pubDate>Wed, 09 Mar 2011 09:00:46 +0000</pubDate><guid>https://blog.ezyang.com/2011/03/killer-mutants-attack-mutation-gone-wrong/</guid><description>&lt;p>This is a collection of WTFs due to misuse of mutable state.&lt;/p>
&lt;hr>
&lt;p>We&amp;rsquo;ll start off with some Java. What do you expect this snippet of code to do? :&lt;/p>
&lt;pre>&lt;code>Sensor Accel = sm.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
Sensor Orient = sm.getDefaultSensor(Sensor.TYPE_ORIENTATION);
sm.registerListener((SensorEventListener) this, Accel, sm.SENSOR_DELAY_FASTEST);
&lt;/code>&lt;/pre>
&lt;p>Ostensibly, it registers the current object to receive just accelerometer updates. But what if I told you getDefaultSensor was implemented like this:&lt;/p>
&lt;pre>&lt;code>public Sensor getDefaultSensor (int type){
 if(sensors == null) {
 sensors = new Sensor(mContext, type);
 return sensors; 
 }else if(sensors.checkList(type)){
 sensors.addSensor(type);
 return sensors;
 }else{
 sensors.removeSensor(type);
 return sensors;
 }
}
&lt;/code>&lt;/pre>
&lt;p>This code completely fails to manage the expected semantics: there is a single &lt;code>sm&lt;/code> wide &lt;code>Sensor&lt;/code> object (stored in &lt;code>sensors&lt;/code>) that accumulates sensor values as &lt;code>getDefaultSensor&lt;/code> is called. So in fact, &lt;code>this&lt;/code> will receive events from both the accelerometer and the magnetometer. The only saving grace is that when we register event listeners, we usually do want them to receive all events, so we might not notice if we weren&amp;rsquo;t looking too closely. This is real code from &lt;a href="http://code.google.com/p/openintents/source/browse/trunk/sensorsimulator/SensorSimulatorSettings/src/org/openintents/sensorsimulator/hardware/SensorManagerSimulator.java">OpenIntents SensorSimulator&lt;/a>.&lt;/p></description></item><item><title>Type Technology Tree</title><link>https://blog.ezyang.com/2011/03/type-tech-tree/</link><pubDate>Mon, 07 Mar 2011 09:00:26 +0000</pubDate><guid>https://blog.ezyang.com/2011/03/type-tech-tree/</guid><description>&lt;p>They say that one doesn’t discover advanced type system extensions: rather, the type system extensions discover you! Nevertheless, it’s worthwhile to know what the tech tree for GHC’s type extensions are, so you can decide how much power (and the correspondingly headache inducing error messages) you need. I’ve organized the relations in the following diagram with the following criterion in mind:&lt;/p>
&lt;ol>
&lt;li>Some extensions automatically enable other extensions (implies);&lt;/li>
&lt;li>Some extensions offer all the features another extension offers (subsumes);&lt;/li>
&lt;li>Some extensions work really nicely with other extensions (synergy);&lt;/li>
&lt;li>Some extensions offer equivalent (but differently formulated) functionality to another extension (equiv).&lt;/li>
&lt;/ol>
&lt;p>It’s also worth noting that the GHC manual divides these extensions into “Extensions to data types and type synonyms”, “Class and instances declarations”, “Type families” and “Other type system extensions”. I have them organized here a little differently.&lt;/p></description></item><item><title>Petri net concurrency</title><link>https://blog.ezyang.com/2011/03/petri-net-concurrency/</link><pubDate>Fri, 04 Mar 2011 09:00:50 +0000</pubDate><guid>https://blog.ezyang.com/2011/03/petri-net-concurrency/</guid><description>&lt;p>A &lt;a href="http://en.wikipedia.org/wiki/Petri_net">petri net&lt;/a> is a curious little graphical modeling language for control flow in concurrency. They came up in this talk a few weeks ago: &lt;a href="http://talks.cam.ac.uk/talk/index/29894">Petri-nets as an Intermediate Representation for Heterogeneous Architectures&lt;/a>, but what I found interesting was how I could describe some common concurrency structures using this modeling language.&lt;/p>
&lt;p>Here is, for example, the well venerated lock:&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/petri/lock.png" alt="image">&lt;/p>
&lt;p>The way to interpret the graph is thus: each circle is a “petri dish” (place) that may contain some number of tokens. The square boxes (transitions) are actions that would like to fire, but in order to do so all of the petri dishes feeding into them must have tokens. It’s the sort of representation that you could make into a board game of sorts!&lt;/p></description></item><item><title>The creation of a statically-typed functional programmer</title><link>https://blog.ezyang.com/2011/03/the-creation-of-a-statically-typed-functional-programmer/</link><pubDate>Wed, 02 Mar 2011 09:00:26 +0000</pubDate><guid>https://blog.ezyang.com/2011/03/the-creation-of-a-statically-typed-functional-programmer/</guid><description>&lt;p>The bug bit me in early 2009, during MIT’s independent activities period; really, it was two bugs. The first was &lt;a href="http://web.mit.edu/alexmv/6.001/">6.184&lt;/a>, the re-animated introductory computer science class taught in Scheme—for obvious reasons. But I don’t think that was sufficient: I seemed to recall thinking Scheme was interesting but not a language I actually wanted to code in. The second was a comment made by Anders Kaseorg after I finished delivering a talk &lt;a href="http://mit.edu/~ezyang/Public/iap/intro-to-was.html">Introduction to Web Application Security&lt;/a> (one of the few things that, as a freshman at MIT, I thought I knew well enough to give a lecture on). One of the emphases of the talk was all about &lt;em>types&lt;/em>: that is, the fact that “string” doesn’t adequately represent the semantic content of most bits of text that float around in our applications these days. Haskell came up as a way of making your compiler make sure you didn’t mix up HTML with plain text.&lt;/p></description></item><item><title>On cargo culting and hacking</title><link>https://blog.ezyang.com/2011/02/on-cargo-culting-and-hacking/</link><pubDate>Mon, 28 Feb 2011 09:00:46 +0000</pubDate><guid>https://blog.ezyang.com/2011/02/on-cargo-culting-and-hacking/</guid><description>&lt;div class="container center">
&lt;p>&lt;em>two inflammatory vignettes&lt;/em>&lt;/p>
&lt;/div>
&lt;p>The term &lt;em>to cargo cult&lt;/em> is one with derogatory connotations: it indicates the act of imitating the superficial exterior without actually understanding the underlying causal structure of the situation. The implication is that one should try to understand what one is doing, before doing it. There is, however, an ounce of truth in the practice of cargo culting: when you are in a situation in which you legitimately do not know what’s going on (e.g. the context of an experiment), it is safest to preserve as many superficial traits as possible, in case a “superficial” trait in fact has a deep, non-obvious connection to the system being studied. But in this regard, beneficial “cargo culting” is nothing like the islanders throwing up airstrips in hopes of attracting planes—understanding what conditions are applicable for this treatment is often the mark of experience: the novice ignores conditions that should be preserved and does not know how to probe deeper.&lt;/p></description></item><item><title>Multi-day debugging</title><link>https://blog.ezyang.com/2011/02/multi-day-debugging/</link><pubDate>Fri, 25 Feb 2011 09:00:51 +0000</pubDate><guid>https://blog.ezyang.com/2011/02/multi-day-debugging/</guid><description>&lt;p>Most of my hacking cycles right now are going towards debugging the new code generator for GHC. The code generation stage of GHC takes the Spineless Tagless G-machine (STG) intermediate representation (IR) to the C&amp;ndash; high-level assembly representation; the old code generator essentially performed this step in one big bang. The new code generator is many things. It is a more modular, understandable and flexible codebase. It is a client of cutting edge research in higher-order frameworks for control-flow optimization.&lt;/p></description></item><item><title>Ad hoc approximations</title><link>https://blog.ezyang.com/2011/02/ad-hoc-approximations/</link><pubDate>Wed, 23 Feb 2011 09:00:25 +0000</pubDate><guid>https://blog.ezyang.com/2011/02/ad-hoc-approximations/</guid><description>&lt;p>In his book &lt;em>Against Method&lt;/em>, Paul Feyerabend writes the following provocative passage about ‘ad hoc approximations’, familiar to anyone whose taken a physics course and thought, “Now where did they get that approximation from&amp;hellip;”&lt;/p>
&lt;blockquote>
&lt;p>The perihelion of Mercury moves along at a rate of about 5600&amp;quot; per century. Of this value, 5026&amp;quot; are geometric, having to do with the movement of the reference system, while 531&amp;quot; are dynamical, due to the perturbations in the solar system. Of these perturbations all but &lt;a href="http://en.wikipedia.org/wiki/Tests_of_general_relativity#Perihelion_precession_of_Mercury">the famous 43&amp;quot;&lt;/a> are accounted for by classical mechanics. This is how the situation is usually explained.&lt;/p></description></item><item><title>Semi-automatic testing</title><link>https://blog.ezyang.com/2011/02/semi-automatic-testing/</link><pubDate>Mon, 21 Feb 2011 09:00:14 +0000</pubDate><guid>https://blog.ezyang.com/2011/02/semi-automatic-testing/</guid><description>&lt;p>When programmers automate something, we often want to go whole-hog and automate everything. But it’s good to remember there’s still a place for manual testing with machine assistance: instead of expending exponential effort to automate everything, automate the easy bits and hard-code answers to the hard research problems. When I was compiling the following graph of sources of test data, I noticed a striking polarization at the ends of &amp;ldquo;automated&amp;rdquo; and &amp;ldquo;non-automated.&amp;rdquo;&lt;/p></description></item><item><title>Two short tips for FFI bindings</title><link>https://blog.ezyang.com/2011/02/two-short-tips-for-ffi-binding/</link><pubDate>Sun, 20 Feb 2011 20:57:03 +0000</pubDate><guid>https://blog.ezyang.com/2011/02/two-short-tips-for-ffi-binding/</guid><description>&lt;p>To: &lt;a href="http://acidcycles.wordpress.com/">Oliver Charles&lt;/a>&lt;br>
Subject: [Haskell-cafe] Please review my Xapian foreign function interface&lt;/p>
&lt;p>Thanks Oliver!&lt;/p>
&lt;p>I haven&amp;rsquo;t had time to look at your bindings very closely, but I do have a few initial things to think about:&lt;/p>
&lt;ul>
&lt;li>You&amp;rsquo;re writing your imports by hand. Several other projects used to do this, and it&amp;rsquo;s a pain in the neck when you have hundreds of functions that you need to bind and you don&amp;rsquo;t quite do it all properly, and then you segfault because there was an API mismatch. Consider using a tool like &lt;a href="http://blog.ezyang.com/2010/06/the-haskell-preprocessor-hierarchy/">c2hs&lt;/a> which rules out this possibility (and reduces the code you need to write!)&lt;/li>
&lt;li>I see a lot of unsafePerformIO and no consideration for interruptibility or thread safety. People who use Haskell tend to expect their code to be thread-safe and interruptible, so we have high standards ;-) But even C++ code that looks thread safe may be mutating shared memory under the hood, so check carefully.&lt;/li>
&lt;/ul>
&lt;p>I use Sup, so I deal with Xapian on a day-to-day basis. Bindings are good to see.&lt;/p></description></item><item><title>On checked exceptions and proof obligations</title><link>https://blog.ezyang.com/2011/02/on-checked-exceptions-and-proof-obligations/</link><pubDate>Fri, 18 Feb 2011 09:00:05 +0000</pubDate><guid>https://blog.ezyang.com/2011/02/on-checked-exceptions-and-proof-obligations/</guid><description>&lt;p>Checked exceptions are a much vilified feature of Java, despite theoretical reasons why it should be a really good idea. The tension is between these two lines of reasoning:&lt;/p>
&lt;blockquote>
&lt;p>Well-written programs handle all possible edge-cases, working around them when possible and gracefully dying if not. It&amp;rsquo;s hard to keep track of &lt;em>all&lt;/em> possible exceptions, so we should have the compiler help us out by letting us know when there is an edge-case that we&amp;rsquo;ve forgotten to handle. Thus, checked exceptions offer a mechanism of ensuring we&amp;rsquo;ve handled all of the edge-cases.&lt;/p></description></item><item><title>Picturing Hoopl transfer/rewrite functions</title><link>https://blog.ezyang.com/2011/02/picturing-hoopl-transferrewrite-functions/</link><pubDate>Wed, 16 Feb 2011 09:00:44 +0000</pubDate><guid>https://blog.ezyang.com/2011/02/picturing-hoopl-transferrewrite-functions/</guid><description>&lt;p>&lt;a href="http://hackage.haskell.org/package/hoopl">Hoopl&lt;/a> is a “higher order optimization library.” Why is it called “higher order?” Because all a user of Hoopl needs to do is write the various bits and pieces of an optimization, and Hoopl will glue it all together, the same way someone using a fold only needs to write the action of the function on one element, and the fold will glue it all together.&lt;/p>
&lt;p>Unfortunately, if you’re not familiar with the structure of the problem that your higher order functions fit into, code written in this style can be a little incomprehensible. Fortunately, Hoopl’s two primary higher-order ingredients: transfer functions (which collect data about the program) and rewrite functions (which use the data to rewrite the program) are fairly easy to visualize.&lt;/p></description></item><item><title>Picturing binomial coefficient identities</title><link>https://blog.ezyang.com/2011/02/picturing-binomial-coefficient-identities/</link><pubDate>Mon, 14 Feb 2011 09:00:10 +0000</pubDate><guid>https://blog.ezyang.com/2011/02/picturing-binomial-coefficient-identities/</guid><description>&lt;p>Guys, I have a secret to admit: I’m terrified of binomials. When I was in high school, I had a traumatic experience with Donald Knuth’s &lt;em>The Art of Computer Programming&lt;/em>: yeah, that book that everyone recommends but no one has actually read. (That’s not actually true, but that subject is the topic for another blog post.) I wasn’t able to solve any recommended exercises in the mathematical first chapter nor was I well versed enough in computers to figure out what assembly languages were about. But probably the most traumatizing bit was Knuth’s extremely compact treatment of the mathematical identities in the first chapter we were expected memorize. As I would find out later in my mathematical career, it pays to convince yourself that a given statement is true before diving into the mess of algebraic manipulation in order to actually prove it.&lt;/p></description></item><item><title>Android 2.x Sensor Simulator</title><link>https://blog.ezyang.com/2011/02/android-2-x-sensor-simulator/</link><pubDate>Fri, 11 Feb 2011 09:00:16 +0000</pubDate><guid>https://blog.ezyang.com/2011/02/android-2-x-sensor-simulator/</guid><description>&lt;p>OpenIntents has a nifty application called &lt;a href="http://code.google.com/p/openintents/wiki/SensorSimulator">SensorSimulator&lt;/a> which allows you feed an Android application accelerometer, orientation and temperature sensor data. Unfortunately, it doesn&amp;rsquo;t work well on the newer Android 2.x series of devices. In particular:&lt;/p>
&lt;ul>
&lt;li>The mocked API presented to the user is different from the true API. This is due in part to the copies of the Sensor, SensorEvent and SensorEventHandler that the original code had in order to work around the fact that Android doesn&amp;rsquo;t have public constructors for these classes,&lt;/li>
&lt;li>Though the documentation claims “Whenever you are not connected to the simulator, you will get real device sensor data”, this is not actually the case: all of the code that interfaces with the real sensor system is commented out. So not only is are the APIs incompatible, you have to edit your code from one way to another when you want to vary testing. (The code also does a terrible job of handling the edge condition where you are not actually testing the application.)&lt;/li>
&lt;/ul>
&lt;p>Being rather displeased with this state of affairs, I decided to fix things up. With the power of Java reflection (cough cough) I switched the representation over to the true Android objects (effectively eliminating all overhead when the simulator is not connected.) Fortunately, Sensor and SensorEvent are small, data-oriented classes, so I don&amp;rsquo;t think I stepped on the internal representation too much, though the code will probably break horribly with future versions of the Android SDK. Perhaps I should suggest to upstream that they should make their constructors public.&lt;/p></description></item><item><title>A suggestion for indent/php.vim</title><link>https://blog.ezyang.com/2011/02/inden-php-vim/</link><pubDate>Wed, 09 Feb 2011 09:00:17 +0000</pubDate><guid>https://blog.ezyang.com/2011/02/inden-php-vim/</guid><description>&lt;p>To: &lt;a href="http://www.2072productions.com/">John Wellesz&lt;/a>&lt;/p>
&lt;p>First off, I&amp;rsquo;d like to thank you for authoring the php.vim indentation plugin. Recent experiences with some other indentation plugins made me realize how annoying editing can be without a good indentation plugin, and php.vim mostly has served me well over the years.&lt;/p>
&lt;p>However, I do have a suggestion for the default behavior of &lt;code>PHP_autoformatcomment&lt;/code>. When this option is enabled (as it is by default), it sets the &amp;lsquo;w&amp;rsquo; format option, which performs paragraphing based off of trailing newlines. Unfortunately, this option has a number of adverse effects that may not be obvious unless you are paying attention to trailing newlines:&lt;/p></description></item><item><title>Lav'net is watching you</title><link>https://blog.ezyang.com/2011/02/lavnet-is-watching-you/</link><pubDate>Mon, 07 Feb 2011 09:00:02 +0000</pubDate><guid>https://blog.ezyang.com/2011/02/lavnet-is-watching-you/</guid><description>&lt;p>This picture snapped in Paris, two blocks from the apartment I holed up in. &lt;a href="http://everything2.com/title/The+LarvNet+Story">Some background.&lt;/a>&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/lavnet.jpg" alt="image">&lt;/p></description></item><item><title>OCaml gotchas</title><link>https://blog.ezyang.com/2011/02/ocaml-gotchas/</link><pubDate>Fri, 04 Feb 2011 09:00:04 +0000</pubDate><guid>https://blog.ezyang.com/2011/02/ocaml-gotchas/</guid><description>&lt;p>I spent some time fleshing out my &lt;a href="https://github.com/ezyang/ocaml-cminsketch">count min sketch&lt;/a> implementation for OCaml (to be the subject of another blog post), and along the way, I noticed a few more quirks about the OCaml language (from a Haskell viewpoint).&lt;/p>
&lt;ul>
&lt;li>
&lt;p>Unlike Haskell’s &lt;code>Int&lt;/code>, which is 32-bit/64-bit, the built-in OCaml &lt;code>int&lt;/code> type is only 31-bit/63-bit. Bit twiddlers beware! (There is a &lt;code>nativeint&lt;/code> type which gives full machine precision, but it less efficient than the &lt;code>int&lt;/code> type).&lt;/p></description></item><item><title>All about MVars</title><link>https://blog.ezyang.com/2011/02/all-about-mvars/</link><pubDate>Wed, 02 Feb 2011 09:00:37 +0000</pubDate><guid>https://blog.ezyang.com/2011/02/all-about-mvars/</guid><description>&lt;p>I recently took the time out to rewrite &lt;a href="http://www.haskell.org/ghc/docs/latest/html/libraries/base/Control-Concurrent-MVar.html">the MVar documentation&lt;/a>, which as it stands is fairly sparse (the introduction section rather tersely states &amp;ldquo;synchronising variables&amp;rdquo;; though to the credit of the original writers the inline documentation for the data type and its fundamental operations is fairly fleshed out.) I&amp;rsquo;ve reproduced my new introduction here.&lt;/p>
&lt;p>While researching this documentation, I discovered something new about how MVars worked, which is encapsulated in this program. What does it do? :&lt;/p></description></item><item><title>A year of blogging</title><link>https://blog.ezyang.com/2010/12/a-year-of-blogging/</link><pubDate>Fri, 31 Dec 2010 09:00:04 +0000</pubDate><guid>https://blog.ezyang.com/2010/12/a-year-of-blogging/</guid><description>&lt;p>Here is to celebrate a year of blogging. Thank you all for reading. It was only &lt;a href="http://blog.ezyang.com/2009/12/iron-blogger/">a year ago&lt;/a> that I first opened up shop under the wings of Iron Blogger. Iron Blogger has mostly disintegrated at this point, but I’m proud to say that this blog has not, publishing thrice a week, every week (excepting that one time I missed a post and made it up with a bonus post later that month), a bet that I made with myself and am happy to have won.&lt;/p></description></item><item><title>Greetings from Switzerland</title><link>https://blog.ezyang.com/2010/12/greetings-from-switzerland/</link><pubDate>Wed, 29 Dec 2010 14:25:35 +0000</pubDate><guid>https://blog.ezyang.com/2010/12/greetings-from-switzerland/</guid><description>&lt;div class="container center">
&lt;p>“Roughing it,” so to speak.&lt;/p>
&lt;/div>
&lt;p>&lt;img src="https://blog.ezyang.com/img/switzerland/roughing.jpg" alt="image">&lt;/p>
&lt;p>With no reservations and no place to go, the hope was to crash somewhere in the Jungfrau region above the “fogline”&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/switzerland/fog.jpg" alt="image">&lt;/p>
&lt;p>but these plans were thwarted by my discovery that Wengen had no hostels. Ah well.&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/switzerland/pretty1.jpg" alt="image">&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/switzerland/pretty2.jpg" alt="image">&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/switzerland/pretty3.jpg" alt="image">&lt;/p>
&lt;p>Still pretty.&lt;/p>
&lt;p>Of which I do not have a photo, one of the astonishing sights from Lauterbrunnen at night (I checked in and asked the owner, “Any open beds?” They replied, “One!” Only one possible response: “Excellent!”) is that the towns and trains interspersed on the mountains almost look like stars (the mountain hidden from view, due to their sparseness), clustered together in chromatic galaxies.&lt;/p></description></item><item><title>No one expects the Scott induction!</title><link>https://blog.ezyang.com/2010/12/no-one-expects-the-scott-induction/</link><pubDate>Mon, 27 Dec 2010 09:00:42 +0000</pubDate><guid>https://blog.ezyang.com/2010/12/no-one-expects-the-scott-induction/</guid><description>&lt;blockquote>
&lt;p>New to this series? Start at &lt;a href="http://blog.ezyang.com/2010/12/hussling-haskell-types-into-hasse-diagrams/">the beginning!&lt;/a>&lt;/p>&lt;/blockquote>
&lt;p>Recursion is perhaps one of the first concepts you learn about when you learn functional programming (or, indeed, computer science, one hopes.) The classic example introduced is factorial:&lt;/p>
&lt;pre>&lt;code>fact :: Int -&amp;gt; Int
fact 0 = 1 -- base case
fact n = n * fact (pred n) -- recursive case
&lt;/code>&lt;/pre>
&lt;p>Recursion on natural numbers is closely related to induction on natural numbers, as is &lt;a href="http://scienceblogs.com/goodmath/2007/01/basics_recursion_and_induction_1.php">explained here&lt;/a>.&lt;/p></description></item><item><title>Thriller: Doing it for the thrills</title><link>https://blog.ezyang.com/2010/12/thriller/</link><pubDate>Fri, 24 Dec 2010 09:00:28 +0000</pubDate><guid>https://blog.ezyang.com/2010/12/thriller/</guid><description>&lt;p>How do you decide what to work on? I started thinking about this topic when I was wasting time on the Internet because I couldn’t think of anything to do that was productive. This seemed kind of strange: there were lots of things I &lt;em>needed&lt;/em> to do: vacations to plan, projects to work on, support requests to answer, patches to merge in, theorems to prove, blog posts to write, papers to read, etc. So maybe the problem wasn’t that I didn’t have anything to do, it was just that I had too much stuff to do, and that I needed to pick something.&lt;/p></description></item><item><title>Travel advisory</title><link>https://blog.ezyang.com/2010/12/travel-advisory/</link><pubDate>Tue, 21 Dec 2010 04:36:05 +0000</pubDate><guid>https://blog.ezyang.com/2010/12/travel-advisory/</guid><description>&lt;p>I will be in the following places at the following times:&lt;/p>
&lt;ul>
&lt;li>Paris up until evening of 12/22&lt;/li>
&lt;li>Berlin from 12/23 to 12/24&lt;/li>
&lt;li>Dresden on 12/24&lt;/li>
&lt;li>Munich from 12/25 to 12/26&lt;/li>
&lt;li>Zurich on 12/27&lt;/li>
&lt;li>Lucerne from 12/28 to 12/29&lt;/li>
&lt;/ul>
&lt;p>Plans over the New Year are still a little mushy, so I’ll post another update then. Let me know if you’d like to meet up!&lt;/p>
&lt;p>&lt;em>Non sequitur.&lt;/em> I went to the Mondrian exhibition at Centre Pompidou, and this particular gem, while not in the exhibition itself (it was in the female artists collection), I couldn’t resist snapping a photo of.&lt;/p></description></item><item><title>Generalization and vagueness in specifications</title><link>https://blog.ezyang.com/2010/12/generalization-and-vagueness-in-specifications/</link><pubDate>Mon, 20 Dec 2010 09:00:35 +0000</pubDate><guid>https://blog.ezyang.com/2010/12/generalization-and-vagueness-in-specifications/</guid><description>&lt;div class="container center">
&lt;p>&lt;em>What semantics has to say about specifications&lt;/em>&lt;/p>
&lt;/div>
&lt;p>Conventional wisdom is that premature generalization is bad (architecture astronauts) and vague specifications are appropriate for top-down engineering but not bottom-up. Can we say something a little more precise about this?&lt;/p>
&lt;p>Semantics are formal specifications of programming languages. They are perhaps some of the most well-studied forms of specifications, because computer scientists love tinkering with the tools they use. They also love having lots of semantics to pick from: the more the merrier. We have small-step and big-step operational semantics; we have axiomatic semantics and denotational semantics; we have game semantics, algebraic semantics and concurrency semantics. Describing the programs we actually write is difficult business, and it helps to have as many different explanations as possible.&lt;/p></description></item><item><title>Tourist by day, Blogger by night</title><link>https://blog.ezyang.com/2010/12/tourist-by-day-blogger-by-night/</link><pubDate>Fri, 17 Dec 2010 09:00:00 +0000</pubDate><guid>https://blog.ezyang.com/2010/12/tourist-by-day-blogger-by-night/</guid><description>&lt;div class="container center">
&lt;p>&lt;em>In which Edward travels France&lt;/em>&lt;/p>
&lt;/div>
&lt;p>Many, many years ago, I decided that I would study French rather than Spanish in High School. I wasn’t a particularly driven foreign language learner: sure I studied enough to get As (well, except for one quarter when I got a B+), but I could never convince myself to put enough importance on absorbing as much vocabulary and grammar as possible. Well, now I’m in France and this dusty, two-year old knowledge is finally being put to good use. And boy, am I wishing that I’d paid more attention in class.&lt;/p></description></item><item><title>ω: I’m lubbin’ it</title><link>https://blog.ezyang.com/2010/12/omega-i-m-lubbin-it/</link><pubDate>Wed, 15 Dec 2010 09:00:14 +0000</pubDate><guid>https://blog.ezyang.com/2010/12/omega-i-m-lubbin-it/</guid><description>&lt;blockquote>
&lt;p>New to this series? Start at &lt;a href="http://blog.ezyang.com/2010/12/hussling-haskell-types-into-hasse-diagrams/">the beginning!.&lt;/a>&lt;/p>&lt;/blockquote>
&lt;p>Today we’re going to take a closer look at a somewhat unusual data type, Omega. In the process, we’ll discuss how the &lt;a href="http://hackage.haskell.org/package/lub">lub&lt;/a> library works and how you might go about using it. This is of practical interest to lazy programmers, because lub is a great way to &lt;em>modularize&lt;/em> laziness, in Conal’s words.&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/hasse3/omega.png" alt="image">&lt;/p>
&lt;p>Omega is a lot like the natural numbers, but instead of an explicit &lt;code>Z&lt;/code> (zero) constructor, we use bottom instead. Unsurprisingly, this makes the theory easier, but the practice harder (but not too much harder, thanks to Conal’s lub library). We’ll show how to implement addition, multiplication and factorial on this data type, and also show how to prove that subtraction and equality (even to vertical booleans) are uncomputable.&lt;/p></description></item><item><title>Getting a fix on fixpoints</title><link>https://blog.ezyang.com/2010/12/getting-a-fix-on-fixpoints/</link><pubDate>Mon, 13 Dec 2010 09:00:20 +0000</pubDate><guid>https://blog.ezyang.com/2010/12/getting-a-fix-on-fixpoints/</guid><description>&lt;p>Previously, we’ve &lt;a href="http://blog.ezyang.com/2010/12/hussling-haskell-types-into-hasse-diagrams/">drawn Hasse diagrams of all sorts of Haskell types&lt;/a>, from data types to function types, and looked at &lt;a href="http://blog.ezyang.com/2010/12/gin-and-monotonic/">the relationship between computability and monotonicity&lt;/a>. In fact, all computable functions are monotonic, but not all monotonic functions are computable. Is there some description of functions that entails computability? Yes: &lt;em>Scott continuous functions.&lt;/em> In this post, we look at the mathematical machinery necessary to define &lt;em>continuity&lt;/em>. In particular, we will look at least upper bounds, chains, chain-complete partial orders (CPOs) and domains. We also look at fixpoints, which arise naturally from continuous functions.&lt;/p></description></item><item><title>Errata for gin and monotonic</title><link>https://blog.ezyang.com/2010/12/errata-for-gin-and-monotonic/</link><pubDate>Fri, 10 Dec 2010 09:00:25 +0000</pubDate><guid>https://blog.ezyang.com/2010/12/errata-for-gin-and-monotonic/</guid><description>&lt;p>Between packing and hacking on GHC, I didn’t have enough time to cough up the next post of the series or edit the pictures for the previous post, so all you get today is a small errata post.&lt;/p>
&lt;ul>
&lt;li>The full list diagram is missing some orderings: ★:⊥ ≤ ★:⊥:⊥ and so on.&lt;/li>
&lt;li>In usual denotational semantics, you can’t distinguish between ⊥ and &lt;code>λ_.⊥&lt;/code>. However, as Anders Kaseorg and the Haskell Report point out, with &lt;code>seq&lt;/code> you can distinguish them. This is perhaps the true reason why seq is a kind of nasty function. I’ve been assuming the stronger guarantee (which is what zygoloid pointed out) when it’s not actually true for Haskell.&lt;/li>
&lt;li>The “ought to exist” arrow in the halts diagram goes the wrong direction.&lt;/li>
&lt;li>In the same fashion of the full list diagram, &lt;code>head&lt;/code> is missing some orderings, so in fact they gray blob is entirely connected. There are situations when we can have disconnected blobs, but not for a domain with only one maximum.&lt;/li>
&lt;li>Obvious typo for fst.&lt;/li>
&lt;li>The formal partial order on functions was not defined correctly: it originally stated that for f ≤ g, f(x) = g(x); actually, it’s weaker than that: f(x) ≤ g(x).&lt;/li>
&lt;li>A non-erratum: the right-side of the head diagram is omitted because&amp;hellip; adding all the arrows makes it look pretty ugly. Here is the sketch I did before I decided it wasn’t a good picture.&lt;/li>
&lt;/ul>
&lt;p>&lt;img src="https://blog.ezyang.com/img/hasse2/head-ugly.png" alt="image">&lt;/p></description></item><item><title>Gin and monotonic</title><link>https://blog.ezyang.com/2010/12/gin-and-monotonic/</link><pubDate>Wed, 08 Dec 2010 09:00:02 +0000</pubDate><guid>https://blog.ezyang.com/2010/12/gin-and-monotonic/</guid><description>&lt;div class="container center">
&lt;p>&lt;em>Gin, because you’ll need it by the time you’re done reading this.&lt;/em>&lt;/p>
&lt;/div>
&lt;p>&lt;a href="http://blog.ezyang.com/2010/12/hussling-haskell-types-into-hasse-diagrams/">Last time&lt;/a> we looked the partial orders of values for data types. There are two extra things I would like to add: an illustration of how star-subscript-bottom expands and an illustration of list without using the star-subscript-bottom notation.&lt;/p>
&lt;p>Here is a triple of star-subscript-bottoms expanded, resulting in the familiar Hasse diagram of the powerset of a set of three elements ordered by inclusion:&lt;/p></description></item><item><title>Hussling Haskell types into Hasse diagrams</title><link>https://blog.ezyang.com/2010/12/hussling-haskell-types-into-hasse-diagrams/</link><pubDate>Mon, 06 Dec 2010 09:00:24 +0000</pubDate><guid>https://blog.ezyang.com/2010/12/hussling-haskell-types-into-hasse-diagrams/</guid><description>&lt;p>Values of Haskell types form a partial order. We can illustrate this partial order using what is called a &lt;a href="http://en.wikipedia.org/wiki/Hasse_diagram">Hasse diagram&lt;/a>. These diagrams are quite good for forcing yourself to explicitly see the bottoms lurking in every type. Since my &lt;a href="http://blog.ezyang.com/2010/12/how-i-learned-to-stop-worrying-and-love-the-bottom/">last post about denotational semantics&lt;/a> failed to elicit much of a response at all, I decided that I would have better luck with some more pictures. After all, everyone loves pictures!&lt;/p>
&lt;hr>
&lt;p>We’ll start off with something simple: &lt;code>()&lt;/code> or unit.&lt;/p></description></item><item><title>Talk Friday</title><link>https://blog.ezyang.com/2010/12/talk-friday/</link><pubDate>Fri, 03 Dec 2010 09:00:25 +0000</pubDate><guid>https://blog.ezyang.com/2010/12/talk-friday/</guid><description>&lt;p>I’ve had the pleasure of attending a number of really interesting talks over the past few months, so many that I couldn’t find time to write thorough articles for each of them as I did over the summer. So you’ll have to forgive me for putting two of them in compressed form here. There is something of a common theme of recasting a problem on a different input domain in order to achieve results, as I hope will become evident by these summaries.&lt;/p></description></item><item><title>How I Learned to Stop Worrying and Love the ⊥</title><link>https://blog.ezyang.com/2010/12/how-i-learned-to-stop-worrying-and-love-the-bottom/</link><pubDate>Wed, 01 Dec 2010 09:00:09 +0000</pubDate><guid>https://blog.ezyang.com/2010/12/how-i-learned-to-stop-worrying-and-love-the-bottom/</guid><description>&lt;div class="container center">
&lt;p>&lt;em>An extended analogy on the denotational and game semantics of ⊥&lt;/em>&lt;/p>
&lt;/div>
&lt;p>This is an attempt at improving on the &lt;a href="http://en.wikibooks.org/wiki/Haskell/Denotational_semantics">Haskell Wikibooks article on Denotational Semantics&lt;/a> by means of a Dr. Strangelove inspired analogy.&lt;/p>
&lt;hr>
&lt;p>&lt;em>The analogy.&lt;/em> In order to prevent Brigadier General Jack D. Ripper from initiating a nuclear attack on Russia, the Pentagon decides that it will be best if every nuclear weapon requires two separate keys in order to be activated, both of which should not be known by the same person at the same time under normal circumstances. Alice is given one half of the key, Bob the other half. If Ripper asks Alice for her half of the key, she can tell him her key, A. However, asking Alice for Bob’s key won’t work, since she doesn&amp;rsquo;t know what Bob&amp;rsquo;s key is.&lt;/p></description></item><item><title>My first proof in Isabelle</title><link>https://blog.ezyang.com/2010/11/my-first-proof-in-isabelle/</link><pubDate>Mon, 29 Nov 2010 09:00:28 +0000</pubDate><guid>https://blog.ezyang.com/2010/11/my-first-proof-in-isabelle/</guid><description>&lt;p>One of the distinctive differences between academic institutions in the United States and in Great Britain is the supplementary learning outside of lectures. We have &lt;em>recitations&lt;/em> in the US, which are something like extra lectures, while in the UK they have &lt;em>tutorials&lt;/em>, or &lt;em>supervisions&lt;/em> as they are called in Cambridge parlance. As always, they are something of a mixed bag: some supervisors are terrible, others are merely competent, and others inspire and encourage a sort of interest in the subject far beyond the outlines of the course.&lt;/p></description></item><item><title>Reflexivity. Qed.</title><link>https://blog.ezyang.com/2010/11/reflexivity-qed/</link><pubDate>Fri, 26 Nov 2010 09:00:24 +0000</pubDate><guid>https://blog.ezyang.com/2010/11/reflexivity-qed/</guid><description>&lt;div class="container center">
&lt;p>&lt;em>In which Mendeley, Software Foundations and Coq are discussed.&lt;/em>&lt;/p>
&lt;/div>
&lt;p>I was grousing on &lt;code>#haskell-blah&lt;/code> one day about how annoying it was to organize all of the papers that I have downloaded (and, of course, not read yet.) When you download a paper off the Internet, it will be named all sorts of tremendously unhelpful things like &lt;code>2010.pdf&lt;/code> or &lt;code>icfp10.pdf&lt;/code> or &lt;code>paper.pdf&lt;/code>. So to have any hope of finding that paper which you skimmed a month ago and vaguely recall the title of, you&amp;rsquo;ll need some sort of organization system. Pre-Mendeley, I had adopted the convention of &lt;code>AuthorName-PaperTitle.pdf&lt;/code>, but I&amp;rsquo;d always feel a bit bad picking an author out of a list of five people to stick at the beginning, and I still couldn&amp;rsquo;t ever find the paper I was looking for.&lt;/p></description></item><item><title>Integer sequences every computer scientist should know?</title><link>https://blog.ezyang.com/2010/11/integer-sequences-every-computer-scientist-should-know/</link><pubDate>Wed, 24 Nov 2010 09:00:09 +0000</pubDate><guid>https://blog.ezyang.com/2010/11/integer-sequences-every-computer-scientist-should-know/</guid><description>&lt;p>The &lt;a href="http://oeis.org/Seis.html">On-Line Encyclopedia of Integer Sequences&lt;/a> is quite a nifty website. Suppose that you’re solving a problem, and you come up with the following sequence of integers: &lt;code>0, 1, 0, 2, 0, 1, 0, 3, 0, 1, 0, 2...&lt;/code> and you wonder to yourself: “huh, what’s that sequence?” Well, just &lt;a href="http://oeis.org/search?q=0%2C+1%2C+0%2C+2%2C+0%2C+1%2C+0%2C+3%2C+0%2C+1%2C+0%2C+2&amp;amp;sort=&amp;amp;language=english&amp;amp;go=Search">type it in&lt;/a> and the answer comes back: &lt;a href="http://oeis.org/A007814">A007814&lt;/a>, along with all sorts of tasty tidbits like constructions, closed forms, mathematical properties, and more. Even simple sequences like &lt;a href="http://oeis.org/A000079">powers of two&lt;/a> have a bazillion alternate interpretations and generators.&lt;/p></description></item><item><title>Is multiply-carry strongly universal?</title><link>https://blog.ezyang.com/2010/11/is-multiply-carry-strongly-universal/</link><pubDate>Mon, 22 Nov 2010 09:00:33 +0000</pubDate><guid>https://blog.ezyang.com/2010/11/is-multiply-carry-strongly-universal/</guid><description>&lt;p>I’ve been wanting to implement a &lt;a href="http://www.eecs.harvard.edu/~michaelm/CS222/countmin.pdf">count-min sketch&lt;/a> for some time now; it’s a little less widely known than the bloom filter, a closely related &lt;em>sketch&lt;/em> data structure (that is, a probabilistic data structure that approximates answers to certain queries), but it seems like a pretty practical structure and has been used in &lt;a href="http://research.microsoft.com/pubs/132859/popularityISeverything.pdf">some interesting ways&lt;/a>.&lt;/p>
&lt;p>Alas, when you want to implement a data structure that was proposed less than a decade ago and hasn’t found its way into textbooks yet, there are a lot of theoretical vagaries that get in the way. In this particular case, the theoretical vagary was selection of a &lt;em>universal hash family.&lt;/em> Having not taken a graduate-level algorithms course yet, I did not know what a universal hash family was, so it was off to the books for me.&lt;/p></description></item><item><title>Cambridge potpourri</title><link>https://blog.ezyang.com/2010/11/cambridge-potpourri/</link><pubDate>Fri, 19 Nov 2010 09:00:39 +0000</pubDate><guid>https://blog.ezyang.com/2010/11/cambridge-potpourri/</guid><description>&lt;div class="container center">
&lt;p>&lt;em>In which Edward tells some stories about Cambridge and posts lots of pictures.&lt;/em>&lt;/p>
&lt;/div>
&lt;p>Apparently, &lt;a href="http://projects.csail.mit.edu/gsb/archives/gsb-msg00111.html">Alyssa B. Hacker&lt;/a> (sic) went on the Cambridge-MIT exchange.&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/cambridge/alyssa-b-hacker.jpeg" alt="image">&lt;/p>
&lt;hr>
&lt;p>This is perhaps a phenomenon of having been around MIT for too long, a campus which has a reputation for not being too picturesque (I can probably count the actually pretty spots on campus with one hand), but it’s real easy to stop appreciating how nice the buildings and architecture are around here. Look!&lt;/p></description></item><item><title>Haskell.org committee</title><link>https://blog.ezyang.com/2010/11/haskell-org-committee/</link><pubDate>Wed, 17 Nov 2010 09:00:40 +0000</pubDate><guid>https://blog.ezyang.com/2010/11/haskell-org-committee/</guid><description>&lt;p>Ever try to go to haskell.org and notice that it was down? Well, now you have someone to complain to: the &lt;a href="http://haskellorg.wordpress.com/2010/11/15/the-haskell-org-committee-has-formed/">haskell.org committee&lt;/a> has formed and apparently I’m on it. &lt;code>8-)&lt;/code>&lt;/p>
&lt;p>One of the first things we’ll be doing is moving haskell.org from a server being hosted at Yale (the hosting has been good, but what will happen is the server will go down during the weekend and there will be no one to kick it until Monday) to some &lt;a href="http://new-www.haskell.org/haskellwiki/Haskell">dedicated hardware&lt;/a>. I must admit, I do feel a bit sheepish for being on the committee but not having any bits (or direct experience) to help do the maintenance work—hopefully that will change soon.&lt;/p></description></item><item><title>It's just a longjmp to the left</title><link>https://blog.ezyang.com/2010/11/its-just-a-longjmp-to-the-left/</link><pubDate>Mon, 15 Nov 2010 09:00:56 +0000</pubDate><guid>https://blog.ezyang.com/2010/11/its-just-a-longjmp-to-the-left/</guid><description>&lt;div class="container center">
&lt;p>&lt;em>And then a signal to the ri-i-i-ight.&lt;/em>&lt;/p>
&lt;/div>
&lt;p>One notable wart with readline is that if you &lt;code>^C&lt;/code> during the prompt, nothing happens, and if you do a second &lt;code>^C&lt;/code> (and weren’t buggering around with the signal handlers) your entire program unceremoniously terminates. That’s not very nice! Fortunately, &lt;code>readline&lt;/code> appears to be one of the rare C libraries that actually put some work into making sure that you could longjmp out of a signal handler and not completely break the library’s internal state (they do this with liberal masking and unmasking, and their own signal handler which cleans up and then rethrows the signal).&lt;/p></description></item><item><title>You are in a maze of twisty little passages, all alike... (a GHC hacking post)</title><link>https://blog.ezyang.com/2010/11/another-ghc-hacking-post/</link><pubDate>Fri, 12 Nov 2010 09:00:00 +0000</pubDate><guid>https://blog.ezyang.com/2010/11/another-ghc-hacking-post/</guid><description>&lt;p>About a month ago I decided that it would be cool if I could solve the bug &lt;a href="http://hackage.haskell.org/trac/ghc/ticket/4262">GHC&amp;rsquo;s runtime never terminates unused worker threads&lt;/a>. Well, I just got around to looking at it today, and after wandering aimlessly around the twisty maze that is the GHC RTS for an hour or so, I finally found a light at the end of a tunnel, in the form of a heart-warmingly simple patch. I’ve sent mail off to Simon Marlow to make sure the light isn’t actually a train, but it occurred to me that it would be interesting to look at my command history and blog about the process by which I came to the conclusion that line 464 of &lt;code>Capability.c&lt;/code> was the correct place to add my change, since this sort of mental journey is not the one that is really ever recorded anywhere in any shape or form.&lt;/p></description></item><item><title>mod_fcgid 2.3 is broken (fixed in 2.3.6)</title><link>https://blog.ezyang.com/2010/11/mod_fcgid-is-broke/</link><pubDate>Wed, 10 Nov 2010 09:00:48 +0000</pubDate><guid>https://blog.ezyang.com/2010/11/mod_fcgid-is-broke/</guid><description>&lt;p>This is a post to get some Google juice for a problem that basically prevented &lt;a href="http://scripts.mit.edu">Scripts&lt;/a> from being able to cut over from Fedora 11 to Fedora 13. The cluster of new machines kept falling over from load, and we kept scratching our heads, wondering, “Why?”&lt;/p>
&lt;p>Turns out, the &lt;a href="http://svn.apache.org/viewvc?view=revision&amp;amp;revision=753578">following commit&lt;/a> broke mod_fcgid in a pretty terrifying way: essentially, mod_fcgid is unable to manage the pools of running FastCGI processes, so it keeps spawning new ones until the system runs out of memory. This is especially obvious in systems with large amounts of generated virtual hosts, i.e. people using mod_vhost_ldap. It got fixed in mod_fcgid 2.3.6, which was released last weekend.&lt;/p></description></item><item><title>Medieval medicine and computers</title><link>https://blog.ezyang.com/2010/11/medieval-medicine-and-computers/</link><pubDate>Mon, 08 Nov 2010 09:00:15 +0000</pubDate><guid>https://blog.ezyang.com/2010/11/medieval-medicine-and-computers/</guid><description>&lt;p>This is a bit of a provocative post, and its impressions (I dare not promote them to the level of &lt;em>conclusions&lt;/em>) should be taken with the amount of salt found in a McDonald’s Happy Meal. Essentially, I was doing some reading about medieval medicine and was struck by some of the similarities between it and computer engineering, which I attempt to describe below.&lt;/p>
&lt;p>&lt;em>Division between computer scientists and software engineers.&lt;/em> The division between those who studied medicine, the &lt;em>physics&lt;/em> (a name derived from physica or natural science) and those who practiced medicine, the &lt;em>empirics&lt;/em>, was extremely pronounced. There was a mutual distrust—Petrarch wrote, “I have never believed in doctors nor ever will” (Porter 169)—that stemmed in part from the social division between the physics and empirics. Physics would have obtained a doctorate from a university, having studied one of the highest three faculties possible (the others being theology and law), and tended to be among the upper strata of society. In fact, the actual art of medicine was not considered “worthy of study,” though the study of natural science was. (Cook 407).&lt;/p></description></item><item><title>DP Zoo Tour</title><link>https://blog.ezyang.com/2010/11/dp-zoo-tour/</link><pubDate>Fri, 05 Nov 2010 09:00:46 +0000</pubDate><guid>https://blog.ezyang.com/2010/11/dp-zoo-tour/</guid><description>&lt;div class="container center">
&lt;p>&lt;em>Someone told me it’s all happening at the zoo&amp;hellip;&lt;/em>&lt;/p>
&lt;/div>
&lt;p>I’ve always thought &lt;em>dynamic programming&lt;/em> was a pretty crummy name for the practice of storing sub-calculations to be used later. Why not call it &lt;em>table-filling algorithms&lt;/em>, because indeed, thinking of a dynamic programming algorithm as one that fills in a table is a quite good way of thinking about it.&lt;/p>
&lt;p>In fact, you can almost completely characterize a dynamic programming algorithm by the shape of its table and how the data flows from one cell to another. And if you know what this looks like, you can often just read off the complexity without knowing anything about the problem.&lt;/p></description></item><item><title>Dead Edward Day</title><link>https://blog.ezyang.com/2010/11/dead-edward-day/</link><pubDate>Wed, 03 Nov 2010 09:00:02 +0000</pubDate><guid>https://blog.ezyang.com/2010/11/dead-edward-day/</guid><description>&lt;p>Should software engineers be required to implement the abstractions use before using them? (Much like how before you’re allowed to use a theorem in a math textbook, you have to prove it first.) A bit like reinventing the wheel for pedagogical purposes.&lt;/p>
&lt;p>(I&amp;rsquo;ve been sick since Saturday, so it’s a Dead Edward Day. Hopefully I’ll clean up the DP Zoo post and present it with more annotations for this Friday.)&lt;/p></description></item><item><title>DP Zoo</title><link>https://blog.ezyang.com/2010/11/dp-zoo/</link><pubDate>Mon, 01 Nov 2010 09:00:09 +0000</pubDate><guid>https://blog.ezyang.com/2010/11/dp-zoo/</guid><description>&lt;p>&lt;img src="https://blog.ezyang.com/img/dp-zoo/path.png" alt="image">&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/dp-zoo/matrix.png" alt="image">&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/dp-zoo/subsequence.png" alt="image">&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/dp-zoo/binary.png" alt="image">&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/dp-zoo/bitonic.png" alt="image">&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/dp-zoo/text.png" alt="image">&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/dp-zoo/edit.png" alt="image">&lt;/p></description></item><item><title>Intelligence is the ability to make finer distinctions: Another Haskell Advocacy Post</title><link>https://blog.ezyang.com/2010/10/finer-distinctions/</link><pubDate>Fri, 29 Oct 2010 09:00:13 +0000</pubDate><guid>https://blog.ezyang.com/2010/10/finer-distinctions/</guid><description>&lt;div class="container center">
&lt;p>&lt;em>I apologize in advance for another&lt;/em> &lt;a href="http://blog.ezyang.com/2010/01/why-haskell/">Haskell advocacy piece&lt;/a>&lt;/p>
&lt;/div>
&lt;p>My parents like foisting various self-help books on me, and while I sometimes groan to myself about it, I do read (or at least skim) them and extract useful bits of information out of them. This particular title quote is from Robert Kiyosaki’s “rich dad” in &lt;em>Rich Dad, Poor Dad.&lt;/em>&lt;/p>
&lt;p>“Intelligence is the ability to make finer distinctions” really spoke to me. I’ve since found it to be an extremely effective litmus test to determine if I’ve really understood something. A recent example comes from my concurrent systems class, where there are many extremely similar methods of mutual exclusion: mutexes, semaphores, critical regions, monitors, synchronized region, active objects, etc. True knowledge entails an understanding of the conceptual details differentiating these gadgets. What are the semantics of a &lt;em>signal&lt;/em> on a condition variable with no waiting threads? Monitors and synchronized regions will silently ignore the signal, thus requiring an atomic release-and-wait, whereas a semaphore will pass it on to the next &lt;em>wait&lt;/em>. Subtle.&lt;/p></description></item><item><title>Blog name changed...</title><link>https://blog.ezyang.com/2010/10/blog-name-changed/</link><pubDate>Wed, 27 Oct 2010 09:00:07 +0000</pubDate><guid>https://blog.ezyang.com/2010/10/blog-name-changed/</guid><description>&lt;p>&amp;hellip;because I don’t live in a room numbered 245s anymore. Yep. :-)&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/cow.jpg" alt="image">&lt;/p>
&lt;p>This is a cow. They munch grass next to the River Cam.&lt;/p>
&lt;p>&lt;em>Pop quiz&lt;/em>. What do matrix-chain multiplication, longest common subsequence, construction of optimal binary search trees, bitonic euclidean traveling-salesman, edit distance and the Viterbi algorithm have in common?&lt;/p></description></item><item><title>OCaml for Haskellers</title><link>https://blog.ezyang.com/2010/10/ocaml-for-haskellers/</link><pubDate>Mon, 25 Oct 2010 09:00:54 +0000</pubDate><guid>https://blog.ezyang.com/2010/10/ocaml-for-haskellers/</guid><description>&lt;p>I’ve started formally learning OCaml (I’ve been reading ML since Okasaki, but I’ve never written any of it), and here are some notes about differences from Haskell from Jason Hickey&amp;rsquo;s &lt;em>Introduction to Objective Caml&lt;/em>. The two most notable differences are that OCaml is &lt;em>impure&lt;/em> and &lt;em>strict.&lt;/em>&lt;/p>
&lt;hr>
&lt;p>&lt;em>Features.&lt;/em> Here are some features OCaml has that Haskell does not:&lt;/p>
&lt;ul>
&lt;li>OCaml has named parameters (&lt;code>~x:i&lt;/code> binds to &lt;code>i&lt;/code> the value of named parameter &lt;code>x&lt;/code>, &lt;code>~x&lt;/code> is a shorthand for &lt;code>~x:x&lt;/code>).&lt;/li>
&lt;li>OCaml has optional parameters (&lt;code>?(x:i = default)&lt;/code> binds &lt;code>i&lt;/code> to an optional named parameter &lt;code>x&lt;/code> with default &lt;code>default&lt;/code>).&lt;/li>
&lt;li>OCaml has open union types (&lt;code>[&amp;gt; 'Integer of int | 'Real of float]&lt;/code> where the type holds the implementation; you can assign it to a type with &lt;code>type 'a number = [&amp;gt; 'Integer of int | 'Real of float] as a&lt;/code>). Anonymous closed unions are also allowed (&lt;code>[&amp;lt; 'Integer of int | 'Real of float]&lt;/code>).&lt;/li>
&lt;li>OCaml has mutable records (preface record field in definition with &lt;code>mutable&lt;/code>, and then use the &lt;code>&amp;lt;-&lt;/code> operator to assign values).&lt;/li>
&lt;li>OCaml has a module system (only briefly mentioned today).&lt;/li>
&lt;li>OCaml has native objects (not covered in this post).&lt;/li>
&lt;/ul>
&lt;hr>
&lt;p>&lt;em>Syntax.&lt;/em> Omission means the relevant language feature works the same way (for example, let &lt;code>f x y = x + y&lt;/code> is the same)&lt;/p></description></item><item><title>Don't Repeat Yourself is context dependent</title><link>https://blog.ezyang.com/2010/10/dry-is-context-dependen/</link><pubDate>Fri, 22 Oct 2010 09:00:52 +0000</pubDate><guid>https://blog.ezyang.com/2010/10/dry-is-context-dependen/</guid><description>&lt;p>I am a member of a group called the &lt;a href="http://web.mit.edu/assassin/www/">Assassins’ Guild&lt;/a>. No, we don’t kill people, and no, we don’t play the game Assassin. Instead, we write and run competitive live action role-playing games: you get some game rules describing the universe, a character sheet with goals, abilities and limitations, and we set you loose for anywhere from four hours to ten days. In this context, I’d like to describe a situation where applying the rule &lt;a href="http://en.wikipedia.org/wiki/Don't_repeat_yourself">Don’t Repeat Yourself&lt;/a> can be harmful.&lt;/p></description></item><item><title>Purpose of proof: semi-formal methods</title><link>https://blog.ezyang.com/2010/10/purpose-of-proof-sem-formal-methods/</link><pubDate>Wed, 20 Oct 2010 09:00:42 +0000</pubDate><guid>https://blog.ezyang.com/2010/10/purpose-of-proof-sem-formal-methods/</guid><description>&lt;p>In which the author muses that “semi-formal methods” (that is, non computer-assisted proof writing) should take a more active role in allowing software engineers to communicate with one another.&lt;/p>
&lt;hr>
&lt;p>&lt;a href="http://en.wikipedia.org/wiki/C%2B%2B0x">C++0x&lt;/a> has a lot of new, whiz-bang features in it, one of which is the atomic operations library. This library has advanced features that enable compiler writers and concurrency library authors to take advantage of a relaxed memory model, resulting in blazingly fast concurrent code.&lt;/p></description></item><item><title>Rapidly prototyping scripts in Haskell</title><link>https://blog.ezyang.com/2010/10/rapid-prototyping-in-haskell/</link><pubDate>Mon, 18 Oct 2010 09:00:08 +0000</pubDate><guid>https://blog.ezyang.com/2010/10/rapid-prototyping-in-haskell/</guid><description>&lt;p>I’ve been having some vicious fun over the weekend hacking up a little tool called &lt;a href="http://github.com/ezyang/mmr-hammer">MMR Hammer&lt;/a> in Haskell. I won’t bore you with the vagaries of multimaster replication with Fedora Directory Server; instead, I want to talk about rapidly prototyping scripts in Haskell—programs that are characterized by a low amount of computation and a high amount of IO. Using this script as a case study, I’ll describe how I approached the problem, what was easy to do and what took a little more coaxing. In particular, my main arguments are:&lt;/p></description></item><item><title>Existential type-curry</title><link>https://blog.ezyang.com/2010/10/existential-type-curry/</link><pubDate>Fri, 15 Oct 2010 09:00:02 +0000</pubDate><guid>https://blog.ezyang.com/2010/10/existential-type-curry/</guid><description>&lt;p>This post is for those of you have always wondered why we have a &lt;code>forall&lt;/code> keyword in Haskell but no &lt;code>exists&lt;/code> keyword. Most of the existing tutorials on the web take a very &lt;em>operational&lt;/em> viewpoint to what an existential type is, and show that placing the forall in the “right place” results in the correct behavior. I’m going to take a different approach and use the Curry-Howard isomorphism to explain the translation. Some of the logic examples are shamelessly stolen from Aaron Coble’s Logic and Proof lecture notes.&lt;/p></description></item><item><title>Quote Day</title><link>https://blog.ezyang.com/2010/10/quote-day/</link><pubDate>Wed, 13 Oct 2010 09:00:56 +0000</pubDate><guid>https://blog.ezyang.com/2010/10/quote-day/</guid><description>&lt;p>Unattributed to protect the innocent. (But you can probably guess.)&lt;/p>

&lt;p>“And so these poor programmers, they had to drink this much whiskey to get the job done.” [triumphantly produces a bottle of whiskey and places it on the table.] “And this group of programmers did X, and how hard was that? Two bottles of whiskey.” [places two more bottles of whiskey on the table] “But that wasn’t fast enough. And so this group of programmers did Y. Four bottles of whiskey.” [four more bottles appear] “As you can see, this is requiring an exponentially increasing amount of whiskey.”&lt;/p></description></item><item><title>Why being a sysadmin will help you do Science!</title><link>https://blog.ezyang.com/2010/10/why-being-a-sysadmin-will-help-you-do-scienc/</link><pubDate>Mon, 11 Oct 2010 09:00:40 +0000</pubDate><guid>https://blog.ezyang.com/2010/10/why-being-a-sysadmin-will-help-you-do-scienc/</guid><description>&lt;p>A complaint I once heard about SIPB is that it leans too much towards the system administration side: we proudly display the services we have deployed and neglect to talk very much about actually programming or conducting novel computer science research (despite the fact that we are very much programmers and some of us are quite research oriented.) So if you’re really not at all interested in that sort of thing (like me) you might think to yourself, “That’s very nice” and go and do something else.&lt;/p></description></item><item><title>The HTML purification manifesto</title><link>https://blog.ezyang.com/2010/10/the-html-purification-manifesto/</link><pubDate>Fri, 08 Oct 2010 09:00:07 +0000</pubDate><guid>https://blog.ezyang.com/2010/10/the-html-purification-manifesto/</guid><description>&lt;p>I recently sent Greg Weber an email about his &lt;a href="http://github.com/gregwebs/haskell-xss-sanitize">xss-sanitize&lt;/a> package, cautioning about his reuse of the pandoc sanitization algorithm for his own package. He responded (with good justification) that a mere caution was not very constructive! So here is my response, the “HTML purification manifesto,” which HTML Purifier follows and which I think is a prerequisite for any industrial grade HTML sanitization library. I will admit it’s a tough manifesto to follow, and I’ll talk about when you can get away with not following it to the line.&lt;/p></description></item><item><title>Abstraction without a concrete concept</title><link>https://blog.ezyang.com/2010/10/beyond-generalizatio/</link><pubDate>Wed, 06 Oct 2010 09:00:28 +0000</pubDate><guid>https://blog.ezyang.com/2010/10/beyond-generalizatio/</guid><description>&lt;p>&lt;a href="http://en.wikipedia.org/wiki/Hoare_logic">Hoare logic&lt;/a>, despite its mathematical sounding name, is actually a quite practical way of reasoning about programs that most software engineers subconsciously employ in the form of preconditions and postconditions. It explicitly axiomatizes things that are common sense to a programmer: for example, a NOP should not change any conditions, or if a line of code has a postcondition that another line of code has as its precondition, those lines of code can be executed one after another and the inner precondition-postcondition pair ignored. Even if you never actually write out the derivation chains, you’re informally applying Hoare logic when you are trying to review code that uses preconditions and postconditions. Hoare logic is an abstraction that lets us rigorously talk about any imperative language with the same set of rules.&lt;/p></description></item><item><title>Why I am in Cambridge</title><link>https://blog.ezyang.com/2010/10/why-i-m-in-cambridge/</link><pubDate>Mon, 04 Oct 2010 09:00:10 +0000</pubDate><guid>https://blog.ezyang.com/2010/10/why-i-m-in-cambridge/</guid><description>&lt;p>I am studying computer science this academic year at Cambridge University, not MIT. For some people, this seems quite strange: when I tell old friends at MIT and new acquaintances at Cambridge about the fact that I am a Cambridge-MIT Exchange student, they say, “Why?” Sometimes, it’s some disbelief at the fact that I am choosing to leave the familiar social circles and situations that mark MIT. Other times, it’s some disbelief that I would want to study computer science at Cambridge rather than MIT (“Just joking,” they add, though I’m not necessarily sure I believe them.)&lt;/p></description></item><item><title>Tips for running a hackathon</title><link>https://blog.ezyang.com/2010/10/tips-for-running-a-hackatho/</link><pubDate>Fri, 01 Oct 2010 09:00:54 +0000</pubDate><guid>https://blog.ezyang.com/2010/10/tips-for-running-a-hackatho/</guid><description>&lt;p>A hackathon is an event, spanning from a day to a week, where hackers (not the cracking kind) get together to work on some common goals in concert. One use of a hackathon is to get some open-source contributors together and work hard on a particular feature: the combination of being together and being expected to work on the task at hand means that people are more productive than they would be if they were just working alone.&lt;/p></description></item><item><title>How to get answers from busy maintainers</title><link>https://blog.ezyang.com/2010/09/how-to-get-answers-from-busy-maintainers/</link><pubDate>Wed, 29 Sep 2010 09:00:45 +0000</pubDate><guid>https://blog.ezyang.com/2010/09/how-to-get-answers-from-busy-maintainers/</guid><description>&lt;p>As one of those “busy maintainers,” I’ve noticed that I assume a certain cognitive mode when fielding support requests. This post is about how I deal with support requests, but I’ve also seen this behavior widely on other projects. While, as the person making the request, you may find such a mentality frustrating and obtuse, if you are a fellow developer you can use it in your favor.&lt;/p>
&lt;p>What do I think when I see your support request?&lt;/p></description></item><item><title>So long America!</title><link>https://blog.ezyang.com/2010/09/so-long-america/</link><pubDate>Mon, 27 Sep 2010 09:00:18 +0000</pubDate><guid>https://blog.ezyang.com/2010/09/so-long-america/</guid><description>&lt;p>For tomorrow I get on a plane traversing three thousand miles from my home to a little place named Cambridge, United Kingdom. I’ll be studying abroad for the 2010-2011 academic year at Cambridge University (specifically, I’ll be at Fitzwilliam college). While I know Baltimore is &lt;a href="http://www.reddit.com/r/haskell/comments/diuhx/this_week_in_baltimore_icfp_haskell_symposium/">a fashionable place to be these days&lt;/a>, if you’re in the area, drop me a line: I’d love to meet up after I get over my jet lag. :-)&lt;/p></description></item><item><title>High performance monads</title><link>https://blog.ezyang.com/2010/09/high-performance-monads/</link><pubDate>Fri, 24 Sep 2010 09:00:51 +0000</pubDate><guid>https://blog.ezyang.com/2010/09/high-performance-monads/</guid><description>&lt;p>Continuations are well known for being notoriously tricky to use: they are the “gotos” of the functional programming world. They can make a mess or do amazing things (after all, what are exceptions but a well structured nonlocal goto). This post is intended for readers with a passing familiarity with continuations but a disbelief that they could be useful for their day-to-day programming tasks: I’d like to show how continuations let us define high performance monads ala the &lt;a href="http://hackage.haskell.org/package/logict">Logic monad&lt;/a> in a fairly methodical way. A (possibly) related post is &lt;a href="http://blog.sigfpe.com/2008/12/mother-of-all-monads.html">The Mother of all Monads&lt;/a>. :&lt;/p></description></item><item><title>Data is Code</title><link>https://blog.ezyang.com/2010/09/data-is-code/</link><pubDate>Wed, 22 Sep 2010 09:00:38 +0000</pubDate><guid>https://blog.ezyang.com/2010/09/data-is-code/</guid><description>&lt;p>Yesterday I had the pleasure of attending a colloquium given by &lt;a href="http://www.cs.rutgers.edu/~ccshan/">Chung-Chieh Shan&lt;/a> on &lt;a href="http://www.cs.rutgers.edu/news/colloquia/?action=view&amp;amp;colloquium_id=4263&amp;amp;organization_id=1">Embedding Probabilistic Languages&lt;/a>. A full account for the talk can be found in &lt;a href="http://okmij.org/ftp/kakuritu/dsl-paper.pdf">this paper&lt;/a>, so I want to focus in on one specific big idea: the idea that &lt;em>data is code.&lt;/em>&lt;/p>
&lt;hr>
&lt;p>Lispers are well acquainted with the mantra, “code is data,” the notion that behind every source code listing there is a data structure of cons-cells and tags representing the code that can constructed, modified and evaluated. With this framework, a very small set of data is code: &lt;code>'(cons 1 (cons 2 ()))&lt;/code> is code but &lt;code>'((.5 ((.5 #t) (.5 #f))) (.5 ((.5 #t))))&lt;/code> isn’t.&lt;/p></description></item><item><title>Tension of patch and tree version control</title><link>https://blog.ezyang.com/2010/09/tension-of-patch-and-tree-version-control/</link><pubDate>Mon, 20 Sep 2010 09:00:06 +0000</pubDate><guid>https://blog.ezyang.com/2010/09/tension-of-patch-and-tree-version-control/</guid><description>&lt;p>&lt;em>This post is not meant as a rag on Darcs, just a observation of the difference between two philosophies of version control. Also, I’m a bit new to Darcs, so there might be some factual inaccuracies. Please let me know about them!&lt;/em>&lt;/p>
&lt;p>At some point, I would like to write a &lt;em>Darcs for Git users&lt;/em> guide, distilling my experiences as an advanced Git user wrangling with Darcs. But perhaps the most important take away point is this: &lt;em>don’t try to superimpose Git’s underlying storage model on Darcs!&lt;/em> Once I realized this point, I found Darcs fit rather nicely with my preferred Git development style—constant rebasing of local patches until they hit the official repository.&lt;/p></description></item><item><title>Session types, subtyping and dependent types</title><link>https://blog.ezyang.com/2010/09/session-types-subtyping-and-dependent-types/</link><pubDate>Fri, 17 Sep 2010 09:00:09 +0000</pubDate><guid>https://blog.ezyang.com/2010/09/session-types-subtyping-and-dependent-types/</guid><description>&lt;p>While I was studying session type encodings, I noticed something interesting: the fact that session types, in their desire to capture protocol control flow, find themselves implementing something strongly reminiscent of dependent types.&lt;/p>
&lt;p>Any reasonable session type encoding requires the ability to denote choice: in Simon Gay’s paper this is the &lt;code>T-Case&lt;/code> rule, in Neubauer and Thiemann’s work it is the &lt;code>ALT&lt;/code> operator, in Pucella and Tov’s implementation it is the &lt;code>:+:&lt;/code> type operator, with the &lt;code>offer&lt;/code>, &lt;code>sel1&lt;/code> and &lt;code>sel2&lt;/code> functions. There is usually some note that a binary alternation scheme is—in terms of user interface—inferior to some name-based alternation between an arbitrary number of cases, but that the latter is much harder to implement.&lt;/p></description></item><item><title>Evolution of a Shared Web Host</title><link>https://blog.ezyang.com/2010/09/evolution-of-a-shared-web-host/</link><pubDate>Wed, 15 Sep 2010 09:00:03 +0000</pubDate><guid>https://blog.ezyang.com/2010/09/evolution-of-a-shared-web-host/</guid><description>&lt;p>&lt;em>Edward continues his spree of systems posts. Must be something in the Boston air.&lt;/em>&lt;/p>
&lt;p>Yesterday, I gave a &lt;a href="http://cluedumps.mit.edu/wiki/SIPB_Cluedump_Series">SIPB cluedump&lt;/a> on the use and implementation of &lt;a href="http://scripts.mit.edu">scripts.mit.edu&lt;/a>, the shared host service that SIPB provides to the MIT community. I derive essentially all of my sysadmin experience points from helping maintain this service.&lt;/p>
&lt;blockquote>
&lt;p>Scripts is SIPB’s shared hosting service for the MIT community. However, it does quite a bit more than your usual $10 host: what shared hosting services integrate directly with your Athena account, replicate your website on a cluster of servers managed by Linux-HA, let you request hostnames on *.mit.edu, or offer automatic installs of common web software, let you customize it, and still upgrade it for you? Scripts is a flourishing development platform, with over 2600 users and many interesting technical problems.&lt;/p></description></item><item><title>Keyword arguments in Haskell</title><link>https://blog.ezyang.com/2010/09/keyword-arguments-in-haskell/</link><pubDate>Mon, 13 Sep 2010 09:00:24 +0000</pubDate><guid>https://blog.ezyang.com/2010/09/keyword-arguments-in-haskell/</guid><description>&lt;p>Keyword arguments are generally considered a good thing by language designers: positional arguments are prone to errors of transposition, and it’s absolutely no fun trying to guess what the &lt;code>37&lt;/code> that is the third argument of a function &lt;em>actually&lt;/em> means. Python is one language that makes extensive use of keyword arguments; they have the following properties:&lt;/p>
&lt;ol>
&lt;li>Functions are permitted to be a mix of positional and keyword arguments (a nod to the compactness of positional arguments),&lt;/li>
&lt;li>Keywords are local to any given function; you can reuse a named function argument for another function,&lt;/li>
&lt;li>In Python 3.0, you can force certain arguments to &lt;em>only&lt;/em> be specifiable with a keyword.&lt;/li>
&lt;/ol>
&lt;p>Does Haskell have keyword arguments? In many ways, they’re much less necessary due to the static type system: if you accidentally interpose an &lt;code>Int&lt;/code> and &lt;code>Bool&lt;/code> your compiler will let you know about it. The type signature guides you!&lt;/p></description></item><item><title>Towards platform-agnostic interruptibility</title><link>https://blog.ezyang.com/2010/09/towards-platform-agnostic-interruptibility/</link><pubDate>Fri, 10 Sep 2010 09:00:47 +0000</pubDate><guid>https://blog.ezyang.com/2010/09/towards-platform-agnostic-interruptibility/</guid><description>&lt;p>Last post, I talked about some of the notable difficulties in &lt;a href="http://blog.ezyang.com/2010/09/pthread-cancel-on-window/">emulating pthread_cancel on Windows&lt;/a>. Today, I want to talk about what a platform agnostic compiler like GHC actually ought to do. Recall our three design goals:&lt;/p>
&lt;ol>
&lt;li>GHC would like to be able to put blocking IO calls on a worker thread but cancel them later; it can currently do this on Linux but not on Windows,&lt;/li>
&lt;li>Users would like to write interrupt friendly C libraries and have them integrate seamlessly with Haskell’s exception mechanism, and&lt;/li>
&lt;li>We’d like to have the golden touch of the IO world, instantly turning blocking IO code into nice, well-behaved, non-blocking, interruptible code.&lt;/li>
&lt;/ol>
&lt;p>I am going to discuss these three situations, described concisely as blocking system calls, cooperative libraries and blocking libraries. I propose that, due to the lack of a cross-platform interruption mechanism, the correct interruptibility interface is to permit user defined handlers for asynchronous exceptions.&lt;/p></description></item><item><title>pthread_cancel on Windows</title><link>https://blog.ezyang.com/2010/09/pthread-cancel-on-window/</link><pubDate>Wed, 08 Sep 2010 09:00:27 +0000</pubDate><guid>https://blog.ezyang.com/2010/09/pthread-cancel-on-window/</guid><description>&lt;blockquote>
&lt;p>Edward, I’m afraid I have some bad news. Your &lt;a href="http://blog.ezyang.com/2010/08/interrupting-ghc/">interruptible GHC patch&lt;/a>; it was involved in a terrible accident on the way to Windows portability. I hope you understand: we’re doing our best to patch it up, but there have been some complications&amp;hellip;&lt;/p>&lt;/blockquote>
&lt;p>Pop quiz! What does this pthreads code do? :&lt;/p>
&lt;pre>&lt;code>#include &amp;lt;pthread.h&amp;gt;
#include &amp;lt;stdio.h&amp;gt;

void *thread1(void *arg) { sleep(10000); }
void *thread2(void *arg) { while (1) {} }

void *psycho_killer(void *arg) {
 pthread_t *id = (pthread_t*)arg;
 pthread_cancel(*id);
 printf(&amp;quot;[%p] Psycho killer...\n&amp;quot;, id);
 pthread_join(*id, NULL);
 printf(&amp;quot;[%p] ...qu'est-ce que c'est.\n&amp;quot;, id);
}

int main(char* argv, int argc) {
 pthread_t t1, t2, k1, k2;
 pthread_create(&amp;amp;t1, NULL, thread1, NULL);
 printf(&amp;quot;[%p] I can't sleep 'cause my bed's on fire\n&amp;quot;, &amp;amp;t1);
 pthread_create(&amp;amp;t2, NULL, thread2, NULL);
 printf(&amp;quot;[%p] Don't touch me I'm a real live wire\n&amp;quot;, &amp;amp;t2);
 pthread_create(&amp;amp;k1, NULL, psycho_killer, &amp;amp;t1);
 pthread_create(&amp;amp;k2, NULL, psycho_killer, &amp;amp;t2);
 pthread_join(k1, NULL);
 pthread_join(k2, NULL);
 printf(&amp;quot;Run run run away!\n&amp;quot;);
 return 0;
}
&lt;/code>&lt;/pre>
&lt;p>It never manages to terminate the second thread&amp;hellip;&lt;/p></description></item><item><title>Embracing Windows</title><link>https://blog.ezyang.com/2010/09/embracing-window/</link><pubDate>Mon, 06 Sep 2010 09:00:27 +0000</pubDate><guid>https://blog.ezyang.com/2010/09/embracing-window/</guid><description>&lt;p>&lt;em>Some things come round full circle.&lt;/em>&lt;/p>
&lt;p>As a high schooler, I was a real Windows enthusiast. A budding programmer, I accumulated a complete development environment out of necessity, a mix of Cygwin, handwritten batch scripts, PuTTY, LogMeIn, a homegrown set of PHP build scripts and Notepad++. I was so devoted to the cause I even got a &lt;a href="http://repo.or.cz/w/git.git/commit/36ad53ffee6ed5b7c277cde660f526fd8ce3d68f">single patch into Git&lt;/a>, for the purpose of making Git play nicely with plink on Windows. The setup worked, but it always felt like a patchwork of different components, all not quite seeing eye-to-eye with each other. When I discovered that Linux was able to offer me an unbelievably coherent development environment, I jumped ship and said goodbye to Windows.&lt;/p></description></item><item><title>Annotating slides</title><link>https://blog.ezyang.com/2010/09/annotating-slides/</link><pubDate>Fri, 03 Sep 2010 09:00:53 +0000</pubDate><guid>https://blog.ezyang.com/2010/09/annotating-slides/</guid><description>&lt;p>A little trick for your toolbox: after you’ve generated your slide deck and printed it out to PDF, you might want to annotate the slides with comments. These is a good idea for several reasons:&lt;/p>
&lt;ul>
&lt;li>If you’ve constructed your slides to be text light, they might be optimized for presentation but not for reading later on. (“Huh, here is this diagram, I sure wish I knew what the presenter was saying at that point.”)&lt;/li>
&lt;li>Writing out a dialog to go along the slides is a nonvocal way of practicing your presentation!&lt;/li>
&lt;/ul>
&lt;p>But how do you interleave the slide pages with your annotations? With the power of &lt;code>enscript&lt;/code> and &lt;code>pdftk&lt;/code>, you can do this entirely automatically, without even having to leave your terminal! Here’s the recipe.&lt;/p></description></item><item><title>My type signature overfloweth</title><link>https://blog.ezyang.com/2010/09/my-type-signature-overfloweth/</link><pubDate>Wed, 01 Sep 2010 09:00:35 +0000</pubDate><guid>https://blog.ezyang.com/2010/09/my-type-signature-overfloweth/</guid><description>&lt;p>I’ve recently started researching the use of &lt;em>session types&lt;/em> for practical coding, a thought that has been in the back of my mind ever since I was part of a team that built a networked collaborative text editor and spent a lot of time closely vetting the server and the client to ensure that they had implemented the correct protocols. The essence of such protocols is often relatively simple, but can quickly become complicated in the presence of error flow (for example, resynchronizing after a disconnection). Error conditions also happen to be difficult to automatically test! Thus, static types seem like an attractive way of tackling this task.&lt;/p></description></item><item><title>Defining “Haskelly”</title><link>https://blog.ezyang.com/2010/08/defining-haskelly/</link><pubDate>Mon, 30 Aug 2010 09:00:05 +0000</pubDate><guid>https://blog.ezyang.com/2010/08/defining-haskelly/</guid><description>&lt;p>At risk of sounding like a broken record, the topic of this post also sprang from &lt;a href="http://blog.ezyang.com/2010/08/galois-tech-talk-abcbridge-functional-interfaces-for-aigs-and-sat-solving/">abcBridge&lt;/a>. John Launchbury asked a question during my presentation that got me thinking about API design in Haskell. (By the way, &lt;a href="http://vimeo.com/14432112">the video for the talk&lt;/a> is out! Unfortunately, the second half had to be cut out due to technical difficulties, but you can still check out the slides.)&lt;/p>
&lt;p>His question was this:&lt;/p>
&lt;blockquote>
&lt;p>You’ve presented this in a very imperative style, where you’ve got this AIG structure in the ABC tool, and what you’ve really done is given me a nicely typed Haskell typed interface that allows you to go in a put a new gate or grab a structure, and I’m left wondering, what is the reason for needing this tight tie-in with what’s going on in that space? Here is a thought experiment: I could imagine myself having a purely functional data structure that is describing the data structure&amp;hellip;and you end up with a functional description of what you want your graph to look like, and then you tell ABC to go and build the graph in one go.&lt;/p></description></item><item><title>Interrupting GHC</title><link>https://blog.ezyang.com/2010/08/interrupting-ghc/</link><pubDate>Fri, 27 Aug 2010 09:00:27 +0000</pubDate><guid>https://blog.ezyang.com/2010/08/interrupting-ghc/</guid><description>&lt;p>In my &lt;a href="http://blog.ezyang.com/2010/08/galois-tech-talk-abcbridge-functional-interfaces-for-aigs-and-sat-solving/">tech talk about abcBridge&lt;/a>, one of the “unsolved” problems I had with making FFI code usable as ordinary Haskell code was interrupt handling. Here I describe an experimental solution involving a change to the GHC runtime system as suggested by &lt;a href="http://permalink.gmane.org/gmane.comp.lang.haskell.glasgow.user/18771">Simon Marlow&lt;/a>. The introductory section may be interesting to practitioners looking for working examples of code that catches signals; the later section is a proof of concept that I hope will turn into a fully fleshed out patch. :&lt;/p></description></item><item><title>abcBridge: Functional interfaces for AIGs and SAT solving</title><link>https://blog.ezyang.com/2010/08/galois-tech-talk-abcbridge-functional-interfaces-for-aigs-and-sat-solving/</link><pubDate>Wed, 25 Aug 2010 09:00:48 +0000</pubDate><guid>https://blog.ezyang.com/2010/08/galois-tech-talk-abcbridge-functional-interfaces-for-aigs-and-sat-solving/</guid><description>&lt;p>Yesterday I gave a &lt;a href="http://www.galois.com/blog/2010/08/19/tech-talk-abcbridge-functional-interfaces-for-aigs-and-sat-solving/">Galois Tech Talk&lt;/a> about abcBridge, a set of bindings in Haskell for &lt;a href="http://www.eecs.berkeley.edu/~alanmi/abc/">ABC&lt;/a> that I built over the summer as part of my internship.&lt;/p>
&lt;p>There should be a video soon, but until then, you can &lt;a href="http://web.mit.edu/~ezyang/Public/galois.pdf">download my annotated slides&lt;/a>. The software’s not public yet, but hopefully it will be soon.&lt;/p></description></item><item><title>Type Kata: Distinguishing different data with the same underlying representation</title><link>https://blog.ezyang.com/2010/08/type-kata-newtypes/</link><pubDate>Mon, 23 Aug 2010 09:00:36 +0000</pubDate><guid>https://blog.ezyang.com/2010/08/type-kata-newtypes/</guid><description>&lt;div class="container center">
&lt;p>&lt;em>Punning is the lowest form of humor. And an endless source of bugs.&lt;/em>&lt;/p>
&lt;/div>
&lt;p>&lt;em>The imperative.&lt;/em> In programming, semantically different data may have the same representation (type). Use of this data requires manually keeping track of what the extra information about the data that may be in a variable. This is dangerous when the alternative interpretation is right &lt;em>most&lt;/em> of the time; programmers who do not fully understand all of the extra conditions are lulled into a sense of security and may write code that seems to work, but actually has subtle bugs. Here are some real world examples where it is particularly easy to confuse semantics.&lt;/p></description></item><item><title>Day in the life of a Galois intern</title><link>https://blog.ezyang.com/2010/08/day-in-the-life-of-a-galois-intern/</link><pubDate>Fri, 20 Aug 2010 09:00:11 +0000</pubDate><guid>https://blog.ezyang.com/2010/08/day-in-the-life-of-a-galois-intern/</guid><description>&lt;div class="container center">
&lt;p>&lt;em>Vrrmm! Vrrmm! Vrrmm!&lt;/em>&lt;/p>
&lt;/div>
&lt;p>It&amp;rsquo;s 9:00AM, and the cell phone next to my pillow is vibrating ominously. I rise and dismiss the alarm before it starts ringing in earnest and peek out the window of my room.&lt;/p>
&lt;p>Portland summer is a fickle thing: the weather of the first month of my internship was marked by mist and rain (a phenomenon, Don tells me, which is highly unusual for Portland), while the weather of the second month was a sleepy gray in the mornings. &amp;ldquo;Is it summer yet?&amp;rdquo; was the topic of &lt;code>#galois&lt;/code> for most of July. But in the heart of August, summer has finally arrived, and the sun greets my gaze. Shorts and a T-shirt, no sweater necessary! I silently go &amp;ldquo;Yes!&amp;rdquo;&lt;/p></description></item><item><title>Type kata: Controlled sharing of references</title><link>https://blog.ezyang.com/2010/08/type-kata-controlled-sharing-of-references/</link><pubDate>Wed, 18 Aug 2010 09:00:51 +0000</pubDate><guid>https://blog.ezyang.com/2010/08/type-kata-controlled-sharing-of-references/</guid><description>&lt;p>&lt;em>The imperative.&lt;/em> Mutable data structures with many children frequently force any given child to be associated with one given parent data structure:&lt;/p>
&lt;pre>&lt;code>class DOMNode {
 private DOMDocument $ownerDocument;
 // ...
 public void appendNode(DOMNode n) {
 if (n.ownerDocument != this.ownerDocument) {
 throw DOMException(&amp;quot;Cannot append node that &amp;quot;
 &amp;quot;does not belong to this document&amp;quot;);
 }
 // ...
 }
}
&lt;/code>&lt;/pre>
&lt;p>Client code must be careful not to mix up children that belong to different owners. An object can be copied from one owner to another via a special function. :&lt;/p></description></item><item><title>What high school Algebra quizzes and NP-complete problems have in common</title><link>https://blog.ezyang.com/2010/08/what-high-school-algebra-quizzes-and-np-complete-problems-have-in-common/</link><pubDate>Mon, 16 Aug 2010 09:00:03 +0000</pubDate><guid>https://blog.ezyang.com/2010/08/what-high-school-algebra-quizzes-and-np-complete-problems-have-in-common/</guid><description>&lt;div class="container center">
&lt;p>&lt;em>What I did for my summer internship at Galois&lt;/em>&lt;/p>
&lt;/div>
&lt;p>&lt;em>World of algebra quizzes.&lt;/em> As a high schooler, I was using concepts from computer science long before I even knew what computer science was. I can recall taking a math quiz—calculators banned—facing a difficult task: the multiplication of large numbers. I was (and still am) very sloppy when it came to pencil-and-paper arithmetic—if I didn’t check my answers, I would invariably lose points because of “stupid mistakes.” Fortunately, I knew the following trick: if I summed together the digits of my factors (re-summing if the result was ten or more), the product of these two numbers should match the sum of the digits of the result. If not, I knew I had the wrong answer. It wasn’t until much later that I discovered that this was a very rudimentary form of the checksum.&lt;/p></description></item><item><title>Generalizing APIs</title><link>https://blog.ezyang.com/2010/08/generalizing-apis/</link><pubDate>Fri, 13 Aug 2010 09:00:54 +0000</pubDate><guid>https://blog.ezyang.com/2010/08/generalizing-apis/</guid><description>&lt;p>&lt;em>Edit.&lt;/em> ddarius pointed out to me that the type families examples were backwards, so I’ve flipped them to be the same as the functional dependencies.&lt;/p>
&lt;p>Type functions can be used to do all sorts of neat type-level computation, but perhaps the most basic use is to allow the construction of generic APIs, instead of just relying on the fact that a module exports “mostly the same functions”. How much type trickery you need depends on properties of your API—perhaps most importantly, on the properties of your data types.&lt;/p></description></item><item><title>A radical Hackage social experiment</title><link>https://blog.ezyang.com/2010/08/the-radical-hackage-social-experiment/</link><pubDate>Wed, 11 Aug 2010 09:00:26 +0000</pubDate><guid>https://blog.ezyang.com/2010/08/the-radical-hackage-social-experiment/</guid><description>&lt;p>&lt;em>Prologue.&lt;/em> This post is an attempt to solidify some of the thoughts about the upcoming Hackage 2.0 that have been discussed around the Galois lunch table. Note that I have never overseen the emergence of a language into mainstream, so take what I say with a grain of salt. The thesis is that Hackage can revolutionize what it means to program in Haskell if it combines the cathedral (Python), the bazaar (Perl/CPAN), and the wheels of social collaboration (Wikipedia, StackOverflow, Github).&lt;/p></description></item><item><title>Paper Monday</title><link>https://blog.ezyang.com/2010/08/paper-monday/</link><pubDate>Mon, 09 Aug 2010 09:00:03 +0000</pubDate><guid>https://blog.ezyang.com/2010/08/paper-monday/</guid><description>&lt;p>Over the weekend, I took the Greyhound up to Seattle to meet up with some friends. The Greyhound buses was very late: forty-five minutes in the case of the trip up, which meant that I had some time to myself in the Internet-less bus station. I formulated the only obvious course of action: start working on the backlog of papers in my queue. In the process, I found out that a paper that had been languishing in my queue since December 2009 actually deals directly with a major problem I spent last Thursday debugging (unsuccessfully) at Galois.&lt;/p></description></item><item><title>The Gateway Drug to Type Programming</title><link>https://blog.ezyang.com/2010/08/the-gateway-drug-to-type-programming/</link><pubDate>Fri, 06 Aug 2010 09:00:14 +0000</pubDate><guid>https://blog.ezyang.com/2010/08/the-gateway-drug-to-type-programming/</guid><description>&lt;p>&lt;a href="http://blog.ezyang.com/2010/07/suggestion-box/#comment-789">David Powell&lt;/a> asks,&lt;/p>
&lt;blockquote>
&lt;p>There seems to be decent detailed information about each of these [type extensions], which can be overwhelming when you’re not sure where to start. I’d like to know how these extensions relate to each other; do they solve the same problems, or are they mutually exclusive?&lt;/p>&lt;/blockquote>
&lt;p>Having only used a subset of GHC’s type extensions (many of them added only because the compiler told me to), I’m unfortunately terribly unqualified to answer this question. In the cases where I’ve gone out of my way to add a language extension, most of the time it’s been because I was following some specific recipe that called for that type. (Examples of the former include FlexibleInstances, MultiParamTypeClasses, and FlexibleContexts; examples of the latter include GADTs and EmptyDataDecl).&lt;/p></description></item><item><title>Tour of a distributed Erlang application</title><link>https://blog.ezyang.com/2010/08/tour-of-preach-distributed-erlang/</link><pubDate>Thu, 05 Aug 2010 09:00:16 +0000</pubDate><guid>https://blog.ezyang.com/2010/08/tour-of-preach-distributed-erlang/</guid><description>&lt;p>Bonus post today! Last Tuesday, John Erickson gave a Galois tech talk entitled &lt;a href="http://vimeo.com/13865125">“Industrial Strength Distributed Explicit Model Checking”&lt;/a> (&lt;a href="http://vimeo.com/13865125">video&lt;/a>), in which he describe &lt;a href="http://bitbucket.org/jderick/preach">PReach&lt;/a>, an open-source model checker based on &lt;a href="http://verify.stanford.edu/dill/murphi.html">Murphi&lt;/a> that Intel uses to look for bugs in its models. It is intended as a simpler alternative to Murphi’s built-in distributed capabilities, leveraging Erlang to achieve much simpler network communication code.&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/preach/intel.png" alt="image">&lt;/p>
&lt;p>&lt;em>First question.&lt;/em> Why do you care?&lt;/p>
&lt;ul>
&lt;li>&lt;em>Model checking is cool.&lt;/em> Imagine you have a complicated set of interacting parallel processes that evolve nondeterministically over time, using some protocol to communicate with each other. You think the code is correct, but just to be sure, you add some assertions that check for invariants: perhaps some configurations of states should never be seen, perhaps you want to ensure that your protocol never deadlocks. One way to test this is to run it in the field for a while and report when the invariants fail. Model checking lets you comprehensively test all of the possible state evolutions of the system for deadlocks or violated invariants. With this, you can find subtle bugs &lt;em>and&lt;/em> you can find out precisely the inputs that lead to that event.&lt;/li>
&lt;li>&lt;em>Distributed applications are cool.&lt;/em> As you might imagine, the number of states that need to be checked explodes exponentially. Model checkers apply algorithms to coalesce common states and reduce the state space, but at some point, if you want to test larger models you will need more machines. PReach has allowed Intel to run the underlying model checker Murphi fifty times faster (with a hundred machines).&lt;/li>
&lt;/ul>
&lt;p>This talk was oriented more towards to the challenges that the PReach team encountered when making the core Murphi algorithm distributed than how to model check your application (although I’m sure some Galwegians would have been interested in that aspect too.) I think it gave an excellent high level overview of how you might design a distributed system in Erlang. Since the software is open source, I’ll link to relevant source code lines as we step through the high level implementation of this system.&lt;/p></description></item><item><title>Buffered streams and iteratees</title><link>https://blog.ezyang.com/2010/08/buffered-streams-and-iteratee/</link><pubDate>Wed, 04 Aug 2010 09:00:42 +0000</pubDate><guid>https://blog.ezyang.com/2010/08/buffered-streams-and-iteratee/</guid><description>&lt;p>While attempting to figure out how I might explain lazy versus strict bytestrings in more depth without boring half of my readership to death, I stumbled upon a nice parallel between a standard implementation of buffered streams in imperative languages and iteratees in functional languages.&lt;/p>
&lt;p>No self-respecting input/output mechanism would find itself without &lt;em>buffering.&lt;/em> Buffering improves efficiency by grouping reads or writes together so that they can be performed as a single unit. A simple read buffer might be implemented like this in C (though, of course, with the static variables wrapped up into a data structure&amp;hellip; and proper handling for error conditions in &lt;code>read&lt;/code>&amp;hellip;):&lt;/p></description></item><item><title>How to pick your string library in Haskell</title><link>https://blog.ezyang.com/2010/08/strings-in-haskell/</link><pubDate>Mon, 02 Aug 2010 09:00:50 +0000</pubDate><guid>https://blog.ezyang.com/2010/08/strings-in-haskell/</guid><description>&lt;p>&lt;em>Notice.&lt;/em> Following a critique from Bryan O’Sullivan, I’ve restructured the page.&lt;/p>
&lt;p>“How do the different text handling libraries compare, and when should we use which package?” &lt;a href="http://blog.ezyang.com/2010/07/suggestion-box/#comment-787">asks Chris Eidhof&lt;/a>. The latter question is easier to answer. Use &lt;a href="http://hackage.haskell.org/package/bytestring">bytestring&lt;/a> for binary data—raw bits and bytes with no explicit information as to semantic meaning. Use &lt;a href="http://hackage.haskell.org/package/text">text&lt;/a> for Unicode data representing human written languages, usually represented as binary data equipped with a character encoding. Both (especially bytestring) are widely used and are likely to become—if they are not already—standards.&lt;/p></description></item><item><title>Suggestion box</title><link>https://blog.ezyang.com/2010/07/suggestion-box/</link><pubDate>Fri, 30 Jul 2010 09:00:46 +0000</pubDate><guid>https://blog.ezyang.com/2010/07/suggestion-box/</guid><description>&lt;p>Taking a page from &lt;a href="http://blogs.msdn.com/b/oldnewthing/archive/2004/06/25/166545.aspx">Raymond Chen’s blog&lt;/a>, please post suggestions for future blog posts by me. What would you like to see me explain? What do you think would be amusing if I attempted to write a post about it? Topics I am inclined to cover:&lt;/p>
&lt;ul>
&lt;li>Almost anything about Haskell, GHC and closely related maths.&lt;/li>
&lt;li>General programming topics.&lt;/li>
&lt;li>Educating, teaching, lecturing.&lt;/li>
&lt;li>Computer science topics of general interest.&lt;/li>
&lt;li>Stories about my internship experiences (at this point, I&amp;rsquo;ve interned at &lt;a href="http://omniti.com/">OmniTI&lt;/a>, &lt;a href="http://www.itasoftware.com/">ITA Software&lt;/a>, &lt;a href="http://www.ksplice.com/">Ksplice&lt;/a> and &lt;a href="http://www.galois.com/">Galois&lt;/a>.)&lt;/li>
&lt;li>SIPB.&lt;/li>
&lt;li>Music.&lt;/li>
&lt;/ul>
&lt;p>Since Raymond is famous and I’m not, I will be much less choosy about which suggestions I will post about.&lt;/p></description></item><item><title>Delaying implicit parameter binding</title><link>https://blog.ezyang.com/2010/07/delaying-implicit-parameter-binding/</link><pubDate>Wed, 28 Jul 2010 09:00:38 +0000</pubDate><guid>https://blog.ezyang.com/2010/07/delaying-implicit-parameter-binding/</guid><description>&lt;p>Today, we talk in more detail at some points about dynamic binding that Dan Doel brought up in the comments of &lt;a href="http://blog.ezyang.com/2010/07/implicit-parameters-in-haskell/">Monday’s post&lt;/a>. Our first step is to solidify our definition of dynamic binding as seen in a lazy language (Haskell, using the Reader monad) and in a strict language (Scheme, using a buggy meta-circular evaluator). We then come back to implicit parameters, and ask the question: do implicit parameters perform dynamic binding? (Disregarding the monomorphism restriction, &lt;a href="http://okmij.org/ftp/Computation/dynamic-binding.html#implicit-parameter-neq-dynvar">Oleg says no&lt;/a>, but with a &lt;a href="http://hackage.haskell.org/trac/ghc/ticket/4226">possible bug in GHC&lt;/a> the answer is yes.) And finally, we show how to combine the convenience of implicit parameters with the explicitness of the Reader monad using a standard trick that Oleg uses in his monadic regions.&lt;/p></description></item><item><title>Reader monad and implicit parameters</title><link>https://blog.ezyang.com/2010/07/implicit-parameters-in-haskell/</link><pubDate>Mon, 26 Jul 2010 12:46:43 +0000</pubDate><guid>https://blog.ezyang.com/2010/07/implicit-parameters-in-haskell/</guid><description>&lt;div class="container center">
&lt;p>&lt;em>For when the Reader monad seems hopelessly clunky&lt;/em>&lt;/p>
&lt;/div>
&lt;p>The Reader monad (also known as the Environment monad) and implicit parameters are remarkably similar even though the former is the standard repertoire of a working Haskell programmer while the latter is a GHC language extension used sparingly by those who know about it. Both allow the programmer to code as if they had access to a global environment that can still change at runtime. However, implicit parameters are remarkably well suited for cases when you would have used a stack of reader transformers. Unfortunately, unlike many type system extensions, GHC cannot suggest that you enable &lt;code>ImplicitParams&lt;/code> because the code you innocently wrote is not valid Haskell98 but would be valid if you enabled this extension. This post intends to demonstrate one way to discover implicit parameters, with a little nudging.&lt;/p></description></item><item><title>Managing foreign pointers effectively</title><link>https://blog.ezyang.com/2010/07/managing-foreign-pointers-effectively/</link><pubDate>Fri, 23 Jul 2010 09:00:43 +0000</pubDate><guid>https://blog.ezyang.com/2010/07/managing-foreign-pointers-effectively/</guid><description>&lt;p>&lt;a href="http://haskell.org/ghc/docs/6.12.2/html/libraries/base-4.2.0.1/Foreign-ForeignPtr.html">Foreign.ForeignPtr&lt;/a> is a magic wand you can wave at C libraries to make them suddenly garbage collected. It’s not quite that simple, but it is &lt;em>pretty darn simple&lt;/em>. Here are a few quick tips from the trenches for using foreign pointers effectively with the Haskell FFI:&lt;/p>
&lt;ul>
&lt;li>Use them as early as possible. As soon as a pointer which you are expected to free is passed to you from a foreign imported function, you should wrap it up in a ForeignPtr before doing anything else: this responsibility lies soundly in the low-level binding. Find the functions that you have to import as &lt;code>FunPtr&lt;/code>. If you’re using c2hs, declare your pointers &lt;code>foreign&lt;/code>.&lt;/li>
&lt;li>As an exception to the above point, you may need to tread carefully if the C library offers more than one way to free pointers that it passes you; an example would be a function that takes a pointer and destroys it (likely not freeing the memory, but reusing it), and returns a new pointer. If you wrapped it in a ForeignPtr, when it gets garbage collected you will have a double-free on your hands. If this is the primary mode of operation, consider a &lt;code>ForeignPtr (Ptr a)&lt;/code> and a customized free that pokes the outside foreign pointer and then frees the inner pointer. If there is no logical continuity with respect to the pointers it frees, you can use a &lt;code>StablePtr&lt;/code> to keep your &lt;code>ForeignPtr&lt;/code> from ever being garbage collected, but this is effectively a memory leak. Once a foreign pointer, always a foreign pointer, so if you can’t commit until garbage do us part, don’t use them.&lt;/li>
&lt;li>You may pass foreign pointers to user code as opaque references, which can result in the preponderance of newtypes. It is quite useful to define &lt;code>withOpaqueType&lt;/code> so you don’t have to pattern-match and then use &lt;code>withForeignPtr&lt;/code> every time your own code peeks inside the black box.&lt;/li>
&lt;li>Be careful to use the library’s &lt;code>free&lt;/code> equivalent. While on systems unified by libc, you can probably get away with using &lt;code>free&lt;/code> on the &lt;code>int*&lt;/code> array you got (because most libraries use &lt;code>malloc&lt;/code> under the hood), this code is not portable and will &lt;a href="http://blogs.msdn.com/b/oldnewthing/archive/2006/09/15/755966.aspx">almost assuredly crash if you try compiling on Windows&lt;/a>. And, of course, complicated structs may require more complicated deallocation strategies. (This was in fact the only bug that hit me when I tested my own library on Windows, and it was quite frustrating until I remembered Raymond’s blog post.)&lt;/li>
&lt;li>If you have pointers to data that is being memory managed by another pointer which is inside a ForeignPtr, extreme care must be taken to prevent freeing the ForeignPtr while you have those pointers lying around. There are several approaches:
&lt;ul>
&lt;li>Capture the sub-pointers in a Monad with rank-2 types (see the &lt;code>ST&lt;/code> monad for an example), and require that the monad be run within a &lt;code>withForeignPtr&lt;/code> to guarantee that the master pointer stays alive while the sub-pointers are around, and guarantee that the sub-pointer can’t leak out of the context.&lt;/li>
&lt;li>Do funny things with &lt;code>Foreign.ForeignPtr.Concurrent&lt;/code>, which allows you to use Haskell code as finalizers: reference counting and dependency tracking (only so long as your finalizer is content with being run after the master finalizer) are possible. I find this very unsatisfying, and the guarantees you can get are not always very good.&lt;/li>
&lt;/ul>
&lt;/li>
&lt;li>If you don’t need to release a pointer into the wild, don’t! &lt;a href="http://article.gmane.org/gmane.comp.lang.haskell.glasgow.user/7107">Simon Marlow&lt;/a> acknowledges that finalizers can lead to all sorts of pain, and if you can get away with giving users only a bracketing function, you should consider it. Your memory usage and object lifetime will be far more predictable.&lt;/li>
&lt;/ul></description></item><item><title>Pipelines and continuations</title><link>https://blog.ezyang.com/2010/07/pipelines-and-continuation/</link><pubDate>Wed, 21 Jul 2010 09:00:19 +0000</pubDate><guid>https://blog.ezyang.com/2010/07/pipelines-and-continuation/</guid><description>&lt;p>&lt;em>Attention conservation notice.&lt;/em> Function pipelines offer an intuitive way to think about continuations: continuation-passing style merely &lt;em>reifies&lt;/em> the pipeline. If you know continuations, this post probably won’t give you much; otherwise, I hope this is an interesting new way to look at them. Why do you care about continuations? They are frequently an extremely fast way to implement algorithms, since they are essentially pure (pipeline) flow control.&lt;/p>
&lt;p>In &lt;a href="http://book.realworldhaskell.org/read/io-case-study-a-library-for-searching-the-filesystem.html">Real World Haskell&lt;/a>, an interesting pattern that recurs in functional programs that use function composition &lt;code>(.)&lt;/code> is named: pipelining. It comes in several guises: Lispers may know it as the “how many closing parentheses did I need?” syndrome:&lt;/p></description></item><item><title>System.Posix.Redirect</title><link>https://blog.ezyang.com/2010/07/system-posix-redirect/</link><pubDate>Mon, 19 Jul 2010 09:00:28 +0000</pubDate><guid>https://blog.ezyang.com/2010/07/system-posix-redirect/</guid><description>&lt;p>&lt;a href="http://hackage.haskell.org/package/system-posix-redirect">System.Posix.Redirect&lt;/a> is a Haskell implementation of a &lt;a href="http://homepage.ntlworld.com/jonathan.deboynepollard/FGA/redirecting-standard-io.html">well-known, clever and effective POSIX hack&lt;/a>. It’s also completely fails software engineering standards. About a week ago, I excised this failed experiment from my work code and uploaded it to Hackage for strictly academic purposes.&lt;/p>
&lt;p>&lt;em>What does it do?&lt;/em> When you run a command in a shell script, you have the option of &lt;em>redirecting&lt;/em> its output to another file or program:&lt;/p>
&lt;pre>&lt;code>$ echo &amp;quot;foo\n&amp;quot; &amp;gt; foo-file
$ cat foo-file
foo
$ cat foo-file | grep oo
foo
&lt;/code>&lt;/pre>
&lt;p>Many APIs for &lt;a href="http://www.haskell.org/ghc/docs/6.12.2/html/libraries/process-1.0.1.2/System-Process.html">creating new processes&lt;/a> which allow custom stdin/stdout/stderr handles exist; what System.Posix.Redirect lets you do is redirect stdout/stderr without having to create a new process:&lt;/p></description></item><item><title>Maximum matching deadlock solution</title><link>https://blog.ezyang.com/2010/07/maximum-matching-deadlock-solution/</link><pubDate>Fri, 16 Jul 2010 09:00:13 +0000</pubDate><guid>https://blog.ezyang.com/2010/07/maximum-matching-deadlock-solution/</guid><description>&lt;p>&lt;a href="http://blog.ezyang.com/2010/07/graphs-not-grids/">Last Monday&lt;/a>, I presented a parallel algorithm for computing maximum weighted matching, and noted that on real hardware, a naive implementation would deadlock.&lt;/p>
&lt;p>Several readers correctly identified that sorting the nodes on their most weighted vertex only once was insufficient: when a node becomes paired as is removed from the pool of unpaired nodes, it could drastically affect the sort. Keeping the nodes in a priority queue was suggested as an answer, which is certainly a good answer, though not the one that Feo ended up using.&lt;/p></description></item><item><title>Flipping arrows in coBurger King</title><link>https://blog.ezyang.com/2010/07/flipping-arrows-in-coburger-king/</link><pubDate>Wed, 14 Jul 2010 09:00:40 +0000</pubDate><guid>https://blog.ezyang.com/2010/07/flipping-arrows-in-coburger-king/</guid><description>&lt;div class="container center">
&lt;p>&lt;em>Category theory crash course for the working Haskell programmer.&lt;/em>&lt;/p>
&lt;/div>
&lt;p>A frequent question that comes up when discussing the dual data structures—most frequently comonad—is “What does the co- mean?” The snippy category theory answer is: “Because you flip the arrows around.” This is confusing, because if you look at one variant of the monad and comonad typeclasses:&lt;/p>
&lt;pre>&lt;code>class Monad m where
 (&amp;gt;&amp;gt;=) :: m a -&amp;gt; (a -&amp;gt; m b) -&amp;gt; m b
 return :: a -&amp;gt; m a

class Comonad w where
 (=&amp;gt;&amp;gt;) :: w a -&amp;gt; (w a -&amp;gt; b) -&amp;gt; w b
 extract :: w a -&amp;gt; a
&lt;/code>&lt;/pre>
&lt;p>there are a lot of “arrows”, and only a few of them flipped (specifically, the arrow inside the second argument of the &lt;code>&amp;gt;&amp;gt;=&lt;/code> and &lt;code>=&amp;gt;&amp;gt;&lt;/code> functions, and the arrow in return/extract). This article will make precise what it means to “flip arrows” and use the “dual category”, even if you don’t know a lick of category theory.&lt;/p></description></item><item><title>Graphs not grids: How caches are corrupting young algorithms designers and how to fix it</title><link>https://blog.ezyang.com/2010/07/graphs-not-grids/</link><pubDate>Mon, 12 Jul 2010 09:00:17 +0000</pubDate><guid>https://blog.ezyang.com/2010/07/graphs-not-grids/</guid><description>&lt;div class="container center">
&lt;p>Subtitle: Massively multithreaded processors make your undergraduate CS education relevant again.&lt;/p>
&lt;/div>
&lt;p>&lt;em>Quicksort. Divide and conquer. Search trees. These and other algorithms form the basis for a classic undergraduate algorithms class, where the big ideas of algorithm design are laid bare for all to see, and the performance model is one instruction, one time unit. “One instruction, one time unit? How quaint!” proclaim the cache-oblivious algorithm researchers and real world engineers. They know that the traditional curriculum, while not wrong, is quite misleading. It’s simply not enough to look at some theoretical computing machine: the next-generation of high performance algorithms need to be in tune with the hardware they run on. They couldn’t be more right.&lt;/em>&lt;/p></description></item><item><title>Safety first: FFI and threading</title><link>https://blog.ezyang.com/2010/07/safety-first-ffi-and-threading/</link><pubDate>Fri, 09 Jul 2010 09:00:05 +0000</pubDate><guid>https://blog.ezyang.com/2010/07/safety-first-ffi-and-threading/</guid><description>&lt;p>&lt;strong>Update.&lt;/strong> While this blog post presents two true facts, it gets the causal relationship between the two facts wrong. &lt;a href="http://blog.ezyang.com/2014/12/unintended-consequences-bound-threads-and-unsafe-ffi-calls/">Here is the correction.&lt;/a>&lt;/p>
&lt;p>&lt;em>Attention conservation notice.&lt;/em> Don’t use &lt;code>unsafe&lt;/code> in your FFI imports! We really mean it!&lt;/p>
&lt;p>Consider the following example in from an old version of Haskellwiki’s &lt;a href="http://www.haskell.org/haskellwiki/?title=FFI_Introduction&amp;amp;oldid=33660">FFI introduction&lt;/a>:&lt;/p>
&lt;pre>&lt;code>{-# INCLUDE &amp;lt;math.h&amp;gt; #-}
{-# LANGUAGE ForeignFunctionInterface #-}
module FfiExample where
import Foreign.C -- get the C types

-- pure function
-- &amp;quot;unsafe&amp;quot; means it's slightly faster but can't callback to haskell
foreign import ccall unsafe &amp;quot;sin&amp;quot; c_sin :: CDouble -&amp;gt; CDouble
sin :: Double -&amp;gt; Double
sin d = realToFrac (c_sin (realToFrac d))
&lt;/code>&lt;/pre>
&lt;p>The comment blithely notes that the function can’t “callback to Haskell.” Someone first learning about the FFI might think, “Oh, that means I can put most &lt;code>unsafe&lt;/code> on most of my FFI declarations, since I’m not going to do anything advanced like call back to Haskell.”&lt;/p></description></item><item><title>Groom: human readable Show for Haskell</title><link>https://blog.ezyang.com/2010/07/groom-human-readable-show-for-haskell/</link><pubDate>Wed, 07 Jul 2010 09:00:34 +0000</pubDate><guid>https://blog.ezyang.com/2010/07/groom-human-readable-show-for-haskell/</guid><description>&lt;p>Tapping away at a complex datastructure, I find myself facing a veritable wall of Babel.&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/groom/messy.png" alt="image">&lt;/p>
&lt;p>“Zounds!” I exclaim, “The GHC gods have cursed me once again with a derived Show instance with no whitespace!” I mutter discontently to myself, and begin pairing up parentheses and brackets, scanning the sheet of text for some discernible feature that may tell me of the data I am looking for.&lt;/p>
&lt;p>But then, a thought comes to me: “Show is specified to be a valid Haskell expression without whitespace. What if I parsed it and then pretty-printed the resulting AST?”&lt;/p></description></item><item><title>Little’s law</title><link>https://blog.ezyang.com/2010/07/littles-law/</link><pubDate>Mon, 05 Jul 2010 09:00:47 +0000</pubDate><guid>https://blog.ezyang.com/2010/07/littles-law/</guid><description>&lt;p>A short thought from standing in line at the World Expo: &lt;a href="http://en.wikipedia.org/wiki/Little's_law">Little’s law&lt;/a> is a remarkable result that relates the number of people in a queue, the arrival rate of people to the queue, and the time spent waiting in the queue. It seems that it could be easily applied to a most universal feature of theme parks: waiting queues. Instead of such unreliable methods as giving visitors tokens to test how long it takes to traverse some portion of the line and then eyeballing the wait time from there, it would be a simple matter to install two gates: one to count incoming visitors and one to count outgoing visitors, and with this data derive an instantaneous “wait time in queue” figure based on a smoothed running average of queue size and arrival rate. Added benefit for being electronic, which means you can easily beam it to information boards across the park!&lt;/p></description></item><item><title>MVC and Purity</title><link>https://blog.ezyang.com/2010/07/mvc-and-purity/</link><pubDate>Fri, 02 Jul 2010 09:00:21 +0000</pubDate><guid>https://blog.ezyang.com/2010/07/mvc-and-purity/</guid><description>&lt;p>&lt;em>Attention conservation notice.&lt;/em> Purely functional programming demonstrates the same practices recommended by object-oriented MVC practice.&lt;/p>
&lt;p>&lt;a href="http://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller">Model-View-Controller&lt;/a> is a widely used object-oriented design pattern for organizing functionality in an application with a user interface. I first ran across it in my early days programming web applications. The Model/View separation made deep intuitive sense to me as a PHP programmer: without it, you’d end up with spaghetti templates with HTML print statements interleaved with MySQL queries. But Controller &lt;a href="http://www.c2.com/cgi/wiki?WhatsaControllerAnyway">was always a little wishy-washy&lt;/a>. What exactly did it do? It was some sort of “glue” code, the kind of stuff that bound together the Model and View and gave them orders. But this was always a sort of half-hearted answer for me (&lt;a href="http://discuss.joelonsoftware.com/default.asp?design.4.354410.6">where should input validation go?&lt;/a>), and soon I left the world of web applications, my questions unanswered.&lt;/p></description></item><item><title>Call and fun: marshalling redux</title><link>https://blog.ezyang.com/2010/06/call-and-fun-marshalling-redux/</link><pubDate>Wed, 30 Jun 2010 09:00:36 +0000</pubDate><guid>https://blog.ezyang.com/2010/06/call-and-fun-marshalling-redux/</guid><description>&lt;p>This part six of a &lt;a href="http://blog.ezyang.com/2010/06/the-haskell-preprocessor-hierarchy/">six part introduction to c2hs&lt;/a>. We finally talk about what ostensibly is the point of c2hs: calling C functions from Haskell. c2hs, due to its knowledge of the C headers, can already do the work for generating FFI imports. The &lt;code>call&lt;/code> hook simply tells c2hs to generate the FFI import, while the &lt;code>fun&lt;/code> hook generates another Haskell function which performs marshalling.&lt;/p>
&lt;p>&lt;em>Call.&lt;/em> The format of call is quite simple, because like &lt;code>get&lt;/code> and &lt;code>set&lt;/code>, it is meant to be interleaved with other Haskell code. If I would like to invoke the &lt;code>readline&lt;/code> function from &lt;code>readline/readline.h&lt;/code>, a &lt;code>{#call readline #}&lt;/code> would suffice; c2hs will then generate the FFI import with the correct signature and transform the call directive into the name of the FFI import.&lt;/p></description></item><item><title>Thinking about talk</title><link>https://blog.ezyang.com/2010/06/thinking-about-talk/</link><pubDate>Mon, 28 Jun 2010 09:00:44 +0000</pubDate><guid>https://blog.ezyang.com/2010/06/thinking-about-talk/</guid><description>&lt;p>This one&amp;rsquo;s for the MIT crowd.&lt;/p>
&lt;p>I will unfortunately not be in Boston over IAP, so I won&amp;rsquo;t be able to do a redux of the class I taught last year, &lt;em>Advanced Typeclasses in Haskell.&lt;/em> However, since I will be in Boston for September, it might be a good time to do &lt;a href="http://cluedumps.mit.edu/wiki/SIPB_Cluedump_Series">cluedump&lt;/a> for &lt;a href="http://sipb.mit.edu/">SIPB&lt;/a> this year. I love talking about Haskell, and so I could do another talk in a similar vein (maybe something that covers rank-2 types and existential quantification?) I&amp;rsquo;ve also been thinking that doing an architectural overview of Scripts would also be good.&lt;/p></description></item><item><title>Marshalling with get and set</title><link>https://blog.ezyang.com/2010/06/marshalling-with-get-and-set/</link><pubDate>Fri, 25 Jun 2010 09:00:43 +0000</pubDate><guid>https://blog.ezyang.com/2010/06/marshalling-with-get-and-set/</guid><description>&lt;p>This part five of a &lt;a href="http://blog.ezyang.com/2010/06/the-haskell-preprocessor-hierarchy/">six part introduction to c2hs&lt;/a>. Today, we explain how to marshal data to and from C structures.&lt;/p>
&lt;p>&lt;em>An important note.&lt;/em> There is a difference between &lt;code>struct foo&lt;/code> and &lt;code>foo&lt;/code>; c2hs only considers the latter a type, so you may need to add some typedefs of the form &lt;code>typedef struct foo foo&lt;/code> in order to get c2hs to recognize these structs.&lt;/p>
&lt;p>&lt;em>Get.&lt;/em> The Haskell FFI has no knowledge of C structs; Haskell&amp;rsquo;s idea of reading a member of a struct is to peek at some byte offset of a memory location, which you calculated manually. This is horrid, and &lt;code>hsc2hs&lt;/code> has &lt;code>#peek&lt;/code> to relieve you of this non-portable drudgery. &lt;code>c2hs&lt;/code> has something even simpler: you can specify &lt;code>{#get StructName-&amp;gt;struct_field #}&lt;/code> and c2hs will replace this with a lambda that does the correct peek with the correct type: &lt;code>(\ptr -&amp;gt; do {peekByteOff ptr 12 ::IO CInt})&lt;/code> (in the IO monad!) Note the following gotchas:&lt;/p></description></item><item><title>First steps in c2hs</title><link>https://blog.ezyang.com/2010/06/first-steps-in-c2hs/</link><pubDate>Wed, 23 Jun 2010 09:00:52 +0000</pubDate><guid>https://blog.ezyang.com/2010/06/first-steps-in-c2hs/</guid><description>&lt;p>This is part four of a &lt;a href="http://blog.ezyang.com/2010/06/the-haskell-preprocessor-hierarchy/">six part tutorial series on c2hs&lt;/a>. Today we discuss the simple things in c2hs, namely the type, enum, pointer, import and context directives.&lt;/p>
&lt;p>&lt;em>Prior art.&lt;/em> All of the directives c2hs supports are tersely described in &lt;a href="http://www.cse.unsw.edu.au/~chak/haskell/c2hs/docu/implementing.html">the “tutorial” page&lt;/a> (which would perhaps be more accurately described as a “reference manual”, not tutorial.) There is also (paradoxically) a much more informal introduction for most of the directives in c2hs&amp;rsquo;s &lt;a href="http://www.cse.unsw.edu.au/~chak/papers/Cha99b.html">research paper&lt;/a>.&lt;/p></description></item><item><title>The secret to successful autogenerated docs</title><link>https://blog.ezyang.com/2010/06/secret-of-autogenerated-docs/</link><pubDate>Mon, 21 Jun 2010 09:00:26 +0000</pubDate><guid>https://blog.ezyang.com/2010/06/secret-of-autogenerated-docs/</guid><description>&lt;p>I&amp;rsquo;ve had a rather successful tenure with autogenerated documentation, both as a writer and a reader. So when &lt;a href="http://jacobian.org/writing/great-documentation/what-to-write/">Jacob Kaplan Moss&amp;rsquo;s articles on writing “great documentation”&lt;/a> resurfaced on Reddit and had some harsh words about auto-generated documentation, I sat back a moment and thought about why autogenerated documentation leave developers with a bad taste in their mouths.&lt;/p>
&lt;p>I interpreted Moss&amp;rsquo;s specific objections (besides asserting that they were “worthless” as the following:&lt;/p></description></item><item><title>Principles of FFI API design</title><link>https://blog.ezyang.com/2010/06/principles-of-ffi-api-design/</link><pubDate>Fri, 18 Jun 2010 09:00:26 +0000</pubDate><guid>https://blog.ezyang.com/2010/06/principles-of-ffi-api-design/</guid><description>&lt;p>This is part three of &lt;a href="http://blog.ezyang.com/2010/06/the-haskell-preprocessor-hierarchy/">a six part tutorial series on c2hs&lt;/a>. Today, we take a step back from the nitty gritty details of FFI bindings and talk about more general design principles for your library.&lt;/p>
&lt;p>On the one hand, writing an FFI binding can little more than churning out the glue code to let you write “C in Haskell,” the API of your library left at the whimsy of the original library author. On the other hand, you can aspire to make your interface indistinguishable from what someone might have written in pure Haskell, introducing modest innovation of your own to encode informally documented invariants from the C code into the type system.&lt;/p></description></item><item><title>Well-founded recursion in Agda</title><link>https://blog.ezyang.com/2010/06/well-founded-recursion-in-agda/</link><pubDate>Wed, 16 Jun 2010 09:00:35 +0000</pubDate><guid>https://blog.ezyang.com/2010/06/well-founded-recursion-in-agda/</guid><description>&lt;p>Last Tuesday, Eric Mertens gave the Galois tech talk &lt;a href="http://www.galois.com/blog/2010/06/11/tech-talk-introducing-well-founded-recursion/">Introducing Well-Founded Recursion&lt;/a>. I have to admit, most of this went over my head the first time I heard it. Here are some notes that I ended up writing for myself as I stepped through the code again. I suggest reading the &lt;a href="http://code.galois.com/talk/2010/10-06-mertens.pdf">slides&lt;/a> first to get a feel for the presentation. These notes are oriented towards a Haskell programmer who feels comfortable with the type system, but not Curry-Howard comfortable with the type system.&lt;/p></description></item><item><title>Setting up Cabal, the FFI and c2hs</title><link>https://blog.ezyang.com/2010/06/setting-up-cabal-the-ffi-and-c2hs/</link><pubDate>Mon, 14 Jun 2010 09:00:18 +0000</pubDate><guid>https://blog.ezyang.com/2010/06/setting-up-cabal-the-ffi-and-c2hs/</guid><description>&lt;p>This part two of a &lt;a href="http://blog.ezyang.com/2010/06/the-haskell-preprocessor-hierarchy/">six part introduction to c2hs&lt;/a>. Today, we discuss getting the damn thing to compile in the first place.&lt;/p>
&lt;p>&lt;em>Reader prerequisites.&lt;/em> You should know how to write, configure and build a vanilla Cabal file for pure Haskell. Fortunately, with &lt;a href="http://byorgey.wordpress.com/2010/04/15/cabal-init/">cabal init&lt;/a>, this is easier than ever. I&amp;rsquo;ll talk about how to setup a Cabal file for linking in C files, which is applicable to any sort of FFI writing (as it turns out, enabling c2hs is the trivial bit).&lt;/p></description></item><item><title>The Haskell Preprocessor Hierarchy</title><link>https://blog.ezyang.com/2010/06/the-haskell-preprocessor-hierarchy/</link><pubDate>Fri, 11 Jun 2010 09:00:12 +0000</pubDate><guid>https://blog.ezyang.com/2010/06/the-haskell-preprocessor-hierarchy/</guid><description>&lt;p>This post is part of what I hope will be a multi-part tutorial/cookbook series on using &lt;a href="http://www.cse.unsw.edu.au/~chak/haskell/c2hs/">c2hs&lt;/a> (&lt;a href="http://hackage.haskell.org/cgi-bin/hackage-scripts/package/c2hs">Hackage&lt;/a>).&lt;/p>
&lt;ol>
&lt;li>The Haskell Preprocessor Hierarchy (this post)&lt;/li>
&lt;li>&lt;a href="http://blog.ezyang.com/2010/06/setting-up-cabal-the-ffi-and-c2hs/">Setting up Cabal, the FFI and c2hs&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://blog.ezyang.com/2010/06/principles-of-ffi-api-design/">Principles of FFI API design&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://blog.ezyang.com/2010/06/first-steps-in-c2hs/">First steps in c2hs&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://blog.ezyang.com/2010/06/marshalling-with-get-and-set/">Marshalling with get an set&lt;/a>&lt;/li>
&lt;li>&lt;a href="http://blog.ezyang.com/2010/06/call-and-fun-marshalling-redux/">Call and fun: marshalling redux&lt;/a>&lt;/li>
&lt;/ol>
&lt;p>&lt;em>What&amp;rsquo;s c2hs?&lt;/em> c2hs is a Haskell preprocessor to help people generate &lt;a href="http://www.haskell.org/haskellwiki/FFI_Introduction">foreign-function interface&lt;/a> bindings, along with &lt;a href="http://www.haskell.org/ghc/docs/6.12.2/html/users_guide/hsc2hs.html">hsc2hs&lt;/a> and &lt;a href="http://www.haskell.org/greencard/">GreenCard&lt;/a>. The below diagram illustrates how the preprocessors currently supported by Cabal fit together. (For the curious, Cpp is thrown in with the rest of the FFI preprocessors, not because it is particularly useful for generating FFI code, but because many of the FFI preprocessors also implement some set of Cpp&amp;rsquo;s functionality. I decided on an order for Alex and Happy on the grounds that Alex was a lexer generator, while Happy was a parser generator.)&lt;/p></description></item><item><title>Static Analysis for everyday (not-PhD) man</title><link>https://blog.ezyang.com/2010/06/static-analysis-mozilla/</link><pubDate>Wed, 09 Jun 2010 09:00:48 +0000</pubDate><guid>https://blog.ezyang.com/2010/06/static-analysis-mozilla/</guid><description>&lt;p>&lt;em>Bjarne Stroustrup once boasted, &amp;ldquo;C++ is a multi-paradigm programming language that supports Object-Oriented and other useful styles of programming. If what you are looking for is something that forces you to do things in exactly one way, C++ isn&amp;rsquo;t it.&amp;rdquo; But as Taras Glek wryly notes, most of the static analysis and coding standards for C++ are mostly to make sure developers don&amp;rsquo;t use the other paradigms.&lt;/em>&lt;/p>
&lt;p>&lt;img src="http://www.mozilla.com/img/tignish/template/footer-logo.png" alt="image">&lt;/p>
&lt;p>On Tuesday, &lt;a href="http://blog.mozilla.com/tglek/">Taras Glek&lt;/a> presented &lt;a href="http://www.galois.com/blog/2010/06/03/tech-talk-large-scale-static-analysis-at-mozilla/">Large-Scale Static Analysis at Mozilla&lt;/a>. You can watch the video at &lt;a href="http://vimeo.com/12614626">Galois’s video stream.&lt;/a> The guiding topic of the talk is pretty straightforward: how does Mozilla use static analysis to manage the millions of lines of code in C++ and JavaScript that it has? But there was another underlying topic: static analysis is not just for the formal-methods people and the PhDs; anyone can and should tap into the power afforded by static analysis.&lt;/p></description></item><item><title>AP Physics: Stuck in the concrete</title><link>https://blog.ezyang.com/2010/06/ap-physics-stuck-in-the-concrete/</link><pubDate>Mon, 07 Jun 2010 09:00:32 +0000</pubDate><guid>https://blog.ezyang.com/2010/06/ap-physics-stuck-in-the-concrete/</guid><description>&lt;p>&lt;em>Attention conservation notice.&lt;/em> The author reminisces about learning physics in high school, and claims that all too often, teaching was focused too much on concrete formulas, and not the unifying theory around them.&lt;/p>
&lt;p>In elementary school, you may have learned D=RT (pronounced &amp;ldquo;dirt&amp;rdquo;), that is, distance is rate multiplied with time. This was mostly lies, but it was okay, because however tenuous the equation&amp;rsquo;s connection to the real world, teachers could use it to introduce the concept of algebraic manipulation, the idea that with just D=RT, you could also find out R if you knew D and T, and T if you knew D and R. Unless you were unusually bright, you didn&amp;rsquo;t know you were being lied to; you just learned to solve the word problems they&amp;rsquo;d give you.&lt;/p></description></item><item><title>Databases are categories</title><link>https://blog.ezyang.com/2010/06/databases-are-categories/</link><pubDate>Fri, 04 Jun 2010 09:00:38 +0000</pubDate><guid>https://blog.ezyang.com/2010/06/databases-are-categories/</guid><description>&lt;p>&lt;em>Update.&lt;/em> The video of the talk can be found here: &lt;a href="http://vimeo.com/channels/galois#12428370">Galois Tech Talks on Vimeo: Categories are Databases&lt;/a>.&lt;/p>
&lt;p>On Thursday Dr. &lt;a href="http://math.mit.edu/~dspivak/">David Spivak&lt;/a> presented &lt;a href="http://vimeo.com/channels/galois/12428370">Categories are Databases&lt;/a> as a Galois tech talk. His slides are &lt;a href="http://math.mit.edu/~dspivak/informatics/talks/galois.pdf">here&lt;/a>, and are dramatically more accessible than the paper &lt;a href="http://math.mit.edu/~dspivak/informatics/SD.pdf">Simplicial databases&lt;/a>. Here is a short attempt to introduce this idea to people who only have a passing knowledge of category theory.&lt;/p>
&lt;p>An essential exercise when designing relational databases is the practice of object modeling using labeled graphs of objects and relationships. Visually, this involves drawing a bunch of boxes representing the objects being modeled, and then drawing arrows between the objects showing relationships they may have. We can then use this object model as the basis for a relational database schema.&lt;/p></description></item><item><title>Bug boogie: Git and symlinks</title><link>https://blog.ezyang.com/2010/06/bug-boogie-git-and-symlinks/</link><pubDate>Wed, 02 Jun 2010 09:00:09 +0000</pubDate><guid>https://blog.ezyang.com/2010/06/bug-boogie-git-and-symlinks/</guid><description>&lt;p>Git is very careful about your files: unless you tell it to be explicitly destructive, it will refuse to write over files that it doesn&amp;rsquo;t know about, instead giving an error like:&lt;/p>
&lt;blockquote>
&lt;p>Untracked working tree file &amp;lsquo;foobar&amp;rsquo; would be overwritten by merge.&lt;/p>&lt;/blockquote>
&lt;p>In my work with &lt;a href="http://scripts.mit.edu/wizard">Wizard&lt;/a>, I frequently need to perform merges on working copies that have been, well, &amp;ldquo;less than well maintained&amp;rdquo;, e.g. they untarred a new version of the the source tree on the old directory and forgot to add the newly added files. When Wizard goes in and tries to automatically upgrade them to the new version the proper way, this results in all sorts of untracked working tree file complaints, and then we have to go and manually check on the untracked files and remove them once they&amp;rsquo;re fine.&lt;/p></description></item><item><title>Punt the Prelude</title><link>https://blog.ezyang.com/2010/05/punt-the-prelude/</link><pubDate>Mon, 31 May 2010 09:00:03 +0000</pubDate><guid>https://blog.ezyang.com/2010/05/punt-the-prelude/</guid><description>&lt;p>&lt;em>Conservation attention notice.&lt;/em> What definitions from the Haskell 98 Prelude tend to get hidden? I informally take a go over the Prelude and mention some candidates.&lt;/p>
&lt;p>&lt;code>(.)&lt;/code> in the Prelude is function composition, that is, &lt;code>(b -&amp;gt; c) -&amp;gt; (a -&amp;gt; b) -&amp;gt; a -&amp;gt; c&lt;/code>. But the denizens of #haskell know it can be much more than that: the function &lt;code>a -&amp;gt; b&lt;/code> is really just the functor, so a more general type is &lt;code>Functor f =&amp;gt; (b -&amp;gt; c) -&amp;gt; f b -&amp;gt; f c&lt;/code>, i.e. fmap. Even more generally, &lt;code>(.)&lt;/code> can indicate morphism composition, as it does in &lt;a href="http://hackage.haskell.org/packages/archive/base/latest/doc/html/Control-Category.html">Control.Category&lt;/a>.&lt;/p></description></item><item><title>Use The Monoid: A worked example</title><link>https://blog.ezyang.com/2010/05/use-the-monoid/</link><pubDate>Fri, 28 May 2010 09:00:14 +0000</pubDate><guid>https://blog.ezyang.com/2010/05/use-the-monoid/</guid><description>&lt;p>&lt;em>Attention conservation notice.&lt;/em> Equivalent Haskell and Python programs are presented for retrieving values from a data structure using state. We then refactor the Haskell program into one that has no state, just a monoid.&lt;/p>
&lt;p>A pretty frequent thing a working programmer needs to do is extract some values (frequently more than one) from some data structure, possibly while keeping track of extra metadata. I found myself writing this code the other day:&lt;/p></description></item><item><title>Bananas, Lenses, Envelopes and Barbed Wire &lt;br>A Translation Guide</title><link>https://blog.ezyang.com/2010/05/bananas-lenses-envelopes-and-barbed-wire-a-translation-guide/</link><pubDate>Wed, 26 May 2010 09:00:05 +0000</pubDate><guid>https://blog.ezyang.com/2010/05/bananas-lenses-envelopes-and-barbed-wire-a-translation-guide/</guid><description>&lt;p>One of the papers I&amp;rsquo;ve been slowly rereading since summer began is &lt;a href="http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.41.125">&amp;ldquo;Functional Programming with Bananas, Lenses, Envelopes and Barbed Wire&amp;rdquo;&lt;/a>, by Erik Meijer, Maarten Fokkinga and Ross Paterson. If you want to know what {cata,ana,hylo,para}morphisms are, this is the paper to read: section 2 gives a highly readable formulation of these morphisms for the beloved linked list.&lt;/p>
&lt;p>Last time, however, my eyes got a little bit glassy when they started discussing algebraic data types, despite having used and defined them in Haskell; part of me felt inundated in a sea of triangles, circles and squiggles, and by the time they reached the laws for the basic combinators, I might as well have said, &amp;ldquo;It&amp;rsquo;s all math to me!&amp;rdquo;&lt;/p></description></item><item><title>Lazy exceptions and IO</title><link>https://blog.ezyang.com/2010/05/imprecise-exceptions-and-io/</link><pubDate>Mon, 24 May 2010 09:00:41 +0000</pubDate><guid>https://blog.ezyang.com/2010/05/imprecise-exceptions-and-io/</guid><description>&lt;p>Consider the following piece of code:&lt;/p>
&lt;pre>&lt;code>import Prelude hiding (catch)
import Control.Exception

main :: IO ()
main = do
 t &amp;lt;- safeCall
 unsafeCall t
 putStrLn &amp;quot;Done.&amp;quot;

safeCall :: IO String
safeCall = do
 return alwaysFails `catch` errorHandler

--alwaysFails = throw (ErrorCall &amp;quot;Oh no!&amp;quot;)
alwaysFails = error &amp;quot;Oh no!&amp;quot;

errorHandler :: SomeException -&amp;gt; IO String
errorHandler e = do
 putStrLn &amp;quot;Caught&amp;quot;
 return &amp;quot;Ok.&amp;quot;
errorHandler_ e = errorHandler e &amp;gt;&amp;gt; return ()

unsafeCall :: String -&amp;gt; IO ()
unsafeCall = putStrLn
&lt;/code>&lt;/pre>
&lt;p>What might you expect the output to be? A straightforward transcription to Python might look like:&lt;/p></description></item><item><title>Upgrading to Ubuntu Lucid</title><link>https://blog.ezyang.com/2010/05/upgrading-to-ubuntu-lucid/</link><pubDate>Fri, 21 May 2010 09:00:58 +0000</pubDate><guid>https://blog.ezyang.com/2010/05/upgrading-to-ubuntu-lucid/</guid><description>&lt;p>Now that term is over, I finally went an upgraded my laptop to Ubuntu 10.04 LTS, Lucid Lynx. The process went substantially more smoothly than &lt;a href="http://ezyang.com/karmic.html">Karmic went&lt;/a>, but there were still a few hiccups.&lt;/p>
&lt;p>&lt;em>Etckeeper.&lt;/em> As always, you should set &lt;code>AVOID_COMMIT_BEFORE_INSTALL&lt;/code> to 0 before attempting a release upgrade, since etckeeper hooks will be invoked multiple times and there&amp;rsquo;s nothing more annoying than getting the notice &amp;ldquo;etckeeper aborted the install due to uncommited changes, please commit them yourselves&amp;rdquo; because there is no way that&amp;rsquo;s going to work.&lt;/p></description></item><item><title>Class Reflections</title><link>https://blog.ezyang.com/2010/05/class-reflections/</link><pubDate>Wed, 19 May 2010 09:00:49 +0000</pubDate><guid>https://blog.ezyang.com/2010/05/class-reflections/</guid><description>&lt;p>Last February, I posted about &lt;a href="http://blog.ezyang.com/2010/02/classes-begin/">classes that I was going to be taking&lt;/a>. Here are some reflections, now that final projects and examinations are over.&lt;/p>
&lt;p>&lt;em>6.005: Software Construction.&lt;/em> Teaching students how to engineer large software projects is one of the oddest paradoxes that you might encounter in academic life. The institute is certainly capable of teaching concepts, tools and methodologies, but, to actually be capable of constructing a system from scratch? It&amp;rsquo;s not really something you can learn, it something that you have to do. And the amount of work you have to put in to start getting the taste of real code as opposed to school code (which gets thrown away at the end of the term) doesn&amp;rsquo;t fit into one term. We&amp;rsquo;ve joked that MIT ought to have a two part series, where the second part you are asked to go modify some code you wrote a year ago in the face of shifting requirements. (Unfortunately, I suspect a large number of people will rewrite the thing: one of the problems of not actually being able to do &lt;em>large&lt;/em> systems.)&lt;/p></description></item><item><title>I Hate Patches: &lt;br>Confessions of an Open-Source Developer</title><link>https://blog.ezyang.com/2010/05/i-hate-patches-confessions-of-an-open-source-developer/</link><pubDate>Mon, 17 May 2010 09:00:11 +0000</pubDate><guid>https://blog.ezyang.com/2010/05/i-hate-patches-confessions-of-an-open-source-developer/</guid><description>&lt;p>It is a truth universally acknowledged that if you &lt;em>really&lt;/em> want a change put into an open source project, you submit a patch along with the bug report. Sure, you might complain that the &lt;em>average&lt;/em> user doesn&amp;rsquo;t have any programming experience and that it&amp;rsquo;s &lt;em>unreasonable&lt;/em> to expect them to learn some complex system and then figure out how to make the change they&amp;rsquo;re looking for, but you&amp;rsquo;re just not in the secret society of hacker enthusiasts who fix their own damn software and give back to the projects they use.&lt;/p></description></item><item><title>Spring 2010: A Random Walk</title><link>https://blog.ezyang.com/2010/05/spring-2010-a-random-walk/</link><pubDate>Fri, 14 May 2010 09:00:05 +0000</pubDate><guid>https://blog.ezyang.com/2010/05/spring-2010-a-random-walk/</guid><description>&lt;p>Here at the eve of Spring 2010 term, I decided to run this little experiment on my laptop: what files had I modified within the last six months?&lt;/p>
&lt;pre>&lt;code>find . \( -path '*/.*' \) -prune -o -mtime -180 -print
&lt;/code>&lt;/pre>
&lt;p>The result was north of one-hundred-fifty thousand modified files. Here&amp;rsquo;s the (slightly) abridged version:&lt;/p>
&lt;ul>
&lt;li>LaTeX files for &lt;a href="http://blog.ezyang.com/2010/01/adventures-in-three-monads/">&amp;ldquo;Adventures in Three Monads&amp;rdquo;&lt;/a>, an article that ran in the Monad Reader. Also, blackboard diagrams for my Advanced Typeclasses class I gave that IAP; I ended up not being able to get to the material I prepared for the Reader.&lt;/li>
&lt;li>&lt;code>valk.txt&lt;/code>, which contained notes for my Valkyrie Nethack character. I made my first ascension on March {24,25}th.&lt;/li>
&lt;li>An Eclipse Java project that served as the jumpboard for my &lt;a href="http://blog.ezyang.com/2010/03/the-case-of-the-hash-array-mapped-trie/">HAMT experiments&lt;/a>, under the purview of my undergraduate research project.&lt;/li>
&lt;li>&lt;code>htmlpurifier-web&lt;/code> and &lt;code>htmlpurifier&lt;/code>, courtesy of the &lt;a href="http://htmlpurifier.org/">HTML Purifier 4.1&lt;/a> release I pushed within the last month. (I suspect there will be another release coming soon too.) This also meant new builds of PHP 5.2.11, 5.2.12, 5.2.13, 5.3.1 and 5.3.2 for my super-amazing PHP &lt;a href="http://repo.or.cz/w/phpv.git">multi-version farm&lt;/a>. Note to self, next time, &lt;em>exclude&lt;/em> the build directories from your automated backups, kthxbai.&lt;/li>
&lt;li>A &lt;code>qemu&lt;/code> checkout, in which I attempted to fix their broken DHCP code when the same MAC address requests two different IP addresses, gave up, and assigned static addresses to the virtual machines we were using to demo live process migration. Mmm&amp;hellip; &lt;a href="http://pdos.csail.mit.edu/6.828/">6.828 final project&lt;/a>.&lt;/li>
&lt;li>A &lt;code>hackage-server&lt;/code> and &lt;code>holumbus&lt;/code> checkout, sprung from aborted dreams of making Holombus and Hackage cooperate to have up-to-the-minute index of all Haskell functions. I hear the Holumbus team has been making changes to make Hayoo be able to incrementally update its index.&lt;/li>
&lt;li>Updates to tidy up &lt;code>extort&lt;/code>, a membership dues tracking application written in Haskell, due to the recent change of leadership in the Assassins&amp;rsquo; Guild. During the replacement election, one of the suggested candidate questions was &amp;ldquo;Do you know Haskell.&amp;rdquo; We&amp;rsquo;ll see how long the program lasts&amp;hellip;&lt;/li>
&lt;li>An &lt;code>abc&lt;/code> source directory, in which I flexed my C source-diving skills and searched for information on how to use the library. I may be working closely with it in my internship at Galois. Curiously enough, this roughly coincided with the SAT solver that was to be written for 6.005, as well as the study of SAT in my computation complexity class 6.045.&lt;/li>
&lt;li>A &lt;code>mit-scheme&lt;/code> checkout, in order to analyze their red-black tree implementation to figure out how easily it could be persisted (the answer was no, and I had to write my own implementation off of Okasaki&amp;rsquo;s notes), and to figure out why &lt;code>--batch-mode&lt;/code> didn&amp;rsquo;t do &lt;a href="http://blog.ezyang.com/2010/04/art-code-math-and-mit-scheme/">what it said on the tin&lt;/a>.&lt;/li>
&lt;li>A &lt;code>log4j&lt;/code> source tree, which I used for two of my Software Engineering 6.005 projects. It was mostly painless to use, and I highly recommend it if you&amp;rsquo;re building software in Java.&lt;/li>
&lt;li>Lots of test directories for &lt;code>wizard&lt;/code> (note to self, backing those up is also a bad idea!) Some day, I&amp;rsquo;ll &lt;a href="http://scripts.mit.edu/wizard/">unleash this software&lt;/a> on the world, but for now, it&amp;rsquo;s usage is growing within the MIT sphere.&lt;/li>
&lt;/ul>
&lt;p>The really abridged version:&lt;/p></description></item><item><title>Refactoring Haskell code?</title><link>https://blog.ezyang.com/2010/05/refactoring-haskell-code/</link><pubDate>Wed, 12 May 2010 09:00:41 +0000</pubDate><guid>https://blog.ezyang.com/2010/05/refactoring-haskell-code/</guid><description>&lt;p>I have to admit, refactoring Haskell code (or perhaps even just functional code) is a bit of a mystery to me. A typical refactoring session for me might look like this: &lt;em>sit down in front of code, reread code. Run hlint on the code, fix the problems it gives you. Look at the code some more. Make some local transformations to make a pipeline tighter or give a local subexpression a name. Decide the code is kind of pretty and functional and go do something else.&lt;/em>&lt;/p></description></item><item><title>Nested Data Parallelism versus Creative Catamorphisms</title><link>https://blog.ezyang.com/2010/05/nd-vs-catamorphisms/</link><pubDate>Mon, 10 May 2010 09:00:49 +0000</pubDate><guid>https://blog.ezyang.com/2010/05/nd-vs-catamorphisms/</guid><description>&lt;p>I got to watch (&lt;em>unfortunately not in person&lt;/em>) Simon Peyton Jones&amp;rsquo; excellent talk (&lt;em>no really, if you haven&amp;rsquo;t seen it, you should carve out the hour necessary to watch it&lt;/em>) on &lt;a href="http://www.youtube.com/watch?v=NWSZ4c9yqW8">Data Parallel Haskell&lt;/a> (&lt;a href="http://research.microsoft.com/en-us/um/people/simonpj/papers/ndp/NdpSlides.pdf">slides&lt;/a>). The talk got me thinking about a &lt;a href="http://blog.ezyang.com/2010/04/creative-catamorphisms/">previous talk about parallelism&lt;/a> given by Guy Steele I had seen recently.&lt;/p>
&lt;p>What&amp;rsquo;s the relationship between these two talks? At first I though, &amp;ldquo;Man, Guy Steele must be advocating a discipline for programmers, while Simon Peyton Jones&amp;rsquo; is advocating a discipline for compilers.&amp;rdquo; But this didn&amp;rsquo;t really seem to fit right: maybe you have a clever catamorphism for the problem, the overhead for fully parallelizing everything is prohibitive. As Steele notes, we need &amp;ldquo;hybrid sequential/parallel strategies,&amp;rdquo; the most simple of which is &amp;ldquo;parallelize it until it&amp;rsquo;s manageable and run the fast sequential algorithm on it,&amp;rdquo; ala flat data parallelism. Nor is nested data parallelism a silver bullet; while it has wider applicability, there are still domains it fits poorly on.&lt;/p></description></item><item><title>Omnipresent Cabal</title><link>https://blog.ezyang.com/2010/05/omnipresent-cabal/</link><pubDate>Fri, 07 May 2010 09:00:34 +0000</pubDate><guid>https://blog.ezyang.com/2010/05/omnipresent-cabal/</guid><description>&lt;p>A short public service announcement: you might think you don&amp;rsquo;t need Cabal. Oh, you might be just whipping up a tiny throw-away script, or a small application that you never intend on distributing. &lt;em>Cabal? Isn&amp;rsquo;t that what you do if you&amp;rsquo;re planning on sticking your package on Hackage?&lt;/em> But the Cabal always knows. The Cabal is always there. And you should embrace the Cabal, even if you think you&amp;rsquo;re too small to care. Here&amp;rsquo;s why:&lt;/p></description></item><item><title>Name conflicts on Hackage</title><link>https://blog.ezyang.com/2010/05/name-conflicts-on-hackage/</link><pubDate>Wed, 05 May 2010 09:00:12 +0000</pubDate><guid>https://blog.ezyang.com/2010/05/name-conflicts-on-hackage/</guid><description>&lt;p>&lt;em>Attention Conservation Notice.&lt;/em> Unqualified identifiers that are used the most on Hackage.&lt;/p>
&lt;p>Perhaps you dread the error message:&lt;/p>
&lt;pre>&lt;code>Ambiguous occurrence `lookup'
It could refer to either `Prelude.lookup', imported from Prelude
 or `Data.Map.lookup', imported from Data.Map
&lt;/code>&lt;/pre>
&lt;p>It is the message of the piper that has come to collect his dues for your unhygenic unqualified unrestricted module import style.&lt;/p>
&lt;p>Or perhaps your a library writer and trying to think up of a new symbol for your funky infix combinator, but you aren&amp;rsquo;t sure what other libraries have used already.&lt;/p></description></item><item><title>Design Patterns in Haskell</title><link>https://blog.ezyang.com/2010/05/design-patterns-in-haskel/</link><pubDate>Mon, 03 May 2010 09:00:32 +0000</pubDate><guid>https://blog.ezyang.com/2010/05/design-patterns-in-haskel/</guid><description>&lt;p>&lt;em>Attention Conservation Notice.&lt;/em> A listing of how Gang of Four design patterns might be equivalently implemented in Haskell. A phrasebook for object-oriented programmers dealing with functional programming concepts.&lt;/p>
&lt;p>In their introduction to seminal work &lt;em>Design Patterns&lt;/em>, the Gang of Four say, &amp;ldquo;The choice of programming language is important because it influences one&amp;rsquo;s point of view. Our patterns assume Smalltalk/C++-level language features, and that choice determines what can and cannot be implemented easily. If we assumed procedural languages, we might have included design patterns called &amp;lsquo;Inheritance,&amp;rsquo; &amp;lsquo;Encapsulation,&amp;rsquo; and &amp;lsquo;Polymorphism.&amp;rsquo;&amp;rdquo;&lt;/p></description></item><item><title>Art. Code. Math. (And mit-scheme)</title><link>https://blog.ezyang.com/2010/04/art-code-math-and-mit-scheme/</link><pubDate>Fri, 30 Apr 2010 09:00:49 +0000</pubDate><guid>https://blog.ezyang.com/2010/04/art-code-math-and-mit-scheme/</guid><description>&lt;p>I was in rehearsal today, doodling away second oboe for Saint Saens&amp;rsquo; Organ Symphony for the nth time, and it occurred to me: I&amp;rsquo;ve listened to and played this piece of music enough times to know the full overall flow as well as a good chunk of the orchestral parts, not just mine. So when the hymnal calls give way to the triumphant entrance of the organ in the last movement, or when the tempos start shifting, simultaneously speeding up and slowing down, at the end of the piece, it&amp;rsquo;s not surprising; it&amp;rsquo;s almost inevitable. Couldn&amp;rsquo;t have it any other way.&lt;/p></description></item><item><title>Inessential guide to fclabels</title><link>https://blog.ezyang.com/2010/04/inessential-guide-to-fclabels/</link><pubDate>Wed, 28 Apr 2010 09:00:04 +0000</pubDate><guid>https://blog.ezyang.com/2010/04/inessential-guide-to-fclabels/</guid><description>&lt;p>Last time I did an &lt;a href="http://blog.ezyang.com/2010/04/inessential-guide-to-data-accessor/">Inessential guide to data-accessor&lt;/a> and everyone told me, &amp;ldquo;You should use fclabels instead!&amp;rdquo; So here&amp;rsquo;s the partner guide, the inessential guide to fclabels. Like data-accessor the goal is to make record access and editing not suck. However, it gives you some more useful abstractions. It uses Template Haskell on top of your records, so it is not compatible with data-accessor.&lt;/p>
&lt;p>&lt;em>Identification.&lt;/em> There are three tell-tale signs:&lt;/p></description></item><item><title>The Problem with xUnit</title><link>https://blog.ezyang.com/2010/04/the-problem-with-xunit/</link><pubDate>Mon, 26 Apr 2010 09:00:07 +0000</pubDate><guid>https://blog.ezyang.com/2010/04/the-problem-with-xunit/</guid><description>&lt;p>Tagline: &lt;em>Assertions considered not ideal.&lt;/em>&lt;/p>
&lt;p>I think automated tests are great. I used two particular flavors of test, the unit test and the integration test, extensively in &lt;a href="http://htmlpurifier.org">HTML Purifier&lt;/a> and they&amp;rsquo;re the only reason why I feel comfortable making changes to code that I first wrote in High School. The automated tests let me hack and then figure out if I broke anything with the single stroke of a button, rather than manually shove a few inputs in and see if they &amp;ldquo;look alright.&amp;rdquo; They&amp;rsquo;re also an informal specification of &amp;ldquo;what I wanted the code to do&amp;rdquo; when I originally wrote it, by the fine tradition of an example.&lt;/p></description></item><item><title>Creative catamorphisms</title><link>https://blog.ezyang.com/2010/04/creative-catamorphisms/</link><pubDate>Fri, 23 Apr 2010 09:00:57 +0000</pubDate><guid>https://blog.ezyang.com/2010/04/creative-catamorphisms/</guid><description>&lt;p>&lt;em>The bag of programming tricks that has served us so well for the last 50 years is the wrong way to think going forward and must be thrown out.&lt;/em>&lt;/p>
&lt;p>Last week, Guy Steele came in and did a guest lecture &lt;a href="http://groups.csail.mit.edu/mac/users/gjs/6.945/readings/MITApril2009Steele.pdf">&amp;ldquo;The Future is Parallel: What&amp;rsquo;s a Programmer to Do?&amp;rdquo;&lt;/a> for my advanced symbolic class (6.945). It&amp;rsquo;s a really excellent talk; such an excellent talk that I had seen the slides for prior to the talk. However hearing Guy Steele talk about it in person really helped set things in context for me.&lt;/p></description></item><item><title>Association maps in mit-scheme</title><link>https://blog.ezyang.com/2010/04/association-maps-in-mit-scheme/</link><pubDate>Wed, 21 Apr 2010 09:00:08 +0000</pubDate><guid>https://blog.ezyang.com/2010/04/association-maps-in-mit-scheme/</guid><description>&lt;p>I recently some did some benchmarking of persistent data structures in mit-scheme for my UROP. There were a few questions we were interested in:&lt;/p>
&lt;ol>
&lt;li>For what association sizes does a fancier data structure beat out your plain old association list?&lt;/li>
&lt;li>What is the price of persistence? That is, how many times slower are persistent data structures as compared to your plain old hash table?&lt;/li>
&lt;li>What is the best persistent data structure?&lt;/li>
&lt;/ol>
&lt;p>These are by no means authoritative results; I still need to carefully comb through the harness and code for correctness. But they already have some interesting implications, so I thought I&amp;rsquo;d share. The implementations tested are:&lt;/p></description></item><item><title>Thoughts on discussion</title><link>https://blog.ezyang.com/2010/04/thoughts-on-discussion/</link><pubDate>Mon, 19 Apr 2010 09:00:52 +0000</pubDate><guid>https://blog.ezyang.com/2010/04/thoughts-on-discussion/</guid><description>&lt;p>In today&amp;rsquo;s world of social news aggregation websites, ala Reddit, Digg, Slashdot, it is rare for the sole dialog between an author and a reader to take place on a private channel or on one&amp;rsquo;s website. I discovered this rather bluntly when I found that a &lt;a href="http://htmlpurifier.org/docs/enduser-utf8.html">document&lt;/a> I had written had amassed a number of comments, one of which &lt;a href="http://www.reddit.com/r/programming/comments/6mlqc/utf8_the_secret_of_character_encoding/c04aold">pointed out an error&lt;/a> in what I had written, and then &lt;em>failed to notify me&lt;/em>.&lt;/p></description></item><item><title>Dudamel visits MIT</title><link>https://blog.ezyang.com/2010/04/dudamel-visits-mit/</link><pubDate>Fri, 16 Apr 2010 09:00:54 +0000</pubDate><guid>https://blog.ezyang.com/2010/04/dudamel-visits-mit/</guid><description>&lt;p>Conductor and violinist &lt;a href="http://en.wikipedia.org/wiki/Gustavo_Dudamel">Gustavo Dudamel&lt;/a> will be visiting MIT today to accept the &lt;a href="http://web.mit.edu/press/2009/dudamel-mcdermott.html">Eugene McDermott Award in the Arts&lt;/a>. Part of the awards ceremony will include a session with Dudamel conducting the &lt;a href="http://web.mit.edu/mitso/">MIT Symphony Orchestra&lt;/a>; I&amp;rsquo;ll be on stage playing Oboe and English Horn on Rimsky Korsakov and Mozart. Our regular conductor (Adam Boyles) has been prepping us for this by taking, erm, &lt;em>unusual&lt;/em> liberties in tempo and phrasing.&lt;/p>
&lt;p>I&amp;rsquo;m not usually very aware of names of conductors, but I have heard Dudamel&amp;rsquo;s float across &lt;a href="http://www.wqxr.org/articles/wqxr-features/2010/jan/08/wqxr-arts-file-new-year-new-opera/">WQXR&lt;/a> on occasion. The evening promises to be exciting.&lt;/p></description></item><item><title>Inessential Guide to data-accessor</title><link>https://blog.ezyang.com/2010/04/inessential-guide-to-data-accessor/</link><pubDate>Wed, 14 Apr 2010 09:00:23 +0000</pubDate><guid>https://blog.ezyang.com/2010/04/inessential-guide-to-data-accessor/</guid><description>&lt;p>&lt;a href="http://hackage.haskell.org/package/data-accessor-0.2.1.2">data-accessor&lt;/a> is a package that makes records &lt;em>not suck.&lt;/em> Instead of this code:&lt;/p>
&lt;pre>&lt;code>newRecord = record {field = newVal}
&lt;/code>&lt;/pre>
&lt;p>You can write this:&lt;/p>
&lt;pre>&lt;code>newRecord = field ^= newVal
 $ record
&lt;/code>&lt;/pre>
&lt;p>In particular, &lt;code>(field ^= newVal)&lt;/code> is now a value, &lt;em>not&lt;/em> a bit of extra syntax, that you can treat as a first-class citizen.&lt;/p>
&lt;p>I came across this module while attempting to use &lt;a href="http://hackage.haskell.org/package/Chart">Chart&lt;/a> (of criterion fame) to graph some data. I didn&amp;rsquo;t recognize it at first, though; it was only after playing around with code samples did I realize that &lt;code>^=&lt;/code> was not a combinator that Chart had invented for its own use (as opposed to the potpourri of &lt;code>--&amp;gt;&lt;/code>, &lt;code>&amp;lt;+&amp;gt;&lt;/code>, &lt;code>|||&lt;/code> and friends you might see in an &lt;em>xmonad.hs&lt;/em>). When utilized with Template Haskell, Data.Accessor represents something of a &lt;em>replacement&lt;/em> for the normal record system, and so it&amp;rsquo;s useful to know when a module speaks this other language. Signs that you&amp;rsquo;re in a module using Data.Accessor:&lt;/p></description></item><item><title>Later Impressions of the VX-8R</title><link>https://blog.ezyang.com/2010/04/later-impressions-of-the-vx-8r/</link><pubDate>Mon, 12 Apr 2010 09:00:02 +0000</pubDate><guid>https://blog.ezyang.com/2010/04/later-impressions-of-the-vx-8r/</guid><description>&lt;p>Earlier in January, I blogged some &lt;a href="http://blog.ezyang.com/2010/01/vx-8r-review/">first impressions about the VX-8R&lt;/a>. It&amp;rsquo;s now three months later, and I&amp;rsquo;ve used my radio on some more extensive field tests. I&amp;rsquo;m considering selling my VX-8R for a 7R, for the following reasons:&lt;/p>
&lt;ul>
&lt;li>I generally need five hours of receive with medium transmission. I only get about 3.5 hours worth of receive with the standard VX-8R battery. This is not really acceptable. (At risk of being &amp;ldquo;get off my lawn&amp;rdquo;, &lt;a href="http://www.1ts.org/~kcr/">Karl Ramm&lt;/a> comments that his old Icom W32 from the 90s got 12 hours of receive.)&lt;/li>
&lt;li>The AA battery adapter is laughable, giving maybe 20min of receive time before flagging. The ability to run digital cameras on AA batteries had given me the false impression that I&amp;rsquo;d be able to do the same for a radio, really this adapter is only fit for emergency receive situations.&lt;/li>
&lt;li>The remaining battery indicator unreliable, going from 8.5V to 7.5V, and then dropping straight to zero. This is the defect I sent mine back in for last time, but I saw this problem in the replacement, and a friend confirmed that he saw the same on his.&lt;/li>
&lt;li>The radio gets quite hot during operation. I&amp;rsquo;d never noticed the temperature with the 7R.&lt;/li>
&lt;li>Everyone else around here owns a 7R, which severely limits the swappability of various components (in particular, batteries).&lt;/li>
&lt;/ul>
&lt;p>I really am going to miss the dedicated stereo jack and slimmer (and, in my opinion, better) interface, but these really are deal breakers. &lt;em>C&amp;rsquo;ést la vie.&lt;/em>&lt;/p></description></item><item><title>Diagramming in Xournal and Gimp</title><link>https://blog.ezyang.com/2010/04/diagramming-in-xournal-and-gimp/</link><pubDate>Fri, 09 Apr 2010 09:00:35 +0000</pubDate><guid>https://blog.ezyang.com/2010/04/diagramming-in-xournal-and-gimp/</guid><description>&lt;p>Two people have asked me how drew the diagrams for my previous post &lt;a href="http://blog.ezyang.com/2010/04/you-could-have-invented-zippers/">You Could Have Invented Zippers&lt;/a>, and I figured I&amp;rsquo;d share it with a little more elaboration to the world, since it&amp;rsquo;s certainly been a bit of experimentation before I found a way that worked for me.&lt;/p>
&lt;p>Diagramming software for Linux sucks. Those of you on Mac OS X can churn out eye-poppingly beautiful diagrams using &lt;a href="http://www.omnigroup.com/products/OmniGraffle/">OmniGraffle&lt;/a>; the best we can do is some dinky GraphViz output, or maybe if we have a lot of time, a painstakingly crafted SVG file from Inkscape. This takes too long for my taste.&lt;/p></description></item><item><title>You could have invented zippers</title><link>https://blog.ezyang.com/2010/04/you-could-have-invented-zippers/</link><pubDate>Wed, 07 Apr 2010 09:00:54 +0000</pubDate><guid>https://blog.ezyang.com/2010/04/you-could-have-invented-zippers/</guid><description>&lt;p>In the beginning, there was a binary tree:&lt;/p>
&lt;pre>&lt;code>struct ctree { // c for children
 int val;
 struct ctree *left;
 struct ctree *right;
}
&lt;/code>&lt;/pre>
&lt;p>The flow of pointers ran naturally from the root of the tree to the leaves, and it was easy as blueberry pie to walk to the children of a node.&lt;/p>
&lt;p>&lt;img src="https://blog.ezyang.com/img/zipper/ctree.png" alt="image">&lt;/p>
&lt;p>Unfortunately, given a node, there was no good way to find out its parent! If you only needed efficient parent access, though, you could just use a single pointer in the other direction:&lt;/p></description></item><item><title>Cup of FP with a Java twist</title><link>https://blog.ezyang.com/2010/04/cup-of-fp-java-twis/</link><pubDate>Mon, 05 Apr 2010 09:00:26 +0000</pubDate><guid>https://blog.ezyang.com/2010/04/cup-of-fp-java-twis/</guid><description>&lt;pre>&lt;code>zip: List&amp;lt;A&amp;gt;, List&amp;lt;B&amp;gt; -&amp;gt; List&amp;lt;(A, B)&amp;gt;
zip(Nil, Nil) = Nil
zip(_, Nil) = Nil
zip(Nil, _) = Nil
zip(Cons(a, as), Cons(b, bs)) = Cons((a, b), zip(as, bs))

fst: (A, B) -&amp;gt; A
fst((a, _)) = a

last: List&amp;lt;A&amp;gt; -&amp;gt; A
last(Cons(a, Nil)) = a
last(Cons(a, as)) = last(as)

foldl: (B, A -&amp;gt; B), B, List&amp;lt;A&amp;gt; -&amp;gt; B
foldl(_, z, Nil) = z
foldl(f, z, Cons(x, xs)) = foldl(f, f(z, x), xs)
&lt;/code>&lt;/pre>
&lt;p>Good grief Edward, what do you have there? It&amp;rsquo;s almost as if it were some bastardized hybrid of Haskell, Java and ML.&lt;/p></description></item><item><title>Summer internship at Galois</title><link>https://blog.ezyang.com/2010/04/summer-internship-at-galois/</link><pubDate>Fri, 02 Apr 2010 09:00:46 +0000</pubDate><guid>https://blog.ezyang.com/2010/04/summer-internship-at-galois/</guid><description>&lt;p>I&amp;rsquo;m happy to report that I&amp;rsquo;ll be interning at &lt;a href="http://www.galois.com/">Galois&lt;/a> over the summer. I&amp;rsquo;m not quite sure how the name of the company passed into my consciousness, but at some point in January I decided it would be really cool to work at an all-Haskell shop, and began pestering Don Stewart (and Galois&amp;rsquo;s HR) for the next two months.&lt;/p>
&lt;p>I&amp;rsquo;ll be working on some project within Cryptol; there were a few specific project ideas tossed around though it&amp;rsquo;s not clear if they&amp;rsquo;ll have already finished one of my projects by the time the summer rolls around. I&amp;rsquo;m also really looking forward to working in an environment with a much higher emphasis towards research, since I need to figure out if I&amp;rsquo;m going to start gunning for a PhD program at the end of my undergraduate program.&lt;/p></description></item><item><title>More fun with Futamura projections</title><link>https://blog.ezyang.com/2010/03/more-fun-with-futamura-projections/</link><pubDate>Wed, 31 Mar 2010 09:00:41 +0000</pubDate><guid>https://blog.ezyang.com/2010/03/more-fun-with-futamura-projections/</guid><description>&lt;p>&lt;em>Code written by Anders Kaseorg.&lt;/em>&lt;/p>
&lt;p>In &lt;a href="http://blog.sigfpe.com/2009/05/three-projections-of-doctor-futamura.html">The Three Projections of Doctor Futamura&lt;/a>, Dan Piponi treats non-programmers to an explanation to the Futamura projections, a series of mind-bending applications of partial evaluation. Go over and read it if you haven&amp;rsquo;t already; this post is intended as a spiritual successor to that one, in which we write some Haskell code.&lt;/p>
&lt;p>&lt;em>The pictorial type of a mint.&lt;/em> In the original post, Piponi drew out machines which took various coins, templates or other machines as inputs, and gave out coins or machines as outputs. Let&amp;rsquo;s rewrite the definition in something that looks a little bit more like a Haskell type.&lt;/p></description></item><item><title>The case of the Hash Array Mapped Trie</title><link>https://blog.ezyang.com/2010/03/the-case-of-the-hash-array-mapped-trie/</link><pubDate>Mon, 29 Mar 2010 09:00:46 +0000</pubDate><guid>https://blog.ezyang.com/2010/03/the-case-of-the-hash-array-mapped-trie/</guid><description>&lt;p>The fast, efficient association map has long been the holy grail of the functional programming community. If you wanted such an abstract data structure in an imperative language, there would be no question about it: you would use a hash table. But the fact that the hash table is founded upon the destructive update makes it hard to use with pure code.&lt;/p>
&lt;p>What we are in search of is a strictly more powerful association map, one that implements a &lt;em>non-destructive&lt;/em> update (i.e. is &amp;ldquo;persistent&amp;rdquo;). In the Haskell world, &lt;a href="http://www.haskell.org/ghc/docs/6.10.4/html/libraries/containers/Data-Map.html">Data.Map&lt;/a> is a reasonably compelling general-purpose structure that only requires the &lt;code>Ord&lt;/code> typeclass on its keys. For keys that map cleanly on to machine-size integers, &lt;a href="http://hackage.haskell.org/packages/archive/containers/0.1.0.1/doc/html/Data-IntMap.html">IntMap&lt;/a> is an extremely fast purely functional that uses bit twiddling tricks on top of big-endian Patricia tries.&lt;/p></description></item><item><title>Ad hoc wireless</title><link>https://blog.ezyang.com/2010/03/ad-hoc-wireless/</link><pubDate>Wed, 24 Mar 2010 09:00:05 +0000</pubDate><guid>https://blog.ezyang.com/2010/03/ad-hoc-wireless/</guid><description>&lt;p>Hello from Montreal! I&amp;rsquo;m writing this from a wireless connection up on the thirty-ninth floor of La Cité. Unfortunately, when we reading the lease, the only thing we checked was that it had &amp;ldquo;Internet&amp;rdquo;&amp;hellip; not &amp;ldquo;Wireless.&amp;rdquo; So what&amp;rsquo;s a troop of MIT students with an arsenal of laptops and no wireless router to do? Set up wireless ad hoc networking.&lt;/p>
&lt;p>Except it doesn&amp;rsquo;t actually work. Mostly. It took us a bit of fiddling and attempts on multiple laptops to finally find a configuration that worked. First, the ones that didn&amp;rsquo;t work:&lt;/p></description></item><item><title>Hunting for abstractions in mathematics</title><link>https://blog.ezyang.com/2010/03/abstractions-in-mathematics/</link><pubDate>Mon, 22 Mar 2010 09:00:20 +0000</pubDate><guid>https://blog.ezyang.com/2010/03/abstractions-in-mathematics/</guid><description>&lt;blockquote>
&lt;p>&lt;strong>Abstraction&lt;/strong> (n.) The act or process of separating in thought, of considering a thing independently of its associations; or a substance independently of its attributes; or an attribute or quality independently of the substance to which it belongs. (Oxford English Dictionary)&lt;/p>&lt;/blockquote>
&lt;p>Abstraction is one of the most powerful beasts in the landscape of programming, but it is also one of the most elusive to capture. The places where abstraction may be found are many:&lt;/p></description></item><item><title>Mutation sleuthing in Python</title><link>https://blog.ezyang.com/2010/03/mutation-sleuthing-in-python/</link><pubDate>Fri, 19 Mar 2010 09:00:27 +0000</pubDate><guid>https://blog.ezyang.com/2010/03/mutation-sleuthing-in-python/</guid><description>&lt;p>Python is a language that gives you a lot of rope, in particular any particular encapsulation scheme is only weakly enforced and can be worked around by a sufficiently savvy hacker. I fall into the &amp;ldquo;my compiler should stop me from doing stupid things&amp;rdquo; camp, but I&amp;rsquo;ll certainly say, dynamic capabilities sure are convenient. But here&amp;rsquo;s the rub: &lt;em>the language must show you where you have done something stupid.&lt;/em>&lt;/p>
&lt;p>In this case, we&amp;rsquo;d like to see when you have improperly gone and mutated some internal state. You might scoff and say, &amp;ldquo;well, I know when &lt;em>I&lt;/em> change &lt;em>my&lt;/em> state&amp;rdquo;, but this is certainly not the case when you&amp;rsquo;re debugging an interaction between two third party libraries that you did not write. Specifically I should be able to point at a variable (it might be a local variable, a global variable, or a class/instance attribute) and say to Python, &amp;ldquo;tell me when this variable changes.&amp;rdquo; When the variable changes, Python should tell me who changed the variable (via a backtrace) and what the variable changed to. I should be able to say, &amp;ldquo;tell me when this variable changed to this value.&amp;rdquo;&lt;/p></description></item><item><title>Haskell, The Hard Sell</title><link>https://blog.ezyang.com/2010/03/haskell-the-hard-sell/</link><pubDate>Wed, 17 Mar 2010 09:00:13 +0000</pubDate><guid>https://blog.ezyang.com/2010/03/haskell-the-hard-sell/</guid><description>&lt;p>Last week I talked about how &lt;a href="http://blog.ezyang.com/2010/03/replacing-small-c-programs-with-haskell/">we replaced a small C program with an equivalent piece of Haskell code.&lt;/a> As much as I&amp;rsquo;d like to say that we deployed the code and there was much rejoicing and client side caching, the real story is a little more complicated than that. There were some really good questions that we had to consider:&lt;/p>
&lt;ol>
&lt;li>
&lt;p>&lt;em>How many maintainers at any given time know the language?&lt;/em> The &lt;a href="http://scripts.mit.edu">Scripts&lt;/a> project is student-run, and has an unusually high turnover rate: any given maintainer is only guaranteed to be around for four to five years (maybe a little longer if they stick around town, but besides a few notable exceptions, most people move on after their time as a student). This means at any given point we have to worry about whether or not the sum knowledge of the active contributors is enough to cover all facets of the system, and facility in a language is critical to being able to administrate the component effectively (students we are, we frequently don both the sysadmin and developer hats). In a corporate setting, this is less prominent, but it still plays a factor: employees switch from one group to another and eventually people leave or retire. We have two current maintainers who are fairly fluent in Haskell. The long-term sustainability of this approach is uncertain, and hinges on our ability to attract prospective students who know or are interested in learning Haskell; in the worst case, people may crack open the code, say &amp;ldquo;what the fuck is this&amp;rdquo; and rewrite it in another language.&lt;/p></description></item><item><title>Straitjacket programming</title><link>https://blog.ezyang.com/2010/03/straitjacket-programming/</link><pubDate>Mon, 15 Mar 2010 09:00:41 +0000</pubDate><guid>https://blog.ezyang.com/2010/03/straitjacket-programming/</guid><description>&lt;p>The importance of constraint is one well known to those who embark on creative endeavors. Tell someone, &amp;ldquo;you can do anything you want: anything at all,&amp;rdquo; and they will blank, paralyzed by the infinite possibility. Artists welcome constraint. Writers like the constraint of a sonnet because it imposes form and gives a place to start; roleplaying groups like the constraint of a campaign setting because it imposes rules and sets the scene for the story to be told; jazz musicians like the constraint of the chords underlying an improvisation because it keeps the soloist anchored to the source tune and suggests ideas for the melody.&lt;/p></description></item><item><title>Five tips for maintainable shell scripts</title><link>https://blog.ezyang.com/2010/03/five-tips-for-maintainable-shell-scripts/</link><pubDate>Fri, 12 Mar 2010 09:00:07 +0000</pubDate><guid>https://blog.ezyang.com/2010/03/five-tips-for-maintainable-shell-scripts/</guid><description>&lt;p>When I was seventeen, I wrote my &lt;a href="http://repo.or.cz/w/htmlpurifier-web.git/blob/136caa2d941e51e5a742df3b05fb3e596f778636:/releases/build.bat">very first shell script&lt;/a>. It was a Windows batch file, bits and pieces very carefully cargo-culted from various code samples on the web. I had already had the &lt;em>exquisite&lt;/em> pleasure of futzing with &lt;code>pear.bat&lt;/code>, and the thought of scripting was not something I relished; &amp;ldquo;why not write the damn thing in a &lt;em>real&lt;/em> programming language!&amp;rdquo; (The extra delicious bit was &amp;ldquo;a real programming language&amp;rdquo; was PHP. Hee.)&lt;/p></description></item><item><title>Replacing small C programs with Haskell</title><link>https://blog.ezyang.com/2010/03/replacing-small-c-programs-with-haskell/</link><pubDate>Wed, 10 Mar 2010 09:00:24 +0000</pubDate><guid>https://blog.ezyang.com/2010/03/replacing-small-c-programs-with-haskell/</guid><description>&lt;p>C is the classic go-to tool for small programs that need to be really fast. When &lt;a href="http://scripts.mit.edu/">scripts.mit.edu&lt;/a> needed a small program to be &lt;a href="http://scripts.mit.edu/trac/browser/trunk/server/common/oursrc/execsys/static-cat.c.pre">a glorified cat&lt;/a> that also added useful HTTP headers to the beginning of its output, there was no question about it: it would be written in C, and it would be fast; the speed of our static content serving depended on it! (The grotty technical details: our webserver is based off of a networked filesystem, and we wanted to avoid giving Apache too many credentials in case it got compromised. Thus, we patched our kernel to enforce an extra stipulation that you must be running as some user id in order to read those files off the filesystem. Apache runs as it&amp;rsquo;s own user, so we need another &lt;em>small&lt;/em> program to act as the go-between.)&lt;/p></description></item><item><title>Being an expert considered harmful</title><link>https://blog.ezyang.com/2010/03/expert-considered-harmful/</link><pubDate>Mon, 08 Mar 2010 09:00:20 +0000</pubDate><guid>https://blog.ezyang.com/2010/03/expert-considered-harmful/</guid><description>&lt;p>&lt;em>It&amp;rsquo;s a sunny day in your advanced symbolic programming class. Your teacher has just started going over monads—in Scheme, though—and you sit in the back of the classroom snarking about little tidbits of knowledge you know from Haskell. Suddenly, the teacher says (quite earnestly too), &amp;ldquo;Edward here seems to know a lot about monads. Why don&amp;rsquo;t we have him come up and teach them to the class?&amp;rdquo; Suddenly, you&amp;rsquo;re up expounding types to people who have never used Haskell before and failing utterly to explain to people how the continuation monad works. Only after several iterations do you manage to partially rewrite the presentation in a form that doesn&amp;rsquo;t assume fluency in Haskell. You&amp;rsquo;ve fallen into the expert trap.&lt;/em>&lt;/p></description></item><item><title>How to use Vim's textwidth like a pro</title><link>https://blog.ezyang.com/2010/03/vim-textwidth/</link><pubDate>Fri, 05 Mar 2010 09:00:53 +0000</pubDate><guid>https://blog.ezyang.com/2010/03/vim-textwidth/</guid><description>&lt;p>There are lots of little blog posts containing advice about various one-line options you can do in Vim. This post falls into that category, but I&amp;rsquo;m hoping to do a more comprehensive view into one small subsystem of Vim&amp;rsquo;s configuration: automatic line wrapping.&lt;/p>
&lt;p>When programming, automatic line wrapping can be a little obnoxious because even &lt;em>if&lt;/em> a piece of code is hanging past the recommended 72/80 column width line, you probably don&amp;rsquo;t want to immediately break it; but if you&amp;rsquo;re writing a text document or an email message, that is specifically the behavior you want. By default, vim does no automatic line wrapping for you; turning it on is a question of being able to toggle it on and off when you want it.&lt;/p></description></item><item><title>Third-party unattended upgrades in three steps</title><link>https://blog.ezyang.com/2010/03/third-party-unattended-upgrade/</link><pubDate>Wed, 03 Mar 2010 12:00:59 +0000</pubDate><guid>https://blog.ezyang.com/2010/03/third-party-unattended-upgrade/</guid><description>&lt;p>&lt;a href="http://packages.ubuntu.com/karmic/unattended-upgrades">unattended-upgrades&lt;/a> is a nifty little package that will go ahead and automatically install updates for you as they become enabled. No serious system administrator should use this (you &lt;em>are&lt;/em> testing updates before pushing them to the servers, right?) but for many personal uses automatic updates are really what you want; if you run &lt;code>sudo aptitude full-upgrade&lt;/code> and don&amp;rsquo;t read the changelog, you might as well turn on unattended upgrades. You can do this by adding the line &lt;code>APT::Periodic::Unattended-Upgrade &amp;quot;1&amp;quot;&lt;/code> to &lt;code>/etc/apt/apt.conf.d/10periodic&lt;/code> (thanks Ken!)&lt;/p></description></item><item><title>Writing generator friendly code</title><link>https://blog.ezyang.com/2010/03/writing-generator-friendly-code/</link><pubDate>Mon, 01 Mar 2010 12:00:34 +0000</pubDate><guid>https://blog.ezyang.com/2010/03/writing-generator-friendly-code/</guid><description>&lt;p>I&amp;rsquo;ve come a long ways from &lt;a href="http://www.mail-archive.com/html5lib-discuss@googlegroups.com/msg00241.html">complaining to the html5lib list that the Python version gratuitously used generators, making it hard to port to PHP&lt;/a>. Having now drunk the laziness kool-aid in Haskell, I enjoy trying to make my code fit the generator idiom. While Python generators have notable downsides compared to infinite lazy lists (for example, forking them for multiple use is nontrivial), they&amp;rsquo;re pretty nice.&lt;/p>
&lt;p>Unfortunately, the majority of code I see that expects to see lists isn&amp;rsquo;t robust enough to accept generators too, and it breaks my heart when I have to say &lt;code>list(generator)&lt;/code>. I&amp;rsquo;ll forgive you if you&amp;rsquo;re expecting O(1) accesses of arbitrary indexes in your internal code, but all too often I see code that only needs sequential access, only to botch it all up by calling &lt;code>len()&lt;/code>. Duck typing won&amp;rsquo;t save you there.&lt;/p></description></item><item><title>History as documentation</title><link>https://blog.ezyang.com/2010/02/history-as-documentation/</link><pubDate>Fri, 26 Feb 2010 12:00:40 +0000</pubDate><guid>https://blog.ezyang.com/2010/02/history-as-documentation/</guid><description>&lt;p>It&amp;rsquo;s &lt;a href="http://developers.slashdot.org/story/09/11/16/1626218/If-the-Comments-Are-Ugly-the-Code-Is-Ugly">real&lt;/a> &lt;a href="http://ask.slashdot.org/article.pl?sid=06/01/09/1544201">easy&lt;/a> to &lt;a href="http://developers.slashdot.org/story/10/01/01/226232/Myths-About-Code-Comments">argue&lt;/a> about the utility, style and implementation of source code comments, those good ole&amp;rsquo; pals of code that try to add supplementary information when the &lt;a href="http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-7.html">pure code isn&amp;rsquo;t enough&lt;/a>.&lt;/p>
&lt;p>However, to focus solely on the latest snapshot of any particular source file is to miss a wealth of information that is not inside the file; namely, the history of the file and the genealogy of every line that graces the file. This is not so relevant when you are rapidly prototyping functionality and versions of the file in source control history represent incomplete, half-baked figments of thought, but once a codebase transitions into a more maintenance-oriented workflow, the history takes on a keen and unusual importance. In particular:&lt;/p></description></item><item><title>The Art of Posing a Problem</title><link>https://blog.ezyang.com/2010/02/art-of-posing-a-problem/</link><pubDate>Wed, 24 Feb 2010 12:00:01 +0000</pubDate><guid>https://blog.ezyang.com/2010/02/art-of-posing-a-problem/</guid><description>&lt;p>Last week, I was talking with &lt;a href="http://web.mit.edu/~axch/www/">Alexey Radul&lt;/a> to figure out some interesting research problems that I can cut my teeth on. His &lt;a href="http://web.mit.edu/~axch/www/phd-thesis.pdf">PhD thesis&lt;/a> discusses &amp;ldquo;propagation networks&amp;rdquo;, which he argues is a more general substrate for computation than traditional methods. It&amp;rsquo;s a long work, and it leaves open many questions, both theoretical and practical. I&amp;rsquo;m now tackling one very small angle with regards to the implementation of the system, but while we were still figuring a problem out, Alexy commented, &amp;ldquo;the more work I realize it takes to do a good job of giving someone a problem.&amp;rdquo;&lt;/p></description></item><item><title>Comonads and Convolutions</title><link>https://blog.ezyang.com/2010/02/comonads-and-convolutions/</link><pubDate>Mon, 22 Feb 2010 12:00:08 +0000</pubDate><guid>https://blog.ezyang.com/2010/02/comonads-and-convolutions/</guid><description>&lt;pre>&lt;code>&amp;gt; {-# LANGUAGE GeneralizedNewtypeDeriving #-}
&amp;gt; import Control.Comonad
&amp;gt; import Data.List
&lt;/code>&lt;/pre>
&lt;p>That scary &lt;code>Control.Comonad&lt;/code> import from &lt;code>category-extras&lt;/code> is going to be the subject of today&amp;rsquo;s post. We&amp;rsquo;re going to look at one possible implementation of comonads for non-empty lists that model causal time-invariant systems, systems whose outputs depend only on inputs that are in the past. We will see that computation in these systems follows a comonadic structure and that one instance of this structure strongly enforces causality and weakly enforces time-invariance.&lt;/p></description></item><item><title>Type manipulation: Tricks of the trade</title><link>https://blog.ezyang.com/2010/02/type-manipulation-tricks-of-the-trade/</link><pubDate>Fri, 19 Feb 2010 12:00:56 +0000</pubDate><guid>https://blog.ezyang.com/2010/02/type-manipulation-tricks-of-the-trade/</guid><description>&lt;p>I present here a few pieces of folklore, well known to those practiced in Haskell, that I&amp;rsquo;ve found to be really useful techniques when analyzing code whose types don&amp;rsquo;t seem to make any sense. We&amp;rsquo;ll build practical techniques for reasoning about types, to be able to derive the type of &lt;code>fmap fmap fmap&lt;/code> by ourselves. Note that you &lt;em>could&lt;/em> just ask GHCI what the type is, but that would spoil the fun! (More seriously, working out the example by hand, just like a good problem set, helps develop intuition for what might be happening.)&lt;/p></description></item><item><title>Why we stay up late</title><link>https://blog.ezyang.com/2010/02/why-mit-students-stay-up-late/</link><pubDate>Wed, 17 Feb 2010 12:00:58 +0000</pubDate><guid>https://blog.ezyang.com/2010/02/why-mit-students-stay-up-late/</guid><description>&lt;p>I was having a discussion a few nights ago about &lt;em>attention&lt;/em>, and someone mentioned the fact that &lt;a href="http://www.paulgraham.com/makersschedule.html">contiguous blocks of time are precious&lt;/a>. It&amp;rsquo;s obvious once it&amp;rsquo;s been pointed out to you, and with it in mind I&amp;rsquo;ve noticed my tendency to bucket useful activities into various categories: checking email, reading news feeds and simple tasks fall into the &amp;ldquo;less than an hour&amp;rdquo; time bucket, while really actually creating software, fixing hard bugs or reading code fall into the &amp;ldquo;more than an hour, preferably several hours&amp;rdquo; time bucket. I&amp;rsquo;ve recognized that attempting to tackle the &amp;ldquo;more than an hour&amp;rdquo; bucket in the snatches of time between classes and extracurriculars is simply wasteful.&lt;/p></description></item><item><title>Hunting for constraints</title><link>https://blog.ezyang.com/2010/02/hunting-for-constraints/</link><pubDate>Mon, 15 Feb 2010 12:00:31 +0000</pubDate><guid>https://blog.ezyang.com/2010/02/hunting-for-constraints/</guid><description>&lt;pre>&lt;code>&amp;gt; import Data.List
&amp;gt; import Control.Monad
&lt;/code>&lt;/pre>
&lt;p>The following question appeared as part of a &lt;a href="http://www.mit.edu/~puzzle/10/puzzles/2010/fun_with_numbers/">numbers-based puzzle&lt;/a> in the &lt;a href="http://www.mit.edu/~puzzle/10/">2010 MIT Mystery Hunt&lt;/a>:&lt;/p>
&lt;blockquote>
&lt;p>His final level on &lt;a href="http://hackage.haskell.org/package/dow">Wizard of Wor&lt;/a> was equal to the smallest number that can be written as the sum of 4 non-zero squares in exactly 9 ways&lt;/p>&lt;/blockquote>
&lt;p>I&amp;rsquo;d like to explore constraint search in Haskell to solve this problem. The hope is to find a (search) program that directly reflects the problem as posed, and also gives us an answer!&lt;/p></description></item><item><title>Scheming environments</title><link>https://blog.ezyang.com/2010/02/scheming-environment/</link><pubDate>Fri, 12 Feb 2010 12:00:59 +0000</pubDate><guid>https://blog.ezyang.com/2010/02/scheming-environment/</guid><description>&lt;p>Environments are &lt;a href="http://www.gnu.org/software/mit-scheme/documentation/mit-scheme-ref/Environment-Operations.html#Environment-Operations">first-class objects in MIT/GNU Scheme&lt;/a>. This is neat, because an integral part of the lexical structure of a Scheme is also a data-structure in its own right, able to encode data and behavior. In fact, the environment data structure is precisely what Yegge calls &lt;a href="http://steve-yegge.blogspot.com/2008/10/universal-design-pattern.html">property lists&lt;/a>, maps that can be linked up with inheritance. So not only is it a data structure, it&amp;rsquo;s a highly general one too.&lt;/p>
&lt;p>Even without the ability to pass around an environment as a first class variable, you can still leverage its syntactic ties to &lt;a href="http://mitpress.mit.edu/sicp/full-text/book/book-Z-H-21.html#%25_sec_3.2.3">stash away local state&lt;/a> in an object-oriented manner. The data is only accessible inside procedures that pointed to the appropriate environment frame, and traditionally the closure returns a lambda (with its double-bubble pointed to the newly born environment frame) that acts as the only interface into the enclosing state. This requires a fair amount of boilerplate, since this lambda has to support every possible operation you might want to do to the innards of the function.&lt;/p></description></item><item><title>Sources of music</title><link>https://blog.ezyang.com/2010/02/sources-of-music/</link><pubDate>Wed, 10 Feb 2010 12:00:18 +0000</pubDate><guid>https://blog.ezyang.com/2010/02/sources-of-music/</guid><description>&lt;p>I &lt;em>love&lt;/em> listening to music, especially new and interesting pieces that I&amp;rsquo;ve never heard before. Unfortunately, being a somewhat frugal spender my own personal collection of music grows very slowly; perhaps a bit too slowly for my own tastes. When I need &lt;em>new&lt;/em> music, where do I turn?&lt;/p>
&lt;ul>
&lt;li>&lt;a href="http://mixapp.com/">MixApp&lt;/a> is a collaborative music listening application. At its worst, it can be simply used as an extension to your current music library; anyone who is your friend and who is online, you can search for music and queue it up for yourself. However, the serendipitous part of MixApp is when you&amp;rsquo;ve dropped into a room of people you don&amp;rsquo;t know and music you don&amp;rsquo;t know, but man, it sounds &lt;em>good&lt;/em> and suddenly you&amp;rsquo;re being taken on a sonic adventure across artists you&amp;rsquo;ve never heard of and a genre you&amp;rsquo;ve just discovered and &lt;em>wham&lt;/em>: you just got MixApp&amp;rsquo;ed. &lt;strong>Update:&lt;/strong> MixApp is dead (the founders went on to build Meteor), though there are replacements popping up like turntable.fm&lt;/li>
&lt;li>&lt;a href="http://www.pandora.com/">Pandora&lt;/a> and &lt;a href="http://www.last.fm/">last.fm&lt;/a> are both pretty reliable methods to get a stream of genre appropriate singles, one after another. The serendipity level is not as nice as MixApp, though, so I don&amp;rsquo;t find myself turning to these much.&lt;/li>
&lt;li>There&amp;rsquo;s not really much that can beat a good radio host. People like David Garland and John Schaefer have such a diverse and deep palette of musical knowledge, and they&amp;rsquo;ve had every evening for who knows how many years to hone the craft of sharing this with the listeners of public radio. I was very pleased when WQXR finally managed to get a high-quality &lt;a href="http://www.wqxr.org/">internet stream&lt;/a> back online.&lt;/li>
&lt;li>I was room-skipping on MixApp one evening, and was caught by the Kleptone&amp;rsquo;s latest album &lt;a href="http://www.kleptones.com/pages/downloads_ud.html">Uptime/Downtime&lt;/a>. I have nothing against mix artists: the whole tradition of music has been founded upon the borrowing, stealing, and building upon of earlier work, and in many cases, an adept mix artist can improve the &amp;ldquo;popular music&amp;rdquo; material it was founded upon. Or sometimes the source material is just really awesome, and should be listened to in its own right: one of the most interesting musical adventures I&amp;rsquo;ve had recently was taking the &lt;a href="http://en.wikipedia.org/wiki/Uptime_/_Downtime">samples list&lt;/a> for Uptime/Downtime and listening to each source piece in turn.&lt;/li>
&lt;li>Orchestra, wind ensemble, small ensemble, or really any type of ensemble, rehearsal, affords time several months to get intimately familiar with a particular piece of music. I would have never have gotten the chance to fully appreciate contemporary works such as Bells for Stokowski or Persichetti&amp;rsquo;s Masquerade for Band without this really in-depth exploration into a piece.&lt;/li>
&lt;/ul>
&lt;p>I should consider myself extremely lucky to be living in an era where new music is constantly at my fingertips. How do you seek out new and interesting music?&lt;/p></description></item><item><title>Nested loops and exceptions (Oleg Kiselyov)</title><link>https://blog.ezyang.com/2010/02/nested-loops-and-exceptions-oleg-kiselyov/</link><pubDate>Mon, 08 Feb 2010 12:00:52 +0000</pubDate><guid>https://blog.ezyang.com/2010/02/nested-loops-and-exceptions-oleg-kiselyov/</guid><description>&lt;p>&lt;em>Editorial.&lt;/em> Today we interrupt our regularly scheduled programming to bring you a guest post by &lt;a href="http://okmij.org/ftp/">Oleg Kiselyov&lt;/a>, reinterpreting our previous post about &lt;a href="http://blog.ezyang.com/2010/02/nested-loops-and-continuation/">nested loops and continuations&lt;/a> with exceptions.&lt;/p>
&lt;hr>
&lt;p>Hello!&lt;/p>
&lt;p>I noticed your recent article about nested loops and continuations. I should have commented on it using the provided form, but I was not sure how formatting would come out. The comment includes a lot of code. Please feel free to post the code in whole or in part, or do anything else with it.&lt;/p></description></item><item><title>Nested loops and continuations</title><link>https://blog.ezyang.com/2010/02/nested-loops-and-continuation/</link><pubDate>Fri, 05 Feb 2010 12:00:43 +0000</pubDate><guid>https://blog.ezyang.com/2010/02/nested-loops-and-continuation/</guid><description>&lt;p>The bread and butter of an imperative programmer is the loop. Coming from a C/assembly perspective, a loop is simply a structured goto which jumps back to a set location if some condition is not met. Frequently, this loop ranges over the elements of some list data structure. In C, you might be doing pointer arithmetic over the elements of an array or following pointers on a linked list until you get &lt;code>NULL&lt;/code>; in Python and other higher-level languages you get the &lt;code>for x in xs&lt;/code> construct which neatly abstracts this functionality. Inside of a loop, you also have access to the flow control operators &lt;code>break&lt;/code> and &lt;code>continue&lt;/code>, which are also highly structured gotos. An even more compact form of loops and nested loops are list comprehensions, which don&amp;rsquo;t permit those flow operators.&lt;/p></description></item><item><title>Classes begin</title><link>https://blog.ezyang.com/2010/02/classes-begin/</link><pubDate>Wed, 03 Feb 2010 12:00:49 +0000</pubDate><guid>https://blog.ezyang.com/2010/02/classes-begin/</guid><description>&lt;p>And so classes begin this Spring Term of 2010. The classes that I am currently signed up to take are:&lt;/p>
&lt;ul>
&lt;li>6.005: Software Construction&lt;/li>
&lt;li>6.02: Intro to EECS II&lt;/li>
&lt;li>6.045: Automata, Computing and Complexity&lt;/li>
&lt;li>6.945: Large-scale Symbolic Systems&lt;/li>
&lt;li>21M.283: Musicals of Stage and Screen&lt;/li>
&lt;/ul>
&lt;p>6.945 is the &amp;ldquo;fun&amp;rdquo; class of the semester; I expect to have to sink a lot of time into and get a lot out of it in return. 6.005 and 6.02 are strictly being taken because my degree requires it (I&amp;rsquo;ve scheduled 6.02 as a conflict class on top of 6.945, so I&amp;rsquo;ll probably have to do a little more legwork to make sure I get all the material for that class.) 6.045 is my mathematical class for the semester; no pure course 18 class for me, unfortunately! And on the advice of Robert Jacobs, 21M.283 is my HASS-ish class (I&amp;rsquo;m quite pleased that I&amp;rsquo;ve gotten the HASS-D requirement out of the way).&lt;/p></description></item><item><title>Cute macro tricks in the kernel</title><link>https://blog.ezyang.com/2010/02/kernel-macro-tricks/</link><pubDate>Mon, 01 Feb 2010 12:00:16 +0000</pubDate><guid>https://blog.ezyang.com/2010/02/kernel-macro-tricks/</guid><description>&lt;p>A classic stylistic tip given to C programmers is that inline functions should be preferred over macros, when possible. This advice stems from the fact that a macro and an inline function can achieve the same effect, but the inline function also gets type checking.&lt;/p>
&lt;p>As it turns out, you &lt;em>can&lt;/em> achieve static type checking with macros, if you&amp;rsquo;re willing to resort to the same cute trick that this following snippet from the Linux kernel uses:&lt;/p></description></item><item><title>Workflows in Git: Single-user style</title><link>https://blog.ezyang.com/2010/01/single-user-git-workflow/</link><pubDate>Fri, 29 Jan 2010 12:00:41 +0000</pubDate><guid>https://blog.ezyang.com/2010/01/single-user-git-workflow/</guid><description>&lt;p>Nelson Elhage wrote a post about &lt;a href="http://blog.nelhage.com/archives/64">Git and usability&lt;/a>, in which he discussed one of the reasons why Git seems to be so confusing to users who have come in straight from a Subversion-style workflow. When discussing this issue offline, one of the things that came up was the fact that, while Subversion imposes a fairly rigid workflow upon its users, Git is flexible enough to do almost any sort of workflow. This is terrible for a user placed in a shop that uses Git: when they go Google for how to use Git, they&amp;rsquo;ll get any multitude of tutorials, each of which is for a &lt;em>different workflow.&lt;/em>&lt;/p></description></item><item><title>Arcadia Rising posters</title><link>https://blog.ezyang.com/2010/01/arcadia-rising-posters/</link><pubDate>Wed, 27 Jan 2010 12:00:08 +0000</pubDate><guid>https://blog.ezyang.com/2010/01/arcadia-rising-posters/</guid><description>&lt;p>As treasurer for the Assassins&amp;rsquo; Guild, I often have to beg and plead GMs to get posters for their respective games, since the UA Finboard has a requirement that, to get funding for events, you need to supply posters.&lt;/p>
&lt;p>So I was quite surprised, amazed and impressed by Lauren Gust&amp;rsquo;s work on posters for Arcadia. The composition is simple, but effective, and definitely adds to the atmosphere of the game. Click for larger versions, and you can get full size PDFs of the posters in &lt;a href="http://web.mit.edu/~lgust/Public/arcadia">Lauren Gust&amp;rsquo;s public&lt;/a>. For a little more background into what the posters are referencing, check out the &lt;a href="http://arcnet.mit.edu/arcadia-scenario.pdf">Arcadia Rising scenario&lt;/a>.&lt;/p></description></item><item><title>To the right! Autocompletable names</title><link>https://blog.ezyang.com/2010/01/to-the-right-autocompletable-names/</link><pubDate>Mon, 25 Jan 2010 12:00:00 +0000</pubDate><guid>https://blog.ezyang.com/2010/01/to-the-right-autocompletable-names/</guid><description>&lt;p>In my younger days, the stylistic convention of MM/DD/YYYY confused me; why on earth would people opt for such an illogical system that placed months, days and years in non-hierarchical order? Surely something on order of YYYY-MM-DD would make far more sense: this format is sortable and, all-in-all, quite logical.&lt;/p>
&lt;p>Eventually, though, I grudgingly accepted that MM/DD/YYYY, trades machine-friendliness for human-friendliness; after all, the year entry rarely changes, and for humans the month and date are the most important pieces of information. Context is usually more than enough to implicity specify what the year is.&lt;/p></description></item><item><title>Hacking git-rerere</title><link>https://blog.ezyang.com/2010/01/hacking-git-rerere/</link><pubDate>Fri, 22 Jan 2010 12:00:31 +0000</pubDate><guid>https://blog.ezyang.com/2010/01/hacking-git-rerere/</guid><description>&lt;p>An unusual workflow for Git, one that &lt;a href="http://scripts.mit.edu/wizard">Wizard&lt;/a> employs extensively, is when a single developer needs to perform merges inside lots of working copies. Normally, a maintainer would pull from the branches he cared about, and offload a large amount of the work to those who were interested in contributing patches. However, Wizard is using Git to provide a service for people who don&amp;rsquo;t know and aren&amp;rsquo;t interested in learning Git, so we need to push updates and merge their software for them.&lt;/p></description></item><item><title>Too many leftovers!</title><link>https://blog.ezyang.com/2010/01/too-many-leftovers/</link><pubDate>Wed, 20 Jan 2010 12:00:02 +0000</pubDate><guid>https://blog.ezyang.com/2010/01/too-many-leftovers/</guid><description>&lt;p>A bad habit in the domain of cooking that I&amp;rsquo;ve picked up from being a starving college student is the propensity to cook all of the ingredients I have on hand. Combine this with the fact that vegetables make a lot of food, the fact that you were planning on feeding 15-20 people (but realistically only fed 10), and that Costco has very &lt;em>large&lt;/em> portions, and you have a recipe for post-Mystery Hunt leftover disaster.&lt;/p></description></item><item><title>Five advanced Git merge techniques</title><link>https://blog.ezyang.com/2010/01/advanced-git-merge/</link><pubDate>Mon, 18 Jan 2010 12:00:17 +0000</pubDate><guid>https://blog.ezyang.com/2010/01/advanced-git-merge/</guid><description>&lt;p>Have you ever performed a merge in Git and not have it quite turn out the way you wanted it to? For example, you accidentally converted all of your UNIX line endings to DOS line endings, and now the entire file reports a conflict? Maybe you see a conflict that you don&amp;rsquo;t really care about resolving, and want to resolve as theirs? Or perhaps the conflicted file is empty and you can&amp;rsquo;t figure out just what happened there?&lt;/p></description></item><item><title>Typeclasses matter</title><link>https://blog.ezyang.com/2010/01/typeclasses-matter/</link><pubDate>Fri, 15 Jan 2010 12:00:46 +0000</pubDate><guid>https://blog.ezyang.com/2010/01/typeclasses-matter/</guid><description>&lt;p>Typeclasses matter. In fact, I&amp;rsquo;ll go as far to say that they have the capacity to &lt;a href="http://www.haskell.org/haskellwiki/OOP_vs_type_classes">replace&lt;/a> what is traditional object-oriented programming. To understand why, however, we have to review the traditionally recognized benefits of object-oriented programming:&lt;/p>
&lt;ul>
&lt;li>&lt;em>Organization.&lt;/em> For C-inspired languages that don&amp;rsquo;t have a module system, this is so incredibly important; without a discipline for organizing code finding the location of any given function is difficult unless you are intimately familiar with the problem domain. With object-oriented programming, all of these aspects are obvious: classes map into obvious filenames, methods go in obvious places, and overall organization is a function of how well the object model is designed, not how well thought out the include files were.&lt;/li>
&lt;li>&lt;em>Encapsulation.&lt;/em> Objects were the first widely utilized method of hiding data and code from clients. Declare something &lt;code>private&lt;/code> or &lt;code>protected&lt;/code>, and you have compile-time guarantees that your clients won&amp;rsquo;t have their grubby fingers all over your innards. Used properly, &lt;em>modularity&lt;/em> follows.&lt;/li>
&lt;li>&lt;em>Polymorphism.&lt;/em> The ability to change behavior based on data is a powerful idea dating back to the days of &lt;code>(void *)&lt;/code>, which can lead to incomprehensible code flow but more often is a more elegant and concise way of writing complicated interactions than a giant &lt;code>switch&lt;/code> statement. These benefits compound in situations that &lt;em>multiple dispatch&lt;/em> is appropriate, and &lt;em>interfaces&lt;/em> can lead to compile-time assurances that a particular class does what it says it does.&lt;/li>
&lt;li>&lt;em>Inheritance.&lt;/em> While a problematic facet of object-oriented programming (especially when manifest as &lt;em>multiple inheritance&lt;/em>), inheritance is still an extremely powerful mechanism of code reuse in object-oriented designs. Subclasses get a default implementation for methods, as well as the ability to break through a level of encapsulation and use &lt;code>protected&lt;/code> methods.&lt;/li>
&lt;/ul>
&lt;p>Typeclasses directly fulfill some of these requirements, while others are achieved due to Haskell&amp;rsquo;s strict types and module system.&lt;/p></description></item><item><title>Sup: Mail for Nerds</title><link>https://blog.ezyang.com/2010/01/sup/</link><pubDate>Wed, 13 Jan 2010 12:00:35 +0000</pubDate><guid>https://blog.ezyang.com/2010/01/sup/</guid><description>&lt;p>&lt;strong>Update (September 1, 2012):&lt;/strong> This post is a bit out of date. I&amp;rsquo;m planning on writing an update, but the main new points are: if you have an SSD, the startup time of Sup is really fast, so you can easily run it on your laptop and you should use the maildir-sync branch, which gives you backwards synchronization of your labels (or my patchset, which is pretty sweet but needs to be polished and published.)&lt;/p></description></item><item><title>First impressions of the VX-8R</title><link>https://blog.ezyang.com/2010/01/vx-8r-review/</link><pubDate>Mon, 11 Jan 2010 23:01:42 +0000</pubDate><guid>https://blog.ezyang.com/2010/01/vx-8r-review/</guid><description>&lt;p>The VX-8R is the first Ham radio I&amp;rsquo;ve ever owned; I have used the VX-7R before, but the extent of my usage of it was someone handing me the radio is &amp;ldquo;Here is the radio preconfigured to the frequencies you&amp;rsquo;ll need; here&amp;rsquo;s how squelch works; here&amp;rsquo;s how to debug common problems; don&amp;rsquo;t fuck it up.&amp;rdquo; Here are my impressions of the VX-8R&lt;/p>
&lt;ul>
&lt;li>Despite the sturdy construction, I am sending it back for warranty replacement. The battery indicator is defective; it is stuck at 100% battery while discharging, and 0% battery when charging. According to a HRO representative, this was highly unusual. Having to send the radio back for replacement is kind of obnoxious, but eh, what can you do.&lt;/li>
&lt;li>The Yaesu tries hard to be non-modal, but when it is it&amp;rsquo;s slightly difficult to tell what keys do what. For example, when scanning, pressing the PTT terminates the scan, but so does BAND and the arrow keys. PTT is actually a fairly reliable method for getting out of FOO mode&lt;/li>
&lt;li>I love the scanning interface. Hold UP/DOWN to initiate scanning, use the dial to nudge it if it gets stock on the wrong thing, whack PTT when you hear something interesting.&lt;/li>
&lt;li>The stereo headphone jack is by far one of the best things about the VX-8R, and partially offsets the suckage of needing two adapters in order to get a split speaker and PTT microphone set. I&amp;rsquo;ve, uh, been listening to a lot of FM radio with my Yaesu (perhaps not the most interesting use, but a use nonetheless!) The stereo plug is contained inside a somewhat appreciable well, so you may have some difficulty getting shorter jacks to plug in soundly.&lt;/li>
&lt;li>On the subject of mods, it appears that despite having been released about a year ago, the VX-8R still has no software mod software available. The &lt;a href="http://www.worldwidedx.com/radio-radio-related-modifications/31824-yaesu-vx-8r-mod-first-internet.html">current hardware mod&lt;/a> only opens up MARS/CAP transmission frequencies.&lt;/li>
&lt;/ul>
&lt;p>Still no word about the microphone dilemma; I might just pony up some cash for a Pryme headset (they&amp;rsquo;re a smidge more expensive than I&amp;rsquo;d like them to be).&lt;/p></description></item><item><title>Why Haskell? The big question</title><link>https://blog.ezyang.com/2010/01/why-haskell/</link><pubDate>Fri, 08 Jan 2010 12:00:03 +0000</pubDate><guid>https://blog.ezyang.com/2010/01/why-haskell/</guid><description>&lt;p>Language selection is a contentious thing, and often a compromise between &amp;ldquo;pick the right language for the job&amp;rdquo; and &amp;ldquo;use as few languages as possible to increase mindshare.&amp;rdquo; Google, for example, &lt;a href="http://steve-yegge.blogspot.com/2007/06/rhino-on-rails.html">limits the programming languages&lt;/a> their employees are allowed to use; and I have come to associate picking whatever language you want for your own projects as irresponsible, having once been told, &amp;ldquo;Yeah&amp;hellip; that project was written in X and no one besides the guy who wrote it knows X&amp;hellip; probably not a good use of your time to work on it.&amp;rdquo; Of course, I&amp;rsquo;ve been quite culpable of this myself; I wrote the member dues tracking system for the Assassins&amp;rsquo; Guild in Haskell, and unless a miracle happens I am kind of doubtful future maintainers will be able to deal with it.&lt;/p></description></item><item><title>rxvt-unicode for gnome-terminal refugees</title><link>https://blog.ezyang.com/2010/01/rxvt-unicode-for-gnome-terminal-refugees/</link><pubDate>Wed, 06 Jan 2010 12:00:24 +0000</pubDate><guid>https://blog.ezyang.com/2010/01/rxvt-unicode-for-gnome-terminal-refugees/</guid><description>&lt;p>When I switched from Ubuntu&amp;rsquo;s default Gnome desktop to the tiling window manager &lt;a href="http://xmonad.org/">Xmonad&lt;/a>, I kept around Gnome Terminal, although with the menu bar and the scroll bars removed. I changed from the default white to a nice shade of #2B2B2B (a hue that &lt;a href="http://sup.rubyforge.org/">Sup&lt;/a> originally introduced me to).&lt;/p>
&lt;p>Over the months, however, I got increasingly annoyed at the slowness at which Gnome Terminal rendered when I switched windows (a not uncommon task in a tiling window manager, made especially important when you have a relatively small screen size); the basic symptom was the screen would flash white as the old terminal left and the new one was being drawn. After testing xterm and finding that it did &lt;em>not&lt;/em> flash when I switched screens, I hereby resolved to find a faster terminal emulator; on the advice of David Benjamin I finally settled on rxvt-unicode, also known as urxvt.&lt;/p></description></item><item><title>Audio connectors and radios</title><link>https://blog.ezyang.com/2010/01/audio-connectors/</link><pubDate>Mon, 04 Jan 2010 12:00:50 +0000</pubDate><guid>https://blog.ezyang.com/2010/01/audio-connectors/</guid><description>&lt;p>Over winter break, I purchased a &lt;a href="http://www.yaesu.com/indexVS.cfm?cmd=DisplayProducts&amp;amp;ProdCatID=111&amp;amp;encProdID=64C913CDBC183621AAA39980149EA8C6">Yaesu VX-8R&lt;/a>, the newest model from Yaesu and the successor to the &lt;a href="http://www.yaesu.com/indexVS.cfm?cmd=DisplayProducts&amp;amp;ProdCatID=111&amp;amp;encProdID=8D3254BFC69FB172D78647DC56EFB0E9&amp;amp;DivisionID=65&amp;amp;isArchived=0">VX-7R&lt;/a>, which is favored by many in the MIT community. Deciding that this was the particular radio I wanted to buy was difficult: purchasing a (cheaper) VX-7R would mean I could tap into the immense pool of knowledge that has already rallied itself around this particular model. But my father was willing to put down the extra $50 for the newer version, and so I decided to be experimental.&lt;/p></description></item><item><title>Adventures in Three Monads</title><link>https://blog.ezyang.com/2010/01/adventures-in-three-monads/</link><pubDate>Fri, 01 Jan 2010 13:16:05 +0000</pubDate><guid>https://blog.ezyang.com/2010/01/adventures-in-three-monads/</guid><description>&lt;p>I&amp;rsquo;ve been busy at work over this winter break working on an article for &lt;a href="http://themonadreader.wordpress.com/">The Monad Reader&lt;/a>, entitled &amp;ldquo;Adventures in Three Monads.&amp;rdquo; The material will overlap the second part of my IAP talk &lt;a href="http://sipb.mit.edu/iap/#haskelltype">Haskell Typeclasses&lt;/a> that I will be delivering under the auspices of SIPB IAP.&lt;/p>
&lt;p>The article itself is a literate Haskell file, and contains sample code I&amp;rsquo;ve cribbed from the various Haskell applications I&amp;rsquo;ve written over my year long flirtations with the language: included is code and explanation for the probabilistic Turing machine I built in order to brute-force a &lt;a href="http://6004.csail.mit.edu/">6.004&lt;/a> assignment. (To the course staff: the code is incomplete enough that it&amp;rsquo;s not equivalent to publishing all of the solutions; intrepid readers will still have to write a search function themselves.)&lt;/p></description></item><item><title>2010: A Roadmap</title><link>https://blog.ezyang.com/2009/12/2010-roadmap/</link><pubDate>Thu, 31 Dec 2009 00:12:36 +0000</pubDate><guid>https://blog.ezyang.com/2009/12/2010-roadmap/</guid><description>&lt;p>I did one of these for 2008, and it was highly amusing to see some of the goals I had put down that, in fact, I do not care at all about in the middle of my sophomore year in college. (For a more technically oriented one, see &amp;ldquo;Get PHP to compile with VS2008&amp;rdquo;&amp;hellip; ick.) They are not quite resolutions, because I know enough that to actually get things done I should set schedules. These are tendencies; guiding principles for the New Year. Things to make habits. Things that are hard.&lt;/p></description></item><item><title>Iron Blogger</title><link>https://blog.ezyang.com/2009/12/iron-blogger/</link><pubDate>Mon, 28 Dec 2009 14:20:54 +0000</pubDate><guid>https://blog.ezyang.com/2009/12/iron-blogger/</guid><description>&lt;p>This social experiment has already hit &lt;a href="http://www.google.com/search?q=iron+blogger">number four Google spot&lt;/a> for &amp;ldquo;Iron Blogger,&amp;rdquo; and there&amp;rsquo;s no reason it shouldn&amp;rsquo;t rise any higher. &lt;a href="http://web.mit.edu/nelhage/www/iron-blogger.html">Iron Blogger&lt;/a> is an experiment in beer (well, not quite for me), blogging, and peer pressure.&lt;/p>
&lt;p>Since we&amp;rsquo;re on the topic of blogging, and why people (including myself) can&amp;rsquo;t seem to do it, we might as well look over the aborted attempts at blogging that I&amp;rsquo;ve had over the years.&lt;/p></description></item><item><title>Archives</title><link>https://blog.ezyang.com/archives/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://blog.ezyang.com/archives/</guid><description/></item></channel></rss>