Functional Programming in Javascript
Total Page:16
File Type:pdf, Size:1020Kb
M U F I Functional Programming in JavaScript B’T Oliver R˝dzi Brno, Fall 2017 Declaration Hereby I declare that this paper is my original authorial work, which I have worked out on my own. All sources, references, and literature used or excerpted during elaboration of this work are properly cited and listed in complete reference to the due source. Oliver R˝dzi Advisor: prof. RNDr. Jiří Barnat Ph.D. i Acknowledgement First, I would like to express my deepest appreciation to my thesis advisor prof. RNDr. Jiří Barnat, Ph. D. - without his guidance and persistent help, this bachelor thesis would not have been possible. I would also like to acknowledge all my friends and colleagues at Webscope, for their valuable inputs and advice whenever I was struggling. Finally, I must express my very profound gratitude to my parents and to my amazing girlfriend for providing me with unfailing support and continuous encouragement throughout my years of study and through the process of researching and writing this thesis. This accomplishment would not have been possible without them. Thank you. iii Abstract The objective of this thesis is to compare and analyze the libraries for functional programming in JavaScript, how they differ from Haskell language, and what are the benefits they provide for JavaScript. To further evaluate usage and advantages of these libraries, appli- cation/game was created, which focuses on the advantages of using functional programming, while also teaching the player functional programming principles and how to use them effectively in JavaScript. iv Keywords JavaScript, Ramda.js, Folktale, Haskell, Elm, Lodash, Lazy.js, Under- score v Contents 1 Introduction 1 1.1 Thesis structure ........................ 1 2 Functional and imperative programming 3 3 Haskell compared to Elm 7 3.1 Haskell ............................ 8 3.2 Elm .............................. 9 3.3 Conclusion .......................... 11 4 Functional libraries in JavaScript 13 4.1 Underscore.js ......................... 14 4.2 Lodash ............................. 15 4.3 Lazy.js ............................. 15 4.4 Ramda.js ........................... 17 4.5 Immutable.js ......................... 20 4.6 Folktale ............................ 21 5 Practical segment 23 5.1 Implementation technologies and processes .......... 23 5.1.1 HTML and CSS . 23 5.1.2 React . 23 5.1.3 Yarn . 27 5.2 First concept of the application ................ 28 5.3 Implementation of the application .............. 29 5.4 Testing ............................. 31 6 Conclusion 35 Bibliography 37 A How to install and run the application 39 B Source codes 41 vii 1 Introduction In recent years, the world of JavaScript has changed a lot. New frame- works and libraries emerged and ECMAScript2015 definitely changed the way web developers write their applications. Functional programming in JavaScript also saw an increase in popularity. Functional-like libraries, such as Underscore.js or Lodash, made it easier to work with arrays, objects, strings, numbers, et cetera. However, they still lacked some of the truly functional features, most noticeably currying of functions. On the other hand, Ramda.js strongly resembles some of the Haskell functionality. Designed specifically for a functional programming style1, it provides automatically curried functions, making function composition easier. Moreover, since Ramda.js does not mutate its data, it works well with JavaScript frameworks that depend on immutability, such as Redux. To explore all possibilities of functional JavaScript, we will also have a look at Elm. Even though Elm is not a library, but a complete language on its own, Elm compiles to JavaScript and can showcase what might be possible to do with JavaScript in the future. The objective of this thesis is to present advantages of above- mentioned approaches to JavaScript programming and to research aspects in which it is better than more common imperative program- ming. 1.1 Thesis structure In the first part, we will focus on defining both functional program- ming and imperative programming. Also, this chapter points out key differences between imperative and functional programming. After we establish these core concepts, we can progress further to examine functional programming by inspecting the most popular functional language at present, Haskell, and compare it to another programming language, Elm, which compiles to JavaScript. We will 1. See http://ramdajs.com/. 1 .I then continue to explore what Elm has in common with Haskell and what are its shortcomings. The next part of this thesis is going to explore the world of JavaScript libraries with the focus on their usage and similarities. Afterwards, we will examine the performance, code readability and shortcomings of those libraries. This will be followed by a summary stating the reasons why to use or not to use some of them. In the practical segment, we are going to evaluate the application that was programmed as a part of this thesis, describing technologies used and its design. We will go through the first concept, summa- rizing what the requirements for this application were, then we will progress to further examine the implementation itself. Afterwards, we will check whether the application satisfies the functional and non-functional requirements. Finally, we are going to summarize what we have learned in this thesis and assess where there is an opportunity to dig deeper in both theoretical and practical segments. 2 2 Functional and imperative programming In this chapter, we are going to establish the terms functional and im- perative programming. Then we are going to focus on how functional programming differs from imperative programming. Definition 2.0.1. Functional programming In functional programming, programs are executed by evaluating expressions, in contrast with imperative programming where pro- grams are composed of statements which change global state when executed. Functional programming typically avoids using mutable state.[1] Definition 2.0.2. Imperative programming Imperative programming is a paradigm of computer programming in which a program describes a sequence of steps that change the state of the computer. Unlike declarative programming, which describes "what" a program should accomplish, imperative programming ex- plicitly tells the computer "how" to accomplish it. Programs written this way often compile to binary executables that run more efficiently since all CPU instructions are themselves imperative statements.[2] Differences between the imperative and functional programming With the imperative approach, the programmer is writing exact steps that computer needs to do in order to meet the goal. This is sometimes referred to as algorithmic programming. On the other hand, functional approach involves composing the problem in a set of functions to be executed1. Changes of state through functions In imperative programming, the state of an application is changed with commands in the source code, i.e. through an assignment. Functions in imperative programming often have side effects that may change the state of the application. Because of this, functions that do not have return value make sense. 1. See https://msdn.microsoft.com/en-us/library/mt693186.aspx 3 .F In contrast to imperative programming, functional programming functions are pure - they do not have side effects. This means that the output of the function is dependent only on the arguments provided to the function, so calling the same function twice with the same arguments always results in the same output. This is often not the case for functions in imperative programming, where functions can depend on the local or global state. Removing side effects from functions makes it easier to track and understand the behavior of an application, which is one of the key advantages of the functional programming. Programmer approach In imperative programming, the developer thinks how to write algo- rithms and how to track any changes of the state. To control the flow of an application, the developer is using loops, conditions and function calls. Those functions are often impure, therefore can change the state of the application. On the other hand, in functional programming, the developer is trying to compose the problem as a set of functions to execute. In other words, the developer thinks about what state is desired, and what transformations are needed to get into that state. To control the flow of the application, the programmer uses pure functions and recursion. Order of execution and primary manipulation unit In imperative programming, variables are assigned values, which are changed as the program executes. Because of this, other expressions in program depend on these variable values. If the order of execution should change, and variables are not assigned values in correct order, then expressions which use those variables may not be correct as a side effect. As a consequence of this, the order of execution has high importance. Contrary to this, functional programming uses pure functions and immutable variables so there is no side effect of any changes done to the variables elsewhere in the code. Because of this, the execution order has little importance. Moreover, functional languages often use this flexibility in execution to achieve the best performance. 4 .F In functional programming, the developer uses functions mainly as first-class objects and data collections, while instances of classes are used in imperative programming. 5 3 Haskell compared to Elm This chapter