Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Nulls in Scala ...why is this possible?

I was coding in Scala and doing some quick refactoring in Intellij, when I stumbled upon the following piece of weirdness...

package misc

/**
 * Created by abimbola on 05/10/15.
 */
object WTF extends App {

  val name: String = name
  println(s"Value is: $name")
}

I then noticed that the compiler didn't complain, so I decided to attempt to run this and I got a very interesting output

Value is: null
Process finished with exit code 0

Can anyone tell me why this works?

EDIT:

  1. First problem, the value name is assigned a reference to itself even though it does not exist yet; why exactly does the Scala compiler not explode with errors???

  2. Why is the value of the assignment null?

like image 346
Abimbola Esuruoso Avatar asked Oct 09 '15 16:10

Abimbola Esuruoso


People also ask

Why does Scala have null?

null is the value of a reference that is not referring to any object. It can be used as a replacement for all reference types — that is, all types that extend scala. AnyRef. We must try to avoid using null while initializing variables if there's an empty value of the variable's type available, such as Nil.

Why should null be avoided in Scala?

Ignoring the possibility of null might be fine in a well built code base where it shouldn't come up anyway and null would be a bug, but a simple guard to catch it could prevent more subtle bugs from showing up in case something went wrong and null actually happens.

Is using null in Scala a good practice?

As a word of caution (and balance), the Twitter Effective Scala page recommends not overusing Option , and using the Null Object Pattern where it makes sense. As usual, use your own judgment, but try to eliminate all null values using one of these approaches.

What is null in Scala?

Null is - together with scala. Nothing - at the bottom of the Scala type hierarchy. Null is the type of the null literal. It is a subtype of every type except those of value classes. Value classes are subclasses of AnyVal, which includes primitive types such as Int, Boolean, and user-defined value classes.


1 Answers

1.) Why does the compiler not explode

Here is a reduced example. This compiles because through given type a default value can be inferred:

class Example { val x: Int = x }

scalac Example.scala 
Example.scala:1: warning: value x in class Example does nothing other than call itself recursively
class Example { val x: Int = x }

This does not compile because no default value can be inferred:

class ExampleDoesNotCompile { def x = x }

scalac ExampleDoesNotCompile.scala 
ExampleDoesNotCompile.scala:1: error: recursive method x needs result type
class ExampleDoesNotCompile { def x = x }

1.1 What happens here

My interpretation. So beware: The uniform access principle kicks in. The assignment to the val x calls the accessor x() which returns the unitialized value of x. So x is set to the default value.

class Example { val x: Int = x }
                             ^
[[syntax trees at end of                   cleanup]] // Example.scala
package <empty> {
  class Example extends Object {
    private[this] val x: Int = _;
    <stable> <accessor> def x(): Int = Example.this.x;
    def <init>(): Example = {
      Example.super.<init>();
      Example.this.x = Example.this.x();
      ()
    }
  }
}                            ^

2.) Why the value is null

The default values are determined by the environment Scala is compiled to.

In the example you have given it looks like you run on the JVM. The default value for Object here is null.

So when you do not provide a value the default value is used as a fallback.

Default values JVM:

byte  0
short 0
int   0
long  0L
float 0.0f
double    0.0d
char  '\u0000'
boolean   false
Object    null // String are objects.

Also the default value is a valid value for given type: Here is an example in the REPL:

scala> val x : Int = 0
x: Int = 0

scala> val x : Int = null
<console>:10: error: an expression of type Null is ineligible for implicit conversion
val x : Int = null
                   ^
scala> val x : String = null
x: String = null
like image 51
Andreas Neumann Avatar answered Oct 17 '22 08:10

Andreas Neumann