Why do Scala index methods return -1 instead of None if the item is not found?

I always wondered why in Scala various index methods for determining the position of an element in a collection (for example, List.indexOf , List.indexWhere ) return -1 to indicate the absence of this element in the collection, and not the more idiomatic Option[Int] . Is there any particular advantage to returning -1 instead of None , or is it just for historical reasons?

+6
source share
3 answers

Itโ€™s just for historical reasons, but then I want to know what historical reasons are: what was the story and why did it happen?

The immediate history is the java.lang.String.indexOf method, which returns the index, or -1 if no matching character is found. But this is hardly new; the Fortran SCAN function returns 0 if the character is not found in the string, which is the same as that in which Fortran uses 1-indexing.

The reason for this is that the strings have only a positive length, so any negative length can be used as a None value without any boxing overhead. -1 is the most convenient negative number, so itโ€™s

And this can add up if the compiler is not smart enough to understand that everything is boxing and unboxing and everything does not matter. In particular, creating an object tends to take 5-10 ns, while calling or comparing functions usually takes more than 1-2 ns, so if the collection is short, creating a new object can have a significant fractional penalty (moreover, if your memory is already taxed tax free, and GC has a lot of work).

If Scala initially had an amazing optimizer, then the choice would probably be different, since you could just write things with options, which would be safer and less specific, and then trust the compiler to convert it to the corresponding high-performance code.

+7
source

Speed? (not sure)

 def a(): Option[Int] = Some(Math.random().toInt) def b(): Int = Math.random().toInt val t0 = System.nanoTime; (0 to 1000000).foreach(_ => a()); println("" + (System.nanoTime - t0)) // 53988000 val t0 = System.nanoTime; (0 to 1000000).foreach(_ => b()); println("" + (System.nanoTime - t0)) // 49273000 

And you should also always check the index <0 in Some(index)

+1
source

There is also the advantage that Int just returns can use the built-in Java types, while Option[Int] needs to wrap the integer in Object . This means both worse speed (as pointed out by @idonnie), but also more memory usage.

While Option great as a general tool (and I use it a lot), as well as other obscene presentations sa Double.NaN or an empty line are absolutely valid and useful.

One of the benefits of using Option is the ability to pass it to for loops, etc. as a collection. If you are unlikely to do this, checking for -1 or NaN may be shorter than doing matches for None / Some .

0
source

All Articles