<<

Linköping university | Department of Computer and Information Science Bachelor’s Thesis, 16 hp | Bachelor’s Programme in Programming Spring term 2019 | LIU-IDA/LITH-EX-G--19/032--SE

The Usefulness of Programming

Languages Beyond

Alexander Jonsson

Supervisor: Jalal Maleki Examiner: Rita Kovordanyi

Linköping universitet SE-581 83 Linköping 013-28 10 00, www.liu.se

The Usefulness of Programming Languages Beyond Java Alexander Jonsson Linköping, Sweden [email protected]

1 ABSTRACT their pros and cons. For example, the JVM is designed for Beyond Java, new programming languages running on the Java which is a statically typed programming language, (JVM) have been developed, such as meaning it is not optimized for dynamically typed Kotlin, Scala, JRuby and amongst others. Since all programming languages running on the JVM [4, 5], such as these languages compile to Java, it is theoretically possible JRuby and . Though, dynamic typing can be beneficial to use them together in the same project. This paper in some cases, for example when creating a short program investigates if this is possible and what benefits it gives using [6]. In the end, the desired properties of a programming those programming languages together in a project. The language are partly dependent on what problem is going to languages chosen to be used together were Jython, Scala and be solved [7]. Kotlin. The purpose of this work is to decide if it is possible to use An experiment was conducted where in a single project, each multiple programming languages running on the JVM programming language was assigned a problem to be solved. together in a single project. Also, we try to decide if this is The experiment was then conducted in two iterations where relevant by looking at the benefits this gives. To answer this, in each iteration, the problems to be solved was assigned to the following research questions are formulated: a different programming language. • RQ1: Is it possible to use Jython, Scala and Kotlin in a Our experiment show that using these languages together in single project? If that is the case, what problems arise? a project was possible but resulted in some complications that need to be addressed. It was also shown that the • RQ2: To what type of programming problems is Jython, following division amongst the languages worked best in the Scala or Kotlin the preferred choice when used together in a present use case: Jython for graphical handling, Scala for single project? calculating and computing and Kotlin for data-handling. 2.1 The Scope of This Work 2 INTRODUCTION RQ2 will not be answered regarding all types of problems. Java is one of the most popular programming languages The answer is limited based on the problems solved in the today. According to Oracle, several billion devices were experiment. Also, due to insufficient time, not all running Java in 2010 [1]. Also, Java had the most job demand combinations of programming languages for all problems in 2017 [2]. Java was created with the purpose of eliminating will be tested. Though, problems out of scope from the the recurring hardware incompatibility problems for experiments will theoretically be discussed. software developers. The problems are caused by the fact The following three programming languages running on the that different hardware requires different instructions for JVM is chosen to be investigated: doing the same work. This issue was solved by implementing Java on a Java Virtual Machine (JVM). A JVM is basically • Jython, a scripting (interpreted) and dynamically typed a virtual computer, giving the CPU instructions according to programming language. the given Java-formatted [3]. Therefore, Java code • Scala, compiled and statically typed with support for can be run on any device having the JVM installed, making functional programming. Java code platform independent. • Kotlin, compiled and statically typed, commonly used for Android development. Given its popularity and platform independency, it is not surprising that programming languages other than Java have 3 THEORY been created to run on the JVM. Examples of such Because Jython, Scala and Kotlin all run on the JVM, the programming languages are Kotlin, Scala, JRuby, Jython, JVM is first introduced in the theory section. Next, a short Clojure and many others. Since all those programming overview of Jython, Scala and Kotlin is given. Then, the languages are compiled to JVM code in the end, it should be different properties of these programming languages, as well possible to combine multiple languages together in a project as how these properties affect implementation of the JVM regardless of the languages’ properties. For example, if the are investigated. In the last section, the different language is interpreted, compiled, dynamically typed or programming paradigms used by Jython, Scala and Kotlin static typed. All these types of programming languages have are investigated. However, some programming language 1 concepts that will be used throughout this paper are first 3.5 Kotlin described. Kotlin is just like Scala a statically typed and compiled programming language implemented on the JVM, with 3.1 Programming Language Concepts support of object-oriented programming. It is mostly used for Typing of a programming language can either be static or Android development as a replacement for Java for various dynamic. Dynamic typing means that a variable’s type is not reasons including the shorter and cleaner code. Also, Kotlin decided until runtime of a program, whereas static typing is not nullable per default, making it safer than Java [10]. means that the type must be declared before running the program. 3.6 Properties of Jython, Scala and Kotlin In Appendix 1 some of the most important properties of Purely object-oriented means that all variables are objects Jython, Scala and Kotlin can be seen. The different and all operations are method calls, i.e. there are no primitive properties of these programming languages can be a potential datatypes [8]. source of problems when trying to use them in a single Nullable means that a variable can both have and be assigned project. For example, the data structures are defined for a the null value. The null value is used in programming to specific programming language, meaning the data structures represent an object with no set value, which can be are very confined inside its own space [7]. Though, with their problematic if not expected. For example, a program will own implementation of the JVM for Jython, Scala and Kotlin crash if you are trying to access a function on a null value makes it possible, since the data structures inside the JVM when you were expecting an actual object value. will be the same in the end. Programming paradigm is basically a pattern or model in As seen in in Appendix 1 Scala is purely object-oriented how to write code. It defines how a programming language while Jython and Kotlin are not. Since there are only is constructed which gives rise to different ways to program. primitive and reference types in the JVM [3], all datatypes when compiling Scala code to should 3.2 Java Virtual Machine technically be references. However, the JVM for Scala is Java was first created with the purpose of being able to run implemented so that all objects representing the typical compiled code transferred between networks. The rise of the primitive datatypes (such as int, float and char) are actually World Wide Web allowed multiple users with different converted to a primitive representation inside the JVM [8]. hardware and network connections access websites. Though, Therefore, the fact that Scala is purely object-oriented should these websites were using HTML which had limited be able to be ignored in regard to RQ1. functionality. Therefore, the HotJava browser was created Since Scala and Kotlin are both compiled to Java bytecode it which allowed websites to download compiled Java would be favorable if Jython also could compile to Java bytecode that could be run on the website. This was done bytecode. Though, since Jython is based on Python, it is an using the JVM which is basically a virtual computer giving interpreted programming language and cannot be compiled instructions to the CPU from a set of possible instructions as seen in Appendix 1. However, this is only true per default specified by the JVM. What instructions to use depends on since it is possible to compile Jython code to JVM class-files the implementation of the programming language running on packaged to classic “.jar”-files using the “jythonc”-compiler the JVM [3], meaning the implementation affects the [9, p. 16]. Unfortunately, this is no longer possible in the performance [9, p. 13]. Though, before going into detail newer versions of Jython. Instead we must use a work- about the programming language’s different properties and around. The work-around basically works by importing a how it affects their implementation on the JVM, we will give Java-interface in Jython, that the Jython-class needs to a brief overview of Jython, Scala and Kotlin. extend. Then, inside Java the Jython-module is imported and converts the class inside the module to same type as the Java- 3.3 Jython interface, using an -object provided by the Jython- Jython is basically Python that works together with Java. package. Note that the Jython types corresponds to a similar Python is a dynamically typed and interpreted scripting Java type and is converted using type coercion [11]. As one language with high-level functionality and Jython is could argue, using the work-around results in extra work and basically the Python programming language implemented in could result in overhead regarding the performance. Though, Java. This means Jython can be run on the JVM, making using Jython together with Scala and Kotlin together in a Jython compatible with Java and other programming project will most likely require using the work-around. On languages also running on the JVM [9]. the contrary, for Jython to be able to import a Java-package (outside of the Java standard library), its JAR-file needs to 3.4 Scala be added to the [11]. This should also apply if Scala is a statically typed and compiled programming you are going to import a Scala or Kotlin-package, since the language implemented on the JVM. It is both an object- class-files are just like Java, also packaged to a JAR-file. oriented and a functional programming language aimed to be used for creating component-based systems [8].

2

The default value of a reference is null in the JVM [3] and as during the interpretation of the Jython-code. This bytecode seen in Appendix 1, Kotlin is not nullable. Though, it is mostly consists of code needed for Python-code in order to possible to add a question mark after the datatype to allow run with an implementation of Java, for example Python’s variables having the null value [12, p. 202]. Additionally, exec function [9, p. 218]. Kotlin maps imported Java types to nullable Kotlin Type erasure means that you force the JVM to decide the representation called platform types [13]. Though, when type during compilation. This means that for example the assigning a null value to a Kotlin-variable it will only work declarations List and List will be seen as when no type is specified, or the type specified includes a List in the compilation step [12, p. 223]. Therefore, question mark. If the type is specified without a question functions with same name but different generic types in the mark it will compile but fail during runtime because the parameter list will not be possible, see example in Listing 2. returned type can’t be null. Listing 1 shows an example of Though, this can be solved in Kotlin by adding the how this works. All these ways to allow nullable variables @JvmName-annotation above the function name [12, p. inside Kotlin makes it easier to use Kotlin together with 224], see example in Listing 3. Scala and Jython that both are nullable.

// Will compile but fail during runtime fun sort(list: List): Unit = {…} val testNull: String = fun sort(list: List): Unit = {…}

// Will compile and work during runtime Listing 2. Example of non-compiling code val testNull = val testNull: String? = Listing 1. Example of Kotlin platform types and its behavior @JvmName("sortString") fun sort(list: List): Unit = {…} @JvmName("sortInt") The different properties of Jython, Scala and Kotlin also fun sort(list: List): Unit = {…} means they each need their own JVM implementation. The implementation could affect performance in some cases, thus Listing 3. Example of compiling code making that language less relevant for solving a specific problem. Type erasure is also a problem in Scala but can be solved using modules such as ClassTag, TypeTags or Manifest As seen in Appendix 1, all programming languages can found in Scala’s scala.reflect1 library. The fact that Jython is import Java-packages. Since all of Jython, Scala and Kotlin dynamically typed prevents code like in Listing 2 in the first in the end is Java bytecode, this means they should place. theoretically be able to be imported just like a Java package as well. Though, the different properties can affect the Deciding which of Jython, Scala and Kotlin is the best choice performance of these imports. For example, Scala supports for a specific problem is not only affected by its JVM multi-inheritance while the JVM does not. Therefore, it is implementation. It is also affected by its properties in required to copy the code from one of the inherited classes general. For example, Jython is said to reduce the amount of into the base class. Also, Scala has no support for static class code by half compared to Java. Since shorter code is said in members. Therefore, Scala must divide the Java classes into many empirical studies to reduce number of bugs [9, p. 9], a singleton class and a regular class, containing static Jython should in general be a good choice for most members and dynamic members respectively [8]. programming problem. Since JVM was designed for Java, which is a statically typed XML is commonly used to store configuration or data and programming language, the JVM contain instructions for Scala makes the handling of XML easy. Furthermore, Scala specific datatypes [3] and is not optimized for dynamically is also being planned to be extended with support for typed languages. Up until recently in 2011, there were no database query languages [8]. Therefore, Scala could be support for implementation of dynamic types inside the JVM more relevant when dealing with problems regarding data [14] (more specifically the bytecode instruction handling. invokedynamic was introduced [3]). Therefore, there is still Static typing makes type errors be detected during ongoing progress and research regarding optimization and compilation and makes the code stricter in general [15]. This performance of dynamic JVM-languages [4, 5]. As seen in means static typing is often more relevant in a larger project Appendix 1, Jython uses dynamic typing compared to Scala that needs to be maintainable. On the other hand, if one and Kotlin meaning the performance of Jython should be would want to write a smaller program it is often quicker and theoretically lower. A practical example of how Jython’s easier using a programming language with dynamic typing dynamic typing affects the performance is that to speed up [6]. the compilation of Jython-code, Java bytecode is generated

1https://www.scala- lang.org/api/2.12.3/scala/reflect/index.html 3

3.7 Programming Paradigms 4 METHOD When choosing what programming language to use for a To answer the research questions, an experiment was specific problem, it is also relevant to look at the paradigms conducted in where modules were created, each with a of that language. The solution to a problem will be different different role or problem to solve. The modules were also based on the paradigm used. A guideline to decide which dependent on one another with each module assigned to paradigm is the best to use is simply to use the paradigm that either Jython, Scala or Kotlin. Then, the modules were tried solves the problem with the least effort. In addition, by to be used together in a project, thus answering RQ1. To also having multiple programming paradigms, it naturally answer RQ2, another iteration of the same experiment was requires the programmer to see the world in different views conducted but with reassigned roles between the [16]. programming languages. By doing that, the solutions of Jython, Scala and Kotlin could be compared to analyze There are essentially two categories of programming which of the programming language or programming paradigms; stateful and stateless. In both categories data can paradigm was the best choice for the module’s particular be created, but stateful paradigms consists of data that can problem to be solved. In addition, the performance in time change over time, which is more closely related to our own for the different solutions and amount of code was also world. Though, stateless programming typically feels more compared. logical and is easier to make sense about. Examples of stateful programming paradigms are imperative and object- In each iteration of the experiment a project was created oriented programming, and examples of stateless using JetBrains’s IntelliJ IDEA2 which is an integrated programming paradigms are functional and logic development environment (IDE) designed specifically for programming [7]. Java. In this project three modules were created, one for each programming language. To create the dependency between Jython, Scala and Kotlin all support both the imperative and the modules Gradle3 was used, which is a tool that helps object-oriented paradigm. Though, Scala also supports the during development of applications, for example with the functional programming paradigm [8]. Since the definition building of a project. of a multiparadigm programming language is that the language must support multiple paradigms [16], all of 4.1 The Experiment Jython, Scala and Kotlin are multiparadigm programming The goal of the experiment was to create a program that languages. Therefore, it is important to note which calculates the average score of movies with a specific genre. programming paradigm is used when answering RQ2. This required three fundamental problems to be solved; The basic and simple definition of an imperative handling the data of movies, calculating the average score for programming language is that it uses statements that changes the specified genre and handling user interaction by allowing the state of a program [17]. The typical way of changing the the user to specify a genre and graphically display the result. state of a program is to reassign variables. In other words, there was a need for a data-layer, logic-layer and a graphical user interface (GUI). These layers could then What defines an object-oriented programming language is in iteration 1 and 2 of the experiment, each be assigned a the support of creating objects consisting of data and/or different programming language. By using this multi-tier operations [18], created from a blueprint called a class. Since architecture, it naturally created dependencies between the these objects are instantiated from a class typically with modules and each layer gets its own problem to solve. In the different values, thus changing the state of the program, it next sections it is briefly explained how the modules in the could be said that object-oriented programming languages project works. naturally also becomes imperative. The main idea behind a functional language is that functions 4.1.1 Data-Layer are regarded as values [16]. Also, the functional paradigm is The data-layer module works by loading a local CSV-file defined as being stateless, meaning the values of variables created from TMDB4, filtering the search based on the are never modified. Therefore, data is typically evaluated on specified genre. Without doing any logic it only returns a list the go. Appendix 2 shows an example of using the functional with the filtered movies’ average score (it could also return paradigm in Scala. Note that no data is being changed and the movies’ title and other interesting information to make everything is evaluated on the go. Also, the division the solution more general). expression is a function call, showing another example that Since the GUI-layer needed all the unique genres for the user Scala is purely object-oriented. to choose from, a function returning a list of strings containing the unique genres was created. This list is

2 https://www.jetbrains.com/idea/. 4 https://www.themoviedb.org/ 3 https://gradle.org/ 4 generated simply by searching through each movie’s genres, assignment allowed all the programming languages to have filtering the unique genres. a new role in the project compared to iteration 1, and therefore a new problem to solve. 4.1.2 Logic-Layer The logic-layer module works by fetching data about movies Note that these assignments of roles require Jython to import obtained from the data-layer, inputting the specified genre a Kotlin-module. As explained in section 3.6 this means you received from the GUI-layer. The logic-layer could then must build the Kotlin-module and its dependencies to a JAR- calculate the average score by dividing the sum of all file. This JAR-file then needed to be added to the movies’ score by the number of movies. CLASSPATH before running Jython. In addition, these assignments could try out the fact that Jython is dynamically To get all unique genres for the GUI-layer to use, the logic- typed while Kotlin is statically typed. Also, by assigning layer simply calls the function from the data-layer and Scala to the data-layer it could practically be tried what is returns the result. mentioned in section 3.6, that Scala could be a good choice for data-handling. 4.1.3 GUI-Layer The GUI-layer module is built using the library5. The 4.4 The Experiment - Comparison of Iteration 1 and 2 Swing library is a Java library and is used to build GUI for To compare the solutions between the programming simple desktop applications. The GUI allows the user to languages both iterations were programmed as identical as specify a genre from a list of possible genres that is obtained possible. Though, this was sometimes not desired since the from the logic-layer. Then, when a button is pressed the different properties of the languages affects the decision of average score calculated and obtained from the logic-layer is what language is the preferred choice. For example, Scala displayed. To make it as simple and quick as possible while supports the functional paradigm which could not be tested programming, the graphical components were only stacked if it were to be coded identical as the corresponding module into a grid layout: that does not support the functional paradigm. • JComboBox: filled with all the possible genres the user As explained in the section 3.6, there are factors that should can choose from, received from the logic-layer. theoretically affect the performance of the different • JButton: tells the logic-layer to calculate the average programming languages, such as the work-around needed to score and graphically updates the result. import the Jython-module. Before measuring the • JLabel: used to show the result of the average score and performance in time, the solutions had to be adjusted to make is updated when user presses the button. sure both iterations were as identical as possible. Measuring the time between the solutions of iteration 1 and 2 was simply 4.2 The Experiment – Iteration 1 done by comparing the time before and after running the 6 In the first iteration of the experiment the different roles were code, using the Java-library java.time . Also, lines of code of randomly assigned as following: Jython for the data-layer, the solutions were counted for an additional comparison Scala for the logic-layer and Kotlin for the GUI-layer. measurement.

Note that these assignments of roles require Scala to import 5 RESULT a Jython-module allowing the testing of different typing. Using Jython, Scala and Kotlin could be used together in the Also, since Jython is created to import Java-code [9] and not project in both iterations. Though, during the process of the vice versa, it means the work-around explained in section 3.6 implementation there were some complications that will be is required. Furthermore, these assignments allow the explained in the following sections. The following sections investigation of the fact that Scala is purely object-oriented will also show and explain parts of the resulted code that is and nullable while Kotlin is not. Though, there was no case relevant for the discussion. If you want to have a more in this experiment where it was desired for Scala to return detailed look at the complete code, you can download the null to Kotlin. Therefore, a simple function that only returns source code from GitHub7. The graphical result of the null was created inside the logic-layer. program which is identical to both parts is shown in Appendix 3. 4.3 The Experiment – Iteration 2 In the second iteration of the experiment the different roles 5.1 The Experiment – Iteration 1 were assigned as following: Scala for the data-layer, Kotlin In Listing 4 we see the Kotlin code executed when the user for the logic-layer and Jython for the GUI-layer. This presses the “calculate”-button. The code gets the user’s

5https://docs.oracle.com/javase/7/docs/api/javax/swing/pack 6https://docs.oracle.com/javase/8/docs/api/java/time/packag age-summary.html e-summary.html 7 https://github.com/SalloxWave/ExamWorkCode 5 specified genre, tells the logic-layer to calculate the average def average(list: Iterable[Float]): Float = { score based on that genre and updates the JLabel to display list.sum./(list.size) } the result. def calculateAverageScore(genre: String): Float = { val genre: String = genresComboBox.selectedItem.toString() val movieScores: Array[Float] = val score: Float = logicLayer.calculateAverageScore(genre) datalayer.getMovieScores(genre) val scoreStr = "%.2f".format(score) average(movieScores) avgScoreLabel.text = "Average score of genre " + genre + ": " } + scoreStr Listing 4. Kotlin code executed when the button is pressed Listing 8. Calculating the average score of a specific genre

For the logic-layer to work it needs to import the data-layer Listing 9 shows how Jython filters all movies with the using the work-around. Listing 5-7 shows the specified genre that are used by the logic-layer. High-ordered implementation of the work-around in Scala. In Listing 5 we functions included in Python’s standard library are used to see the creation of a factory class and a call to the create first filter movies with the specified genre and then mapping function expecting to return an object with data type the score of the movie to a new list. Note that the returned DataLayerType. In Listing 6, we can see how this type is list of Floats will be converted to an Array of Floats with defined as a Scala-trait (trait works basically like an interface Jython’s type coercion [11], which can be seen in Listing 8 in other languages) and then implemented by the Jython- (observe that Array class derives from the Iterable-class). module. Then, the Jython-module can be imported, def getMovieScores(self, genre): initialized and converted to the data type DataLayerType return map(lambda m: m.score, list(filter(lambda m: genre in m.genres, self.movies))) with the code shown in Listing 7. Listing 9. Code filtering all movies by a specific genre val datalayer: DataLayerType = new DataLayerFactory().create() In Listing 10 we see a simple function in Scala returning null Listing 5. Creating the data-layer using a factory class and what happens in Kotlin. The first assignment compiled 8 // Scala code but threw the exception java.lang.IllegalStateException from import DataLayerType with a message saying that the return value of the function can’t be null. Though, the rest of the assignment worked. trait DataLayerType { def getMovieScores(genre: String): Array[Float] def getGenres(): Array[String] // Scala code def testNullable(): Movie ={ } null // Jython code } class DataLayer(DataLayerType): def getMovieScores(self, genre): // Kotlin code ... // Will compile but fail during runtime def getGenres(self): val testNull: Movie = logicLayer.testNullable()

... // Will compile and work during runtime val testNull = logicLayer.testNullable() Listing 6. Data-layer implementing the Scala-interface val testNull: Movie? = logicLayer.testNullable()

// Importing the Jython-module and getting a reference to the Listing 10. Testing of returning null to Kotlin DataLayer-class var interpreter: PythonInterpreter = new PythonInterpreter() interpreter.exec("from datalayer import DataLayer") The shown code is the result after some complications were var buildingClass = interpreter.get("DataLayer") solved. The first complication comes with the work-around. // create-function returning an initialized and converted objects of DataLayerType-class With this work-around there were some problems with the def create(): DataLayerType = { path. To be able to import the required Scala-interface as val datalayerObject = buildingClass.__call__() datalayerObject.__tojava__(classOf[DataLayerType]).asInstanceO shown in Listing 6 it was required to be inside the project f[DataLayerType] } environment since the package was created as a dependency using Gradle. At the same time, to import the Jython-module Listing 7. Importing, initializing and converting the data-layer from Scala (using the python-interpreter function exec as shown in Listing 7) the path to the Jython-module either had When the data-layer has been imported the logic-layer can to be hardcoded or added to Jython’s system path. If the path get the data it needs. In Listing 8 we see how the logic-layer was hardcoded, there were problems with different calculates the average score for a specific genre. It divides formatting between Scala and Jython (the python interpreter- the sum of the scores obtained from a high-ordered function object parsed the string as it was, meaning the escaped with the total number of scores. backslashes needed by Scala were ignored). If instead the Jython-module was added to Jython’s system path the Scala-

8https://docs.oracle.com/javase/7/docs/api/java/lang/IllegalS tateException.html 6 interface could not be imported as it was internally and def getMoviesByGenre(genre: String): List[Movie] = { temporarily added to the CLASSPATH when running inside movies.filter(_.genres.contains(genre)).toList } IntelliJ IDEA. The final fix was to create a symbolic link inside Jython’s system path pointing to the Jython-file inside Listing 13. Scala code filtering movies by the specified genre the project. This allowed the Jython-file to be run as if it would have been inside the project, allowing the import of For the Jython-module to be able to import the Kotlin- the Scala-interface. At the same time, Scala could import the package, a packaged JAR-file of Kotlin had to be added to Jython-module since it was in Jython’s system path. the CLASSPATH. This was solved by first compiling both the Kotlin logic-layer and the Scala data-layer, including The second complication arises from the fact that to make their dependencies to a JAR-file. Then, IntelliJ IDEA is the solution more general it was desired to return a dictionary configured, as we can see in Figure 1, to add the absolute type from Jython containing additional data beyond the path of the JAR-files to the CLASSPATH, before running movie’s score. Though, there is no type coercion from the program. Jython’s dictionary to Scala [11]. To solve this, a movie- class could be created and included in the work-around, but it was initially decided to use a less verbose solution, Figure 1. Setting CLASSPATH in run configurations returning a string that could be formatted by Scala. The data was split using the vertical bar sign (‘|’), making it possible To make the code as identical as possible when calculating to split the string into a list, extracting the wanted data. the average score in Kotlin, it was desired to use higher- Finally, since in this case there was only a need to get the ordered functions in the same way as in Listing 8 from average scores, a list of floats could simply be returned, iteration 1. More specifically, it was desired to use the which is a possible type coercion [11]. function map to select all average scores and then use functions such as reduce or sum to calculate the score. The 5.2 The Experiment – Iteration 2 datatype of the returned object from Scala was as seen in In Listing 11 we see what happens when the user presses the Listing 12 from Scala’s standard library. This caused “calculate”-button. Just like in iteration 1, the code works by problems when calling high-ordered functions on the object getting the user’s specified genre, telling the logic-layer to due to syntactic differences (for example, the syntax of calculate the average score based on that genre and displays lambda expression is different between Scala and Kotlin). In the result by updating the JLabel. the end, it was decided to simply iterate the movies, adding average score to a sum variable, as shown in Listing 12. def calculate_score(self): genre = self.genresComboBox.getSelectedItem() avgScore = self.logicLayer.calculateAverageScore(genre) 5.3 The Experiment – Comparison of Iteration 1 and 2 scoreStr = "{0:.2f}".format(avgScore) self.avgScoreLabel.setText("Average score of genre " + Observe that differences between the iterations that are not genre + ": " + scoreStr) objective will be discussed in section 6. Listing 11. Jython code executed when button is pressed Appendix 4 shows how the time in Kotlin was measured using the Java library java.time. Though, it works the same Calculating the average score in Kotlin was done basically in in Jython and Scala. the same way as we see in Listing 8 from iteration 1. Though, as we can see in Listing 12, we don’t use a high-ordered Appendix 5 roughly shows the difference of the performance function to get the sum. in time between iteration 1 and 2. The first column shows the total time it took for the program to initialize and start, and fun calculateAverageScore(genre: String): Float { val movies: scala.collection.immutable.List = rest of the columns roughly shows how many percent of this datalayer.getMoviesByGenre(genre) total time the different parts took to execute. Though, before var sum = 0.0f conducting these tests the function calculating the average for (movie in movies) { sum+=movie.avgScore() scores shown in Listing 8 had to be temporarily changed to } be more identical to the function shown in Listing 12 from return sum / movies.size() iteration 2. }

Listing 12. Kotlin code calculating the average score for a Appendix 6 shows the number of lines of code used for the specified genre different modules. Note that this does not include the imports and the code used for the work-around. The code in Listing 13 is used to filter the movies by a specified genre which is fundamentally done in the same way 6 DISCUSSION as in Listing 9 from iteration 1. Though, note that this time a In the following sections, the result will first be discussed list of objects of the class Movie is returned instead of a list with the aim to answer the research questions. Then, the of Floats. method’s validity will be criticized.

7

6.1 Result – RQ1 6.2 Result – RQ2 As we could see from the experiment it is possible to use In the following sections, RQ2 is first discussed based on the Jython, Scala and Kotlin together in a project. Note that used result of the conducted experiment. Then, RQ2 will be Java libraries such as Swing was easily imported in all discussed based on general theoretical reasons found outside programming languages as expected from Appendix 1. of the result. Though using the languages in the same project did not come without any problems. These problems will be discussed in 6.2.1 The Experiment – Comparison of Iteration 1 and 2 the following sections. As we can see from Appendix 5 using the work-around increases the time to initialize and start the program by 6.1.1 The Experiment – Iteration 1 roughly 6 times. This means that when using Jython in a When using and importing Scala code from Kotlin there project together with another programming language running were no difficulties. Even though Scala is purely object- on the JVM, Jython should be avoided to be a dependency to oriented while Kotlin is not, the datatype Float are in both another language. By using Appendix 5 it can also be languages compiled to primitive datatypes inside the JVM, calculated that using Jython for the data-layer or GUI-layer avoiding any problems. Also, as shown in Listing 12, resulted in 35% or 66% increase in time respectively. This is returning null from Scala to Kotlin works as theoretically not surprising since the fact that Jython is dynamically typed expected. was in section 3.6 expected to decrease the performance. This means that in general, one would want to avoid using When using and importing Jython code from Scala a work- Jython for the heaviest computations. around was required. The work-around was theoretically expected to require extra work and overhead in performance. As mentioned in section 3.6, Jython reduces amount of code This was proven to be true since as we can see from Listing by half compared to Java. From earlier experience, code used 5-8, majority of code written for the logic-layer was code for the GUI is usually the part in a program using the most used for the work-around. Also, as we can see from amount of code. This could be caused by the fact that there Appendix 5, 80% of the time to initializing and starting the are many properties and event handling for the many program comes from importing the data-layer using the components needed. This also applies to this project where work-around. However, the work-around required Jython to as seen in Appendix 6, the GUI-layer uses at least 50% more import a Scala-interface where the data types were already lines of code than the logic-layer and data-layer. Since defined, meaning that the fact that Scala is statically typed shorter programs are often proven to have less bugs, using and Jython is dynamically typed did not result in any Jython for a verbose GUI is concluded to be a relevant problems. Though, as explained in section 5.1, it was not choice. Furthermore, using Jython for the GUI-layer avoids optimal if a class representing a movie were to be returned Jython being a dependency to another module, which was in from Jython to Scala. this section and section 6.1.1 proven to be costly. It is also mentioned in section 3.6 that stateful programming 6.1.2 The Experiment – Iteration 2 Again, there were no problems caused by the fact that Scala paradigms is more connected to the real world and object- is purely object-oriented while Kotlin is not for the same oriented paradigm is stateful. In this case, a movie is reason as explained in section 6.1.1. Also, Scala did not have something connected to our real world, meaning creating a to return null to Kotlin, avoiding any problems. Even though movie-class feels natural while programming. Since all of there would have been a need to return null it was proven to Jython, Scala and Kotlin support object-oriented have worked as shown in Listing 10. programming they are all a relevant choice for this particular problem. Though, importing a class from Jython was not Importing to Jython by adding JAR-files to the optimal because of the work-around, as explained in section CLASSPATH worked as theoretically expected. Also, this 5.1. time there were no problems returning a class representing a movie from the data-layer to the logic-layer. The Movie-class 6.2.2 General Discussion – RQ2 defined in Scala could be imported and used by Kotlin as The functional paradigm is stateless, meaning it cannot shown in Listing 11. Though, as explained from section 5.2, modify data. This means that when facing a problem that the datatype returned to Kotlin caused some problems. only needs to handle given data, one would consider using the functional paradigm. In this case, the logic-layer only Jython is dynamically typed while Kotlin is statically typed. needs to handle given data meaning Scala is assumed to be a Though, this didn’t result in any problems because Jython is relevant choice for the logic-layer. On the other hand, it is the Python programming language implemented in 100% also mentioned that Scala has a broad support for data Java. Additionally, the JVM has support for dynamic typing, handling, thus making it more relevant for the data-layer. avoiding any problems in this case. Creating functions with the same name but with different generic types, could be relevant in the context of an application programming interface (API). Since this is

8 supported by Scala and Kotlin it is concluded that using those create a factory for each Jython-class that is going to be languages are a better choice for an API compared to Jython. imported. This way an object from a defined class Movie In this case, the logic-layer and data-layer are used as an API. could be created, instead of storing the data in a string. Static typing is argued to be more relevant when writing a 6.3.2 The Experiment – Second Iteration larger program that needs to be maintainable, which is in this Having to add the JAR-files to the CLASSPATH could not paper assumed to be the case with the experiment. Even be avoided since that is the intended way as explained in the though the program is not relatively large it still needs to be theory section. Though, it required a bit of work. First, you maintainable since there are many modules with had to rebuild the JAR-files each time a change was made dependencies. Having many modules could make it harder which can take quite some time. Second, the absolute path finding errors, resulting in extra cost in time. Therefore, it is had to be manually added to the run configurations inside concluded that using Kotlin or Scala that are statically typed IntelliJ IDEA. In addition, using the absolute path is rarely a is better than using Jython when used together in a project. good idea as explained in 6.3.1. 6.3 Method 6.3.3 The Experiment – Comparison of Iteration 1 and 2 The most important flaw with the method to discuss is the Using the Java library java.time as a way to measure the run fact that there is a need for more experiments. First off, there time is not optimal if you want to have a detailed and were some dependencies never tried. More specifically, accurate result. Though, this is okay in this case since it was Jython was never dependent on Scala, Scala on Kotlin or only interesting to see if the difference in time was Kotlin on Jython. Second, the single experiment was not noticeable. For the same reason the specification of the setup in a way allowing all the different properties shown in computer is not needed to be included. On the other hand, Appendix 1 to be tested. For example, returning null from something that can affect the reliability of the result when Scala to Kotlin required an extra function to be added. Also, measuring the performance in time is that the code was not the fact that Scala should be better for XML-handling or data identical enough in some cases. An example of this is the fact handling in general was never tested. Instead a CSV-file was 9 that the data-layer in iteration 1 returns a list of Floats while imported using an external Scala-library . iteration 2 returns a list of Movie-objects. Another example is that different libraries for loading the CSV-file in the data- 6.3.1 The Experiment – First Iteration layer were used. Furthermore, the performance in time is The solution regarding the problem with the path explained only measured from the startup of the program and the logic- in the section 5.1 has some problems. First, having to create layer don’t do any work during the startup (excluding the a symbolic link for each Jython-module requires extra work. work-around), making it hard to compare the solutions of the Second, the symbolic link has to be recreated if the Jython- logic-layer. module inside the project is moved and the fact that the symbolic link points to an absolute path is rarely a good idea. 6.3.4 References - Critique For example, if someone else works on the project, the Information about the different properties and its benefits of symbolic link must be recreated since the absolute path will a programming language was often found from blog posts most likely no longer point to the correct path. and other non-scientific sources. That is why many sources A better solution could have been to do as in iteration 2, about the programming languages such as books are reused. adding a JAR-file to the CLASSPATH, which is in this case The only blog post [2] including in the sources was used to the Scala-interface. This solution would allow Jython to show a point that Java is popular, which is not scientifically import the Scala-interface and therefore eliminating the need relevant for this work. Furthermore, since RQ1 is specific, it of using a symbolic link. Though, this was not known during was hard finding sources to help answering RQ1. Therefore, the time of iteration 1. Therefore, when testing if the Jython more general sources were used that for example specified data-layer worked the code regarding the Scala-interface had the properties and behavior of the programming languages. to either be removed or run indirectly from the logic-layer or GUI-layer. This resulted in an unnecessary loss in time. 7 CONCLUSION Since the different properties and paradigms of a In section 5.1 it was proposed a solution to if one would want programming language has its pros and cons, it was more data about movies than just the score, it could be solved important to try if it is possible using multiple programming by splitting a string by the vertical bar sign. This could be languages together in a project. This was proven possible problematic if for example data about a movie happens to using Jython, Scala and Kotlin but comes with various contain the vertical bar sign, giving an incorrect result. The complications that affect the performance and productivity. best way would have been to use the loosely coupled object factory from the work-around [11], that avoids having to

9 https://github.com/tototoshi/scala-csv 9

A GUI-layer typically do not require heavy computations, [6] S. Diomidis, "Choosing a Programming Language," however, it usually involves a relatively high amount of code IEEE software, vol. 23, no. 4, pp. 62-63, 2006. and has no dependency to another modules. Jython was [7] M. Müller, T. Müller and P. Van Roy, "Multiparadigm shown to in general be slower than Scala or Kotlin, reducing Programming in Oz," in Visions for the Future of Logic the amount of code and required using the work-around Programming: Laying the Foundations for a Modern when imported. Therefore, Jython should be the best choice Successor to Prolog, Portland, 1995. for problems similar to the GUI-layer. In addition, Jython does not support multiple functions with the same name but [8] M. Odersky, P. Altherr, V. Cremet, B. Emir, S. Maneth, with different generic types as input parameters compared to S. Micheloud, N. Mihaylov, M. Schinz, E. Stenman and Scala and Kotlin, which is not relevant for a GUI-layer that M. Zenger, "An overview of the Scala programming will not be used as an API. language," in No. LAMP-REPORT-2004-006, Lausanne, 2004. Scala’s support for the functional paradigm makes it relevant [9] P. Samuele and N. Rapping, Jython Essentials: rapid for the logic-layer and Scala’s broad support for handling of scripting in Java, O'Reilly Media, Inc, 2002. data makes it also relevant for the data-layer. Though, the data handling in Scala was not tested enough to compare it [10] Panchal, K. Ronak, Patel and K. Akshay, "A to Jython or Kotlin. Therefore, it is assumed that Scala is an comparative study: Java Vs kotlin Programming in equally relevant choice compared to Jython and Kotlin for Android," International journal of Innovative Trends in the data-layer. Since using Kotlin as the logic-layer Engineering & Research, vol. 2, no. 9, pp. 4-10, 2017. compared to Scala does not have any noticeable benefits, it [11] J. Juneau, J. Baker, V. Ng, L. Soto and F. Wierzbicki, is concluded that Scala’s functional nature makes it a better "Jython and Java Integration," in The definitive guide to choice when it comes to problems similar to the logic-layer. Jython: Python for the Java platform, Apress, 2010, pp. This means the problem left to solve for Kotlin is the data- 175-197. layer. This could be argued to be a relevant choice since [12] S. Stephen and S. Bocutiu, Programming Kotlin, Packt Kotlin does not allow null values, meaning that if the data Publishing Ltd, 2017. would have been incorrect it is noticed early in the chain of [13] JetBrains, "Calling Java code from Kotlin," JetBrains, 7 tiers. To summarize, the best choice is Jython for the GUI- December 2018. [Online]. Available: layer, Scala for the logic-layer and Kotlin for the data-layer. https://kotlinlang.org/docs/reference/java-interop.html. [Accessed 5 May 2019]. 8 REFERENCES [14] Oracle, "jpc.org," 28 February 2006. [Online]. [1] Oracle, “Java,” 26 September 2010. [Online]. Available: Available: https://jcp.org/en/jsr/detail?id=292. https://web.archive.org/web/20100925204716/https://ja [Accessed 16 April 2019]. va.com/en/download/faq/whatis_java.xml. [Accessed [15] A. P. Luker, "Never Mind the Language, What About 31 Januari 2019]. the Paradigm?," in ACM SIGCSE Bulletin, Chico, ACM, [2] S. Misirlakis, “Coding Dojo,” 13 December 2017. 1989, pp. 252-256. [Online]. Available: [16] T. A. Budd and R. K. Pandey, "Never mind the https://www.codingdojo.com/blog/7-most-in-demand- paradigm, what about multiparadigm languages?," ACM programming-languages-of-2018/. [Accessed 31 Januari SIGCSE Bulletin, vol. 27, no. 2, pp. 25-30, 1995. 2019]. [17] J. . Mitchell, "Functional and Imperative Languages," [3] T. Lindholm, F. Yellin, G. Bracha and A. Buckley, The in Conecpts in Programming Language, Stanford, Java Virtual Machine Specification, Redwood City: Cambridge University Press, 2003, pp. 76-82. Oracle America, 2015, pp. 2-3. [18] J. C. Mitchell, "Concepts in Object-Oriented [4] A. Sarimbekov, L. Bulej, Y. Zheng, N. Ricci and W. Languages," in Concepts in Programming Languages, Binder, "Characteristics of dynamic JVM languages," in Stanford, Cambridge University Press, 2003, pp. 277- the 7th ACM workshop, Indianapolis, 2013. 299. [5] A. Sarimbekov, L. Stadler, L. Bulej, A. Sewe, A. [19] M. Odersky, L. Spoon and B. Venners, Programming in Podzimek, Y. Zheng and W. Binder, "Workload Scala, Artima Inc., 2007. characterization of JVM languages," Software: Practice and Experience, vol. 46, no. 8, pp. 1053-1089, 2016.

10

9 APPENDIXES Programming Jython Scala Kotlin language

Property Typing Dynamic Static Static

Compiled No Yes Yes

Pure object-oriented No Yes No

Nullable Yes Yes No [12, p. 202]

Can import Java- Yes [9] Yes [19, pp. 12-13] Yes [12] packages Appendix 1. Comparison of properties between Jython, Scala and Kotlin

def average(list: Iterable[Float]): Float = { list.sum./(list.size) } def calculateAverageScore(genre: String): Float = { average(getMovies().map(movie => movie.score)) } Appendix 2. Example of functional paradigm in Scala

Appendix 3. Graphical result of program (Swing-application)

val starts = Instant.now() // Run code to measure here val ends = Instant.now() println(Duration.between(starts, ends).toMillis() + " ms") Appendix 4. Code in Kotlin used to measure performance in time

Module Total GUI-Layer Logic-Layer Logic-Layer Data-Layer Work-around Iteration Iteration 1 6000 ms 2% 80% 79-80% 18%

Iteration 2 1000 ms 20% <1% - 80%

Appendix 5. Time to start and initializing the program

Module GUI-Layer Logic-Layer Data-Layer Iteration Iteration 1 44 lines 24 lines 22 lines Iteration 2 33 lines 21 lines 24 lines

Appendix 6. Lines of code used (excluding imports and work-around)

Upphovsrätt Detta dokument hålls tillgängligt på Internet – eller dess framtida ersättare – under 25 år från publiceringsdatum under förutsättning att inga extraordinära omständigheter uppstår. Tillgång till dokumentet innebär tillstånd för var och en att läsa, ladda ner, skriva ut enstaka kopior för enskilt bruk och att använda det oförändrat för ickekommersiell forskning och för undervisning. Överföring av upphovsrätten vid en senare tidpunkt kan inte upphäva detta tillstånd. All annan användning av dokumentet kräver upphovsmannens medgivande. För att garantera äktheten, säkerheten och tillgängligheten finns lösningar av teknisk och administrativ art. Upphovsmannens ideella rätt innefattar rätt att bli nämnd som upphovsman i den omfattning som god sed kräver vid användning av dokumentet på ovan beskrivna sätt samt skydd mot att dokumentet ändras eller presenteras i sådan form eller i sådant sammanhang som är kränkande för upphovsmannens litterära eller konstnärliga anseende eller egenart. För ytterligare information om Linköping University Electronic Press se förlagets hemsida http://www.ep.liu.se/.

Copyright The publishers will keep this document online on the Internet – or its possible replacement – for a period of 25 years starting from the date of publication barring exceptional circumstances. The online availability of the document implies permanent permission for anyone to read, to download, or to print out single copies for his/hers own use and to use it unchanged for non-commercial research and educational purpose. Subsequent transfers of copyright cannot revoke this permission. All other uses of the document are conditional upon the consent of the copyright owner. The publisher has taken technical and administrative measures to assure authenticity, security and accessibility. According to intellectual property law the author has the right to be mentioned when his/her work is accessed as described above and to be protected against infringement. For additional information about the Linköping University Electronic Press and its procedures for publication and for assurance of document integrity, please refer to its www home page: http://www.ep.liu.se/.