Cats: Type class instance naming conventions

Created on 25 Apr 2015  路  10Comments  路  Source: typelevel/cats

Currently Cats is using capital letters for type class instance parameter names, such as this:

def map[B](f: A => B)(implicit F: Functor[F]): F[B]

It may be worth noting that this same convention is used by Scalaz.

This convention is fairly straightforward once you are used to it, and it is very concise. However, both @stew and I have seen people struggle with confusion with this convention.

I believe this confusion tends to stem from the fact that parameter names are typically not capitalized in Scala, and they are either thrown off by F being both a value and a type, or they don't realize that it is a value in addition to a type within the method.

Since one of the goals of Cats is to be approachable and fairly beginner-friendly, I'm wondering if we should adopt a new convention for type class instance parameter names.

What do people think of something like this?

def map[B](f: A => B)(implicit functorF: Functor[F]): F[B]

It adds a bit of verbosity. However, I think that to many people it may convey its meaning more clearly.

meta question

Most helpful comment

We've spent 5 years building learning materials and precedent around this convention, which I think only raises the bar to a change that didn't gather critical mass 5 years ago. I like questioning our old decisions, but I think at this point, a change here is as likely to confuse as to assist.

All 10 comments

See also this gitter conversation in which @propensive weighs in with some thoughts.

Hmm. My gut reaction to functorF is pretty negative. I think there are two things I don't like:

  1. I worry that repeating the word _functor_ makes things more obscure in a certain way.
  2. I find the name to be a bit ugly.

A great question is what alternative would I propose? I don't have a clear answer yet.

If everyone else wants to move to functorF-style parameters I won't stand in the way. But I am holding out hope that we can come up with something better.

One question for @ceedubs and @stew:

Are people confused by seeing params like F and G used? Or is just the existence of the parameter that is confusing?

If it is the former, then trying to make it easier to avoid needing to reference the implicit params would be useful (and we could move to context bounds in many-but-not-all cases). If the latter, then trying to move to context bounds might help, but we still need to solve the underlying problem.

that we are using F to mean one thing in contexts and another in value contexts.

I see. So it mirrors (but is possibly worse than) the confusion between a type Foo and its companion object Foo.

In defense of the status quo, it simplifies refactoring whenever a context bound is found to be too strict or too lax. I'm open to change here, but functorF has a faint odor of Hungarian notation.

A problem with the A-convention is that it doesn't scale:

def foo[A](implicit ev0: Foo[A], ev1: Bar[A]) = ...

Can't be written using A for both parameters. In these cases I have punted and used F and B, but now I'm thinking maybe a middle ground like evF and evB would work. Lowercase makes the identifiers less jarring to see in term position, but they're still weird enough that you understand they're somehow distinct from normal parameters.

I'm really not a fan of Scalaz's single upper case term name convention.

In @tpolecat's example I would most likely use fooA and barA or possibly abbreviate to fA and bA. In the case of functors I would most likely abbreviate functorT to fT.

@ceedubs @tpolecat

Doing some issue archeology. Considering that the F-convention has scaped to other libraries (such as cats-effect or http4s), and that there is even a compiler plugin for generating that F name... Is this something you stil are interested to push?

We've spent 5 years building learning materials and precedent around this convention, which I think only raises the bar to a change that didn't gather critical mass 5 years ago. I like questioning our old decisions, but I think at this point, a change here is as likely to confuse as to assist.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

LukaJCB picture LukaJCB  路  4Comments

fosskers picture fosskers  路  3Comments

diesalbla picture diesalbla  路  4Comments

julien-truffaut picture julien-truffaut  路  3Comments

LukaJCB picture LukaJCB  路  3Comments