Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer...

60
IN DEGREE PROJECT COMPUTER SCIENCE AND ENGINEERING, SECOND CYCLE, 30 CREDITS , STOCKHOLM SWEDEN 2017 Immutability: An Empirical Study in Scala LUDVIG AXELSSON KTH ROYAL INSTITUTE OF TECHNOLOGY SCHOOL OF COMPUTER SCIENCE AND COMMUNICATION

Transcript of Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer...

Page 1: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

IN DEGREE PROJECT COMPUTER SCIENCE AND ENGINEERING,SECOND CYCLE, 30 CREDITS

, STOCKHOLM SWEDEN 2017

Immutability: An Empirical Study in Scala

LUDVIG AXELSSON

KTH ROYAL INSTITUTE OF TECHNOLOGYSCHOOL OF COMPUTER SCIENCE AND COMMUNICATION

Page 2: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

Immutability: An Empirical Study inScala

LUDVIG AXELSSON

Master in Computer ScienceDate: 2017Supervisor: Philipp HallerExaminer: Mads DamSwedish title: Oföränderlighet: en empirisk studie i ScalaSchool of Computer Science and Communication

Page 3: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

i

AbstractUtilizing immutability is considered to have many desired benefits when it comes to software develop-ment and reasoning about programs. It is also one of the core principles of functional programming,and many programming languages have support for specifying immutability. Developers can by spec-ifying immutability write code that, for example, prevent program state from being unintentionallymutated. The Scala programming language is a functional and object-oriented language where devel-opers can specify immutability with reassignable and non-reassignable variables. The type system inScala has no built-in support for developers to express the fact that a type is immutable, immutability isinstead by convention and considered best practice. However, knowledge about the immutability usageand how prevalent it is in real-world Scala code are until this point non-existent.

This project presents an immutability analysis and evaluation of six small-to-large open sourceprojects written in Scala providing empirical data on immutability usage. The analysis investigates theimmutability property of templates, where a template refers to one of Scala’s different class types, onthree distinct properties: shallow, conditionally deep and deep immutability, where deep is the strongestimmutability property. The analysis works as a plug-in for the Scala compiler that statically analyzesthe source code of projects. We report immutability statistics for each evaluated project, includingthree widely used projects, Scala’s standard library, Akka’s actor framework and ScalaTest. Expla-nations to why stronger immutability properties do not hold are also provided.

The analysis show that the majority of templates for each project satisfied an immutability propertyand were not classified as mutable. Because each analyzed project had templates that were assumed tobe mutable, as they were unreachable by our analysis, there could potentially be more templates thatsatisfy an immutability property. Inheritance is shown to be an important factor when it comes to atemplate’s immutability and mutability was found to be lower for the template types case class and sin-gleton object. This can be seen as intended by the designers of Scala, indicating that these type of classabstractions help programmers utilize immutability. Our results show that immutability is frequentlyused in Scala and the high degree of immutability usage could be due to the functional nature of thelanguage.

Keywords immutability, empirical study, static analysis

Page 4: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

ii

SammanfattningAtt använda immuterbar (oföränderlig) data anses ha många önskvärda fördelar när det kommer till ut-veckling av program och att kunna resonera om dess funktionalitet. Immuterbar data är också en viktigprincip inom funktionell programmering och många språk har idag stöd för att ange immuterbarhet.Utvecklare kan i kod ange ifall data ska vara immuterbar för att till exempel förhindra ett programtill-stånd från att oavsiktligt förändras. Programmeringsspråket Scala är ett funktionellt och objektoriente-rat språk där utvecklare kan ange immuterbarhet med två typer av variabler, en som är tilldelningsbaroch en som är icke-tilldelningsbar. Typsystemet i Scala har inget inbyggt stöd för utvecklare att uttryc-ka det faktum att en typ är immuterbar, att använda immuterbarhet är i stället konvention och ansesvara den bästa metoden. Men uppgifter om hur immuterbarhet egentligen används i riktiga Scala pro-jekt har fram tills nu inte varit tillgängligt.

Detta projekt presenterar en immuterbarhetsanalys och en utvärdering av sex små till stora projektmed öppen källkod skrivna i programmeringsspråket Scala. Analysen undersöker immuterbarhetse-genskaper hos Scalas olika typer av klasser med avseende på tre olika egenskaper: ytlig, villkorligt djupoch djup immuterbar, där djup är den starkaste immuterbarhetsegenskapen. Analysen fungerar somett tillägg för Scalas kompilator och utfärdar en statisk analys av källkoden för ett projekt. Statistik omimmuterbarhet för varje projekt redovisas och utvärderas, bland annat tre välkända och populära kod-baser, Scalas standard bibliotek, Akka’s actor ramverk och ScalaTest. Förklaringar till varför klasserinte uppfyller en immuterbarhetsegenskap visas också.

Analysen visar att majoriteten av alla klasser i projekten har en immuterbarhetsegenskap och varinte klassificerade som muterbara. Eftersom varje projekt hade klasser som antogs vara muterbara föratt dessa inte var nåbara för våran analys så kan det potentiellt finnas fler klasser som har en immuter-barhetsegenskap. Vad en klass ärver visar sig vara en viktig faktor när det kommer till vilken typ avimmuterbarhetsegenskap den har. Muterbarhet visade sig vara lägre för klasser som är av typen caseclass and singleton object vilket kan anses vara avsett av Scalas skapare, då dessa klass abstraktionerhjälper programmerare att använda immuterbarhet. Resultaten visar att immuterbarhet används flitigt iScala och den höga användningsgraden kan vara på grund av att det är ett funktionellt språk.

Keywords immuterbarhet, empirisk studie, statisk analys

Page 5: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

Contents

1 Introduction 11.1 Motivation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11.2 Problem Statement . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.3 Contribution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.4 Choice of Methodology . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31.5 Delimitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41.6 Societal, Sustainability and Ethical Aspects . . . . . . . . . . . . . . . . . . . . . . . 4

2 Background 52.1 The Scala Programming Language . . . . . . . . . . . . . . . . . . . . . . . . . . . 5

2.1.1 Classes and Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62.1.2 Templates (class, object and trait) . . . . . . . . . . . . . . . . . . . . . . . . 62.1.3 Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9

2.2 Functional Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102.3 Immutability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11

2.3.1 Why Immutability Matters . . . . . . . . . . . . . . . . . . . . . . . . . . . 112.3.2 Varieties of Immutability . . . . . . . . . . . . . . . . . . . . . . . . . . . . 122.3.3 Immutability in Scala . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13

2.4 Immutability Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142.4.1 Static Program Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142.4.2 Scala Compiler Plug-in . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15

3 Related Work 173.1 Immutability Support in Programming Languages . . . . . . . . . . . . . . . . . . . 173.2 Immutability with Type Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . 183.3 Immutability Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20

3.3.1 Static Code Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203.4 An Empirical Study on C++ const and Immutability . . . . . . . . . . . . . . . . . . 213.5 Tools for Immutability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 223.6 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22

4 Methodology 234.1 The Immutability Analysis . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

4.1.1 Immutability Properties . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 244.1.2 Detecting Immutability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254.1.3 Limitations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274.1.4 Immutability Assumptions . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

iii

Page 6: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

iv CONTENTS

4.2 Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

5 Results 295.1 Projects Analyzed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295.2 Template Statistics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305.3 Immutability Statistics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 325.4 Immutability Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365.5 Conditional Deep Immutability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39

6 Discussion 416.1 The Empirical Study . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 416.2 Future Work . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 426.3 Conclusion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

Glossary 44

Bibliography 45

A Source Code and Data 48A.1 The Analysis Program . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48A.2 Immutability Assumptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48A.3 Immutability Attributes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50

Page 7: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

Chapter 1

Introduction

This chapter serves as an introduction to the degree project. We begin by describing the motivationand background of the project, followed by the problem statement and overall goal of it. The choice ofmethodology, delimitations, and contributions of the project are then also explained.

1.1 MotivationUnintended mutations of a program’s state are one reason for inconsistent behavior and bugs of theprogram. These mutations might have been introduced by side-effects of functions that developerswere unaware of during the program’s implementation. Some programming languages do, for exam-ple, allow arguments of a function to be mutated. The fact that a third-party function can mutate thestate of its argument can go undetected. The problem of rogue and complicated state mutations canbecome difficult to handle when states are shared among objects. One way to avoid undesired muta-tions is to use immutable data instead of mutable data. Immutable data cannot be mutated once createdand instead of mutating shared data in memory, data would have to be re-created to include the modi-fications needed. Programmers can then safely share data without the possibility of having it mutate tosomething else, which is crucial to avoid, for example, race conditions in concurrent programs.

Immutability is a property of data types and immutable data is one of the core principles of func-tional programming. In functional programming, programmers are supposed to use functions withoutside-effects, and a function has no side-effect when it does not mutate any state. Side-effects of func-tions disappear when the data used cannot be mutated. The concept of immutability is important andutilizing immutable data is considered to ease software development and reasoning about programs innumerous ways, for example:

Predictability It is harder to understand and reason about programs that have shared mutablestates with unclear interactions. Tracking mutations and maintaining the correct state of a programcan be difficult. Using immutable data naturally, avoids state changes and forces the programmerto let data flow and be utilized in a different way throughout the program, making the state of theprogram more predictable. For example, calling the same function twice would yield the same re-sult, and the outcome is predictable. Without the immutability guarantee, the second call couldyield another result because of an underlying state mutation making it less predictable.

Testability Because immutable data can only be changed once during construction, they are inher-ently simpler and easier to unit test. One may reason that by restricting the number of possible mu-tations in a program; the number of potential errors of the program is also reduced. Testing is es-sentially to validate that mutations in the program occur correctly and thus having more mutations

1

Page 8: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

2 CHAPTER 1. INTRODUCTION

would require more testing. By restricting the number of mutations in a program, the program hasfewer reasons for errors to occur and there are fewer state transitions to test.

Concurrency Immutable data are thread-safe, as data cannot mutate, there is no danger in havingmultiple threads access the same data at the same time and have synchronization issues.

Modularity Without depending on a local or global state, immutable types and data may be reusedin different contexts more easily.

This degree project aims to investigate immutability usage with the Scala programming languageas the target. The Scala programming language is a popular functional and object-oriented program-ming language with a strong static type system that was released publicly in 2004 [1]. The language isdesigned to be high-level with a concise syntax that allows programmers to do complex tasks with lessamount of code that is still easy to understand. Scala does not enforce developers to write code in afunctional style, and code can be written in both an imperative and functional style. The philosophy isto write code in the style that fits the program’s task [1], the functional style utilizing immutable datais highly encouraged and considered best practice when using Scala. The mix of object-oriented andfunctional programming, together with other properties of Scala, make this investigation particularlyinteresting from the immutability perspective because functional programming would by definition usemore immutable data.

In Scala, developers specify immutability with reassignable and non-reassignable variables on tem-plates. A template1 refers to either a class, case class, trait, object or case object definition, where thedefinitions beside class are special types of classes. There is no built-in way to know if a template isimmutable and it is not possible to express the fact that a type is immutable in Scala. Developers candefine types that are in fact immutable but the Scala’s type system does not support any functional-ity to reason about it. This is also true for many mainstream programming language [3] and externaltools or manual inspection has to be used to detect immutability. Immutability in Scala is instead byconvention and considered best practice. The Scala standard library, for example, systematically distin-guishes between mutable and immutable types by design. For example, the collection package containtwo packages mutable and immutable providing the same functionality but with different immutability.All templates that are mutable by design are in the mutable package and immutable classes in the im-mutable package. This allow developers to chose collection depending on if it should be immutable ornot.

Detecting immutability is a challenging task, and there are no prior data on immutability usagefor real-world Scala code. Such data could motivate a feature of the Scala compiler to enforce cer-tain immutability properties, for example, letting programmers explicitly specify if a template is im-mutable. As Coblenz et al. [4] points out, there are very little empirical data about the immutability ofreal-world applications in general. Empirical data can be used to understand immutability better and asgrounds for programming language design decisions.

1Following the terminology of the Scala language specification. [2]

Page 9: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

CHAPTER 1. INTRODUCTION 3

1.2 Problem StatementThe goal of this degree project is to investigate and attempt to explore the immutability usage of real-world code written in the Scala programming language. To explore immutability usage, an immutabil-ity analysis will be defined and developed to gather immutability statistics. To implement the im-mutability analysis this project will also include research about immutability and methods of introduc-ing immutability. More specifically, the following Research Questions (RQs) is what this project willaim to answer:

RQ1 How can a simple immutability analysis be defined and implemented in Scala? What are theneeded immutability properties?

RQ2 Using an implementation of the defined immutability analysis, how frequent is each im-mutability property for the different templates?

RQ3 What are the reasons to why stronger immutability properties are not satisfied?

RQ4 How often are types that are mutable or have a weaker immutability property used on tem-plates whose immutability is conditional? This involves, for example, using a mutable type on animmutable collection.

1.3 ContributionThe statistics, classification of immutability and found observations contribute to the understanding ofthe Scala language immutability usage and features. More specifically, the contribution includes:

• We present the design and implementation of a novel immutability analysis for Scala.

• An empirical study on the use of immutability in real-world, open-source Scala code.

• Based on the results of the empirical study, a set of explanations for discovered immutability.

1.4 Choice of MethodologyTo answer the problem statement in section 1.2 we base our results and conclusions on a scientificstudy using empirical data. We begin by investigating the problem statement with a literature studyof immutability and the Scala programming language. The literature study conducted will give a bet-ter understanding of the problem and to implement an analysis for the empirical evaluation. Gatheredliterature lay the foundation of the theoretical chapters, related work and the final implementation ofthe project. The literature study is followed by the implementation of an immutability analysis that canevaluate Scala source code and output empirical data. Scientific validity will be achieved by the empir-ical data and evaluation conducted gathered from Scala source code and conclusions of this thesis willbe based on that scientific study.

Page 10: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

4 CHAPTER 1. INTRODUCTION

1.5 DelimitationsThis project does not aim to extend the Scala compiler’s type system to have better built-in supportfor immutability. A well defined and simple immutability analysis will instead be developed for theempirical case study. We do not consider to create anything that can be used in practice for the Scalacompiler or as a tool for developers to use on a daily basis. The performance of the developed analysiswill thus not be of concern in this project, but it should, however, be usable to do the evaluation. Theamount of source code analyzed for the empirical study depends on the time frame of the project.

1.6 Societal, Sustainability and Ethical AspectsWhile the actual results and goals of this project have little impact on sustainability, societal and ethicalaspects, there are related areas that can utilize it with regards to these aspects. As today’s modern soci-ety relies on programming and programs for many crucial tasks, the role of software development anddesign has become exceedingly more important. The alleged benefits of using immutable data by de-sign in programs or immutability in programming languages can, therefore, touch upon many differentsocietal aspects. One frequent argument is that utilizing immutable data provides more maintainablecode (e.g, increased testability) which has several economical aspects to it. With maintainable code,resources can be spent on developing newer functionalities, optimizations and innovations in less timethat could reduce the development cost. Performance gains and shorter running times are also withwell-maintained code likely to arise if prioritized and may have positive effects on the environment andsustainability depending on the application.

The empirical study relies on publicly available open-sourced code that is not unethical to use anddoes, for example, not contain any proprietary or sensitive data. The study does not reveal or makeany claims to what the quality of the code is with regards to, for example, maintainability and it is im-portant to recognize the intellectual property of the code and not take any credit for it. Furthermore,the insights given from this study may influence researchers or language designers in their decisionswith regards to immutability. These design decisions could make immutability easier or harder to use,which in turn affects how many people that can learn and use it on an ethical aspect. It is thereforetogether with other aspects important for others to be able to validate and reproduce the results fromthis study. The results of this project are hence open-sourced and can be found in the appendix A to letanyone access and verify it.

Page 11: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

Chapter 2

Background

The purpose of this chapter is to give a theoretical background that is relevant to this project and neededto understand the problem explored. We begin by briefly explaining key features of the Scala program-ming language and touch upon concepts of object-oriented programming. Ideas of functional program-ming are then discussed followed by a detailed explanation of immutability and immutability analysis.

2.1 The Scala Programming LanguageThis section gives a short introduction to the Scala programming language and focus on a few key as-pects of it related to this project.

Scala is an acronym for “Scalable Language” and is a popular functional and object-oriented pro-gramming language with a strong static type system that was released publicly in 2004 [1]. The name“Scalable” comes from the idea that the language should scale and grow with the programmer’s needs.The language is designed to be high-level with a concise syntax that allows programmers to do complextasks with less amount of code and while it is still easy to understand. The majority of programs writ-ten in Scala are compiled to Java bytecode and executed on the Java Virtual Machine (JVM). Recentprojects, for example, Scala.js [5] and Scala Native [6] allow you to compile Scala code to run outsidethe JVM. Because of Scala’s relation with Java and the JVM, Scala is featured to have seamless inter-operability with Java. The Scala compiler allow developers to mix both Java and Scala classes [1] andit is possible to use Java libraries and call Java methods in Scala programs with no special syntax. Scalare-uses much of what is already written in Java without the Scala programmer’s knowledge, for exam-ple, Java’s primitive types, under the hood. Two of the key features of the language are that Scala is anobject-oriented language and full-fledged functional language and a very important aspect of Scala isthat:

“Every value is an object and every operation is a method-call” [1].

A value is the result of any computation or expression in Scala. Because Scala is object-oriented andclass-based, all values are therefore objects that are instances of classes. Functions are therefore ob-jects, and the function type is a class like any other value. The same goes for numerical values such asintegers or doubles which are objects too. An example of this is the statement 1 + 2 where two inte-gers 1 and 2 are added together. The two integers are instances of the Int class and the operator + is amethod-call on the object, the operation could thus be written as 1.+(2).

5

Page 12: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

6 CHAPTER 2. BACKGROUND

2.1.1 Classes and ObjectsPrograms that are written in an object-oriented programming language use objects that interact witheach other at run-time to carry out tasks. Classes are used to generate objects and defines their behav-ior. An object is an instance of a class, and an object is created by instantiating a class at run-time.In Scala, a class is defined with the class keyword and classes are instantiated using the new keyword,creating an object.

class Hello {

// Class definition goes here

private val greeting: String = ”Hello, World!”

def printGreeting = {

println(greeting)

}

}

Listing 1: The class declaration of Hello in Scala.

Listing 1 shows the definition of a class Hello written in Scala. Using the Hello class you can createHello objects with the new keyword by using the statement: new Hello. A class in Scala consist of fieldsand methods (functions). The fields hold data by using variables that refer to objects, and the variablesare defined with the keywords val or var. Methods are defined by the keyword def and contain the ex-ecutable code. The methods of a class are often used to manipulate its fields to do some computation.When creating an object (instantiating a class), the runtime allocates memory and stores the data of theobject. The assigned values for the fields (the data) of an object are called the object’s state.

Depending on how classes are designed, classes and its instances can be made immutable. If thestate of an object cannot change after it has been created, then we say that it is an immutable object.More about immutable objects and immutability in section 2.3.

2.1.2 Templates (class, object and trait)In the previous section 2.1.1 we used the notion of classes and objects that are related. The class isa key component in object-oriented programming and represents the source code that defines somebehavior once, where an object is an instance of a class at run-time that can be initialized several times.

Beside the ordinary concept of object-oriented classes, Scala has different templates [2] calledclass, object and trait, that can be used to create different types of classes. We also have the notionof case (for objects and classes), anonymous and different modifiers, for example, abstract and privatethat can be used on these templates.

Page 13: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

CHAPTER 2. BACKGROUND 7

The reason that the class types are brought up and explained here is because the analysis is goingto treat them separately and check how each type differs in immutability. Here is a short description ofthe template keywords:

class: The class keyword is used to create an ordinary class as described in section 2.1.1.

object: The object keyword is used to define a singleton object (a common design pattern in object-oriented programming). A Scala object is a type of class that can only be initialized once and thereis thus at most only one instance of that object. The object is automatically initialized the first timeit is used.

trait: The trait keyword can briefly be described to create a type of class that cannot be instanti-ated but can be used for inheritance. Classes, objects and traits can extend multiple traits but onlyone class at the time.

case class and case object: The case class and case object are two types of classes that automat-ically support pattern matching by implementing helping methods by default, for example, equalsand copy. These are often used to to compare and store data, and the generated functionality re-duces boilerplate code.

There is also the concept of anonymous class that is a synthetic subclass generated by the Scalacompiler.

class Person {

var name: String = ””

}

// The variable ”p” is an instance of an anonymous subclass

val p = new Person {

name = ”Tycho”

def nameLength = name.length

}

Listing 2: An example of an anonymous class that is a subclass of Person that implements a methodcalled nameLength.

Listing 2 shows an example of an anonymous class that. Anonymous classes are often used by theuser to create a subclass for some very specific task that will never be re-used, for example, when aspecific instance of a class is needed as an argument of a function.

Page 14: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

8 CHAPTER 2. BACKGROUND

trait Immutability

case object Immutable extends Immutability

case class Mutable(val reason: String) extends Immutability

class ImmutabilityAnalyzer(val sourceCodes: List[File]) {

sourceCodes.foreach(analyze(_))

// The immutability analysis

def analyze(file: File) = {

val immutability = getImmutability(file)

immutability match {

case Mutable => ...

...

}

}

}

object Program {

// The starting-point of the program

def main(args: Array[String]): Unit = {

val sourceCodeDir = args(1)

val sourceCode = new File(sourceCodeDir)

.listFiles

.toList

new ImmutabilityAnalyzer(sourceCode)

}

}

Listing 3: Example pseudo code of the different templates of Scala representing an immutabilityanalyzer.

Listing 3 is an example program that ties together the different templates (class types), trait, caseobject, case class, class and object, and represents a sample program of an immutability analysis. Theobject program is a singleton that represents the starting point of the application with its main method,which is reasonable since we only want to have one point of entry. The main method in the programuses an instance of the class called ImmutabilityAnalyzer to run analysis on given files. The returnedimmutability from the file is compared with pattern matching using the case class Mutable and caseobject Immutable that both inherit the trait Immutability.

Page 15: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

CHAPTER 2. BACKGROUND 9

2.1.3 TypesIn statically-typed programming languages, the type of a variable is known at compile-time with theuse of a static type system [7]. The task of the system is to classify variables and expressions with re-gards to the kind of value they can refer to or compute at run-time. Knowing the type of a variablemakes it possible to avoid certain run-time errors. For example, multiplying two types that would notcompute can be detected at compile-time instead of giving a run-time error when evaluated. Static typesystems can also detect if the correct number of arguments is passed to a function or that private vari-ables are never accessed outside of their scope.

The Scala compiler has type checking phase that verifies and enforces the type of a variable. Thetype of the variable limits and restricts the possible values of what it can refer to or compute at run-time. “Every variable and expression in a Scala program has a type that is known at compile-time” [1].

In Scala, there is a distinction between a template and a type. For example, a class is not a typebecause a class can construct many types with the use of type parameters. The generic class, Queue de-fined as, class Queue[T] has a type parameter T that can be instantiated with many different types. In-stantiating Queue with the type String and Int would result in the two types Queue[String] and Queue[Int],but not in the type Queue that is a class.

Figure 2.1: The Scala class hierarchy. [8]

The diagram in figure 2.1 illustrate the class hierarchy in Scala. The class that all classes inheritsfrom is Any that has two subclasses AnyVal and AnyRef. These two subclasses represent two differentclass categories. All classes belonging to AnyVal are predefined “value” classes in Scala. The othercategory contains reference classes where all user-defined classes belong, any user-defined class extendsAnyRef.

Page 16: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

10 CHAPTER 2. BACKGROUND

2.2 Functional ProgrammingThe functional way of programming is essentially to write programs that use functions without side-effects to evaluate expressions whenever possible. We say that a function has no side-effect when itdoes not mutate any state and we also call it a pure function. This is opposed to the imperative wayof programming where the program is a sequence of statements where each statement often mutatessome state in the program to do some task. Naturally, to avoid side-effects, a functional programmingstyle use immutable data to avoid mutations from taking place. In a purely functional programminglanguage, a program would be defined as a function composed entirely out of other functions [9]. Thisis not entirely feasible in practice for all programs, and some side-effects are inevitable, and that is whyfunctional programming languages often allow mutations in some way or another.

def square(x: Int) = x * x

Listing 4: A function that calculates and returns the square of a number x without any side-effect.

A pure function without side-effects does not depend on any state outside the function and cannotmutate any as seen in listing 4. Having functions with no side-effects means that order of executiondoes not matter [9] and any function can be evaluated at any time and is guaranteed to return the sameoutput with an input. Each function would take some input and return some output with no other effectthan to compute the output. Functions with side-effects, on the other hand, do modify some state of theprogram. A function could, for example, change a variable that is shared with other functionality andmutate a state.

private var y: Integer = 0

def square(x: Int) = {

y = x * x

y

}

def isZero() = {

y == 0

}

Listing 5: A function with a side-effect that calculates the square of a number x and stores it in a vari-able y outside the function (the side-effect).

As shown in listing 5, the side-effect of the function square is that the variable y is mutated on ex-ecution. It is not obvious to the programmer that when we call the square function also mutates thestate. Here the state of the object is changed other than just returning a value, making the functionisZero return another value than previously.

Functional programming languages have features that help to program in a functional style. Oneconsidered important feature is to have so-called first-class and higher-order functions which mean thatfunctions are treated as any other value. Functions should be able to be passed to functions, return fromfunctions and be stored as data. To tell if a function has side-effects in Scala the result of returned fromthe function is of type Unit. A function that does not return any value would not do anything in theprogram unless it did with some side-effect.

Page 17: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

CHAPTER 2. BACKGROUND 11

2.3 ImmutabilityWhen something is immutable, we say that it cannot be changed or that it is unchangeable. The defi-nition of an immutable object in an object-oriented programming language is an object that has a statethat cannot be mutated once instantiated (created). Moreover, an immutable class is a class whose in-stances cannot be mutated, meaning that there are no methods in the class that can mutate an instanceof it. Classes that are not immutable can, however, have instances of it that are immutable. An exam-ple of this is having the class List[T] that can be instantiated with both an immutable type and muta-ble type T. In a functional programming style the program naturally use immutable data and functionswithout side effects see section 2.2.

2.3.1 Why Immutability MattersThere are benefits and trade-offs of using immutable objects, some of which we have already listed in1. One benefit is that it may be easier to reason about immutable objects compared to mutable objectsbecause they are generally simpler because of their lack of state. Immutable objects cannot changetheir state over time and only have one state, and that is the state it was created in. A mutable ob-ject, on the other hand, can change over time and differently depending on how it is used making itmore complex and potentially more difficult to have an understanding of. Immutable objects are goodfor multi-threaded environments as they are thread-safe: two threads that concurrently access an im-mutable object cannot cause race conditions because no state can be modified. Immutable objects canalso be shared freely between functions. Passing a mutable object to a function may in the worst caserequire a defensive copy to be made first to ensure that the state of the object does not change unin-tentionally inside the function. That would not be an issue with an immutable object because its statecannot be mutated inside the function.

The most apparent trade-off when using immutable objects is the performance cost of needing tocreate a whole new object to change single state value. Instead of creating a whole new modified copyof the object, it is simpler and intuitive to mutate the existing object. One may argue that it is a morenatural way of doing things, we often mutate existing material in the real world instead of creating newmaterial from scratch.

From the book, “Effective Java” by Joshua Bloch “Classes should be immutable unless there’s avery good reason to make them mutable” and “If a class cannot be made immutable, limit its muta-bility as much as possible.” [10]. By limiting mutability, the number of states in that an object or anapplication can exist in is reduced. With fewer states it is easier to reason about that object and errorsare more likely to be reduced [10].

Page 18: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

12 CHAPTER 2. BACKGROUND

2.3.2 Varieties of ImmutabilityThere are different varieties of immutability used in practice today, and this section lists some of themto give an overview of each concept based on Potanin et al. [3]. Some of these varieties are used whenimplementing an immutability analysis for this project.

Object immutability

An immutable object is an object that cannot be modified (mutated), i.e., its state cannot be mutated.

Class immutability

When every instantiated object of a class is immutable, then we say that the class itself is immutable.

Deep and shallow immutability (transitivity)

Immutability can be deep or shallow, i.e., transitive or non-transitive:

• Deep (transitive) immutability means that all objects referred to by an immutable object mustalso be immutable.

• Shallow (non-transitive) immutability has a more relaxed constraint, and the immutable ob-ject may refer to objects that are mutable, but the fields of the immutable object itself cannot bemutated.

Reference immutability (read-only references)

Languages with the support of reference immutability have the notion of read-only references. A read-only reference cannot mutate the object it is referring to. When all references to an object are read-only, then nothing can mutate the object, and the object is immutable. There are, however, often noguarantee that a referred to object is immutable because the object may still be mutated by some otherreference that is not read-only, unless there is some analysis that ensures that there only exist ready-only references to that object [11]. Reference immutability thus often ensure shallow (non-transitive)immutability and “reference immutability” does not mean that a reference itself is immutable.

Non-assignability

Non-assignability is a form of immutability and property of a variable that makes sure that it cannotbe reassigned. Since fields of objects are variables and if no variable can be reassigned after its initialassignment, the object is effectively immutable if what the fields are referring to is immutable. Thismake non-assignability give shallow (non-transitive) immutability too. Assignment of an object’s fieldmutates the object, but it does not mutate what was previously on the field or what was assigned to thefield.

Concrete and abstract immutability

Concrete immutability does not allow any change to the object’s state. Abstract immutability, however,allows an immutable object to change its internal state but not the object’s “abstract” value. The objectis still immutable from the perspective of the object’s observer that can only see the abstract value, butthe object may mutate internally. This can, for example, be useful to speed up certain operations, lazyinitialization and buffering.

Page 19: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

CHAPTER 2. BACKGROUND 13

class Cache {

private var cached: Boolean = false

private var theValue: Integer = 0

def getValue() = {

if (!cached) {

theValue = someLongComputation()

cached = true

}

theValue

}

def someLongComputation(): Integer = {

42

}

}

Listing 6: A class where instantiated objects have abstract immutability behavior. An object ofCache would first compute the value once and return it; any subsequence call would only returnthe value (the abstract state).

An example of this is shown in listing 6. No observable mutation is visible for the user, but theobject’s of the class Cache do mutate internally by setting the cached and theValue field. The abstractvalue of the class does not change since the same value of the function always returned.

2.3.3 Immutability in ScalaScala programs can achieve all of the varieties of immutability, beside reference immutability, listed in2.3.2 with the correct use of two variables, var and val for fields. A variable in Scala is an entity thatrefers to an object:

• val: Once initialized, the variable can never be reassigned, and the reference is read-only through-out execution. The object referred to by the variable may, however, still be mutable.

• var: Can be reassigned and refer to different objects after initialization and throughout execu-tion, effectively making it mutable.

Programmers need to use val with care to achieve deep or shallow immutability to ensure that anobject’s state cannot be mutated at run-time. The use of val is highly encouraged and considered goodpractice. Arguments of functions are, for example, by default val instead of var and programmers donot have to worry about and determine if the passed arguments to functions are reassigned, somethingthat would be needed if var was used. Also, as described in “Programming in Scala” by Martin Oder-sky (the designer of Scala):

“Prefer vals, immutable objects, and methods without side effects. Reach for them first. Use vars,mutable objects, and methods with side effects when you have a specific need and justification for

them.” [1]

There are also two access modifiers, private and protected, that can be used to restrict access tovariables for certain scopes of the code. Listing 6 displays the class Cache that uses two private vars.

Page 20: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

14 CHAPTER 2. BACKGROUND

The meaning of private here is that those variables can only be accesses within the class Cache. Ob-ject’s of Cache can thus not be mutated at run-time from other objects. The other modifier protectedmake variables accessible only from the class itself and children of the class. The scope of private canbe altered to allow certain packages or classes to have access to them with the syntax private[X] andprotected[X] where X is a class, package or object. These access modifiers can be used to create. forexample, different versions of abstract immutability, by never exposing a var field as shown with thecaching example of listing 6.

2.4 Immutability AnalysisThe goal of immutability analysis in object-oriented programming languages is to figure out the im-mutability of a class or an instance of a class. Reasons for wanting to do immutability analysis can beto verify if a class is mutable or find out the cause of why it is. It may be that the reason for mutabilityis unintended or unnecessary and removing the cause would then make the program more simple (lesscomplex) in turn. An analysis can be done statically, without executing the program in question, ordynamically, by analyzing it under execution. In this project, a static immutability analysis will be con-ducted by analyzing the source code of Scala projects. One reason for making a static analysis tool isthat it can be automated to accompany a developer aiming to write code using principles of immutabil-ity without needing to execute the program. The dynamic approach, on the other hand would requirethe program to execute and the result of the analysis may depend on how the program is executed. Allexecutable parts of a program may not run, and some programs may be hard to execute and get anygood information from.

2.4.1 Static Program AnalysisBecause programs written in Scala are compiled to Java bytecode and executed on the we have twooptions when it comes to statically analyzing Scala programs source code. Either we analyze the pro-gram’s plain Scala source code or its bytecode after it has been compiled.

An issue with analyzing bytecode is that it does not have all the details that source code has. Scalasource code gets throughout the compilation process translated to a more Java-like language and at lastto the actual bytecode. The bytecode may, for example, contain optimizations or code that the userhas not written. This means that it would, for example, be hard to know which template we are ana-lyzing with bytecode, i.e., if it is an object, trait or class because they all end up as a Java class in thebytecode. These templates are abstractions at the Scala-level and the underlying bytecode only usesavailable instructions for the that does, for example, not include instructions for trait specifically.

Another important aspect when it comes to immutability analysis is that code written and fulfilla certain immutability property may be translated and optimized to something that looks mutablein bytecode. For example, the non-reassignable field lazy val would be translated by the compiler tosomething mutable, and its class would become mutable, even if it is not mutable from the developer’spoint of view.

Page 21: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

CHAPTER 2. BACKGROUND 15

2.4.2 Scala Compiler Plug-inThe Scala compiler is designed in a way that makes it possible to create and use plug-ins without mod-ifying the compiler itself. A plug-in is an external component with some extra functionality that theScala compiler load utilize it. This allows users to create and distribute plug-ins with functionalitywithout making any changes to the Scala compiler. An example of a plug-in can be extending the com-piler with functionality to read extra annotations and type-checking information or add an entirely newphase of the compiler after an internal compiler phase has completed.

A static program analysis, in the form of a compiler plug-in for Scala, is created for this project.The plug-in reads Scala source code, and output information about the immutability of detected classes,more details about the plug-in can be found in chapter 4.

To achieve the extra functionality that is suitable for a compiler plug-in a form of metaprogram-ming is often used. Metaprogramming refers to and is briefly about writing meta-programs. Meta-programs can, for example, be compilers, interpreters and program analyzers, programs that manipu-late itself or other programs [12]. A key concept of metaprogramming is called Reflection that can beused to observe and manipulate the behavior of programs at compile time or when they are executed.In Scala there a Reflection framework (the package scala.reflect) that can be used to view and modify,for example, fields and methods of templates.

Listing 7 shows an example of a compiler plug-in that if loaded by the Scala compiler would output“Class is immutable” if an immutable class is detected. The plug-in implements a new phase called“immutability analysis” and runs after Scala compiler phase called “refchecks”1 that is one out of manycompiler phases. The plug-in can utilize these different compiler phases to achieve different results,running after the plug-in after or before an optimization phase for example.

1https://wiki.scala-lang.org/display/SIW/Overview+of+Compiler+Phases

Page 22: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

16 CHAPTER 2. BACKGROUND

class ImmutabilityAnalysis(val global: Global) extends Plugin {

import global._

val name = ”immutability analysis”

val description = ”figures out the immutability of templates”

val components = List[PluginComponent](Component)

private object Component extends PluginComponent {

val runsAfter = ”refchecks”

def newPhase(_prev: Phase) = new

ImmutabilityAnalysisPhase(_prev)↪→

def isImmutable(t: Type): Boolean = {

// Return true if immutable

}

// Traverse through source code and check immutability

class ImmutabilityTraverser() extends Traverser {

override def traverse(tree: Tree): Unit = tree match {

case cls@ClassDef(mods, name, tparams, impl) =>

// We matched with a class

val klass = cls.symbol

if (isImmutable(klass.tpe)) {

// Do something if immutable

println(s”Class \$klass is immutable”)

}

traverse(impl)

case _ =>

// We did not match a class, traverse through the tree

super.traverse(tree)

}

}

// Immutability analysis phase

class ImmutabilityAnalysisPhase(prev: Phase) extends

StdPhase(prev) {↪→

override def name = ImmutabilityAnalysis.this.name

def apply(unit: CompilationUnit) {

val immutabilityTraverser = new ImmutabilityTraverser()

// Traverse through all source code

immutabilityTraverser.traverse(unit.body)

}

}

}

}

Listing 7: Example code of a Scala compiler plug-in implementing an immutability analysis.

Page 23: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

Chapter 3

Related Work

This chapter highlights relevant research conducted related to this project’s area. A number of researchpapers are discussed in the area of immutability, some of which are recent in-depth comparisons anddiscussions about immutability.

3.1 Immutability Support in Programming LanguagesAs explained in section 2.3, there is in general no doubt that using immutability is in many cases con-sidered good design when programming. Immutable data can, for example, yield simpler states, thread-safety and less concern when data is shared.

Potanin et al. [3] investigate what immutability is and how it is implemented in today’s “main-stream programming languages” (e.g., Java and C++). They provide an excellent summarization ofrecent research conducted in the area of immutability and object-oriented languages. One thing theypoint out is that programming languages that are non-functional have very limited support for im-mutability. They suggest that the two major improvements by recent immutability research and pro-posals of the last decade are:

• “Support transitive read-only by supporting the enforcement of not just the reference to an objectbut also any further references from such object being read-only.”

• “Support for object immutability rather than just read-only references thus guaranteeing that nounexpected alias to an immutable object can change its state.”

The first point ensures that the references of an object, that is referred to by a read-only reference, arealso read-only. Having only a read-only reference to an object does, however, not mean that the objectcannot be referred to by another reference that has write access. The second point introduces objectimmutability that in turn guarantee that none of those write access references can exist. Section 3.2 willin more detail explain and show how these two points can be achieved with type systems.

There is wide variety of ways of having immutability support in languages. Much of the supporthave little empirical data on what software engineers actually wants in practice according to Coblenzet al. [4]. They reviewed existing literature about immutability and developed a classification system.Their classification system showed mutability restrictions for selected languages and type systems indetail. They also interviewed developers and conclude that immutability is an important feature inpractice, but support for it lacks in commonly used programming languages. They point out that theirempirical study of interviewing programmers is not significant enough and “significantly more workwill be required in this area if we are to base language design decisions on empirical data.”, what anempirical study on source code like this project contributes with is therefore interesting.

17

Page 24: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

18 CHAPTER 3. RELATED WORK

3.2 Immutability with Type SystemsOne way of achieving immutability in programming languages is to let the type system enforce rulesof immutability. Having the compiler guarantee immutability can, for example, be useful for enablingoptimizations and documentation.

Birka and Ernst [11] introduced a type system that enables reference immutability or so-calledread-only references (see section 2.3.2). The type system does compile-time verification and run-timechecks for reference immutability and can be used for essentially any object-oriented programminglanguage. They have created a working implementation of the type system for the Java programminglanguage. The implementation is called Javari (Java with reference immutability), and it was used andtested in practice for usability and efficiency. Javari has keywords and additional annotations to vari-able declarations in Java, the keyword read-only is, for example, checked by the type system. The newannotations ensure that no read-only reference can be mutated or assigned to by the Javari compiler.According to them, it is more flexible to ensure reference immutability rather than object immutability.Reference immutability allows objects to be mutated during a construction phase and not after that.Having reference immutability can lead to object immutability if properly used. If all references to anobject are read-only references, then the object cannot be mutated and is immutable. They concludethat reference immutability is something to consider to support when designing a programming lan-guage.

Case studies have shown that Javari is practical to use and enforce reference immutability. How-ever, as pointed out by Quinonez et al. [13] Javari only type-check references that use the Javari typeannotations and not original Java code. To solve this usability issue, they developed an algorithm thatautomatically infers reference immutability for Javari and a tool called Javarifier. The tool Javarifiercan automatically convert Java libraries to be compatible with Javari and infers mutability for refer-ences. They showed that the tool could infer mutability in Java programs with one hundred thousandlines of code. This allows developers to use Javari without manually converting existing code, whichmay be tedious and error-prone. We could, however, not find any open sourced code of Javari beingused in practice.

Building on Java’s generics and annotations Zibin et al. [14] introduced a language extension forJava called Immutability Generic Java (IGJ). IGJ ensure both reference immutability and object im-mutability where an object is either mutable or immutable. The terminology of IGJ is similar to Javaribut the guarantee of object immutability allow for stronger immutability properties. Without changingJava’s syntax they have, for example, added a new type argument (the immutability argument) to thebeginning of the type arguments list. Three types of references Mutable, Immutable and ReadOnly canbe used.

Page 25: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

CHAPTER 3. RELATED WORK 19

class ListContains<I extends ReadOnly, X> {

private Integer id;

private List<Immutable, X> list;

public @ReadOnly boolean contains(X x) {

...

}

public @Immutable Integer getId() {

return this.id;

}

public @Mutable Integer setId(Integer id) {

this.id = id;

}

}

Listing 8: The definition of a Java class ListContains written using IGJ annotations and generics.

Listing 8 show an example of a Java class definition using IGJ. The class has a private field listthat is an Immutable list defined by the first type parameter in the declaration. Annotations are usedto specify the immutability of this inside a method, for example, @ReadOnly and @Immutable as seenin the ListContains class.

As seen in section 2.3.1 one of the benefits of having immutable objects is that they are inherentlythread-safe. Concurrent programs have to make sure that two threads cannot be affected by side-effectsfrom each other. A type system developed by Gordon et al. [15] was designed to prevent unintendedside-effects in concurrent programs. They too introduce reference immutability to control the muta-tion of objects together with the notion of isolation. Their type system introduces four type qualifiers:writeable, readable, immutable and isolated. The read-only type qualifiers are readable and immutable,references with these qualifiers are not allowed to mutate its referent (it is transitive). The isolated typequalifier ensures that the reference is unique to what they call an “externally-unique object cluster” thatis a graph of objects.

Figure 3.1: A figure that shows an isolated reference and an immutable reference referring to graph ofobjects [15].

Figure 3.1 is a figure taken from the paper that shows how the isolated reference uniquely refersto a graph of objects. The objects inside the graph all refer to each other freely, and it is allowed forthe objects to also refer to immutable objects outside the graph (adds flexibility). It is, however, not al-lowed to refer to any of the objects inside the object graph because all objects that are reachable froman isolated reference must pass through that isolated reference. References that are isolated are good

Page 26: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

20 CHAPTER 3. RELATED WORK

for parallelism as mutable data can be grouped amongst threads. Because there is also only one ref-erence to the graph of objects it can easily be converted to other type qualifiers such as writeable orimmutable. The flexibility is said to be good for algorithms that utilize parallelism to update and de-stroy objects. They test the type system with an implementation of it in the programming language C#that was in active use by a Microsoft team. The team at Microsoft were satisfied with the type systemand the benefits of reference immutability, but in particular, the provided safe parallelism.

Pechtchanski and Sarkar [16] introduce a specification for immutability. The immutability speci-fication is then applied and discussed with regards to code optimization. The specification has a set of“immutability assertions” and an assertion expresses an immutability property. These properties are ex-pressed in three dimensions, lifetime, reachability and context. Immutability assertions can with the life-time dimension specify the duration for when an object is immutable and in the reachability dimensionspecify deep or shallow immutability. Assertions in the context dimension can, for example, specifythat a field F is deeply immutable in a specific method. The field F can thus be mutated in some othercontext in another method or statement in a program. They show how these immutability assertionscan be used to improve the effectiveness of code optimization, for example, in global value number-ing, load elimination, elimination of null pointer checks and array bounds check, loop-invariant codemotion, dependency analysis, data transformations. They implement the specification as a frameworkfor Java and showed promising results of optimizations, some benchmarks had 5-10% improvement inspeed.

3.3 Immutability AnalysisAs we touched upon in section 2.4, immutability analysis attempts to answer the question whether aclass or an object fulfill some immutability property. For example, given a class definition, we can an-alyze if it is a class whose instance can never be mutated after construction and conclude that the classis deeply immutable. Dynamic and static code analysis are two methodologies used to conduct im-mutability analysis, the latter requires the program under analysis to be executed were the former donot.

3.3.1 Static Code AnalysisStatic code analysis or source code and byte code analysis for Scala is a methodology where we analyzecode without executing it. Instead of executing the program, we analyze its code either by reading thebytecode or the source code of it. An extensive framework for static code analysis is OPAL [17] thathave implemented different Java bytecode analyses. One analysis mode that is of great interest for thisproject is OPAL’s immutability analysis.

Their immutability analysis specifies two types of immutability, object immutability, and type im-mutability. The first one, object immutability, define a mutability rating of an instance of a class. Theyhave defined three different ratings that are “mutable”, “immutable” (deeply immutable) and “condi-tionally immutable”. The first two ratings are very similar to their corresponding definition listed in 2.3and conditionally immutable is a new concept. When an instance of a class is conditionally immutable,then the instance of the class cannot be mutated, but that instance can itself refer to other objects thatmay be mutated. A typical example of something that is conditionally immutable is an immutable col-lection that may contain mutable objects. The analysis looks at the bytecode of classes and investigatestheir fields to figure to define a mutability rating.

The second type of immutability, type immutability, investigate if all instances of a type and givesone of the three mutability ratings to the type (it could be the type of a class).

Page 27: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

CHAPTER 3. RELATED WORK 21

Any related work that do source code analysis as explored in this project were found, it does, how-ever, not mean that there are none.

3.4 An Empirical Study on C++ const and ImmutabilityAs we have discovered previously in section 3.2 much research has been done in designing type sys-tems that deal with immutability. These type systems can for example guarantee deep (transitive) im-mutability. However, none of these studies focus on what developers actually do in practice with theimmutability support we have in languages available today. Eyolofson and Lam [18] did an empiricalstudy of immutability usage with regards to the C++ programming language with a developed dynamicanalysis tool.

The keyword const is a type qualifier in C++ that can be used to specify immutability. When constis used on a method of a class then mutating the fields of the class (in context of the object) from thatmethod is not allowed. Moreover, when const is used on a reference, it specifies that no mutation canhappen through that reference (we can only read it and not write to it). These two cases of const (onmethods and references) indicate that const give developers shallow immutability by default. Remem-ber, shallow mutability means that fields of an object cannot be mutated. To have deep immutability,we also need to ensure that any object referenced through the fields cannot be mutated, which constdoes not do.

As we explored in section 2.3.2 about varieties of immutability, there is also the notion of abstractand concrete immutability that is used in practice. Having concrete immutability essentially means thatno state of the object is mutated. Abstract immutability, however, say that there should not be any ob-servable mutation to the object, the internal state may be mutated. Concrete immutability is the defaultbehavior given by const and to get abstract immutability in C++ there are escape hatches to do it. Onecan use the mutable keyword on a field that makes it possible for const qualified methods to mutate thefield. This feature also makes concrete immutability not guaranteed, since any const qualified methodmay mutate fields using the mutable keyword.

In their study, they observed how developers utilize const with 7 different large C++ projects rang-ing from 13 to 214 thousand lines of code. Their goal was to explore possible meanings of immutabil-ity and what immutability guarantees developers are expecting in practice. The hypothesis to why de-velopers would use abstract immutability is, for example, buffering, caching and delayed initialization.They created a dynamic analysis tool called ConstSanitizer that was used to track how const was usedand why. Their approach was to modify the way projects were built to use their tool and conduct theanalysis by running the project’s test suite. The tool tracked mutations performed on const qualifiedobjects or references which they call “writes-through-const”. Either a writes-through-const happentransitively (through a field which is allowed) or through some of the C++’s const escape hatches. Toevaluate the projects they compiled them with ConstSanitizer and ran the compiled executable that gen-erated a report of writes-through-const. They then classified the writes-through-const how the writeoccurred and why the write occurred.

They discovered that developer does write-through-const in practice and observed 17 unique cases.Developers did write-through-const by violating shallow immutability (using mutable keyword) anddeep immutability (by mutating objects referred to in fields) equally. Deep and shallow immutabilitywas violated 8 times each in the 17 cases. Half or 9 out of 17 cases of the writes-through-const werenot abstract immutable and had observable mutations (which was classified as incorrect).

Page 28: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

22 CHAPTER 3. RELATED WORK

3.5 Tools for ImmutabilityDeveloping programs in object-oriented programming languages often yield in a mix of both mutableand immutable classes. The nature of many programming languages makes it easy for many developersto mutate state, something that might be unnecessary. Striving to have immutable classes can be a gooddesign choice to, as we have seen, avoid reasoning about side-effects.

Kjolstad et al. [19] present an algorithm that can transform a mutable class into an immutableclass. The tool proved to be less error prone than doing manually transforming classes and it was suc-cessful in most cases. They showed that the tool potentially saved a programmer from doing non-trivialchanges (analyzing many methods) and about 45 lines of code on average per class on their test data.

Instead of transforming existing code, there are also tools that can help developers write code usingimmutability principles. For example, an editor used to write code can notify the developer if a classwas detected to become mutable after some code change. A program that works this way is calledMutabilityDetector [20] that analyze Java classes and detects if they are immutable. By annotating theclasses with, for example, Immutable, the program would detect if the class became mutable using aplug-in for the developer’s editor. The tool inspects the fields of the class and checks if they are, forexample, reassignable.

3.6 SummaryAs we have discovered in this chapter, research has been done in designing type systems that deal withimmutability. These type systems can, among other things, guarantee deep (transitive) immutability.There have, however, not been much research on what developers actually do in practice, with the im-mutability support in languages used today. Furthermore, there are, to our knowledge, no study todayabout immutability usage in the Scala programming language. One reason for it might be because im-mutability analysis is a complex task when classes can be mutated in many different ways. The goal isthus to define a simple immutability analysis and evaluate it.

Page 29: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

Chapter 4

Methodology

This chapter describes in detail how the goal of the degree project was achieved, the implementation ofan immutability analysis, in the form of a compiler plug-in, and how it was evaluated.

4.1 The Immutability AnalysisThis section describes how we developed an immutability analysis in the form of a compiler plug-in.The developed plug-in analyzes source code and assigns immutability properties to templates of a Scalaprogram. A class declaration in Scala consist of fields and methods, and in immutability analysis, thequestion is how these statements define the immutability of an instance of that class. For example, if noinstance of that class can be mutated after initialization, we call the class immutable.

The analysis reads and analyzes source code during the compilation phase of a program and printsout the immutability information about the analyzed program. It was implemented as a compiler plug-in for the Scala compiler, utilizing the Scala reflection library and a programming model called Reac-tive Async [21]. The programming model Reactive Async is mainly designed for handling concurrencyin programs, but it also has support for resolving cyclic dependencies, something that is crucial for ourimmutability analysis.

The plug-in is made to execute in between compiler phases and after a phase called refchecks. Atthis point, the compiler has, among other things, throughout different phases parsed the code into anAST and type-checked it. The code has been transformed to have the information we need in orderto do the analysis, a later phase than refchecks may not work as needed information gets lost at laterphases. For example, the last phase called jvm transforms the source code to bytecode and class files.As seen in figure 4.1, the compiler plug-in is one of the phases the Scala compiler executes when com-piling a program.

23

Page 30: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

24 CHAPTER 4. METHODOLOGY

Scala source code

Scala compiler

Phase 1 Phase 2 Immutability analysis

Phase n-1 Phase n

Java Virtual Machine (JVM)

Java bytecode

Traversal of typed AST

Analysis Report statistics

Figure 4.1: An overview of the compilation process

The Reactive Async model utilizes the notion of a cell, which holds a value, and a correspondingcell completer to perform updates on the cell. The cell can be assigned values from a lattice designedto make the assignments monotonic and deterministic. A lattice has a defined join operator that returnsthe next value of the cell given the current and the new value. In our analysis, a cell is assigned to eachtemplate (class, trait, or object declaration) found and the values of the lattice are immutability proper-ties. Cells can have dependencies between each other so that an update of one cell may trigger an up-date of another cell. These updates can be conditional and setup so that only if the original cell updatefulfill some condition we update another cell. Conditional updates are used for handling dependenciesbetween templates and explained in more detail in section 4.1.2.

4.1.1 Immutability PropertiesWith knowledge gathered from chapter 2 and 3, we list the immutability properties deemed necessaryto create a simple but useful analysis that can decide the immutability property of a template. The im-mutability properties are:

Mutable: We give a template the mutable property if an instance of that template can be mutateddirectly or indirectly.

Shallow immutable: A template has the shallow (non-transitive) immutable property if the tem-plate does not have fields that can be reassigned, but has references to other objects that may bemutated (are shallow immutable or mutable).

Deeply immutable: A template is deeply (transitive) immutable if all instances of that templatecannot be mutated after initialization.

Conditionally deeply immutable: The conditionally deeply immutable property is given to atemplate that is deeply immutable but depends on some other potentially mutable type. An exam-ple of this is a generic collection that can store different types, and the collection itself is declaredin a way so that it cannot be mutated, but the type that is used with the collection may be shallowimmutable or mutable (an example of this is shown in listing 9).

Page 31: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

CHAPTER 4. METHODOLOGY 25

As we have discovered in previous chapters, there are different types and properties of immutabil-ity. One immutability property not considered by our analysis is the notion of abstract immutability [3].The reasoning behind it is that abstract immutability is not simple enough, and to compute abstract im-mutability one would have to deal with a class’s internal state which could be set up in a multitude ofdifferent ways and track state changes [18].

4.1.2 Detecting ImmutabilityThis section details how the plug-in detects and defines the immutability properties. The plug-in con-sists of three different steps that are executed in between compiler phases and after a compiler phasecalled refchecks. Inside the plug-in, using the Reactive Async model, each template is assigned a cell,and the lattice contains the different immutability properties. The values of the lattice are thus be muta-ble, shallow immutable, conditionally deeply immutable and deeply immutable (defined in section 4.1.1).The initial value of a cell is immutable and the methodology is to find proof that the class has anotherimmutability property.

The first step of our plug-in traverses every AST and creates a cell and cell completer for eachtemplate found. These cells and corresponding cell completers are stored in a map with bidirectionallookup between templates and cells that are needed for the below analysis.

The next step is to analyze the fields and parents of each template found. First we check if the cur-rent immutability property of a field or parent yields a new immutability property for the analyzed tem-plate. We then set up a conditional update between the template’s cell and all the cells of the fields andparents templates. In this way, if the immutability property of a template cell changes, dependent cellswill be notified and change accordingly (it may yield a new immutability property), an example of thisis provided further below in listing 10 and 11. Each immutability property has a set of conditions thatmost hold. We determine a template to have one of the following immutability properties if the listedconditions of that property hold:

• We determine a template to have the mutable property if:

– The class contains any reassignable field, i.e., a var field definition.– The source code of the class is unknown and unreachable (see section 4.1.3).– It inherits from a mutable class or mixes in a mutable trait.

The property mutable is thus given by only inspecting the fields and the parents of a class.

• A template is given the property shallow immutable if:

– The template has only non-reassignable fields, i.e., val field definitions.– Has a parent that is shallow immutable.– A field has a type that is known to be mutable or shallow immutable.– A field has a type argument that is mutable or shallow immutable.

The use of a conditionally deeply immutable collection may be rated as shallow immutable, anexample of this is shown below in listing 9.

• We give the property deeply immutable to a template if:

– All fields are non-reassignable, i.e., val definitions.

Page 32: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

26 CHAPTER 4. METHODOLOGY

– The type of all fields is deeply immutable.

All known templates are by default assigned this property until another property holds.

• A template has the conditionally deeply immutable property if:

– It is deeply immutable with one or more type parameters.

An example of a conditionally deeply immutable template is a collection that can be used withany type of class. Listing 9 shows an example scenario where a conditionally deeply immutableclass called List is used.

class Mutable(var argument: String)

class ImportantTask {

val test: List[Mutable] = new List(new Mutable)

...

}

class List[T](val argument: T) {

val immutable: String = ”Immutable string”

...

}

Listing 9: Example usage of a conditionally deeply immutable class List.

The class List[T] would be deeply immutable if it did not have the type argument T. The classcan now be instantiated with a mutable or deeply immutable type T. In the example, the class Im-portantTask uses the List class with a type argument that is mutable, making the ImportantTaskeffectively shallow immutable.

When a template is deemed not to be deeply immutable, then the join operator of the immutabilitylattice is used. The join operator gives the highest precedence to the immutability property mutablefollowed by shallow immutable, conditionally deeply immutable and deeply immutable. A join betweentwo properties returns the maximum of the, thus succeed only if one of the properties have a higherprecedence. The mutable property is consequently final, and the join operator does not return any otherimmutability property. A template can, for example, first be assigned a property that holds at that pointin time but later on become mutable.

Dependencies between templates can be setup in many different ways and, for example, createcycles as shown in listing 10. When a template A uses another template B, we say that template A de-pends on template B. To draw any conclusion about the immutability property of template A, accordingto the properties above, we also need to know the the immutability property of B. In other words, weneed to handle dependencies between templates. Here is where conditional updates in the ReactiveAsync model come into play.

Page 33: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

CHAPTER 4. METHODOLOGY 27

class A(val b: B)

class B {

var a: A = new A(this)

}

Listing 10: Two classes A and B with a cyclic dependency.

We cannot assume that we know the immutability of B when we analyze A with a dependency ofB and dependencies can be read in different orders in listing 10. To solve this, we added conditionalupdates using Reactive Async between the cells and a callback is fired when a change to a cell occurs.An example callback is shown in listing 11.

cellForA.whenNext(cellForB, (x: Immutability) => {

if (x == Mutable || x == ShallowImmutable) {

WhenNext

} else {

FalsePred

}

}, Some(ShallowImmutable))

Listing 11: When the cell cellForA changes a callback is given for cell cellForB.

For the code example of listing 10 the corresponding dependency callback in 11 may be createdin a different version with another order, where the cells are cellForB to cellForAinstead. If we readclass A first, we would detect class B with having the default deeply immutable property and setup aconditional update as in listing 11. When we then analyze class B we notice that it has a reassignablefield, giving class B the mutable property. A callback is then fired for class A and the if statement re-turnsWhenNext meaning that the cell for class A should receive an update. The third argument of thewhenNext method is the value it should receive on update, which in this case is ShallowImmutable andclass A is given the shallow immutable property. If the callback would return FalsePred then the cellfor class A would not update with a new value.

The third and last step for the plug-in is to print out all the statistics gathered and this is done whenall dependencies between templates have been resolved.

4.1.3 LimitationsThe plug-in described in this section is not designed to handle external or unknown dependencies. Ifthe project analyzed by the plug-in finds a template that depends on some other external template, thenwe have to assume that the immutability property is mutable. This is because we can, in most cases,not know the immutability property of the external dependency. The source code of an external de-pendency might be proprietary and unavailable. This includes Scala code that uses Java classes as well,because these are not compiled by the Scala compiler and therefore never accessed by our plug-in. Inthe case of bytecode analysis, this would not be an issue, because the entire project’s bytecode also in-cludes the code from the external dependencies and can, therefore, be analyzed.

Page 34: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

28 CHAPTER 4. METHODOLOGY

4.1.4 Immutability AssumptionsDue to the limitation of not being able to handle external or unknown dependencies the developedplug-in is by default executing with some assumptions about the immutability of certain templates.The plug-in assume that primitive, crucial and known to be immutable templates are deeply immutablewithout analyzing them. This is to reduce the problem of having unknown external dependencies de-scribed in section 4.1.3. These templates are for example frequently used primitive Scala and Javaclasses such as Int, Boolean but also java.lang.Object that is an immutable class that all classes inheritfrom by default. The class java.lang.Object would not considered to be a part of the analyzed Scalaproject and would be treated as mutable without the assumption, effectively making all templates mu-table because they extend a mutable parent. Instead of considering all unknown templates mutable, afew assumptions about templates that are mutable are also included. These templates are selected withcare, and include, for example, the mutable package of the standard library that are designed to havemutable templates.

The assumptions that are part of the Scala standard library itself are not enabled when analyzing it,because these templates would not be unknown in the scenario of analyzing the library. For all projectsexcept Scala’s standard library, we assume that classes in for example, scala.collection.immutable, aredeeply immutable because the packages is designed to be immutable. The assumptions can be found inmore-detail in the appendix A.2.

4.2 EvaluationTo answer the research questions of this degree project six different small-to-large open-source Scalaprojects are evaluted with the developed compiler plug-in. The following Scala projects and librariesare evaluated:

Scala’s standard library [22] The Scala standard library is included by default with the Scalaprogramming language and consist of approximately 33107 lines of code (excluding blank linesand comments)1. The library have, for example, a math, I/O, concurrency packages (such as fu-tures) and an extensive collection package implemented in both a mutable and immutable version.

Akka’s actor [24] The standard actor implementation for Scala (16910 lines of code).

ScalaTest [25] A very popular testing framework for Scala (39452 lines of code).

Signal/Collect [26] A distributed graph processing framework based on Akka (10159 lines ofcode).

Scala-js [5] A Scala to JavaScript compiler (6500 lines of code).

Scala-fmt [27] A code formatter for Scala (6242 lines of code).

These projects were selected because they are popular, open sourced, do not depend on many thirdparty libraries and are different in sizes (from smaller to larger). All projects, except for Scala’s stan-dard library, require third party libraries.

1Measured using cloc v 1.6 [23]

Page 35: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

Chapter 5

Results

This chapter presents the results of this degree project obtained with the methodology and evaluationdetailed in chapter 4.

5.1 Projects AnalyzedTable 5.1 lists the six different Scala projects that we analyzed with the compiler plug-in and based ourresults on. A short description of each project can be found in section 4.2.

Scala project Project key Version Lines of code [23]Scala’s standard library standard-library 2.11.8 33107Akka’s actor package akka-actor 2.4.17 16910ScalaTest scala-test 3.0.1 39452Signal/Collect signal-collect 8.0.2 10159Scala-js scala-js 0.6.14 6500Scalafmt scala-fmt 0.5.6 6242

Table 5.1: The Scala projects analyzed and the results of this chapter are based on.

The second column of table 5.1 is an assigned “project key” for each project that will from hereon be used to refer to a project. For example, Akka’s actor package has the key akka-actor and willbe referred to as akka-actor. Remember that projects make certain immutability assumptions aboutexternal dependencies as described in 4.1.4.

29

Page 36: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

30 CHAPTER 5. RESULTS

5.2 Template StatisticsWe begin with two figures, 5.1 and 5.2, that provide an overview of each analyzed project of table5.1 showing the number of templates and the distribution of the different template types within eachproject.

Figure 5.1: The number of templates and the distribution of different types within the project forscala-fmt, signal-collect and scala-js.

Figure 5.2: The number of templates and the distribution of different types within the project forakka-aktor, standard-library and scala-test.

Page 37: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

CHAPTER 5. RESULTS 31

Table 5.2 provides the raw data of figure 5.1 and 5.2. It contains the number of analyzed templatesfor each project and template type, including how many of these templates that were unknown. If atemplate is unknown then, as explained in section 4.1.3, it means that we could not read the source of itand we need to assume that the template in turn has the mutable property.

Template scala-js scala-fmt akka-actor scala-test standard-library signal-collectClasses 61 (19,6%) 22 (10,4%) 299 (23,7%) 791 (32,4%) 626 (30,9%) 160 (53,2%)Case classes 92 (29,6%) 56 (26,4%) 206 (16,3%) 153 (6,3%) 75 (3,7%) 42 (14,0%)Anon classes 4 (1,3%) 28 (13,2%) 77 (6,1%) 688 (28,2%) 330 (16,3%) 4 (1,3%)Trait 16 (5,1%) 9 (4,2%) 239 (18,9%) 227 (9,3%) 466 (23,0%) 24 (8,0%)Object 77 (24,8%) 53 (25,0%) 220 (17,4%) 254 (10,4%) 358 (17,7%) 41 (13,6%)Case object 26 (8,4%) 27 (12,7%) 76 (6,0%) 81 (3,3%) 12 (0,6%) 5 (1,7%)Unknown 35 (11,3%) 17 (8,0%) 146 (11,6%) 246 (10,1%) 157 (7,8%) 25 (8,3%)Total 311 (100,0%) 212 (100,0%) 1263 (100,0%) 2440 (100,0%) 2024 (100,0%) 301 (100,0%)

Table 5.2: Gathered statistics of the different templates, including unknown, for each project analyzed.

Table 5.2 shows the gathered statistics about templates that were analyzed for the different projects.The number of templates ranges from 218 (scala-fmt) to 2786 (scala-test), where the seemingly mostpopular templates among the projects are classes and singleton objects. Only one project, signal-collect,have one kind of template with more that 30% occurrences and that are classes that stand for 53.2%of all templates. We also notice that the compiler project, scala-js, or the code formatter, scala-fmt,utilize more case classes than the other projects and we believe that this is due to the fact that these areeasier to pattern match and pattern matching is a methodology that is natural in these type of projects.

For the number of unknown templates akka-actor stands out with a high of 11.6% unknown tem-plates, meaning that all those templates were assumed to be mutable in the analysis. Scala’s standard li-brary, standard-library, had 7.8% unknown templates and was a little higher than expected for us. Ourinitial hypothesis was that it would be lower since it does not have any third-party dependencies like theother projects do. Manual inspection showed that a majority of unknown templates of standard-librarywere Java classes that the plug-in cannot read and analyze.

Page 38: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

32 CHAPTER 5. RESULTS

5.3 Immutability StatisticsIn this section we provide the results of analyzing the Scala projects listed in table 5.1 using the method-ology described in chapter 4. We begin with figure 5.3 that displays the distribution of immutabilityproperties for each analyzed project based on table 5.3.

Figure 5.3: The distribution of the immutability properties for each analyzed project.

Project Mutable Shallow immutable Deeply immutable Conditionally deepscala-js 28 (10,1%) 131 (47,5%) 117 (42,4%) 0 (0%)scala-fmt 40 (20,5%) 58 (29,7%) 97 (49,7%) 0 (0%)akka-actor 204 (18,3%) 229 (20,5%) 586 (52,5%) 98 (8,8%)scala-test 513 (23,4%) 686 (31,3%) 924 (42,1%) 71 (3,2%)scala-compiler 891 (47,7%) 131 (7,0%) 553 (29,6%) 292 (15,6%)signal-collect 111 (40,2%) 41 (14,9%) 54 (19,6%) 70 (25,4%)

Table 5.3: Summarized immutability statistics for each analyzed project.

The following tables, table 5.4, 5.5, 5.6, 5.7, 5.8 and 5.9 are the immutability statistics for eachproject gathered from the implemented immutability analysis. The first column of each table indicatesthe analyzed Scala template and the second column the number of occurrences of each template typein the project. The following columns show the occurrences and percentage of each immutability prop-erty and template type. The last row is the sum of the rows above giving the total number of occur-rences for each template type and immutability property.

Page 39: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

CHAPTER 5. RESULTS 33

Template Occurrences Mutable Shallow Deep Conditionally DeepClass 61 (22,1%) 18 (29,5%) 24 (39,3%) 19 (31,1%) 0 (0%)Case class 92 (33,3%) 0 (0%) 84 (91,3%) 8 (8,7%) 0 (0%)Anonymous class 4 (1,4%) 2 (50,0%) 0 (0%) 2 (50,0%) 0 (0%)Trait 16 (5,8%) 4 (25,0%) 7 (43,8%) 5 (31,3%) 0 (0%)Object 77 (27,9%) 4 (5,2%) 16 (20,8%) 57 (74,0%) 0 (0%)Case object 26 (9,4%) 0 (0%) 0 (0%) 26 (100,0%) 0 (0%)Total 276 (100,0%) 28 (10,1%) 131 (47,5%) 117 (42,4%) 0 (0%)

Table 5.4: scala-js: Immutability statistics.

Template Occurrences Mutable Shallow Deep Conditionally DeepClass 22 (11,3%) 1 (4,5%) 9 (40,9%) 12 (54,5%) 0 (0%)Case class 56 (28,7%) 16 (28,6%) 23 (41,1%) 17 (30,4%) 0 (0%)Anonymous class 28 (14,4%) 23 (82,1%) 1 (3,6%) 4 (14,3%) 0 (0%)Trait 9 (4,6%) 0 (0%) 2 (22,2%) 7 (77,8%) 0 (0%)Object 53 (27,2%) 0 (0%) 17 (32,1%) 36 (67,9%) 0 (0%)Case object 27 (13,8%) 0 (0%) 6 (22,2%) 21 (77,8%) 0 (0%)Total 195 (100,0%) 40 (20,5%) 58 (29,7%) 97 (49,7%) 0 (0%)

Table 5.5: scala-fmt: Immutability statistics.

Template Occurrences Mutable Shallow Deep Conditionally DeepClass 299 (26,8%) 115 (38,5%) 93 (31,1%) 82 (27,4%) 9 (3,0%)Case class 206 (18,4%) 23 (11,2%) 64 (31,1%) 90 (43,7%) 29 (14,1%)Anonymous class 77 (6,9%) 33 (42,9%) 8 (10,4%) 36 (46,8%) 0 (0%)Trait 239 (21,4%) 22 (9,2%) 17 (7,1%) 140 (58,6%) 60 (25,1%)Object 220 (19,7%) 9 (4,1%) 47 (21,4%) 164 (74,5%) 0 (0%)Case object 76 (6,8%) 2 (2,6%) 0 (0%) 74 (97,4%) 0 (0%)Total 1117 (100,0%) 204 (18,3%) 229 (20,5%) 586 (52,5%) 98 (8,8%)

Table 5.6: akka-actor: Immutability statistics.

Page 40: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

34 CHAPTER 5. RESULTS

Template Occurrences Mutable Shallow Deep Conditionally DeepClass 791 (36,1%) 216 (27,3%) 249 (31,5%) 288 (36,4%) 38 (4,8%)Case class 153 (7,0%) 15 (9,8%) 81 (52,9%) 54 (35,3%) 3 (2,0%)Anonymous class 688 (31,4%) 200 (29,1%) 293 (42,6%) 195 (28,3%) 0 (0%)Trait 227 (10,3%) 61 (26,9%) 45 (19,8%) 91 (40,1%) 30 (13,2%)Object 254 (11,6%) 19 (7,5%) 18 (7,1%) 217 (85,4%) 0 (0%)Case object 81 (3,7%) 2 (2,5%) 0 (0%) 79 (97,5%) 0 (0%)Total 2194 (100,0%) 513 (23,4%) 686 (31,3%) 924 (42,1%) 71 (3,2%)

Table 5.7: scala-test: Immutability statistics.

Template Occurrences Mutable Shallow Deep Conditionally DeepClass 626 (33,5%) 330 (52,7%) 54 (8,6%) 124 (19,8%) 118 (18,8%)Case class 75 (4,0%) 19 (25,3%) 7 (9,3%) 9 (12,0%) 40 (53,3%)Anonymous class 330 (17,7%) 209 (63,3%) 26 (7,9%) 95 (28,8%) 0 (0%)Trait 466 (25,0%) 224 (48,1%) 15 (3,2%) 93 (20,0%) 134 (28,8%)Object 358 (19,2%) 106 (29,6%) 29 (8,1%) 223 (62,3%) 0 (0%)Case object 12 (0,6%) 3 (25,0%) 0 (0%) 9 (75,0%) 0 (0%)Total 1867 (100,0%) 891 (47,7%) 131 (7,0%) 553 (29,6%) 292 (15,6%)

Table 5.8: standard-library: Immutability statistics.

Template Occurrences Mutable Shallow Deep Conditionally DeepClass 160 (58,0%) 78 (48,8%) 24 (15,0%) 14 (8,8%) 44 (27,5%)Case class 42 (15,2%) 4 (9,5%) 11 (26,2%) 15 (35,7%) 12 (28,6%)Anonymous class 4 (1,4%) 4 (100,0%) 0 (0%) 0 (0%) 0 (0%)Trait 24 (8,7%) 6 (25,0%) 1 (4,2%) 3 (12,5%) 14 (58,3%)Object 41 (14,9%) 19 (46,3%) 5 (12,2%) 17 (41,5%) 0 (0%)Case object 5 (1,8%) 0 (0%) 0 (0%) 5 (100,0%) 0 (0%)Total 276 (100,0%) 111 (40,2%) 41 (14,9%) 54 (19,6%) 70 (25,4%)

Table 5.9: signal-collect: Immutability statistics.

Page 41: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

CHAPTER 5. RESULTS 35

The most important insight given from the tables 5.4, 5.5, 5.6, 5.7, 5.9 and 5.8 is that a majorityof templates of the projects do not have the mutable property and are instead either shallow immutable,deeply immutable or conditionally deeply immutable. This means that most templates satisfy one of im-mutability properties and a reasonable explanation could be that the functional programming style ofScala leads to higher immutability usage. To verify that claim one would have to do the same analy-sis and compare functional and none-functional programming languages. We can, however, say thatat least half of the templates have an immutability property and there could be more because everyproject had an amount of unknown templates that we assume to be mutable (that could instead have animmutability property).

More specifically, the two projects with the lowest number of templates that is mutable are scala-jswith 10.1% (table 5.4) and akka-actor with 18.3% (table 5.6). The other projects all had more than20% of their templates as mutable, scala-fmt with 20.5% (table 5.5), scala-test with 23.4% (table 5.7),signal-collect with 40.2% (table 5.9) and scala-standard-library with 47.7% (table 5.8). We can seethat the lowest percentage 10.1% is significantly lower compared to the highest 47.7%. The fact thatthe standard library has a higher degree of mutable templates could be because of performance rea-sons. It uses mutability internally to optimize efficiency, something that is needed when it is widelyused in many applications. Our analysis penalizes the mutability even if it could be abstract immutabil-ity and mutate in a none-observable manner for the user.

Looking at the different templates types we see that their immutability property varies betweenthe projects. The types case object and object are, however, throughout the projects more frequentlydeeply immutable, where all case objects were above 70% deeply immutable. An exception for object isthe project signal-collect that had a high degree of mutable objects (46.3%). For projects that had tem-plates with the conditionally deeply immutable property, we see that this was the least common propertyand that the template type trait is most frequently used (the types object and anonymous class cannothave this property because they lack type parameters).

Page 42: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

36 CHAPTER 5. RESULTS

5.4 Immutability AttributesThe previous section 5.3 showed gathered immutability statistics for each project. In this section weexplore the reasons for the mutable and shallow immutable statistics. As described in chapter 4 weassign the deeply immutable property to a template until we find a reason not to, and if the templatetype has any type parameters, we assign it to be conditionally deeply immutable. The ten different im-mutability attributes listed in table 5.10 give a reason to why a template was given the immutabilityproperty mutable or shallow immutable. Each reason is associated with an “attribute” and the corre-sponding property.

Reason Immutability property AttributeParent type mutable (assumption) mutable AParent type mutable mutable Bvar field (public) mutable Cvar field (private) mutable DParent type unknown mutable EParent type shallow immutable shallow immutable Fval field refers to unknown type shallow immutable Gval field refers to mutable type shallow immutable Hval field refers to mutable type (assumption) shallow immutable Ival field refers to shallow type shallow immutable J

Table 5.10: Reasons for the assigned immutability property immutable defined by an attribute.

If the immutability plug-in encounters one of the first five attributes (A to E) when analyzing atemplate it would assign the mutable property to it. For example, if the template had a parent that wasmutable then attribute B would hold and be assigned the mutable property. The other attributes in thelist are reasons for shallow immutable, for example, if a parent is shallow immutable (attribute F), thenthe analyzed template cannot be deeply immutable or conditionally deeply immutable. Each attribute iscounted once per template type. For example, a class with multiple parents that are mutable (attributeB) would only count as one occurrence of having attribute B. If that template also has one or more varfields (attribute C) we count that template as having both attribute B and C.

Figure 5.4, 5.5, 5.6, 5.7, 5.8 and 5.9 shows the distribution of each attribute for the larger projectsakka-actor, scala-test and standard-library. All templates that have more than one attribute are clas-sified as “Combination” in the figures. For example, a template with attribute B and C, and anothertemplate with B and D in the same project are boh part of “Combination” in the figure. Immutabil-ity attributes for the projects signal-collect, scala-js and scala-fmt can be found in the appendix A.3together with tables providing more detailed statistics for each project, all attribute combinations areomitted in the figures but are displayed in the appendix tables.

Page 43: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

CHAPTER 5. RESULTS 37

Figure 5.4: akka-actor: attributes causingmutable.

Figure 5.5: akka-actor: attributes causingshallow.

Figure 5.6: scala-test: attributes causingmutable.

Figure 5.7: scala-test: attributes causingshallow.

Figure 5.8: standard-library: attributes caus-ing mutable.

Figure 5.9: standard-library: attributes caus-ing shallow.

Page 44: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

38 CHAPTER 5. RESULTS

For the attributes that cause mutable, we see that “Parent type unknown” (attribute E) alone standsfor 35.3% of the cases for akka-actor (figure 5.4), 53.6% for scala-test (figure 5.6) and 7.4% for standard-library (figure 5.8). For standard-library with the lowest rate of attribute E, the most common attributeis having a parent that is mutable (attribute B) that stand for 68.4% of the attributes causing mutable(figure 5.8). Attribute B is also frequent in both akka-actor and scala-test. This indicates that inheri-tance is an important factor when it comes to the immutability of a template. Another interesting andimportant property causing mutable is private reassignable fields (attribute D), which may indicate thatthese templates are abstract immutable and mutate in a none-visible manner.

The most common reasons for shallow immutable are: the parent of the template were shallow im-mutable (attribute F), the existence of a non-reassignable field referring to a mutable (attribute H) or anunknown (attribute G) type. These attributes are more spread out within the projects compared to theattributes causing mutable where attribute E was dominant. Attribute F were most frequent (43.3%,figure 5.7) for scala-test, attribute G for akka-aktor (41.0%, figure 5.7) and attribute H (30.5%, figure5.9) standard-library.

Page 45: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

CHAPTER 5. RESULTS 39

5.5 Conditional Deep ImmutabilityIf a template type is deeply immutable and depends on a type parameter, we call it conditionally deeplyimmutable. The following section contains statistics on how mutable or shallow immutable templatesare used with a template that is conditionally deeply immutable. We have identified two cases for wherethis can happen:

Case A: If a template extends a conditionally deeply immutable template and uses a mutable orshallow type as its type argument.

Case B: Same as case A, but instead of extending a template, it uses the template on a field with amutable or shallow type as its type argument.

The following tables 5.11, 5.12, 5.13 and 5.14 show gathered occurrences of these two cases forthe analyzed projects. The projects scala-js, scala-fmt and signal-collect had no occurrences of condi-tionally immutable templates being used this way. As we can see in tables 5.5 and 5.4, scala-fmt andscala-js did in fact not have a single template that was conditionally deeply immutable. Omitted tables,for example, case B for akka-actor means that there were none found and only case A was observed.

Page 46: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

40 CHAPTER 5. RESULTS

Template Occurrences Mutable ShallowClass 6 (24,0%) 6 (100,0%) 0 (0%)Case class 11 (44,0%) 6 (54,5%) 5 (45,5%)Object 8 (32,0%) 0 (0%) 8 (100,0%)Total 25 (100,0%) 12 (48,0%) 13 (52,0%)

Table 5.11: akka-actor: case A

Template Occurrences Mutable ShallowClass 3 (50,0%) 1 (33,3%) 2 (66,7%)Anonymous class 3 (50,0%) 1 (33,3%) 2 (66,7%)Total 6 (100,0%) 2 (33,3%) 4 (66,7%)

Table 5.12: scala-test: case A

Template Occurrences Mutable Shallow Conditionally DeepClass 39 (19,9%) 36 (92,3%) 0 (0%) 3 (7,7%)Anonymous class 19 (9,7%) 17 (89,5%) 2 (10,5%) 0 (0%)Trait 53 (27,0%) 53 (100,0%) 0 (0%) 0 (0%)Object 85 (43,4%) 85 (100,0%) 0 (0%) 0 (0%)Total 196 (100,0%) 191 (97,4%) 2 (1,0%) 3 (1,5%)

Table 5.13: standard-library: case A

Template Occurrences Mutable ShallowClass 6 (40,0%) 5 (83,3%) 1 (16,7%)Case class 0 (0%) 0 (0%) 0 (0%)Anonymous class 7 (46,7%) 1 (14,3%) 6 (85,7%)Trait 1 (6,7%) 1 (100,0%) 0 (0%)Object 1 (6,7%) 0 (0%) 1 (100,0%)Total 15 (100,0%) 9 (60,0%) 6 (40,0%)

Table 5.14: standard-library: case B

Case A was apparent for three of the largest projects and perhaps surprisingly, only standard-library had occurrences of case A and B. In the results, we see that this behavior is most frequent forstandard-library and there are very few occurrences for both akka-actor and scala-test. The standardlibrary with 2024 templates had occurrences of case A in 9.68% of all templates. If it this was moreprevalent then one could argue that developers need more help in knowing if a type is immutable ornot, for example, by the type system.

Page 47: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

Chapter 6

Discussion

This chapter begins with a discussion and interpretation of the gathered results from chapter 5 in con-text of the project’s goal. Future work that is deemed relevant and limitations of the project are alsodiscussed, followed by conclusions for the project’s research questions listed in section 1.2.

6.1 The Empirical StudyFrom the results gathered and listed in chapter 5, we can see that immutability statistics vary betweenthe different projects analyzed. The aim of the empirical study and the gathered results was to try andfind answers to the research questions listed in section 1.2. In the scope of this project, we believe thatthe most important results are present in order for the questions to be answered. However, besides theresults given in chapter 5, we noticed that more data about immutability can be generated by our im-plemented tool.

The number of unknown templates is surprisingly low for many of the projects and the initial hy-pothesis was that the dependencies unreachable from our analysis would be higher. The akka-actorproject stands out with a high of 11.6% unknown templates, meaning that all those templates were as-sumed to be mutable in the analysis. Scala’s standard library, standard-library, had 7.8% unknowntemplates which was higher than expected and our theory was that it would be lower because it doesnot have any third-party dependencies like the other projects do. However, manual inspection showedthat the majority of unknown templates of the standard-library were Java classes that the plug-in can-not read and analyze. The presence of unknown templates are unfortunate and it is hard to know ex-actly how much these affect the results. In a bad scenario, many templates would depend on one fre-quently used unknown template and these would all be classified as mutable or shallow immutable in-creasing these numbers. However, we think the results are interesting despite this fact and we can saythat there can potentially be a lot more templates with the immutability properties.

Furthermore, we found that the major reason for a template being mutable is “Parent type un-known” (attribute E). If we look at the distribution of reasons for mutable, using the data found in theappendix A.3, we find that attribute E stand for 8.6% of standard-library, 39.7% of akka-actor and64.5% of scala-test, out of all mutable reasons. This make scala-test have the highest degree of mutablecaused by unknown templates, but interestingly still only have 23.4% of all templates as mutable shownin table 5.7, consequently showing that the unknowns did not have a significant impact on immutabilityin this case. The results also indicate that inheritance is an important factor when it comes to the im-mutability of a template. This indication could, however, also be due to one frequently used unknowntemplate (as previously mentioned). For example, if a commonly used templates has a parent that isunknown then this templates would become mutable and in return all templates that inherit from this

41

Page 48: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

42 CHAPTER 6. DISCUSSION

template would be become mutable. We cannot verify this with the data we have today, moreover, thesame scenario could happen even if the template was not an unknown but actually mutable in the firstplace.

Subsequently, a good reason for using deeply immutable data is that you know for a fact that oncedata is created, it cannot change. An interesting aspect is when deeply immutable data are mixed to-gether with mutable data. This can, of course, be by design, but it is also likely to be the cause of amistake. Using deeply immutable data on, for example, a deeply immutable data structure, can lead tothe wrong assumption that data in the structure cannot change. Because of the implementation of ouranalysis and that we assume unknown templates to be mutable we cannot be sure that the type argu-ment is in fact truly mutable. The analysis and the obtained results did unfortunately not consider ifthe type argument was mutable because of an unknown template. This behavior was nevertheless onlyfound in three out of five projects and with very few occurrences. As this behavior rarely happened ordid not occur at all for the smaller projects, it does not seem to be an issue.

6.2 Future WorkThere are a lot of interesting topics to be explored in the area of immutability and some of which canbe expanded upon the work presented in this project. The major issue with the type of analysis con-ducted in this project is the fact that all source code must be available, something that may not be thecase for certain projects. A natural extension to our solution and this project would be to solve this is-sue. Combining both source code and bytecode analysis could, for example, be an interesting way ofhandling it. It would also be interesting to compare source code to bytecode analysis on a larger scaleand see how much they differ in detecting immutability. The combination of dynamic and static analy-sis might also be an area worth exploring to yield improvements.

Furthermore, the analyzed projects in this study are open-sourced, possibly developed by severalpeople and considered popular, meaning that one can argue that they follow Scala conventions and bestpractices carefully. It would, therefore, be meaningful to analyze more projects, or other languages witha similar immutability features, to see if new insights can be found.

To put immutability usage of real-world code into perspective, future work could be done in mea-suring immutability usage and, for example, the technical debt of programs in practice. Such as a studywould give useful insights in many aspects since immutability is considered and said to ease reasoningabout programs. For example, how cost-effective is to spend time and effort on ensuring immutabilityduring the development of a program.

Moreover, related to real-world code, it is clear that more research can be done into exploring howimmutability is used in different languages. As we have seen in chapter 3, there are type systems thatguarantee immutability, but not much data on how these are used or if they are used in practice. Howdoes having built-in support for deep immutability affect the programmer, for example, what kind ofcompiler optimizations can be utilized or are there any useful documentation advantages?

A final and important related area is to analyze abstract immutability which is lacking from theanalysis provided in this project. Abstract immutability is an interesting concept, and we do not knowhow many of the shallow immutable or mutable templates are in fact abstract immutable or not in ouranalysis. There are many use cases of abstract immutability and supporting it in the analysis wouldmost likely improve the results of it.

Page 49: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

CHAPTER 6. DISCUSSION 43

6.3 ConclusionIn this thesis, a novel immutability analysis of Scala source code is presented together with previouslyconducted immutability research. We evaluated templates of six small-to-large open-source Scalaprojects on three different immutability properties, shallow immutable, deeply immutable and condi-tionally deeply immutable all of which occurred frequently in our analysis. The analysis shows, evenwhen assuming mutability to a large extent, that the majority of all templates for each project satis-fies an immutability property. Mutability was found to be lower for templates such as case classes andsingleton objects, that can be seen as intended by the Scala designers, indicating that these type of ab-stractions help programmers with utilizing immutability.

To summarize and answer our Research Questions (RQs):

RQ1 How can a simple immutability analysis be defined and implemented in Scala? What are theneeded immutability properties?

We defined and implemented a simple immutability analysis and explained it in detail in chapter4, the immutability properties are shallow immutable, deeply immutable and conditionally deeplyimmutable.

RQ2 Using an implementation of the defined immutability analysis, how frequent is each immutabilityproperty for the different templates?

The majority of templates of the projects are either shallow immutable, deeply immutable or con-ditionally deeply immutable, i.e., they were not mutable. Because every project had unreachable(unknown) templates that were assumed to be mutable, there could potentially be more templatesthat have an immutability property. The results varied between the projects and the templatetypes trait and object were throughout the projects more frequently deeply immutable.

RQ3 What are the reasons to why stronger immutability properties are not satisfied?

From the results we conclude that inheritance is an important factor when it comes to the im-mutability of a template, both inheriting the mutable or shallow immutable property. Many tem-plates that were classified as mutable had a private reassignable field indicating that they maybe abstract immutable and mutate in a none-observable manner, for example, used to cache im-mutable data. Moreover, a large percentage of the reasons for being shallow immutable is thatnone-reassignable fields refers to an unknown template meaning that the percentage of deeplyimmutable could be higher.

RQ4 How often are types that are mutable or have a weaker immutability property used on templateswhose immutability is conditional?

We defined two cases of how this could happen, one case by inheritance and the other usingfields, and the case of inheritance had a few occurrences only in three of the largest projects ana-lyzed. Only the Scala standard library had occurrences of both the first and second case, but onlyon a small percentage of the templates. We consider it a mistake to use a conditional templatewith a mutable or shallow immutable type, and because it rarely happened or did not occur at allfor the smaller projects, this does not seem to be a widespread issue. These results are, however,unfortunately not very reliable because we assume that unknown templates are mutable.

We believe that this type of research is valuable for programming language design, both for newand old languages and there is more future work and improvements that can be done. The insightsgained from our results suggest that combining functional and imperative features in a language, suchas Scala, leads to a high degree of immutability usage without much help from the language itself.

Page 50: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

Glossary

AST An abstract syntax tree (AST) is a tree representation of a program’s source code first.

JVM The Java Virtual Machine, or JVM runtime, that hosts a running Scala program..

RQ A research question this project will aim to answer.

template Following the terminology of the Scala language specification, a template refers to aclass, case class, trait, object, or case object definition.

44

Page 51: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

Bibliography

[1] Martin Odersky, Lex Spoon, and Bill Venners. Programming in Scala: Updated for Scala 2.12.Artima Incorporation, USA, 3rd edition, 2016. ISBN 0981531687, 9780981531687.

[2] Martin Odersky, Philippe Altherr, Vincent Cremet, Gilles Dubochet, Burak Emir, PhilippHaller, Stéphane Micheloud, Nikolay Mihaylov, Adriaan Moors, Lukas Rytz, Michel Schinz,Erik Stenman, and Matthias Zenger. The Scala language specification version 2.11. http:

//www.scala-lang.org/files/archive/spec/2.11/, April 2014. URLhttp://www.scala-lang.org/files/archive/spec/2.11/.

[3] Alex Potanin, Johan Östlund, Yoav Zibin, and Michael D. Ernst. Immutability. In Alias-ing in Object-Oriented Programming. Types, Analysis and Verification, pages 233–269.2013. doi: 10.1007/978-3-642-36946-9_9. URL http://dx.doi.org/10.1007/978-3-642-36946-9_9.

[4] Michael Coblenz, Joshua Sunshine, Jonathan Aldrich, Brad Myers, Sam Weber, and ForrestShull. Exploring Language Support for Immutability. In Proceedings of the 38th Interna-tional Conference on Software Engineering, ICSE ’16, pages 736–747, New York, NY, USA,2016. ACM. ISBN 978-1-4503-3900-1. doi: 10.1145/2884781.2884798. URL http://doi.acm.org/10.1145/2884781.2884798.

[5] Scala.js - the Scala to JavaScript compiler. Version 0.6.14, May 2017. URL https://www.scala-js.org/.

[6] Denys Shabalin. Scala Native. An optimising ahead-of-time compiler for Scala built on top of theLLVM compiler infrastructure, May 2017. URL http://www.scala-native.org/.

[7] Benjamin C. Pierce. Types and Programming Languages. The MIT Press, 1st edition, 2002.ISBN 0262162091, 9780262162098.

[8] Unified Types. May 2017. URL http://docs.scala-lang.org/tutorials/tour/unified-types.html.

[9] J. Hughes. Why Functional Programming Matters. Comput. J., 32(2):98–107, April 1989.ISSN 0010-4620. doi: 10.1093/comjnl/32.2.98. URL http://dx.doi.org/10.1093/comjnl/32.2.98.

[10] Joshua Bloch. Effective Java (2Nd Edition) (The Java Series). Prentice Hall PTR, Upper SaddleRiver, NJ, USA, 2 edition, 2008. ISBN 0321356683, 9780321356680.

[11] Adrian Birka and Michael D. Ernst. A Practical Type System and Language for Reference Im-mutability. SIGPLAN Not., 39(10):35–49, October 2004. ISSN 0362-1340. doi: 10.1145/1035292.1028980. URL http://doi.acm.org/10.1145/1035292.1028980.

45

Page 52: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

46 BIBLIOGRAPHY

[12] Tim Sheard. Accomplishments and Research Challenges in Meta-programming, pages 2–44.Springer Berlin Heidelberg, Berlin, Heidelberg, 2001. ISBN 978-3-540-44806-8. doi: 10.1007/3-540-44806-3_2. URL http://dx.doi.org/10.1007/3-540-44806-3_2.

[13] Jaime Quinonez, Matthew S. Tschantz, and Michael D. Ernst. Inference of Reference Im-mutability. In Proceedings of the 22Nd European Conference on Object-Oriented Programming,ECOOP ’08, pages 616–641, Berlin, Heidelberg, 2008. Springer-Verlag. ISBN 978-3-540-70591-8. doi: 10.1007/978-3-540-70592-5_26. URL http://dx.doi.org/10.1007/978-3-540-70592-5_26.

[14] Yoav Zibin, Alex Potanin, Mahmood Ali, Shay Artzi, Adam Kie, un, and Michael D. Ernst.Object and Reference Immutability Using Java Generics. In Proceedings of the the 6th JointMeeting of the European Software Engineering Conference and the ACM SIGSOFT Symposiumon The Foundations of Software Engineering, ESEC-FSE ’07, pages 75–84, New York, NY,USA, 2007. ACM. ISBN 978-1-59593-811-4. doi: 10.1145/1287624.1287637. URLhttp://doi.acm.org/10.1145/1287624.1287637.

[15] Colin S. Gordon, Matthew J. Parkinson, Jared Parsons, Aleks Bromfield, and Joe Duffy. Unique-ness and Reference Immutability for Safe Parallelism. SIGPLAN Not., 47(10):21–40, October2012. ISSN 0362-1340. doi: 10.1145/2398857.2384619. URL http://doi.acm.org/10.1145/2398857.2384619.

[16] Igor Pechtchanski and Vivek Sarkar. Immutability Specification and Its Applications. In Pro-ceedings of the 2002 Joint ACM-ISCOPE Conference on Java Grande, JGI ’02, pages 202–211,New York, NY, USA, 2002. ACM. ISBN 1-58113-599-8. doi: 10.1145/583810.583833. URLhttp://doi.acm.org/10.1145/583810.583833.

[17] Michael Eichberg and Ben Hermann. A Software Product Line for Static Analyses: The OPALFramework. In Proceedings of the 3rd ACM SIGPLAN International Workshop on the State of theArt in Java Program Analysis, SOAP ’14, pages 1–6, New York, NY, USA, 2014. ACM. ISBN978-1-4503-2919-4. doi: 10.1145/2614628.2614630. URL http://doi.acm.org/10.1145/2614628.2614630.

[18] Jon Eyolfson and Patrick Lam. C++ const and Immutability: An Empirical Study of Writes-Through-const. In Shriram Krishnamurthi and Benjamin S. Lerner, editors, 30th EuropeanConference on Object-Oriented Programming (ECOOP 2016), volume 56 of Leibniz InternationalProceedings in Informatics (LIPIcs), pages 8:1–8:25, Dagstuhl, Germany, 2016. Schloss Dagstuhl–Leibniz-Zentrum fuer Informatik. ISBN 978-3-95977-014-9. doi: http://dx.doi.org/10.4230/LIPIcs.ECOOP.2016.8. URL http://drops.dagstuhl.de/opus/volltexte/2016/6102.

[19] Fredrik Kjolstad, Danny Dig, Gabriel Acevedo, and Marc Snir. Transformation for Class Im-mutability. In Proceedings of the 33rd International Conference on Software Engineering, ICSE’11, pages 61–70, New York, NY, USA, 2011. ACM. ISBN 978-1-4503-0445-0. doi: 10.1145/1985793.1985803. URL http://doi.acm.org/10.1145/1985793.1985803.

[20] Graham Allan. Mutability Detector. May 2017. URL http://mutabilitydetector.org/.

Page 53: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

BIBLIOGRAPHY 47

[21] Philipp Haller, Simon Geries, Michael Eichberg, and Guido Salvaneschi. Reactive Async: Ex-pressive Deterministic Concurrency. In Proceedings of the 2016 7th ACM SIGPLAN Sympo-sium on Scala, SCALA 2016, pages 11–20, New York, NY, USA, 2016. ACM. ISBN 978-1-4503-4648-1. doi: 10.1145/2998392.2998396. URL http://doi.acm.org/10.1145/2998392.2998396.

[22] Scala’s standard library. Version 2.11.8, May 2017. URL http://www.scala-lang.org/api/2.11.8.

[23] AlDanial. Cloc: Count Lines of Code. Version 1.6, May 2017. URL https://github.com/AlDanial/cloc.

[24] Akka’s actor - the standard Actor implementation for Scala. Version 2.4.17, May 2017. URLhttp://akka.io/.

[25] ScalaTest - A testing framework for Scala. Version 3.0.1, May 2017. URL http://www.scalatest.org/.

[26] Signal/collect - a distributed graph processing framework based on Akka. Version 8.0.2, May2017. URL http://uzh.github.io/signal-collect/.

[27] Ólafur Páll Geirsson. Scala-fmt - a code formatter for scala. Version 0.5.6, May 2017. URLhttp://www.scalafmt.org.

Page 54: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

Appendix A

Source Code and Data

A.1 The Analysis ProgramThe analysis and compiler plug-in developed for this project can be found at:

https://github.com/luax/scala-immutability-plugin

Instructions on how to use the analysis and reproduce the results can also be found there.

A.2 Immutability AssumptionsThe different immutability assumptions can be found in the project file Assumptions.scala at the path/plugin/src/main/scala/immutability/Assumptions.scala, or by following this link:

https://github.com/luax/scala-immutability-plugin/blob/

88ef151fd82572ae7cc16022a0db57a3d93599ff/plugin/src/main/scala/

immutability/Assumptions.scalaa

Some of the assumptions for deeply immutable that were used on all projects are, for example:

• java.io.Serializable

• java.lang.Class

• java.lang.Comparable

• java.lang.Error

• java.lang.Exception

• java.lang.Object

• java.lang.String

• java.lang.Throwable

• scala.Any

• scala.AnyVal

• scala.Boolean

• scala.Byte

• scala.Char

• scala.Double

• scala.Float

• scala.Int

• scala.Long

• scala.None

• scala.Nothing

• scala.Null

• scala.Option

• scala.Product

• scala.Serializable

• scala.Some

48

Page 55: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

APPENDIX A. SOURCE CODE AND DATA 49

We also assumed these classes to be mutable when not analyzing the standard library project:

• scala.collection.BufferedIterator

• scala.collection.IndexedSeq

• scala.collection.Iterable

• scala.collection.Iterator

• scala.collection.Seq

• scala.collection.Traversable

• scala.collection.TraversableOnce

• scala.collection.mutable.*

• scala.collection.parallel.mutable.*

The classes that were in fact used in the analysis of the mutable package were:

• scala.collection.mutable.ArrayBuffer

• scala.collection.mutable.Builder

• scala.collection.mutable.ListBuffer

• scala.collection.mutable.Map

• scala.collection.mutable.Set

• scala.collection.mutable.SynchronizedBuffer

• scala.collection.parallel.mutable.ParArray

The assumptions starting with the word scala are templates of Scala and those starting with java areJava classes.

Page 56: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

50 APPENDIX A. SOURCE CODE AND DATA

A.3 Immutability Attributes

Reason Immutability property AttributeParent type mutable (assumption) mutable AParent type mutable mutable Bvar field (public) mutable Cvar field (private) mutable DParent type unknown mutable EParent type shallow immutable shallow immutable Fval field refers to unknown type shallow immutable Gval field refers to mutable type shallow immutable Hval field refers to mutable type (assumption) shallow immutable Ival field refers to shallow type shallow immutable J

Table A.1: Reasons for the assigned immutability property immutable defined by an attribute.

Table A.2, A.3, A.4, A.5, A.6 and A.7 indicate how many occurrences of each attribute per projectwas found. The sum of all occurrences are therefore the total number of mutable or shallow immutabletemplate types found in the appropriate table of section 5.3, for example, table 5.8 for the Scala stan-dard library.

Page 57: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

APPENDIX A. SOURCE CODE AND DATA 51

Attribute(s) OccurrencesA 3 (1,5%)A B D 1 (0,5%)A E 1 (0,5%)B 76 (37,3%)B C 3 (1,5%)B C D 1 (0,5%)B D 6 (2,9%)B E 6 (2,9%)C 7 (3,4%)C D 2 (1,0%)C D E 1 (0,5%)D 24 (11,8%)D E 1 (0,5%)E 72 (35,3%)

Table A.2: akka-actor: attributes causingmutable.

Attribute(s) OccurrencesF 38 (16,6%)F G 9 (3,9%)F G H 2 (0,9%)F G J 3 (1,3%)F H 3 (1,3%)F J 3 (1,3%)G 94 (41,0%)G H 8 (3,5%)G H I 1 (0,4%)G H J 1 (0,4%)G J 16 (7,0%)H 22 (9,6%)H J 4 (1,7%)J 25 (10,9%)

Table A.3: akka-actor: attributes causingshallow immutable.

Attribute(s) OccurrencesA 10 (1,9%)A B E 22 (4,3%)A D 1 (0,2%)B 120 (23,4%)B D 3 (0,6%)B D E 1 (0,2%)B E 26 (5,1%)C 13 (2,5%)C E 1 (0,2%)D 35 (6,8%)D E 6 (1,2%)E 275 (53,6%)

Table A.4: scala-test: attributes causingmutable.

Attribute(s) OccurrencesF 297 (43,3%)F G 10 (1,5%)F G H 1 (0,1%)F G H I 1 (0,1%)F G H I J 2 (0,3%)F G J 10 (1,5%)F H 2 (0,3%)F H J 15 (2,2%)F J 3 (0,4%)G 198 (28,9%)G H 2 (0,3%)G H I 1 (0,1%)G H J 6 (0,9%)G I 14 (2,0%)G J 2 (0,3%)H 20 (2,9%)H I 1 (0,1%)H J 21 (3,1%)I 43 (6,3%)I J 5 (0,7%)J 32 (4,7%)

Table A.5: scala-test: attributes causingshallow immutable.

Page 58: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

52 APPENDIX A. SOURCE CODE AND DATA

Attribute(s) OccurrencesB 609 (68,4%)B C 71 (8,0%)B C D 1 (0,1%)B D 19 (2,1%)B E 7 (0,8%)C 26 (2,9%)C D 1 (0,1%)D 87 (9,8%)D E 4 (0,4%)E 66 (7,4%)

Table A.6: standard-library: attributes caus-ing mutable.

Attribute(s) OccurrencesF 28 (21,4%)F G 5 (3,8%)F G J 1 (0,8%)F H 4 (3,1%)F J 6 (4,6%)G 21 (16,0%)G H 8 (6,1%)G H J 2 (1,5%)G J 3 (2,3%)H 43 (32,8%)H J 3 (2,3%)J 7 (5,3%)

Table A.7: standard-library: attributes caus-ing shallow immutable.

Attribute(s) OccurrencesA 5 (4,5%)A C 3 (2,7%)B 25 (22,5%)B C 6 (5,4%)B C D 1 (0,9%)B C D E 1 (0,9%)B D 2 (1,8%)C 26 (23,4%)C D 3 (2,7%)C D E 1 (0,9%)C E 5 (4,5%)D 3 (2,7%)E 30 (27,0%)

Table A.8: signal-collect: attributes causingshallow immutable.

Attribute(s) OccurrencesF 2 (4,9%)F H 1 (2,4%)G 18 (43,9%)G H 2 (4,9%)G H I J 1 (2,4%)G H J 1 (2,4%)G I 1 (2,4%)G J 2 (4,9%)H 8 (19,5%)H J 1 (2,4%)J 4 (9,8%)

Table A.9: signal-collect: attributes causingshallow immutable.

Page 59: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

APPENDIX A. SOURCE CODE AND DATA 53

Attribute(s) OccurrencesB E 16 (40,0%)C 1 (2,5%)E 23 (57,5%)

Table A.10: scala-fmt: attributes causingmutable.

Attribute(s) OccurrencesF 8 (13,8%)F G 1 (1,7%)F J 1 (1,7%)G 19 (32,8%)G H 2 (3,4%)G H I 1 (1,7%)G H I J 1 (1,7%)G H J 1 (1,7%)G I 2 (3,4%)G J 5 (8,6%)H 5 (8,6%)I J 2 (3,4%)J 10 (17,2%)

Table A.11: scala-fmt: attributes causingshallow immutable.

Attribute(s) OccurrencesA 1 (3,6%)B 5 (17,9%)C 2 (7,1%)D 4 (14,3%)D E 2 (7,1%)E 14 (50,0%)

Table A.12: scala-js: attributes causing muta-ble.

Attribute(s) OccurrencesF 3 (2,3%)F G 1 (0,8%)G 39 (29,8%)G H 1 (0,8%)G H I 1 (0,8%)G I 2 (1,5%)H 4 (3,1%)I 1 (0,8%)J 79 (60,3%)

Table A.13: scala-js: attributes causing shal-low immutable.

Page 60: Immutability: An Empirical Study in Scala1150007/... · 2017-07-05 · degree project in computer science and engineering, second cycle, 30 credits stockholm , sweden 2017 immutability:

www.kth.se