featherweight go - General

Welcome to the Functional Programming Zulip Chat Archive. You can join the chat here.

Julian KG

There was a pretty interesting addition to the Go generics discussion. I don't know if this is quite FP, but it does involve Philip Wadler, and type systems, so I thought it might interest people here.

the paper:
https://arxiv.org/abs/2005.11710

a talk on it by Philip Wadler:
YouTube - Phil Wadler: Featherweight Go

One interesting result of this design is a unique kind of generic data structures. Because Go does not have ADTs it might seem like you can't ergonomically emulate types like Maybe and List but actually you can in a sort of way with this generics proposal. What you can do is specify an interface, and then implement the constructors as separate types that implement that interface. for example you could have a struct Nil that contains no members, and a struct Cons that contains a member of type a, and a List a where List is an interface. One of the interesting outgrowths of this combined with Go's structural typing is that you define a bunch of types for free. For example I could create another struct that implements list called append, and it contains 2 List a. In Haskell if I have some code that uses lists and I realize I want to do something that uses a lot of appends, and that I should probably switch to a DList, it becomes a bit of a hassle. But in this version of Go it's not a problem.

James King

In the talk he mentions the possibility of Haskell learning something from Go here -- a way out of the nominal structure of type classes would be my guess.

Torsten Schmits

@James King what does "nominal structure" mean?

James King

@Torsten Schmits that two types are equivalent or sub-types of one another by explicit declarations; in contrast to structural where a type that has similar structure can be considered a sub-type or equivalent to another.

James King

I don't recall him spelling it out in the talk but I assume he meant that Go does something useful here that would enable Haskell to shuffle around the type class hierarchy without forcing everyone to update their code.

Torsten Schmits

would that be a new language feature that allows specifying type class relationship with something other than dependency constraints?

Torsten Schmits

or is this about the equivalence of the types that inhabit type classes?

TheMatten

Or maybe class Generics :big_smile:

James King

He wasn't specific -- if you want to know more I recommend watching the talk :smiley:

James King

Or maybe send him an email and let us know what he says.

Torsten Schmits

my question was more about your explanation than what was hinted at in the talk

James King

In that case to your first question, I think that might be what he was hinting at.

James King

Because he was mostly talking about type classes and specifically the change of monad's super classes

James King

And how if we did this change in Haskell we could have avoided forcing everyone to update their code to handle the new hierarchy. Does that make sense?

Torsten Schmits

yes, interesting. thanks!

Asad Saeeduddin

It's not so much a way out of problems caused by typeclasses (although there's that too) but out of the more fundamental problem caused by generative type and data constructors (e.g. in the case of sum types). Every time you create a new data type in Haskell it can't hope to be more closely related to another type than via an explicit isomorphism that pollutes all your other code. In structural typing, types can end up being strictly equivalent

Asad Saeeduddin

e.g. Compose (Const Foo) Bar can actually be precisely Const Foo, you don't need to manage an isomorphism between those two everywhere

Asad Saeeduddin

or lists can actually be precisely the fixpoint of \a r -> Maybe (a, r), instead of only being isomorphic to it

Torsten Schmits

@Asad Saeeduddin what does "generative" mean here?

Asad Saeeduddin
f and g are generative iff f a ~ g b => f ~ g
Asad Saeeduddin

where ~ is equality of types and => is implication

Asad Saeeduddin

in more natural language it means that it is impossible to exactly unify the type constructors introduced by two distinct data/newtype declarations by applying some arguments to each, even though it is very often the case that applying some type arguments to each gives you a pair of isomorphic types

Torsten Schmits

if a and b don't matter for the equality, are they phantoms?

Torsten Schmits

that is, if they don't need to be equal

Torsten Schmits

ah, no, it's a condition, so they do matter

Asad Saeeduddin

Yes, they may or may not be equal. It's simply saying that no possible a and b exist such that f a ~ g b unless f ~ g.