Erdos Project

Toronto, Canada

Jonathan Lorimer (JonathanLorimer)

Project: Weft
Dates: 2019-08-06 → 2019-08-09

Back at Jonathan's, in a second push attempting to get weft finished. We had a long list of things to do, and we powered through almost all of them. We pulled a few 15 hour days, aggressively programming as hard as we could. Things were looking promising to releasing the library --- just hours before Jon was going to present it at the local Haskell meetup.

But that morning, I'd decided to do a big refactor, using higgledy to magically hide all of our HKD machinery. The approach is actually quite involved: instead of forcing your users to use a type family TypeFam a, you instead wrap it with a newtype newtype ToTypeFam a = ToTypeFam (TypeFam a), and then HKD over that. The result is gross, but it works.

God am I ever excited for unsaturated type families.

Anyway, such a refactor was an exceptionally breaking change. Literally every module we had assumed your code was written in the direct-HKD style. A few extra typeclass instances helped:

Assuming you have class GSomething (rep :: * -> *), with instances for GHC.Generics, we found that if you separate the structural bits (M1, :*:, :+:, eg.) from the interesting pieces (K1), everything becomes much easier. We introduced a second typeclass for the K1 contents, and then implemented the structural bit in terms of it:

This separation allows you to easily inject the higgledy-style HKD logic into a more traditional approach. You need to add two additional cases of GSomethingTerm. The first is:

which expands your type family's instance. The second is:

which ties the recursive knot, connecting the GHC.Generics-based representation of higgledy back into the original generics instances you wrote for the traditional HKD style.

It's crazy, but amazingly, it works. I don't even want to think about how much work we're making the compiler do in Weft.

Enough shop talk. Jonathan also took me to the Toronto Haskell meetup which he organizes. I gave a beginner-level talk about the value of types, stressing Matt Parsons' old adage that if your business logic bugs aren't type errors, you should make them be.

Hamilton, Canada

James King (agentultra)

Project: DataMigration
Dates: 2019-08-05 → 2019-08-06

James and I bonded over a shared uneasiness with data versioning. It's tedious, and hard to do correctly. So we decided to build a data migration library, where you explicitly tag your types via a data family indexed by the version. OK, obvious idea, right? But not quite!

We realized that if you enable -XDuplicateRecordFields, you can use the same field names between different versions. Which means we can now programmatically compute most of the migration details from one type to the next; if the name and the type stay the same, you just want to copy the data between versions. If the type changes, you want to provide a function to map it. If a field gets added, you can hopefully compute it via some projection of the full data structure.

Unfortunately we didn't have enough time to finish everything up, but when I left we were half way through writing a DSL for providing the missing transformation pieces. The idea was to compute a superrecord whose names correspond to the fields you need to fill in, and then put their transformations inside there.

Richmond Hill, Canada

Boris Rozinov (oofp)

Dates: 2019-08-03 → 2019-08-05

Boris has been working on a library for tracking dependent state management of resources over application lifetimes, complete with refinement of the possibilities based on specific filters. It's wicked cool, though performs compiles aggressively slowly. We looked at the performance, and realized the primary problem is that everything is encoded as type-level lists. We thought that maybe having a better type-level data structure would be effective.

So I implemented a plugin that solves a type-level CmpType for ordering types. Such a thing means we can effectively write binary search trees for arbitrary types of kind *, and now get all sorts of great performance improvements. We hunkered down on that, and then on writing BSTs in terms of it. But then I realized most of the work was actually in getting the plugin to solve the type family, and not in comparing types, so we spun out another library for generating plugins.

The result: three libraries. type-sets, cmptype and magic-tyfams; not bad for a weekend of work.

On Boris' project, we found a bug in GHC's TypeError machinery --- it explodes in the wrong place in the presence of partial type signatures. Having tracked that down, we did some work on existentializing his types so the partial ty sigs weren't required. We then thought about how to reduce the boilerplate in his library, and came up with a combination of Servant and HKD for expressing the state transition graph.

Toronto, Canada

Asad Saeeduddin (masaeedu)

Dates: 2019-08-03 → 2019-08-03

Asad and I met on the University of Toronto campus. We were planning on infiltrating a lecture hall, but they were all locked up. He showed me his encoding of all user interfaces via (u -> m ()) -> s -> v, and walked me through how it actually works --- pretty dang cool. We grabbed coffee, and Asad saved me a few hundred bucks per year in AWS costs. He walked me through some of the intuitions behind how lenses work, and it was an excellent time.

Ben Hart (Benjmhart)

Project: Type Tetris
Dates: 2019-08-02 → 2019-08-02

Ben and I met up for dinner, and spent it discussing why Haskell hasn't taken over the world, and what it would need to be in order to do so. We then meandered down to his office, hung out on the roof on a Friday night, and coded up the most type-astronaut version of Tetris we could think of. The board is a Store comonad, with gravity and movement being implemented as extends. A lot of the core implementation got finished, but the game aspect sadly not.

Jonathan Lorimer (JonathanLorimer)

Project: Weft
Dates: 2019-07-15 → 2019-07-18

Weft is a GraphQL implementation for Haskell, based around the idea that Haskell types should be powerful enough to encode everything you need to generate a GQL server. It uses HKDs extensively, to reuse the same data structure from everything from data, IO resolvers, parsed queries, and responses.

Also, Jonathan and Claire took me out to the art museum where we saw totem poles built out of sports bags. We had great philosophical chats (he is a philosopher by training!)

David Rusu (davidrusu)

Project: nimic
Dates: 2019-07-12 → 2019-07-15

Nimic is a tiny macro language, with no built-in syntax or operational semantics. I wrote a little blog post on it.

Together, David and I designed the language, wrote a parser and the macro substitution, and a "compiler." He added the bash primitive, and I worked on the interactive stepper.

Also, David took me out for a pottery class, and to the computer scientists' dinner. We almost managed to burn down his house with an explosive barbecue incident.