3

I tend to use variables a lot to improve readability but when it comes to monad, I came with my own convention to make it clear my variable is wrapped in a (possibly stack of) monad(s)

def getUser(id: Int): Future[User] = ???

val _user1 = getUser(1)
val _user2 = getUser(2)

for {
  user1 <- _user1
  user2 <- _user2
} yield (user1, user2)

some of my colleagues tend to prefer this syntax:

val fUser1 = getUser(1) // makes it clear user is wrapped in a Future

But I believe this could be error prone as :

// getUser now returns an option 
def getUser(id: Int): Option[User]  

val fUser1 = getUser(1) // still compiles but is misleading

// same, if getUser returns a Future[Either[String, User]]
val fUser1 = getUser(1) // fUser1 looks like a Future[User] to me

I think prefixing variables name by _ is the less worst solution but is not ideal either... Do you have a solution for that ?

itsu
  • 222
  • 1
  • 10
  • Overuse/Misuse of anything is not a good idea. `Monad` is no exception. In my opinion, wrapping an `Int` in a `Future` serves no purpose other than adding the heavy cost of `thread-overhead`. If you are just wondering about names then you can follow the scheme of `userFuture1` or `user1Future`. – sarveshseri Dec 19 '17 at 11:07
  • 2
    This is called [Hungarian notation](https://en.wikipedia.org/wiki/Hungarian_notation). – Jesper Dec 19 '17 at 11:10
  • 4
    What about `val user1: Future[User] = getUser(1)` and then make sure it's in a small enough scope that you can always glance and see its type declaration? – Tom Dec 19 '17 at 11:26
  • @Tom so how would you do for comprehension or flatmap ? `for { user1 <- user1 user2 <- user2 } yield (user1, user2)` `user1.flatMap(user1 => ...)` – itsu Dec 19 '17 at 13:10

1 Answers1

3

I think that an underscore prefix to indicate that your value is wrapped is unconventional so unlikely to be helpful to other readers.

Underscore prefixes are commonly used to indicate fields, e.g. in C#, see Naming Conventions in C# - underscores

The use of an "f" prefix for futures is Hungarian Notation and is at least widely understood, if old-fashioned.

I would consider using a suffix, like userFuture if you felt it was necessary to emphasise the type, otherwise I would just use user.

You can also use type annotations to clarify the type, if you feel it is necessary, e.g. val user: Future[User] = getUser(1)

You say:

But I believe this could be error prone as :

// getUser now returns an option 
def getUser(id: Int): Option[User]  

val fUser1 = getUser(1) // still compiles but is misleading

You won't find a naming convention which is enforced by the compiler, so this concern will apply to any naming convention you pick.

Rich
  • 15,048
  • 2
  • 66
  • 119