Which are the problems of having primitive types?


#1

Hello, I am starting to learn Scala and while reading Programming in Scala I found the following statement in Chapter 1 · A Scalable Language.

Even though object-oriented programming has been mainstream for a long time, there are relatively few languages that have followed Smalltalk in pushing this construction principle to its logical conclusion. For instance, many languages admit values that are not objects, such as the primitive values in Java. Or they allow static fields and methods that are not members of any object. These deviations from the pure idea of object-oriented programming look quite harmless at first, but they have an annoying tendency to complicate things and limit scalability.

In the following lines there isn’t an explanation. Which are the problems behind primitives that led Scala developers to rather choose Objects?

Thank you for your atention


#2

The problem is not having primitive values (in the sense of values the underlying platform, e.g. JVM, CPU, etc., directly support), but treating them differently from objects. In Scala, an Int will compile down to a primitive JVM int if possible, using the boxing types from Java otherwise, but you can use it on the language level like any other type, for example call methods on it and use it as type parameter. This can make APIs more consistent.

For an example, where the distinction makes things complicated, just look at the Java Standard Library. Collections can not be used with primitives, you have to use the wrapper types, instead of List<int> you write List<Integer>. The boxing itself will mostly be automatic, but now you have two names for essentially the same thing.

Especially the newer stuff since Java 8 also has completely separate implementation for primitive variants of some types. There is Stream<T>, which works for all object types, and then IntStream, DoubleStream, etc. which do not have a compatible API. Same for Optional with it’s specializations OptionalInt etc. having nearly none of the methods of the generic variant (I stumbled upon it not having map and filter several times).

The reason for creating these is efficiency, because as said primitives cannot be used in generic type arguments and all values will be boxed in an additional object when using the generic variant. Scala allows you to create such specialized versions in a way that makes this transparent for users of the API (by using an annotation to tell the compiler to generate specialized versions), which is only possible because the primitives are not treated as completely separate in the type system and can be used in generics like any other type.