社団法人 電子情報通信学会
THE INSTITUTE OF ELECTRONICS,
INFORMATION AND COMMUNICATION ENGINEERS

信学技報
TECHNICAL REPORT OF IEICE.

Identifying Cross-Function Side Eﬀects using Static Analysis
Jiachen YANG† , Keisuke HOTTA† , Yoshiki HIGO† , and Shinji KUSUMOTO†† Graduate School of Information Science and Technology, Osaka University, 1-5, Yamadaoka, Suita-shi,
Osaka, 565-0871, Japan
E-mail: †{jc-yang,k-hotta,higo,kusumoto}@ist.osaka-u.ac.jp
Abstract Side eﬀects are modifications done to the state of the objects in Object-Oriented Programming languages such as Java. Side eﬀects can happen across the boundary of the functions, therefore they are important
properties that often be neglected by the documentations. In this paper, we studied the side eﬀects of functions byusing a static analysis method to automatically infer the state dependencies for the return value and side eﬀects offunctions. We also present a set of annotations to document these state dependencies. As a result, the annotations
presented in this paper reveals well-defined state interactions between objects. These annotations can be used infurther investigations by both programmers and tools. We have implemented the analysis method targeting Java
bytecode and tested it on vary-sized open source Java software libraries. From our experimental results, we foundthat 25–33% of the functions in the evaluated open source Java libraries are pure functions, which indicates that alarge percentage of the functions is suitable for high level refactoring. And we present a case study of equals andhashCode functions to show the importance of our method in real world programming tasks.
Key words state boundary, state dependency, object-oriented, eﬀect annotation, static analysis

1. Introduction
It is diﬃcult for programmers to use software components•

An approach to automatically infer eﬀect annotations,as well as a concrete implementation for Java bytecode.
•

A set of function annotations that document the de-without fully understanding their behavior. The documen-tails of eﬀects such as return value dependencies or variabletation and naming of these components usually focuses onstate modifications, for programmers to understand the ef-

intent, i.e., what the functions are required to do, but fails

fects.

to illustrate their side eﬀects, i.e., how these functions ac-•

Experiments on well-known open source software li-

complish their task [1]. Because of the possible side eﬀects

braries with varies size of code bases. In our experiments,in API libraries, it is hard to reuse the modularized com-

we observed modifier functions that should be pure, revealing

ponents. In addition, undocumented API side eﬀects may

tricks or potential bugs in the implementation.

be changed during software maintenance, making debugging
even more challenging in the future [7]. With the under-

2. Purity and Eﬀect Annotations

standing of side eﬀects in the software libraries, programmers

In this section, we firstly discuss our definition of the pu-

can perform high level refactoring on the functional part ofrity and side eﬀects. Secondly, we define a set of annotations

the source code. However, the purity information is usually

to document these informations. Lastly, we discuss the rules

missing in external libraries, therefore programmers wouldthat should be followed by these annotations.

risk introducing bugs with such refactorings.

2. 1 Stateless & Stateful Purity of Functions

In this paper, we present an approach to infer a function’s

The notion of purity on functions does not match wellpurity from byte code and automatically document eﬀect an-with other OO programming paradigm concepts. In OO

notations for later use by programmers and static processing

languages, program states are usually encapsulated withintools. Programmers can use eﬀect annotations to understandobjects, which use well-defined boundary functions calleda function’s side eﬀects, whereas static processing tools canmethods to interact with each other. This is the opposite

use them for static checking, optimizing or refactoring.

of a pure functional paradigm where the states of the pro-

The contributions of this research include:•

An extended definition of purity as stateless or statefulin object-oriented(in short, OO) languages such as Java.

gram are passing through function arguments.
Moreover, we noticed that most objects have a life spanpattern of creation, use and destroy. Many objects will not—1—

change their states after properly created, and the functions
called on them simply query these internal states. We would
like to distinguish these state-querying functions from thosefunctions that modify the states. Through our research wehave observed that OO libraries can still contain around 25–
33% of functional code that do not modify the program’s
state (e.g., tree traversals).
Based on the above observation, we define a function as
pure if it does not generate side eﬀects such as modifying
the state outside the object. Note that this definition isslightly diﬀerent from the traditional definition of pure functions by return value dependencies [6]. Meanwhile, many
existing studies such as [3, 5, 9] share the same purity definition with us. To illustrate the diﬀerence of two definitions,
we divide the our definition of a pure function into statelessand stateful functions:［Definition 1］（Stateless） If the return value of a purefunction is only determined by the state of its arguments.
［Definition 2］（Stateful） If the return value of a pure func-tion is also determined by the states of member fields or
static fields.
2. 2 Lexical State Accessors and Side Eﬀects
The main purpose of this research is to reveal the side effects of functions. Therefore, we need to define what is aneﬀect and what is a side eﬀect of a function.
［Definition 3］（Eﬀect） We define the eﬀects of a function as

the modifications to the states of the program, including thereturn value.
［Definition 4］（Side Eﬀect） We define the side eﬀects of afunction as the modifications to the states of the objects or
performing I/O operations.
The eﬀects of a function are all the side eﬀects including
the return value. According to the single response principle
in [4], a function should have exactly one eﬀect, either calculating a value and return it, or doing one kind of modification
to the state of the program. Disobeying this practice usuallyclass Tree extends Comparable {@Depend ( dependThis = true ,dependFields = { " Tree Node . r " , " int Leaf . f " ," Tree Node . l " }from = { " int Leaf . freq () " ," int Node . freq () " })int freq () { return 0; }@Depend ( dependThis = true ,d ep e nd Ar g um en t s = { " Tree tree " } ,dependFields = { " Tree Node . r " , " int Leaf . f " ," Tree Node . l " })int compareTo ( Tree t ) { return freq () - t . freq () ; }}class Leaf extends Tree {char v ; int f ;@Field ( type = int . class , owner = Leaf . class ,name = " f " , d e pe nd A rg um e nt s = { " int fr " })@Field ( type = char . class , owner = Leaf . class ,name = " v " , d e pe nd A rg um e nt s = { " char va " })Leaf ( int fr , char va ) { f = fr ; v = va ; }@Depend ( dependThis = true ,dependFields = { " int Leaf . f " })int freq () { return f ; }}class Node extends Tree {Tree l , r ;@Field ( type = Tree . class , owner = Node . class ,name = " l " , d e pe nd A rg um e nt s = { " Tree le " })@Field ( type = Tree . class , owner = Node . class ,name = " r " , d e pe nd A rg um e nt s = { " Tree ri " })Node ( Tree le , Tree ri ) {f = le . f + ri . f ;l = le ;r = ri ;}@Depend ( dependThis = true ,dependFields = { " Tree Node . r " , " Tree Node . l " })int freq () { return l . freq () + r . freq () ; }}class Main {@Depend ( d ep e nd Ar g um e nt s = { " int [] chrs " })Tree build ( int [] chrs ) {PriQueue q = new PriQueue () ;for ( int i = 0; i < chrs . length ; i = i + 1) {if ( chrs [ i ] > 0) {q . offer ( new Leaf ( chrs [ i ] , ( char ) i ) ) ;}}for (; q . size () > 1;) {q . offer ( new Node ( q . poll () ,q . poll () ) ) ;}return q . poll () ;}void main ( String [] args ) {String test = " this is an example " ;int [] chrs = new int [256];for ( int i = 0; i < test . length () ; i = i + 1) {char c = test . getChar ( i ) ;chrs [ c ] = chrs [ c ]+1;}
Tree tree = build ( chrs ) ;}}Figure 1 Annotated Huﬀman Algorithm

leads to problematic, unmaintainable coding style.
［Definition 5］（Lexical State Accessor） We define a lexicalachieved by accessing the aforementioned lexical state acces-

state accessor to be any variable that is directly accessible

sors. There are two forms of modification: changing thewithin a function’s lexical scope before the execution.

values of these accessors directly, or modifying indirectly

In statically-typed object-oriented languages such as Java,though the use of lexical state accessors. These modifica-

lexical state accessors of a function include the possible thistions are considered to be the side eﬀects of executing thepointer, the arguments, the member fields within the samefunction. Additional side eﬀects include calling system rou-class, and the static fields in any arbitrary classes. Notetines to perform I/O operations directly or transitively.

that local variables defined inside a function are excluded in

2. 3 Eﬀect Annotations

the definition of lexical accessors, because they do not exist

We introduce a set of function annotations to indicate theoutside the function’s body. We focus on lexical variables

eﬀects that can arise during invocation. For each function,

because they can be easily identified and understood fromseveral annotations can be prepended, each representing a

the function definition by programmers.

side eﬀect that for example modifies one member field. The

All possible modifications to the state of a program areproposed annotations express the eﬀects such as direct or—2—

transitive modifications to lexical state accessors, with thependency as the value of a lexical state accessor before apossible data dependency between these eﬀects and otherfunction executes, and a dependency set (DS) as the set of

lexical state accessors from the function. The data dependen-

data dependencies such that DS ⊂ {x|x ∈ S ∪ F ∪ A}.

cies are captured in annotation records such as dependThis,The above definition of dependency set is used in both ourdependArguments, dependFields and dependStatic, withdata flow analysis and reference alias analysis. The diﬀer-

detailed information such as types and owner classes of theence between the dependency sets used in these two analyses

fields. Although the this pointer is not a mutable variable

is that we only consider reference type dependencies in refer-in the context of a target function, it is possible to compare

ence alias analysis, and value type dependencies in data flow

the identity by using this pointer to other pointers or expose

analysis. All dependencies suitable in reference alias analy-

this pointer as return value of the function, hence the thissis are also suitable in data flow analysis, but not vice versa.

pointer is included in data dependency.

We define two dependency sets used in these two stages ofFor example, the annotated version of the source code of
the Huﬀman algorithm is represented in Figure 1. The eﬀect
annotations are intended to be used by both programmers

analysis as:•

reference dependency (rd) is a DS of the possiblereference aliases.

and tools that process the program, as a contract describing•

the given function. This contract can be viewed as a compli-

value.

value dependency (vd) is a DS that aﬀects thementary to the function signature and exception specifica-

Our analyzer interprets the code, follow the instructions

tion that imposes restrictions on the implementation of thein the given function, and applies the aforementioned threefunction.

analysis. The analyzer begins its interpretation by breaking
the code of a given function into statement block s using con-

3. Automatic Inference of Eﬀect Annotations

trol flow analysis, where we define a block to be a sequence

Asking developers to manually annotate eﬀect annota-of its condition if it is nested in an if or while statement.

of statements. The block can be associated with a value

tions is tedious, error-prone, and infeasible for third party

Next, the analyzer interprets the each block ’s instructions tolibraries. In this section, we present our approach to auto-

evaluate the value dependencies and obtain a list of eﬀects.

matically inferring eﬀect annotations.

During the interpretation stage, each value is represented as

The analyzer identifies function targets by using a class
diagram and call graph. The class diagram records the in-a triplet of its static type, a reference-dependency set, and avalue dependency set (V = (type, rd, vd)).

heritance relationship of classes (including interfaces) andAt the beginning of the interpretation of the given func-

the overriding relationship between functions in a class hi-tion, the argument values are assigned with value and ref-erarchy. The call graph records the invocation instructions

erence dependencies of themselves. Next we interpret each

inside the function, which points to another function defined

instructions of the function by following the transfer func-

in the class diagram.

tions in Table 1. The input of a transfer function is V before

3. 1 Data and Control Analysis

the execution of the instruction, and the output is a new V

Our analyzer traverses all of the functions in the class dia-

after the execution. Besides the reference and value depen-gram, inferring possible eﬀects including side eﬀects. We capture only the dependencies of lexical state accessors, which
are defined in in Subsection 2. 2, during these three analysis
stages:•data flow analysis estimates the return value depen-dency.
•

reference alias analysis identifies possible modifi-

cations to lexical state accessors that are side eﬀects.
•

control flow analysis supports data dependence cal-culations on conditional branches.
There are three kinds of lexical state accessors as definedin Section 2. 2, which are the static field s (shortened as S)of a class, the member field s (shortened as F ) of an object,
and the arguments (shortened as A) passed to the function.

Table 1 Transfer Functions for Values and Instructions
Type
Code Pattern
RD
VD
vn

new τ

∅

∅

vp

x

{x}

{x}

vl

y

∅

∅

vt

this.field{field}{field}vsClass.field{field}{field}vf

V .field

Vrd

Vvd

vu

op V

∅

V

vb

V1 op V2∅

V1vd ∪ V2vd

va

V1 [V2 ]V1rd

V1vd ∪ V2vd

vc(τ ) V

Vrd

Vvd

assignV1 = V2

V1rd

V2vd

returnreturn V

merge

∅

∅

V1rd ∪ V2rd

V1vd ∪ V2vd

［Definition 6］（Data Dependency Set） We define a data de-—3—

dency sets in this table, the static types of these values should

With the eﬀect annotations on the functions, we can sim-

also be calculated as defined in the language specifications.

ply determine whether a function is a pure function, andNote that the “merge” instruction in this table merges thefurther, whether it is stateful or stateless. A function thatbranches of statements during the interpretation. Besides

has no modification annotations is considered to be a purethe instructions listed in the table, there is another impor-function. A pure function whose return value depends only

tant kind of instructions, the function invocations, describedon arguments is considered to be a stateless pure function.

in Section 3. 2. During interpretation, possible function ef-

3. 3 Iteration to a Fix-point of Class Diagram

fects are collected when processing assignment instructions.

A function’s eﬀect annotations depend on the annotations

We initially mark two kinds of dependencies: modification be-of its callees as well its overriding functions, potentially caus-havior for reference dependencies and return statement foring a function to be analyzed several times. In addition, re-value dependencies. Both dependencies are merged with thecursive functions may also be analyzed multiple times. We

value dependency set for the current block.

continue analyzing until the eﬀect annotations are inferred.

3. 2 Eﬀects from Function Invocations

We set a flag in each function on the class diagram to indi-

We refer to the function containing an invocation as acate whether the eﬀects for this function need to be inferredcaller, and the function being called as a callee. When theor updated.

analyzer sees a function invocation instruction during in-Firstly, we initialize all functions in the class diagram withterpretation, it generates possible eﬀects by examining theeﬀects as ∅. Next we mark the flags for all of these functions

date flow across the invocation boundaries. Fortunately, thisas “need to be analyzed”. Then, for each function whose flagcross-function analysis is possible with the generated eﬀect

is marked, the analyzer:

annotations on the callee, so that we do not need to examine（ 1 ） Merges the eﬀects with the result of the data anal-

the codes of the caller and callee at the same time. Whenysis on this function.

the eﬀect annotations on the callee are not available during（ 2 ） Clears the flag on this function.

analysis of a caller, the analyzer simply ignores the invoca-（ 3 ） If the eﬀects have changed since last analysis, markstion, pretends callee has no eﬀects, and then refreshes thethe flags of all functions that depend on this function.

result when the annotations on the callee become available.

We continue the iteration until none of the functions in the

All of the invocation instructions share the same form asclass diagram are marked, which means the reach of a fix-

Vobj .function(Varg ).

All side eﬀects on static fields aretransferred from callee to caller. If there are argument effects generated on the callee function, i.e., when the callee ispoint of the analysis.

4. Experiments

modifying the state of a passed argument, then the analyzer

We evaluated our analyzer on real world software compo-

will generate a modification behavior on the reference de-nents in terms of accuracy, performance, and the distribution

pendencies of corresponding position, as if the modificationof diﬀerent kinds of eﬀects in diﬀerent scale of software com-occurs inside the caller function.

ponents.

The Vobj is the object that owns the function, which

4. 1 Distribution of Eﬀect Annotations

could be this, ClassName or a certain dynamically calculated

To show the distribution of purity and side eﬀects ofvalue during the interpretation. Static member functions on

the functions in real world software components, we experi-ClassNames are guaranteed not to generate modification side

mented on 4 target software projects, listed in Table 2. Theseeﬀects on member fields. If a reference dependency of Vobj

experiments were executed on an octa-core Xeon E5520 CPU

is this, all the modification side eﬀect annotations on mem-with a 16GB heap size limitation. purano is the implementa-

ber fields will be copied, otherwise a single modification ef-

tion of the analyzer presented in this paper, which includes afect on the reference dependency of the current Vobj will be

modified version of the ASM library. Both htmlparser, tom-recorded. This behavior of analyzer follows the definition of

cat and argouml are well-known open source Java libraries

lexical state accessors described in Section 2. 2, to distinguishbetween directly and transitively accesses of these accessors.
Finally, if the interpreted invocation expression returns a

Table 2 Experiment Target and Analysis Performance
Softwarevalue, we need to determine the reference and value dependency of its return value. The reference dependency of the
invocation expression is the reference dependency of return
value from callee, and the value-dependency of this expres-All
Classes

User

User

Time

Classes Functions (sec.)

Passpurano

3,541

232

2,120

215

19

htmlparser

4,843

158

1,621

344

22

tomcat

6,658

763

8,662

665

23

argouml

11,234

2,544

20,2742,217

28

sion is the merged value dependencies of all Varg s.
—4—

package javax . swing . text ;public class DefaultCaret extends Rectangle ... {/* Compares this object to the s p e c i f i e d object .
* The s u p e r c l a s s b e h a v i o r of c o m p a r i n g* r e c t a n g l e s is not desired , so this is changed* to the Object b eh av io r .
*/public boolean equals ( Object obj ) {return ( this == obj ) ;}}Figure 2 A Special Design in DefaultCaret

are defined interfaces or abstract classes. There were also 2
equals and 6 hashCode functions defined in classes without
member fields. There were 9 equals that compare referential
identities defined in classes with member fields. These wereused in unusual cases when comparing by referential identity rather than value identity is desired. An example of thiskind of special design can be found in DefaultCaret.equals,
shown in Figure 2, where the author explicitly documented
in the Javadoc as “The superclass behavior of comparing

package java . io ;public final class FilePe rmission ... {public boolean equals ( Object obj ) {if ( obj == this ) return true ;if (!( obj instanceof FileP ermiss ion ) )return false ;FilePermi ssion that = ( FilePermiss ion ) obj ;return ( this . mask == that . mask ) &&this . cpath . equals ( that . cpath ) &&( this . directory == that . directory ) &&( this . recursive == that . recursive ) ;}public int hashCode () {return 0;}}

Figure 3 A Potential Problem in FilePermission

rectangles is not desired, so this is changed to the Object behavior”. In addition, most of these classes are innerclasses in Java with their names containing a “$” character. These inner classes are supposed to be used internally,
where programmers control the creation of all objects. We
found 3 hashCode functions that return a constant, whereas
their corresponding equals functions compared the statesof member fields. An example is shown in Figure 3, that
FilePermission.hashCode will always return 0. The userof these classes must be aware of their respective behaviors,in order to avoid putting them in a HashSet or HashMap, orand we use their latest stable binary distributions. Based oncomparing them using equals. With the introduction of ef-

the analysis times in Table 2, we determine that the perfor-fect annotations as documentation, the user of these classes

mance of our analyzer is reasonable within a daily program-can notice the special behavior.

ming environment, although it could be further optimized bycaching the result of the standard libraries.

Next we examined the functions in Table 4 that generate side eﬀects. Most of these functions cached the result

The purity of functions of the experimental result is listedof calculations inside the object, similar to functions on thein Table 3. From the annotation output, we find that aroundwhite-list. Some classes such as Date and Calendar normal-

25–33% of the functions in these software projects wereized their internal representation before comparing equal-

marked as stateless or stateful pure functions. We manu-

ity or calculating the hash code. Classes used in reflection

ally confirmed the generated result for purano to make sureat runtime, such as java.lang.reflect.Class, used a lazy

it matched our expectation.

loading technique to optimize general performance, which is

4. 2 A Case Study: Purity of equals and hashCodea variant of caching technique.

Diﬀerent programmers may use our tool for their own us-

5. Related Workages. Therefore, we conducted a case study to illustrate one
possible usage of our study. We examined the inferred an-

Many previous eﬀorts on combining pure functional style

notations on two functions, namely equals and hashCode.

into an object-oriented paradigm concentrate on introduc-

These two functions are related with the value equality of

ing immutable restrictions on existing type systems, as inobjects in Java, and they are used by collection classes suchfunctional programming languages.

Tschantz, et al. [10]as HashMap. The programmer must ensure that the return
values of these functions reflect their value equalities, andTable 4 Purity of equals (as e) and hashCode (as h)hence these return values should depend on the state of the

Softwareobjects. Therefore, we expect these functions to be stateful pure functions if they contain member fields. The purity

puranotypes of these two functions are listed in Table 4. We cansee from the distribution that nearly 70% of these functions

htmlparser

were annotated as stateful pure, as expected.
tomcatTo further understand the result, firstly we focused on theexistence of stateless pure functions in Table 4 by manually examining their source code. Most of these functions

All

Pure Functions
StatelessStateful

Side Eﬀects

e 335 13 (3.9%) 237 (70.7%)

85 (25.4%)

h 316 25 (7.9%) 224 (70.9%)

67 (21.2%)

e 290 19 (6.6%) 198 (68.3%)

73 (25.2%)

h 284 23 (8.1%) 199 (70.1%)

62 (21.8%)

e 407 23 (5.7%) 277 (68.1%) 107 (26.3%)
h 399 30 (7.5%) 268 (67.4%) 101 (25.3%)

argoumle 358 24 (6.7%) 239 (66.8%)

95 (26.5%)

h 344 28 (8.1%) 248 (72.1%)

68 (19.8%)—5—

Table 3 Percentage of Eﬀect Annotations
SoftwarePure Functions

Side Eﬀects

Modifying

StatelessStatefulpurano319 (15.0%)

203 ( 9.6%)

1,598 (75.4%)

htmlparser

286 (17.6%)

257 (15.9%)

1,078 (66.5%)

718 (44.3%)

894 (10.3%) 1,782 (20.6%)

5,986 (69.1%)

4,684 (54.1%)

14,549 (71.8%)

8,345 (41.2%) 12,824 (63.3%) 3,902 (19.2%)

tomcatargouml

4,239 (20.9%)

1,486 ( 7.3%)

Member Fields

Static Fields

Arguments

1,425 (67.2%)

1,054 (49.7%)

430 (20.3%)

782 (48.2%)

145 ( 8.9%)

4,318 (49.8%) 1,238 (14.3%)

proposed Javari as a new programming language that adds

eﬀect annotations, by programmers as well as by analysis

readonly and other keywords into Java syntax to indicate

tools. The format of these annotations needs to be more

the reference immutably of variables.

Based their work,

readable and understandable to be used by programmers.

Quinonez [2] proposed an analyzer called Javarifier to auto-

We will also further investigate the applications of these ef-

matically infer reference immutability in Javari syntax. Allfect annotations other than identification of pure functions.

these type-system-based approaches require syntax modifi-

To conclude, in this paper we presented a study on the

cation of the source code. Although they can be applied inpurity and side eﬀects of the functions in OO languages such

newly developed projects, it is much more diﬃcult for theseas Java, helping programmers to understand the software li-

approaches to be adopted in legacy libraries, and existing

braries. We proposed a method to automatically infer thetools such as IDE support need to be extended to accept

purity and side eﬀect information from Java bytecode. We

their new syntax.

implemented and experimented the proposed method on real

There are studies of automatic purity analyzers on un-

world Java software libraries, and found that around 25–33%

modified syntax. Sălcianu, et al. present a purity analyzer

of all the function of the Java libraries is made of pure func-

for Java in [9], which uses an inter-procedural pointer anal-

tions. We compared the accuracy of distribution of pureysis [8] and escape analysis to infer reference immutability.

functions with existing study. And we demonstrated how

Similar to our approach, they verify the purity of functions,programmers will use our method to understand the behav-

but their pointer and escape analysis relies on a whole pro-ior of library APIs by a case study.

gram analysis starting from a main entry point, which is notalways available for software libraries. JPure [5] eliminatedthe need for reference immutability inference by introducing
pure, fresh and local annotations, which lead to a more

Acknowledgment
This work was supported by MEXT/JSPS KAKENHI
25220003, 24650011, and 24680002.

restrictive definition of purity, and loses the exact informa-

Referencestion for eﬀects. Both studies focus on analyzing of purity[1] B. Goetz. Java theory and practice: I have to document that? http://www.ibm.com/developerworks/java/
library/j-jtp0821/index.html, 2002.
[2] Q. J. Javarifier: Inference of reference immutability inJava. PhD thesis, Massachusetts Institute of Technology,
2008.
[3] G. T. Leavens, A. L. Baker, and C. Ruby. Preliminary design of jml. Technical report, Technical Report 96-06p, Iowa
State University, 2001.
[4] R. C. Martin. Clean code: a handbook of agile software
craftsmanship. Prentice Hall, 2008.
[5] D. J. Pearce. Jpure: a modular purity system for java. In
Compiler Construction, pages 104–123. Springer, 2011.
[6] S. L. Peyton Jones and P. Wadler. Imperative functional
programming. In Proceedings of the 20th ACM SIGPLANSIGACT symposium on Principles of programming languages, pages 71–84. ACM, 1993.
[7] C. Raymond. The importance of error code backwards
compatibility.
http://blogs.msdn.com/b/oldnewthing/archive/2005/01/18/355177.aspx, 2005.
[8] A. Sălcianu. Pointer analysis and its applications for Java
programs. PhD thesis, Citeseer, 2001.
[9] A. Sălcianu and M. Rinard. Purity and side eﬀect analysis for java programs. In Verification, Model Checking, andAbstract Interpretation, pages 199–215. Springer, 2005.
[10] M. Tschantz and M. Ernst. Javari: Adding reference immutability to Java, volume 40. ACM, 2005.

only, and does not expose eﬀects information outside their
toolchain. Compared with these studies, our approach uses
lexical state accessor analysis, which will hopefully combine
the modularity of JPure by illuminating the need for interprocedure analysis, and the flexibility of reference immutability with the availability of eﬀect information. Also neitherof these two studies further classify the pure functions into
Stateless and Stateful as we do.

6. Future Work and Conclusions
The current implementation of our analyzer works on Java
bytecode rather than source code. analysis tool at Besides
all the advantages described, this target language decision
is made to ease the early development, because it is easy togenerate bytecode from source code by a compiler but notvice versa. However, targeting source code format is still important for integrating as an IDE plugin. We plan to add asource code analyzer in the future.
Moreover, we plan to further evaluate the usability of these—6—