Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How are lazy val class variables implemented in Scala 2.10?

This answer to What's the (hidden) cost of Scala's lazy val? shows how they were implemented in Scala 2.7. But as the comments say, this must have changed since then, so I'm curious, what's the current (2.10) implementation of class lazy val variables?

like image 271
Petr Avatar asked Jul 14 '13 18:07

Petr


People also ask

How does lazy Val work in Scala?

Vals and Lazy vals are present in Scala. lazy keyword changes the val to get lazily initialized. Lazy initialization means that whenever an object creation seems expensive, the lazy keyword can be stick before val.

What are lazy Vals in Scala?

Scala Language Var, Val, and Def Lazy val lazy val is a language feature where the initialization of a val is delayed until it is accessed for the first time. After that point, it acts just like a regular val .

What does a lazy Val do?

7 Answers. Show activity on this post. The difference between them is, that a val is executed when it is defined whereas a lazy val is executed when it is accessed the first time. In contrast to a method (defined with def ) a lazy val is executed once and then never again.


1 Answers

Compiled this with scala 2.10.2:

class Foo {

  lazy val bar = math.pow(5, 3)

}

Then decompiled the result with JD-GUI:

import scala.math.package.;
import scala.reflect.ScalaSignature;

@ScalaSignature(bytes="\006\001e1A!\001\002\001\013\t\031ai\\8\013\003\r\tq\001P3naRLhh\001\001\024\005\0011\001CA\004\013\033\005A!\"A\005\002\013M\034\027\r\\1\n\005-A!AB!osJ+g\rC\003\016\001\021\005a\"\001\004=S:LGO\020\013\002\037A\021\001\003A\007\002\005!A!\003\001EC\002\023\0051#A\002cCJ,\022\001\006\t\003\017UI!A\006\005\003\r\021{WO\0317f\021!A\002\001#A!B\023!\022\001\0022be\002\002")
public class Foo {

    private double bar;
    private volatile boolean bitmap$0;

    private double bar$lzycompute() {
        synchronized (this) { 
            if (!this.bitmap$0) { 
                this.bar = package..MODULE$.pow(5.0D, 3.0D); 
                this.bitmap$0 = true; 
            } 
            return this.bar; 
        }  
    } 

    public double bar() { 
        return this.bitmap$0 ? this.bar : bar$lzycompute(); 
    }

}

Edit - Here's what it looks like for three fields:

class Foo {

  lazy val a = math.pow(5, 1)
  lazy val b = math.pow(5, 2)
  lazy val c = math.pow(5, 3)

}

Decompiled:

import scala.math.package.;
import scala.reflect.ScalaSignature;

@ScalaSignature(bytes="\006\001\0052A!\001\002\001\013\t\031ai\\8\013\003\r\tq\001P3naRLhh\001\001\024\005\0011\001CA\004\013\033\005A!\"A\005\002\013M\034\027\r\\1\n\005-A!AB!osJ+g\rC\003\016\001\021\005a\"\001\004=S:LGO\020\013\002\037A\021\001\003A\007\002\005!A!\003\001EC\002\023\0051#A\001b+\005!\002CA\004\026\023\t1\002B\001\004E_V\024G.\032\005\t1\001A\t\021)Q\005)\005\021\021\r\t\005\t5\001A)\031!C\001'\005\t!\r\003\005\035\001!\005\t\025)\003\025\003\t\021\007\005\003\005\037\001!\025\r\021\"\001\024\003\005\031\007\002\003\021\001\021\003\005\013\025\002\013\002\005\r\004\003")
public class Foo {

    private double a;
    private double b;
    private double c;

    private volatile byte bitmap$0;

    private double a$lzycompute() {
        synchronized (this) {
            if ((byte)(this.bitmap$0 & 0x1) == 0) {
                this.a = package..MODULE$.pow(5.0D, 1.0D); 
                this.bitmap$0 = ((byte)(this.bitmap$0 | 0x1)); 
            } 
            return this.a;
        }  
    } 

    private double b$lzycompute() { 
        synchronized (this) {
            if ((byte)(this.bitmap$0 & 0x2) == 0) {
                this.b = package..MODULE$.pow(5.0D, 2.0D); 
                this.bitmap$0 = ((byte)(this.bitmap$0 | 0x2)); 
            } 
            return this.b; 
        }  
    } 

    private double c$lzycompute() { 
        synchronized (this) {
            if ((byte)(this.bitmap$0 & 0x4) == 0) {
                this.c = package..MODULE$.pow(5.0D, 3.0D); 
                this.bitmap$0 = ((byte)(this.bitmap$0 | 0x4)); 
            } 
            return this.c;
        }
    }

    public double a() {
        return (byte)(this.bitmap$0 & 0x1) == 0 ? a$lzycompute() : this.a;
    }

    public double b() { 
        return (byte)(this.bitmap$0 & 0x2) == 0 ? b$lzycompute() : this.b; 
    } 

    public double c() { 
        return (byte)(this.bitmap$0 & 0x4) == 0 ? c$lzycompute() : this.c;
    }

}
like image 126
Chris Martin Avatar answered Sep 18 '22 12:09

Chris Martin