b -‐> a + b } ! assert adder(1, 2) == 3 assert adder('a', 'b') == 'ab' Short form of: adder.call(‘a’, ‘b’) Assign a function into a variable Closure parameters
b -‐> a + b } ! assert adder(1, 2) == 3 assert adder('a', 'b') == 'ab' Short form of: adder.call(‘a’, ‘b’) Genericity with duck typing & operator overloading Assign a function into a variable Closure parameters
elements -‐> elements.sum() } ! assert sum(1, 2) == 3 assert sum('a', 'b', 'c') == 'abc' You can specify the type: int... Variable number of arguments
! def r = ints.dropWhile { it < 10 } .take( 3 ) ! assert r == [10, 11, 12] Could use an infinite iterator take(), takeWhile(), drop(), dropWhile() Returns an iterator
! def r = ints.dropWhile { it < 10 } .take( 3 ) ! assert r == [10, 11, 12] Could use an infinite iterator take(), takeWhile(), drop(), dropWhile() Returns an iterator Variants for maps too
new File('out.txt').withWriter { w -‐> r.eachLine { line -‐> if (line.contains('Groovy')) w << line.toUpperCase() } } } Take care of properly opening / closing resources
of closures or methods with the same set of argument values !54 def fib = { n -‐> if (n < 2) 1 else call(n -‐ 1) + call(n -‐ 2) }.memoize() ! assert fib(10) == 89
.asImmutable() ! list << 9 Throws UnsupportedOperationException Easier to reason about Only one state Can be shared in parallel Suitable for caching ....
.asImmutable() ! list << 9 Throws UnsupportedOperationException Easier to reason about Only one state Can be shared in parallel Suitable for caching .... What about immutable POJOs/POGOs?
– an int age !59 public final class Person {! private final String name;! private final int age;! ! public Person(String name, int age) {! this.name = name;! this.age = age;! }! ! public String getName() {! return name;! }! ! public int getAge() {! return age;! }! ! public int hashCode() {! return age + 31 * name.hashCode();! }! ! public boolean equals(Object other) {! if (other == null) {! return false;! }! if (this == other) {! return true;! }! if (Person.class != other.getClass()) {! return false;! }! Person otherPerson = (Person)other;! if (!name.equals(otherPerson.getName()) {! return false;! }! if (age != otherPerson.getAge()) {! return false;! }! return true;! }! ! public String toString() {! return "Person(" + name + ", " + age + ")";! }! }!
– an int age !59 public final class Person {! private final String name;! private final int age;! ! public Person(String name, int age) {! this.name = name;! this.age = age;! }! ! public String getName() {! return name;! }! ! public int getAge() {! return age;! }! ! public int hashCode() {! return age + 31 * name.hashCode();! }! ! public boolean equals(Object other) {! if (other == null) {! return false;! }! if (this == other) {! return true;! }! if (Person.class != other.getClass()) {! return false;! }! Person otherPerson = (Person)other;! if (!name.equals(otherPerson.getName()) {! return false;! }! if (age != otherPerson.getAge()) {! return false;! }! return true;! }! ! public String toString() {! return "Person(" + name + ", " + age + ")";! }! }! Damn verbose Java!
– an int age !59 public final class Person {! private final String name;! private final int age;! ! public Person(String name, int age) {! this.name = name;! this.age = age;! }! ! public String getName() {! return name;! }! ! public int getAge() {! return age;! }! ! public int hashCode() {! return age + 31 * name.hashCode();! }! ! public boolean equals(Object other) {! if (other == null) {! return false;! }! if (this == other) {! return true;! }! if (Person.class != other.getClass()) {! return false;! }! Person otherPerson = (Person)other;! if (!name.equals(otherPerson.getName()) {! return false;! }! if (age != otherPerson.getAge()) {! return false;! }! return true;! }! ! public String toString() {! return "Person(" + name + ", " + age + ")";! }! }! Damn verbose Java! Although it’s also a valid Groovy program!
@Lazy String[] codes = ['FR', 'US', 'GB', /*...*/] } ! class Portfolio { @Lazy List<Position> positions = { // fetch positions lazily from a DB }() } Lazily allocate and create some collection A lazy computation for an expensive structure with closure logic
delegate design pattern ! • @Canonical – like @Immutable but for mutable data – combines the @TupleConstructor, @EqualsAndHashcode, and @ToString transformations ! • @Singleton – to create singleton objects (potentially lazily) !65
monads, option, either, comprehensions, but third-party libraries bring that support ! – Monadologie – Fpiglet – Functional Groovy !69 References available in the «resources» part
Functional Groovy • http://slideshare.net/paulk_asert/functional-groovy • Andres Almiray – Functional Groovy • http://slideshare.net/aalmiray/functional-groovy-confess • Arturo Herrero – Functional programming with Groovy • http://slideshare.net/arturoherrero/functional-programming-with-groovy • Neal Ford – Functional thinking • http://www.youtube.com/watch?v=7aYS9PcAITQ&feature=youtu.be • Mario Fusco – If you think you can stay away from FP, you are wrong • http://slideshare.net/mariofusco/if-you-think-you-can-stay-away-from-functional-programming-you-are-wrong Resources — Presentations !74