SlideShare a Scribd company logo
1 of 71
Download to read offline
Functional Programming
      with Groovλ
@ArturoHerrero

http://arturoherrero.com
Working at OSOCO




Small but outstanding software development shop
           Groovy and Grails hackers
               on EC2 cloud nine
              TDD mantra singers
               Quality preachers
LISt Processing



  (define (factorial n)
    (if (= n 1)
        1
        (* n (factorial (- n 1)))))
Lots of Insipid Stupid Parentheses



  (         (factorial   )
      (   (     )

          (    (factorial (   )))))
Code Complete


The Pragmatic Programmer


Structure and Interpretation of Computer Programs
A language that doesn't affect the way you think
   about programming, is not worth knowing

                                     Alan Perlis
Functional Programming
Function
Functional Programming
    Avoiding Mutable State
λ




    Side-Effect-Free Functions
λ




    Referential Transparency
λ




    First-Class Citizens
λ




    Higher-Order Functions
λ




    Lambdas and Closures
λ




    Lazy Evaluation
λ




    Recursion
λ
Why Functional Programming?
    Referential transparency
λ




    Unit testing
λ




    Debbuging
λ




    Parallelization
λ




    Modularity and composition
λ




    Increases the quality of code
λ




    Abstractions
λ
OOP vs. FP
Imperative vs. Declarative

Imperative: how to achieve our goal
 Take the next customer from a list.
 If the customer lives in Spain, show their details.
 If there are more customers in the list, go to the beginning



Declarative: what we want to achieve
 Show customer details of every customer living in Spain
Imperative vs. Declarative

Functional programming is like describing
   your problem to a mathematician.
 Imperative programming is like giving
       instructions to an idiot.

                arcus, #scheme on Freenode
Functional Programming
with Groovy?

             is an imperative language,

but we still can apply functional principles

   It's basically a programmer's choice
Immutability
Simple
  Immutable objects can only be in exactly
  one state, the state in which it was created

Always consistent
  Less prone to errors and more secure

Immutable objects can be shared freely
  Freedom to cache

Inherently thread-safe
Immutability
NO: (even being a name rebind and not a real update)
book =   'Fooled by Randomness'
book =   "$book - Nassim Taleb"
book =   "$book (2001)"
assert   'Fooled by Randomness - Nassim Taleb (2001)' == book




YES:
book = 'Fooled   by Randomness'
bookWithAuthor   = "$book - Nassim Taleb"
completeBook =   "$bookWithAuthor (2001)"
assert 'Fooled   by Randomness - Nassim Taleb (2001)' == completeBook
Immutability
NO:
years = [2001, 2002]
years << 2003
years += [2004, 2005]
assert [2001, 2002, 2003, 2004, 2005] == years




YES:
years = [2001, 2002]
allYears = years + 2003 + [2004, 2005]
assert [2001, 2002, 2003, 2004, 2005] == allYears
Immutability
def list = ['Gr', 'vy']

NO:
list.addAll 1, 'oo'
assert list == ['Gr', 'oo', 'vy']


YES:
assert list.plus(1, 'oo') == ['Gr', 'oo', 'vy']
assert list == ['Gr', 'vy']
Immutability
def list = [1, 2, 2, 3]

NO:
list.removeAll 2
assert list == [1, 3]


YES:
assert list.minus(2) == [1, 3]
assert list == [1, 2, 2, 3]
Immutability
def list = ['Scala', 'Groovy', 'Java']

NO:
sortedList = list.sort()
assert sortedList == ['Groovy', 'Java', 'Scala']
assert list == ['Groovy', 'Java', 'Scala']


YES:
sortedList = list.sort(false)
assert sortedList == ['Groovy', 'Java', 'Scala']
assert list == ['Scala', 'Groovy', 'Java']
Immutability
def list = ['Java', 'Groovy', 'Java']

NO:
uniqueList = list.unique()
assert uniqueList == ['Java', 'Groovy']
assert list == ['Java', 'Groovy']


YES:
uniqueList = list.unique(false)
assert uniqueList == ['Java', 'Groovy']
assert list == ['Java', 'Groovy', 'Java']
Immutability
def list = ['Java', 'Groovy']

NO:
reverseList = list.reverse(true)
assert reverseList == ['Groovy', 'Java']
assert list == ['Groovy', 'Java']


YES:
reverseList = list.reverse()
assert reverseList == ['Groovy', 'Java']
assert list == ['Java', 'Groovy']
Immutability Collection
def list = ['Groovy', 'Java'].asImmutable()
assert 'Groovy' == list.first()

try {
    list.add 'Scala'    // Cannot add item
} catch (e) {
    assert e instanceof UnsupportedOperationException
}

try {
    list.remove 'Java' // Cannot remove item
} catch (e) {
    assert e instanceof UnsupportedOperationException
}
Immutability Class

@Immutable class Coordinates {
    Double latitude, longitude
}

def c1 = new Coordinates(latitude: 48.824068,
                         longitude: 2.531733)

def c2 = new Coordinates(48.824068, 2.531733)

assert c1 == c2
Higher-Order Functions

First-Class Citizen
 Can be stored in variables
 Can be passed as function parameter
 Can be returned from functions

Higher-Order Functions (First-Class Functions)
 Functions that take other functions
 as arguments or return them as results
Closures
def closure = { 'Hello world!' }
assert closure() == 'Hello world!'

def sum = { a, b -> a + b }
assert sum(2,3) == 5

def square = { it * it }
assert square(9) == 81

final BASE = 1000
def salary = { variable -> BASE + variable }
assert salary(500) == 1500
Turn Methods into Closures
def salary(variable) {
    final BASE = 1000
    BASE + variable
}
assert salary(500) == 1500

def salaryClosure = this.&salary
assert salaryClosure(500) == 1500
Closures Composition

def minutesToSeconds = { it * 60 }
def hoursToMinutes = { it * 60 }
def daysToHours = { it * 24 }

def hoursToSeconds = minutesToSeconds << hoursToMinutes
def daysToSeconds = hoursToSeconds << daysToHours

assert daysToSeconds(1) == 86400
Closures Composition

def upper = { it.toUpperCase() }
def firstLetter = { it.charAt(0) }

def words = ["Don't", "Repeat", "Yourself"]
def acronym = words.collect(firstLetter >> upper).join()

assert acronym == 'DRY'
Currying
given:   ƒ: (X x Y) -> Z

then:    curry(ƒ): X -> (Y -> Z)

  Takes a function with a particular
 number of parameters and returns a
 function with some of the parameter
 values fixed, creating a new function
Currying
def modulus = { mod, num ->
    num % mod
}
assert modulus(2, 5) == 1
assert modulus(3, 5) == 2

def mod2 = modulus.curry(2)
assert mod2(5) == 1

def mod3 = modulus.curry(3)
assert mod3(5) == 2
Currying
def bill = { amount, currency ->
    "$amount $currency"
}
assert bill(1000, '$') == '1000 $'
assert bill(1000, '€') == '1000 €'

def billInDollars = bill.rcurry('$')
assert billInDollars(1000) == '1000 $'

def billInEuros = bill.rcurry('€')
assert billInEuros(1000) == '1000 €'
Currying
def joinWithSeparator = { one, sep, two ->
    one + sep + two
}

def joinWithAmpersand =
    joinWithSeparator.ncurry(1, '&')

assert joinWithAmpersand('a', 'b') == 'a&b'
Classic Operations on
Functional Data Types

   list          filter



                  map



                  fold
Classic Operations on
Functional Data Types

   list         findAll



                collect



                 inject
Classic Operations on
Functional Data Types

   list           any

                 every
                 sort

                  min
                  sum
findAll()
NO:
def result = []
[1, 2, 3, 4].each {
    if (it > 2) {
        result << it
    }
}
assert result == [3, 4]


YES:
assert [1, 2, 3, 4].findAll{ it > 2 } == [3, 4]
collect()
NO:
def result = []
[1, 2, 3].each {
    result << it * 2
}
assert result == [2, 4, 6]


YES:
assert [1, 2, 3].collect{ it * 2 } == [2, 4, 6]
inject()
NO:
def total = 0
[1, 2, 3].each {
    total += it
}
assert total == 6


YES:
def total = [1, 2, 3].inject(0) { acc, n ->
    acc + n
}
assert total == 6
find()
NO:
def result
try {
    [1, 2, 3].each {
        if (it > 1) {
            result = it
            throw new Exception()   // monstrous
        }
    }
} catch(exception) { }
assert result == 2


YES:
assert [1, 2, 3].find{ it > 1 } == 2
max()
@TupleConstructor   // import groovy.transform.*
class Person {
    String name
    Integer age
}

def   person1 = new Person('Arturo', 26)
def   person2 = new Person('Luis', 61)
def   person3 = new Person('Laura', 19)
def   family = [] << person1 << person2 << person3

assert family.max{ it.age }.age == 61
assert family.collect{ it.age }.max() == 61
assert family*.age.max() == 61
Refactoring
def exists = false
family.each { person ->
    if (person.age > 60) {
        exists = true
    }
}
assert exists == true

def exists = family.inject(false) { found, person ->
    if (person.age > 60) {
        found = true
    }
    return found
}
assert exists == true

assert family.any{ it.age > 60 } == true
Combinator Functions
@TupleConstructor // import groovy.transform.*
class Person {
    String name
    String lastname
    Integer age
}

def   rafa = new Person('Rafael', 'Luque', 36)
def   marcin = new Person('Marcin', 'Gryszko', 34)
def   arturo = new Person('Arturo', 'Herrero', 26)
def   osokers = [] << rafa << marcin << arturo << rafa

assert osokers.unique(false)
              .findAll{ it.age > 30}
              .sort{ it.lastname } == [marcin, rafa]

assert osokers == [rafa, marcin, arturo, rafa]
Combinator Functions
// Procedural style
def count = 0
for (i in (1 .. 1000)) {
    if (i % 2) {
        count += ("$i".size())
    }
}
assert count == 1445

// Functional style
def count = (1 .. 1000).findAll{ it % 2 }
                       .collect{ "$it" }
                       .inject(0) { sum, num ->
                            sum + num.size()
                        }
assert count == 1445
Lazy Evaluation
Only does as much work as necessary
 Delays the evaluation of the expression
 until it's needed

CPU efficient
  The value is not calculated or assigned
  until the value is requested

Manage potentially infinite data structures
 Only a manageable subset of the data
 will actually be used
Lazy Evaluation

class Person {
    @Lazy String name = 'Arturo'
}

def person = new Person()
assert !(person.dump().contains('Arturo'))

assert person.name.size() == 6
assert person.dump().contains('Arturo')
Lazy Evaluation
class Get {
    String url
    @Lazy URL urlObj = { url?.toURL() }()
    @Lazy(soft=true) String text = urlObj?.text
}

def get = new Get(url: 'http://arturoherrero.com')

assert get.url == 'http://arturoherrero.com'
assert get.dump().contains('text=null')
assert get.dump().contains('urlObj=null')

assert get.urlObj.protocol == 'http'
assert get.urlObj.host == 'arturoherrero.com'
assert get.text.contains('Arturo Herrero')
Lazy Evaluation
groovy.sql.DataSet.DataSet
groovy.util.XmlSlurper



@Singleton(lazy=true)
class Util {
    Integer count(text) {
        text.size()
    }
}

assert 6 == Util.instance.count('Arturo')
Infinite structures

class LazyList {
    ...
}

def naturalnumbers = integers(1)
assert '1 2 3 4 5 6' == naturalnumbers.take(6).join(' ')

def evennumbers = naturalnumbers.filter{ it % 2 == 0 }
assert '2 4 6 8 10 12' == evennumbers.take(6).join(' ')
Infinite structures

@Grab('org.functionaljava:functionaljava:3.0')
import fj.data.Stream

Stream.metaClass.filter = { Closure c ->
    delegate.filter(c as fj.F) }

Stream.metaClass.asList = {
    delegate.toCollection().asList() }

def evens = Stream.range(1).filter{ it % 2 == 0 }
assert [2, 4, 6, 8, 10, 12] == evens.take(6).asList()
Recursive
factorial(6)
6 * factorial(5)
6 * (5 * factorial(4))
6 * (5 * (4 * factorial(3)))
6 * (5 * (4 * (3 * factorial(2))))
6 * (5 * (4 * (3 * (2 * factorial(1)))))
6 * (5 * (4 * (3 * (2 * 1))))
6 * (5 * (4 * (3 * 2)))
6 * (5 * (4 * 6))
6 * (5 * 24)
6 * 120
720
Recursive
factorial(6)
6 * factorial(5)
6 * (5 * factorial(4))
6 * (5 * (4 * factorial(3)))
6 * (5 * (4 * (3 * factorial(2))))
6 * (5 * (4 * (3 * (2 * factorial(1)))))
6 * (5 * (4 * (3 * (2 * 1))))
6 * (5 * (4 * (3 * 2)))
6 * (5 * (4 * 6))
6 * (5 * 24)
6 * 120
720
Tail-Recursive
factorial(6,   1)
factorial(5,   6)
factorial(4,   30)
factorial(3,   120)
factorial(2,   360)
factorial(1,   720)
Tail-Recursive
factorial(6,   1)
factorial(5,   6)
factorial(4,   30)
factorial(3,   120)
factorial(2,   360)
factorial(1,   720)
Tail Call Optimization

3 techniques:

    The compiler transform the recursion into a loop
λ




    Let the JVM recognize the recursion and eliminate it
λ




    Transform the recursion into iterative by hand
λ
Tail Call Optimization

3 techniques:

    The compiler transform the recursion into a loop
λ




    Let the JVM recognize the recursion and eliminate it
λ




    Transform the recursion into iterative by hand
λ




                                          really?
Tail Call Optimization

def factorial

factorial = { n ->
    n == 1 ? 1 :
    n * factorial(n - 1)
}

factorial(1000)
Tail Call Optimization
                                rflow
                           kO ve
def factorial       S   tac
factorial = { n ->
    n == 1 ? 1 :
    n * factorial(n - 1)
}

factorial(1000)
Tail Call Optimization

def factorial

factorial = { n, BigInteger acc = 1 ->
    n == 1 ? acc :
    factorial(n - 1, n * acc)
}

factorial(1000)
Tail Call Optimization
                                rflow
                           kO ve
def factorial       S   tac
factorial = { n, BigInteger acc = 1 ->
    n == 1 ? acc :
    factorial(n - 1, n * acc)
}

factorial(1000)
Tail Call Optimization

def factorial

factorial = { n, BigInteger acc = 1 ->
    n == 1 ? acc :
    factorial.trampoline(n - 1, n * acc)
}.trampoline()

factorial(1000)
Trampolining

def even, odd

even = { x -> x == 0 ? true :
              odd.trampoline(x - 1) }.trampoline()

odd = { x -> x == 0 ? false :
             even.trampoline(x - 1) }.trampoline()

assert even(1000) == true
Memoization

def fibonacci

fibonacci = { n ->
    n <= 1 ? n :
    fibonacci(n - 1) + fibonacci(n - 2)
}

fibonacci(35)   // 9.935 seconds
Memoization

def fibonacci

fibonacci = { n ->
    n <= 1 ? n :
    fibonacci(n - 1) + fibonacci(n - 2)
}.memoize()

fibonacci(35)   // 0.002 seconds
Memoization
def plus = { a, b -> sleep 1000; a + b }.memoize()

assert   plus(1,   2)   ==   3   //   after 1000ms
assert   plus(1,   2)   ==   3   //   return immediately
assert   plus(2,   2)   ==   4   //   after 1000ms
assert   plus(2,   2)   ==   4   //   return immediately

def plusAtLeast = { ... }.memoizeAtLeast(10)

def plusAtMost      = { ... }.memoizeAtMost(10)

def plusBetween = { ... }.memoizeBetween(10, 20)
“Functional” is more a way of thinking
            than a tool set

                            Neal Ford
Be a craftsman
Thank you!
@ArturoHerrero

Join us at OSOCO

More Related Content

What's hot

From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modelingMario Fusco
 
Functional Programming
Functional ProgrammingFunctional Programming
Functional ProgrammingRyan Riley
 
Lambda Expressions in Java | Java Lambda Tutorial | Java Certification Traini...
Lambda Expressions in Java | Java Lambda Tutorial | Java Certification Traini...Lambda Expressions in Java | Java Lambda Tutorial | Java Certification Traini...
Lambda Expressions in Java | Java Lambda Tutorial | Java Certification Traini...Edureka!
 
OOP with Java - Continued
OOP with Java - Continued OOP with Java - Continued
OOP with Java - Continued Hitesh-Java
 
Basics of reflection in java
Basics of reflection in javaBasics of reflection in java
Basics of reflection in javakim.mens
 
Java Arrays
Java ArraysJava Arrays
Java ArraysOXUS 20
 
Functional programming
Functional programmingFunctional programming
Functional programmingijcd
 
Class and Objects in PHP
Class and Objects in PHPClass and Objects in PHP
Class and Objects in PHPRamasubbu .P
 
Advanced Node.JS Meetup
Advanced Node.JS MeetupAdvanced Node.JS Meetup
Advanced Node.JS MeetupLINAGORA
 
Test-Driven Development in Vue with Cypress
Test-Driven Development in Vue with CypressTest-Driven Development in Vue with Cypress
Test-Driven Development in Vue with CypressJosh Justice
 
Sequence and Traverse - Part 2
Sequence and Traverse - Part 2Sequence and Traverse - Part 2
Sequence and Traverse - Part 2Philip Schwarz
 
Sagas Middleware Architecture
Sagas Middleware ArchitectureSagas Middleware Architecture
Sagas Middleware ArchitectureMateusz Bosek
 
Introduction to Design Patterns and Singleton
Introduction to Design Patterns and SingletonIntroduction to Design Patterns and Singleton
Introduction to Design Patterns and SingletonJonathan Simon
 
The Power Of Composition (DotNext 2019)
The Power Of Composition (DotNext 2019)The Power Of Composition (DotNext 2019)
The Power Of Composition (DotNext 2019)Scott Wlaschin
 
Functional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorldFunctional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorldJorge Vásquez
 
Domain Modeling in a Functional World
Domain Modeling in a Functional WorldDomain Modeling in a Functional World
Domain Modeling in a Functional WorldDebasish Ghosh
 

What's hot (20)

From object oriented to functional domain modeling
From object oriented to functional domain modelingFrom object oriented to functional domain modeling
From object oriented to functional domain modeling
 
Functional Programming
Functional ProgrammingFunctional Programming
Functional Programming
 
Lambda Expressions in Java | Java Lambda Tutorial | Java Certification Traini...
Lambda Expressions in Java | Java Lambda Tutorial | Java Certification Traini...Lambda Expressions in Java | Java Lambda Tutorial | Java Certification Traini...
Lambda Expressions in Java | Java Lambda Tutorial | Java Certification Traini...
 
OOP with Java - Continued
OOP with Java - Continued OOP with Java - Continued
OOP with Java - Continued
 
Basics of reflection in java
Basics of reflection in javaBasics of reflection in java
Basics of reflection in java
 
Java Arrays
Java ArraysJava Arrays
Java Arrays
 
Functional programming
Functional programmingFunctional programming
Functional programming
 
Class and Objects in PHP
Class and Objects in PHPClass and Objects in PHP
Class and Objects in PHP
 
Advanced Node.JS Meetup
Advanced Node.JS MeetupAdvanced Node.JS Meetup
Advanced Node.JS Meetup
 
Test-Driven Development in Vue with Cypress
Test-Driven Development in Vue with CypressTest-Driven Development in Vue with Cypress
Test-Driven Development in Vue with Cypress
 
Sequence and Traverse - Part 2
Sequence and Traverse - Part 2Sequence and Traverse - Part 2
Sequence and Traverse - Part 2
 
Redux Thunk
Redux ThunkRedux Thunk
Redux Thunk
 
Sagas Middleware Architecture
Sagas Middleware ArchitectureSagas Middleware Architecture
Sagas Middleware Architecture
 
Introduction to Design Patterns and Singleton
Introduction to Design Patterns and SingletonIntroduction to Design Patterns and Singleton
Introduction to Design Patterns and Singleton
 
The Power Of Composition (DotNext 2019)
The Power Of Composition (DotNext 2019)The Power Of Composition (DotNext 2019)
The Power Of Composition (DotNext 2019)
 
Java &amp; advanced java
Java &amp; advanced javaJava &amp; advanced java
Java &amp; advanced java
 
Functional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorldFunctional Programming 101 with Scala and ZIO @FunctionalWorld
Functional Programming 101 with Scala and ZIO @FunctionalWorld
 
Domain Modeling in a Functional World
Domain Modeling in a Functional WorldDomain Modeling in a Functional World
Domain Modeling in a Functional World
 
Broadleaf Presents Thymeleaf
Broadleaf Presents ThymeleafBroadleaf Presents Thymeleaf
Broadleaf Presents Thymeleaf
 
Scala fundamentals
Scala fundamentalsScala fundamentals
Scala fundamentals
 

Viewers also liked

A Common API & UI for Building Next Generation Identity Services
A Common API & UI for Building Next Generation Identity ServicesA Common API & UI for Building Next Generation Identity Services
A Common API & UI for Building Next Generation Identity ServicesForgeRock
 
The rise of ad networks
The rise of ad networksThe rise of ad networks
The rise of ad networksDung Tri
 
Take a Groovy REST
Take a Groovy RESTTake a Groovy REST
Take a Groovy RESTRestlet
 
Groovy Tutorial
Groovy TutorialGroovy Tutorial
Groovy TutorialPaul King
 
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...Guillaume Laforge
 
Webinar: Extend The Power of The ForgeRock Identity Platform Through Scripting
Webinar: Extend The Power of The ForgeRock Identity Platform Through ScriptingWebinar: Extend The Power of The ForgeRock Identity Platform Through Scripting
Webinar: Extend The Power of The ForgeRock Identity Platform Through ScriptingForgeRock
 
Dropwizard and Groovy
Dropwizard and GroovyDropwizard and Groovy
Dropwizard and Groovytomaslin
 
groovy and concurrency
groovy and concurrencygroovy and concurrency
groovy and concurrencyPaul King
 
Dev Ops Geek Fest: Automating the ForgeRock Platform
Dev Ops Geek Fest: Automating the ForgeRock PlatformDev Ops Geek Fest: Automating the ForgeRock Platform
Dev Ops Geek Fest: Automating the ForgeRock PlatformForgeRock
 
Customer Scale: Stateless Sessions and Managing High-Volume Digital Services
Customer Scale: Stateless Sessions and Managing High-Volume Digital ServicesCustomer Scale: Stateless Sessions and Managing High-Volume Digital Services
Customer Scale: Stateless Sessions and Managing High-Volume Digital ServicesForgeRock
 
“Here be Dragons”, connecting a changing world to strategic decisions through...
“Here be Dragons”, connecting a changing world to strategic decisions through...“Here be Dragons”, connecting a changing world to strategic decisions through...
“Here be Dragons”, connecting a changing world to strategic decisions through...Gill Ringland
 
Evaluation question 1- In what ways do your media products use, develop or ch...
Evaluation question 1- In what ways do your media products use, develop or ch...Evaluation question 1- In what ways do your media products use, develop or ch...
Evaluation question 1- In what ways do your media products use, develop or ch...zayzay96
 
Presentación sobre autores María G. y Evelyn
Presentación sobre autores María G. y EvelynPresentación sobre autores María G. y Evelyn
Presentación sobre autores María G. y EvelynsextoBLucena
 
Introducción a vectores en C
Introducción a vectores en CIntroducción a vectores en C
Introducción a vectores en CJuan Quintero
 
Derechos humanos y accesibilidad universal.
Derechos humanos y accesibilidad universal.Derechos humanos y accesibilidad universal.
Derechos humanos y accesibilidad universal.José María
 
Socia Media in the Workplace
Socia Media in the WorkplaceSocia Media in the Workplace
Socia Media in the WorkplaceTodd Wheatland
 
مسيرة التنمية
مسيرة التنميةمسيرة التنمية
مسيرة التنميةTarek Ghonaim
 

Viewers also liked (20)

A Common API & UI for Building Next Generation Identity Services
A Common API & UI for Building Next Generation Identity ServicesA Common API & UI for Building Next Generation Identity Services
A Common API & UI for Building Next Generation Identity Services
 
The rise of ad networks
The rise of ad networksThe rise of ad networks
The rise of ad networks
 
Take a Groovy REST
Take a Groovy RESTTake a Groovy REST
Take a Groovy REST
 
Groovy Tutorial
Groovy TutorialGroovy Tutorial
Groovy Tutorial
 
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
Groovy DSLs, from Beginner to Expert - Guillaume Laforge and Paul King - Spri...
 
Webinar: Extend The Power of The ForgeRock Identity Platform Through Scripting
Webinar: Extend The Power of The ForgeRock Identity Platform Through ScriptingWebinar: Extend The Power of The ForgeRock Identity Platform Through Scripting
Webinar: Extend The Power of The ForgeRock Identity Platform Through Scripting
 
Dropwizard and Groovy
Dropwizard and GroovyDropwizard and Groovy
Dropwizard and Groovy
 
groovy and concurrency
groovy and concurrencygroovy and concurrency
groovy and concurrency
 
Dev Ops Geek Fest: Automating the ForgeRock Platform
Dev Ops Geek Fest: Automating the ForgeRock PlatformDev Ops Geek Fest: Automating the ForgeRock Platform
Dev Ops Geek Fest: Automating the ForgeRock Platform
 
Customer Scale: Stateless Sessions and Managing High-Volume Digital Services
Customer Scale: Stateless Sessions and Managing High-Volume Digital ServicesCustomer Scale: Stateless Sessions and Managing High-Volume Digital Services
Customer Scale: Stateless Sessions and Managing High-Volume Digital Services
 
“Here be Dragons”, connecting a changing world to strategic decisions through...
“Here be Dragons”, connecting a changing world to strategic decisions through...“Here be Dragons”, connecting a changing world to strategic decisions through...
“Here be Dragons”, connecting a changing world to strategic decisions through...
 
Birmańskie opowieści
Birmańskie opowieściBirmańskie opowieści
Birmańskie opowieści
 
Evaluation question 1- In what ways do your media products use, develop or ch...
Evaluation question 1- In what ways do your media products use, develop or ch...Evaluation question 1- In what ways do your media products use, develop or ch...
Evaluation question 1- In what ways do your media products use, develop or ch...
 
Presentación sobre autores María G. y Evelyn
Presentación sobre autores María G. y EvelynPresentación sobre autores María G. y Evelyn
Presentación sobre autores María G. y Evelyn
 
Introducción a vectores en C
Introducción a vectores en CIntroducción a vectores en C
Introducción a vectores en C
 
Derechos humanos y accesibilidad universal.
Derechos humanos y accesibilidad universal.Derechos humanos y accesibilidad universal.
Derechos humanos y accesibilidad universal.
 
Presentation media
Presentation media Presentation media
Presentation media
 
Socia Media in the Workplace
Socia Media in the WorkplaceSocia Media in the Workplace
Socia Media in the Workplace
 
PlanoGestão
PlanoGestão PlanoGestão
PlanoGestão
 
مسيرة التنمية
مسيرة التنميةمسيرة التنمية
مسيرة التنمية
 

Similar to Functional Programming with Groovy

Groovy puzzlers по русски с Joker 2014
Groovy puzzlers по русски с Joker 2014Groovy puzzlers по русски с Joker 2014
Groovy puzzlers по русски с Joker 2014Baruch Sadogursky
 
Groovy grails types, operators, objects
Groovy grails types, operators, objectsGroovy grails types, operators, objects
Groovy grails types, operators, objectsHusain Dalal
 
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRaimonds Simanovskis
 
Groovy puzzlers jug-moscow-part 2
Groovy puzzlers jug-moscow-part 2Groovy puzzlers jug-moscow-part 2
Groovy puzzlers jug-moscow-part 2Evgeny Borisov
 
Monadologie
MonadologieMonadologie
Monadologieleague
 
A swift introduction to Swift
A swift introduction to SwiftA swift introduction to Swift
A swift introduction to SwiftGiordano Scalzo
 
A limited guide to intermediate and advanced Ruby
A limited guide to intermediate and advanced RubyA limited guide to intermediate and advanced Ruby
A limited guide to intermediate and advanced RubyVysakh Sreenivasan
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfHiroshi Ono
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick touraztack
 

Similar to Functional Programming with Groovy (20)

Introduction to Groovy
Introduction to GroovyIntroduction to Groovy
Introduction to Groovy
 
CoffeeScript
CoffeeScriptCoffeeScript
CoffeeScript
 
Groovy puzzlers по русски с Joker 2014
Groovy puzzlers по русски с Joker 2014Groovy puzzlers по русски с Joker 2014
Groovy puzzlers по русски с Joker 2014
 
Groovy grails types, operators, objects
Groovy grails types, operators, objectsGroovy grails types, operators, objects
Groovy grails types, operators, objects
 
Introduction to Scala
Introduction to ScalaIntroduction to Scala
Introduction to Scala
 
SDC - Einführung in Scala
SDC - Einführung in ScalaSDC - Einführung in Scala
SDC - Einführung in Scala
 
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and JasmineRails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
Rails-like JavaScript Using CoffeeScript, Backbone.js and Jasmine
 
Groovy puzzlers jug-moscow-part 2
Groovy puzzlers jug-moscow-part 2Groovy puzzlers jug-moscow-part 2
Groovy puzzlers jug-moscow-part 2
 
Monadologie
MonadologieMonadologie
Monadologie
 
Pooya Khaloo Presentation on IWMC 2015
Pooya Khaloo Presentation on IWMC 2015Pooya Khaloo Presentation on IWMC 2015
Pooya Khaloo Presentation on IWMC 2015
 
A swift introduction to Swift
A swift introduction to SwiftA swift introduction to Swift
A swift introduction to Swift
 
A limited guide to intermediate and advanced Ruby
A limited guide to intermediate and advanced RubyA limited guide to intermediate and advanced Ruby
A limited guide to intermediate and advanced Ruby
 
Python : Functions
Python : FunctionsPython : Functions
Python : Functions
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdfpragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
pragmaticrealworldscalajfokus2009-1233251076441384-2.pdf
 
Ruby Language - A quick tour
Ruby Language - A quick tourRuby Language - A quick tour
Ruby Language - A quick tour
 
ddd+scala
ddd+scaladdd+scala
ddd+scala
 
Coding in Style
Coding in StyleCoding in Style
Coding in Style
 

Recently uploaded

Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebUiPathCommunity
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticscarlostorres15106
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyAlfredo García Lavilla
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Wonjun Hwang
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubKalema Edgar
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii SoldatenkoFwdays
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024Stephanie Beckett
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Mark Simos
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationSafe Software
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek SchlawackFwdays
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsSergiu Bodiu
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfSeasiaInfotech2
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Enterprise Knowledge
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024BookNet Canada
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsMiki Katsuragi
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Manik S Magar
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxNavinnSomaal
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfRankYa
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piececharlottematthew16
 

Recently uploaded (20)

Dev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio WebDev Dives: Streamline document processing with UiPath Studio Web
Dev Dives: Streamline document processing with UiPath Studio Web
 
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmaticsKotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
Kotlin Multiplatform & Compose Multiplatform - Starter kit for pragmatics
 
Commit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easyCommit 2024 - Secret Management made easy
Commit 2024 - Secret Management made easy
 
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
Bun (KitWorks Team Study 노별마루 발표 2024.4.22)
 
Unleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding ClubUnleash Your Potential - Namagunga Girls Coding Club
Unleash Your Potential - Namagunga Girls Coding Club
 
"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko"Debugging python applications inside k8s environment", Andrii Soldatenko
"Debugging python applications inside k8s environment", Andrii Soldatenko
 
What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024What's New in Teams Calling, Meetings and Devices March 2024
What's New in Teams Calling, Meetings and Devices March 2024
 
DMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special EditionDMCC Future of Trade Web3 - Special Edition
DMCC Future of Trade Web3 - Special Edition
 
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
Tampa BSides - Chef's Tour of Microsoft Security Adoption Framework (SAF)
 
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry InnovationBeyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
Beyond Boundaries: Leveraging No-Code Solutions for Industry Innovation
 
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
"Subclassing and Composition – A Pythonic Tour of Trade-Offs", Hynek Schlawack
 
DevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platformsDevEX - reference for building teams, processes, and platforms
DevEX - reference for building teams, processes, and platforms
 
The Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdfThe Future of Software Development - Devin AI Innovative Approach.pdf
The Future of Software Development - Devin AI Innovative Approach.pdf
 
Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024Designing IA for AI - Information Architecture Conference 2024
Designing IA for AI - Information Architecture Conference 2024
 
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
Transcript: New from BookNet Canada for 2024: BNC CataList - Tech Forum 2024
 
Vertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering TipsVertex AI Gemini Prompt Engineering Tips
Vertex AI Gemini Prompt Engineering Tips
 
Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!Anypoint Exchange: It’s Not Just a Repo!
Anypoint Exchange: It’s Not Just a Repo!
 
SAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptxSAP Build Work Zone - Overview L2-L3.pptx
SAP Build Work Zone - Overview L2-L3.pptx
 
Search Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdfSearch Engine Optimization SEO PDF for 2024.pdf
Search Engine Optimization SEO PDF for 2024.pdf
 
Story boards and shot lists for my a level piece
Story boards and shot lists for my a level pieceStory boards and shot lists for my a level piece
Story boards and shot lists for my a level piece
 

Functional Programming with Groovy

  • 1. Functional Programming with Groovλ
  • 3. Working at OSOCO Small but outstanding software development shop Groovy and Grails hackers on EC2 cloud nine TDD mantra singers Quality preachers
  • 4. LISt Processing (define (factorial n) (if (= n 1) 1 (* n (factorial (- n 1)))))
  • 5. Lots of Insipid Stupid Parentheses ( (factorial ) ( ( ) ( (factorial ( )))))
  • 6. Code Complete The Pragmatic Programmer Structure and Interpretation of Computer Programs
  • 7.
  • 8. A language that doesn't affect the way you think about programming, is not worth knowing Alan Perlis
  • 11. Functional Programming Avoiding Mutable State λ Side-Effect-Free Functions λ Referential Transparency λ First-Class Citizens λ Higher-Order Functions λ Lambdas and Closures λ Lazy Evaluation λ Recursion λ
  • 12. Why Functional Programming? Referential transparency λ Unit testing λ Debbuging λ Parallelization λ Modularity and composition λ Increases the quality of code λ Abstractions λ
  • 14. Imperative vs. Declarative Imperative: how to achieve our goal Take the next customer from a list. If the customer lives in Spain, show their details. If there are more customers in the list, go to the beginning Declarative: what we want to achieve Show customer details of every customer living in Spain
  • 15. Imperative vs. Declarative Functional programming is like describing your problem to a mathematician. Imperative programming is like giving instructions to an idiot. arcus, #scheme on Freenode
  • 16. Functional Programming with Groovy? is an imperative language, but we still can apply functional principles It's basically a programmer's choice
  • 17. Immutability Simple Immutable objects can only be in exactly one state, the state in which it was created Always consistent Less prone to errors and more secure Immutable objects can be shared freely Freedom to cache Inherently thread-safe
  • 18. Immutability NO: (even being a name rebind and not a real update) book = 'Fooled by Randomness' book = "$book - Nassim Taleb" book = "$book (2001)" assert 'Fooled by Randomness - Nassim Taleb (2001)' == book YES: book = 'Fooled by Randomness' bookWithAuthor = "$book - Nassim Taleb" completeBook = "$bookWithAuthor (2001)" assert 'Fooled by Randomness - Nassim Taleb (2001)' == completeBook
  • 19. Immutability NO: years = [2001, 2002] years << 2003 years += [2004, 2005] assert [2001, 2002, 2003, 2004, 2005] == years YES: years = [2001, 2002] allYears = years + 2003 + [2004, 2005] assert [2001, 2002, 2003, 2004, 2005] == allYears
  • 20. Immutability def list = ['Gr', 'vy'] NO: list.addAll 1, 'oo' assert list == ['Gr', 'oo', 'vy'] YES: assert list.plus(1, 'oo') == ['Gr', 'oo', 'vy'] assert list == ['Gr', 'vy']
  • 21. Immutability def list = [1, 2, 2, 3] NO: list.removeAll 2 assert list == [1, 3] YES: assert list.minus(2) == [1, 3] assert list == [1, 2, 2, 3]
  • 22. Immutability def list = ['Scala', 'Groovy', 'Java'] NO: sortedList = list.sort() assert sortedList == ['Groovy', 'Java', 'Scala'] assert list == ['Groovy', 'Java', 'Scala'] YES: sortedList = list.sort(false) assert sortedList == ['Groovy', 'Java', 'Scala'] assert list == ['Scala', 'Groovy', 'Java']
  • 23. Immutability def list = ['Java', 'Groovy', 'Java'] NO: uniqueList = list.unique() assert uniqueList == ['Java', 'Groovy'] assert list == ['Java', 'Groovy'] YES: uniqueList = list.unique(false) assert uniqueList == ['Java', 'Groovy'] assert list == ['Java', 'Groovy', 'Java']
  • 24. Immutability def list = ['Java', 'Groovy'] NO: reverseList = list.reverse(true) assert reverseList == ['Groovy', 'Java'] assert list == ['Groovy', 'Java'] YES: reverseList = list.reverse() assert reverseList == ['Groovy', 'Java'] assert list == ['Java', 'Groovy']
  • 25. Immutability Collection def list = ['Groovy', 'Java'].asImmutable() assert 'Groovy' == list.first() try { list.add 'Scala' // Cannot add item } catch (e) { assert e instanceof UnsupportedOperationException } try { list.remove 'Java' // Cannot remove item } catch (e) { assert e instanceof UnsupportedOperationException }
  • 26. Immutability Class @Immutable class Coordinates { Double latitude, longitude } def c1 = new Coordinates(latitude: 48.824068, longitude: 2.531733) def c2 = new Coordinates(48.824068, 2.531733) assert c1 == c2
  • 27. Higher-Order Functions First-Class Citizen Can be stored in variables Can be passed as function parameter Can be returned from functions Higher-Order Functions (First-Class Functions) Functions that take other functions as arguments or return them as results
  • 28. Closures def closure = { 'Hello world!' } assert closure() == 'Hello world!' def sum = { a, b -> a + b } assert sum(2,3) == 5 def square = { it * it } assert square(9) == 81 final BASE = 1000 def salary = { variable -> BASE + variable } assert salary(500) == 1500
  • 29. Turn Methods into Closures def salary(variable) { final BASE = 1000 BASE + variable } assert salary(500) == 1500 def salaryClosure = this.&salary assert salaryClosure(500) == 1500
  • 30. Closures Composition def minutesToSeconds = { it * 60 } def hoursToMinutes = { it * 60 } def daysToHours = { it * 24 } def hoursToSeconds = minutesToSeconds << hoursToMinutes def daysToSeconds = hoursToSeconds << daysToHours assert daysToSeconds(1) == 86400
  • 31. Closures Composition def upper = { it.toUpperCase() } def firstLetter = { it.charAt(0) } def words = ["Don't", "Repeat", "Yourself"] def acronym = words.collect(firstLetter >> upper).join() assert acronym == 'DRY'
  • 32. Currying given: ƒ: (X x Y) -> Z then: curry(ƒ): X -> (Y -> Z) Takes a function with a particular number of parameters and returns a function with some of the parameter values fixed, creating a new function
  • 33. Currying def modulus = { mod, num -> num % mod } assert modulus(2, 5) == 1 assert modulus(3, 5) == 2 def mod2 = modulus.curry(2) assert mod2(5) == 1 def mod3 = modulus.curry(3) assert mod3(5) == 2
  • 34. Currying def bill = { amount, currency -> "$amount $currency" } assert bill(1000, '$') == '1000 $' assert bill(1000, '€') == '1000 €' def billInDollars = bill.rcurry('$') assert billInDollars(1000) == '1000 $' def billInEuros = bill.rcurry('€') assert billInEuros(1000) == '1000 €'
  • 35. Currying def joinWithSeparator = { one, sep, two -> one + sep + two } def joinWithAmpersand = joinWithSeparator.ncurry(1, '&') assert joinWithAmpersand('a', 'b') == 'a&b'
  • 36. Classic Operations on Functional Data Types list filter map fold
  • 37. Classic Operations on Functional Data Types list findAll collect inject
  • 38. Classic Operations on Functional Data Types list any every sort min sum
  • 39. findAll() NO: def result = [] [1, 2, 3, 4].each { if (it > 2) { result << it } } assert result == [3, 4] YES: assert [1, 2, 3, 4].findAll{ it > 2 } == [3, 4]
  • 40. collect() NO: def result = [] [1, 2, 3].each { result << it * 2 } assert result == [2, 4, 6] YES: assert [1, 2, 3].collect{ it * 2 } == [2, 4, 6]
  • 41. inject() NO: def total = 0 [1, 2, 3].each { total += it } assert total == 6 YES: def total = [1, 2, 3].inject(0) { acc, n -> acc + n } assert total == 6
  • 42. find() NO: def result try { [1, 2, 3].each { if (it > 1) { result = it throw new Exception() // monstrous } } } catch(exception) { } assert result == 2 YES: assert [1, 2, 3].find{ it > 1 } == 2
  • 43. max() @TupleConstructor // import groovy.transform.* class Person { String name Integer age } def person1 = new Person('Arturo', 26) def person2 = new Person('Luis', 61) def person3 = new Person('Laura', 19) def family = [] << person1 << person2 << person3 assert family.max{ it.age }.age == 61 assert family.collect{ it.age }.max() == 61 assert family*.age.max() == 61
  • 44. Refactoring def exists = false family.each { person -> if (person.age > 60) { exists = true } } assert exists == true def exists = family.inject(false) { found, person -> if (person.age > 60) { found = true } return found } assert exists == true assert family.any{ it.age > 60 } == true
  • 45. Combinator Functions @TupleConstructor // import groovy.transform.* class Person { String name String lastname Integer age } def rafa = new Person('Rafael', 'Luque', 36) def marcin = new Person('Marcin', 'Gryszko', 34) def arturo = new Person('Arturo', 'Herrero', 26) def osokers = [] << rafa << marcin << arturo << rafa assert osokers.unique(false) .findAll{ it.age > 30} .sort{ it.lastname } == [marcin, rafa] assert osokers == [rafa, marcin, arturo, rafa]
  • 46. Combinator Functions // Procedural style def count = 0 for (i in (1 .. 1000)) { if (i % 2) { count += ("$i".size()) } } assert count == 1445 // Functional style def count = (1 .. 1000).findAll{ it % 2 } .collect{ "$it" } .inject(0) { sum, num -> sum + num.size() } assert count == 1445
  • 47. Lazy Evaluation Only does as much work as necessary Delays the evaluation of the expression until it's needed CPU efficient The value is not calculated or assigned until the value is requested Manage potentially infinite data structures Only a manageable subset of the data will actually be used
  • 48. Lazy Evaluation class Person { @Lazy String name = 'Arturo' } def person = new Person() assert !(person.dump().contains('Arturo')) assert person.name.size() == 6 assert person.dump().contains('Arturo')
  • 49. Lazy Evaluation class Get { String url @Lazy URL urlObj = { url?.toURL() }() @Lazy(soft=true) String text = urlObj?.text } def get = new Get(url: 'http://arturoherrero.com') assert get.url == 'http://arturoherrero.com' assert get.dump().contains('text=null') assert get.dump().contains('urlObj=null') assert get.urlObj.protocol == 'http' assert get.urlObj.host == 'arturoherrero.com' assert get.text.contains('Arturo Herrero')
  • 50. Lazy Evaluation groovy.sql.DataSet.DataSet groovy.util.XmlSlurper @Singleton(lazy=true) class Util { Integer count(text) { text.size() } } assert 6 == Util.instance.count('Arturo')
  • 51. Infinite structures class LazyList { ... } def naturalnumbers = integers(1) assert '1 2 3 4 5 6' == naturalnumbers.take(6).join(' ') def evennumbers = naturalnumbers.filter{ it % 2 == 0 } assert '2 4 6 8 10 12' == evennumbers.take(6).join(' ')
  • 52. Infinite structures @Grab('org.functionaljava:functionaljava:3.0') import fj.data.Stream Stream.metaClass.filter = { Closure c -> delegate.filter(c as fj.F) } Stream.metaClass.asList = { delegate.toCollection().asList() } def evens = Stream.range(1).filter{ it % 2 == 0 } assert [2, 4, 6, 8, 10, 12] == evens.take(6).asList()
  • 53. Recursive factorial(6) 6 * factorial(5) 6 * (5 * factorial(4)) 6 * (5 * (4 * factorial(3))) 6 * (5 * (4 * (3 * factorial(2)))) 6 * (5 * (4 * (3 * (2 * factorial(1))))) 6 * (5 * (4 * (3 * (2 * 1)))) 6 * (5 * (4 * (3 * 2))) 6 * (5 * (4 * 6)) 6 * (5 * 24) 6 * 120 720
  • 54. Recursive factorial(6) 6 * factorial(5) 6 * (5 * factorial(4)) 6 * (5 * (4 * factorial(3))) 6 * (5 * (4 * (3 * factorial(2)))) 6 * (5 * (4 * (3 * (2 * factorial(1))))) 6 * (5 * (4 * (3 * (2 * 1)))) 6 * (5 * (4 * (3 * 2))) 6 * (5 * (4 * 6)) 6 * (5 * 24) 6 * 120 720
  • 55. Tail-Recursive factorial(6, 1) factorial(5, 6) factorial(4, 30) factorial(3, 120) factorial(2, 360) factorial(1, 720)
  • 56. Tail-Recursive factorial(6, 1) factorial(5, 6) factorial(4, 30) factorial(3, 120) factorial(2, 360) factorial(1, 720)
  • 57. Tail Call Optimization 3 techniques: The compiler transform the recursion into a loop λ Let the JVM recognize the recursion and eliminate it λ Transform the recursion into iterative by hand λ
  • 58. Tail Call Optimization 3 techniques: The compiler transform the recursion into a loop λ Let the JVM recognize the recursion and eliminate it λ Transform the recursion into iterative by hand λ really?
  • 59. Tail Call Optimization def factorial factorial = { n -> n == 1 ? 1 : n * factorial(n - 1) } factorial(1000)
  • 60. Tail Call Optimization rflow kO ve def factorial S tac factorial = { n -> n == 1 ? 1 : n * factorial(n - 1) } factorial(1000)
  • 61. Tail Call Optimization def factorial factorial = { n, BigInteger acc = 1 -> n == 1 ? acc : factorial(n - 1, n * acc) } factorial(1000)
  • 62. Tail Call Optimization rflow kO ve def factorial S tac factorial = { n, BigInteger acc = 1 -> n == 1 ? acc : factorial(n - 1, n * acc) } factorial(1000)
  • 63. Tail Call Optimization def factorial factorial = { n, BigInteger acc = 1 -> n == 1 ? acc : factorial.trampoline(n - 1, n * acc) }.trampoline() factorial(1000)
  • 64. Trampolining def even, odd even = { x -> x == 0 ? true : odd.trampoline(x - 1) }.trampoline() odd = { x -> x == 0 ? false : even.trampoline(x - 1) }.trampoline() assert even(1000) == true
  • 65. Memoization def fibonacci fibonacci = { n -> n <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2) } fibonacci(35) // 9.935 seconds
  • 66. Memoization def fibonacci fibonacci = { n -> n <= 1 ? n : fibonacci(n - 1) + fibonacci(n - 2) }.memoize() fibonacci(35) // 0.002 seconds
  • 67. Memoization def plus = { a, b -> sleep 1000; a + b }.memoize() assert plus(1, 2) == 3 // after 1000ms assert plus(1, 2) == 3 // return immediately assert plus(2, 2) == 4 // after 1000ms assert plus(2, 2) == 4 // return immediately def plusAtLeast = { ... }.memoizeAtLeast(10) def plusAtMost = { ... }.memoizeAtMost(10) def plusBetween = { ... }.memoizeBetween(10, 20)
  • 68. “Functional” is more a way of thinking than a tool set Neal Ford
  • 70.