0

I was following the scala course from coursera taught Martin Odersky. He was giving some brilliant examples about return types and one thing puzzled me:

if(true) 1 else false // return AnyVal as this is the closest subtype of both primitive types

I assume that the following:

if(true) Tweet.comment("hello") else String("Hello") // I assume that this code will return AnyRef

However when will scala ever return Any? Will it ever return Any?

tilpner
  • 4,401
  • 2
  • 19
  • 42
Bula
  • 1,808
  • 4
  • 24
  • 48
  • 2
    `if (cond) 1 else "hello"`. There are two subtypes of `Any` - `AnyVal` and `AnyRef`, so if the two branches return a subtype of each of these, the type of the entire expression will be `Any`. – Lee May 18 '14 at 18:26
  • @Lee this should be an answer – Ryan May 18 '14 at 18:36

3 Answers3

8

@dfeuer's answer is correct, I just wanted to add some more information.

AnyVal is the base type for primitive types, i.e. Int, Boolean, Byte, etc. In Java, these are the 'keyword' types int, boolean, byte.

AnyRef is the base type for reference types, i.e. java.lang.Object and just about any class.

Any is the common type between AnyVal and AnyRef. In your example, you return 1 else false, so the compiler looks for the common type between Int and Boolean, finding AnyVal.

If you return if(true) 1 else "hello", it finds the common type between Int (an AnyVal) and String (an AnyRef), so it finds Any.

Dylan
  • 11,912
  • 2
  • 35
  • 64
  • `AnyRef includes just about any class` that isn't `AnyVal`. Given `class X(val x: Int) extends AnyVal` then `if (true) new X(42) else 42` has type `AnyVal`. – som-snytt May 18 '14 at 20:33
  • What function does the `AnyVal` class serve? I imagine there are a lot of things that can be done with `AnyRef` (generic containers, etc.), but raw/unboxed values are highly non-uniform. Does `AnyVal` exist just so you can declare a class to be a value class and have the compiler verify for you that it really is one? – dfeuer May 19 '14 at 19:45
  • I can't answer that with any real authority, but [this question](http://stackoverflow.com/questions/12655028/what-is-the-purpose-of-anyval) seems related – Dylan May 19 '14 at 19:53
4

How about:

scala> if (true) "hi"
res0: Any = hi

That is because the spec says that the else clause is supplied with the Unit value, which is an AnyVal:

scala> if (true) "hi" else ()
res1: Any = hi

That came up on SO a while ago, but I'm not motivated to hunt it down. The lesson, though, is that one might naively expect the lone if to be type Unit.

I just had a compiler error for a recursive function of the form:

def f = if (cond) f

You have to specify the result type of f.

som-snytt
  • 38,672
  • 2
  • 41
  • 120
1

I don't know Scala, but based on your examples,

if(true) 1 else "hello"

should probably do the trick.

acjay
  • 28,690
  • 4
  • 51
  • 93
dfeuer
  • 44,398
  • 3
  • 56
  • 155