Chapter 4: Type Inference

Type inference is another interesting concept of programming languages. This concept is available in Dynamic and Static programming languages. In Dynamic, the interpreter is the responsible for inferring the types of values, but in Static compiler is responsible for inferring the values and detects its type automatically after that, on the basis of that type, it creates variables. The maturity of type inferencing depends on language to language.

In Scala, type inferencing is performed the major role in a variable declaration, method return types, method arguments, pattern matching and more. In Java, type inference is not rich as Scala, from Java 7 onwards, we can use type inference with generics using diamond operator and in Java 8 there are some enhancements for the same. From Java 10 onwards, we can declare a variable using var and infer type automatically but in the limited scope. Let’s see in Scala how type inference work.

val name = “Harmeet”

When compiler read this code, first checks, whether type annotation is explicitly declared or not. If it is explicitly declared then it evalautes the expression and matched expression results type is equals to declared type otherwise it declares the type of variable on the basis of expressions evaluation result type. Compiler follows a similar way to resolve type inference in other areas of code like method return type, pattern matching, etc. If our expression returns more that one type of value like using an if-else expression or pattern matching as below:

val result = if(<condition>) 13 else “thirteen”

val result = obj match {
	case value: String => value
	case value: Int => value
}

In that case, type inference looking for the “common type” for inferencing the actual type of variable result. Like in our if-else expression we are returning two different types on the basis of the condition. When type inference looking for the type, it evaluates on the basis of type hierarchy (we will explore type hierarchy more in next chapter) as below:

Int => AnyVal => Any
String => AnyRef => Any

As per hierarchy, Int is a subclass of AnyVal which is a subclass of Any. Similar to String , String is a subclass of AnyRef, AnyRef is a subclass of Any. So, in both of the cases, Any is the common type, and in that case, type inference evaluates the result variable is a type of Any.

Some Internals:

As we know after compilation scala source code is converted into byte code. Byte code is based on the Java language and we know, Java doesn't contain Any type, so now the question is, how Any type is handled in byte code as per our if-else and pattern match expression?

val answer = if(<condition>) 13 else “thirteen”

Under the hood compiler boxed int value into Integer type of Java wrapper class, In that case, Object is a superclass of both String and Integer. So, in byte our code is something like this:

public Object method() {
        return BoxesRunTime.boxToInteger(12);
}

Last updated