Collecting attributes

October 28, 2009

I’m proceeding with the redesign of my diagrams library slowly but surely. I don’t have a lot of time to work on it, hence the “slowly”. But progress is being made. It’s still very much in the design phase, which makes it difficult for others to help, but Lennart has created a diagrams page on the Haskell wiki which I hope can be a good way to have an open design process and get input from the community. There’s a lot of stuff I have written down that I haven’t gotten around to putting on that page yet, but I hope to do that soon.

Occasionally I plan to write some blog posts about interesting issues that arise in the design; today is the first.

Here’s the background: a diagram is essentially a tree of sub-diagrams (although there will be a principled way to refer to subdiagrams in other parts of the tree; more on this in a future post), with leaves corresponding to atomic primitives. Every node in the tree can (optionally) have some associated style attributes, such as stroke width and color, fill color, font, and other such things. When we encounter a primitive at a leaf, how do we know what attributes to use when rendering it? It may have some associated attributes, but its parent node might also have some associated attributes, and other ancestor nodes higher up the tree might have attributes as well.

What we’d really like to do is have a Style data type which has a Monoid instance:

data Style = Style { strokeWidth :: Double
                   , strokeColour :: Colour
                   ... }

instance Monoid Style where
  ...

Then to determine the style to use for a leaf, we just combine the styles of all its ancestors using the monoid.

So, how to implement this Monoid instance? Well, first of all, what I wrote above is slightly bogus; at the very least each particular attribute ought to be optional, so it should look something more like this:

data Style = Style { strokeWidth :: Maybe Double
                   , strokeColour :: Maybe Colour
                   ... }

To combine two Style records, we match them up field-by-field, and Just trumps Nothing.

So far, so good. But how do we combine two fields containing Just? It seems we have two choices: we can be biased towards the top of the tree (i.e. parent attributes override child attributes) or towards the bottom (i.e. child attributes override parent attributes). Indeed, Data.Monoid contains two newtypes, First and Last, whose Monoid instances exhibit exactly this behavior.

But here’s the problem: in this application, one of these choices isn’t obviously better than the other. In fact, it’s easy to imagine situations where each would be the desired behavior. For example, imagine that we have created a subdiagram that we want to use many times throughout a larger diagram. Most of the time it will be blue, so it makes sense to specify that attribute as part of the subdiagram itself. However, in one place we want it to be red, so we’d like to be able to override its attributes with parent attributes. On the other hand, imagine a situation where a diagram is going to be composed of many different subdiagrams, which all share the property that they are blue. To avoid repeating ourselves, it makes sense to specify “blueness” as an attribute of the parent diagram and have all the subdiagrams inherit it. However, one subdiagram should be red, so we’d like to be able to override the parent attribute in this particular child.

What to do? A first cut might look something like this:

data Override a = Default | OverrideUp a | OverrideDown a

data Style = Style { strokeWidth :: Override Double
                   , strokeColour :: Override Colour
                   ... }

The intention is that OverrideUp a overrides any attributes above/before it, and OverrideDown a overrides any attributes below/after it. However, there’s a problem: what should

(OverrideDown a) `mappend` (OverrideUp b)

be? The OverrideDown a claims to override the OverrideUp b… and vice versa! So this doesn’t really work. We need a way to specify relative priorities. So, another solution would just be to assign each attribute with a priority:

data Prioritized a = Default | Priority Double a

data Style = Style { strokeWidth :: Prioritized Double
                   , strokeColour :: Prioritized Colour
                   ... }

For the Monoid instance, we just take the value with maximum priority. This allows us to do what we wanted—overriding parent or child attributes is done simply by assigning a higher priority. However, I really dislike this solution. Having to specify a priority is annoying—but not only that, figuring out what priority to use to achieve your desired effect requires global knowledge about the value of the priorities used elsewhere. One improvement we could make is to adopt the solution used by CSS: attributes are leaf-biased by default, but assigning a priority can override this. That is,

data Prioritized a = Default | Priority (Maybe Double) a

where the Monoid instance chooses the value with the highest priority, or the right/leaf-most value if no priorities are specified. This might be the best option—but it’s still somewhat unsatisfactory.

I wonder about a solution that allows you to say, “I want to override the attribute on THAT node”—where “THAT” represents some way to refer to a particular node by name (what these names look like will be the subject of another post). This might solve the problem of arbitrariness with the numerical priorities, but might also be veering into the realm of the overengineered…


Typeclassopedia in Japanese!

October 20, 2009

Satoshi Nakamura has published a Japanese translation of the Typeclassopedia. I don’t read any Japanese, but it sure looks cool, and I hope this will be a great resource for Japanese learners of Haskell. A big thank you to Satoshi for his hard work; the Typeclassopedia is certainly not short!


Call for submissions: Monad.Reader issue 15

October 12, 2009

I’m excited to be taking over the editorship of the Monad.Reader. I’ll be putting together Issue 15 in January—the deadline for submissions will be January 8, 2010. Please consider writing something! You don’t need to be an expert; past articles have included things like tutorials, book reviews, new ideas, beginner perspectives, illustrations of nifty code, explanations of a new library or piece of software… Collaboration is encouraged, too. Have a great idea for an article but not sure you could pull it off for one reason or another? Send an email to haskell-cafe@haskell.org asking for a coauthor. Writing an article is a great way to learn and to create a high-quality resource for others learning FP.

If you plan to write something—or are considering it—let me know. Submission guidelines can be found on the Monad.Reader website.


diagrams 0.2.1, and future plans

September 24, 2009

First of all, I’ve just released version 0.2.1 of the Haskell diagrams library. This is a minor release which fixes a few bugs and adds a few new combinators, most notably a grid layout combinator contributed by Ganesh Sittampalam. For more information and a full list of the features new to 0.2.1, see the diagrams web page.

The real reason for the release, however, is to get existing new features out the door before gearing up for a planned major rewrite of the backend to use a constraint-solving layout engine. This will allow for much greater elegance and flexibility, as well as a number of features (such as arrows connecting different parts of the diagram) which would be difficult or impossible to implement in the current framework.

My ultimate vision is for the diagrams library to become a viable alternative to declarative drawing systems such as MetaPost and Asymptote, with the distinct advantages that it will be

  • purely declarative, and
  • an embedded DSL, providing the full power of Haskell and its ecosystem, as opposed to the ad-hoc specialized languages used by MetaPost and Asymptote.

If this sounds exciting to you, I hope you’ll join me, either by trying out diagrams for your projects and providing feedback, or by contributing some code. If you’re interested in helping with the rewrite itself, let me know; I also plan to set up a core/contrib model like that of xmonad, so there should also be plenty of opportunities for contributing independent add-on modules which enhance the core functionality.


Functional MetaPost

September 21, 2009

I just spent a very frustrating hour trying to get the functional MetaPost library (a Haskell DSL for generating MetaPost) working. It installs (via cabal-install) without a hitch, but I haven’t been able to get it to actually work. I can write a test program which imports the FMP module, and compile it, but then when I try to run it, it spews out a gazillion .log, .tmp, .mpx, .aux… files and a nasty-looking series of error messages (including a segfault). I’m happy to provide more details if anyone thinks they would actually be able to help…

All the more motivation to get back to a rewrite of my diagrams library


Edinburgh

August 26, 2009

I’m having a great time in Edinburgh so far! I’m currently at Heriot-Watt University for the International Summer School on Advances in Programming Languages, learning some interesting things but more importantly meeting interesting people. I’m also looking forward to meeting yet more interesting people at Hac7 and at ICFP (if you’re reading this and plan to be at either, then you are one of them).

Here are a few pictures I took while sight-seeing on my first day; some pictures of the summer school itself will follow soon.


New 2D text layout library

August 14, 2009

I’ve just uploaded to Hackage a small library, boxes, for 2D text layout/pretty-printing. This is something I’ve wanted a couple times and have heard others ask for—Text.PrettyPrint.HughesPJ, as nice as it is, is intended for pretty-printing only linear output (such as source code), and is ill-suited for layout of a two-dimensional nature, such as columns of text, proof trees, and the like.

I wrote this library almost a year ago and have been sitting on it ever since, and finally decided that I really ought to just release what I have so others can make use of it. It’s quite usable as it is, and has (I hope) solid documentation. There’s nothing in the way of examples or tutorials or QuickCheck properties, and there are many more features one could imagine adding to it, but it’s simply not a priority for me right now, so it is what it is. However, if anyone is interested in taking over as maintainer and extending it, be my guest! Just fork off a new darcs repo and hack away.


Going on vacation

August 9, 2009

Later today I’m leaving for a two-week vacation, and I will probably have only very occasional Internet access. If at any point over the next two weeks you wonder why I {didn’t moderate your comment, didn’t put out the Haskell Weekly News, am not on IRC, am ignoring your email}, you should remember this.

I’ll continue writing more about my combinatorial species library when I get back—including recursively defined species, which I’m working on at the moment.


Species operations: differentiation

August 5, 2009

Continuing my series describing my new combinatorial species library, today we’ll take a look at the operation of differentiation.

You may remember that the Species type class has an Algebra.Differential constraint, which, as I previously explained, transitively implies an Algebra.Ring constraint. But we haven’t yet talked about the Differential contraint itself, which requires a method differentiate :: Species s => s -> s (which I will abbreviate using the standard “prime” notation), which should satisfy

(x * y)' \equiv x' * y + x * y'

(up to isomorphism). Okay, this is just the normal product rule for differentiation, from calculus—but what on earth could such a thing mean combinatorially?

There is actually a nice, simple answer: an F'-structure on the underlying set U consists of an F-structure on U \cup \{*\}, where * is a distinguished element distinct from all the elements of U. To make the connection to data type differentiation, we can also think of * as a “hole”.

Species differentiation

Species differentiation

The above diagram illustrates the situation: an F'-structure on \{1,2,3,4,5\} is an F-structure on \{1,2,3,4,5,*\}.

And how about the law (F * G)' \equiv F' * G + F * G'? Does this make combinatorial sense? (You may want to stop and think about it before reading on!)

By definition, an (F * G)'-structure on U is an (F*G)-structure on U \cup \{*\}, which is a pair of an F-structure and a G-structure on a splitting (a two-partition) of U \cup \{*\}. The distinguished * label must end up on one side or the other, so an (F*G)'-structure can arise in one of two ways: it is either an F'-structure paired with a G-structure, or an F-structure paired with a G'-structure, depending on where the * ends up. But this is precisely saying that (F * G)' \equiv F' * G + F * G'!

Where does species differentiation show up? The most well-known place is in defining the species L of lists (linear orderings). In fact,

L = C',

that is, the species L is the derivative of the species C of cycles. A cycle defines an ordering, but there is no distinguished beginning or end; by making a cycle out of some elements with a distinguished extra element *, we uniquely identify a beginning/end of the ordering on the original elements: a list!

Differentiating a cycle to get a list

Differentiating a cycle to get a list


> take 10 . labelled $ lists
[1,1,2,6,24,120,720,5040,40320,362880]
> take 10 . labelled $ oneHole cycles
[1,1,2,6,24,120,720,5040,40320,362880]
> generate lists ([1..3] :: [Int])
[[1,2,3],[1,3,2],[2,1,3],[2,3,1],[3,1,2],[3,2,1]]
> generate (oneHole cycles) ([1..3] :: [Int])
[<*,1,2,3>,<*,1,3,2>,<*,2,1,3>,<*,2,3,1>,<*,3,1,2>,<*,3,2,1>]

Here’s an example of differentiation in action. In the species library, the function oneHole is provided as a synonym for differentiate. The session above shows that there are the same number of labelled lists as labelled one-hole cycles: this isn’t surprising given the discussion above, and in fact, list is actually implemented as oneHole cycle. Actually, this is a tiny lie, as the rest of the session shows: since lists are such a common combinatorial structure, there is a special case for them in the generation code. But we can explicitly generate one-hole cycles as above; it’s easy to see that they are in one-to-one correspondence with the lists.

To finish off this post, a few exercises for you (you can check your answers with the species library):

  1. Describe the species 1'.
  2. Describe the species X'.
  3. Describe the species E'.
  4. Does differentiation distribute over addition? That is, is it true that (F + G)' \equiv F' + G' for any species F and G? Give a combinatorial interpretation of this identity, or say why it does not hold.
  5. Describe the species L'.
  6. Describe the species C^{(n)} (i.e. the nth derivative of the species of cycles).

Primitive species and species operations, part II

July 31, 2009

In my previous post, I began describing the primitive species and species operations supported by my combinatorial species library; we looked at the ring structure on species, that is, the primitive species 0 and 1, and the operations of species sum and product. Today we’ll continue by looking at a few more primitive species: singletons, sets, and cycles.

[By the way, all the diagrams for this post and the previous one were generated programmatically using my diagrams library. I'll probably put the code up as an example on the diagrams website sometime in the near future.]

X

The species X, also known as the species of singletons, is picky in a way similar to the species 1. Whereas 1 only puts a structure on the empty set of labels, X only puts a (single) structure on singleton label sets. If you give it more than one label, or none, it turns up its nose and refuses to do anything.

The species X of singletons

The species X of singletons


> take 10 $ labelled singleton
[0,1,0,0,0,0,0,0,0,0]
> generate singleton (['a'] :: [Char])
['a']
> generate singleton ("abc" :: [Char])
[]

A few exercises: try to work them out yourself, then use the species library to check if you are correct!

  1. Describe the species X + X. Show that it is isomorphic to the species 2 * X.
  2. Describe the species X * X.

E

The species E of sets, on the other hand, isn’t picky at all: it will happily put a singleton structure on any label set. Usually we identify this structure with the label set itself; that is, the only E-structure on a label set U is U itself.

The species E of sets

The species E of sets


> take 10 $ labelled sets
[1,1,1,1,1,1,1,1,1,1]
> take 10 $ unlabelled sets
[1,1,1,1,1,1,1,1,1,1]
> generate set ([1..3] :: [Int])
[{1,2,3}]
> generate set ([] :: [Int])
[{}]

We can now also describe the derived species X * E of elements, also known as the species of pointed sets. The only way to get any X * E structures is by partitioning the label set U into a singleton and all the rest, in which case we get exactly one structure; so there is one X * E structure for each element of U.


> take 10 $ labelled (x * set)
[0,1,2,3,4,5,6,7,8,9]
> take 10 $ unlabelled (x * set)
[0,1,1,1,1,1,1,1,1,1]
> generate (x * set) ([1..3] :: [Int])
[(1,{2,3}),(2,{1,3}),(3,{1,2})]

(x is just a synonym for singleton.) Noteworthy is the fact that this is the first species we’ve looked at which has different numbers of labelled and unlabelled structures! This makes sense: there are n labelled (X * E)-structures on a size n set; but if we can’t tell the difference between the labels, any one of them is just as good as any other, so we only get one unlabelled structure (unless the label set is empty, when we don’t get any structures: the X still requires us to have at least one element!). Note also that element is a special synonym for x * set with a special semantics under generate: if we really want to pick elements of the label set, then we probably don’t want to actually see each element paired with a set of the leftover elements, we just want to see the element itself:


> generate elements ([1..3]::[Int])
[1,2,3]

C

The final primitive species—and the only one so far that doesn’t feel quite so utterly trivial—is the species C of cycles. C puts no structures on an empty label set, but given any non-empty label set, C generates the set of all cyclical orderings of the labels.

The species C of cycles

The species C of cycles

Of course, the above diagram only shows six of the cycle structures on five labels; the ellipsis is meant to suggest the others not shown. So… how many labelled cycle structures are there on five labels, or generally on n labels? (Of course there is only one unlabelled n-cycle.) I’ll leave it as a (hopefully easy) exercise; and of course you know how to check your answer!


> generate cycles ([1..4] :: [Int])
[<1,2,3,4>,<1,2,4,3>,<1,3,2,4>,<1,3,4,2>,<1,4,2,3>,<1,4,3,2>]

As you can see, cycles are indicated with angle brackets; it is understood that <1,2,3,4>, <2,3,4,1>, <3,4,1,2>, and <4,1,2,3> are all equivalent.

At this point, you’re probably thinking about a certain species and wondering why I haven’t mentioned it yet—it seems pretty fundamental and primitive. Are you thinking of… the species of lists? It turns out that we don’t have to take lists as primitive—we can define the species of lists as the derivative of the species of cycles! The derivative of a regular type is its type of one-hole… but I’m getting ahead of myself. We’ll look at species differentiation (along with several other operations on species) in the next post!