Functional Programming in Scala PDF

Summary

This document serves as an introduction to functional programming in Scala, providing explanations of core concepts. It details imperative versus functional programming styles, Scala's features such as declarations, branches, and data types, and delves into primitive data types like Booleans, integers, and strings, offering examples of usage.

Full Transcript

# Functional Programming in Scala ## 9.1 Foundations of Functional Programming An imperative program is a sequence of instructions, each changing the state of the system. In contrast to that a functional program is a set of (mathematical) functions and expressions compound of these functions. Let...

# Functional Programming in Scala ## 9.1 Foundations of Functional Programming An imperative program is a sequence of instructions, each changing the state of the system. In contrast to that a functional program is a set of (mathematical) functions and expressions compound of these functions. Let us consider the following Python example: ```python def f(x): global y y = y + 1 return 2 * x + y ``` The function *f* changes the state of the system, since the scope of *y* is global. Therefore, the result of *f(x)* does not only depend on *x* but also on the state of the system. The function has side effects. In the context of functional programming, functions are not allowed to have side effects and their output purely depends on the input parameters. This concept is called referential transparency. ## 9.2 Introduction to Scala Scala is a multiparadigm language, i.e., we are able to write imperative, functional and object-oriented programs. First, we only focus on the functional part of Scala. Moreover, Scala is embedded into the Java system, which means we can use the functionality of Java. Programs of these languages will be compiled, i.e., we can find lots of mistakes before starting the program. This differs from Python, which uses an interpreter. Furthermore, Scala is a statically typed language, which means that data types of variables are fixed during the compiling process. This is another difference to Python which has a dynamically typed system. We will work with Scala 3.x. Since Scala 3 we are able to use indentations to structure the programs. ### Declarations Scala distinguishes the concepts value declaration and variable declaration. In a purely functional context we are only allowed to use value declarations. They work as follows: ```scala val name: Type = expression ``` Once we have declared a value like this we can use it in our program, but we are not allowed to reassign a new value - the are immutable. The variable declaration works with *var* instead of *val*. Here we are allowed to reassign - they are mutable. Each variable or value has to be declared before using it in our program. Here is an example: ```scala val n: Int = 42 * 13 ``` In most of the cases, the type of the value/variable can be left out, since Scala is able to derive the correct type. However, it is good programming style to write the type explicitly. ### Branches The syntax of branches in Scala is very close to the syntax in Python: ```scala if (condition_1) then statements 1 else if (condition_2) then statements_2 ... else statements_n ``` The essential difference to Python is that each if/else-construct has a return value, i.e., the last expression in a block examines the return value of the branch. This makes more sense in the context of functions. ### Loops There are *while-* and *for-*loops in Scala. They behave like the loops in Python. However, loops are purely imperative and hence, forbidden in functional programs. ## 9.3 Data Types in Scala In Scala, the type of an expression is fixed during compiling. For function parameters and return values we have to explicitly give the types. For variables and values we can sometimes omit the type, but as said before, this is bad programming style. Subsequently, we find some information about important types in Scala - most of them are known from Python. ### 9.3.1 Primitive Data Types In Scala, primitive data types are sometimes called value types. All other types are called reference types. Later, we will have a closer look to this distinction. - **Boolean** has the two values *false* and *true*. The logical operations are: && (and), || (or) and ! (not). The logical operations evaluate expressions in a lazy manner, e.g., *false && foo()* never calls *foo()*. - **Byte** contains the integer numbers [-27, 27-1] represented as Two's complement. - **Short** contains the integer numbers [-215, 215-1] represented as Two's complement. - **Int **contains the integer numbers [-231, 231 - 1] represented as Two's complement. - **Long** contains the integer numbers [-263, 2631] represented as Two's complement. - **Float** contains the floating point numbers with 32 bits represented by the IEEE-754 standard. - **Double** contains the floating point numbers with 64 bits represented by the IEEE-754 standard. - **Char** contains the unicode symbols for the numbers [0, 2161], for example 'a' or '4' or 'T'. - **Unit** is a place holder for "...There is no type". It is comparable to the type *NoneType* from Python. The elementary operations for numbers are the same as in Python. Type conversion is also possible, unless there is information loss. This information loss is defined by the hierarchy of types. The following example will work, since *127* is representable in all number types: ```scala val b: Byte = 127 val i: Int = b val l: Long = i val b2: Byte = 1 ``` ### 9.3.2 Strings Strings are immutable sequences of characters. In Scala, 'a' is a character, i.e., it is of type *Char*, whereas "a" is a string of length one, i.e., it is of type *String*. For a string *text* and integer *i* we can use *text(i)* to access the *i*-th element. ```scala val text: String = "Hallo" val first: Char = text(0) // 'H' ``` Each value has a (more or less) human-readable form. We can transfer this representation into a string by using the syntax *s"$var1 text $var2"*. Example: ```scala val f: Float = 3.7 val i: Int = 10 val s: String = s"f is $f and i is $i" // "f is 3.7 and i is 10" ``` Remark that *s"* is relevant. We can also use complete code after $: ```scala val s : String = s"1+1 = ${1+1}" // "1+1 = 2" ``` ### 9.3.3 Tuples Tuples are like strings immutable sequences. Like in Python we are able to compose values of different data types and use index notation to access the different parts. ```scala val student = ("Toni", "Mustermensch", 22) ``` The type of *student* is *(String, String, Int)*. Using the index notation we will for example get 22 from *student(2)*. Furthermore, we can use pattern matching in connection with tuples: ```scala val (name, firstname, _) = student ``` Thus, we have two new values *name* and *firstname* both of type *String*.

Use Quizgecko on...
Browser
Browser