5

Okay, I guess question is already complete in the title. Nothing big, but I am just wondering. I have a method which returns either a correct value or an error code enum item. For example something like this:

def doMyStuff(): Future[_] = {
    val result = db.queryMyData().map {
        case some(data) =>
            val modifiedData = data.doStuff()
            modifiedData
        case None =>
            Errors.THIS_IS_FALSE
    }
    result
}

Where db.queryMyData() returns a Future, and data.doStuff() just modifies the data.

Now I have intuitively written Future[_], cause the return value is flexible. But when looking in other libraries I've seen Future[Any] used. Which seems to be logic too, when you use a match-case on the return of the function to check which data it is.

The code which uses that is for example something like this:

doMyStuff().map {
    case data: MyDataType => // Blah blah
    case Errors.Value => // error handling
}

So, my questions is: What's the difference between the use of Any or _ here, and why should I use the correct one?

Wolfsblvt
  • 1,061
  • 12
  • 27
  • I'm thinking of closing this in favor of it being a duplicate of: http://stackoverflow.com/questions/15186520/scala-any-vs-underscore-in-generics. I have the golden hammer, so I wanted to get others feedback before marking this as a duplicate and thus closing it. – cmbaxter Jan 22 '16 at 13:05
  • I just would like to advice to use `Either[Error, Data]` instead of `Any` – Łukasz Jan 22 '16 at 13:07
  • @Łukasz: Either would be working if it's just two possible return types like in that example. And Either looks less *clean* and readable for me, especially with that `case Left(blah)` stuff in the match. Or what would the real advantage be when using `Either`? – Wolfsblvt Jan 22 '16 at 13:16
  • @cmbaxter That's a very complicated question/answer there and I don't feel like it answers my question. But maybe I just don't understand that stuff there. It doesn't answer what to prefer to use in my case, does it? – Wolfsblvt Jan 22 '16 at 13:17
  • 1
    @cmbaxter I wouldn't; that's a more complicated case. There is a much closer case http://stackoverflow.com/questions/28866944/scala-set-vs-setany, though `Set` isn't covariant. – Alexey Romanov Jan 22 '16 at 13:49
  • @AlexeyRomanov, am I wrong in thinking that because `Future` is covariant then as Regis Jean-Giles pointed out the use of `_` vs `Any` doesn't matter and only comes down to style? – cmbaxter Jan 22 '16 at 13:52
  • @cmbaxter Yes, I think they are pretty much equivalent. There might be some corner cases I am missing. – Alexey Romanov Jan 22 '16 at 13:55
  • I guess when I don't explicitely write the return type of the function, IntelliJ says the function returns `Future[Any]`. Guess that's cause the IDE regocnizes different types inside the future and then says it's Any. So both is valid and it doesn't make a real difference, if I understand correct? But which should I use then? – Wolfsblvt Jan 22 '16 at 14:07
  • Check out this blog post series from S11 - http://typelevel.org/blog/2015/07/13/type-members-parameters.html – Kevin Meredith Jan 22 '16 at 18:58

1 Answers1

4

It is a matter of semantics:

The Existential TypeT[_] means there is a class/type at the position of _ for which I do not care at all but it must be there.

T[Any] means there has to be a subclass Any present.

The difference comes into play when you want to serialize the underlying class. If you just use _ without any typebounds you will not be able to use some of the many Scala JSON libraries.

Andreas Neumann
  • 10,734
  • 1
  • 32
  • 52
  • Thank you, that helps me to understand a bit more. `_` means I don't care and `Any` means I care but it can be everything. So in my example, what would it be? I guess Any would be more correct? (Oh, and a bit offtopic, but your last paragraph, does that mean you can serialize `Any`?) – Wolfsblvt Jan 22 '16 at 14:56
  • 1
    Another attempt to state it: `T[Any]` means "at compile time, we know for sure that at runtime, the value might be anything". `T[_]` means "maybe we have some compile-time knowledge here, maybe we don't, it's fine either way". – Seth Tisue Jan 22 '16 at 17:35
  • Yes. I would go for `Any` when in doubt. – Andreas Neumann Jan 22 '16 at 19:27
  • You definitly can not serialize `_`. – Andreas Neumann Jan 22 '16 at 19:36