Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
0% found this document useful (0 votes)
6 views

Slides Cours10 Functional Programming

The document discusses functional programming concepts in Java including lambda expressions, functional interfaces, and nested classes. It provides examples of how these concepts can be used to write more concise and reusable code.

Uploaded by

jimes30928
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
6 views

Slides Cours10 Functional Programming

The document discusses functional programming concepts in Java including lambda expressions, functional interfaces, and nested classes. It provides examples of how these concepts can be used to write more concise and reusable code.

Uploaded by

jimes30928
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 64

LEPL1402 – Functional programming in Java

2023-12-07
You’ve already met functional programming in Python!

Image credits: https://realpython.com/python-functional-programming/


Why functional programming?

Functions + immutable data


Code that is easier to reason about (shorter, clarity…)

Improved uncoupling of code

Better handling of concurrency
Why functional programming?

Functions + immutable data


Code that is easier to reason about (shorter, clarity…)

Functional interfaces

Improved uncoupling of code

Lambda expressions

Better handling of concurrency

Stream API
Nesting classes
A basic spreadsheet
A basic spreadsheet
Spreadsheet document
Spreadsheet document

Keep rows sorted


after each modification
Spreadsheet document

Sorting using an external class:

Keep rows sorted


after each modification
Static nested classes: Bring class closer to method
Static nested classes: Bring class closer to method

This is the
“outer” class
Static nested classes: Bring class closer to method

This is the
“outer” class
“RowComparator2” has access to the private
static members of Spreadsheet
(enumerations, helpers...)
Static nested classes: Bring class closer to method

This is the
“outer” class
“RowComparator2” has access to the private
static members of Spreadsheet
(enumerations, helpers...)

Static nested classes


improve code
organization, “packages
at a finer granularity”
Static nested classes: Bring class closer to method

This is the
“outer” class
“RowComparator2” has access to the private
static members of Spreadsheet
(enumerations, helpers...)

Static nested classes


improve code
organization, “packages
at a finer granularity”

Problem: “sortOnColumn” is copied!


Inner classes: Give access to non-static members
Inner classes: Give access to non-static members

The class is not tagged as


static anymore!
Inner classes: Give access to non-static members

The class is not tagged as


static anymore!

The method now


has access to the
members of the
outer object
Inner classes: Give access to non-static members

The class is not tagged as


static anymore!

The method now


has access to the
members of the
outer object

No need to copy
“sortOnColumn”
anymore!
Inner classes: Give access to non-static members

The class is not tagged as


static anymore!

The method now


has access to the
members of the
outer object

No need to copy
“sortOnColumn”
anymore!
Syntactic sugar
Syntactic sugar

Java compiler
Syntactic sugar

Java compiler
Syntactic sugar

Java compiler
Syntactic sugar

Java compiler

Syntactic sugar refers to language features


that do not introduce new functionality
but provide a more convenient way of writing code
Inner classes keep a reference to their outer object

Code automatically generated for inner classes

Image credits: https://syntactic-sugar.netlify.app/


Local inner classes: Bring class inside the method

The comparator is entirely local to sort(), and cannot be used


in another method or class, which further reduces coupling
Anonymous inner classes

No need to give a name to the comparator if it is only used once!


Access to method variables (1/3)

Inner and anonymous classes have access to the variables of their method!

Example: Filling a matrix with multiple threads

Image credits: https://www.cuemath.com/algebra/solve-matrices/


Access to method variables (2/3)

The Filler class receives a copy


of the variables in fill1()
at its creation
Access to method variables (3/3)
Access to method variables (3/3)

Create one callable


per row to augment
parallelism
Access to method variables (3/3)

The inner class can only access


final variables (which row is not)
Create one callable
per row to augment
parallelism
Lambda expressions
A recurring pattern
A recurring pattern
A recurring pattern
A recurring pattern
A recurring pattern

Very stupid classes implementing


one single method!
Functional interfaces


A functional interface is defined as an interface that contains only one abstract method

Functional interfaces are also known as Single Abstract Method (SAM) interfaces

The interfaces Comparator<T>, ActionListener, Runnable, and Callable<T>
are all examples of functional interfaces

Functional interfaces are a key component of functional programming support
introduced in Java 8
Lambda expressions

A lambda expression is an expression that creates an instance of an


anonymous inner class that has no member and
that implements a functional interface
Lambda expressions

A lambda expression is an expression that creates an instance of an


anonymous inner class that has no member and
that implements a functional interface

Name of the
arguments
Lambda expressions

A lambda expression is an expression that creates an instance of an


anonymous inner class that has no member and
that implements a functional interface

Name of the Body implementing the


arguments functional interface
Lambda expressions

A lambda expression is an expression that creates an instance of an


anonymous inner class that has no member and
that implements a functional interface

Name of the Body implementing the


arguments functional interface

Thanks to the context, the compiler


knows that the functional interface
to be implemented is Comparator<Row>
Lambda expressions

A lambda expression is an expression that creates an instance of an


anonymous inner class that has no member and
that implements a functional interface

Name of the Body implementing the


arguments functional interface

Thanks to the context, the compiler


knows that the functional interface
to be implemented is Comparator<Row>
Lambda expressions for our recurring pattern

Comparator<T>

ActionListener

Runnable
General form of a lambda expression
General form of a lambda expression

Possible simplifications:

The compiler can generally infer the type of the arguments:
(a, b, c /*...*/) -> { /*...*/ }

If one argument: a -> { /*...*/ }

If no body: (a, b, c /*...*/) -> /* result */

If no return: (a, b, c /*...*/) -> /* body */
General form of a lambda expression

Possible simplifications: Method references:



The compiler can generally infer the type of the arguments:
(a, b, c /*...*/) -> { /*...*/ }

If one argument: a -> { /*...*/ }

If no body: (a, b, c /*...*/) -> /* result */

If no return: (a, b, c /*...*/) -> /* body */
General-purpose functions
Package java.util.function

General-purpose classes that provide a context to create and hold lambda expressions:


Unary functions: Function<T,R>

Binary functions: BiFunction<T,U,R>

Unary operators: UnaryOperator<T>

Binary operators: BinaryOperator<T>

Predicates: Predicate<T>

Consumers: Consumer<T>

...
Unary functions

Example 1

Example 2
Binary functions
Operators: Functions with one type
Predicates: Functions returning a Boolean
Consumers: Functions producing no result
Composition of functions or operators
Composition of predicates
Higher-order functions

Methods that can accept other functions as arguments,


return functions as results, or both
Higher-order functions

Methods that can accept other functions as arguments,


return functions as results, or both

In the context of collections:



The Iterable<T> interface has forEach() method to apply a consumer to a collection

The Collection<T> interface has removeIf() method to apply a predicate to filter a collection

The ArrayList<T> class has replaceAll() method to apply an operator to a collection
Higher-order functions

Methods that can accept other functions as arguments,


return functions as results, or both

In the context of collections:



The Iterable<T> interface has forEach() method to apply a consumer to a collection

The Collection<T> interface has removeIf() method to apply a predicate to filter a collection

The ArrayList<T> class has replaceAll() method to apply an operator to a collection

A bit like Python, but Streams (next week)


will bring Java even closer to Python!
Examples on collections
Implementing composition by ourselves

You might also like