Vancouver, Canada

Andrew McKnight (amcknight)

Project: GHC
Dates: 2019-09-07 → 2019-09-09

Andrew has some loft goals about getting AIs to optimize bad algorithms into good ones; in other words, you write a brute force algorithm and it some how "massages" it into something that runs fast. That seemed hard, so we instead decided to focus on GHC's simplifier, which performs similar transformations on Haskell code. We figured getting familiar with it might be helpful for Andrew's longer term goals.

We took up Reed and my idea to Scott encode the simplifier --- which should theoretically improve compiler performance by 20%+. After a few hours of prototyping Scott-encoded things to ensure we understood how they worked and why, we jumped into GHC and got going. In our first afternoon we got half of the work done, and spent the rest of the evening talking about huge world-scale projects we could tackle, and what modern super-powers would look like.

The next day we wandered around town for a bit, and then got back to business. After getting stuck in a quagmire of biting off too much for one commit, we undid some work and were more careful moving forwards. A lot of GHC's simplifier is written with explicit recursion, but contains lots of ugly fall-through logic in its pattern matching of such. It's a mess, and desugaring that into something that can take advantage of the Scott encoding is finicky and easy to get wrong. Would that GHC took advantage of good Haskell design principles, but alas it does not.

All in all, 10/10 visit. Would recommend, and would definitely return!

Reed Mullanix (TOTBWF)

Project: Refinery
Dates: 2019-08-24 → 2019-08-27

(dates are approximate, I actually spent this week staying with Travis Willis, but Travis and I didn't do any Haskell)

As the only known user of Reed's library refinery, I sat him down and had him explain most of the machinery to me. We spent several hours debugging his new Scott-encoded v2, eventually figuring it out, and teaching me lots about Scott-encoding in the process.

On our second encounter, Reed and I attempted to determine whether or not the polynomial interpretation of monads via Curry-Howard have any interesting number-theory properties. Neither of our category theory was sufficient to come up with any satisfactory answers, but it seems like a pretty interesting line of inquiry.

We then looked at my Dyna editor, working through the semantics of what structural editing should look like. We then spent some time diving into GHC's simplifier, trying to figure out why it's so dang slow (one function is singlehandedly responsible for 20% of compile times.) We're pretty sure that a Scott-encoding of the SimplCont type would be sufficient to kick off wicked savings, but it seems like a nightmare to actually make happen.

Saskatoon, Canada

Chris Penner (ChrisPenner)

Dates: 2019-08-16 → 2019-08-24

Literally the first thing we did, Chris Penner sat me down and ran me through optics. "They're just traverse in different pants," he said. A few hours later, I felt like I had a pretty good grasp on the whole idea.

We found it a little hard to find things to collaborate on; Chris' big project these days is his Lens book, which is obviously not something I can contribute much to. But we had an excellent time hanging out, chatting about the ecosystem, and how to fix the problems in the community.

Also, Chris is an amazing musician. We broke into the music store and had a few jam sessions. I came away feeling inspired by the things he taught me on piano, and I can't wait to get my hands on one again to give the new ideas a go.

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.