Call for submissions: FARM 2018

I’m the general chair this year for the ACM SIGPLAN International Workshop on Functional Art, Music, Modelling and Design (better known as FARM), which will be colocated with ICFP this September in St. Louis, Missouri, USA. The goal of the workshop is to “gather together people who are harnessing functional techniques in the pursuit of creativity and expression”. For me (and I think for many others as well), FARM, including the associated performance evening, is always one of the highlights of ICFP.

Please consider submitting something! As in previous years, we are accepting a wide range of types of submissions. Paper and demo submissions are due by June 28: you can submit original research, a technology tutorial, a call for collaboration, or propose some sort of live demo. In addition, we also solicit performances to be given during the associated performance evening—performance proposals are due by July 8.

See the website for more info, and let me know if you have any questions!

Advertisements
Posted in meta | Tagged , , , , , , , | 3 Comments

Parametricity for Bifunctor

I’ve begun work to add Bifunctor, Bifoldable, and Bitraversable to the Typeclassopedia. While thinking and writing about Bifunctor I ended up proving some “folklore” results for my own satisfaction, and decided someone might possibly find it useful if I formally record the proofs here.

Bifunctor and its laws

The Bifunctor type class governs types of kind * -> * -> * which are (covariantly) functorial in both type arguments; that is, we can map over the two type arguments independently:

class Bifunctor (p :: * -> * -> *) where
  bimap  :: (a -> b) -> (c -> d) -> p a c -> p b d

  first  :: (a -> b) -> p a c -> p b c
  second :: (b -> c) -> p a b -> p a c

bimap allows mapping over both type arguments simultaneously, for example, bimap toUpper (+1) ('j', 3) = ('J',4). first and second allow mapping over only one or the other. Note that bimap can be implemented in terms of first and second, or first and second in terms of bimap (we’ll see what these implementations are later, or you can work them out as an easy exercise if you haven’t seen them before).

Instances of Bifunctor should satisfy some laws, which are straightforward analogues of the laws for Functor instances:

bimap id id = id                                (IB)
bimap (f . g) (h . i) = bimap f h . bimap g i   (CB)

first id = id                                   (IF)
first (f . g) = first f . first g               (CF)

second id = id                                  (IS)
second (f . g) = second f . second g            (CS)

So far so good. But there is an additional law relating bimap, first, and second:

bimap f g = first f . second g                  (BFS)

When I first read this law, it gave me pause: unlike the other laws, there seems to be some arbitrary asymmetry here. What about the symmetric law BFS2?

bimap f g = second g . first f                  (BFS2)

Intuitively, the order in which we perform first f and second g should not make any difference, since they cannot interact with each other in any way; the a values and b values in an arbitrary p a b structure have to be distinct. That is, intuitively, if (BFS) holds, then (BFS2) should hold as well, and I wondered whether it is possible to formally derive this fact.

Let us note first that if one defines a Bifunctor instance by defining bimap alone, then first and second receive default definitions:

first  f = bimap f id
second g = bimap id g

In this case, assuming that bimap satisfies its composition law (CB), we can see that

  first f . second g
= bimap f id . bimap id g
= bimap (f . id) (id . g)
= bimap f g
= bimap (id . f) (g . id)
= bimap id g . bimap f id
= second g . first f

So when bimap alone is defined and satisfies (CB), both (BFS) and (BFS2) hold automatically. Let’s now consider the situation where first and second are defined, and bimap acquires its default definition of bimap f g = first f . second g (which is just (BFS))—or we can assume that all three of first, second, and bimap are defined, as long as law (BFS) still holds. In this case, can we derive (BFS2) as well?

Parametricity for Bifunctor

We can derive parametricity, aka a free theorem, for any function with the type of bimap. Let p :: * -> * -> * be some two-argument type. In order to even express parametricity for types involving p, we have to assume that p is functorial—that is, we assume the existence of a function

BIMAP :: (a -> b) -> (c -> d) -> p a c -> p b d

satisfying (IB). (As with Functor, (IB) + parametricity is enough to imply that it must satisfy (CB) as well.) We write BIMAP in all caps to indicate that it is some canonical, Platonic function, handed down from on high, inherent to the very essence of p. (Something like that.) Now let us suppose that we mortals have written some function bimap with the same type as BIMAP, which also satisfies (IB). But we don’t make any assumptions about whether our bimap is the same function as BIMAP; we only assume that it has type (a -> b) -> (c -> d) -> p a c -> p b d and satisfies (IB).

We can now take the polymorphic type of bimap and turn the crank to derive a statement of parametricity. I’m assuming some familiarity with this process; for details, see Wadler’s paper. If you don’t care about the details of the derivation, you can just skip to the final statement of parametricity at the end of this section, and then proceed to see how it is applied in the next.

Parametricity for bimap says that if we interpret its type as a relation (according to certain rules), then (bimap, bimap) will be a member of the relation, that is, bimap will be related to itself. Below I show the process of expanding out the definition of the relation corresponding to bimap’s type. (I don’t want to take the time to typeset it really nicely using LaTeX or anything like that; a slightly cleaned-up text version will do for now.) I use @a to denote explicit type application, but after the second step I leave type application implicit to reduce clutter.

(bimap,bimap) ∈ ∀ a b c d. (a -> b) -> (c -> d) -> p a c -> p b d

<=>

∀ Q :: a <-> a', R :: b <-> b', S :: c <-> c', T :: d <-> d'.
  (bimap @a @b @c @d, bimap @a' @b' @c' @d')
    ∈ (Q -> R) -> (S -> T) -> p Q S -> p R T

<=>

∀ Q :: a <-> a', R :: b <-> b', S :: c <-> c', T :: d <-> d'.
  ∀ (g,g') ∈ (Q -> R).
    ∀ (h,h') ∈ (S -> T).
      ∀ (x,x') ∈ p Q S.
        (bimap g h x, bimap g' h' x') ∈ p R T

<=>

∀ Q :: a <-> a', R :: b <-> b', S :: c <-> c', T :: d <-> d'.
  ∀ (g,g'). (∀ (y,y') ∈ Q. (g y, g' y') ∈ R) ->
    ∀ (h,h'). (∀ (z,z') ∈ S. (h z, h' z') ∈ T) ->
      ∀ (x,x') ∈ p Q S.
        (bimap g h x, bimap g' h' x') ∈ p R T

At this point, we don’t need the extra generality afforded by assuming everything is a relation, so we specialize all the relations in sight to functions. For example, the relation Q :: a <-> a' just becomes a function q :: a -> a'; statements of relatedness, such as (y,y') ∈ Q, turn into equations like q y = y'.

∀ q :: a -> a', r :: b -> b', s :: c -> c', t :: d -> d'.
  ∀ (g,g'). (∀ (y,y'). q y = y' -> r (g y) = g' y') ->
    ∀ (h,h'). (∀ (z,z'). s z = z' -> t (h z) = h' z') ->
      ∀ (x,x') ∈ p q s.
        (bimap g h x, bimap g' h' x') ∈ p r t

We now have to interpret p q s and p r t as relations. Wadler’s original paper doesn’t really cover this; it only talks about the specific case of the list functor. However, reading between the lines (and consulting subsequent work on parametricity), we can see that the right way to do this is

(a,b) ∈ p f g <=> BIMAP f g a = b

That is, we interpret the type p as the relation corresponding to its BIMAP function. Hence, we now have

∀ q :: a -> a', r :: b -> b', s :: c -> c', t :: d -> d'.
  ∀ (g,g'). (∀ (y,y'). q y = y' -> r (g y) = g' y') ->
    ∀ (h,h'). (∀ (z,z'). s z = z' -> t (h z) = h' z') ->
      ∀ (x,x'). (BIMAP q s x = x') ->
        BIMAP r t (bimap g h x) = bimap g' h' x'

Finally, we can simplify this by substituting equals for equals in a few places:

∀ q :: a -> a', r :: b -> b', s :: c -> c', t :: d -> d'.
  ∀ (g,g'). (∀ (y,y'). r (g y) = g' (q y)) ->
    ∀ (h,h'). (∀ (z,z'). t (h z) = h' (s z)) ->
      ∀ (x,x').
        BIMAP r t (bimap g h x) = bimap g' h' (BIMAP q s x)       (PAR)

This is the specific statement of parametricity for bimap that we will use to derive the results below.

Uniquness of bimap

Let’s first prove that bimap is unique—that is, anything with the type of bimap must in fact be equal to BIMAP. The name of the game is just to pick appropriate values for all those quantified variables in (PAR). In particular, let’s pick

  • g = h = q = s = id,
  • r = g', and
  • t = h'.

We have some conditions to check:

  • (∀ (y,y'). r (g y) = g' (q y)) under our choices becomes (∀ (y,y'). r (id y) = r (id y)) which is obviously true.
  • Likewise, (∀ (z,z'). t (h z) = h' (s z)) becomes (∀ (z,z'). t (id z) = t (id z)) which is also obviously true.

We then get to conclude that ∀ (x,x'). BIMAP r t (bimap g h x) = bimap g' h' (BIMAP q s x), which is equivalent to

∀ (x,x'). BIMAP r t (bimap g h x) = bimap g' h' (BIMAP q s x)

<=>

BIMAP r t . bimap g h = bimap g' h' . BIMAP q s

<=>

BIMAP r t . bimap id id = bimap r t . BIMAP id id

Since we have assumed that both BIMAP and bimap satisfy the id law, this is equivalent to BIMAP r t = bimap r t, so bimap and BIMAP coincide (r and t were arbitrary).

first and second commute

Finally, let’s prove that first and second commute. We will again use (PAR), but with different choices:

  • g = g' = t = s = id
  • h = h'
  • q = r

Let’s check the conditions:

  • We have to check(∀ (y,y'). r (g y) = g' (q y)), which becomes (∀ (y,y'). r (id y) = id (r y)), which is true since both sides reduce to r y.
  • Likewise, (∀ (z,z'). t (h z) = h' (s z)) becomes (∀ (z,z'). id (h z) = h (id z)) which is true by similar reasoning.

Hence, we may conclude that BIMAP r t (bimap g h x) = bimap g' h' (BIMAP q s x), which is equivalent to

BIMAP r id . bimap id h = bimap id h . BIMAP r id

We can simplify this further using a few assumptions: first, we already showed that BIMAP = bimap. Second, since we are assuming (BFS), that is, bimap f g = first f . second g, setting f or g to id shows that bimap f id = first f . second id = first f . id = first f (by the id law for second), and likewise bimap id g = second g. Hence the equation becomes

first r . second h = second h . first r

And voila!

One can also show that the id laws plus parametricity together imply the composition laws—I will leave that as an exercise. (Hint: make appropriate choices for g', h', q, and s.)

Posted in haskell, math | Tagged , , , , , | 3 Comments

Beeminder guest post on Beeminding All The Things

I’ve written about my use of Beeminder a few times here before. I just wrote a guest post for the Beeminder blog entitled Beeminding All The Things, in which I explain some lessons learned and best practices for dealing with a very large number of Beeminder goals (50, in my case)—and why you might even consider having so many in the first place. If thinking about tools for productivity is your cup of tea, you might be interested to check it out.

Posted in meta | Tagged , , | 1 Comment

Test your intuition: logarithmic time

Here is a question to test your intuition for logarithms. NO CALCULATORS allowed, and don’t take a long time to work out an answer in your head! Just go with your gut. After you have committed to a choice (say, by writing it down), then go get a calculator and a pencil and see if you can work out whether you were right!

On a certain input, an O(n) algorithm runs in one-tenth of a second. On the same input, an O(n^2) algorithm takes one and a half weeks to run. Approximately how long would an O(n \log n) algorithm take on the same input?

  1. a few seconds?
  2. a few minutes?
  3. a few hours?
  4. a few days?

I’m pretty sure it wasn’t until quite a few years out of undergrad that I would have gotten this right.

Posted in teaching | Tagged , , , | 16 Comments

Visiting assistant professor position at Hendrix

My department at Hendrix College is hiring a 1-year visitor in CS for next year. This is my third year at Hendrix and I really love it—the department is friendly and supportive, the administration really cares about faculty and students, and the students, on the whole, are motivated, bright, and enthusiastic. The position is a sabbatical replacement, so there’s no possibility of it turning into something longer than a year; nonetheless, it is a great opportunity for someone interested in pursuing a position at a liberal arts institution who wants to gain more teaching experience (something that is an absolute must for a liberal arts job but can be hard to come by in grad school). I think my department does a great job of supporting one another and helping each other grow as teachers, so it wouldn’t just be something to put on your CV, but a real opportunity to become a better teacher. And Conway, Arkansas is a wonderful place to live—despite what certain prejudices may lead you to believe!

The initial application deadline is soon (February 28)—I forgot to post something about it earlier!—but we’ll continue to accept applications until the position is filled, so don’t hesitate to apply even if you end up missing the deadline by a bit. And of course feel free to contact me with any questions.

Here’s a link to the application.

Posted in meta | Tagged , , , | Leave a comment

A (work in progress) translation of Joyal’s original paper on species

tl;dr: I’m working on an English translation, with additional commentary, of Joyal’s 1981 paper introducing the concept of combinatorial species. Collaboration and feedback welcome!


Back when I was writing my PhD thesis on combinatorial species, I was aware that André Joyal’s original papers introducing combinatorial species are written in French, which I don’t read. I figured this was no big deal, since there is plenty of secondary literature on species in English (most notably Bergeron et al., which, though originally written in French, has been translated into English by Margaret Readdy). But at some point I asked a question on MathOverflow to which I hadn’t been able to find an answer, and was told that the answer was already in one of Joyal’s original papers!

So I set out to try to read Joyal’s original papers in French (there are two in particular: Une théorie combinatoire des séries formelles, and Foncteurs analytiques et espèces de structures), and found out that it was actually possible since (a) they are mathematics papers, not high literature; (b) I already understand a lot of the mathematics; and (c) these days, there are many easily accessible digital tools to help with the task of translation.

However, although it was possible for me to read them, it was still hard work, and for someone without my background in combinatorics it would be very tough going—which is a shame since the papers are really very beautiful. So I decided to do something to help make the papers and their ideas more widely accessible. In particular, I’m making an English translation of the papers1—or at least of the first one, for now—interspersed with my own commentary to fill in more background, give additional examples, make connections to computation and type theory, or offer additional perspective. I hope it will be valuable to those in the English-speaking mathematics and computer science communities who want to learn more about species or gain more appreciation for a beautiful piece of mathematical history.

This is a long-term project, and not a high priority at the moment; I plan to work on it slowly but steadily. I’ve only worked on the first paper so far, and I’m at least far enough along that I’m not completely embarrassed to publicize it (but not much more than that). I decided to publicize my effort now, instead of waiting until I’m done, for several reasons: first, it may be a very long time before I’m really “done”, and some people may find it helpful or interesting before it gets to that point. Second, I would welcome collaboration, whether in the form of help with the translation itself, editing or extending the commentary, or simply offering feedback on early drafts or fixing typos. You can find an automatically updated PDF with the latest draft here, and the github repo is here. There are also simple instructions for compiling the paper yourself (using stack) should you want to do that.


  1. And yes, I checked carefully, and this is explicitly allowed by the copyright holder (Elsevier) as long as I put certain notices on the first page.

Posted in combinatorics, projects, species, writing | Tagged , , , , , , | 5 Comments

Off the Beaten Track: Explaining Type Errors

Last week I gave a talk at Off the Beaten Track 2018 about something that Richard Eisenberg, Harley Eades and I have been thinking about recently: namely, how to generate good interactive error explanations for programmers, especially for type errors. None of the talks at OBT were recorded, but I’ve prepared a version of my slides interspersed with (something like) a transcript of what I said.

Posted in projects, writing | Tagged , , , , , , , , | 2 Comments