• No results found

Improving the Developer Experience by Implementing Syntax in the Encore Language

N/A
N/A
Protected

Academic year: 2022

Share "Improving the Developer Experience by Implementing Syntax in the Encore Language"

Copied!
42
0
0

Loading.... (view fulltext now)

Full text

(1)

Sj ¨alvst ¨andigt arbete i informationsteknologi June 21, 2017

Improving the Developer

Experience by Implementing Syntax in the Encore Language

Lowe Eklund Karolina Nikamo Casper Str ¨omberg

Civilingenj ¨orsprogrammet i informationsteknologi

(2)

Institutionen f ¨or informationsteknologi

Bes ¨oksadress:

ITC, Polacksbacken L ¨agerhyddsv ¨agen 2

Postadress:

Box 337 751 05 Uppsala

Hemsida:

http:/www.it.uu.se

Abstract

Improving the Developer Experience by Imple- menting Syntax in the Encore Language

Lowe Eklund Karolina Nikamo Casper Str ¨omberg

Good concurrent software is a necessity today, as concurrent architec- tures have become commonplace. Consequently, a good programming experience in languages designed for concurrency becomes essential.

This project provides the design and implementation of a set of features in the Encore programming language, which is designed for concur- rency. The aim is to provide increased convenience and efficiency in the programming experience. The project resulted in two new language features in Encore: default field values and default parameters. Imple- mentation of the new features was done by modification/extension of the Encore compiler. A majority of surveyed participants preferred the new features over the old syntax.

Extern handledare: Tobias Wrigstad och Elias Castegren

Handledare: Virginia Grande Castro och Bj¨orn Victor

Examinator: Bj¨orn Victor

(3)

Sammanfattning

Bra parallelliserbar mjukvara ¨ar en n¨odv¨andighet idag n¨ar m˚angk¨arnade arkitekturer blivit vanligt. D¨armed blir ¨aven utvecklarupplevelsen i programmeringsspr˚ak designa- de f¨or samtidighet viktig. Detta projekt utformar och tillhandah˚aller genomf¨orandet av upps¨attning syntaxfinesser i parallellprogrammeringsspr˚aket Encore. Syftet ¨ar att

¨oka effektivitet och bekv¨amlighet f¨or utvecklaren. Projektet resulterade i tv˚a nya syn-

taxfinesser i Encore: f¨altinitiering och standardv¨arden p˚a parameterar. Dessa syntaxfi-

nesser implmenterades genom att modifiera Encore-kompilatorn. En majoritet av un-

ders¨okningsdeltagarna anser att de nya sytaxfinesserna ¨ar b¨attre ¨an dess f¨oreg˚angare.

(4)

Contents

1 Introduction 1

2 Background 1

2.1 Concurrency and concurrency related bugs . . . . 2 2.2 Encore . . . . 3

3 Purpose, aims, and motivation 4

3.1 Purpose . . . . 4 3.2 Aim and motivation . . . . 4 3.3 Delimitations . . . . 7

4 Related work 7

4.1 Default field values . . . . 7 4.2 Multiple initializers . . . . 8 4.3 Default parameters . . . . 8

5 Method 9

5.1 Design . . . . 9 5.2 Implementation . . . . 9

6 System structure 10

7 Implementation 11

7.1 Default field values . . . . 11 7.2 Default parameters . . . . 12

8 Requirements and evaluation methods 13

(5)

8.1 Unit tests . . . . 14

8.2 Survey . . . . 16

8.3 Performance tests . . . . 16

9 Evaluation results 16 9.1 Unit tests . . . . 16

9.2 Survey . . . . 17

9.3 Performance tests . . . . 18

10 Results and discussion 19 11 Conclusions 20 12 Future work 20 12.1 Default field values . . . . 20

12.2 Multiple initializers . . . . 21

12.3 Object finalizers . . . . 22

12.4 Wrapped primitive . . . . 23

A Survey 29 A.1 Background questions . . . . 29

A.2 Default field values . . . . 31

A.3 Multiple initializers . . . . 32

A.4 Default parameters . . . . 34

B Performance results 37

(6)

2 Background

1 Introduction

The purpose of introducing new programming languages is often to simplify the expres- sion of certain types of complex behavior [2]. Encore is a programming language that aims to make it simpler to express concurrent behaviors in a safe manner. A safe type system together with an implementation of the actor model, explained further in subsec- tion 2.2, is the core in achieving this. Encore has to provide convenient syntax features to facilitate the process of expressing complex concurrent behaviors. This will result in that the developer can focus on the problem trying to be solved as opposed to working out all the implementation details.

Good concurrent software is a necessity today, as concurrent architectures have become commonplace [23]. Concurrent programs differ from the more common paradigm of sequential programs in some key ways. Many programming languages are designed for developing sequential programs from the outset and have added support for concurrency subsequently. However, frequently these languages still follow a sequential paradigm, resulting in unnecessarily complex concurrent software.

In this report, we provide the design and implementation of a set of new language fea- tures in the programming language Encore. Encore is a language that is designed ex- plicitly for concurrency at Uppsala University. For the language to become accessible to the general developer community it does not only need to provide the concurrency benefits but also good and recognizable syntax features. Besides making Encore more accessible, such features also have the extra bonus of making the developer more pro- ductive.

The goal of this project is to provide syntactical features in the Encore language that would further simplify the process of developing concurrent applications. The language features developed in this project are the following:

• Default field values

• Default parameters

2 Background

Programming languages are essentially protocols after which humans communicate

with computers. It is preferable if the communication can be conducted in a way which

clearly states, both for the computer and for the human, the intent of the instructions

(7)

2 Background

given to the computer. Beyond that, it is preferable if the language is not overly com- plex. The goal of syntax design ought to be that developers should need to think less about how to express their intents and thus be able to think more about what to express.

Design of semantics and syntax is key in achieving this goal for a given programming language.

Natural languages tend to have several ways to convey a message. We suggest that the reason for this is partly because one expression might be more convenient to use than the other expression in a given context. When developing programming languages there is a continuous search for ways to exploit this feature that many natural languages exhibit.

The way to achieve the ability to convey the same message in several different ways is usually through the implementation of syntactic sugar [19]. Syntactic sugar can be thought of as shortcuts that the developer can use to convey the intended message. The difference between syntactic sugar and other syntactic features is that syntactic sugar does not add new functionality or meaning to the language. Instead syntactic sugar uses already existing features in the language to construct new convenience features.

Therefore several different ways of conveying an intent could be implemented. These different ways, in other words the syntactic sugar, will during compilation be translated back to the same standard form, also called the canonical version. This process is in this report referred to as desugaring and is further explained in section 6.

2.1 Concurrency and concurrency related bugs

Modern computer architectures have in recent years failed to increase the central pro- cessing unit (CPU) clock speed [10]. This implies that the basic processing unit, or core, of the CPU can not process operations faster than a given speed. To overcome this issue multicore and manycore architectures are used, which is when a computer has more than one processing unit. Sequential programs fail to utilize these architectures as they cannot divide their work among several cores simultaneously. Concurrent pro- grams are needed instead. These programs can divide their work among several cores concurrently, i.e. execute one operation on one core and execute another operation on a different core at the same time [23]. It does not necessarily mean that a program is running concurrently on multiple cores on the same machine. A distributed system uses a network of computers to execute its tasks [18]. There are several benefits of designing a system this way. A network of computers allows for durable and scalable systems, a single point of failure can be avoided and high loads can be distributed over the network.

Executing several computations concurrently increases the complexity of programs.

Suppose that two of these computations have some shared resources that they both ac-

cess simultaneously. Below is an example that illustrates two threads with a shared

(8)

2 Background

resource sharedVariable.

v a r s h a r e d V a r i a b l e = 1

T h r e a d 1

r e a d s h a r e d V a r i a b l e T h r e a d 2

w r i t e 14 s h a r e d V a r i a b l e

The example above describes a scenario where the resulting execution is nondetermin- istic. Both threads run concurrently and the order of execution is not predetermined. In this case there are two possible outcomes:

• Thread 1 performs the read operation before Thread 2 performs the write opera- tion. This would result in Thread 1 reading the value of 1.

• Thread 2 performs the write operation before Thread 1 performs the read opera- tion. This yields Thread 1 reading the value of 14.

The example illustrates what is referred to as a race condition [20]. To avoid such con- ditions, some form of concurrency control is needed. A common form of concurrency control is to enforce mutual exclusion by using locks. Mutual exclusion requires that only one thread of execution is allowed to enter its critical section at a time. A critical section is a part of a program where a shared resource is accessed. The critical sec- tions in the example above are the read and write operations. Locks when implemented wrong can cause what is called a deadlock: threads that wait for each other and thus never get access to the critical section, or unexpected violations of mutual exclusion in programs. Implementation of concurrency control is in general a bug-prone process.

Developing with locks is also a balance: over- or misuse might hurt performance when for example threads spends much time waiting to require locks [17].

2.2 Encore

Encore is being developed by researchers at Uppsala University. Encore is an object- oriented concurrency focused language, that aims to make concurrent applications eas- ier and safer to develop. The Encore compiler, which is written in the programming language Haskell, compiles Encore-code to C-code (read more in section 6).

The concurrency model To be able to handle concurrent tasks, a programming

language needs to represent the tasks in some way. Encore does this by implementing

(9)

3 Purpose, aims, and motivation

a concurrency model that is called the actor model. In the actor model an actor is the fundamental unit of computation [15, 2]. An actor embodies three things: processing, storage and communication. A system consists of several actors that together communi- cate via asynchronous message passing. An actor can modify private state but if it wants to affect another actor it has to send a message. When an actor receives a message, it can perform three tasks: (1) create more actors, (2) send a message to actors it knows, (3) designate what it should do when receiving the next message. This pattern avoids the need for locks.

Type System Today the responsibility of concurrency control is usually left to the programmer. This could arguably be thought of as unreasonable considering the diffi- culties associated with implementation of such. Kappa, the type system used in Encore, can guarantee data race freedom [11]. A compiled Encore program is guaranteed to be free from race conditions, which is incredibly useful when developing concurrent software.

3 Purpose, aims, and motivation

3.1 Purpose

The purpose of the project is to improve the implementation process for developers working with the Encore language by simplifying the interaction between human and computer. Specifically we aim to do this by implementing new language features.

Many programming languages are ultimately compiled into machine code. In theory everything can thus be programmed in machine code. This would however be a tedious process for a human. It is in general very difficult for humans to read and write ma- chine code. Higher level languages help the developer to abstract away logic that is not specific to the problem being solved.

3.2 Aim and motivation

The general purpose of programming languages is to make software development effec- tive for programmers [4]. The aim of the creation and further development of Encore is to reduce the complexity for programmers when developing concurrent applications.

Reduced complexity allows the developer to be more effective. In this project we are

(10)

3 Purpose, aims, and motivation

going to implement a set of features in the Encore language to make the developer even more effective. Additionally these features will reduce the amount of code in most En- core programs. The project aims to provide support for the following features in the Encore programming language.

Default field values The ability to instantiate an object with default values on its fields. The code below is an example where every new instance of Pupil will have field name initialized to ”Glenn” and field age initialized to 12.

a c t i v e c l a s s P u p i l

v a r name : S t r i n g = ” G l e n n ” v a r a g e : i n t = 12

. . .

Today in Encore the fields have to be initialized in the init method. The example below illustrates how this is done.

a c t i v e c l a s s P u p i l v a r name : S t r i n g v a r a g e : i n t d e f i n i t ( ) : u n i t

t h i s . name = ” M a t i l d a ” t h i s . a g e = 12

. . .

The convenience of default field values is more apparent when considering a class with multiple constructors (see below). Without the support for default field values these fields would have to be initialized in every constructor, consequently creating dupli- cation of code which is not optimal and is discouraged by the “don’t repeat yourself”

(DRY) principle [16].

Multiple initializations methods on a class When an Encore object is initialized the initializer method is called. Encore currently only support one initializer method on each class. This project aims to add the ability to have multiple initializers on each class. The figure shows SmartPerson with two initializations methods having different parameters.

a c t i v e c l a s s S m a r t P e r s o n v a r i q : i n t

d e f new w i t h P e r s o n ( p e r s o n : P e r s o n ) : u n i t t h i s . i q = p e r s o n . i q

(11)

3 Purpose, aims, and motivation

end

d e f new w i t h I q ( i q : i n t) : u n i t t h i s . i q = i q

end . . .

Support for multiple initializers provides the ability to initialize an object differently depending on which initialization method is called. The example below shows how the class SmartPerson could be instantiated using the two different initialization methods.

v a r e i n s t e i n : S m a r t P e r s o n = new S m a r t P e r s o n . w i t h P e r s o n ( . . ) v a r t e s l a : S m a r t P e r s o n = new S m a r t P e r s o n . w i t h I q ( 1 4 0 )

Default parameters on methods and functions Providing a mechanism so that methods and functions could be called with some arguments omitted. In this sense the feature could also be referred to as optional arguments. The arguments that are not given by the caller are set to the default value defined by the callee. The example below illustrates a function foo with a parameter y with default value 42.

f u n f o o ( x :i n t , y :i n t = 4 2 ) p r i n t( x )

p r i n t( y ) end

f o o ( 1 ) −− 1 42

An advantage with default parameters is the possibility to add another parameter in the function without affecting the existing callers. This makes it possible to extend a method or function without introducing breaking changes; the new function can be called in the same way as the old function. The code snippet below shows how the function foo can be extended with an extra default parameter. Note that the function call foo(1) from the previous example still works.

f u n f o o ( x :i n t , y :i n t = 4 2 , z : i n t = 6 6 6 ) p r i n t( x )

p r i n t( y ) p r i n t( z ) end

f o o ( 1 ) −− 1 42 666

f o o ( 1 , 2 ) −− 1 2 666

f o o ( 1 , 2 , 3 ) −− 1 2 3

In some languages the caller specifies the argument name for each argument. The argu-

ment name can be used to map the arguments to the corresponding parameter. In other

(12)

4 Related work

languages, including Encore, arguments are not given a name by the caller. When this is the case, all arguments to the left of the argument that should be assigned to the default value have to be specified.

3.3 Delimitations

There are many improvements that could be done regarding developer efficiency in the Encore language with unlimited time and resources. The scope of this projects is restricted to a limited set of three language features which are listed in subsection 3.2.

Selection of the features was based on suggestions from the Encore research team in combination with our views of what was feasible. Due to time constraints the feature multiple initialization methods was not implemented.

4 Related work

Several other programming languages offer similar features to the ones that were devel- oped for Encore in this project. Some examples from different languages are described in the subsections below.

4.1 Default field values

The Swift programming language [9] has support for default values on fields. In Swift it is not allowed to reference the object itself in the default field values. This is to avoid cyclic references. Swift provides a default initializer if all fields in the class are declared and the class does not contain an initializer [9, Chapter Initialization]. The default initializer sets all fields to their default values, which is shown in the example below. The example also illustrates that a class in Swift does not need an initializer if all fields have default values.

c l a s s MyClass { v a r a = ” h e l l o ” v a r b = 42 }

v a r m y O b j e c t = MyClass ( )

(13)

4 Related work

4.2 Multiple initializers

The Objective-C programming language [8] supports multiple initializers [5]. This im- plementation uses a pattern of designated and convenience initializers. A designated initializer is the main initializer of the class. A convenience initializer is required to call either a designated initializer or an initializer that eventually calls a designated initializer as visualized in Figure 1.

Figure 1: Illustrating the relation between designate and convenience initializers in the Objective-C programming language. The blocks represent initialization methods that are marked with either designate or convenience to indicate its kind. The arrows sym- bolize method calls, each arrow is drawn from the caller to the callee.

The Swift programming language [9] follows the same pattern of designated and conve- nience initializers as Objective-C [5]. Additionally the Java language [13] and the Scala language [22] both have support for multiple initializers on classes.

4.3 Default parameters

The Scala language [24] is similar to Encore in many aspects and has support for de- fault parameters [21], but this implementation is more complex in its behavior than our implementation: named arguments can be used to map arguments to parameters instead of ordering.

The ECMAScript scripting language [12] is different from Encore in many aspects but have support for assigning default parameters to functions. In this implementation pa- rameters that have a default value are not required to be passed by the caller when in- voking the function. This is accomplished by leveraging two properties of the language, namely the primitive value undefined and named arguments.

The Swift programming language [9] also supports default parameters [6]. Below is an

example of default parameters in Swift where the arguments are named; thus a default

parameter can be used on the first argument while still specifying an argument for the

second parameter.

(14)

5 Method

f u n c m y A d d i t i o n ( a : I n t = 0 , b : I n t ) { r e t u r n a + b

}

m y A d d i t i o n ( a : 1 , b : 3 ) / / 4 m y A d d i t i o n ( b : 3 ) / / 3

5 Method

Our method for developing support for the new features is driven by research and dis- cussions with researchers. Adding support for new features in a programming language mainly involves editing the language’s compiler. Hence the major part of this project will be development of the Encore compiler, which is written in the functional program- ming language Haskell.

5.1 Design

Research on implementation of similar features in other programming languages was inspirational for designing the syntax of the new features in Encore. Research was done both in languages that are similar to Encore and languages that are not (see section 4).

When the design was specified, implementation began.

5.2 Implementation

We have followed a test driven development method where the first step was to write unit tests that defined how each feature was expected to work. Secondly the Encore compiler was modified to support the feature.

Unit tests Unit tests were a fundamental part of the method that was used to im-

plement the features. Unit tests were used to continuously test our implementation, to

understand in which cases the implementation worked as specified and in which case it

did not. The Encore compiler project provides a basic testing suite that was used to test

the syntax features. A test consists of two parts: a test program and an output file. The

test program should test a specific feature, and use the print function to output certain

values. The desired output of the test program is specified in the output file. When the

test suite is executed, it runs the Encore program and compares it to the output file. If

the output of the program is identical to the output file, the test has passed.

(15)

6 System structure

Compiler development To implement the designed features the Encore compiler had to be improved. The strategy during the development process was to follow the compiler’s phases and start at the beginning, see Figure 2 and section 6. Our method involved trying to solve as much of the problem as possible in the desugarer. It is often beneficial to solve the problem in the desugarer because then no new language feature is introduced. Hence the feature will be compatible with all old code, which includes type checking and error handling.

6 System structure

The Encore compiler is the main subject of this project. It is written in the functional programming language Haskell and consists of multiple phases. The different phases are run sequentially and combined compiles Encore-code to C-code. Figure 2 is a visu- alization of the Encore compiler’s phases.

Figure 2: Illustrating the different stages in the compilation process. The figure is not complete but shows the parts relevant to this project.

Lexical analysis The input to the Encore compiler is the developers Encore source files. The Encore-code can be seen as a long string. Lexical analysis takes the string and splits it up into smaller parts, a stream of tokens (words) [14].

Parser The parser takes the stream of tokens and turns it into something more man- ageable, in this case an abstract syntax tree (AST) [14]. The abstract syntax tree rep- resents the tokens as a tree instead of a stream. Each token in the stream will be trans- formed into a node in the tree. The tree structure is beneficial since it represents the structure of the source program’s syntax as a hierarchy. The AST serves as an interme- diate representation of the language during compilation [3].

Desugarer The desugarer deals with syntactic sugar. The desugarer’s job is to trans-

late such syntactic sugar into its canonical form. The code in the first example below is

syntactic sugar for the code in the second example. Concretely in the case presented in

the code below, the desugarer would translate the code in the first example to the code

(16)

7 Implementation

in the second example. One way of looking at desugaring and syntactic sugar is that it provides shortcuts for the developer.

An example of syntactic sugar.

a c t i v e c l a s s P u p i l v a r a g e : I n t = 20

. . . .

The canonical version of the syntactic sugar illustrated above.

a c t i v e c l a s s P u p i l v a r a g e : I n t d e f i n i t ( ) : u n i t

t h i s . a g e = 20 . . .

Typechecker The typechecker works on the AST and checks that each operator is applied to the correct number of operands of the right types. The typechecker might also perform coercion of types. If an operator is applied on an operand of type A but the operator expect an operand of type B the typechecker would then convert (coerce) that operand from type A to type B. Additionally the typechecker might handle symbol overloading, that is, a symbol could have a variety of meanings and what meaning that applies is decided by the context [3].

Code generation The code generator transforms the intermediate representation used during compilation to the final output language. In the case of the Encore compiler the output language is C.

7 Implementation

In this section we describe how the new features were implemented and how they per- form.

7.1 Default field values

Default field values were implemented by modifying the parser and desugarer. The

parser was modified to read an optional expression together with a field declaration. On

(17)

7 Implementation

all classes where default field values are specified the desugarer transforms them into assignments. The assignments are then placed in the top of the class constructor, as shown in the example below. A class without an initializer gets an initializer during desugaring.

Before desugaring:

a c t i v e c l a s s MyClass

v a r a : S t r i n g = ” h e l l o ” d e f i n i t ( )

p r i n t l n(” i n i t ”) end

end

After desugaring:

a c t i v e c l a s s MyClass v a r a : S t r i n g d e f i n i t ( )

t h i s . a = ” h e l l o ” p r i n t l n(” i n i t ”) end

end

7.2 Default parameters

Default parameters was implemented by modifications in the parser, the desugarer and the typechecker. First, the parser was modified to be able to understand a declaration of default parameters. Handling method and function declarations was done in the desug- arer. When the desugarer encounters a declaration with default parameters, it generates as many extra functions as there are default parameters. In the example below the add function has two default parameters, and hence the desugarer will create two new func- tion declarations.

Before desugaring:

f u n add ( a : I n t , b : I n t = 2 , c : I n t = 3 ) a + b + c

end

After desugaring:

(18)

8 Requirements and evaluation methods

f u n add ( a : I n t , b : I n t , c : I n t) a + b + c

end

f u n a d d 1 ( a : I n t , b : I n t) add ( a , b , 3 )

end

f u n a d d 2 ( a : I n t) add ( a , 2 , 3 ) end

As the example above shows, each generated method will have a name starting with an underscore, followed by the original function name and the number of default param- eters used, i.e. add2. The parser does not allow function or method names to begin with an underscore. Hence a developer is neither able to declare nor call a function or method with a name beginning with underscore in the Encore source code. But in the desugarer, after the parser phase, names beginning with underscore are allowed.

The next step of the implementation was modifying the typechecker. When a method or function call is encountered by the typechecker it will try to find the declaration of that method or function. The typechecker will compare the number of arguments passed with the number of parameters in the method or function declaration. If the caller specified less arguments than the declaration specified, the typechecker will look for a function or method with a name starting with underscore, followed by the original name and number of arguments missing (the difference between number of arguments in the declaration and number of parameters given by the caller). The example below shows how the typechecker handles a function call.

Before typechecking:

add ( 0 )

After typechecking:

a d d 2 ( 0 )

8 Requirements and evaluation methods

The requirements of the implemented features are:

• The syntax should perform as specified. This means that all unit tests written

(19)

8 Requirements and evaluation methods

specifically for the new features should pass. Of course the already existing tests should also pass to make sure the new features has not affected the current func- tionality.

• At least half (50% or more) of potential Encore developers prefers the new fea- tures over the “old” syntax.

• The overhead in execution time during runtime that the features may introduce should be less than 50% and potential overhead should be described.

The evaluation of the Encore language features consists of three parts: unit tests, a survey, and performance tests.

8.1 Unit tests

Unit test for the features was written when the design of the syntax was decided. In the paragraphs below some examples are given to illustrate the specified syntax. If a test throws a compile time error or if it does not produce the desired output, the test fails.

The following tests are examples of very basic unit tests.

Default field values

An Encore test for default field values.

a c t i v e c l a s s Main d e f main( ) : u n i t

new T e s t e r ( ) end

end

a c t i v e c l a s s T e s t e r

v a l f o o : S t r i n g = ” f o o ” v a l b a r : S t r i n g = ” b a r ” d e f i n i t ( ) : u n i t

p r i n t l n( t h i s . f o o ) p r i n t l n( t h i s . b a r ) end

end

The output file

f o o b a r

(20)

8 Requirements and evaluation methods

Multiple initializers

An Encore test for multiple initializers.

a c t i v e c l a s s Main d e f main( ) : u n i t

new P u p i l . w i t h A g e ( 2 5 ) new P u p i l . w i t h o u t A g e ( ) end

end

l o c a l c l a s s P u p i l

d e f new w i t h A g e ( a g e : i n t) : u n i t p r i n t l n( a g e )

end

d e f new w i t h o u t A g e ( ) : u n i t p r i n t l n(” no a g e ”)

end end

The output file

25 no a g e

Default parameters

An Encore test for default parameters on functions.

a c t i v e c l a s s Main d e f main( ) : u n i t

p r i n t l n( t e s t A d d e r ( 1 , 2 , 3 ) ) p r i n t l n( t e s t A d d e r ( 1 , 2 ) ) p r i n t l n( t e s t A d d e r ( 1 ) ) end

end

f u n t e s t A d d e r ( a : i n t , b : i n t = 0 , c : i n t = 0 ) : i n t

a + b + c end

The output file

6 3 1

If it produces the desired output we know that the default parameters is passed into the

function. The limitation of this test is that it only tests integer parameters as well as it

only tests functions and not methods.

(21)

9 Evaluation results

8.2 Survey

To evaluate if potential Encore developers would benefit from the implemented features, a survey was done (see Appendix A). The survey was first and foremost aimed at devel- opers that are not part of the Encore community. The focus of the survey was evaluation of the readability and usability of “old” syntax versus the new features. Therefore the questions consisted of a comparison between short pieces of Encore code with our im- plemented features and without them. For each question, the different options were equivalent in that they achieve the same result, the differentiating factor was the syn- tax. First the survey asked which piece of code was the easiest to read and understand according to the participant. Secondly the survey asked which of the examples the test participant would write. To get a better understanding of the test participant’s answers, the survey asked which aspect he or she considered most important when answering the two aforementioned questions.

8.3 Performance tests

To investigate the performance implications of the features, we tested them with per- formance tests. The goal with the performance tests was to find out if the implemented features introduced overhead. This information is useful for current and future devel- opers of the Encore compiler if reduction of overhead should be necessary later. The tests were done with two profiling tools: dTrace [1] and Instruments [7]. To evaluate the performance of a feature, a comparison of two blocks of code was done. The blocks were equivalent in that they achieved the same result, but one block used a new feature and the other block did not. One block at a time was then looped for a certain amount of iterations and the execution time was measured. The tests were repeated ten times for each block, and an average execution time was calculated. Results of the performance tests are found in Appendix B.

9 Evaluation results

9.1 Unit tests

The unit tests were run continuously while developing the features. During the imple-

mentation phase the tests were used to verify that the solution worked. The test results

below are the result of running the test after the implementation phase.

(22)

9 Evaluation results

Default field values 4 out of 4 tests passed. Default field values work as expected.

Multiple initializers 0 out of 2 tests passed. This is not surprising since the feature was not implemented due to time constraints.

Default parameters 5 out of 5 tests passed. Default parameters work as expected for both functions and methods.

9.2 Survey

The survey results are found in Appendix A. The survey was sent to 30 people with programming experience and without previous experience of Encore. 26 people an- swered, which was a response rate of approximately 87%. All participants (100%) had experience from object-oriented programming. A great majority, 96%, had experi- ence of functional programming and 92% had experience of imperative programming.

Many test participants stated studying as their main occupation (96%) and the rest (4%) stated application development as their main occupation. Programming experience level among participants varied from beginner to expert, see Figure 3.

Figure 3: The test participants’ self-assessment of their programming experience level.

Default field values Encore code with default field values was easier to understand

according to a majority (81%) of the test participants. Of the participants, 81% would

(23)

9 Evaluation results

also write code with default field values. Hence the requirement that a majority of po- tential Encore developers prefers the new feature over the “old” syntax is considered satisfied for default field values. When the test participants decided which code snippet was easiest to understand, and which they were going to write, a majority (64%) con- sidered clarity was most important. Length of the code was most important for 18% and familiarity was most important for 14%.

Multiple initializers More than half of the participants (62%) thought Encore code with multiple initializers was easiest to understand. Less than half of the participants (42%) would write a program with multiple initializers. Hence the requirement that a majority of potential Encore developers prefers the new feature over the “old” syntax is not considered satisfied for multiple initializers. When the test participants decided which code snippet was easiest to understand, and which they were going to write, a majority (70%) considered clarity was most important. Familiarity was most important for 19% and the length of the code was most important for 7%.

Default parameters Encore code with default parameters was easiest to understand according to 42% of the test participants. Half of the participants (50%) would write code with default parameters. Hence the requirement that a majority of potential En- core developers prefers the new feature over the “old” syntax is considered satisfied for default parameters. When the test participants decided which code snippet was easiest to understand, and which they were going to write, a majority (69%) considered clarity was most important. Familiarity and length of the code were most important for 15%

respectively.

9.3 Performance tests

The performance results are found in Appendix B. Three separate test were done: one for default field values and two for default parameters.

Default field values The performance of default field values was tested by creating actors with and without the feature and measuring the execution time. We created 10

6

actors and did observe an insignificant difference, around 2% in execution time. This means that the requirement (less than 50% overhead) is satisfied for default field values.

The result is expected due to the way that the feature is implemented. Default field

values are implemented as syntactic sugar that the developer would otherwise use to

initiate an object. The two test blocks are hence equivalent.

(24)

10 Results and discussion

Default parameters We tested default parameters in two ways. The first test we wrote tested the performance of default parameters used in a function. The test con- sisted of a function that declared one parameter with a default value together with a function call with and without an argument. The function was called 10

8

times. We measured that default parameters introduced about 30% overhead compared to passing in arguments directly. When executing a function with a default parameter, what is hap- pening behind the scenes is that a generated function is called, which in turn calls the original function with the default parameter filled in. This extra function call introduces overhead compared to the standard way of calling functions.

The other way we tested the feature was on methods on an actor. We created one actor with a method that used default parameters and then passed messages to it with and without arguments. We passed 5 ∗ 10

6

messages to the actor and measured the execu- tion time. The execution time was on average 8% slower with default parameters than without. We observed a smaller change in execution time compared to the feature on functions. The reason for is due to the relatively low impact compared to the time it takes to pass messages between actors.

For both these tests the overhead was less than 50% and explanations are provided.

Hence the requirements are satisfied for default parameters.

10 Results and discussion

The aim of this project was to implement and evaluate three new features in the lan- guage. The project resulted in implementations of two new syntactic features:

• Default field values

• Default parameters

The project did not fully satisfy the aims. Multiple initializers were not implemented due to time constraints.

A survey was also done to evaluate the usability and importance of all three features.

The survey results showed that the participants would both prefer to read code with de-

fault field values as well as to use default parameters over a solution that emulated the

same feature. The participants would rather write a function that provided arguments

instead of providing default parameters in the function declaration. The multiple ini-

tializers were shown to be understandable but was not something that the participants

(25)

12 Future work

would write in their own code. The most important factor when deciding which code the participants preferred was in great majority clarity for all features that were surveyed.

The survey had a good response rate and had relatively many participants. However, the survey was arguably too short and had some shortcomings in the examples which may have skewed the results slightly. The survey had a very narrow demographic with almost only students as subjects. Nonetheless programming experience was represented better with subjects ranging from beginners to experts.

11 Conclusions

Default field values and default parameters are now available for Encore’s developer community. The survey participants preferred the Encore code with the implemented features compared to Encore code written without them. This indicates that the Encore language with the new features is more accessible for potential developers. However, a greater part of the participants preferred code written without our new syntax features than we had expected. The reason for this, we believe, is that the code examples given in the survey failed to highlight the full utility of our new features, in particular default parameters and multiple initializers. The project resulted in a better understanding of what syntax the general developer appreciate given the survey results. Developing ex- perience and general completeness for the Encore language was improved as a result of the project.

12 Future work

There is still room for improvements regarding syntax features in Encore. Below we have specified some improvements of the features that we have implemented as well as additional features that this project has identified as possible future work.

12.1 Default field values

There is a flaw in the design of the default field values: the implementation does not prohibit cyclic references like shown in the example below.

Illustrating a cyclic reference that could potentially cause problems if not properly ac-

counted for.

(26)

12 Future work

a c t i v e c l a s s MyClass

v a r a : S t r i n g = t h i s . b v a r b : S t r i n g = t h i s . a end

To circumvent this problem the implementation can be made to only allow certain ex- pressions to be assigned to the parameter. By limiting the expressions that can be used as a default field value cyclic reference can be avoided. However, this limits the usabil- ity of default field values. A suggestion of further work is to add logic to prevent the issue with cyclic references.

12.2 Multiple initializers

Encore currently only allow one constructor method on each class. The proposed fea- ture is to allow an arbitrary number of constructors on each class.

Current syntax:

Illustrating how the initialization method looks in Encore currently

a c t i v e c l a s s MyClass d e f i n i t ( ) : u n i t

. . . end end

Proposed syntax for declaration of initializers:

Illustrating how several initialization methods could be defined on the same class. With this syntax each initialization method would have a unique name and be identified by the new keyword.

a c t i v e c l a s s MyClass

d e f new i n i t W i t h N u m b e r ( number : i n t) : u n i t . . .

end

d e f new i n i t W i t h S t r i n g ( s t r : S t r i n g) : u n i t . . .

end

(27)

12 Future work

d e f new a n o t h e r I n i t M e t h o d ( ) : u n i t . . .

end end

Proposed syntax for creating instances:

Illustrating how an object could be instantiated from the different initialization methods provided by the class.

v a l a = new MyClass . i n i t W i t h N u m b e r ( 1 0 ) v a l b = new MyClass . i n i t W i t h S t r i n g (” Ten ”)

A simple solution that accommodates for the syntax shown above is to translate each constructor to an ordinary method that return an instance of the class.

Before translation

d e f new i n i t W i t h S t r i n g ( s t r : S t r i n g) : u n i t . . .

end

After translation

d e f i n i t W i t h S t r i n g ( s t r : S t r i n g) : MyClass . . .

r e t u r n t h i s end

Initialization methods should only be accessible to instantiate an object. This implies that logic that prevents the method to be called at other times need to be implemented.

This behavior can already be found in the current implementation of the single initial- ization method in Encore and inspiration could be taken from there.

The solution also needs to accommodate for our implementation of default field val- ues discussed in 7.1. That is, initialization of default field values can be placed in the beginning of every initialization method.

12.3 Object finalizers

Object finalizers is a feature that gives programmers the ability to perform manual deini-

tialization of an object before it is deallocated, that is when the object is removed from

further use in the program. This is useful when an object has a resource that should be

(28)

12 Future work

closed before the object is deallocated. For example if the object has opened some files the finalize method could be used to close those files.

Finalize method:

Our proposed syntax for declaring the finalize method.

a c t i v e c l a s s MyClass

d e f f i n i a l i z e ( ) : u n i t

/ / do m a n u a l c l e a n u p end

end

Encore’s run-time have support for finalizers. The support includes the ability to invoke a method on an object before the garbage collector collects the object. The part missing is the front-end, i.e. the part exposed to the programmer.

An implementation needs to account for various aspects. There needs to be a way of declaring the finalize method. This could be implemented by defining a specific method name “finalize” in the same fashion as the method name “init” for constructors. This method should only be called by the garbage collector. To accomplish this inspiration could again be taken from the init method which is only accessible when initializing an object. The semantics of the finalize method also need to be considered, more specific what operations should be allowed to be performed inside the method. There are sev- eral operations that should not be done in a finalize method. One example is to save a reference to the object that is soon to be deallocated, as this would result in a dangling reference or dangling pointer. A dangling reference is a reference to a deallocated, i.e. a non-existing, object. It is also important that the implementation of the front-end do not malfunction in any way, as such could lead to crashes at runtime, performance issues and general unpredicted behavior of programs written in Encore.

12.4 Wrapped primitive

In certain cases it is useful to wrap a primitive type, e.g. int, to provide extended con-

trol of the value. One case of this is when it is desired to restrict the set of values the

type contains. Another case is if two variables are coupled to achieve an extended set

of values type contains. For example if a digit type is desired an int constant could be

wrapped in a class with an initialization method that only allows values between 0 and

9. This is illustrated in the code snippet below.

(29)

12 Future work

The wrapper class approach:

c l a s s D i g i t −− o b j e c t t y p e

v a l v a l u e : i n t −− p r i m i t i v e t y p e d e f i n i t ( d i g i t : i n t) : u n i t

a s s e r t T r u e ( 0 <= d i g i t && d i g i t <= 9 ) −− r e s t r i c t i o n t h i s . v a l u e = d i g i t

end

d e f b e f o r e ( y : D i g i t) : b o o l −− m e t h o d s on an i n s t a n c e o f t h e t y p e t h i s . v a l u e < y . v a l u e

end

d e f a f t e r ( y : D i g i t) : b o o l t h i s . v a l u e > y . v a l u e end

. . . end

This approach succeeds in restricting the wrapped values to the expected values, i.e. the integer numbers from 0 to 9. It also achieves an object oriented design which is suitable to the actor model discussed in 2.2. Objects of the Digit type can be created and method calls can be made like illustrated below.

The wrapper class approach:

Creating two values of the Digit type and making a method call.

v a r a : D i g i t = D i g i t( 5 ) −− O b j e c t c r e a t i o n v a r b : D i g i t = D i g i t( 6 ) −− O b j e c t c r e a t i o n a . a f t e r ( b ) −− method c a l l on o b j e c t a

The problem with this approach is the introduced performance overhead. The Digit type

is now an object type instead of a primitive int value. Suppose that we have an array

of 1000 Digit values and that the Digit type is an object type. Since an object type is a

reference type this would result in a sequence of pointers pointing to different memory

locations in the generated C-code. Iterating through the values of the array would, for

instance, provide inferior performance to an approach where the array contain values of

a primitive type. An approach that achieves exactly that is illustrated in the code snippet

below.

(30)

12 Future work

The typedef approach:

t y p e d e f D i g i t = i n t −− p r i m i t i v e v a l u e f u n n e w d i g i t ( d i g i t : i n t) : D i g i t

a s s e r t T r u e ( 0 <= d i g i t && d i g i t <= 9 ) −− r e s t r i c t i o n o n l y when u s i n g t h i s method

y e a r end

f u n b e f o r e ( t h i s : D i g i t , y : D i g i t) : b o o l −− f u n c t i o n w i t h two f o r m a l p a r a m e t e r s o f t h e D i g i t t y p e

t h i s < y end

f u n a f t e r ( t h i s : D i g i t , y : D i g i t) : b o o l t h i s > y

end

In this solution the Digit type is a primitive type. However the notation for using the functions defined for the Digit type is cumbersome.

The typedef approach:

Creating two values of the Digit type and making a function call.

v a l a : D i g i t = n e w d i g i t ( 1 ) v a l b : D i g i t = n e w d i g i t ( 2 ) b e f o r e ( a , b )

Additionally the digit type and the int type can in this approach be used interchangeably.

This means that methods that have parameters of type Digit could be called with a value of the int type as well as the Digit type. It also means that a variable of the Digit type can hold any value a variable of the int type can hold.

The typedef approach:

The Digit type is interchangeable with the int type. Consequently the restriction achieved in the wrapper class approach can not be given. The example below illustrates that a value of the Digit type can be assigned any value in the set of int values.

v a l d i g i t : D i g i t = −1234 v a l d i g i t : D i g i t = 12

This behavior is clearly not optimal. The only difference between an int and a Digit is

(31)

References

the name. All this accomplishes is a more expressive syntax where the name of the data more precisely describes what that data is expected to be. But this is only part of the benefits in the approach of the wrapper class.

A solution that achieves the same behavior as the wrapper class approach and has the performance benefits of the typedef approach is optimal. This could be achieved by translating all the objects that purely contain field values of primitive types into some- thing that is more efficient. Preferably after type checking is done so the part exposed to the front-end keeps the benefits of the wrapper class approach. Front-end refers to the part that is exposed to the programmer writing in the Encore language. The afore- mentioned approach with typedef would work fine. In that case all method calls could be translated like illustrated below.

Before translation

v a r a : D i g i t = D i g i t( 5 ) v a r b : D i g i t = D i g i t( 6 ) a . a f t e r ( b )

After translation

v a r a : D i g i t = n e w d i g i t ( 5 ) v a r b : D i g i t = n e w d i g i t ( 6 ) a f t e r ( a , b )

The typedef approach provides great performance benefits. The Digit type is not a object type but instead a primitive value. Suppose as previously that we have an array of 1000 values of the Digit type in the C-code. This yields an continuous allocated memory block containing the elements of the array. Iterating through the elements of the array in this implementation should perform much better than in the wrapper class approach.

References

[1] “Dynamic Tracing Guide,” http://dtrace.org/guide/bookinfo.html, (Accessed on 05/15/2017).

[2] G. A. Agha, “Actors: A model of concurrent computation in distributed systems.”

DTIC Document, Tech. Rep., 1985.

[3] A. V. Aho, M. S. Lam, R. Sethi, and J. D. Ullman, Compilers: Principles, Techniques and Tools, 2nd ed. Pearson, 2007. [Online]. Available: http://www.

informatik.uni-bremen.de/agbkb/lehre/ccfl/Material/ALSUdragonbook.pdf [4] C. Anslow, S. Markstrum, and E. Murphy-Hill, “Evaluation and usability

of programming languages and tools (plateau),” School of Engineering and

(32)

References

Computer Science Victoria University of Wellington, New Zealand, Tech. Rep., 7 2010. [Online]. Available: http://gustavopinto.org/lost+found/plateau2015.pdf [5] Apple Inc, “Cocoa core competencies. multiple initializers,” https:

//developer.apple.com/library/content/documentation/General/Conceptual/

DevPedia-CocoaCore/MultipleInitializers.html, (Accessed on 05/15/2017).

[6] ——. Function argument labels and parameter names. [Online].

Available: https://developer.apple.com/library/content/documentation/Swift/

Conceptual/Swift Programming Language/Functions.html [7] ——. Instruments User Guide.

[8] ——, “Objective-c. apple developer documentation,” https://developer.apple.com/

reference/objectivec, (Accessed on 05/15/2017).

[9] ——, “The swift programming language (swift 3.1),” https://developer.apple.com/

library/content/documentation/Swift/Conceptual/Swift Programming Language/.

[10] S. Borkar and A. A. Chien, “The future of microprocessors,” Commun.

ACM, vol. 54, no. 5, pp. 67–77, May 2011. [Online]. Available: http:

//doi.acm.org/10.1145/1941487.1941507

[11] E. Castegren and T. Wrigstad, “Kappa: Insights, current status and future work,” Uppsala University, Tech. Rep., 2016. [Online]. Available:

http://uu.diva-portal.org/smash/record.jsf?pid=diva2%3A1052902&dswid=-6593 [12] ECMA International, Standard ECMA-262 - ECMAScript Language Specification, 5th ed., June 2011. [Online]. Available: http://www.ecma-international.org/

publications/standards/Ecma-262.htm

[13] J. ”Gosling, B. Joy, G. Steele, G. Bracha, and A. Buckley, The Java® Language Specification Java SE 8 Edition, 8th ed. 500 Oracle Parkway, Redwood City, California 94065, U.S.A.: Oracle America, Inc, mar 2015.

[14] D. Grune, K. van Reeuwijk, H. E Bal, C. J. H. Jacobs, and K. Langendoen, Modern Compiler Design, 2nd ed. Springer, 2012. [Online]. Available: https://comsciers.files.wordpress.com/2015/12/

dick-grune-bal-jacobs-langendoen-modern-compiler-design-wiley.pdf

[15] C. Hewitt and H. G. Baker, “Laws for communicating parallel processes.” in IFIP Congress, 1977, pp. 987–992. [Online]. Available: http://dblp.uni-trier.de/

db/conf/ifip/ifip1977.html#HewittB77

[16] A. Hunt, The pragmatic programmer. Pearson Education India, 2000.

(33)

References

[17] T. Kelly, Y. Wang, S. Lafortune, and S. Mahlke, “Eliminating concurrency bugs with control engineering,” Computer, vol. 42, no. 12, 2009.

[18] J. F. Kurose, Computer networking: A top-down approach featuring the internet, 3/E. Pearson Education India, 2005.

[19] S. Marlow, S. P. Jones et al., “The glasgow haskell compiler,” 2004.

[20] R. H. Netzer and B. P. Miller, “What are race conditions?: Some issues and for- malizations,” ACM Letters on Programming Languages and Systems (LOPLAS), vol. 1, no. 1, pp. 74–88, 1992.

[21] M. Odersky, The Scala Language Specification Version 2.9. Switzerland: PRO- GRAMMING METHODS LABORATORY EPFL, jun”, chapter = 2014.

[22] M. Odersky, P. Altherr, V. Cremet, G. Dubochet, B. Emir, P. Haller, S. Micheloud, N. Mihaylov, A. Moors, L. Rytz, M. Schinz, E. Stenman, and M. Zenger. Scala language specification (version 2.12), classes and objects. [Online]. Available:

https://www.scala-lang.org/files/archive/spec/2.12/05-classes-and-objects.html [23] B. Roscoe, “The theory and practice of concurrency,” 1998.

[24] Scala Language. Scala language specification (version 2.12). [Online]. Available:

https://www.scala-lang.org/files/archive/spec/2.12/

(34)

A Survey

A Survey

The survey was sent to 30 students we knew have programming experience. 26 people answered, which is a response rate of 87%.

This survey is part of the evaluation of our Independent Project in Information Engi- neering. The purpose of the project is to implement some features in the object-oriented programming language Encore. The survey is aimed at people familiar with program- ming. Thank you for your participation!

Lowe Eklund Karolina Nikamo Casper Str¨omberg

A.1 Background questions

1. How would you describe your programming experience level?

See results in Figure 4.

Figure 4: The test participants’ self-assessment of their programming experience level.

2. What is your main occupation? Choose one alternative.

See result in Figure 5.

(35)

A Survey

Figure 5: The test participants’ main occupation.

Previous experience

For questions 3-5 you can choose between three options. If you have experience from both school and work, choose the option “Yes, I have working experience”.

- No

- Yes, I have experience from school/university - Yes, I have working experience

3. Do you have previous experience of object oriented programming languages? Ex- amples of such languages are Java, Swift, C++ and C#.

4. Do you have previous experience of functional programming languages? Exam- ples of such languages are Haskell and Erlang.

5. Do you have previous experience of imperative programming languages? Exam- ples of such languages are C and C#.

See results for questions 3-5 in Figure 6.

(36)

A Survey

Figure 6: The test participants’ previous experience in three different types of program- ming languages.

A.2 Default field values

The alternatives in Figure 7 are code snippets written in Encore. Both alternatives yield the same result.

a c t i v e c l a s s MyClass

v a r a : S t r i n g = ” h e l l o ” . . .

(a)

a c t i v e c l a s s MyClass v a r a : S t r i n g d e f i n i t ( )

t h i s . a = ” h e l l o ” . . .

(b)

Figure 7: Every new instance of MyClass will have a variable a with value “hello”.

1. Which piece of code in Figure 7 is easiest to understand in your opinion? See result in Figure 8a.

2. Which piece of code in Figure 7 would you write if you were going to write a

program? See result in Figure 8a.

(37)

A Survey

3. What did you consider to be most important when answering the questions above?

Choose one alternative. See result in Figure 8b.

(a) Test participants’ opinion on which code snippet (A or B, Figure 7) was easiest to under- stand/write. Alternative A was the code with support for default field value syntax. Alterna- tive B was the code with “old” syntax.

(b) What test participants considered most im- portant when deciding which code snippet was easiest to understand/write.

Figure 8: Results for questions about default field values.

A.3 Multiple initializers

The alternatives in Figure 9 are code snippets written in Encore. Both alternatives yield

the same result.

(38)

A Survey

a c t i v e c l a s s Main d e f main( ) : u n i t

new P u p i l ( 2 5 ) new P u p i l ( −1) end

end

l o c a l c l a s s P u p i l

d e f i n i t ( a g e : i n t) : u n i t i f ( a g e == −1) {

p r i n t l n(” no a g e ”) } e l s e {

p r i n t l n( a g e ) }

end end

(a)

a c t i v e c l a s s Main d e f main( ) : u n i t

new P u p i l . w i t h A g e ( 2 5 ) new P u p i l . w i t h o u t A g e ( ) end

end

l o c a l c l a s s P u p i l

d e f new w i t h A g e ( a g e : i n t) : u n i t p r i n t l n( a g e )

end

d e f new w i t h o u t A g e ( ) : u n i t p r i n t l n(” no a g e ”)

end end

(b)

Figure 9: Both alternatives will create two instances of Pupil: one with age 25 and one without an age.

1. Which piece of code in Figure 9 is easiest to understand in your opinion?. See result in Figure 10a.

2. Which piece of code in Figure 9 would you write if you were going to write a Encore program? See result in Figure 10a.

3. What did you consider to be most important when answering the questions above?

Choose one alternative. See result in Figure 10b.

(39)

A Survey

(a) Test participants’ opinion on which code snippet (A or B, Figure 9) was easiest to un- derstand/write. Alternative A was code with

“old” syntax. Alternative B was the code with support for multiple initializers syntax.

(b) What test participants considered most im- portant when deciding which code snippet was easiest to understand/write.

Figure 10: Results for questions about multiple initializers.

A.4 Default parameters

The alternatives in Figure 11 are code snippets written in Encore.

1. Which piece of code in Figure 11 is easiest to understand in your opinion? See result in Figure 12.

2. Which piece of code in Figure 11 would you write if you were going to write a Encore program? See result in Figure 12.

3. What did you consider to be most important when answering the questions above?

Choose one alternative. See result in Figure 13.

(40)

A Survey

a c t i v e c l a s s Main d e f main( ) : u n i t

p r i n t l n( t e s t A d d e r ( 1 , 2 , 3 ) ) p r i n t l n( t e s t A d d e r b ( 1 , 2 ) ) p r i n t l n( t e s t A d d e r a ( 1 ) ) end

end

f u n t e s t A d d e r ( a : i n t , b : i n t , c : i n t) : i n t a + b + c

end

f u n t e s t A d d e r a ( a : i n t) : i n t t e s t A d d e r ( a , 0 , 0 )

end

f u n t e s t A d d e r b ( a : i n t , b : i n t) : i n t t e s t A d d e r ( a , b , 0 )

end

(a)

a c t i v e c l a s s Main

d e f main( ) : u n i t

p r i n t l n( t e s t A d d e r ( 1 , 2 , 3 ) ) p r i n t l n( t e s t A d d e r ( 1 , 2 ) ) p r i n t l n( t e s t A d d e r ( 1 ) ) end

end

f u n t e s t A d d e r ( a : i n t , b : i n t = 0 , c : i n t = 0 ) : i n t a + b + c

end

(b)

a c t i v e c l a s s Main

d e f main( ) : u n i t

p r i n t l n( t e s t A d d e r ( 1 , 2 , 3 ) ) p r i n t l n( t e s t A d d e r ( 1 , 2 , 0 ) ) p r i n t l n( t e s t A d d e r ( 1 , 0 , 0 ) ) end

end

f u n t e s t A d d e r ( a : i n t , b : i n t , c : i n t) : i n t a + b + c

end

(c)

Figure 11: All the alternatives yield the same result. The code will calculate and then

(41)

A Survey

Figure 12: Test participants’ opinion on which code snippet (A, B or C in Figure 11) was easiest to understand/write. Alternative B was the code with support for default parameters syntax. Alternative A and C were code with “old” syntax.

Figure 13: What test participants considered most important when deciding which code

snippet (in Figure 11) was easiest to understand/write.

(42)

B Performance results

B Performance results

Default parameters, actor with method

Default parameters,

function Default field values Loop: 5 000 000 Loop: 100 000 000 Loop: 100 000 000

WITH WITHOUT WITH WITHOUT WITH WITHOUT

24 25 3.09 2.85 6.95 6.75

18 18 3.71 2.71 6.21 6.15

20 17 3.65 2.73 6.95 6.44

17 18 3.56 2.79 6.84 6.85

16 16 3.59 2.76 6.84 6.92

21 18 3.59 2.82 6.87 6.71

22 19 3.63 2.81 6.49 6.25

18 16 3.87 2.81 6.92 6.86

20 17 3.77 2.82 6.86 6.74

18 16 3.67 2.79 6.74 6.93

19.4 18.0 3.61 2.79 6.77 6.66 Average

execution time (s)

7.78% 29.54% 1.61% Execution overhead

with feature Table 1: Performance tests results. WITH refers to code with the implemented feature.

WTIHOUT refers to code without the implemented feature, i.e. “old” syntax.

References

Related documents

46 Konkreta exempel skulle kunna vara främjandeinsatser för affärsänglar/affärsängelnätverk, skapa arenor där aktörer från utbuds- och efterfrågesidan kan mötas eller

Generally, a transition from primary raw materials to recycled materials, along with a change to renewable energy, are the most important actions to reduce greenhouse gas emissions

För att uppskatta den totala effekten av reformerna måste dock hänsyn tas till såväl samt- liga priseffekter som sammansättningseffekter, till följd av ökad försäljningsandel

Från den teoretiska modellen vet vi att när det finns två budgivare på marknaden, och marknadsandelen för månadens vara ökar, så leder detta till lägre

The increasing availability of data and attention to services has increased the understanding of the contribution of services to innovation and productivity in

Generella styrmedel kan ha varit mindre verksamma än man har trott De generella styrmedlen, till skillnad från de specifika styrmedlen, har kommit att användas i större

Parallellmarknader innebär dock inte en drivkraft för en grön omställning Ökad andel direktförsäljning räddar många lokala producenter och kan tyckas utgöra en drivkraft

I dag uppgår denna del av befolkningen till knappt 4 200 personer och år 2030 beräknas det finnas drygt 4 800 personer i Gällivare kommun som är 65 år eller äldre i