# Functional Programming - FP101

- UNIFEI - October - 2018

# Hello!

Prof. Edmilson

Hanneli Tavante

<3

Prolog

Prof. Maurilio

<3

Deutschland

## Questions

• What is this course?
• A: An attempt to bring interesting subjects to the courses at UNIFEI
• Why are the slides in English?
• I am reusing some material that I prepared before
• What should I expect?
• This is the first time we give this course. We will be looking forward to hearing your feedback

## Rules

• Don't skip classes
• The final assignment is optional
• We will have OPTIONAL assignments during the classes
• Feel free to ask questions
• Don't feel discouraged with the mathematics

# Agenda

1. Foundation concepts; intro to Programming Languages
2. Why Functional Programming (FP)?
3. Types
4. Lists (gotta love them)
5. Recursion
6. Higher order functions (Hof)
8. Lazy Evaluation
9. A word or two about Lambda Calculus
10. Final considerations

Note: this list can change

WAT

# Agenda

1. Foundation concepts; intro to Programming Languages
2. Why Functional Programming (FP)?
3. Types and classes
4. Lists (gotta love them)
5. Recursion
6. Higher order functions (Hof)
8. Lazy Evaluation
9. A word or two about Lambda Calculus
10. Final considerations

Note: this list can change

[1, 2, 3, 4, 5]

# Is this the only way to solve this?

No.

[1, 2, 3, 4, 5].map { |el| el*2 }

=> [2, 4, 6, 8, 10]

Which language is this??

A: Ruby!

[ el*2 for el in [1, 2, 3, 4, 5]]
[2, 4, 6, 8, 10]

Which language is this??

A: Python!

[ el*2 | el <- [1..5] ]
[2, 4, 6, 8, 10]

Which language is this??

List(1, 2, 3, 4, 5).map( el => el*2)
res0: List[Int] = List(2, 4, 6, 8, 10)

Which language is this??

A: Scala!

fn main() {
let res = vec![1, 2, 3, 4, 5].iter()
.map(|&el| el*2).collect::<Vec<_>>();
println!("{:?}", res);
}
[2, 4, 6, 8, 10]

Which language is this??

A: Rust!

# There are different styles to write code (paradigm)

## There is one style of programming in which expressions are more important than statements

Note: examples of statements: for, do/while, {...}, return

# Agenda

1. Foundation concepts; intro to Programming Languages
2. Why Functional Programming (FP)?
3. Types
4. Lists (gotta love them)
5. Recursion
6. Higher order functions (Hof)
8. Lazy Evaluation
9. A word or two about Lambda Calculus
10. Final considerations

# Challenge: Create a program to sum the numbers from 0 to 100 (including 100)

//pseudocode

int res = 0;
for (int i=0; i<= 100; i++) {
res = res + i;
}

What are the problems of this code?

Is there anything you can't predict?

There are two things to be aware:

res: 5050

# 2. Mutable states

## Is it possible to write the same program only using expressions?

sum[1..100]
5050

sum[1..100]

sum()

1..100

# Some historical background

Turing

Alonzo Church

"How can we formalize the concept of effective computability?"

Turing Machines

Lambda Calculus

## Like the calculus you see at MAT001, λ-calculus is a formalism

J. McCarthy

Lisp Programming Language - one of the first functional languages

Functional Programming => One way to implement λ-calculus formalisms

Why is this programming style so important?

# Agenda

1. Foundation concepts; intro to Programming Languages
2. Why Functional Programming (FP)?
3. Types
4. Lists (gotta love them)
5. Recursion
6. Higher order functions (Hof)
8. Lazy Evaluation
9. A word or two about Lambda Calculus
10. Final considerations

Data

Operations

# Wait - what is a type?

Type: a name for a collection of related values

{ True, False }: Bool

# Wait - what is a type system?

"In programming languages, a type
system is a collection of rules
that assign a property called
type to various constructs a
computer program consists of, such
as variables, expressions, functions
or modules"

## Strategies

• Generate a compile error
• Perform a type check before run the code
• Well defined error set
• Unpredictable  runtime errors
• Try implicit conversion
• A compiler tags pieces of code and tries to infer if the behaviour will be valid or not (before the program runs)
• A compiler / interpreter generates code to keep track of the data

## Strategies

• Generate a compile error
• Perform a type check before run the code
• Well defined error set
• Unpredictable  runtime errors
• Try implicit conversion
• A compiler tags pieces of code and tries to infer if the behaviour will be valid or not (before the program runs)
• A compiler / interpreter generates code to keep track of the data

"Strong"

"Weak"

"Static"

"Dynamic"

* Definitions are not exact on literature

## You don't have to choose only one alternative

Java: static (why?)

Python: dynamic

# Can you see the benefits of statically typed languages?

• A compiler tags pieces of code and tries to infer if the behaviour will be valid or not (before the program runs)

"Static"

# Benefits of statically typed languages

1. Reduce the number of runtime errors

# Benefits of statically typed languages

2. The compiler can calculate the type of an expression

Type inference

# Benefits of statically typed languages

3. The type the compiler calculates corresponds to the type you obtain when you execute the expression in runtime

Type Soundness

# Basic Types

• Lists

(group of elements, the types can be different)

• Tuples

(Sequence of values where all the elements have the same type)

# expr::type

This is the terminology we use to indicate that an expression has a certain type (::)

Prelude> :type 1
1 :: Num t => t

# Functions also have types

Can you put 'Function' and 'type' in the same sentence so that you can come up with a definition of function?

"Function is a mapping of values from one type to another type"

# An exercise

Let's write a function to sum two integers in Haskell

Attempt #1

addd (x, y) = x+y
addd (3, 4)
7

Attempt #2

addd x y = x+y
addd 3 4
7

# What is the difference?

## What is the difference?

Attempt #1

addd (x, y) = x+y
addd (3, 4)
7

Attempt #2

addd x y = x+y
addd 3 4
7
:t addd
addd :: Num a => (a, a) -> a
:t addd
addd :: Num a => a -> a -> a

Attempt #2

addd x y = x+y
addd 3 4
7
:t addd
addd :: Num a => a -> a -> a

There is an advantage in writing the function like this:

It is a function (1)

That returns a function (2)

That takes another number (3)

And returns a number (4)

Attempt #2

addd x y = x+y
addd 3 4
7
:t addd
addd :: Num a => a -> a -> a

There is an advantage in writing the function like this:

:t addd
addd :: Num a => a -> (a -> a)

Is equivalent to:

Remember: Arrows associate to the right (*)

Attempt #2

addd x y = x+y
addd 3 4
7
:t addd
addd :: Num a => a -> (a -> a)

Now it is easier to see:

It is a function (1)

That returns a function (2)

That takes another number (3)

And returns a number (4)

# a Curried Function

:t addd
addd :: Num a => a -> a -> a

Remember: Arrows associate to the right

(*)

:t addd
addd :: Num a => a -> (a -> a)

Remember: Function applications associates to the left

mult x y z
((mult x) y) z

# Question: Does addd work for float numbers?

:t addd
addd :: Num a => a -> (a -> a)
addd 3.1 3.2
6.300000000000001

# How can we restrict that to Integers only?

addd     :: Int -> (Int -> Int)
addd x y = x+y
:t addd
addd :: Int -> Int -> Int
addd 3.1 3.2
error: No instance for
(Fractional Int)
arising from the literal ‘3.1’

# Agenda

1. Foundation concepts; intro to Programming Languages
2. Why Functional Programming (FP)?
3. Types
4.  Lists (gotta love them)
5.  Recursion
6. Higher order functions (Hof)
8. Lazy Evaluation
9. A word or two about Lambda Calculus
10. Final considerations

# Lists

[1, 2, 3, 4, 5]

What are lists in terms of expressions?

Whiteboard time! Let's understand the x:xs notation

What are lists in terms of expressions?

1:(2:(3:(4:(5:[ ]))))

# How do we manipulate lists?

(ex: transform elements into other elements, get only specific elements, transform lists into tuples)

A: List Comprehensions

# List comprehensions

[x^2 | x <- [1..5]]

generator:

defines how to generate the values of x

function to

transform x

# Filters

[x | x <- [1..5], even x]

Get the number, no transformation

Get only the even numbers of a list

generator

filter

## Challenge: Determine the position(s) of an element in a list

positions 2 [1, 2, 3, 4, 5, 2, 1, 3]

A: 1 and 5

Problem: Lists do not have an index!

# Start rom the beginning

positions

function name

x
xs

el

list

=

Strategy: transform each element of the list in a tuple: (el, pos)

# The solution

[1, 2, 3, 4, 5, 2, 1, 3]

Our list

[0, 1, 2, 3, 4, 5, 6, 7]

Positions

Solution

(1, 0)
,(2, 1)
,(3, 2)
[

...

zip

operation

# The code

[0, 1, 2, 3, 4, 5, 6, 7]

Positions

Goal

[(1, 0), (2, 1) ...]

zip

operation

positions x xs =
zip xs [1, 2, 3, 4, 5, 2, 1, 3]

# The code

[0, 1, 2, 3, 4, 5, 6, 7]

Positions

Goal

[(1, 0), (2, 1) ...]

zip operation

positions x xs =
zip xs [1..n]
where n = length xs - 1

# The code

[0, 1, 2, 3, 4, 5, 6, 7]

Positions

Goal

[(1, 0), (2, 1) ...]

zip operation

positions x xs =
zip xs [1..n]
where n = length xs - 1
<-
(  ,  )

el, pos

get pos

i |

# The code

[0, 1, 2, 3, 4, 5, 6, 7]

Positions

Goal

[(1, 0), (2, 1) ...]

zip operation

positions x xs =
zip xs [1..n]
where n = length xs - 1
<-
(  , i)

el, pos

list comprehension

i |
[

Now we need to filter the elements that we specified

# The code

[0, 1, 2, 3, 4, 5, 6, 7]

Positions

Goal

[(1, 0), (2, 1) ...]

zip operation

positions x xs =
zip xs [1..n]
where n = length xs - 1
<-
(  , i)

el, pos

list comprehension

i |
[
,
x'== x
(x', i)
]

# Break

What are functions?

In λ-calculus, we have λ expressions

\lambda x -> x+x
$\lambda x -> x+x$

expression that denotes functions

λ:

# Let's give it a try

Write the addd function as a  λ expression

addd x y = x+y
add = \lambda x \rightarrow ( \lambda y \rightarrow x+y )
$add = \lambda x \rightarrow ( \lambda y \rightarrow x+y )$

# Agenda

1. Foundation concepts; intro to Programming Languages
2. Why Functional Programming (FP)?
3. Types
4.  Lists
5.  Recursion
6. Higher order functions (Hof)
8. Lazy Evaluation
9. A word or two about Lambda Calculus
10. Final considerations

# Why is recursion such a nice feature?

One reason is being able to prove properties by mathematical induction :)

The practical reason here is that it helps us to get rid of statements

# Challenge - write a length function using recursion

1. Let's define the types

length    :: 
[a]
-> Int

## Challenge - write a length function using recursion

1. Let's define the types

length    :: 
[a]
-> Int

2. Define the base case

The "base case" is the one that will not change the result

length [] = 0

## Challenge - write a length function using recursion

1. Let's define the types

length    :: 
[a]
-> Int

2. Define the base case

length [] = 0

3. Define the recursive structure

Add one to each element of the list, until you get an empty list

Remember: this is a list

1:(2:(3:(4:(5:[ ]))))

## Challenge - write a length function using recursion

1. Let's define the types

length    :: 
[a]
-> Int

2. Define the base case

length [] = 0

3. Define the recursive structure

length (  : xs) = 1 + length xs

Anything

(_ : xs)

# Agenda

1. Foundation concepts; intro to Programming Languages
2. Why Functional Programming (FP)?
3. Types
4.  Lists
5.  Recursion
6. Higher order functions (Hof)
8. Lazy Evaluation
9. A word or two about Lambda Calculus
10. Final considerations

# Agenda

1. Foundation concepts; intro to Programming Languages
2. Why Functional Programming (FP)?
3. Types
4.  Lists
5.  Recursion
6. Higher order functions (Hof)
8. Lazy Evaluation
9. A word or two about Lambda Calculus
10. Final considerations

Whiteboard time

Use this video for reference (Computerphile)

# There is an important question none asked:

How are expressions evaluated?

# Agenda

1. Foundation concepts; intro to Programming Languages
2. Why Functional Programming (FP)?
3. Types
4.  Lists
5.  Recursion
6. Higher order functions (Hof)
8. Lazy Evaluation
9. A word or two about Lambda Calculus
10. Final considerations

Lazy Evaluation

# Agenda

1. Foundation concepts; intro to Programming Languages
2. Why Functional Programming (FP)?
3. Types
4.  Lists
5.  Recursion
6. Higher order functions (Hof)