lambdas: myths and mistakes · lambdas: myths and mistakes by richard warburton. the critical...

69
Lambdas: Myths and Mistakes by Richard Warburton

Upload: others

Post on 29-May-2020

7 views

Category:

Documents


0 download

TRANSCRIPT

Page 1: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Lambdas:Myths andMistakesby Richard Warburton

Page 2: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

the critical design tool for softwaredevelopment is a mind well educated indesign principles. It is not ... technology.

Craig Larman

Page 3: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Talk StructureWhy am I talking about this?

Intro to Lambda Expressions

Beyond the Myths

Functional Thinking

Page 4: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Why am Italking about

this?

Page 5: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Lambda Expressions arecoming in Java 8!

Page 6: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

lots of discussion/debate

Page 7: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

How can we help?Adopt-a-JSR

Page 8: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Adopt-a-JSR?More community driven standards

Hackdays

Serve on Expert Groups

Page 9: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Some discussionunimportant

Concrete Examples focus discussion

Page 10: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Intro toLambda

Expressions

Page 11: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Overview of LambdasGoal: Better Libraries

Example: Collections with Data Parallelism

Approach: Allow Code as Data

Page 12: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Action Listenerbutton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { System.out.println("button clicked"); }});

Page 13: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Code as Databutton.addActionListener( ?);

Page 14: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Need a parameterbutton.addActionListener(event

);

Page 15: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Lambda Examplebutton.addActionListener(event -> System.out.println("button clicked"));

Page 16: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

No parametersRunnable helloWorld = () -> System.out.println("Hello World");

Page 17: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Variable CaptureString name = getUserName();button.addActionListener(event -> System.out.println("hi " + name));

Page 18: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Functional InterfacesEverything in Java has a type

Problem: Need types to represent

Functions

Solution: Use interfaces

Page 19: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Functional Interfacespublic interface ActionListener extends EventListener { public void actionPerformed(ActionEvent event);}

Page 20: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

StreamsSupport automated data parallelism

Build computation pipelines

Iterator with inversion of control

Page 21: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

External Iterationint count = 0;for (Artist artist : artists) { if (artist.isFrom("London")) { count++; }}

Page 22: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Internal Iterationartists.stream() .filter(artist -> artist.isFrom("London")) .count();

Page 23: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

map

Page 24: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

mapList<String> collected = Stream.of("a", "b", "hello") .map(string -> string.toUpperCase()) .collect(toList());

assertEquals(asList("A", "B", "HELLO"), collected);

Page 25: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

reduce

Page 26: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

reduceint sum = Stream.of(1, 2, 3, 4) .reduce(0, (acc, x) -> acc + x);

assertEquals(10, sum);

Page 27: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

filter

Page 28: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

filterList<String> beginningWithNumbers = Stream.of("a", "1abc", "abc1") .filter(value -> isDigit(value.charAt(0))) .collect(toList());

assertEquals(asList("1abc"), beginningWithNumbers);

Page 29: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Putting it all togetherfor a given an album, find the nationality of every band

playing on that album

Page 30: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Putting it all together (2)1. transform an album into its artists2. figure out which artists are bands3. find the nationalities of each band

Page 31: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Putting it all together (3)List<String> origins = album.getMusicians() .filter(artist -> artist.getName().startsWith("The")) .map(artist -> artist.getNationality()) .collect(toList());

Page 32: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Method Referencesstr -> str.lengthString::length

x -> foo.bar(x)foo::bar

str -> new Name(str)Name::new

Page 33: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Beyond theMyths

Page 34: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Claim: Syntax is the mostimportant thing aboutLambda Expressions

Page 35: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Yeah, I liked the # syntax proposal better,too. One less character to type! :)

Page 36: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Have you considered 'default null'? It willsave a keyword

Page 37: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

How about a single punctuation mark,currently unused, as syntax sugar for "()->".

Page 38: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

(_, _) -> _ + _

This is starting to look like risque ASCII art :)

Page 39: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Its a Myth!

Page 40: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Claim: Syntax is irrelevant

Page 41: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

// Originally invalidStream.of(1, 2, 3) .forEach(x -> System.out.println(x));

// Required extra ;Stream.of(1, 2, 3) .forEach(x -> System.out.println(x););

Page 42: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Difference betweenexpectations

Many language features stolen! adapted

Missing Features

Stronger Type System

Tuples

List construction syntax

Page 43: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Framing EffectDifferent reactions depending on whether something is

presented as a loss or a gain.

Page 44: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Recall our earlier exampleList<String> origins = album.getMusicians() .filter(artist -> artist.getName().startsWith("The")) .map(artist -> artist.getNationality()) .collect(toList());

Page 45: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Eager vs Lazy (2) album.getMusicians() .filter(artist -> artist.getName().startsWith("The")) .map(artist -> artist.getNationality())

// What's happened? .collect(toList());

Page 46: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Very little TestingMaybe ...

a reflection on popularity of TDD

spikes are good for learning

unfamiliarity with testing lambdas

Page 47: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

How do I test this?list.stream() .map(x -> 1.0 / Math.ceil(1 + Math.pow(x) + Math.atan2(y, x))) .collect(toList());

Page 48: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Approach 1: Testsurrounding method

Don't test the lambda

Test the method its surrounded by

Works well for simple lambdas

Page 49: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Approach 2: ExtractMethod

double complexFunction(double x) { return 1.0 / Math.ceil(1 + Math.pow(x) + Math.atan2(0, x));}

list.stream() .map(this::complexFunction) .collect(toList());

Page 50: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Mistake: debugging// Streamslist.stream() .filter(filteringFunction) .map(mappingFunction) .collect(toList());

// Ye olde for loopList<Bar> bars = new ArrayList<>();for (Foo element : list) { if (filteringFunction(element) { Bar result = mappingFunction(element); bars.add(result); }}

Page 51: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

peeklist.stream() .filter(filteringFunction) .peek(e -> System.out.println("Filtered value: " + e)); .map(mappingFunction) .map(e -> e); .collect(toList());

Page 52: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Compiler Error Messages

Page 53: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

ComparatorsComparator<String> comparator = comparing(String::length);

Comparator<String> comparator = comparing(str -> str.length);

Page 54: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Compiler Errorjava: reference to comparing is ambiguous bothmethod<T>comparing(java.util.function.ToIntFunction< ? super T>)in java.util.Comparator and method<T,U>comparing(java.util.function.Function< ? super T,? extends U>)in java.util.Comparator match

Page 55: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

What happened?// Generic object variantpublic static <T, U extends Comparable< ? super U>> Comparator<T> comparing(Function< ? super T, ? extends U> keyExtractor)

// Specialised primitive variantpublic static <T> Comparator<T> comparing(ToIntFunction< ? super T> keyExtractor)

Page 56: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

SummarySyntax important, but not in the way

people think

New approaches for debugging and

testing

Take care of overloads and compiler error

messages

Page 57: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

FunctionalThinking

Page 58: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

FunctionalThinking?

Thinking in terms of the input to output relationship and nota sequence of steps

Page 59: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

First code that peoplewrite

List<Integer> numbers = Arrays.asList(1, 2, 3);numbers.forEach(x -> { System.out.println(x);});

Page 60: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Non-idiomatic ProposalsEg: capture non-final local variables

Page 61: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Example ProblemCount the number of instances of each word in a document.

Page 62: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Ideal Solutionreader.lines() .flatMap(s -> s.splitAsStream(" ")) .collect(groupingBy(s -> s, counting()));

Page 63: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Ideal Solution (then)reader.lines() .flatMap(s -> Stream.of(s.split(" "))) .collect(groupingBy(s -> s, reducing(s -> 1, Integer::sum)));

// Map entries for "dad"// [ "dad", "dad", "dad" ] => [1, 1, 1] => 3

Page 64: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Bad Solution (Part 1)Map<String, List<String>> initial = br.lines() .flatMap(s -> Arrays.stream(s.split(" "))) .collect(groupingBy(s -> s)); Map<Map.Entry<String, Integer>, Integer> freq1 = initial .entrySet().stream() .map(entry -> new AbstractMap.SimpleImmutableEntry<String,Integer>(entry.getKey(), entry.getValue().size())) .collect(Collectors.toMap(entry -> entry.getValue()));

Page 65: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Bad Solution (Part 2) Supplier<HashMap<String, Integer>> supplier = () -> newHashMap<String, Integer>(); BiConsumer<HashMap<String, Integer>, Map.Entry<String, Integer>> accum = (HashMap<String, Integer> result, Map.Entry<String, Integer>entry) -> result.put(entry.getKey(), entry.getValue()); BiConsumer<HashMap<String, Integer>, HashMap<String, Integer>>merger = HashMap::putAll;

Map<String, Integer> freq2 = initial.entrySet().stream() .map(entry -> new AbstractMap.SimpleImmutableEntry<String,Integer>(entry.getKey(), entry.getValue().size())) .collect(supplier, accum, merger);

Page 66: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

This takes thought

Page 67: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

SummaryIdioms are vital

Not Java specific at all

Requires Practise

Page 68: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

ConclusionsGone through a bunch of examples of

specific issues

‘Functional Thinking’: Not necessary to

start learning.

Try before you buy

Page 69: Lambdas: Myths and Mistakes · Lambdas: Myths and Mistakes by Richard Warburton. the critical design tool for software ... Craig Larman. Talk Structure Why am I talking about this?

Q & A

@RichardWarburto