SlideShare a Scribd company logo
1 of 43
Download to read offline
What’s in Groovy for
Functional
Programming
Naresha K
@naresha_k
https://blog.nareshak.com/
APACHECON @HOME
Spt, 29th – Oct. 1st 2020
About me
Developer, Architect &
Tech Excellence Coach
Founder & Organiser
Bangalore Groovy User
Group
2
https://twitter.com/mfeathers/status/29581296216
3
4
String greet(String message) {
"Hello, ${message}"
}
String greet() {
"Hello"
}
String greet(String message, String friend) {
"Hello $friend, $message"
}
Regular Functions
5
String greet(String message) {
"Hello, ${message}"
}
def greet = { message -> "Hello, ${message}" }
// OR
def greet = { "Hello, ${it}" }
println greet("Good morning")
Closures are powerful
6
String greet() {
"Hello"
}
def greet = { -> "Hello" }
println greet()
7
String greet(String message, String friend) {
"Hello $friend, $message"
}
def greet = { message, friend -> "Hello $friend, $message" }
println greet()
8
def greet = { message -> "Hello, ${message}" }
def message = "Hello"
Integer age = 30
println greet("Good morning")
Closures are first class
9
@ToString(includePackage = false)
class Developer {
String name
int age
List<String> skills
}
List<Developer> developers = [
new Developer(name: 'Raj', age: 24, skills: ['Java',
'Groovy']),
new Developer(name: 'Sheldon', age: 30, skills: ['Java',
'Scala', 'Clojure']),
new Developer(name: 'Penny', age: 28, skills: ['Groovy',
'Scala']),
]
Sample data
10
List<Developer> findGroovyDevelopers(List<Developer> devs) {
List<Developer> groovyDevs = []
for(developer in devs) {
if(developer.skills.contains("Groovy")){
groovyDevs << developer
}
}
groovyDevs
}
println findGroovyDevelopers(developers)
Imperative code!
11
List<Developer> findGroovyDevelopers(List<Developer> devs) {
List<Developer> groovyDevs = []
for(developer in devs) {
if(developer.skills.contains("Groovy")){
groovyDevs << developer
}
}
groovyDevs
}
List<Developer> findGroovyDevelopers(List<Developer> devs) {
devs.findAll { dev -> dev.skills.contains('Groovy') }
}
Refactor to idiomatic Groovy
12
List<Developer> findGroovyDevelopers(List<Developer> devs) {
List<Developer> groovyDevs = []
for(developer in devs) {
if(developer.skills.contains("Groovy")){
groovyDevs << developer
}
}
groovyDevs
}
List<Developer> findGroovyDevelopers(List<Developer> devs) {
devs.findAll { dev -> dev.skills.contains('Groovy') }
}
Higher Order Function
13
List<Developer> findGroovyDevelopers(List<Developer> devs) {
devs.findAll { dev -> dev.skills.contains('Groovy') }
}
List<Developer> findGroovyDevelopers(List<Developer> devs) {
def knowsGroovy = { dev -> dev.skills.contains('Groovy') }
devs.findAll(knowsGroovy)
}
List<Developer> findDevelopers(List<Developer> devs,
Closure skillFinder) {
devs.findAll(skillFinder)
}
14
List<Developer> findDevelopers(List<Developer> devs, Closure
skillFinder) {
devs.findAll(skillFinder)
}
Closure createSkillFinder(String language) {
Closure skillFinder = { Developer developer ->
developer.skills.contains(language)
}
skillFinder
}
Closure knowsGroovy = createSkillFinder('Groovy')
println findDevelopers(developers, knowsGroovy)
15
Closure knowsGroovy = createSkillFinder('Groovy')
Closure knowsJava = createSkillFinder('Java')
println findDevelopers(developers, knowsGroovy)
println findDevelopers(developers, knowsJava)
16
Closure knowsGroovy = createSkillFinder('Groovy')
Closure knowsJava = createSkillFinder('Java')
println findDevelopers(developers, knowsGroovy)
println findDevelopers(developers, knowsJava)
Strategy Pattern
17
def command1 = {
println "Running command-1"
}
def command2 = {
println "Running command-2"
}
void runCommand(Closure command) {
command()
}
runCommand(command1)
runCommand(command2)
Command Pattern
18
def command1 = {
println "Running command-1"
}
def command2 = {
println "Running command-2"
}
void runCommand(Closure command) {
command()
}
[command1, command2].each { runCommand(it) }
Command Pattern
19
def command1 = {
println "Running command-1"
}
def command2 = {
println "Running command-2"
}
void runCommand(Closure command) {
println "Before command"
command()
println "After command"
}
[command1, command2].each { runCommand(it) }
Execute-Around Pattern
20
def add = { a, b -> a + b }
println add(10, 20)
21
def add = { a, b -> a + b }
println add(10, 20)
def increment = add.curry(1)
println increment(10)
Partial Application/ 

Currying
22
Closure createSkillFinder(String language) {
Closure skillFinder = { Developer developer ->
developer.skills.contains(language)
}
skillFinder
}
Closure knowsGroovy = createSkillFinder('Groovy')
Closure knowsJava = createSkillFinder('Java')
def findDevelopers = { List<Developer> devs, Closure skillFinder ->
devs.findAll(skillFinder)
}
23
def findDevelopers = { List<Developer> devs, Closure skillFinder ->
devs.findAll(skillFinder)
}
List<String> firstNamesOfDevs(List<Developer> devs, Closure
devSelector) {
List<Developer> selectedDevs = devSelector(devs)
selectedDevs.collect { it.name }
}
24
def findDevelopers = { List<Developer> devs, Closure skillFinder ->
devs.findAll(skillFinder)
}
List<String> firstNamesOfDevs(List<Developer> devs, Closure
devSelector) {
List<Developer> selectedDevs = devSelector(devs)
selectedDevs.collect { it.name }
}
def groovyDevSelector = findDevelopers.rcurry(knowsGroovy)
println firstNamesOfDevs(developers, groovyDevSelector)
25
println firstNamesOfDevs(developers, javaAndGroovyDevSelector)
26
Closure groovyDevSelector = findDevelopers.rcurry(knowsGroovy)
Closure javaDevSelector = findDevelopers.rcurry(knowsJava)
println firstNamesOfDevs(developers, javaAndGroovyDevSelector)
27
Closure groovyDevSelector = findDevelopers.rcurry(knowsGroovy)
Closure javaDevSelector = findDevelopers.rcurry(knowsJava)
Closure javaAndGroovyDevSelector =
groovyDevSelector << javaDevSelector
println firstNamesOfDevs(developers, javaAndGroovyDevSelector)
Function Composition
28
Closure knowsGroovy = { dev -> dev.skills.contains('Groovy') }
Closure ageOfDev = { Developer developer -> developer.age }
def averageAgeOfGroovyDevs = developers
.findAll(knowsGroovy)
.collect(ageOfDev)
.with { sum() / size() }
Map, filter, reduce
29
Closure knowsGroovy = { dev -> dev.skills.contains('Groovy') }
Closure ageOfDev = { Developer developer -> developer.age }
def averageAgeOfGroovyDevs = developers.stream()
.filter(knowsGroovy)
.map(ageOfDev)
.mapToInt(number -> number)
.average()
.orElse(0)
Streams API compatibility
30
Pure Functions
and
Immutable Data
31
// Instead of
developers.sort()
// Use
sortedData = developers.sort(false)
32
developers.asImmutable()
33
@Immutable
class Point {
int x
int y
}
new Point(x: 10, y: 20)
public final class Point { 

private final int x 

private final int y 

public Point(int x, int y) { // }

public Point(java.util.Map args) { // }

public Point() {

this ([:])

}

public final int getX() {

return x 

}

public final int getY() {

return y 

}

}
34
def numbers = [1, 2, 3, 4, 5]
println numbers.inject(0) { s, item -> s + item }
Iteration/ fold left
35
def numbers = [1, 2, 3, 4, 5]
def sum
sum = { head, tail ->
if (!tail) {
head
} else {
head + sum(tail.head(), tail.tail())
}
}
println(sum(0, numbers))
Recursion
36
import groovy.transform.*
@TailRecursive
def factorial(number, fact = 1) {
number == 0 ? fact : factorial(number - 1, fact * number)
}
println factorial(2500G)
Tail call optimisation
37
import groovy.transform.*
@TailRecursive
def factorial(number, fact = 1) {
number == 0 ? fact : factorial(number - 1, fact * number)
}
println factorial(2500G)
// factorial(3,1)
// factorial(2, 1 * 3)
// factorial(1, 1 * 3 * 2)
// factorial(0, 1 * 3 * 2 * 1)
// 1 * 3 * 2 * 1
// 6
38
import groovy.transform.Memoized
int timeConsumingOp(int number) {
Thread.sleep(5000)
number * number
}
println timeConsumingOp(10)
println timeConsumingOp(10)
println timeConsumingOp(10)
39
import groovy.transform.Memoized
@Memoized
int timeConsumingOp(int number) {
Thread.sleep(5000)
number * number
}
println timeConsumingOp(10)
println timeConsumingOp(10)
println timeConsumingOp(10)
Memoizing
40
https://blog.nareshak.com/whats-in-groovy-for-functional-programming/
41
Effective Java
With Groovy -
How Language
Influences Adoption of
Good Practices
APACHECON @HOME
Spt, 29th – Oct. 1st 2020
42
Thank You
APACHECON @HOME
Spt, 29th – Oct. 1st 2020
43

More Related Content

What's hot

All I know about rsc.io/c2go
All I know about rsc.io/c2goAll I know about rsc.io/c2go
All I know about rsc.io/c2goMoriyoshi Koizumi
 
プログラム実行の話と
OSとメモリの挙動の話
プログラム実行の話と
OSとメモリの挙動の話プログラム実行の話と
OSとメモリの挙動の話
プログラム実行の話と
OSとメモリの挙動の話tatsunori ishikawa
 
OSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP hatersOSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP hatersLin Yo-An
 
Dip Your Toes in the Sea of Security (PHP South Africa 2017)
Dip Your Toes in the Sea of Security (PHP South Africa 2017)Dip Your Toes in the Sea of Security (PHP South Africa 2017)
Dip Your Toes in the Sea of Security (PHP South Africa 2017)James Titcumb
 
Creating own language made easy
Creating own language made easyCreating own language made easy
Creating own language made easyIngvar Stepanyan
 
ClojurianからみたElixir
ClojurianからみたElixirClojurianからみたElixir
ClojurianからみたElixirKent Ohashi
 
Creating a compiler in Perl 6
Creating a compiler in Perl 6Creating a compiler in Perl 6
Creating a compiler in Perl 6Andrew Shitov
 
Melhorando sua API com DSLs
Melhorando sua API com DSLsMelhorando sua API com DSLs
Melhorando sua API com DSLsAugusto Pascutti
 
Climbing the Abstract Syntax Tree (PHP South Africa 2017)
Climbing the Abstract Syntax Tree (PHP South Africa 2017)Climbing the Abstract Syntax Tree (PHP South Africa 2017)
Climbing the Abstract Syntax Tree (PHP South Africa 2017)James Titcumb
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)James Titcumb
 
c++ project on restaurant billing
c++ project on restaurant billing c++ project on restaurant billing
c++ project on restaurant billing Swakriti Rathore
 
How To Think In Go
How To Think In GoHow To Think In Go
How To Think In Golestrrat
 
Hangman Game Programming in C (coding)
Hangman Game Programming in C (coding)Hangman Game Programming in C (coding)
Hangman Game Programming in C (coding)hasan0812
 
PHP in 2018 - Q4 - AFUP Limoges
PHP in 2018 - Q4 - AFUP LimogesPHP in 2018 - Q4 - AFUP Limoges
PHP in 2018 - Q4 - AFUP Limoges✅ William Pinaud
 
The Perl6 Type System
The Perl6 Type SystemThe Perl6 Type System
The Perl6 Type Systemabrummett
 
Learning Perl 6
Learning Perl 6 Learning Perl 6
Learning Perl 6 brian d foy
 

What's hot (20)

All I know about rsc.io/c2go
All I know about rsc.io/c2goAll I know about rsc.io/c2go
All I know about rsc.io/c2go
 
プログラム実行の話と
OSとメモリの挙動の話
プログラム実行の話と
OSとメモリの挙動の話プログラム実行の話と
OSとメモリの挙動の話
プログラム実行の話と
OSとメモリの挙動の話
 
Sbaw091006
Sbaw091006Sbaw091006
Sbaw091006
 
OSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP hatersOSDC.TW - Gutscript for PHP haters
OSDC.TW - Gutscript for PHP haters
 
Dip Your Toes in the Sea of Security (PHP South Africa 2017)
Dip Your Toes in the Sea of Security (PHP South Africa 2017)Dip Your Toes in the Sea of Security (PHP South Africa 2017)
Dip Your Toes in the Sea of Security (PHP South Africa 2017)
 
ES2015 New Features
ES2015 New FeaturesES2015 New Features
ES2015 New Features
 
Creating own language made easy
Creating own language made easyCreating own language made easy
Creating own language made easy
 
ClojurianからみたElixir
ClojurianからみたElixirClojurianからみたElixir
ClojurianからみたElixir
 
Creating a compiler in Perl 6
Creating a compiler in Perl 6Creating a compiler in Perl 6
Creating a compiler in Perl 6
 
Melhorando sua API com DSLs
Melhorando sua API com DSLsMelhorando sua API com DSLs
Melhorando sua API com DSLs
 
Climbing the Abstract Syntax Tree (PHP South Africa 2017)
Climbing the Abstract Syntax Tree (PHP South Africa 2017)Climbing the Abstract Syntax Tree (PHP South Africa 2017)
Climbing the Abstract Syntax Tree (PHP South Africa 2017)
 
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
Mirror, mirror on the wall: Building a new PHP reflection library (DPC 2016)
 
Tgh.pl
Tgh.plTgh.pl
Tgh.pl
 
c++ project on restaurant billing
c++ project on restaurant billing c++ project on restaurant billing
c++ project on restaurant billing
 
How To Think In Go
How To Think In GoHow To Think In Go
How To Think In Go
 
Hangman Game Programming in C (coding)
Hangman Game Programming in C (coding)Hangman Game Programming in C (coding)
Hangman Game Programming in C (coding)
 
PHP in 2018 - Q4 - AFUP Limoges
PHP in 2018 - Q4 - AFUP LimogesPHP in 2018 - Q4 - AFUP Limoges
PHP in 2018 - Q4 - AFUP Limoges
 
Beware sharp tools
Beware sharp toolsBeware sharp tools
Beware sharp tools
 
The Perl6 Type System
The Perl6 Type SystemThe Perl6 Type System
The Perl6 Type System
 
Learning Perl 6
Learning Perl 6 Learning Perl 6
Learning Perl 6
 

Similar to What's in Groovy for Functional Programming

Kotlin, smarter development for the jvm
Kotlin, smarter development for the jvmKotlin, smarter development for the jvm
Kotlin, smarter development for the jvmArnaud Giuliani
 
Lies Told By The Kotlin Compiler
Lies Told By The Kotlin CompilerLies Told By The Kotlin Compiler
Lies Told By The Kotlin CompilerGarth Gilmour
 
Lies Told By The Kotlin Compiler
Lies Told By The Kotlin CompilerLies Told By The Kotlin Compiler
Lies Told By The Kotlin CompilerGarth Gilmour
 
Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Jonathan Felch
 
.gradle 파일 정독해보기
.gradle 파일 정독해보기.gradle 파일 정독해보기
.gradle 파일 정독해보기경주 전
 
2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Ws2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Wsloffenauer
 
Introduction to kotlin + spring boot demo
Introduction to kotlin + spring boot demoIntroduction to kotlin + spring boot demo
Introduction to kotlin + spring boot demoMuhammad Abdullah
 
golang_getting_started.pptx
golang_getting_started.pptxgolang_getting_started.pptx
golang_getting_started.pptxGuy Komari
 
Kotlin / Android Update
Kotlin / Android UpdateKotlin / Android Update
Kotlin / Android UpdateGarth Gilmour
 
Kotlin+MicroProfile: Enseñando trucos de 20 años a un nuevo lenguaje
Kotlin+MicroProfile: Enseñando trucos de 20 años a un nuevo lenguajeKotlin+MicroProfile: Enseñando trucos de 20 años a un nuevo lenguaje
Kotlin+MicroProfile: Enseñando trucos de 20 años a un nuevo lenguajeVíctor Leonel Orozco López
 
Tuga IT 2018 Summer Edition - The Future of C#
Tuga IT 2018 Summer Edition - The Future of C#Tuga IT 2018 Summer Edition - The Future of C#
Tuga IT 2018 Summer Edition - The Future of C#Paulo Morgado
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with ClojureDmitry Buzdin
 
NetPonto - The Future Of C# - NetConf Edition
NetPonto - The Future Of C# - NetConf EditionNetPonto - The Future Of C# - NetConf Edition
NetPonto - The Future Of C# - NetConf EditionPaulo Morgado
 

Similar to What's in Groovy for Functional Programming (20)

Kotlin, smarter development for the jvm
Kotlin, smarter development for the jvmKotlin, smarter development for the jvm
Kotlin, smarter development for the jvm
 
Lies Told By The Kotlin Compiler
Lies Told By The Kotlin CompilerLies Told By The Kotlin Compiler
Lies Told By The Kotlin Compiler
 
Lies Told By The Kotlin Compiler
Lies Told By The Kotlin CompilerLies Told By The Kotlin Compiler
Lies Told By The Kotlin Compiler
 
Introduction to Groovy
Introduction to GroovyIntroduction to Groovy
Introduction to Groovy
 
Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)Groovy On Trading Desk (2010)
Groovy On Trading Desk (2010)
 
.gradle 파일 정독해보기
.gradle 파일 정독해보기.gradle 파일 정독해보기
.gradle 파일 정독해보기
 
Groovy!
Groovy!Groovy!
Groovy!
 
2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Ws2007 09 10 Fzi Training Groovy Grails V Ws
2007 09 10 Fzi Training Groovy Grails V Ws
 
Groovy
GroovyGroovy
Groovy
 
Why Kotlin is your next language?
Why Kotlin is your next language? Why Kotlin is your next language?
Why Kotlin is your next language?
 
Introduction to kotlin + spring boot demo
Introduction to kotlin + spring boot demoIntroduction to kotlin + spring boot demo
Introduction to kotlin + spring boot demo
 
golang_getting_started.pptx
golang_getting_started.pptxgolang_getting_started.pptx
golang_getting_started.pptx
 
Kotlin / Android Update
Kotlin / Android UpdateKotlin / Android Update
Kotlin / Android Update
 
Clojure And Swing
Clojure And SwingClojure And Swing
Clojure And Swing
 
Kotlin+MicroProfile: Enseñando trucos de 20 años a un nuevo lenguaje
Kotlin+MicroProfile: Enseñando trucos de 20 años a un nuevo lenguajeKotlin+MicroProfile: Enseñando trucos de 20 años a un nuevo lenguaje
Kotlin+MicroProfile: Enseñando trucos de 20 años a un nuevo lenguaje
 
Tuga IT 2018 Summer Edition - The Future of C#
Tuga IT 2018 Summer Edition - The Future of C#Tuga IT 2018 Summer Edition - The Future of C#
Tuga IT 2018 Summer Edition - The Future of C#
 
Clojure class
Clojure classClojure class
Clojure class
 
PHP and MySQL
PHP and MySQLPHP and MySQL
PHP and MySQL
 
Refactoring to Macros with Clojure
Refactoring to Macros with ClojureRefactoring to Macros with Clojure
Refactoring to Macros with Clojure
 
NetPonto - The Future Of C# - NetConf Edition
NetPonto - The Future Of C# - NetConf EditionNetPonto - The Future Of C# - NetConf Edition
NetPonto - The Future Of C# - NetConf Edition
 

More from Naresha K

The Groovy Way of Testing with Spock
The Groovy Way of Testing with SpockThe Groovy Way of Testing with Spock
The Groovy Way of Testing with SpockNaresha K
 
Evolving with Java - How to Remain Effective
Evolving with Java - How to Remain EffectiveEvolving with Java - How to Remain Effective
Evolving with Java - How to Remain EffectiveNaresha K
 
Take Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainersTake Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainersNaresha K
 
Implementing Resilience with Micronaut
Implementing Resilience with MicronautImplementing Resilience with Micronaut
Implementing Resilience with MicronautNaresha K
 
Take Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainersTake Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainersNaresha K
 
Favouring Composition - The Groovy Way
Favouring Composition - The Groovy WayFavouring Composition - The Groovy Way
Favouring Composition - The Groovy WayNaresha K
 
Effective Java with Groovy - How Language Influences Adoption of Good Practices
Effective Java with Groovy - How Language Influences Adoption of Good PracticesEffective Java with Groovy - How Language Influences Adoption of Good Practices
Effective Java with Groovy - How Language Influences Adoption of Good PracticesNaresha K
 
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...Naresha K
 
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...Naresha K
 
Eclipse Collections, Java Streams & Vavr - What's in them for Functional Pro...
Eclipse Collections, Java Streams & Vavr - What's in them for  Functional Pro...Eclipse Collections, Java Streams & Vavr - What's in them for  Functional Pro...
Eclipse Collections, Java Streams & Vavr - What's in them for Functional Pro...Naresha K
 
Implementing Cloud-Native Architectural Patterns with Micronaut
Implementing Cloud-Native Architectural Patterns with MicronautImplementing Cloud-Native Architectural Patterns with Micronaut
Implementing Cloud-Native Architectural Patterns with MicronautNaresha K
 
Groovy - Why and Where?
Groovy  - Why and Where?Groovy  - Why and Where?
Groovy - Why and Where?Naresha K
 
Leveraging Micronaut on AWS Lambda
Leveraging Micronaut on AWS LambdaLeveraging Micronaut on AWS Lambda
Leveraging Micronaut on AWS LambdaNaresha K
 
Groovy Refactoring Patterns
Groovy Refactoring PatternsGroovy Refactoring Patterns
Groovy Refactoring PatternsNaresha K
 
Implementing Cloud-native Architectural Patterns with Micronaut
Implementing Cloud-native Architectural Patterns with MicronautImplementing Cloud-native Architectural Patterns with Micronaut
Implementing Cloud-native Architectural Patterns with MicronautNaresha K
 
Effective Java with Groovy
Effective Java with GroovyEffective Java with Groovy
Effective Java with GroovyNaresha K
 
Evolving with Java - How to remain Relevant and Effective
Evolving with Java - How to remain Relevant and EffectiveEvolving with Java - How to remain Relevant and Effective
Evolving with Java - How to remain Relevant and EffectiveNaresha K
 
Effective Java with Groovy - How Language can Influence Good Practices
Effective Java with Groovy - How Language can Influence Good PracticesEffective Java with Groovy - How Language can Influence Good Practices
Effective Java with Groovy - How Language can Influence Good PracticesNaresha K
 
Beyond Lambdas & Streams - Functional Fluency in Java
Beyond Lambdas & Streams - Functional Fluency in JavaBeyond Lambdas & Streams - Functional Fluency in Java
Beyond Lambdas & Streams - Functional Fluency in JavaNaresha K
 
GORM - The polyglot data access toolkit
GORM - The polyglot data access toolkitGORM - The polyglot data access toolkit
GORM - The polyglot data access toolkitNaresha K
 

More from Naresha K (20)

The Groovy Way of Testing with Spock
The Groovy Way of Testing with SpockThe Groovy Way of Testing with Spock
The Groovy Way of Testing with Spock
 
Evolving with Java - How to Remain Effective
Evolving with Java - How to Remain EffectiveEvolving with Java - How to Remain Effective
Evolving with Java - How to Remain Effective
 
Take Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainersTake Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainers
 
Implementing Resilience with Micronaut
Implementing Resilience with MicronautImplementing Resilience with Micronaut
Implementing Resilience with Micronaut
 
Take Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainersTake Control of your Integration Testing with TestContainers
Take Control of your Integration Testing with TestContainers
 
Favouring Composition - The Groovy Way
Favouring Composition - The Groovy WayFavouring Composition - The Groovy Way
Favouring Composition - The Groovy Way
 
Effective Java with Groovy - How Language Influences Adoption of Good Practices
Effective Java with Groovy - How Language Influences Adoption of Good PracticesEffective Java with Groovy - How Language Influences Adoption of Good Practices
Effective Java with Groovy - How Language Influences Adoption of Good Practices
 
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
Effective Java with Groovy & Kotlin - How Languages Influence Adoption of Goo...
 
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...
Effective Java with Groovy & Kotlin How Languages Influence Adoption of Good ...
 
Eclipse Collections, Java Streams & Vavr - What's in them for Functional Pro...
Eclipse Collections, Java Streams & Vavr - What's in them for  Functional Pro...Eclipse Collections, Java Streams & Vavr - What's in them for  Functional Pro...
Eclipse Collections, Java Streams & Vavr - What's in them for Functional Pro...
 
Implementing Cloud-Native Architectural Patterns with Micronaut
Implementing Cloud-Native Architectural Patterns with MicronautImplementing Cloud-Native Architectural Patterns with Micronaut
Implementing Cloud-Native Architectural Patterns with Micronaut
 
Groovy - Why and Where?
Groovy  - Why and Where?Groovy  - Why and Where?
Groovy - Why and Where?
 
Leveraging Micronaut on AWS Lambda
Leveraging Micronaut on AWS LambdaLeveraging Micronaut on AWS Lambda
Leveraging Micronaut on AWS Lambda
 
Groovy Refactoring Patterns
Groovy Refactoring PatternsGroovy Refactoring Patterns
Groovy Refactoring Patterns
 
Implementing Cloud-native Architectural Patterns with Micronaut
Implementing Cloud-native Architectural Patterns with MicronautImplementing Cloud-native Architectural Patterns with Micronaut
Implementing Cloud-native Architectural Patterns with Micronaut
 
Effective Java with Groovy
Effective Java with GroovyEffective Java with Groovy
Effective Java with Groovy
 
Evolving with Java - How to remain Relevant and Effective
Evolving with Java - How to remain Relevant and EffectiveEvolving with Java - How to remain Relevant and Effective
Evolving with Java - How to remain Relevant and Effective
 
Effective Java with Groovy - How Language can Influence Good Practices
Effective Java with Groovy - How Language can Influence Good PracticesEffective Java with Groovy - How Language can Influence Good Practices
Effective Java with Groovy - How Language can Influence Good Practices
 
Beyond Lambdas & Streams - Functional Fluency in Java
Beyond Lambdas & Streams - Functional Fluency in JavaBeyond Lambdas & Streams - Functional Fluency in Java
Beyond Lambdas & Streams - Functional Fluency in Java
 
GORM - The polyglot data access toolkit
GORM - The polyglot data access toolkitGORM - The polyglot data access toolkit
GORM - The polyglot data access toolkit
 

Recently uploaded

W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...panagenda
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software DevelopersVinodh Ram
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsAlberto González Trastoy
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxbodapatigopi8531
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AIABDERRAOUF MEHENNI
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxComplianceQuest1
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...gurkirankumar98700
 
Clustering techniques data mining book ....
Clustering techniques data mining book ....Clustering techniques data mining book ....
Clustering techniques data mining book ....ShaimaaMohamedGalal
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfjoe51371421
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providermohitmore19
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfkalichargn70th171
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdfWave PLM
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️Delhi Call girls
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendArshad QA
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...OnePlan Solutions
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsAndolasoft Inc
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comFatema Valibhai
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...OnePlan Solutions
 

Recently uploaded (20)

Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
W01_panagenda_Navigating-the-Future-with-The-Hitchhikers-Guide-to-Notes-and-D...
 
Professional Resume Template for Software Developers
Professional Resume Template for Software DevelopersProfessional Resume Template for Software Developers
Professional Resume Template for Software Developers
 
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time ApplicationsUnveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
Unveiling the Tech Salsa of LAMs with Janus in Real-Time Applications
 
Hand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptxHand gesture recognition PROJECT PPT.pptx
Hand gesture recognition PROJECT PPT.pptx
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
(Genuine) Escort Service Lucknow | Starting ₹,5K To @25k with A/C 🧑🏽‍❤️‍🧑🏻 89...
 
Clustering techniques data mining book ....
Clustering techniques data mining book ....Clustering techniques data mining book ....
Clustering techniques data mining book ....
 
why an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdfwhy an Opensea Clone Script might be your perfect match.pdf
why an Opensea Clone Script might be your perfect match.pdf
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...Call Girls In Mukherjee Nagar 📱  9999965857  🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
Call Girls In Mukherjee Nagar 📱 9999965857 🤩 Delhi 🫦 HOT AND SEXY VVIP 🍎 SE...
 
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
call girls in Vaishali (Ghaziabad) 🔝 >༒8448380779 🔝 genuine Escort Service 🔝✔️✔️
 
Test Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and BackendTest Automation Strategy for Frontend and Backend
Test Automation Strategy for Frontend and Backend
 
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
How To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.jsHow To Use Server-Side Rendering with Nuxt.js
How To Use Server-Side Rendering with Nuxt.js
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 
Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...Advancing Engineering with AI through the Next Generation of Strategic Projec...
Advancing Engineering with AI through the Next Generation of Strategic Projec...
 

What's in Groovy for Functional Programming

  • 1. What’s in Groovy for Functional Programming Naresha K @naresha_k https://blog.nareshak.com/ APACHECON @HOME Spt, 29th – Oct. 1st 2020
  • 2. About me Developer, Architect & Tech Excellence Coach Founder & Organiser Bangalore Groovy User Group 2
  • 4. 4
  • 5. String greet(String message) { "Hello, ${message}" } String greet() { "Hello" } String greet(String message, String friend) { "Hello $friend, $message" } Regular Functions 5
  • 6. String greet(String message) { "Hello, ${message}" } def greet = { message -> "Hello, ${message}" } // OR def greet = { "Hello, ${it}" } println greet("Good morning") Closures are powerful 6
  • 7. String greet() { "Hello" } def greet = { -> "Hello" } println greet() 7
  • 8. String greet(String message, String friend) { "Hello $friend, $message" } def greet = { message, friend -> "Hello $friend, $message" } println greet() 8
  • 9. def greet = { message -> "Hello, ${message}" } def message = "Hello" Integer age = 30 println greet("Good morning") Closures are first class 9
  • 10. @ToString(includePackage = false) class Developer { String name int age List<String> skills } List<Developer> developers = [ new Developer(name: 'Raj', age: 24, skills: ['Java', 'Groovy']), new Developer(name: 'Sheldon', age: 30, skills: ['Java', 'Scala', 'Clojure']), new Developer(name: 'Penny', age: 28, skills: ['Groovy', 'Scala']), ] Sample data 10
  • 11. List<Developer> findGroovyDevelopers(List<Developer> devs) { List<Developer> groovyDevs = [] for(developer in devs) { if(developer.skills.contains("Groovy")){ groovyDevs << developer } } groovyDevs } println findGroovyDevelopers(developers) Imperative code! 11
  • 12. List<Developer> findGroovyDevelopers(List<Developer> devs) { List<Developer> groovyDevs = [] for(developer in devs) { if(developer.skills.contains("Groovy")){ groovyDevs << developer } } groovyDevs } List<Developer> findGroovyDevelopers(List<Developer> devs) { devs.findAll { dev -> dev.skills.contains('Groovy') } } Refactor to idiomatic Groovy 12
  • 13. List<Developer> findGroovyDevelopers(List<Developer> devs) { List<Developer> groovyDevs = [] for(developer in devs) { if(developer.skills.contains("Groovy")){ groovyDevs << developer } } groovyDevs } List<Developer> findGroovyDevelopers(List<Developer> devs) { devs.findAll { dev -> dev.skills.contains('Groovy') } } Higher Order Function 13
  • 14. List<Developer> findGroovyDevelopers(List<Developer> devs) { devs.findAll { dev -> dev.skills.contains('Groovy') } } List<Developer> findGroovyDevelopers(List<Developer> devs) { def knowsGroovy = { dev -> dev.skills.contains('Groovy') } devs.findAll(knowsGroovy) } List<Developer> findDevelopers(List<Developer> devs, Closure skillFinder) { devs.findAll(skillFinder) } 14
  • 15. List<Developer> findDevelopers(List<Developer> devs, Closure skillFinder) { devs.findAll(skillFinder) } Closure createSkillFinder(String language) { Closure skillFinder = { Developer developer -> developer.skills.contains(language) } skillFinder } Closure knowsGroovy = createSkillFinder('Groovy') println findDevelopers(developers, knowsGroovy) 15
  • 16. Closure knowsGroovy = createSkillFinder('Groovy') Closure knowsJava = createSkillFinder('Java') println findDevelopers(developers, knowsGroovy) println findDevelopers(developers, knowsJava) 16
  • 17. Closure knowsGroovy = createSkillFinder('Groovy') Closure knowsJava = createSkillFinder('Java') println findDevelopers(developers, knowsGroovy) println findDevelopers(developers, knowsJava) Strategy Pattern 17
  • 18. def command1 = { println "Running command-1" } def command2 = { println "Running command-2" } void runCommand(Closure command) { command() } runCommand(command1) runCommand(command2) Command Pattern 18
  • 19. def command1 = { println "Running command-1" } def command2 = { println "Running command-2" } void runCommand(Closure command) { command() } [command1, command2].each { runCommand(it) } Command Pattern 19
  • 20. def command1 = { println "Running command-1" } def command2 = { println "Running command-2" } void runCommand(Closure command) { println "Before command" command() println "After command" } [command1, command2].each { runCommand(it) } Execute-Around Pattern 20
  • 21. def add = { a, b -> a + b } println add(10, 20) 21
  • 22. def add = { a, b -> a + b } println add(10, 20) def increment = add.curry(1) println increment(10) Partial Application/ Currying 22
  • 23. Closure createSkillFinder(String language) { Closure skillFinder = { Developer developer -> developer.skills.contains(language) } skillFinder } Closure knowsGroovy = createSkillFinder('Groovy') Closure knowsJava = createSkillFinder('Java') def findDevelopers = { List<Developer> devs, Closure skillFinder -> devs.findAll(skillFinder) } 23
  • 24. def findDevelopers = { List<Developer> devs, Closure skillFinder -> devs.findAll(skillFinder) } List<String> firstNamesOfDevs(List<Developer> devs, Closure devSelector) { List<Developer> selectedDevs = devSelector(devs) selectedDevs.collect { it.name } } 24
  • 25. def findDevelopers = { List<Developer> devs, Closure skillFinder -> devs.findAll(skillFinder) } List<String> firstNamesOfDevs(List<Developer> devs, Closure devSelector) { List<Developer> selectedDevs = devSelector(devs) selectedDevs.collect { it.name } } def groovyDevSelector = findDevelopers.rcurry(knowsGroovy) println firstNamesOfDevs(developers, groovyDevSelector) 25
  • 27. Closure groovyDevSelector = findDevelopers.rcurry(knowsGroovy) Closure javaDevSelector = findDevelopers.rcurry(knowsJava) println firstNamesOfDevs(developers, javaAndGroovyDevSelector) 27
  • 28. Closure groovyDevSelector = findDevelopers.rcurry(knowsGroovy) Closure javaDevSelector = findDevelopers.rcurry(knowsJava) Closure javaAndGroovyDevSelector = groovyDevSelector << javaDevSelector println firstNamesOfDevs(developers, javaAndGroovyDevSelector) Function Composition 28
  • 29. Closure knowsGroovy = { dev -> dev.skills.contains('Groovy') } Closure ageOfDev = { Developer developer -> developer.age } def averageAgeOfGroovyDevs = developers .findAll(knowsGroovy) .collect(ageOfDev) .with { sum() / size() } Map, filter, reduce 29
  • 30. Closure knowsGroovy = { dev -> dev.skills.contains('Groovy') } Closure ageOfDev = { Developer developer -> developer.age } def averageAgeOfGroovyDevs = developers.stream() .filter(knowsGroovy) .map(ageOfDev) .mapToInt(number -> number) .average() .orElse(0) Streams API compatibility 30
  • 32. // Instead of developers.sort() // Use sortedData = developers.sort(false) 32
  • 34. @Immutable class Point { int x int y } new Point(x: 10, y: 20) public final class Point { private final int x private final int y public Point(int x, int y) { // } public Point(java.util.Map args) { // } public Point() { this ([:]) } public final int getX() { return x } public final int getY() { return y } } 34
  • 35. def numbers = [1, 2, 3, 4, 5] println numbers.inject(0) { s, item -> s + item } Iteration/ fold left 35
  • 36. def numbers = [1, 2, 3, 4, 5] def sum sum = { head, tail -> if (!tail) { head } else { head + sum(tail.head(), tail.tail()) } } println(sum(0, numbers)) Recursion 36
  • 37. import groovy.transform.* @TailRecursive def factorial(number, fact = 1) { number == 0 ? fact : factorial(number - 1, fact * number) } println factorial(2500G) Tail call optimisation 37
  • 38. import groovy.transform.* @TailRecursive def factorial(number, fact = 1) { number == 0 ? fact : factorial(number - 1, fact * number) } println factorial(2500G) // factorial(3,1) // factorial(2, 1 * 3) // factorial(1, 1 * 3 * 2) // factorial(0, 1 * 3 * 2 * 1) // 1 * 3 * 2 * 1 // 6 38
  • 39. import groovy.transform.Memoized int timeConsumingOp(int number) { Thread.sleep(5000) number * number } println timeConsumingOp(10) println timeConsumingOp(10) println timeConsumingOp(10) 39
  • 40. import groovy.transform.Memoized @Memoized int timeConsumingOp(int number) { Thread.sleep(5000) number * number } println timeConsumingOp(10) println timeConsumingOp(10) println timeConsumingOp(10) Memoizing 40
  • 42. Effective Java With Groovy - How Language Influences Adoption of Good Practices APACHECON @HOME Spt, 29th – Oct. 1st 2020 42
  • 43. Thank You APACHECON @HOME Spt, 29th – Oct. 1st 2020 43