If Scala is a compiled language, then why didn't it detect an out of bound exception in this program beforehand?

157 views Asked by At

The program is:

object Hello extends App {
    
    val a: List[Int] = List(1, 3, 4, 5, 8, 10, 11, 22, 33)
    for (i <- 0 to 11)
        println(a(i))

}

The Output is:

1
3
4
5
8
10
11
22
33
java.lang.IndexOutOfBoundsException: 9 // continues as a long error message.

How did it not detect at the compile time that the index was going to be out of bound? Aren't compiled languages supposed to do this? If no, could you please share what is included in the compile time checks and what's not?

As a newbie, I always hear that, compiled languages are great that they find errors at compile time thus are more robust.

2

There are 2 answers

4
Tim On

The main problem here is that for in Scala does not mean the same as it does in other languages. The code in the question is equivalent to

(0.to(11)).foreach(i => println(a.apply(i))

The compiler would have to inspect a number of different methods and infer their behaviour in order to determine that the apply method would throw an exception.

But the main advantage of compiled languages is performance, not error checking. It is strongly-typed languages (which are typically compiled) that provide better error detection.

5
Dmytro Mitin On

You shouldn't confuse compiled languages (or statically typed languages) with dependently typed languages. Collections not longer than n elements is a typical example of dependent type. A language being compiled means that there are compile-time checks besides runtime checks. Whether to make a specific check (like the check of collection length) runtime or compile-time is your choice (or the choice of language designers or the choice of standard-library designers). And even if a check is compile-time, whether to encode it in types or with different tools is also a choice.

Interpreted vs Compiled: A useful distinction?

Can every language be categorized as either compiled or interpreted?

Can every language be compiled? And can every language be interpreted?

What is dependent typing?

Any reason why scala does not explicitly support dependent types?

Shapeless: Collections with statically known sizes

import shapeless.Sized
import shapeless.nat._

val a: Sized[List[Int], _9] = Sized[List](1, 3, 4, 5, 8, 10, 11, 22, 33)

a(10) // doesn't compile

scastie