SlideShare une entreprise Scribd logo
1  sur  98
© Instil Software 2017
March 2017
eamonn.boyle@instil.coeamonn.boyle@instil.cogarth.gilmour@instil.co | eamonn.boyle@instil.co
Functional Coding in Java
Gateway Drug or End Of Line?
Functional Kats Cork
& Cork Java Users Group
© Instil Software 2017
https://github.com/garthgilmour/
CjugCfpMeetupMarch2017
© Instil Software 2017
Thank You Kats and JUGs For Inviting Me!
© Instil Software 2017
About Me
Experienced trainer
• 15 years in the trenches
• Over 1000 deliveries
The day job
• Head of Learning at Instil
• Coaching, mentoring etc…
The night job(s)
• Husband and father
• Krav Maga Instructor
Big Scala fanboy
• Can we still be friends?
© Instil Software 2017
Arguing About Languages…
© Instil Software 2017
Who Brought A Laptop?
© Instil Software 2017
C
C++
Java
C#
Pascal
Delphi
Basic
Visual Basic
VB .NET
Perl
F#
Java
Script
CoffeeScript
1990
2000
2010
TypeScript
Jython
JRuby
PowerShell
Dart
Scala
Clojure
Kotlin
Groovy
Go
Objective C
Shell
Scripting
Swift
Python
Ruby
© Instil Software 2017
The Great Language Design Debate
© Instil Software 2017
Procedural
Object
Oriented
Generic Functional
Styles of Programming Supported in Java
class Order {
…
}
Order o1 = new Order();
Order o2 = new Order();
orders.filter(o -> o.value > 500)
.map(o -> o.customer)
.each(c -> print(c.name))
while(orders.hasNext()) {
Order o = orders.next();
if(o.priority == URGENT) {
o.ship();
}
}
f1(List<? extends Order> data) {
Optional<Client> opt = f2();
for(Order o : data) {
o.send(opt.getOrElse(me));
}
}
© Instil Software 2017
public class Program {
public static void main(String [] args) {
doThing(new Callable<String>() { //bad
public String call() throws Exception {
return "porthos";
}
},
new Consumer<Exception>(){
public void accept(Exception ex) {
System.err.println(ex);
}
});
doThing(() -> "athos", ex -> System.err.println(ex)); //better
doThing(() -> "aramis", System.err::println); //disco
}
public static void doThing(Callable<String> input, Consumer<Exception> handler) {
try {
System.out.println(input.call());
} catch (Exception e) {
handler.accept(e);
}
}
}
© Instil Software 2017
The Road Not Taken…
The newest version of the Microsoft Visual J++ development environment supports a language construct
called delegates or bound method references…
It is unlikely that the Java programming language will ever include this construct. Sun already carefully
considered adopting it in 1996, to the extent of building and discarding working prototypes. Our
conclusion was that bound method references are unnecessary and detrimental to the language…
We believe bound method references are unnecessary because another design alternative, inner classes,
provides equal or superior functionality. In particular, inner classes fully support the requirements of user-
interface event handling, and have been used to implement a user-interface API at least as
comprehensive as the Windows Foundation Classes.
We believe bound method references are harmful because they detract from the simplicity of the Java
programming language and the pervasively object-oriented character of the APIs….
Extracts From: About Microsoft’s “Delegates"
Whitepaper by the Java language team at JavaSoft
© Instil Software 2017
How Many Of You Are Using Java 8?
© Instil Software 2017
How Many Of You Are Using Scala?
© Instil Software 2017
Some things remain the same…
© Instil Software 2017
Some FP related tips …
Top
Tip!
© Instil Software 2017
… and a funny one 
© Instil Software 2017
The Big Question on the JVM
© Instil Software 2017
What This Talk Is Not About
© Instil Software 2017
• The Functional Toolkit
Level One (a)
© Instil Software 2017
Lets Get Judgemental…
© Instil Software 2017
1. Functional Interfaces
2. Separate Streams
3. Streams For Primitives
4. No Nested Functions
5. Single Use Streams
6. Confusing Reductions
7. Learning About Collect
8. Underpowered Optional
9. Strings Aren't Streams
10. Missing & Misnamed Methods
Top 10 Java 8 Annoyances (My Own Order)
© Instil Software 2017
Annoyance 1: The Functional Interfaces
© Instil Software 2017
Annoyance 2: Separate Streams
© Instil Software 2017
Annoyance 3: Streams For Primitives
© Instil Software 2017
Annoyance 3: Streams For Primitives
© Instil Software 2017
A key FP best practice is:
• Don’t go nuts with lambdas
• In particular avoid multi-line lambdas
• Instead put tasks into helper functions
But this creates an issue:
• Our class namespace becomes polluted with helpers
The problem is we don’t have nested functions
• Unlike JavaScript, where we use them constantly
Annoyance 4: No Nested Functions
© Instil Software 2017
Annoyance 5: Single Use Streams
© Instil Software 2017
Streams and their Descriptions
public class Program {
public static void main(String[] args) {
PrintStream out = System.out;
String msg1 = "t%d survived filtern";
String msg2 = "Processed result %dn";
out.println("Demo begins");
IntStream input = IntStream.of(10,11,12,13,14,15,16,17,18,19,20);
out.println("Input has been built");
IntStream results = input.filter(x -> x % 2 == 0)
.peek(x -> out.printf(msg1,x))
.map(x -> x * 2);
out.println("Results have been built");
results.forEach(item -> out.printf(msg2,item));
}
}
What would you
expect this
program to print?
© Instil Software 2017
Streams and their Descriptions
Demo begins
Input has been built
Results have been built
10 survived filter
Processed result 20
12 survived filter
Processed result 24
14 survived filter
Processed result 28
16 survived filter
Processed result 32
18 survived filter
Processed result 36
20 survived filter
Processed result 40
© Instil Software 2017
Flags Used in Stream Descriptions
© Instil Software 2017
Annoyance 6: Confusing Reductions
© Instil Software 2017
Annoyance 7: Learning To Use Collect
© Instil Software 2017
Annoyance 8: Underpowered Optional
NB: Partially fixed
in Java 9
© Instil Software 2017
Annoyance 9: Strings Aren’t Streams
© Instil Software 2017
© Instil Software 2017
Annoyance 10: Misnamed / Missing Methods
Name What It Should Have Been Comment
allMatch all Growl
anyMatch any Growl
noneMatch none Growl
findFirst first WTF
findAny any WTF
Missing Method Comment
find Have to use ‘filter(foo).findFirst()’ WTF
single WTF
sum Have to use collect instead
groupBy Have to use collect instead
combinations WTF
© Instil Software 2017
• The Case Study
Level One (b)
© Instil Software 2017
The Sample Data to be Queried
© Instil Software 2017
Titles of Courses
© Instil Software 2017
Titles of Courses Without Trainers
© Instil Software 2017
Names and Rates of Trainers
© Instil Software 2017
The Number of Advanced Courses
© Instil Software 2017
Durations of (Non) Beginner Courses
© Instil Software 2017
Durations of (Non) Beginner Courses
© Instil Software 2017
Durations of (Non) Beginner Courses
© Instil Software 2017
Durations of (Non) Beginner Courses
© Instil Software 2017
Pairs of Trainers to Deliver Java Courses
© Instil Software 2017
Pairs of Trainers to Deliver Java Courses
© Instil Software 2017
The Cost of ‘JEE Web Development’
© Instil Software 2017
The Cost of ‘JEE Web Development’
© Instil Software 2017
Grouping ID’s and Titles by Type
© Instil Software 2017
Grouping ID’s and Titles by Type
© Instil Software 2017
• Getting Funky With RESTful
Level Two
© Instil Software 2017
‘Reactive Design’ has been trending for a while now
• After being announced to great fanfare its quietly been
integrated into both client and server side frameworks
• E.g. Angular 2 returns values as RxJS Observables
The goal is to be ‘asynchronous all the way down’
• Removing all blocking operations in order to increase
performance, scalability and utilise many cores
• Were ‘many’ could mean tens of thousands
Spring 5 offers a reactive version of Spring MVC
• Based on the ‘Reactor’ implementation of Reactive Streams
• A ‘Flux<T>’ is a stream of ‘Item’ which may be asynchronous
• A ‘Mono<T>’ is a the same but holding a single item
• Useful in the simpler cases e.g. when retrieving a list
The Reactive Web Framework in Spring 5
© Instil Software 2017
© Instil Software 2017
© Instil Software 2017
An Angular Front End to Spring Reactive MVC
© Instil Software 2017
But We’ve Seen All This Before…
© Instil Software 2017
Akka offers a message-oriented, actor based coding model
• It has been around (in its current form) since 2010
Akka HTTP lets you create and consume REST API’s
• Replacing the earlier Spray framework
Everything you need for Reactive Design is already there
• It is typically combined with the Slick library for DB access
It can be used from both Java and Scala
• But the latter is much more succinct…
Introducing Akka HTTP
© Instil Software 2017
AKKA HTTP Courses Setup
© Instil Software 2017
AKKA HTTP Courses Setup
© Instil Software 2017
AKKA HTTP Utility Methods
© Instil Software 2017
AKKA HTTP Server Loop & Routing DSL
© Instil Software 2017
AKKA HTTP JSON Conversion
© Instil Software 2017
Testing Via Postman (Finding All Courses)
© Instil Software 2017
Testing Via Postman (Finding a Single Course)
© Instil Software 2017
Testing Via Postman (Adding Courses)
© Instil Software 2017
Testing Via Postman (Adding Courses)
© Instil Software 2017
• Tests, tests, tests…
Level Three
© Instil Software 2017
TDD and BDD are brilliant methodologies
• But they leave at least one question unresolved
Explicit tests can’t address the ‘unknown unknowns’
• More correctly called edge or corner cases
The Limits of TDD & BDD
Reports that say that something hasn't
happened are always interesting to me,
because as we know, there are known
knowns; there are things we know we know.
We also know there are known unknowns;
that is to say we know there are some things
we do not know. But there are also unknown
unknowns – the ones we don't know we don't
know.
Donald Rumsfeld
© Instil Software 2017
Introducing Properties
Properties are simply parameterized tests
• Where actual values are replaced with placeholders
A property is the generalization of a test
• We make our tests as close to specifications as possible
• We express logical truths that should apply to all inputs
To take a simple example:
• “If we add ‘ab’, ‘cd’ and ‘ef’ to a collection then its size is 3”
• “If we add n items to a collection then its size is n”
• The former is a test whereas the latter is a property
© Instil Software 2017
Property Based Testing
In property based testing we instantiate many tests by
replacing placeholders with random values
• We are trying to falsify the hypothesis that your property is a
logical truth that applies to all inputs
Property based testing tools allow you to:
• Specify the number of test instances required
• Provide your own generators to create input values
• Combine properties with more conventional kinds of test
The merits of properties may include:
• A smaller and more maintainable test codebase
• A more complete spec with better code coverage
© Instil Software 2017
QuickCheck was the original property based test tool
• However it is written in Haskell and so not widely known
ScalaCheck is the Scala rewrite
• At the moment it is the best known tool of its kind
• It provides a wide range of additional features
Similar tools now exist on other platforms
Examples of Tools
Language Tool
F# FsCheck
Python Hypothesis
Ruby Rantly
JavaScript JSVerify, purescript-quickcheck
© Instil Software 2017
Hello World in ScalaCheck
object HelloScalaCheck {
def main(args: Array[String]) {
val prop = forAll { (no1: Int, no2: Int) =>
printf("Checking with %d and %dn",no1,no2)
(no1 + no2) == (no2 + no1)
}
val params = Parameters.default.withMinSuccessfulTests(10)
prop.check(params)
}
}
Checking with 108643437 and 1550798728
Checking with 1773604856 and 1774391105
Checking with 2147483647 and 1413099849
Checking with -1996116831 and 2147483647
Checking with -1800499841 and 454421160
Checking with -1 and 1605504523
Checking with 172417505 and -279849306
Checking with -2147483648 and 1156729111
Checking with 1577680038 and 2147483647
Checking with -2147483648 and 0
+ OK, passed 10 tests.
© Instil Software 2017
ScalaCheck integrates with other testing tools
• Within which it can use their support for matching
• E.g. the ‘Matchers’ trait and DSL in ScalaTest
To use ScalaCheck as a standalone tool
• Create a class which extends from ‘Properties’
• The name of the spec is passed to the base constructor
• Define your properties via ‘property(foo) = Props.bar’
• ‘foo’ represents the name of the property and ‘bar’ is the
name of one of the factory methods of the ‘Props’ type
• ‘Props.forAll’ is the most commonly used factory method
• The inputs are an optional generator and a code block
• The result of the block determines if the property passes
Basic Testing with ScalaCheck
© Instil Software 2017
object StringBuilderProps extends Properties("StringBuilder") {
property("appending") =
forAll { (s1: String, s2: String) =>
val sb = new StringBuilder()
sb.append(s1).append(s2)
sb.toString == (s1 + s2)
}
property("inserting") =
forAll { (s1: String, s2: String) =>
val sb = new StringBuilder()
sb.insert(0,s1).insert(0,s2)
all(
"content" |: sb.toString =? (s2 + s1),
"length" |: sb.toString.length =? (s2.length + s1.length)
)
}
property("reversal") =
forAll(alphaStr) { s: String =>
(s.length > 1) ==> {
val sb = new StringBuilder()
sb.append(s)
sb.toString != sb.reverse.toString
}
}
}
+ StringBuilder.appending: OK, passed 100 tests.
+ StringBuilder.inserting: OK, passed 100 tests.
! StringBuilder.reversal: Falsified after 3 passed tests.
> ARG_0: "xx"
> ARG_0_ORIGINAL: "xsx"
© Instil Software 2017
Property Declarations in Depth
property("appending") =
forAll { ( s1 : String, s2 : String ) =>
val sb = new StringBuilder()
sb.append(s1).append(s2)
sb.toString == (s1 + s2)
}
‘forAll’ is a helper method of the ‘Prop’ type
‘s1’ and ‘s2’ will be populated with random values
the input to ‘forAll’
is a code block
© Instil Software 2017
Property Declarations in Depth
property("inserting") =
forAll { (s1: String, s2: String) =>
val sb = new StringBuilder()
sb.insert(0,s1).insert(0,s2)
all (
"content" |: sb.toString =? (s2 + s1),
"length" |: sb.toString.length =? (s2.length + s1.length)
)
}
all is a helper method of the ‘Prop’ type
the |: operator allows you to assign labels to
properties, this makes it easier to pinpoint
failures in the output
the =? operator enables ScalaCheck to record
both sides of an expression
© Instil Software 2017
Property Declarations in Depth
property("reversal") =
forAll( alphaStr ) { s: String =>
(s.length > 1) ==> {
val sb = new StringBuilder()
sb.append(s)
sb.toString != sb.reverse.toString
}
}
‘alphaStr’ is a helper method of the ‘Gen’ type that returns a Generator
this is a precondition, which
restricts the range of valid inputs
© Instil Software 2017
ScalaCheck with ScalaTest
class StringBuilderTest extends FunSuite with Checkers {
test("appending is supported") {
check(
forAll { (s1: String, s2: String) =>
val sb = new StringBuilder()
sb.append(s1).append(s2)
sb.toString == (s1 + s2)
})}
test("inserting is supported") {
check(
forAll { (s1: String, s2: String) =>
val sb = new StringBuilder()
sb.insert(0,s1).insert(0,s2)
all( "content" |: sb.toString =? (s2 + s1),
"length" |: sb.toString.length =? (s2.length + s1.length))
})}
}
A standard ScalaTest base class
A trait to support ScalaCheck
© Instil Software 2017
ScalaCheck does not stop when a property fails
• Instead it examines the failing input to see if there is a subset
which will still invalidate the property
• It will reduce the contents of a list, the size of a string, the
variation in a range of numbers etc…
Both the original and simplified inputs are printed
• The original input is labelled ‘ARG_N_ORIGINAL’
• The simplified input is labelled ‘ARG_N’
You can add this feature to your own generators
• By providing an implementation of the ‘Shrink’ type with a
‘shrink’ method that returns a stream of simplified inputs
Simplifying Test Specifications
© Instil Software 2017
Controlling How ScalaCheck Runs
ScalaCheck defaults to 100 runs per property
• In many cases this will not be sufficient
• You can increase it to any number you like
This is one of many settings your can alter
• Other examples are the ratio between discarded and
successful tests, the number of worker threads and which
random number generator to use
These settings can be changed by
• Creating and injecting a custom ‘Parameters’ object
• Specifying options on the applications command line
• Specifying options within an ‘sbt’ or ‘Maven’ build file
© Instil Software 2017
Controlling How ScalaCheck Runs
object StringBuilderPropsRedux {
def main(args:Array[String]) {
val params = new Parameters.Default {
override val minSuccessfulTests = 10000
}
val prop = forAll(alphaStr) { s: String =>
(s.length > 1) ==> {
val sb = new StringBuilder()
sb.append(s)
sb.toString != sb.reverse.toString
}
}
prop.check(params)
}
}
! Falsified after 112 passed tests.
> ARG_0: "pp"
> ARG_0_ORIGINAL: "pxp"
© Instil Software 2017
Properties can be hard to write at first
• Because we are used to thinking in terms of sample inputs
Some possible strategies are
• Express relationships between different outputs
• Timestamps should increase, search results should be
ranked by popularity, a GET should not succeed after a
DELETE etc…
• Perform round trip checking
• E.g. a message which has been encrypted and then
decrypted should have the same hash as the original
• Use a reference implementation
• When a result can be found by brute force or a 3rd party
implementation you can use this to validate your work
Hints for Writing Properties
© Instil Software 2017
Most properties are declared via ‘Prop.forAll’
• But other factory methods are available
There are also constant properties
• Such as ‘proved’, ‘passed’ and ‘falsified’
Methods of the ‘Prop’ Type
Factory Method Description
forAll Acts as the universal qualifier i.e. a condition is true for all inputs within
a set (integers, positive integers, string etc…)
exists Acts as the existential qualifier i.e. a condition is true for at least one
input. ScalaCheck stops at the first successful result
throws Returns true if an expression throws an exception of type ‘T’
all Combines multiple properties such that all must validate
atLeastOne Combines multiple properties such that one or more validates
within Wraps a property to ensure it completes within a time limit
© Instil Software 2017
Normally the set of inputs will need to be restricted
• Allowing any integer, float or string will not be acceptable
You can specify a generator object when creating properties
• The ‘Gen’ class provides a wide range of factory methods
• Generators can be nested, combined and used in sequences
The Standard Generators
Factory Method Description
choose Returns an integer in the specified inclusive range
posNum, negNum Return random positive and negative integers
alphaChar, alphaUpperChar Return random characters
alphaStr, identifier Return different kinds of string
const An implicit method that wraps a value as a generator
listOf, nonEmptyListOf, listOfN Take other generators and use then to produce lists of values
© Instil Software 2017
object UsingGenerators {
def main(args:Array[String]): Unit = {
demoFrequency
demoListOf
demoSequence
demoConst
}
def demoFrequency(): Unit = {
val gen = frequency(
(9,choose(1,99)),
(1,choose(100,500))
)
runDemo("The Frequency Generator",gen,100)
}
def demoListOf(): Unit = {
val gen1 = listOf(choose(1,100))
val gen2 = listOfN(5,choose(10,99))
runDemo("The List Of Generator", gen1,10)
runDemo("The List Of N Generator", gen2,10)
}
© Instil Software 2017
def demoSequence(): Unit = {
val gen = sequence(List(choose(10,99),choose(100,999),const("Fred")))
runDemo("The Sequence Generator", gen,10)
}
def demoConst(): Unit = {
val gen = const(7)
runDemo("The Const Generator", gen,10)
}
def runDemo(title: String, generator: Gen[Any], numTests: Int): Unit = {
println(title)
val prop = forAll(generator) { input: Any =>
printf("t%sn",input)
true
}
Test.check(Parameters.default.withMinSuccessfulTests(numTests),prop)
}
}
© Instil Software 2017
The List Of Generator
List()
List()
List(12, 35, 7, 67, 14, 38, 3, 31, 94, 63, 71, 99, 24, 43, 93, 88, 55, 89, 79)
List(53, 100, 13, 12, 29, 51, 42, 77, 62, 99, 92, 98, 24, 57, 47, 21, 49, 53, 60)
List(87, 72, 28)
List(46)
List(22, 73, 33, 37, 57, 59, 26, 69, 39, 53, 1, 16, 18, 15, 37, 77, 7, 75, 36, 31, 54, 7, 86, 35)
List(10, 65, 29, 14, 75, 93, 58, 48, 43, 18, 55, 54, 1, 50, 75, 5, 44, 99, 35, 79, 25, 25, 82, 14, 16, 15, 82, 84, 84)
List(100, 35, 86, 40)
List(54, 38, 66, 87, 61, 45, 79, 15, 31, 66, 38, 58, 59, 45, 85, 30, 54, 56, 87, 3, 10, 5, 98, 57, 59, 66, 52, 51)
The Frequency Generator
38
52
2
22
24
30
217
43
49
Other values
omitted
The List Of N Generator
List(91, 82, 94, 40, 47)
List(74, 84, 38, 54, 43)
List(63, 86, 22, 23, 96)
List(57, 98, 55, 22, 41)
List(17, 25, 23, 28, 20)
List(29, 40, 86, 10, 56)
List(97, 37, 50, 82, 23)
List(92, 85, 76, 89, 19)
List(22, 23, 39, 41, 94)
List(61, 95, 12, 33, 61)
The Sequence Generator
[31, 671, Fred]
[63, 380, Fred]
[79, 369, Fred]
[61, 312, Fred]
[24, 721, Fred]
[87, 749, Fred]
[68, 799, Fred]
[37, 691, Fred]
[14, 147, Fred]
[22, 230, Fred]
The Const Generator
7
7
7
7
7
7
7
7
7
7
Some lists
truncated
© Instil Software 2017
A More Complex Example
We need a program that recognises poker hands
• So given “3H JH 4D 3S JC” it should output “two pair”
To test this using properties we need to:
• Create a custom generator for poker hands
• Raise the ‘minimum successful test’ parameter
• Write properties to validate the identification of hands
The custom generator can be created by:
• Using ‘Gen.oneOf’ to pick a rank and a suit
• Then using a for comprehension to yield a card
• Then using ‘Gen.listOfN’ to produce a 5 card hand
• ‘suchThat’ or ‘filter’ will prevent hands with duplicate cards
© Instil Software 2017
class PokerHandGenSpec extends FunSuite {
def buildHandGen() = {
val rankGen = Gen.oneOf(List("A", "Q", "K", "J", "10", "9", "8", "7", "6", "5", "4", "3", "2"))
val suitGen = Gen.oneOf(List("C", "H", "S", "D"))
val cardGen = for {
rank <- rankGen
suit <- suitGen
} yield rank + suit
Gen.listOfN(5, cardGen) //create a list of 5 cards
.suchThat(_.distinct.size == 5) //remove hands with duplicated cards
.map(PokerHand.apply) //convert cards to poker hands
}
def assertProp(prop: Prop) {
val params = Parameters.default.withMinSuccessfulTests(50000)
val res = Test.check(params, prop)
assert(res.passed)
}
val handGen = buildHandGen()
© Instil Software 2017
test("Every poker hand is present") {
val props = List(
exists(handGen)(_.isPair),
exists(handGen)(_.isTwoPair),
exists(handGen)(_.isThreeOfAKind),
exists(handGen)(_.isStraight),
exists(handGen)(_.isFlush),
exists(handGen)(_.isFullHouse),
exists(handGen)(_.isRoyalFlush), //may require more hands
exists(handGen)(_.isFourOfAKind))
props.foreach(assertProp(_))
}
test("All 2 Pairs are Pairs") {
val prop = forAll(handGen)(h => if (h.isTwoPair) h.isPair else true)
assertProp(prop)
}
test("All Full Houses are Pairs and Three Of A Kind") {
val check = (h: PokerHand) => if (h.isFullHouse) (h.isPair && h.isThreeOfAKind) else true
val prop = forAll(handGen)(check)
assertProp(prop)
}
© Instil Software 2017
test("All Three Of A Kind are Pairs") {
val prop = forAll(handGen)(h => if (h.isThreeOfAKind) h.isPair else true)
assertProp(prop)
}
test("All Four Of A Kind are Pairs and Three Of A KInd") {
val check = (h: PokerHand) => if (h.isFourOfAKind) {
h.isPair && h.isThreeOfAKind
} else { true }
val prop = forAll(handGen)(check)
assertProp(prop)
}
test("All Royal Flushes are Flushes") {
val prop = forAll(handGen)(h => if (h.isRoyalFlush) h.isFlush else true)
assertProp(prop)
}
}
© Instil Software 2017
Resources
© Instil Software 2017
• What Floats Your Boat?
Summing Up
© Instil Software 2017
Where Do We All Stand?
© Instil Software 2017
Where Do We All Stand?
© Instil Software 2017
Thank You - And Do Enjoy Your Party…

Contenu connexe

Tendances

apidays LIVE Paris 2021 - Automating API Documentation by Ajinkya Marudwar, G...
apidays LIVE Paris 2021 - Automating API Documentation by Ajinkya Marudwar, G...apidays LIVE Paris 2021 - Automating API Documentation by Ajinkya Marudwar, G...
apidays LIVE Paris 2021 - Automating API Documentation by Ajinkya Marudwar, G...apidays
 
Cloud-native Patterns (July 4th, 2019)
Cloud-native Patterns (July 4th, 2019)Cloud-native Patterns (July 4th, 2019)
Cloud-native Patterns (July 4th, 2019)Alexandre Roman
 
I Love APIs 2015: End to End Testing: Bug Squashing for Developers
I Love APIs 2015: End to End Testing: Bug Squashing for DevelopersI Love APIs 2015: End to End Testing: Bug Squashing for Developers
I Love APIs 2015: End to End Testing: Bug Squashing for DevelopersApigee | Google Cloud
 
Api clarity webinar
Api clarity webinarApi clarity webinar
Api clarity webinarLibbySchulze
 
Life After Microservices – Shifting the Boundaries
Life After Microservices – Shifting the BoundariesLife After Microservices – Shifting the Boundaries
Life After Microservices – Shifting the BoundariesNordic APIs
 
Oscon2014 Netflix API - Top 10 Lessons Learned
Oscon2014 Netflix API - Top 10 Lessons LearnedOscon2014 Netflix API - Top 10 Lessons Learned
Oscon2014 Netflix API - Top 10 Lessons LearnedSangeeta Narayanan
 
Continuous Testing- A Key Ingredient for Success in Agile & DevOps
Continuous Testing- A Key Ingredient for Success in Agile & DevOpsContinuous Testing- A Key Ingredient for Success in Agile & DevOps
Continuous Testing- A Key Ingredient for Success in Agile & DevOpsSmartBear
 
apidays LIVE New York 2021 - Supercharge microservices with Service Mesh by S...
apidays LIVE New York 2021 - Supercharge microservices with Service Mesh by S...apidays LIVE New York 2021 - Supercharge microservices with Service Mesh by S...
apidays LIVE New York 2021 - Supercharge microservices with Service Mesh by S...apidays
 
I Love APIs 2015: Crash Course Foundational Topics in Apigee Edge Workshop
I Love APIs 2015: Crash Course Foundational Topics in Apigee Edge WorkshopI Love APIs 2015: Crash Course Foundational Topics in Apigee Edge Workshop
I Love APIs 2015: Crash Course Foundational Topics in Apigee Edge WorkshopApigee | Google Cloud
 
Lessons Learned from Revamping Our Doc Site
Lessons Learned from Revamping Our Doc SiteLessons Learned from Revamping Our Doc Site
Lessons Learned from Revamping Our Doc SitePronovix
 
Containers at Netflx - An Evolving Story QConSF2015
Containers at Netflx - An Evolving Story QConSF2015Containers at Netflx - An Evolving Story QConSF2015
Containers at Netflx - An Evolving Story QConSF2015Sangeeta Narayanan
 
GITPro World Apr 2015 - Continuous Innovation with Rapid Software Delivery
 GITPro World Apr 2015 - Continuous Innovation with Rapid Software Delivery GITPro World Apr 2015 - Continuous Innovation with Rapid Software Delivery
GITPro World Apr 2015 - Continuous Innovation with Rapid Software DeliverySangeeta Narayanan
 
apidays LIVE Paris 2021 - Taming the beast by Markus Mueller, Apiida
apidays LIVE Paris 2021 - Taming the beast by Markus Mueller, Apiidaapidays LIVE Paris 2021 - Taming the beast by Markus Mueller, Apiida
apidays LIVE Paris 2021 - Taming the beast by Markus Mueller, Apiidaapidays
 
The State of Testing 2017
The State of Testing 2017The State of Testing 2017
The State of Testing 2017SmartBear
 
Design-first API Development using Swagger and Node
Design-first API Development using Swagger and NodeDesign-first API Development using Swagger and Node
Design-first API Development using Swagger and NodeApigee | Google Cloud
 
Best Practices for API Design to Keep Your App Secure, Scalable & Efficient
Best Practices for API Design to Keep Your App Secure, Scalable & EfficientBest Practices for API Design to Keep Your App Secure, Scalable & Efficient
Best Practices for API Design to Keep Your App Secure, Scalable & EfficientNordic APIs
 
apidays Paris 2019 - How Do Async APIs Survive in a Rest World? by Luca Ferra...
apidays Paris 2019 - How Do Async APIs Survive in a Rest World? by Luca Ferra...apidays Paris 2019 - How Do Async APIs Survive in a Rest World? by Luca Ferra...
apidays Paris 2019 - How Do Async APIs Survive in a Rest World? by Luca Ferra...apidays
 
Developing and deploying the Netflix API service
Developing and deploying the Netflix API serviceDeveloping and deploying the Netflix API service
Developing and deploying the Netflix API serviceSangeeta Narayanan
 
apidays LIVE Paris 2021 - Low-Code API DevOps approach to API Lifecycle Manag...
apidays LIVE Paris 2021 - Low-Code API DevOps approach to API Lifecycle Manag...apidays LIVE Paris 2021 - Low-Code API DevOps approach to API Lifecycle Manag...
apidays LIVE Paris 2021 - Low-Code API DevOps approach to API Lifecycle Manag...apidays
 
Api gateway
Api gatewayApi gateway
Api gatewayenyert
 

Tendances (20)

apidays LIVE Paris 2021 - Automating API Documentation by Ajinkya Marudwar, G...
apidays LIVE Paris 2021 - Automating API Documentation by Ajinkya Marudwar, G...apidays LIVE Paris 2021 - Automating API Documentation by Ajinkya Marudwar, G...
apidays LIVE Paris 2021 - Automating API Documentation by Ajinkya Marudwar, G...
 
Cloud-native Patterns (July 4th, 2019)
Cloud-native Patterns (July 4th, 2019)Cloud-native Patterns (July 4th, 2019)
Cloud-native Patterns (July 4th, 2019)
 
I Love APIs 2015: End to End Testing: Bug Squashing for Developers
I Love APIs 2015: End to End Testing: Bug Squashing for DevelopersI Love APIs 2015: End to End Testing: Bug Squashing for Developers
I Love APIs 2015: End to End Testing: Bug Squashing for Developers
 
Api clarity webinar
Api clarity webinarApi clarity webinar
Api clarity webinar
 
Life After Microservices – Shifting the Boundaries
Life After Microservices – Shifting the BoundariesLife After Microservices – Shifting the Boundaries
Life After Microservices – Shifting the Boundaries
 
Oscon2014 Netflix API - Top 10 Lessons Learned
Oscon2014 Netflix API - Top 10 Lessons LearnedOscon2014 Netflix API - Top 10 Lessons Learned
Oscon2014 Netflix API - Top 10 Lessons Learned
 
Continuous Testing- A Key Ingredient for Success in Agile & DevOps
Continuous Testing- A Key Ingredient for Success in Agile & DevOpsContinuous Testing- A Key Ingredient for Success in Agile & DevOps
Continuous Testing- A Key Ingredient for Success in Agile & DevOps
 
apidays LIVE New York 2021 - Supercharge microservices with Service Mesh by S...
apidays LIVE New York 2021 - Supercharge microservices with Service Mesh by S...apidays LIVE New York 2021 - Supercharge microservices with Service Mesh by S...
apidays LIVE New York 2021 - Supercharge microservices with Service Mesh by S...
 
I Love APIs 2015: Crash Course Foundational Topics in Apigee Edge Workshop
I Love APIs 2015: Crash Course Foundational Topics in Apigee Edge WorkshopI Love APIs 2015: Crash Course Foundational Topics in Apigee Edge Workshop
I Love APIs 2015: Crash Course Foundational Topics in Apigee Edge Workshop
 
Lessons Learned from Revamping Our Doc Site
Lessons Learned from Revamping Our Doc SiteLessons Learned from Revamping Our Doc Site
Lessons Learned from Revamping Our Doc Site
 
Containers at Netflx - An Evolving Story QConSF2015
Containers at Netflx - An Evolving Story QConSF2015Containers at Netflx - An Evolving Story QConSF2015
Containers at Netflx - An Evolving Story QConSF2015
 
GITPro World Apr 2015 - Continuous Innovation with Rapid Software Delivery
 GITPro World Apr 2015 - Continuous Innovation with Rapid Software Delivery GITPro World Apr 2015 - Continuous Innovation with Rapid Software Delivery
GITPro World Apr 2015 - Continuous Innovation with Rapid Software Delivery
 
apidays LIVE Paris 2021 - Taming the beast by Markus Mueller, Apiida
apidays LIVE Paris 2021 - Taming the beast by Markus Mueller, Apiidaapidays LIVE Paris 2021 - Taming the beast by Markus Mueller, Apiida
apidays LIVE Paris 2021 - Taming the beast by Markus Mueller, Apiida
 
The State of Testing 2017
The State of Testing 2017The State of Testing 2017
The State of Testing 2017
 
Design-first API Development using Swagger and Node
Design-first API Development using Swagger and NodeDesign-first API Development using Swagger and Node
Design-first API Development using Swagger and Node
 
Best Practices for API Design to Keep Your App Secure, Scalable & Efficient
Best Practices for API Design to Keep Your App Secure, Scalable & EfficientBest Practices for API Design to Keep Your App Secure, Scalable & Efficient
Best Practices for API Design to Keep Your App Secure, Scalable & Efficient
 
apidays Paris 2019 - How Do Async APIs Survive in a Rest World? by Luca Ferra...
apidays Paris 2019 - How Do Async APIs Survive in a Rest World? by Luca Ferra...apidays Paris 2019 - How Do Async APIs Survive in a Rest World? by Luca Ferra...
apidays Paris 2019 - How Do Async APIs Survive in a Rest World? by Luca Ferra...
 
Developing and deploying the Netflix API service
Developing and deploying the Netflix API serviceDeveloping and deploying the Netflix API service
Developing and deploying the Netflix API service
 
apidays LIVE Paris 2021 - Low-Code API DevOps approach to API Lifecycle Manag...
apidays LIVE Paris 2021 - Low-Code API DevOps approach to API Lifecycle Manag...apidays LIVE Paris 2021 - Low-Code API DevOps approach to API Lifecycle Manag...
apidays LIVE Paris 2021 - Low-Code API DevOps approach to API Lifecycle Manag...
 
Api gateway
Api gatewayApi gateway
Api gateway
 

Similaire à Java 8 - Gateway Drug or End of Line?

BelTech 2017 - Building Quality in the Browser
BelTech 2017 - Building Quality in the BrowserBelTech 2017 - Building Quality in the Browser
BelTech 2017 - Building Quality in the BrowserEamonn Boyle
 
To be or not to be serverless
To be or not to be serverlessTo be or not to be serverless
To be or not to be serverlessSteve Houël
 
ASP .Net Core SPA Templates
ASP .Net Core SPA TemplatesASP .Net Core SPA Templates
ASP .Net Core SPA TemplatesEamonn Boyle
 
VidyaBhooshanMishra_CV
VidyaBhooshanMishra_CVVidyaBhooshanMishra_CV
VidyaBhooshanMishra_CVLandis+Gyr
 
Angular 2 overview
Angular 2 overviewAngular 2 overview
Angular 2 overviewJesse Warden
 
Opticon 2017 How Developers Can Take Experimentation
Opticon 2017 How Developers Can Take ExperimentationOpticon 2017 How Developers Can Take Experimentation
Opticon 2017 How Developers Can Take ExperimentationOptimizely
 
Product Camp Silicon Valley 2018 - PM Technical Skills
Product Camp Silicon Valley 2018 - PM Technical SkillsProduct Camp Silicon Valley 2018 - PM Technical Skills
Product Camp Silicon Valley 2018 - PM Technical SkillsSandeep Adwankar
 
ATAGTR2017 Protractor Cucumber BDD Approach
ATAGTR2017 Protractor Cucumber BDD ApproachATAGTR2017 Protractor Cucumber BDD Approach
ATAGTR2017 Protractor Cucumber BDD ApproachAgile Testing Alliance
 
Stream SQL eventflow visual programming for real programmers presentation
Stream SQL eventflow visual programming for real programmers presentationStream SQL eventflow visual programming for real programmers presentation
Stream SQL eventflow visual programming for real programmers presentationstreambase
 
5 hs mpostcustomizationrenefonseca
5 hs mpostcustomizationrenefonseca5 hs mpostcustomizationrenefonseca
5 hs mpostcustomizationrenefonsecassuserfadb24
 
Introducing wsgi_lineprof / PyCon JP 2017 LT
Introducing wsgi_lineprof / PyCon JP 2017 LTIntroducing wsgi_lineprof / PyCon JP 2017 LT
Introducing wsgi_lineprof / PyCon JP 2017 LTYusuke Miyazaki
 
Asp .Net Website on E Learning
Asp .Net Website on E LearningAsp .Net Website on E Learning
Asp .Net Website on E LearningMujeeb Rehman
 
iOS Development at Scale @Chegg
iOS Development at Scale @CheggiOS Development at Scale @Chegg
iOS Development at Scale @CheggGalOrlanczyk
 
Aspect Based Sentiment Analysis
Aspect Based Sentiment AnalysisAspect Based Sentiment Analysis
Aspect Based Sentiment AnalysisGaurav kumar
 
How to Architect and Develop Cloud Native Applications
How to Architect and Develop Cloud Native ApplicationsHow to Architect and Develop Cloud Native Applications
How to Architect and Develop Cloud Native ApplicationsSufyaan Kazi
 

Similaire à Java 8 - Gateway Drug or End of Line? (20)

BelTech 2017 - Building Quality in the Browser
BelTech 2017 - Building Quality in the BrowserBelTech 2017 - Building Quality in the Browser
BelTech 2017 - Building Quality in the Browser
 
Dust.js
Dust.jsDust.js
Dust.js
 
To be or not to be serverless
To be or not to be serverlessTo be or not to be serverless
To be or not to be serverless
 
DineshCV (1)
DineshCV (1)DineshCV (1)
DineshCV (1)
 
RishabhAgarwal
RishabhAgarwalRishabhAgarwal
RishabhAgarwal
 
ASP .Net Core SPA Templates
ASP .Net Core SPA TemplatesASP .Net Core SPA Templates
ASP .Net Core SPA Templates
 
VidyaBhooshanMishra_CV
VidyaBhooshanMishra_CVVidyaBhooshanMishra_CV
VidyaBhooshanMishra_CV
 
Angular 2 overview
Angular 2 overviewAngular 2 overview
Angular 2 overview
 
Opticon 2017 How Developers Can Take Experimentation
Opticon 2017 How Developers Can Take ExperimentationOpticon 2017 How Developers Can Take Experimentation
Opticon 2017 How Developers Can Take Experimentation
 
Visual studio 2019 launch
Visual studio 2019 launch Visual studio 2019 launch
Visual studio 2019 launch
 
Ravindra Prasad
Ravindra PrasadRavindra Prasad
Ravindra Prasad
 
Product Camp Silicon Valley 2018 - PM Technical Skills
Product Camp Silicon Valley 2018 - PM Technical SkillsProduct Camp Silicon Valley 2018 - PM Technical Skills
Product Camp Silicon Valley 2018 - PM Technical Skills
 
ATAGTR2017 Protractor Cucumber BDD Approach
ATAGTR2017 Protractor Cucumber BDD ApproachATAGTR2017 Protractor Cucumber BDD Approach
ATAGTR2017 Protractor Cucumber BDD Approach
 
Stream SQL eventflow visual programming for real programmers presentation
Stream SQL eventflow visual programming for real programmers presentationStream SQL eventflow visual programming for real programmers presentation
Stream SQL eventflow visual programming for real programmers presentation
 
5 hs mpostcustomizationrenefonseca
5 hs mpostcustomizationrenefonseca5 hs mpostcustomizationrenefonseca
5 hs mpostcustomizationrenefonseca
 
Introducing wsgi_lineprof / PyCon JP 2017 LT
Introducing wsgi_lineprof / PyCon JP 2017 LTIntroducing wsgi_lineprof / PyCon JP 2017 LT
Introducing wsgi_lineprof / PyCon JP 2017 LT
 
Asp .Net Website on E Learning
Asp .Net Website on E LearningAsp .Net Website on E Learning
Asp .Net Website on E Learning
 
iOS Development at Scale @Chegg
iOS Development at Scale @CheggiOS Development at Scale @Chegg
iOS Development at Scale @Chegg
 
Aspect Based Sentiment Analysis
Aspect Based Sentiment AnalysisAspect Based Sentiment Analysis
Aspect Based Sentiment Analysis
 
How to Architect and Develop Cloud Native Applications
How to Architect and Develop Cloud Native ApplicationsHow to Architect and Develop Cloud Native Applications
How to Architect and Develop Cloud Native Applications
 

Plus de Garth Gilmour

Kotlin / Android Update
Kotlin / Android UpdateKotlin / Android Update
Kotlin / Android UpdateGarth Gilmour
 
TypeScript Vs. KotlinJS
TypeScript Vs. KotlinJSTypeScript Vs. KotlinJS
TypeScript Vs. KotlinJSGarth Gilmour
 
Shut Up And Eat Your Veg
Shut Up And Eat Your VegShut Up And Eat Your Veg
Shut Up And Eat Your VegGarth 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
 
A TypeScript Fans KotlinJS Adventures
A TypeScript Fans KotlinJS AdventuresA TypeScript Fans KotlinJS Adventures
A TypeScript Fans KotlinJS AdventuresGarth Gilmour
 
The Heat Death Of Enterprise IT
The Heat Death Of Enterprise ITThe Heat Death Of Enterprise IT
The Heat Death Of Enterprise ITGarth 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
 
Type Driven Development with TypeScript
Type Driven Development with TypeScriptType Driven Development with TypeScript
Type Driven Development with TypeScriptGarth Gilmour
 
Generics On The JVM (What you don't know will hurt you)
Generics On The JVM (What you don't know will hurt you)Generics On The JVM (What you don't know will hurt you)
Generics On The JVM (What you don't know will hurt you)Garth Gilmour
 
Using Kotlin, to Create Kotlin, to Teach Kotlin, in Space
Using Kotlin, to Create Kotlin,to Teach Kotlin,in SpaceUsing Kotlin, to Create Kotlin,to Teach Kotlin,in Space
Using Kotlin, to Create Kotlin, to Teach Kotlin, in SpaceGarth Gilmour
 
Is Software Engineering A Profession?
Is Software Engineering A Profession?Is Software Engineering A Profession?
Is Software Engineering A Profession?Garth Gilmour
 
Social Distancing is not Behaving Distantly
Social Distancing is not Behaving DistantlySocial Distancing is not Behaving Distantly
Social Distancing is not Behaving DistantlyGarth Gilmour
 
The Great Scala Makeover
The Great Scala MakeoverThe Great Scala Makeover
The Great Scala MakeoverGarth Gilmour
 
Transitioning Android Teams Into Kotlin
Transitioning Android Teams Into KotlinTransitioning Android Teams Into Kotlin
Transitioning Android Teams Into KotlinGarth Gilmour
 
Simpler and Safer Java Types (via the Vavr and Lambda Libraries)
Simpler and Safer Java Types (via the Vavr and Lambda Libraries)Simpler and Safer Java Types (via the Vavr and Lambda Libraries)
Simpler and Safer Java Types (via the Vavr and Lambda Libraries)Garth Gilmour
 
The Three Horse Race
The Three Horse RaceThe Three Horse Race
The Three Horse RaceGarth Gilmour
 
The Bestiary of Pure Functional Programming
The Bestiary of Pure Functional Programming The Bestiary of Pure Functional Programming
The Bestiary of Pure Functional Programming Garth Gilmour
 
BelTech 2019 Presenters Workshop
BelTech 2019 Presenters WorkshopBelTech 2019 Presenters Workshop
BelTech 2019 Presenters WorkshopGarth Gilmour
 
Kotlin The Whole Damn Family
Kotlin The Whole Damn FamilyKotlin The Whole Damn Family
Kotlin The Whole Damn FamilyGarth Gilmour
 

Plus de Garth Gilmour (20)

Compose in Theory
Compose in TheoryCompose in Theory
Compose in Theory
 
Kotlin / Android Update
Kotlin / Android UpdateKotlin / Android Update
Kotlin / Android Update
 
TypeScript Vs. KotlinJS
TypeScript Vs. KotlinJSTypeScript Vs. KotlinJS
TypeScript Vs. KotlinJS
 
Shut Up And Eat Your Veg
Shut Up And Eat Your VegShut Up And Eat Your Veg
Shut Up And Eat Your Veg
 
Lies Told By The Kotlin Compiler
Lies Told By The Kotlin CompilerLies Told By The Kotlin Compiler
Lies Told By The Kotlin Compiler
 
A TypeScript Fans KotlinJS Adventures
A TypeScript Fans KotlinJS AdventuresA TypeScript Fans KotlinJS Adventures
A TypeScript Fans KotlinJS Adventures
 
The Heat Death Of Enterprise IT
The Heat Death Of Enterprise ITThe Heat Death Of Enterprise IT
The Heat Death Of Enterprise IT
 
Lies Told By The Kotlin Compiler
Lies Told By The Kotlin CompilerLies Told By The Kotlin Compiler
Lies Told By The Kotlin Compiler
 
Type Driven Development with TypeScript
Type Driven Development with TypeScriptType Driven Development with TypeScript
Type Driven Development with TypeScript
 
Generics On The JVM (What you don't know will hurt you)
Generics On The JVM (What you don't know will hurt you)Generics On The JVM (What you don't know will hurt you)
Generics On The JVM (What you don't know will hurt you)
 
Using Kotlin, to Create Kotlin, to Teach Kotlin, in Space
Using Kotlin, to Create Kotlin,to Teach Kotlin,in SpaceUsing Kotlin, to Create Kotlin,to Teach Kotlin,in Space
Using Kotlin, to Create Kotlin, to Teach Kotlin, in Space
 
Is Software Engineering A Profession?
Is Software Engineering A Profession?Is Software Engineering A Profession?
Is Software Engineering A Profession?
 
Social Distancing is not Behaving Distantly
Social Distancing is not Behaving DistantlySocial Distancing is not Behaving Distantly
Social Distancing is not Behaving Distantly
 
The Great Scala Makeover
The Great Scala MakeoverThe Great Scala Makeover
The Great Scala Makeover
 
Transitioning Android Teams Into Kotlin
Transitioning Android Teams Into KotlinTransitioning Android Teams Into Kotlin
Transitioning Android Teams Into Kotlin
 
Simpler and Safer Java Types (via the Vavr and Lambda Libraries)
Simpler and Safer Java Types (via the Vavr and Lambda Libraries)Simpler and Safer Java Types (via the Vavr and Lambda Libraries)
Simpler and Safer Java Types (via the Vavr and Lambda Libraries)
 
The Three Horse Race
The Three Horse RaceThe Three Horse Race
The Three Horse Race
 
The Bestiary of Pure Functional Programming
The Bestiary of Pure Functional Programming The Bestiary of Pure Functional Programming
The Bestiary of Pure Functional Programming
 
BelTech 2019 Presenters Workshop
BelTech 2019 Presenters WorkshopBelTech 2019 Presenters Workshop
BelTech 2019 Presenters Workshop
 
Kotlin The Whole Damn Family
Kotlin The Whole Damn FamilyKotlin The Whole Damn Family
Kotlin The Whole Damn Family
 

Dernier

How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationBradBedford3
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxRTS corp
 
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdfEnhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdfRTS corp
 
SoftTeco - Software Development Company Profile
SoftTeco - Software Development Company ProfileSoftTeco - Software Development Company Profile
SoftTeco - Software Development Company Profileakrivarotava
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?Alexandre Beguel
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsSafe Software
 
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics
 
Osi security architecture in network.pptx
Osi security architecture in network.pptxOsi security architecture in network.pptx
Osi security architecture in network.pptxVinzoCenzo
 
eSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolseSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolsosttopstonverter
 
What’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesWhat’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesVictoriaMetrics
 
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...OnePlan Solutions
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Rob Geurden
 
Not a Kubernetes fan? The state of PaaS in 2024
Not a Kubernetes fan? The state of PaaS in 2024Not a Kubernetes fan? The state of PaaS in 2024
Not a Kubernetes fan? The state of PaaS in 2024Anthony Dahanne
 
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...Bert Jan Schrijver
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identityteam-WIBU
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Developmentvyaparkranti
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringHironori Washizaki
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfMarharyta Nedzelska
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...confluent
 
Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldRoberto Pérez Alcolea
 

Dernier (20)

How to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion ApplicationHow to submit a standout Adobe Champion Application
How to submit a standout Adobe Champion Application
 
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptxReal-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
Real-time Tracking and Monitoring with Cargo Cloud Solutions.pptx
 
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdfEnhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
Enhancing Supply Chain Visibility with Cargo Cloud Solutions.pdf
 
SoftTeco - Software Development Company Profile
SoftTeco - Software Development Company ProfileSoftTeco - Software Development Company Profile
SoftTeco - Software Development Company Profile
 
SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?SAM Training Session - How to use EXCEL ?
SAM Training Session - How to use EXCEL ?
 
Powering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data StreamsPowering Real-Time Decisions with Continuous Data Streams
Powering Real-Time Decisions with Continuous Data Streams
 
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News UpdateVictoriaMetrics Q1 Meet Up '24 - Community & News Update
VictoriaMetrics Q1 Meet Up '24 - Community & News Update
 
Osi security architecture in network.pptx
Osi security architecture in network.pptxOsi security architecture in network.pptx
Osi security architecture in network.pptx
 
eSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration toolseSoftTools IMAP Backup Software and migration tools
eSoftTools IMAP Backup Software and migration tools
 
What’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 UpdatesWhat’s New in VictoriaMetrics: Q1 2024 Updates
What’s New in VictoriaMetrics: Q1 2024 Updates
 
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
Tech Tuesday Slides - Introduction to Project Management with OnePlan's Work ...
 
Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...Simplifying Microservices & Apps - The art of effortless development - Meetup...
Simplifying Microservices & Apps - The art of effortless development - Meetup...
 
Not a Kubernetes fan? The state of PaaS in 2024
Not a Kubernetes fan? The state of PaaS in 2024Not a Kubernetes fan? The state of PaaS in 2024
Not a Kubernetes fan? The state of PaaS in 2024
 
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
JavaLand 2024 - Going serverless with Quarkus GraalVM native images and AWS L...
 
Post Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on IdentityPost Quantum Cryptography – The Impact on Identity
Post Quantum Cryptography – The Impact on Identity
 
VK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web DevelopmentVK Business Profile - provides IT solutions and Web Development
VK Business Profile - provides IT solutions and Web Development
 
Machine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their EngineeringMachine Learning Software Engineering Patterns and Their Engineering
Machine Learning Software Engineering Patterns and Their Engineering
 
A healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdfA healthy diet for your Java application Devoxx France.pdf
A healthy diet for your Java application Devoxx France.pdf
 
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
Catch the Wave: SAP Event-Driven and Data Streaming for the Intelligence Ente...
 
Keeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository worldKeeping your build tool updated in a multi repository world
Keeping your build tool updated in a multi repository world
 

Java 8 - Gateway Drug or End of Line?

  • 1. © Instil Software 2017 March 2017 eamonn.boyle@instil.coeamonn.boyle@instil.cogarth.gilmour@instil.co | eamonn.boyle@instil.co Functional Coding in Java Gateway Drug or End Of Line? Functional Kats Cork & Cork Java Users Group
  • 2. © Instil Software 2017 https://github.com/garthgilmour/ CjugCfpMeetupMarch2017
  • 3. © Instil Software 2017 Thank You Kats and JUGs For Inviting Me!
  • 4. © Instil Software 2017 About Me Experienced trainer • 15 years in the trenches • Over 1000 deliveries The day job • Head of Learning at Instil • Coaching, mentoring etc… The night job(s) • Husband and father • Krav Maga Instructor Big Scala fanboy • Can we still be friends?
  • 5. © Instil Software 2017 Arguing About Languages…
  • 6. © Instil Software 2017 Who Brought A Laptop?
  • 7. © Instil Software 2017 C C++ Java C# Pascal Delphi Basic Visual Basic VB .NET Perl F# Java Script CoffeeScript 1990 2000 2010 TypeScript Jython JRuby PowerShell Dart Scala Clojure Kotlin Groovy Go Objective C Shell Scripting Swift Python Ruby
  • 8. © Instil Software 2017 The Great Language Design Debate
  • 9. © Instil Software 2017 Procedural Object Oriented Generic Functional Styles of Programming Supported in Java class Order { … } Order o1 = new Order(); Order o2 = new Order(); orders.filter(o -> o.value > 500) .map(o -> o.customer) .each(c -> print(c.name)) while(orders.hasNext()) { Order o = orders.next(); if(o.priority == URGENT) { o.ship(); } } f1(List<? extends Order> data) { Optional<Client> opt = f2(); for(Order o : data) { o.send(opt.getOrElse(me)); } }
  • 10. © Instil Software 2017 public class Program { public static void main(String [] args) { doThing(new Callable<String>() { //bad public String call() throws Exception { return "porthos"; } }, new Consumer<Exception>(){ public void accept(Exception ex) { System.err.println(ex); } }); doThing(() -> "athos", ex -> System.err.println(ex)); //better doThing(() -> "aramis", System.err::println); //disco } public static void doThing(Callable<String> input, Consumer<Exception> handler) { try { System.out.println(input.call()); } catch (Exception e) { handler.accept(e); } } }
  • 11. © Instil Software 2017 The Road Not Taken… The newest version of the Microsoft Visual J++ development environment supports a language construct called delegates or bound method references… It is unlikely that the Java programming language will ever include this construct. Sun already carefully considered adopting it in 1996, to the extent of building and discarding working prototypes. Our conclusion was that bound method references are unnecessary and detrimental to the language… We believe bound method references are unnecessary because another design alternative, inner classes, provides equal or superior functionality. In particular, inner classes fully support the requirements of user- interface event handling, and have been used to implement a user-interface API at least as comprehensive as the Windows Foundation Classes. We believe bound method references are harmful because they detract from the simplicity of the Java programming language and the pervasively object-oriented character of the APIs…. Extracts From: About Microsoft’s “Delegates" Whitepaper by the Java language team at JavaSoft
  • 12. © Instil Software 2017 How Many Of You Are Using Java 8?
  • 13. © Instil Software 2017 How Many Of You Are Using Scala?
  • 14. © Instil Software 2017 Some things remain the same…
  • 15. © Instil Software 2017 Some FP related tips … Top Tip!
  • 16. © Instil Software 2017 … and a funny one 
  • 17. © Instil Software 2017 The Big Question on the JVM
  • 18. © Instil Software 2017 What This Talk Is Not About
  • 19. © Instil Software 2017 • The Functional Toolkit Level One (a)
  • 20. © Instil Software 2017 Lets Get Judgemental…
  • 21. © Instil Software 2017 1. Functional Interfaces 2. Separate Streams 3. Streams For Primitives 4. No Nested Functions 5. Single Use Streams 6. Confusing Reductions 7. Learning About Collect 8. Underpowered Optional 9. Strings Aren't Streams 10. Missing & Misnamed Methods Top 10 Java 8 Annoyances (My Own Order)
  • 22. © Instil Software 2017 Annoyance 1: The Functional Interfaces
  • 23. © Instil Software 2017 Annoyance 2: Separate Streams
  • 24. © Instil Software 2017 Annoyance 3: Streams For Primitives
  • 25. © Instil Software 2017 Annoyance 3: Streams For Primitives
  • 26. © Instil Software 2017 A key FP best practice is: • Don’t go nuts with lambdas • In particular avoid multi-line lambdas • Instead put tasks into helper functions But this creates an issue: • Our class namespace becomes polluted with helpers The problem is we don’t have nested functions • Unlike JavaScript, where we use them constantly Annoyance 4: No Nested Functions
  • 27. © Instil Software 2017 Annoyance 5: Single Use Streams
  • 28. © Instil Software 2017 Streams and their Descriptions public class Program { public static void main(String[] args) { PrintStream out = System.out; String msg1 = "t%d survived filtern"; String msg2 = "Processed result %dn"; out.println("Demo begins"); IntStream input = IntStream.of(10,11,12,13,14,15,16,17,18,19,20); out.println("Input has been built"); IntStream results = input.filter(x -> x % 2 == 0) .peek(x -> out.printf(msg1,x)) .map(x -> x * 2); out.println("Results have been built"); results.forEach(item -> out.printf(msg2,item)); } } What would you expect this program to print?
  • 29. © Instil Software 2017 Streams and their Descriptions Demo begins Input has been built Results have been built 10 survived filter Processed result 20 12 survived filter Processed result 24 14 survived filter Processed result 28 16 survived filter Processed result 32 18 survived filter Processed result 36 20 survived filter Processed result 40
  • 30. © Instil Software 2017 Flags Used in Stream Descriptions
  • 31. © Instil Software 2017 Annoyance 6: Confusing Reductions
  • 32. © Instil Software 2017 Annoyance 7: Learning To Use Collect
  • 33. © Instil Software 2017 Annoyance 8: Underpowered Optional NB: Partially fixed in Java 9
  • 34. © Instil Software 2017 Annoyance 9: Strings Aren’t Streams
  • 36. © Instil Software 2017 Annoyance 10: Misnamed / Missing Methods Name What It Should Have Been Comment allMatch all Growl anyMatch any Growl noneMatch none Growl findFirst first WTF findAny any WTF Missing Method Comment find Have to use ‘filter(foo).findFirst()’ WTF single WTF sum Have to use collect instead groupBy Have to use collect instead combinations WTF
  • 37. © Instil Software 2017 • The Case Study Level One (b)
  • 38. © Instil Software 2017 The Sample Data to be Queried
  • 39. © Instil Software 2017 Titles of Courses
  • 40. © Instil Software 2017 Titles of Courses Without Trainers
  • 41. © Instil Software 2017 Names and Rates of Trainers
  • 42. © Instil Software 2017 The Number of Advanced Courses
  • 43. © Instil Software 2017 Durations of (Non) Beginner Courses
  • 44. © Instil Software 2017 Durations of (Non) Beginner Courses
  • 45. © Instil Software 2017 Durations of (Non) Beginner Courses
  • 46. © Instil Software 2017 Durations of (Non) Beginner Courses
  • 47. © Instil Software 2017 Pairs of Trainers to Deliver Java Courses
  • 48. © Instil Software 2017 Pairs of Trainers to Deliver Java Courses
  • 49. © Instil Software 2017 The Cost of ‘JEE Web Development’
  • 50. © Instil Software 2017 The Cost of ‘JEE Web Development’
  • 51. © Instil Software 2017 Grouping ID’s and Titles by Type
  • 52. © Instil Software 2017 Grouping ID’s and Titles by Type
  • 53. © Instil Software 2017 • Getting Funky With RESTful Level Two
  • 54. © Instil Software 2017 ‘Reactive Design’ has been trending for a while now • After being announced to great fanfare its quietly been integrated into both client and server side frameworks • E.g. Angular 2 returns values as RxJS Observables The goal is to be ‘asynchronous all the way down’ • Removing all blocking operations in order to increase performance, scalability and utilise many cores • Were ‘many’ could mean tens of thousands Spring 5 offers a reactive version of Spring MVC • Based on the ‘Reactor’ implementation of Reactive Streams • A ‘Flux<T>’ is a stream of ‘Item’ which may be asynchronous • A ‘Mono<T>’ is a the same but holding a single item • Useful in the simpler cases e.g. when retrieving a list The Reactive Web Framework in Spring 5
  • 57. © Instil Software 2017 An Angular Front End to Spring Reactive MVC
  • 58. © Instil Software 2017 But We’ve Seen All This Before…
  • 59. © Instil Software 2017 Akka offers a message-oriented, actor based coding model • It has been around (in its current form) since 2010 Akka HTTP lets you create and consume REST API’s • Replacing the earlier Spray framework Everything you need for Reactive Design is already there • It is typically combined with the Slick library for DB access It can be used from both Java and Scala • But the latter is much more succinct… Introducing Akka HTTP
  • 60. © Instil Software 2017 AKKA HTTP Courses Setup
  • 61. © Instil Software 2017 AKKA HTTP Courses Setup
  • 62. © Instil Software 2017 AKKA HTTP Utility Methods
  • 63. © Instil Software 2017 AKKA HTTP Server Loop & Routing DSL
  • 64. © Instil Software 2017 AKKA HTTP JSON Conversion
  • 65. © Instil Software 2017 Testing Via Postman (Finding All Courses)
  • 66. © Instil Software 2017 Testing Via Postman (Finding a Single Course)
  • 67. © Instil Software 2017 Testing Via Postman (Adding Courses)
  • 68. © Instil Software 2017 Testing Via Postman (Adding Courses)
  • 69. © Instil Software 2017 • Tests, tests, tests… Level Three
  • 70. © Instil Software 2017 TDD and BDD are brilliant methodologies • But they leave at least one question unresolved Explicit tests can’t address the ‘unknown unknowns’ • More correctly called edge or corner cases The Limits of TDD & BDD Reports that say that something hasn't happened are always interesting to me, because as we know, there are known knowns; there are things we know we know. We also know there are known unknowns; that is to say we know there are some things we do not know. But there are also unknown unknowns – the ones we don't know we don't know. Donald Rumsfeld
  • 71. © Instil Software 2017 Introducing Properties Properties are simply parameterized tests • Where actual values are replaced with placeholders A property is the generalization of a test • We make our tests as close to specifications as possible • We express logical truths that should apply to all inputs To take a simple example: • “If we add ‘ab’, ‘cd’ and ‘ef’ to a collection then its size is 3” • “If we add n items to a collection then its size is n” • The former is a test whereas the latter is a property
  • 72. © Instil Software 2017 Property Based Testing In property based testing we instantiate many tests by replacing placeholders with random values • We are trying to falsify the hypothesis that your property is a logical truth that applies to all inputs Property based testing tools allow you to: • Specify the number of test instances required • Provide your own generators to create input values • Combine properties with more conventional kinds of test The merits of properties may include: • A smaller and more maintainable test codebase • A more complete spec with better code coverage
  • 73. © Instil Software 2017 QuickCheck was the original property based test tool • However it is written in Haskell and so not widely known ScalaCheck is the Scala rewrite • At the moment it is the best known tool of its kind • It provides a wide range of additional features Similar tools now exist on other platforms Examples of Tools Language Tool F# FsCheck Python Hypothesis Ruby Rantly JavaScript JSVerify, purescript-quickcheck
  • 74. © Instil Software 2017 Hello World in ScalaCheck object HelloScalaCheck { def main(args: Array[String]) { val prop = forAll { (no1: Int, no2: Int) => printf("Checking with %d and %dn",no1,no2) (no1 + no2) == (no2 + no1) } val params = Parameters.default.withMinSuccessfulTests(10) prop.check(params) } } Checking with 108643437 and 1550798728 Checking with 1773604856 and 1774391105 Checking with 2147483647 and 1413099849 Checking with -1996116831 and 2147483647 Checking with -1800499841 and 454421160 Checking with -1 and 1605504523 Checking with 172417505 and -279849306 Checking with -2147483648 and 1156729111 Checking with 1577680038 and 2147483647 Checking with -2147483648 and 0 + OK, passed 10 tests.
  • 75. © Instil Software 2017 ScalaCheck integrates with other testing tools • Within which it can use their support for matching • E.g. the ‘Matchers’ trait and DSL in ScalaTest To use ScalaCheck as a standalone tool • Create a class which extends from ‘Properties’ • The name of the spec is passed to the base constructor • Define your properties via ‘property(foo) = Props.bar’ • ‘foo’ represents the name of the property and ‘bar’ is the name of one of the factory methods of the ‘Props’ type • ‘Props.forAll’ is the most commonly used factory method • The inputs are an optional generator and a code block • The result of the block determines if the property passes Basic Testing with ScalaCheck
  • 76. © Instil Software 2017 object StringBuilderProps extends Properties("StringBuilder") { property("appending") = forAll { (s1: String, s2: String) => val sb = new StringBuilder() sb.append(s1).append(s2) sb.toString == (s1 + s2) } property("inserting") = forAll { (s1: String, s2: String) => val sb = new StringBuilder() sb.insert(0,s1).insert(0,s2) all( "content" |: sb.toString =? (s2 + s1), "length" |: sb.toString.length =? (s2.length + s1.length) ) } property("reversal") = forAll(alphaStr) { s: String => (s.length > 1) ==> { val sb = new StringBuilder() sb.append(s) sb.toString != sb.reverse.toString } } } + StringBuilder.appending: OK, passed 100 tests. + StringBuilder.inserting: OK, passed 100 tests. ! StringBuilder.reversal: Falsified after 3 passed tests. > ARG_0: "xx" > ARG_0_ORIGINAL: "xsx"
  • 77. © Instil Software 2017 Property Declarations in Depth property("appending") = forAll { ( s1 : String, s2 : String ) => val sb = new StringBuilder() sb.append(s1).append(s2) sb.toString == (s1 + s2) } ‘forAll’ is a helper method of the ‘Prop’ type ‘s1’ and ‘s2’ will be populated with random values the input to ‘forAll’ is a code block
  • 78. © Instil Software 2017 Property Declarations in Depth property("inserting") = forAll { (s1: String, s2: String) => val sb = new StringBuilder() sb.insert(0,s1).insert(0,s2) all ( "content" |: sb.toString =? (s2 + s1), "length" |: sb.toString.length =? (s2.length + s1.length) ) } all is a helper method of the ‘Prop’ type the |: operator allows you to assign labels to properties, this makes it easier to pinpoint failures in the output the =? operator enables ScalaCheck to record both sides of an expression
  • 79. © Instil Software 2017 Property Declarations in Depth property("reversal") = forAll( alphaStr ) { s: String => (s.length > 1) ==> { val sb = new StringBuilder() sb.append(s) sb.toString != sb.reverse.toString } } ‘alphaStr’ is a helper method of the ‘Gen’ type that returns a Generator this is a precondition, which restricts the range of valid inputs
  • 80. © Instil Software 2017 ScalaCheck with ScalaTest class StringBuilderTest extends FunSuite with Checkers { test("appending is supported") { check( forAll { (s1: String, s2: String) => val sb = new StringBuilder() sb.append(s1).append(s2) sb.toString == (s1 + s2) })} test("inserting is supported") { check( forAll { (s1: String, s2: String) => val sb = new StringBuilder() sb.insert(0,s1).insert(0,s2) all( "content" |: sb.toString =? (s2 + s1), "length" |: sb.toString.length =? (s2.length + s1.length)) })} } A standard ScalaTest base class A trait to support ScalaCheck
  • 81. © Instil Software 2017 ScalaCheck does not stop when a property fails • Instead it examines the failing input to see if there is a subset which will still invalidate the property • It will reduce the contents of a list, the size of a string, the variation in a range of numbers etc… Both the original and simplified inputs are printed • The original input is labelled ‘ARG_N_ORIGINAL’ • The simplified input is labelled ‘ARG_N’ You can add this feature to your own generators • By providing an implementation of the ‘Shrink’ type with a ‘shrink’ method that returns a stream of simplified inputs Simplifying Test Specifications
  • 82. © Instil Software 2017 Controlling How ScalaCheck Runs ScalaCheck defaults to 100 runs per property • In many cases this will not be sufficient • You can increase it to any number you like This is one of many settings your can alter • Other examples are the ratio between discarded and successful tests, the number of worker threads and which random number generator to use These settings can be changed by • Creating and injecting a custom ‘Parameters’ object • Specifying options on the applications command line • Specifying options within an ‘sbt’ or ‘Maven’ build file
  • 83. © Instil Software 2017 Controlling How ScalaCheck Runs object StringBuilderPropsRedux { def main(args:Array[String]) { val params = new Parameters.Default { override val minSuccessfulTests = 10000 } val prop = forAll(alphaStr) { s: String => (s.length > 1) ==> { val sb = new StringBuilder() sb.append(s) sb.toString != sb.reverse.toString } } prop.check(params) } } ! Falsified after 112 passed tests. > ARG_0: "pp" > ARG_0_ORIGINAL: "pxp"
  • 84. © Instil Software 2017 Properties can be hard to write at first • Because we are used to thinking in terms of sample inputs Some possible strategies are • Express relationships between different outputs • Timestamps should increase, search results should be ranked by popularity, a GET should not succeed after a DELETE etc… • Perform round trip checking • E.g. a message which has been encrypted and then decrypted should have the same hash as the original • Use a reference implementation • When a result can be found by brute force or a 3rd party implementation you can use this to validate your work Hints for Writing Properties
  • 85. © Instil Software 2017 Most properties are declared via ‘Prop.forAll’ • But other factory methods are available There are also constant properties • Such as ‘proved’, ‘passed’ and ‘falsified’ Methods of the ‘Prop’ Type Factory Method Description forAll Acts as the universal qualifier i.e. a condition is true for all inputs within a set (integers, positive integers, string etc…) exists Acts as the existential qualifier i.e. a condition is true for at least one input. ScalaCheck stops at the first successful result throws Returns true if an expression throws an exception of type ‘T’ all Combines multiple properties such that all must validate atLeastOne Combines multiple properties such that one or more validates within Wraps a property to ensure it completes within a time limit
  • 86. © Instil Software 2017 Normally the set of inputs will need to be restricted • Allowing any integer, float or string will not be acceptable You can specify a generator object when creating properties • The ‘Gen’ class provides a wide range of factory methods • Generators can be nested, combined and used in sequences The Standard Generators Factory Method Description choose Returns an integer in the specified inclusive range posNum, negNum Return random positive and negative integers alphaChar, alphaUpperChar Return random characters alphaStr, identifier Return different kinds of string const An implicit method that wraps a value as a generator listOf, nonEmptyListOf, listOfN Take other generators and use then to produce lists of values
  • 87. © Instil Software 2017 object UsingGenerators { def main(args:Array[String]): Unit = { demoFrequency demoListOf demoSequence demoConst } def demoFrequency(): Unit = { val gen = frequency( (9,choose(1,99)), (1,choose(100,500)) ) runDemo("The Frequency Generator",gen,100) } def demoListOf(): Unit = { val gen1 = listOf(choose(1,100)) val gen2 = listOfN(5,choose(10,99)) runDemo("The List Of Generator", gen1,10) runDemo("The List Of N Generator", gen2,10) }
  • 88. © Instil Software 2017 def demoSequence(): Unit = { val gen = sequence(List(choose(10,99),choose(100,999),const("Fred"))) runDemo("The Sequence Generator", gen,10) } def demoConst(): Unit = { val gen = const(7) runDemo("The Const Generator", gen,10) } def runDemo(title: String, generator: Gen[Any], numTests: Int): Unit = { println(title) val prop = forAll(generator) { input: Any => printf("t%sn",input) true } Test.check(Parameters.default.withMinSuccessfulTests(numTests),prop) } }
  • 89. © Instil Software 2017 The List Of Generator List() List() List(12, 35, 7, 67, 14, 38, 3, 31, 94, 63, 71, 99, 24, 43, 93, 88, 55, 89, 79) List(53, 100, 13, 12, 29, 51, 42, 77, 62, 99, 92, 98, 24, 57, 47, 21, 49, 53, 60) List(87, 72, 28) List(46) List(22, 73, 33, 37, 57, 59, 26, 69, 39, 53, 1, 16, 18, 15, 37, 77, 7, 75, 36, 31, 54, 7, 86, 35) List(10, 65, 29, 14, 75, 93, 58, 48, 43, 18, 55, 54, 1, 50, 75, 5, 44, 99, 35, 79, 25, 25, 82, 14, 16, 15, 82, 84, 84) List(100, 35, 86, 40) List(54, 38, 66, 87, 61, 45, 79, 15, 31, 66, 38, 58, 59, 45, 85, 30, 54, 56, 87, 3, 10, 5, 98, 57, 59, 66, 52, 51) The Frequency Generator 38 52 2 22 24 30 217 43 49 Other values omitted The List Of N Generator List(91, 82, 94, 40, 47) List(74, 84, 38, 54, 43) List(63, 86, 22, 23, 96) List(57, 98, 55, 22, 41) List(17, 25, 23, 28, 20) List(29, 40, 86, 10, 56) List(97, 37, 50, 82, 23) List(92, 85, 76, 89, 19) List(22, 23, 39, 41, 94) List(61, 95, 12, 33, 61) The Sequence Generator [31, 671, Fred] [63, 380, Fred] [79, 369, Fred] [61, 312, Fred] [24, 721, Fred] [87, 749, Fred] [68, 799, Fred] [37, 691, Fred] [14, 147, Fred] [22, 230, Fred] The Const Generator 7 7 7 7 7 7 7 7 7 7 Some lists truncated
  • 90. © Instil Software 2017 A More Complex Example We need a program that recognises poker hands • So given “3H JH 4D 3S JC” it should output “two pair” To test this using properties we need to: • Create a custom generator for poker hands • Raise the ‘minimum successful test’ parameter • Write properties to validate the identification of hands The custom generator can be created by: • Using ‘Gen.oneOf’ to pick a rank and a suit • Then using a for comprehension to yield a card • Then using ‘Gen.listOfN’ to produce a 5 card hand • ‘suchThat’ or ‘filter’ will prevent hands with duplicate cards
  • 91. © Instil Software 2017 class PokerHandGenSpec extends FunSuite { def buildHandGen() = { val rankGen = Gen.oneOf(List("A", "Q", "K", "J", "10", "9", "8", "7", "6", "5", "4", "3", "2")) val suitGen = Gen.oneOf(List("C", "H", "S", "D")) val cardGen = for { rank <- rankGen suit <- suitGen } yield rank + suit Gen.listOfN(5, cardGen) //create a list of 5 cards .suchThat(_.distinct.size == 5) //remove hands with duplicated cards .map(PokerHand.apply) //convert cards to poker hands } def assertProp(prop: Prop) { val params = Parameters.default.withMinSuccessfulTests(50000) val res = Test.check(params, prop) assert(res.passed) } val handGen = buildHandGen()
  • 92. © Instil Software 2017 test("Every poker hand is present") { val props = List( exists(handGen)(_.isPair), exists(handGen)(_.isTwoPair), exists(handGen)(_.isThreeOfAKind), exists(handGen)(_.isStraight), exists(handGen)(_.isFlush), exists(handGen)(_.isFullHouse), exists(handGen)(_.isRoyalFlush), //may require more hands exists(handGen)(_.isFourOfAKind)) props.foreach(assertProp(_)) } test("All 2 Pairs are Pairs") { val prop = forAll(handGen)(h => if (h.isTwoPair) h.isPair else true) assertProp(prop) } test("All Full Houses are Pairs and Three Of A Kind") { val check = (h: PokerHand) => if (h.isFullHouse) (h.isPair && h.isThreeOfAKind) else true val prop = forAll(handGen)(check) assertProp(prop) }
  • 93. © Instil Software 2017 test("All Three Of A Kind are Pairs") { val prop = forAll(handGen)(h => if (h.isThreeOfAKind) h.isPair else true) assertProp(prop) } test("All Four Of A Kind are Pairs and Three Of A KInd") { val check = (h: PokerHand) => if (h.isFourOfAKind) { h.isPair && h.isThreeOfAKind } else { true } val prop = forAll(handGen)(check) assertProp(prop) } test("All Royal Flushes are Flushes") { val prop = forAll(handGen)(h => if (h.isRoyalFlush) h.isFlush else true) assertProp(prop) } }
  • 94. © Instil Software 2017 Resources
  • 95. © Instil Software 2017 • What Floats Your Boat? Summing Up
  • 96. © Instil Software 2017 Where Do We All Stand?
  • 97. © Instil Software 2017 Where Do We All Stand?
  • 98. © Instil Software 2017 Thank You - And Do Enjoy Your Party…