SlideShare a Scribd company logo
1 of 108
Download to read offline
#DWX22 #PatternMatching @hannotify @PeterWessels
Pattern
Pattern
Pattern
Pattern
Pattern
Pattern
Pattern
Pattern
Pattern
Pattern
Pattern
Pattern
Matching
Matching
Matching
Matching
Matching
Matching
Matching
Matching
Matching
Matching
Matching
Matching
Small Enhancement or Major Feature?
Small Enhancement or Major Feature?
Hanno Embregts
Peter Wessels
@hannotify
@PeterWessels
#DWX22 #PatternMatching @hannotify @PeterWessels
#DWX22 #PatternMatching @hannotify @PeterWessels
#DWX22 #PatternMatching @hannotify @PeterWessels
Small Enhancement
Small Enhancement
Small Enhancement
Small Enhancement
Small Enhancement
https://gph.is/g/ZPJNoPQ
#DWX22 #PatternMatching @hannotify @PeterWessels
Major Feature
Major Feature
Major Feature
Major Feature
Major Feature
https://thumbs.gfycat.com/DefiantElasticGadwall.webp
#DWX22 #PatternMatching @hannotify @PeterWessels
Pattern
Pattern
Pattern
Pattern
Pattern
Matching for
Matching for
Matching for
Matching for
Matching for
instanceof
instanceof
instanceof
instanceof
instanceof
https://pxhere.com/en/photo/752901
#DWX22 #PatternMatching @hannotify @PeterWessels
https://pxhere.com/en/photo/548063
#DWX22 #PatternMatching @hannotify @PeterWessels
Instanceof-and-cast
Instanceof-and-cast
if (product instanceof Guitar) {
Guitar lesPaul =
(Guitar) product;
// use lesPaul
}
1
2
3
4
5
#DWX22 #PatternMatching @hannotify @PeterWessels
Instanceof-and-cast
Instanceof-and-cast
if (product instanceof Guitar) { // 1. is product a Guitar?
1
Guitar lesPaul =
2
(Guitar) product;
3
// use lesPaul
4
}
5
#DWX22 #PatternMatching @hannotify @PeterWessels
Instanceof-and-cast
Instanceof-and-cast
(Guitar) product; // 2. perform conversion
if (product instanceof Guitar) { // 1. is product a Guitar?
1
Guitar lesPaul =
2
3
// use lesPaul
4
}
5
#DWX22 #PatternMatching @hannotify @PeterWessels
Instanceof-and-cast
Instanceof-and-cast
Guitar lesPaul = // 3. declare variable, bind value
if (product instanceof Guitar) { // 1. is product a Guitar?
1
2
(Guitar) product; // 2. perform conversion
3
// use lesPaul
4
}
5
#DWX22 #PatternMatching @hannotify @PeterWessels
Improve the situation
Improve the situation
if (product instanceof Guitar) { // 1. is product a Guitar?
Guitar lesPaul = // 3. declare variable, bind value
(Guitar) product; // 2. perform conversion
// use lesPaul
}
1
2
3
4
5
#DWX22 #PatternMatching @hannotify @PeterWessels
Improve the situation
Improve the situation
if (product instanceof Guitar lesPaul) {
1
2 // use lesPaul
3 }
#DWX22 #PatternMatching @hannotify @PeterWessels
Type pattern
Type pattern
Type pattern
Type pattern
Type pattern
Consists of a predicate that specifies a type,
along with a single binding variable.
https://www.pexels.com/photo/person-holding-white-chalk-625219/
#DWX22 #PatternMatching @hannotify @PeterWessels
Pattern matching
Pattern matching
Pattern matching
Pattern matching
Pattern matching
Allows the conditional extraction of
components from objects to be expressed more
concisely and safely.
https://www.pexels.com/photo/person-holding-white-chalk-625219/
#DWX22 #PatternMatching @hannotify @PeterWessels
Demo
Demo
Simplify implementation of equals
https://pxhere.com/en/photo/1458897
#DWX22 #PatternMatching @hannotify @PeterWessels
Declaring 'in the middle'
Declaring 'in the middle'
if (product instanceof Guitar lesPaul) {
// use lesPaul
}
1
2
3
#DWX22 #PatternMatching @hannotify @PeterWessels
Scoping
Scoping
Pattern binding variable ('flow scoping')
Pattern binding variable ('flow scoping')
The set of places where it would definitely be assigned.
if (product instanceof Guitar lesPaul && lesPaul.isInTune()) {
// can use lesPaul here
} else {
// can't use lesPaul here
}
1
2
3
4
5
#DWX22 #PatternMatching @hannotify @PeterWessels
Benefits
Benefits
Nearly 100% of casts will just disappear!
More concise
#DWX22 #PatternMatching @hannotify @PeterWessels
It's a kind of Pattern
It's a kind of Pattern
It's a kind of Pattern
It's a kind of Pattern
It's a kind of Pattern
pattern example
type pattern Guitar lesPaul
https://thumbs.gfycat.com/DefiantElasticGadwall.webp
#DWX22 #PatternMatching @hannotify @PeterWessels
Feature Status
Feature Status
Type Patterns
Type Patterns
Java version Feature status JEP
14 Preview
15 Second preview
16 Final
JEP 305
JEP 375
JEP 394
#DWX22 #PatternMatching @hannotify @PeterWessels
Pattern
Pattern
Pattern
Pattern
Pattern
Matching for
Matching for
Matching for
Matching for
Matching for
switch
switch
switch
switch
switch
https://pxhere.com/en/photo/752901
#DWX22 #PatternMatching @hannotify @PeterWessels
https://pxhere.com/en/photo/548063
#DWX22 #PatternMatching @hannotify @PeterWessels
https://pxhere.com/en/photo/544037
#DWX22 #PatternMatching @hannotify @PeterWessels
https://pxhere.com/en/photo/544037
#DWX22 #PatternMatching @hannotify @PeterWessels
String apply(Effect effect) {
String formatted = "";
if (effect instanceof Delay) {
Delay de = (Delay) effect;
formatted = String.format("Delay active of %d ms.", de.getTimeInMs());
} else if (effect instanceof Reverb) {
Reverb re = (Reverb) effect;
formatted = String.format("Reverb active of type %s and roomSize %d.", re.getName(
} else if (effect instanceof Overdrive) {
Overdrive ov = (Overdrive) effect;
formatted = String.format("Overdrive active with gain %d.", ov.getGain());
} else if (effect instanceof Tremolo) {
Tremolo tr = (Tremolo) effect;
formatted = String.format("Tremolo active with depth %d and rate %d.", tr.getDepth
} else if (effect instanceof Tuner) {
Tuner tu = (Tuner) effect;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#DWX22 #PatternMatching @hannotify @PeterWessels
g ( yp , g (
formatted = String.format("Overdrive active with gain %d.", ov.getGain());
formatted = String.format("Tremolo active with depth %d and rate %d.", tr.getDepth
formatted = String.format("Tuner active with pitch %d. Muting all signal!", tu.get
formatted = el.getEffects().stream().map(this::apply).collect(Collectors.joining(S
formatted = String.format("Unknown effect active: %s.", effect);
} else if (effect instanceof Overdrive) {
9
Overdrive ov = (Overdrive) effect;
10
11
} else if (effect instanceof Tremolo) {
12
Tremolo tr = (Tremolo) effect;
13
14
} else if (effect instanceof Tuner) {
15
Tuner tu = (Tuner) effect;
16
17
} else if (effect instanceof EffectLoop) {
18
EffectLoop el = (EffectLoop) effect;
19
20
} else {
21
22
}
23
#DWX22 #PatternMatching @hannotify @PeterWessels
String apply(Effect effect) {
String formatted = "";
if (effect instanceof Delay de) {
} else if (effect instanceof Reverb re) {
} else if (effect instanceof Overdrive ov) {
} else if (effect instanceof Tremolo tr) {
} else if (effect instanceof Tuner tu) {
} else if (effect instanceof EffectLoop el) {
1
2
3
4 formatted = String.format("Delay active of %d ms.", de.getTimeInMs());
5
6 formatted = String.format("Reverb active of type %s and roomSize %d.", re.getName(
7
8 formatted = String.format("Overdrive active with gain %d.", ov.getGain());
9
10 formatted = String.format("Tremolo active with depth %d and rate %d.", tr.getDepth
11
12 formatted = String.format("Tuner active with pitch %d. Muting all signal!", tu.get
13
14 formatted = el.getEffects().stream().map(this::apply).collect(Collectors.joining(S
15 } else {
16 formatted = String format("Unknown effect active: %s " effect);
#DWX22 #PatternMatching @hannotify @PeterWessels
formatted = String.format( Delay active of %d ms. , de.getTimeInMs());
formatted = String.format("Reverb active of type %s and roomSize %d.", re.getName(
formatted = String.format("Overdrive active with gain %d.", ov.getGain());
formatted = String.format("Tremolo active with depth %d and rate %d.", tr.getDepth
formatted = String.format("Tuner active with pitch %d. Muting all signal!", tu.get
formatted = el.getEffects().stream().map(this::apply).collect(Collectors.joining(S
formatted = String.format("Unknown effect active: %s.", effect);
4
} else if (effect instanceof Reverb re) {
5
6
} else if (effect instanceof Overdrive ov) {
7
8
} else if (effect instanceof Tremolo tr) {
9
10
} else if (effect instanceof Tuner tu) {
11
12
} else if (effect instanceof EffectLoop el) {
13
14
} else {
15
16
}
17
return formatted;
18
}
19
#DWX22 #PatternMatching @hannotify @PeterWessels
Switch expression
Switch expression
1 String apply(Effect effect) {
2 return switch(effect) {
3 default -> String.format("Unknown effect active: %s.", effect);
4 };
5 }
#DWX22 #PatternMatching @hannotify @PeterWessels
Switch expression
Switch expression
case Delay de -> String.format("Delay active of %d ms.", de.getTimeInMs());
case Reverb re -> String.format("Reverb active of type %s and roomSize %d.", re
String apply(Effect effect) {
1
return switch(effect) {
2
3
4
5 default -> String.format("Unknown effect active: %s.", effect);
6 };
7 }
#DWX22 #PatternMatching @hannotify @PeterWessels
Switch expression
Switch expression
1 String apply(Effect effect) {
2 return switch(effect) {
3 case Delay de -> String.format("Delay active of %d ms.", de.getTimeInMs());
4 case Reverb re -> String.format("Reverb active of type %s and roomSize %d.", r
5 case Overdrive ov -> String.format("Overdrive active with gain %d.", ov.getGain()
6 case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", t
7 case Tuner tu -> String.format("Tuner active with pitch %d. Muting all signal
8 default -> String.format("Unknown effect active: %s.", effect);
9 };
10 }
#DWX22 #PatternMatching @hannotify @PeterWessels
Switch expression
Switch expression
case EffectLoop el -> el.getEffects().stream().map(this::apply).collect(Collectors
String apply(Effect effect) {
1
return switch(effect) {
2
case Delay de -> String.format("Delay active of %d ms.", de.getTimeInMs());
3
case Reverb re -> String.format("Reverb active of type %s and roomSize %d.", r
4
case Overdrive ov -> String.format("Overdrive active with gain %d.", ov.getGain()
5
case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", t
6
case Tuner tu -> String.format("Tuner active with pitch %d. Muting all signal
7
8
9 default -> String.format("Unknown effect active: %s.", effect);
10 };
11 }
#DWX22 #PatternMatching @hannotify @PeterWessels
Switch expression
Switch expression
String apply(Effect effect) {
return switch(effect) {
case Delay de -> String.format("Delay active of %d ms.", de.getTimeInMs());
case Reverb re -> String.format("Reverb active of type %s and roomSize %d.", r
case Overdrive ov -> String.format("Overdrive active with gain %d.", ov.getGain()
case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", t
case Tuner tu -> String.format("Tuner active with pitch %d. Muting all signal
case EffectLoop el -> el.getEffects().stream().map(this::apply).collect(Collectors
default -> String.format("Unknown effect active: %s.", effect);
};
}
1
2
3
4
5
6
7
8
9
10
11
#DWX22 #PatternMatching @hannotify @PeterWessels
https://pxhere.com/en/photo/544037
#DWX22 #PatternMatching @hannotify @PeterWessels
Sensible operations to the effect loop
Sensible operations to the effect loop
apply()
setVolume(int volume)
contains(Effect... effect)
#DWX22 #PatternMatching @hannotify @PeterWessels
Nonsensical operations to the effect
Nonsensical operations to the effect
loop
loop
isTunerActive()
isDelayTimeEqualToReverbRoomSize()
isToneSuitableToPlayPrideInTheNameOfLove()
#DWX22 #PatternMatching @hannotify @PeterWessels
Switch expression
Switch expression
String apply(Effect effect) {
return switch(effect) {
case Delay de -> String.format("Delay active of %d ms.", de.getTimeInMs());
case Reverb re -> String.format("Reverb active of type %s and roomSize %d.", r
case Overdrive ov -> String.format("Overdrive active with gain %d.", ov.getGain()
case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", t
case Tuner tu -> String.format("Tuner active with pitch %d. Muting all signal
case EffectLoop el -> el.getEffects().stream().map(this::apply).collect(Collectors
default -> String.format("Unknown effect active: %s.", effect);
};
}
1
2
3
4
5
6
7
8
9
10
11
#DWX22 #PatternMatching @hannotify @PeterWessels
Switch expression
Switch expression
static String apply(Effect effect) {
return switch(effect) {
case Delay de -> String.format("Delay active of %d ms.", de.getTimeInMs());
case Reverb re -> String.format("Reverb active of type %s and roomSize %d.", r
case Overdrive ov -> String.format("Overdrive active with gain %d.", ov.getGain()
case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", t
case Tuner tu -> String.format("Tuner active with pitch %d. Muting all signal
case EffectLoop el -> el.getEffects().stream().map(Effect::apply).collect(Collecto
default -> String.format("Unknown effect active: %s.", effect);
};
}
1
2
3
4
5
6
7
8
9
10
11
#DWX22 #PatternMatching @hannotify @PeterWessels
Benefits of pattern matching
Benefits of pattern matching
No need for the Visitor pattern or a common supertype
A single expression instead of many assignments
Less error-prone (in adding cases)
More concise
Safer - the compiler can check for missing cases
#DWX22 #PatternMatching @hannotify @PeterWessels
But what if
But what if effect
effect is
is null
null?
?
return switch(effect) { // throws NullPointerException!
static String apply(Effect effect) {
1
2
case Delay de -> String.format("Delay active of %d ms.", de.getTimeInMs());
3
case Reverb re -> String.format("Reverb active of type %s and roomSize %d.", r
4
case Overdrive ov -> String.format("Overdrive active with gain %d.", ov.getGain()
5
case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", t
6
case Tuner tu -> String.format("Tuner active with pitch %d. Muting all signal
7
case EffectLoop el -> el.getEffects().stream().map(Effect::apply).collect(Collecto
8
default -> String.format("Unknown effect active: %s.", effect);
9
};
10
}
11
#DWX22 #PatternMatching @hannotify @PeterWessels
Combining case labels
Combining case labels
case null, default -> String.format("Unknown or malfunctioning effect active: %s."
static String apply(Effect effect) {
1
return switch(effect) {
2
case Delay de -> String.format("Delay active of %d ms.", de.getTimeInMs());
3
case Reverb re -> String.format("Reverb active of type %s and roomSize %d.", r
4
case Overdrive ov -> String.format("Overdrive active with gain %d.", ov.getGain()
5
case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", t
6
case Tuner tu -> String.format("Tuner active with pitch %d. Muting all signal
7
case EffectLoop el -> el.getEffects().stream().map(Effect::apply).collect(Collecto
8
9
};
10
}
11
#DWX22 #PatternMatching @hannotify @PeterWessels
Demo
Demo
Guarded patterns
https://pxhere.com/en/photo/1458897
#DWX22 #PatternMatching @hannotify @PeterWessels
Guarded patterns
Guarded patterns
String apply(Effect effect, Guitar guitar) {
return switch(effect) {
// (...)
case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", tr.ge
case Tuner tu -> String.format("Tuner active with pitch %d. Muting all signal!", tu
case EffectLoop el -> el.getEffects().stream().map(this::apply).collect(Collectors.
default -> String.format("Unknown effect active: %s.", effect);
};
}
1
2
3
4
5
6
7
8
9
#DWX22 #PatternMatching @hannotify @PeterWessels
Guarded patterns
Guarded patterns
case Tuner tu && !tu.isInTune(guitar) -> String.format("Guitar is in need of tuning
String apply(Effect effect, Guitar guitar) {
1
return switch(effect) {
2
// (...)
3
case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", tr.ge
4
5
case EffectLoop el -> el.getEffects().stream().map(this::apply).collect(Collectors.
6
default -> String.format("Unknown effect active: %s.", effect);
7
};
8
}
9
#DWX22 #PatternMatching @hannotify @PeterWessels
Guarded patterns
Guarded patterns
case Tuner tu when !tu.isInTune(guitar) -> String.format("Guitar is in need of tuni
String apply(Effect effect, Guitar guitar) {
1
return switch(effect) {
2
// (...)
3
case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", tr.ge
4
5
case EffectLoop el -> el.getEffects().stream().map(this::apply).collect(Collectors.
6
default -> String.format("Unknown effect active: %s.", effect);
7
};
8
}
9
#DWX22 #PatternMatching @hannotify @PeterWessels
Guarded patterns
Guarded patterns
switch(effect) {
// ...
case Tuner tu:
if (!tu.isInTune(guitar)) { // tuning is needed }
else { // no tuning is needed }
break;
// ...
}
1
2
3
4
5
6
7
8
#DWX22 #PatternMatching @hannotify @PeterWessels
It's a kind of Pattern
It's a kind of Pattern
It's a kind of Pattern
It's a kind of Pattern
It's a kind of Pattern
pattern example
guarded pattern Tuner tu when
!tu.isInTune(guitar)
type pattern Guitar lesPaul
https://thumbs.gfycat.com/DefiantElasticGadwall.webp
#DWX22 #PatternMatching @hannotify @PeterWessels
Feature Status
Feature Status
Guarded Patterns
Guarded Patterns
Java version Feature status JEP
17 Preview
18 Second preview
19 Third preview
JEP 406
JEP 420
JEP 427
#DWX22 #PatternMatching @hannotify @PeterWessels
Deconstruction
Deconstruction
Deconstruction
Deconstruction
Deconstruction
Patterns
Patterns
Patterns
Patterns
Patterns
https://pxhere.com/en/photo/752901
#DWX22 #PatternMatching @hannotify @PeterWessels
Disclaimer
Disclaimer
Disclaimer
Disclaimer
Disclaimer
We can't tell you when the following features
are coming to Java. Also: syntax and
implementation specifics may still change.
https://pxhere.com/en/photo/1359311
#DWX22 #PatternMatching @hannotify @PeterWessels
Deconstruction patterns
Deconstruction patterns
String apply(Effect effect) {
return switch(effect) {
case Delay de -> String.format("Delay active of %d ms.", de.getTimeInMs());
case Reverb re -> String.format("Reverb active of type %s and roomSize %d.", r
case Overdrive ov -> String.format("Overdrive active with gain %d.", ov.getGain()
case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", t
case Tuner tu -> String.format("Tuner active with pitch %d. Muting all signal
case EffectLoop el -> el.getEffects().stream().map(this::apply).collect(Collectors
default -> String.format("Unknown effect active: %s.", effect);
};
}
1
2
3
4
5
6
7
8
9
10
11
#DWX22 #PatternMatching @hannotify @PeterWessels
Deconstruction patterns
Deconstruction patterns
case Overdrive(int gain) -> String.format("Overdrive active with gain %d.", gain);
String apply(Effect effect) {
1
return switch(effect) {
2
case Delay de -> String.format("Delay active of %d ms.", de.getTimeInMs());
3
case Reverb re -> String.format("Reverb active of type %s and roomSize %d.", r
4
5
case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", t
6
case Tuner tu -> String.format("Tuner active with pitch %d. Muting all signal
7
case EffectLoop el -> el.getEffects().stream().map(this::apply).collect(Collectors
8
default -> String.format("Unknown effect active: %s.", effect);
9
};
10
}
11
#DWX22 #PatternMatching @hannotify @PeterWessels
Pattern definition
Pattern definition
public class Overdrive implements Effect {
private final int gain;
public Overdrive(int gain) {
this.gain = gain;
}
}
1
2
3
4
5
6
7
#DWX22 #PatternMatching @hannotify @PeterWessels
Pattern definition
Pattern definition
1 public class Overdrive implements Effect {
2 private final int gain;
3
4 public Overdrive(int gain) {
5 this.gain = gain;
6 }
7
public pattern Overdrive(int gain) {
8
gain = this.gain;
9
}
10
11 }
#DWX22 #PatternMatching @hannotify @PeterWessels
Deconstruction patterns
Deconstruction patterns
case Overdrive(int gain) -> String.format("Overdrive active with gain %d.", gain);
String apply(Effect effect) {
1
return switch(effect) {
2
case Delay de -> String.format("Delay active of %d ms.", de.getTimeInMs());
3
case Reverb re -> String.format("Reverb active of type %s and roomSize %d.", r
4
5
case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", t
6
case Tuner tu -> String.format("Tuner active with pitch %d. Muting all signal
7
case EffectLoop el -> el.getEffects().stream().map(this::apply).collect(Collectors
8
default -> String.format("Unknown effect active: %s.", effect);
9
};
10
}
11
#DWX22 #PatternMatching @hannotify @PeterWessels
Demo
Demo
Deconstruction with Records
https://pxhere.com/en/photo/1458897
#DWX22 #PatternMatching @hannotify @PeterWessels
Deconstruction patterns
Deconstruction patterns
String apply(Effect effect) {
return switch(effect) {
case Delay(int timeInMs) -> String.format("Delay active of %d ms.", timeInMs);
case Reverb(String name, int roomSize) -> String.format("Reverb active of type %s
case Overdrive(int gain) -> String.format("Overdrive active with gain %d.", gain);
case Tremolo(int depth, int rate) -> String.format("Tremolo active with depth %d a
case Tuner(int pitchInHz) -> String.format("Tuner active with pitch %d. Muting all
case EffectLoop(Set<Effect> effects) -> effects.stream().map(this::apply).collect(
default -> String.format("Unknown effect active: %s.", effect);
};
}
1
2
3
4
5
6
7
8
9
10
11
#DWX22 #PatternMatching @hannotify @PeterWessels
Can we combine patterns?
Can we combine patterns?
static boolean isDelayTimeEqualToReverbRoomSize(EffectLoop effectLoop) {
}
1
2
3
#DWX22 #PatternMatching @hannotify @PeterWessels
Pattern composition
Pattern composition
static boolean isDelayTimeEqualToReverbRoomSize(EffectLoop effectLoop) {
if (effectLoop instanceof EffectLoop(Delay(int timeInMs), Reverb(String name, int roomS
return timeInMs == roomSize;
1
2
3
}
4
return false;
5
6 }
#DWX22 #PatternMatching @hannotify @PeterWessels
Pattern composition
Pattern composition
1 static boolean isDelayTimeEqualToReverbRoomSize(EffectLoop effectLoop) {
2 return effectLoop.getEffects().stream()
3 .filter(e -> e instanceof Delay || e instanceof Reverb)
4 .map(dr -> {
5 if (dr instanceof Delay d) {
6 return d.getTimeInMs();
} else {
7
Reverb r = (Reverb) dr;
8
return r.getRoomSize();
9
}
10
11
}).distinct().count() == 1;
12
13 }
#DWX22 #PatternMatching @hannotify @PeterWessels
It's a kind of Pattern
It's a kind of Pattern
It's a kind of Pattern
It's a kind of Pattern
It's a kind of Pattern
pattern example
deconstruction pattern Delay(int timeInMs)
type pattern Guitar lesPaul
guarded pattern Tuner tu when
!tu.isInTune(guitar)
https://thumbs.gfycat.com/DefiantElasticGadwall.webp
#DWX22 #PatternMatching @hannotify @PeterWessels
Var and any patterns
Var and any patterns
// Pre-Java 10
Guitar telecaster = new Guitar("Fender Telecaster Baritone Blacktop", GuitarType.TELECASTER
// Java 10
var telecaster = new Guitar("Fender Telecaster Baritone Blacktop", GuitarType.TELECASTER);
1
2
3
4
5
https://openjdk.java.net/jeps/286
https://openjdk.java.net/jeps/286
#DWX22 #PatternMatching @hannotify @PeterWessels
Var and any patterns
Var and any patterns
static boolean isDelayTimeEqualToReverbRoomSize(EffectLoop effectLoop) {
if (effectLoop instanceof EffectLoop(Delay(int timeInMs), Reverb(String name, int roomS
return timeInMs == roomSize;
}
return false;
}
1
2
3
4
5
6
#DWX22 #PatternMatching @hannotify @PeterWessels
Var and any patterns
Var and any patterns
if (effectLoop instanceof EffectLoop(Delay(var timeInMs), Reverb(var name, var roomSize
static boolean isDelayTimeEqualToReverbRoomSize(EffectLoop effectLoop) {
1
2
return timeInMs == roomSize;
3
}
4
return false;
5
}
6
#DWX22 #PatternMatching @hannotify @PeterWessels
http://gph.is/2lFlHIK
#DWX22 #PatternMatching @hannotify @PeterWessels
Var and any patterns
Var and any patterns
static boolean isDelayTimeEqualToReverbRoomSize(EffectLoop effectLoop) {
if (effectLoop instanceof EffectLoop(Delay(var timeInMs), Reverb(_, var roomSize))) {
return timeInMs == roomSize;
}
return false;
}
1
2
3
4
5
6
#DWX22 #PatternMatching @hannotify @PeterWessels
Optimization
Optimization
static String apply(Effect effect) {
return switch(effect) {
case Delay(int timeInMs) -> String.format("Delay active of %d ms.", timeInMs);
case Reverb(String name, int roomSize) -> String.format("Reverb active of type %s
case Overdrive(int gain) -> String.format("Overdrive active with gain %d.", gain);
case Tremolo(int depth, int rate) -> String.format("Tremolo active with depth %d a
case Tuner(int pitchInHz) -> String.format("Tuner active with pitch %d. Muting all
case EffectLoop(var effects) -> effects.stream().map(Effect::apply).collect(Collec
default -> String.format("Unknown effect active: %s.", effect);
};
}
1
2
3
4
5
6
7
8
9
10
11
#DWX22 #PatternMatching @hannotify @PeterWessels
Optimization
Optimization
1 static String apply(Effect effect) {
2 return switch(effect) {
3 // ...
4 case EffectLoop(var effects) -> effects.stream().map(Effect::apply).collect(Collect
5 default -> String.format("Unknown effect active: %s.", effect);
6 };
7 }
#DWX22 #PatternMatching @hannotify @PeterWessels
Optimization
Optimization
case EffectLoop(Tuner(int pitchInHz), _) -> String.format("The EffectLoop contains
static String apply(Effect effect) {
1
return switch(effect) {
2
// ...
3
4
5 case EffectLoop(var effects) -> effects.stream().map(Effect::apply).collect(Collect
6 default -> String.format("Unknown effect active: %s.", effect);
7 };
8 }
#DWX22 #PatternMatching @hannotify @PeterWessels
Benefits
Benefits
Better encapsulation
a case branch only receives data that it actually references.
More elegant logic
by using pattern composition
Optimization
through the use of any patterns
#DWX22 #PatternMatching @hannotify @PeterWessels
It's a kind of Pattern
It's a kind of Pattern
It's a kind of Pattern
It's a kind of Pattern
It's a kind of Pattern
pattern example
var pattern var timeInMs
type pattern Guitar lesPaul
guarded pattern Tuner tu when
!tu.isInTune(guitar)
deconstruction pattern Delay(int timeInMs)
https://thumbs.gfycat.com/DefiantElasticGadwall.webp
#DWX22 #PatternMatching @hannotify @PeterWessels
It's a kind of Pattern
It's a kind of Pattern
It's a kind of Pattern
It's a kind of Pattern
It's a kind of Pattern
pattern example
any pattern _
type pattern Guitar lesPaul
guarded pattern Tuner tu when
!tu.isInTune(guitar)
deconstruction pattern Delay(int timeInMs)
var pattern var timeInMs
https://thumbs.gfycat.com/DefiantElasticGadwall.webp
#DWX22 #PatternMatching @hannotify @PeterWessels
Feature Status
Feature Status
Java
version
Feature status JEP
19 Preview (composition of record and type
patterns only)
JEP
405
#DWX22 #PatternMatching @hannotify @PeterWessels
Pattern Matching Plays Nice
Pattern Matching Plays Nice
With
With
Sealed Types
Sealed Types
Sealed Types
Sealed Types
Sealed Types
and Records
and Records
and Records
and Records
and Records
https://pxhere.com/en/photo/752901
#DWX22 #PatternMatching @hannotify @PeterWessels
Demo
Demo
Make Effect a sealed type
https://pxhere.com/en/photo/1458897
#DWX22 #PatternMatching @hannotify @PeterWessels
Sealed types yield completeness
Sealed types yield completeness
static String apply(Effect effect) {
return switch(effect) {
case Delay(int timeInMs) -> String.format("Delay active of %d ms.", timeInMs);
case Reverb(String name, int roomSize) -> String.format("Reverb active of type %s
case Overdrive(int gain) -> String.format("Overdrive active with gain %d.", gain);
case Tremolo(int depth, int rate) -> String.format("Tremolo active with depth %d a
case Tuner(int pitchInHz) -> String.format("Tuner active with pitch %d. Muting all
case EffectLoop(Tuner(int pitchInHz), _) -> String.format("The EffectLoop contains
case EffectLoop(var effects) -> effects.stream().map(Effect::apply).collect(Collec
default -> String.format("Unknown effect active: %s.", effect);
};
}
1
2
3
4
5
6
7
8
9
10
11
12
#DWX22 #PatternMatching @hannotify @PeterWessels
Sealed types yield completeness
Sealed types yield completeness
static String apply(Effect effect) {
return switch(effect) {
case Delay(int timeInMs) -> String.format("Delay active of %d ms.", timeInMs);
case Reverb(String name, int roomSize) -> String.format("Reverb active of type %s
case Overdrive(int gain) -> String.format("Overdrive active with gain %d.", gain);
case Tremolo(int depth, int rate) -> String.format("Tremolo active with depth %d a
case Tuner(int pitchInHz) -> String.format("Tuner active with pitch %d. Muting all
case EffectLoop(Tuner(int pitchInHz), _) -> String.format("The EffectLoop contains
case EffectLoop(var effects) -> effects.stream().map(Effect::apply).collect(Collec
1
2
3
4
5
6
7
8
9
10 };
11 }
https://cr.openjdk.java.net/~briangoetz/amber/pattern-match.html
#DWX22 #PatternMatching @hannotify @PeterWessels
Records
Records
Input:
Input:
Commit to the class being a transparent carrier for its data.
Output:
Output:
constructors
accessor methods
equals()-implementation
hashCode()-implementation
toString()-implementation
deconstruction pattern
#DWX22 #PatternMatching @hannotify @PeterWessels
Array patterns
Array patterns
record EffectLoop(String name, int volume, Effect... effects) { }
1
static String apply(EffectLoop effectLoop) {}
return switch(effectLoop) {
case EffectLoop(var name, var volume) -> "Effect loop contains no effects.";
}
}
1
2
3
4
5
#DWX22 #PatternMatching @hannotify @PeterWessels
Array patterns
Array patterns
record EffectLoop(String name, int volume, Effect... effects) { }
1
static String apply(EffectLoop effectLoop) {}
return switch(effectLoop) {
case EffectLoop(var name, var volume) -> "Effect loop contains no effects.";
case EffectLoop(_, _, var effect) -> "Effect loop contains exactly one effect.";
1
2
3
4
5 }
6 }
#DWX22 #PatternMatching @hannotify @PeterWessels
Array patterns
Array patterns
record EffectLoop(String name, int volume, Effect... effects) { }
1
static String apply(EffectLoop effectLoop) {}
return switch(effectLoop) {
case EffectLoop(var name, var volume) -> "Effect loop contains no effects.";
case EffectLoop(_, _, var effect) -> "Effect loop contains exactly one effect.";
case EffectLoop(_, _, var effect, ...) -> "Effect loop contains more than one effec
1
2
3
4
5
6 }
7 }
#DWX22 #PatternMatching @hannotify @PeterWessels
Array patterns
Array patterns
record EffectLoop(String name, int volume, Effect... effects) { }
1
static String apply(EffectLoop effectLoop) {}
return switch(effectLoop) {
case EffectLoop(var name, var volume) -> "Effect loop contains no effects.";
case EffectLoop(_, _, var effect) -> "Effect loop contains exactly one effect.";
case EffectLoop(_, _, var effect, ...) -> "Effect loop contains more than one effec
case EffectLoop(_, _, var effect1, var effect2) -> "Effect loop contains exactly tw
case EffectLoop(_, _, var effect1, var effect2, ...) -> "Effect loop contains more
1
2
3
4
5
6
7
8 }
9 }
#DWX22 #PatternMatching @hannotify @PeterWessels
It's a kind of Pattern
It's a kind of Pattern
It's a kind of Pattern
It's a kind of Pattern
It's a kind of Pattern
pattern example
array pattern EffectLoop(var name, var effect, ...)
.. ..
var pattern var timeInMs
any pattern _
https://thumbs.gfycat.com/DefiantElasticGadwall.webp
#DWX22 #PatternMatching @hannotify @PeterWessels
Feature Status
Feature Status
Sealed Types
Sealed Types
Java version Feature status JEP
15 Preview
16 Second preview
17 Final
JEP 360
JEP 397
JEP 409
#DWX22 #PatternMatching @hannotify @PeterWessels
Feature Status
Feature Status
Completeness
Completeness
Java version Feature status JEP
17 Preview
18 Second preview
19 Third preview
JEP 406
JEP 420
JEP 427
#DWX22 #PatternMatching @hannotify @PeterWessels
Feature Status
Feature Status
Record Patterns
Record Patterns
Java version Feature status JEP
19 Preview JEP 405
#DWX22 #PatternMatching @hannotify @PeterWessels
A Better
A Better
A Better
A Better
A Better
Serialization?
Serialization?
Serialization?
Serialization?
Serialization?
https://pxhere.com/en/photo/752901
#DWX22 #PatternMatching @hannotify @PeterWessels
Here be dragons!
Here be dragons!
Here be dragons!
Here be dragons!
Here be dragons!
We can't be sure at all that the following
features will appear in Java as depicted. They
can change a lot in the meantime.
https://www.pexels.com/photo/dragon-festival-during-nighttime-6068535/
#DWX22 #PatternMatching @hannotify @PeterWessels
Opposites
Opposites
Deconstruction pattern
Deconstruction pattern
transforms an object into a set of typed fields
Constructor
Constructor
transforms a set of typed fields into an object
#DWX22 #PatternMatching @hannotify @PeterWessels
Serialization
Serialization
very important feature
but many people hate its current implementation
Drawbacks
Drawbacks
it undermines the accessibility model
serialization logic is not 'readable code'
it bypasses constructors and data validation
#DWX22 #PatternMatching @hannotify @PeterWessels
Serialization
Serialization
public class EffectLoop implements Effect {
private String name;
private Set<Effect> effects;
public EffectLoop(String name) {
this.name = name;
this.effects = new HashSet<>();
}
}
1
2
3
4
5
6
7
8
9
#DWX22 #PatternMatching @hannotify @PeterWessels
Serialization
Serialization
1 public class EffectLoop implements Effect {
2 private String name;
3 private Set<Effect> effects;
4
5 public EffectLoop(String name) {
6 this.name = name;
7 this.effects = new HashSet<>();
8 }
9
public pattern EffectLoop(String name, Effect[] effects) {
10
name = this.name;
11
effects = this.effects.toArray();
12
}
13
14 }
#DWX22 #PatternMatching @hannotify @PeterWessels
Serialization
Serialization
public EffectLoop(String name, Effect[] effects) {
this(name);
for (Effect effect : effects) {
this.effects.add(effect);
}
this.name = name;
6
this.effects = new HashSet<>();
7
}
8
9
10
11
12
13
14
15 }
16
17 public pattern EffectLoop(String name, Effect[] effects) {
18 name = this.name;
19 effects = this.effects.toArray();
}
20
21 }
#DWX22 #PatternMatching @hannotify @PeterWessels
Serialization
Serialization
public class EffectLoop implements Effect {
private String name;
private Set<Effect> effects;
public EffectLoop(String name) {
this.name = name;
this.effects = new HashSet<>();
}
@Deserializer
1
2
3
4
5
6
7
8
9
10
11 public EffectLoop(String name, Effect[] effects) {
12 this(name);
13 for (Effect effect : effects) {
14 this.effects.add(effect);
15 }
16 }
#DWX22 #PatternMatching @hannotify @PeterWessels
Some challenges remain
Some challenges remain
Q:
Q: How to support multiple versions of one class?
How to support multiple versions of one class?
A: @Serializer and @Deserializer annotations could get a
property version in the future.
#DWX22 #PatternMatching @hannotify @PeterWessels
Feature Status
Feature Status
Java
version
Feature status JEP
n/a Exploratory
document
Towards Better
Serialization
https://cr.openjdk.java.net/~briangoetz/amber/serialization.html
#DWX22 #PatternMatching @hannotify @PeterWessels
Future
Future
Future
Future
Future
Expansions
Expansions
Expansions
Expansions
Expansions
https://pxhere.com/en/photo/752901
#DWX22 #PatternMatching @hannotify @PeterWessels
Here be super dragons!
Here be super dragons!
Here be super dragons!
Here be super dragons!
Here be super dragons!
We can't be sure that the following features will
appear in Java as depicted, if at all.
Proceed with caution!
https://www.pexels.com/photo/dragon-festival-during-nighttime-6068535/
#DWX22 #PatternMatching @hannotify @PeterWessels
Pattern bind statements
Pattern bind statements
var reverb = new Reverb("ChamberReverb", 2);
__let Reverb(String name, int roomSize) = reverb;
// do something with name & roomSize
1
2
3
4
5
https://cr.openjdk.java.net/~briangoetz/amber/pattern-match.html
#DWX22 #PatternMatching @hannotify @PeterWessels
Pattern bind statements
Pattern bind statements
else throw new IllegalArgumentException("not a Reverb!");
var reverb = new Reverb("ChamberReverb", 2);
1
2
__let Reverb(String name, int roomSize) = reverb;
3
4
5
6 // do something with name & roomSize
#DWX22 #PatternMatching @hannotify @PeterWessels
Other ideas
Other ideas
AND patterns:
PatternOne&PatternTwo
Patterns in catch clauses:
(will most likely complement multi-catch blocks)
Collection patterns
https://mail.openjdk.java.net/pipermail/amber-spec-experts/2021-January/002758.html
https://mail.openjdk.java.net/pipermail/amber-spec-experts/2021-January/002758.html
#DWX22 #PatternMatching @hannotify @PeterWessels
Pattern
Pattern
Pattern
Pattern
Pattern
Contexts
Contexts
Contexts
Contexts
Contexts
https://pxhere.com/en/photo/752901
#DWX22 #PatternMatching @hannotify @PeterWessels
Pattern Contexts
Pattern Contexts
Pattern context Example Purpose
instanceof
predicate
product instanceof Guitar
guitar
Test if target matches the indicated
pattern.
switch statement
or expression
switch (effect) {
case Delay d ->
}
Test if target matches one (or more)
of the indicated patterns.
bind statement __let Reverb(var name, var
roomSize) = reverb;
Destructure a target using a pattern.
#DWX22 #PatternMatching @hannotify @PeterWessels
Wrap-up
Wrap-up
Wrap-up
Wrap-up
Wrap-up
https://pxhere.com/en/photo/752901
#DWX22 #PatternMatching @hannotify @PeterWessels
Pattern matching...
Pattern matching...
is a rich feature arc that will play out over several versions.
allows us to use type patterns in instanceof.
improves switch expressions.
makes destructuring objects as easy as (and more similar to)
constructing them.
holds the potential to simplify and streamline much of the code
we write today.
#DWX22 #PatternMatching @hannotify @PeterWessels
Major Feature
Major Feature
Major Feature
Major Feature
Major Feature
#DWX22 #PatternMatching @hannotify @PeterWessels
Thank you! 😀
Thank you! 😀
github.com/hannotify/pattern-
matching-music-store
hanno.codes peterwessels.nl
@hannotify @PeterWessels

More Related Content

More from 🎤 Hanno Embregts 🎸

"Will Git Be Around Forever? A List of Possible Successors" from FrontMania 2022
"Will Git Be Around Forever? A List of Possible Successors" from FrontMania 2022"Will Git Be Around Forever? A List of Possible Successors" from FrontMania 2022
"Will Git Be Around Forever? A List of Possible Successors" from FrontMania 2022🎤 Hanno Embregts 🎸
 
JCON 2021 talk - "Wil Git Be Around Forever? A List of Possible Successors"
JCON 2021 talk - "Wil Git Be Around Forever? A List of Possible Successors"JCON 2021 talk - "Wil Git Be Around Forever? A List of Possible Successors"
JCON 2021 talk - "Wil Git Be Around Forever? A List of Possible Successors"🎤 Hanno Embregts 🎸
 
"Will Git Be Around Forever? A List of Possible Successors" at UtrechtJUG
"Will Git Be Around Forever? A List of Possible Successors" at UtrechtJUG"Will Git Be Around Forever? A List of Possible Successors" at UtrechtJUG
"Will Git Be Around Forever? A List of Possible Successors" at UtrechtJUG🎤 Hanno Embregts 🎸
 
Entering the Fourth Dimension of OCR with Tesseract
Entering the Fourth Dimension of OCR with TesseractEntering the Fourth Dimension of OCR with Tesseract
Entering the Fourth Dimension of OCR with Tesseract🎤 Hanno Embregts 🎸
 
The Soft Side of Software Development / Devoxx 2019
The Soft Side of Software Development / Devoxx 2019The Soft Side of Software Development / Devoxx 2019
The Soft Side of Software Development / Devoxx 2019🎤 Hanno Embregts 🎸
 
Beware of Survivorship Bias! (conference talk at J-Fall 2019)
Beware of Survivorship Bias! (conference talk at J-Fall 2019)Beware of Survivorship Bias! (conference talk at J-Fall 2019)
Beware of Survivorship Bias! (conference talk at J-Fall 2019)🎤 Hanno Embregts 🎸
 
Will Git Be Around Forever? A List of Possible Successors
Will Git Be Around Forever? A List of Possible SuccessorsWill Git Be Around Forever? A List of Possible Successors
Will Git Be Around Forever? A List of Possible Successors🎤 Hanno Embregts 🎸
 
Entering the Fourth Dimension of OCR with Tesseract - Talk from Voxxed Days B...
Entering the Fourth Dimension of OCR with Tesseract - Talk from Voxxed Days B...Entering the Fourth Dimension of OCR with Tesseract - Talk from Voxxed Days B...
Entering the Fourth Dimension of OCR with Tesseract - Talk from Voxxed Days B...🎤 Hanno Embregts 🎸
 
QWERTY or DVORAK? Debunking the Keyboard Layout Myths -- from GeeCON 2018
QWERTY or DVORAK? Debunking the Keyboard Layout Myths -- from GeeCON 2018QWERTY or DVORAK? Debunking the Keyboard Layout Myths -- from GeeCON 2018
QWERTY or DVORAK? Debunking the Keyboard Layout Myths -- from GeeCON 2018🎤 Hanno Embregts 🎸
 
Building a Spring Boot 2 Application - Ask the Audience! (from Voxxed Days Vi...
Building a Spring Boot 2 Application - Ask the Audience! (from Voxxed Days Vi...Building a Spring Boot 2 Application - Ask the Audience! (from Voxxed Days Vi...
Building a Spring Boot 2 Application - Ask the Audience! (from Voxxed Days Vi...🎤 Hanno Embregts 🎸
 
Building a Spring Boot Application - Ask the Audience! (from JVMCon 2018)
Building a Spring Boot Application - Ask the Audience! (from JVMCon 2018)Building a Spring Boot Application - Ask the Audience! (from JVMCon 2018)
Building a Spring Boot Application - Ask the Audience! (from JVMCon 2018)🎤 Hanno Embregts 🎸
 
Building a Spring Boot Application - Ask the Audience!
Building a Spring Boot Application - Ask the Audience!Building a Spring Boot Application - Ask the Audience!
Building a Spring Boot Application - Ask the Audience!🎤 Hanno Embregts 🎸
 
QWERTY or DVORAK? Debunking the Keyboard Layout Myths
QWERTY or DVORAK? Debunking the Keyboard Layout MythsQWERTY or DVORAK? Debunking the Keyboard Layout Myths
QWERTY or DVORAK? Debunking the Keyboard Layout Myths🎤 Hanno Embregts 🎸
 
Building a Spring Boot Application - Ask the Audience! (from JavaLand 2017)
Building a Spring Boot Application - Ask the Audience!  (from JavaLand 2017)Building a Spring Boot Application - Ask the Audience!  (from JavaLand 2017)
Building a Spring Boot Application - Ask the Audience! (from JavaLand 2017)🎤 Hanno Embregts 🎸
 
Migrating 25K lines of Ant scripting to Gradle
Migrating 25K lines of Ant scripting to GradleMigrating 25K lines of Ant scripting to Gradle
Migrating 25K lines of Ant scripting to Gradle🎤 Hanno Embregts 🎸
 

More from 🎤 Hanno Embregts 🎸 (15)

"Will Git Be Around Forever? A List of Possible Successors" from FrontMania 2022
"Will Git Be Around Forever? A List of Possible Successors" from FrontMania 2022"Will Git Be Around Forever? A List of Possible Successors" from FrontMania 2022
"Will Git Be Around Forever? A List of Possible Successors" from FrontMania 2022
 
JCON 2021 talk - "Wil Git Be Around Forever? A List of Possible Successors"
JCON 2021 talk - "Wil Git Be Around Forever? A List of Possible Successors"JCON 2021 talk - "Wil Git Be Around Forever? A List of Possible Successors"
JCON 2021 talk - "Wil Git Be Around Forever? A List of Possible Successors"
 
"Will Git Be Around Forever? A List of Possible Successors" at UtrechtJUG
"Will Git Be Around Forever? A List of Possible Successors" at UtrechtJUG"Will Git Be Around Forever? A List of Possible Successors" at UtrechtJUG
"Will Git Be Around Forever? A List of Possible Successors" at UtrechtJUG
 
Entering the Fourth Dimension of OCR with Tesseract
Entering the Fourth Dimension of OCR with TesseractEntering the Fourth Dimension of OCR with Tesseract
Entering the Fourth Dimension of OCR with Tesseract
 
The Soft Side of Software Development / Devoxx 2019
The Soft Side of Software Development / Devoxx 2019The Soft Side of Software Development / Devoxx 2019
The Soft Side of Software Development / Devoxx 2019
 
Beware of Survivorship Bias! (conference talk at J-Fall 2019)
Beware of Survivorship Bias! (conference talk at J-Fall 2019)Beware of Survivorship Bias! (conference talk at J-Fall 2019)
Beware of Survivorship Bias! (conference talk at J-Fall 2019)
 
Will Git Be Around Forever? A List of Possible Successors
Will Git Be Around Forever? A List of Possible SuccessorsWill Git Be Around Forever? A List of Possible Successors
Will Git Be Around Forever? A List of Possible Successors
 
Entering the Fourth Dimension of OCR with Tesseract - Talk from Voxxed Days B...
Entering the Fourth Dimension of OCR with Tesseract - Talk from Voxxed Days B...Entering the Fourth Dimension of OCR with Tesseract - Talk from Voxxed Days B...
Entering the Fourth Dimension of OCR with Tesseract - Talk from Voxxed Days B...
 
QWERTY or DVORAK? Debunking the Keyboard Layout Myths -- from GeeCON 2018
QWERTY or DVORAK? Debunking the Keyboard Layout Myths -- from GeeCON 2018QWERTY or DVORAK? Debunking the Keyboard Layout Myths -- from GeeCON 2018
QWERTY or DVORAK? Debunking the Keyboard Layout Myths -- from GeeCON 2018
 
Building a Spring Boot 2 Application - Ask the Audience! (from Voxxed Days Vi...
Building a Spring Boot 2 Application - Ask the Audience! (from Voxxed Days Vi...Building a Spring Boot 2 Application - Ask the Audience! (from Voxxed Days Vi...
Building a Spring Boot 2 Application - Ask the Audience! (from Voxxed Days Vi...
 
Building a Spring Boot Application - Ask the Audience! (from JVMCon 2018)
Building a Spring Boot Application - Ask the Audience! (from JVMCon 2018)Building a Spring Boot Application - Ask the Audience! (from JVMCon 2018)
Building a Spring Boot Application - Ask the Audience! (from JVMCon 2018)
 
Building a Spring Boot Application - Ask the Audience!
Building a Spring Boot Application - Ask the Audience!Building a Spring Boot Application - Ask the Audience!
Building a Spring Boot Application - Ask the Audience!
 
QWERTY or DVORAK? Debunking the Keyboard Layout Myths
QWERTY or DVORAK? Debunking the Keyboard Layout MythsQWERTY or DVORAK? Debunking the Keyboard Layout Myths
QWERTY or DVORAK? Debunking the Keyboard Layout Myths
 
Building a Spring Boot Application - Ask the Audience! (from JavaLand 2017)
Building a Spring Boot Application - Ask the Audience!  (from JavaLand 2017)Building a Spring Boot Application - Ask the Audience!  (from JavaLand 2017)
Building a Spring Boot Application - Ask the Audience! (from JavaLand 2017)
 
Migrating 25K lines of Ant scripting to Gradle
Migrating 25K lines of Ant scripting to GradleMigrating 25K lines of Ant scripting to Gradle
Migrating 25K lines of Ant scripting to Gradle
 

Recently uploaded

Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesŁukasz Chruściel
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtimeandrehoraa
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作qr0udbr0
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...OnePlan Solutions
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmSujith Sukumaran
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024StefanoLambiase
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...Christina Lin
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfStefano Stabellini
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanyChristoph Pohl
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEOrtus Solutions, Corp
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureDinusha Kumarasiri
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideChristina Lin
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsAhmed Mohamed
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaHanief Utama
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfLivetecs LLC
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...Technogeeks
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...soniya singh
 
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in NoidaBuds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in Noidabntitsolutionsrishis
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odishasmiwainfosol
 

Recently uploaded (20)

Unveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New FeaturesUnveiling the Future: Sylius 2.0 New Features
Unveiling the Future: Sylius 2.0 New Features
 
SpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at RuntimeSpotFlow: Tracking Method Calls and States at Runtime
SpotFlow: Tracking Method Calls and States at Runtime
 
英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作英国UN学位证,北安普顿大学毕业证书1:1制作
英国UN学位证,北安普顿大学毕业证书1:1制作
 
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
Maximizing Efficiency and Profitability with OnePlan’s Professional Service A...
 
Intelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalmIntelligent Home Wi-Fi Solutions | ThinkPalm
Intelligent Home Wi-Fi Solutions | ThinkPalm
 
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
Dealing with Cultural Dispersion — Stefano Lambiase — ICSE-SEIS 2024
 
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
ODSC - Batch to Stream workshop - integration of Apache Spark, Cassandra, Pos...
 
Xen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdfXen Safety Embedded OSS Summit April 2024 v4.pdf
Xen Safety Embedded OSS Summit April 2024 v4.pdf
 
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte GermanySuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
SuccessFactors 1H 2024 Release - Sneak-Peek by Deloitte Germany
 
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASEBATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
BATTLEFIELD ORM: TIPS, TACTICS AND STRATEGIES FOR CONQUERING YOUR DATABASE
 
Implementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with AzureImplementing Zero Trust strategy with Azure
Implementing Zero Trust strategy with Azure
 
2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva2.pdf Ejercicios de programación competitiva
2.pdf Ejercicios de programación competitiva
 
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop SlideBuilding Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
Building Real-Time Data Pipelines: Stream & Batch Processing workshop Slide
 
Unveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML DiagramsUnveiling Design Patterns: A Visual Guide with UML Diagrams
Unveiling Design Patterns: A Visual Guide with UML Diagrams
 
React Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief UtamaReact Server Component in Next.js by Hanief Utama
React Server Component in Next.js by Hanief Utama
 
How to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdfHow to Track Employee Performance A Comprehensive Guide.pdf
How to Track Employee Performance A Comprehensive Guide.pdf
 
What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...What is Advanced Excel and what are some best practices for designing and cre...
What is Advanced Excel and what are some best practices for designing and cre...
 
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
Russian Call Girls in Karol Bagh Aasnvi ➡️ 8264348440 💋📞 Independent Escort S...
 
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in NoidaBuds n Tech IT Solutions: Top-Notch Web Services in Noida
Buds n Tech IT Solutions: Top-Notch Web Services in Noida
 
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company OdishaBalasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
Balasore Best It Company|| Top 10 IT Company || Balasore Software company Odisha
 

Pattern Matching - Small Enhancement or Major Feature? from Developer Week 202

  • 1. #DWX22 #PatternMatching @hannotify @PeterWessels Pattern Pattern Pattern Pattern Pattern Pattern Pattern Pattern Pattern Pattern Pattern Pattern Matching Matching Matching Matching Matching Matching Matching Matching Matching Matching Matching Matching Small Enhancement or Major Feature? Small Enhancement or Major Feature? Hanno Embregts Peter Wessels @hannotify @PeterWessels
  • 4. #DWX22 #PatternMatching @hannotify @PeterWessels Small Enhancement Small Enhancement Small Enhancement Small Enhancement Small Enhancement https://gph.is/g/ZPJNoPQ
  • 5. #DWX22 #PatternMatching @hannotify @PeterWessels Major Feature Major Feature Major Feature Major Feature Major Feature https://thumbs.gfycat.com/DefiantElasticGadwall.webp
  • 6. #DWX22 #PatternMatching @hannotify @PeterWessels Pattern Pattern Pattern Pattern Pattern Matching for Matching for Matching for Matching for Matching for instanceof instanceof instanceof instanceof instanceof https://pxhere.com/en/photo/752901
  • 7. #DWX22 #PatternMatching @hannotify @PeterWessels https://pxhere.com/en/photo/548063
  • 8. #DWX22 #PatternMatching @hannotify @PeterWessels Instanceof-and-cast Instanceof-and-cast if (product instanceof Guitar) { Guitar lesPaul = (Guitar) product; // use lesPaul } 1 2 3 4 5
  • 9. #DWX22 #PatternMatching @hannotify @PeterWessels Instanceof-and-cast Instanceof-and-cast if (product instanceof Guitar) { // 1. is product a Guitar? 1 Guitar lesPaul = 2 (Guitar) product; 3 // use lesPaul 4 } 5
  • 10. #DWX22 #PatternMatching @hannotify @PeterWessels Instanceof-and-cast Instanceof-and-cast (Guitar) product; // 2. perform conversion if (product instanceof Guitar) { // 1. is product a Guitar? 1 Guitar lesPaul = 2 3 // use lesPaul 4 } 5
  • 11. #DWX22 #PatternMatching @hannotify @PeterWessels Instanceof-and-cast Instanceof-and-cast Guitar lesPaul = // 3. declare variable, bind value if (product instanceof Guitar) { // 1. is product a Guitar? 1 2 (Guitar) product; // 2. perform conversion 3 // use lesPaul 4 } 5
  • 12. #DWX22 #PatternMatching @hannotify @PeterWessels Improve the situation Improve the situation if (product instanceof Guitar) { // 1. is product a Guitar? Guitar lesPaul = // 3. declare variable, bind value (Guitar) product; // 2. perform conversion // use lesPaul } 1 2 3 4 5
  • 13. #DWX22 #PatternMatching @hannotify @PeterWessels Improve the situation Improve the situation if (product instanceof Guitar lesPaul) { 1 2 // use lesPaul 3 }
  • 14. #DWX22 #PatternMatching @hannotify @PeterWessels Type pattern Type pattern Type pattern Type pattern Type pattern Consists of a predicate that specifies a type, along with a single binding variable. https://www.pexels.com/photo/person-holding-white-chalk-625219/
  • 15. #DWX22 #PatternMatching @hannotify @PeterWessels Pattern matching Pattern matching Pattern matching Pattern matching Pattern matching Allows the conditional extraction of components from objects to be expressed more concisely and safely. https://www.pexels.com/photo/person-holding-white-chalk-625219/
  • 16. #DWX22 #PatternMatching @hannotify @PeterWessels Demo Demo Simplify implementation of equals https://pxhere.com/en/photo/1458897
  • 17. #DWX22 #PatternMatching @hannotify @PeterWessels Declaring 'in the middle' Declaring 'in the middle' if (product instanceof Guitar lesPaul) { // use lesPaul } 1 2 3
  • 18. #DWX22 #PatternMatching @hannotify @PeterWessels Scoping Scoping Pattern binding variable ('flow scoping') Pattern binding variable ('flow scoping') The set of places where it would definitely be assigned. if (product instanceof Guitar lesPaul && lesPaul.isInTune()) { // can use lesPaul here } else { // can't use lesPaul here } 1 2 3 4 5
  • 19. #DWX22 #PatternMatching @hannotify @PeterWessels Benefits Benefits Nearly 100% of casts will just disappear! More concise
  • 20. #DWX22 #PatternMatching @hannotify @PeterWessels It's a kind of Pattern It's a kind of Pattern It's a kind of Pattern It's a kind of Pattern It's a kind of Pattern pattern example type pattern Guitar lesPaul https://thumbs.gfycat.com/DefiantElasticGadwall.webp
  • 21. #DWX22 #PatternMatching @hannotify @PeterWessels Feature Status Feature Status Type Patterns Type Patterns Java version Feature status JEP 14 Preview 15 Second preview 16 Final JEP 305 JEP 375 JEP 394
  • 22. #DWX22 #PatternMatching @hannotify @PeterWessels Pattern Pattern Pattern Pattern Pattern Matching for Matching for Matching for Matching for Matching for switch switch switch switch switch https://pxhere.com/en/photo/752901
  • 23. #DWX22 #PatternMatching @hannotify @PeterWessels https://pxhere.com/en/photo/548063
  • 24. #DWX22 #PatternMatching @hannotify @PeterWessels https://pxhere.com/en/photo/544037
  • 25. #DWX22 #PatternMatching @hannotify @PeterWessels https://pxhere.com/en/photo/544037
  • 26. #DWX22 #PatternMatching @hannotify @PeterWessels String apply(Effect effect) { String formatted = ""; if (effect instanceof Delay) { Delay de = (Delay) effect; formatted = String.format("Delay active of %d ms.", de.getTimeInMs()); } else if (effect instanceof Reverb) { Reverb re = (Reverb) effect; formatted = String.format("Reverb active of type %s and roomSize %d.", re.getName( } else if (effect instanceof Overdrive) { Overdrive ov = (Overdrive) effect; formatted = String.format("Overdrive active with gain %d.", ov.getGain()); } else if (effect instanceof Tremolo) { Tremolo tr = (Tremolo) effect; formatted = String.format("Tremolo active with depth %d and rate %d.", tr.getDepth } else if (effect instanceof Tuner) { Tuner tu = (Tuner) effect; 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
  • 27. #DWX22 #PatternMatching @hannotify @PeterWessels g ( yp , g ( formatted = String.format("Overdrive active with gain %d.", ov.getGain()); formatted = String.format("Tremolo active with depth %d and rate %d.", tr.getDepth formatted = String.format("Tuner active with pitch %d. Muting all signal!", tu.get formatted = el.getEffects().stream().map(this::apply).collect(Collectors.joining(S formatted = String.format("Unknown effect active: %s.", effect); } else if (effect instanceof Overdrive) { 9 Overdrive ov = (Overdrive) effect; 10 11 } else if (effect instanceof Tremolo) { 12 Tremolo tr = (Tremolo) effect; 13 14 } else if (effect instanceof Tuner) { 15 Tuner tu = (Tuner) effect; 16 17 } else if (effect instanceof EffectLoop) { 18 EffectLoop el = (EffectLoop) effect; 19 20 } else { 21 22 } 23
  • 28. #DWX22 #PatternMatching @hannotify @PeterWessels String apply(Effect effect) { String formatted = ""; if (effect instanceof Delay de) { } else if (effect instanceof Reverb re) { } else if (effect instanceof Overdrive ov) { } else if (effect instanceof Tremolo tr) { } else if (effect instanceof Tuner tu) { } else if (effect instanceof EffectLoop el) { 1 2 3 4 formatted = String.format("Delay active of %d ms.", de.getTimeInMs()); 5 6 formatted = String.format("Reverb active of type %s and roomSize %d.", re.getName( 7 8 formatted = String.format("Overdrive active with gain %d.", ov.getGain()); 9 10 formatted = String.format("Tremolo active with depth %d and rate %d.", tr.getDepth 11 12 formatted = String.format("Tuner active with pitch %d. Muting all signal!", tu.get 13 14 formatted = el.getEffects().stream().map(this::apply).collect(Collectors.joining(S 15 } else { 16 formatted = String format("Unknown effect active: %s " effect);
  • 29. #DWX22 #PatternMatching @hannotify @PeterWessels formatted = String.format( Delay active of %d ms. , de.getTimeInMs()); formatted = String.format("Reverb active of type %s and roomSize %d.", re.getName( formatted = String.format("Overdrive active with gain %d.", ov.getGain()); formatted = String.format("Tremolo active with depth %d and rate %d.", tr.getDepth formatted = String.format("Tuner active with pitch %d. Muting all signal!", tu.get formatted = el.getEffects().stream().map(this::apply).collect(Collectors.joining(S formatted = String.format("Unknown effect active: %s.", effect); 4 } else if (effect instanceof Reverb re) { 5 6 } else if (effect instanceof Overdrive ov) { 7 8 } else if (effect instanceof Tremolo tr) { 9 10 } else if (effect instanceof Tuner tu) { 11 12 } else if (effect instanceof EffectLoop el) { 13 14 } else { 15 16 } 17 return formatted; 18 } 19
  • 30. #DWX22 #PatternMatching @hannotify @PeterWessels Switch expression Switch expression 1 String apply(Effect effect) { 2 return switch(effect) { 3 default -> String.format("Unknown effect active: %s.", effect); 4 }; 5 }
  • 31. #DWX22 #PatternMatching @hannotify @PeterWessels Switch expression Switch expression case Delay de -> String.format("Delay active of %d ms.", de.getTimeInMs()); case Reverb re -> String.format("Reverb active of type %s and roomSize %d.", re String apply(Effect effect) { 1 return switch(effect) { 2 3 4 5 default -> String.format("Unknown effect active: %s.", effect); 6 }; 7 }
  • 32. #DWX22 #PatternMatching @hannotify @PeterWessels Switch expression Switch expression 1 String apply(Effect effect) { 2 return switch(effect) { 3 case Delay de -> String.format("Delay active of %d ms.", de.getTimeInMs()); 4 case Reverb re -> String.format("Reverb active of type %s and roomSize %d.", r 5 case Overdrive ov -> String.format("Overdrive active with gain %d.", ov.getGain() 6 case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", t 7 case Tuner tu -> String.format("Tuner active with pitch %d. Muting all signal 8 default -> String.format("Unknown effect active: %s.", effect); 9 }; 10 }
  • 33. #DWX22 #PatternMatching @hannotify @PeterWessels Switch expression Switch expression case EffectLoop el -> el.getEffects().stream().map(this::apply).collect(Collectors String apply(Effect effect) { 1 return switch(effect) { 2 case Delay de -> String.format("Delay active of %d ms.", de.getTimeInMs()); 3 case Reverb re -> String.format("Reverb active of type %s and roomSize %d.", r 4 case Overdrive ov -> String.format("Overdrive active with gain %d.", ov.getGain() 5 case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", t 6 case Tuner tu -> String.format("Tuner active with pitch %d. Muting all signal 7 8 9 default -> String.format("Unknown effect active: %s.", effect); 10 }; 11 }
  • 34. #DWX22 #PatternMatching @hannotify @PeterWessels Switch expression Switch expression String apply(Effect effect) { return switch(effect) { case Delay de -> String.format("Delay active of %d ms.", de.getTimeInMs()); case Reverb re -> String.format("Reverb active of type %s and roomSize %d.", r case Overdrive ov -> String.format("Overdrive active with gain %d.", ov.getGain() case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", t case Tuner tu -> String.format("Tuner active with pitch %d. Muting all signal case EffectLoop el -> el.getEffects().stream().map(this::apply).collect(Collectors default -> String.format("Unknown effect active: %s.", effect); }; } 1 2 3 4 5 6 7 8 9 10 11
  • 35. #DWX22 #PatternMatching @hannotify @PeterWessels https://pxhere.com/en/photo/544037
  • 36. #DWX22 #PatternMatching @hannotify @PeterWessels Sensible operations to the effect loop Sensible operations to the effect loop apply() setVolume(int volume) contains(Effect... effect)
  • 37. #DWX22 #PatternMatching @hannotify @PeterWessels Nonsensical operations to the effect Nonsensical operations to the effect loop loop isTunerActive() isDelayTimeEqualToReverbRoomSize() isToneSuitableToPlayPrideInTheNameOfLove()
  • 38. #DWX22 #PatternMatching @hannotify @PeterWessels Switch expression Switch expression String apply(Effect effect) { return switch(effect) { case Delay de -> String.format("Delay active of %d ms.", de.getTimeInMs()); case Reverb re -> String.format("Reverb active of type %s and roomSize %d.", r case Overdrive ov -> String.format("Overdrive active with gain %d.", ov.getGain() case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", t case Tuner tu -> String.format("Tuner active with pitch %d. Muting all signal case EffectLoop el -> el.getEffects().stream().map(this::apply).collect(Collectors default -> String.format("Unknown effect active: %s.", effect); }; } 1 2 3 4 5 6 7 8 9 10 11
  • 39. #DWX22 #PatternMatching @hannotify @PeterWessels Switch expression Switch expression static String apply(Effect effect) { return switch(effect) { case Delay de -> String.format("Delay active of %d ms.", de.getTimeInMs()); case Reverb re -> String.format("Reverb active of type %s and roomSize %d.", r case Overdrive ov -> String.format("Overdrive active with gain %d.", ov.getGain() case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", t case Tuner tu -> String.format("Tuner active with pitch %d. Muting all signal case EffectLoop el -> el.getEffects().stream().map(Effect::apply).collect(Collecto default -> String.format("Unknown effect active: %s.", effect); }; } 1 2 3 4 5 6 7 8 9 10 11
  • 40. #DWX22 #PatternMatching @hannotify @PeterWessels Benefits of pattern matching Benefits of pattern matching No need for the Visitor pattern or a common supertype A single expression instead of many assignments Less error-prone (in adding cases) More concise Safer - the compiler can check for missing cases
  • 41. #DWX22 #PatternMatching @hannotify @PeterWessels But what if But what if effect effect is is null null? ? return switch(effect) { // throws NullPointerException! static String apply(Effect effect) { 1 2 case Delay de -> String.format("Delay active of %d ms.", de.getTimeInMs()); 3 case Reverb re -> String.format("Reverb active of type %s and roomSize %d.", r 4 case Overdrive ov -> String.format("Overdrive active with gain %d.", ov.getGain() 5 case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", t 6 case Tuner tu -> String.format("Tuner active with pitch %d. Muting all signal 7 case EffectLoop el -> el.getEffects().stream().map(Effect::apply).collect(Collecto 8 default -> String.format("Unknown effect active: %s.", effect); 9 }; 10 } 11
  • 42. #DWX22 #PatternMatching @hannotify @PeterWessels Combining case labels Combining case labels case null, default -> String.format("Unknown or malfunctioning effect active: %s." static String apply(Effect effect) { 1 return switch(effect) { 2 case Delay de -> String.format("Delay active of %d ms.", de.getTimeInMs()); 3 case Reverb re -> String.format("Reverb active of type %s and roomSize %d.", r 4 case Overdrive ov -> String.format("Overdrive active with gain %d.", ov.getGain() 5 case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", t 6 case Tuner tu -> String.format("Tuner active with pitch %d. Muting all signal 7 case EffectLoop el -> el.getEffects().stream().map(Effect::apply).collect(Collecto 8 9 }; 10 } 11
  • 43. #DWX22 #PatternMatching @hannotify @PeterWessels Demo Demo Guarded patterns https://pxhere.com/en/photo/1458897
  • 44. #DWX22 #PatternMatching @hannotify @PeterWessels Guarded patterns Guarded patterns String apply(Effect effect, Guitar guitar) { return switch(effect) { // (...) case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", tr.ge case Tuner tu -> String.format("Tuner active with pitch %d. Muting all signal!", tu case EffectLoop el -> el.getEffects().stream().map(this::apply).collect(Collectors. default -> String.format("Unknown effect active: %s.", effect); }; } 1 2 3 4 5 6 7 8 9
  • 45. #DWX22 #PatternMatching @hannotify @PeterWessels Guarded patterns Guarded patterns case Tuner tu && !tu.isInTune(guitar) -> String.format("Guitar is in need of tuning String apply(Effect effect, Guitar guitar) { 1 return switch(effect) { 2 // (...) 3 case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", tr.ge 4 5 case EffectLoop el -> el.getEffects().stream().map(this::apply).collect(Collectors. 6 default -> String.format("Unknown effect active: %s.", effect); 7 }; 8 } 9
  • 46. #DWX22 #PatternMatching @hannotify @PeterWessels Guarded patterns Guarded patterns case Tuner tu when !tu.isInTune(guitar) -> String.format("Guitar is in need of tuni String apply(Effect effect, Guitar guitar) { 1 return switch(effect) { 2 // (...) 3 case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", tr.ge 4 5 case EffectLoop el -> el.getEffects().stream().map(this::apply).collect(Collectors. 6 default -> String.format("Unknown effect active: %s.", effect); 7 }; 8 } 9
  • 47. #DWX22 #PatternMatching @hannotify @PeterWessels Guarded patterns Guarded patterns switch(effect) { // ... case Tuner tu: if (!tu.isInTune(guitar)) { // tuning is needed } else { // no tuning is needed } break; // ... } 1 2 3 4 5 6 7 8
  • 48. #DWX22 #PatternMatching @hannotify @PeterWessels It's a kind of Pattern It's a kind of Pattern It's a kind of Pattern It's a kind of Pattern It's a kind of Pattern pattern example guarded pattern Tuner tu when !tu.isInTune(guitar) type pattern Guitar lesPaul https://thumbs.gfycat.com/DefiantElasticGadwall.webp
  • 49. #DWX22 #PatternMatching @hannotify @PeterWessels Feature Status Feature Status Guarded Patterns Guarded Patterns Java version Feature status JEP 17 Preview 18 Second preview 19 Third preview JEP 406 JEP 420 JEP 427
  • 50. #DWX22 #PatternMatching @hannotify @PeterWessels Deconstruction Deconstruction Deconstruction Deconstruction Deconstruction Patterns Patterns Patterns Patterns Patterns https://pxhere.com/en/photo/752901
  • 51. #DWX22 #PatternMatching @hannotify @PeterWessels Disclaimer Disclaimer Disclaimer Disclaimer Disclaimer We can't tell you when the following features are coming to Java. Also: syntax and implementation specifics may still change. https://pxhere.com/en/photo/1359311
  • 52. #DWX22 #PatternMatching @hannotify @PeterWessels Deconstruction patterns Deconstruction patterns String apply(Effect effect) { return switch(effect) { case Delay de -> String.format("Delay active of %d ms.", de.getTimeInMs()); case Reverb re -> String.format("Reverb active of type %s and roomSize %d.", r case Overdrive ov -> String.format("Overdrive active with gain %d.", ov.getGain() case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", t case Tuner tu -> String.format("Tuner active with pitch %d. Muting all signal case EffectLoop el -> el.getEffects().stream().map(this::apply).collect(Collectors default -> String.format("Unknown effect active: %s.", effect); }; } 1 2 3 4 5 6 7 8 9 10 11
  • 53. #DWX22 #PatternMatching @hannotify @PeterWessels Deconstruction patterns Deconstruction patterns case Overdrive(int gain) -> String.format("Overdrive active with gain %d.", gain); String apply(Effect effect) { 1 return switch(effect) { 2 case Delay de -> String.format("Delay active of %d ms.", de.getTimeInMs()); 3 case Reverb re -> String.format("Reverb active of type %s and roomSize %d.", r 4 5 case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", t 6 case Tuner tu -> String.format("Tuner active with pitch %d. Muting all signal 7 case EffectLoop el -> el.getEffects().stream().map(this::apply).collect(Collectors 8 default -> String.format("Unknown effect active: %s.", effect); 9 }; 10 } 11
  • 54. #DWX22 #PatternMatching @hannotify @PeterWessels Pattern definition Pattern definition public class Overdrive implements Effect { private final int gain; public Overdrive(int gain) { this.gain = gain; } } 1 2 3 4 5 6 7
  • 55. #DWX22 #PatternMatching @hannotify @PeterWessels Pattern definition Pattern definition 1 public class Overdrive implements Effect { 2 private final int gain; 3 4 public Overdrive(int gain) { 5 this.gain = gain; 6 } 7 public pattern Overdrive(int gain) { 8 gain = this.gain; 9 } 10 11 }
  • 56. #DWX22 #PatternMatching @hannotify @PeterWessels Deconstruction patterns Deconstruction patterns case Overdrive(int gain) -> String.format("Overdrive active with gain %d.", gain); String apply(Effect effect) { 1 return switch(effect) { 2 case Delay de -> String.format("Delay active of %d ms.", de.getTimeInMs()); 3 case Reverb re -> String.format("Reverb active of type %s and roomSize %d.", r 4 5 case Tremolo tr -> String.format("Tremolo active with depth %d and rate %d.", t 6 case Tuner tu -> String.format("Tuner active with pitch %d. Muting all signal 7 case EffectLoop el -> el.getEffects().stream().map(this::apply).collect(Collectors 8 default -> String.format("Unknown effect active: %s.", effect); 9 }; 10 } 11
  • 57. #DWX22 #PatternMatching @hannotify @PeterWessels Demo Demo Deconstruction with Records https://pxhere.com/en/photo/1458897
  • 58. #DWX22 #PatternMatching @hannotify @PeterWessels Deconstruction patterns Deconstruction patterns String apply(Effect effect) { return switch(effect) { case Delay(int timeInMs) -> String.format("Delay active of %d ms.", timeInMs); case Reverb(String name, int roomSize) -> String.format("Reverb active of type %s case Overdrive(int gain) -> String.format("Overdrive active with gain %d.", gain); case Tremolo(int depth, int rate) -> String.format("Tremolo active with depth %d a case Tuner(int pitchInHz) -> String.format("Tuner active with pitch %d. Muting all case EffectLoop(Set<Effect> effects) -> effects.stream().map(this::apply).collect( default -> String.format("Unknown effect active: %s.", effect); }; } 1 2 3 4 5 6 7 8 9 10 11
  • 59. #DWX22 #PatternMatching @hannotify @PeterWessels Can we combine patterns? Can we combine patterns? static boolean isDelayTimeEqualToReverbRoomSize(EffectLoop effectLoop) { } 1 2 3
  • 60. #DWX22 #PatternMatching @hannotify @PeterWessels Pattern composition Pattern composition static boolean isDelayTimeEqualToReverbRoomSize(EffectLoop effectLoop) { if (effectLoop instanceof EffectLoop(Delay(int timeInMs), Reverb(String name, int roomS return timeInMs == roomSize; 1 2 3 } 4 return false; 5 6 }
  • 61. #DWX22 #PatternMatching @hannotify @PeterWessels Pattern composition Pattern composition 1 static boolean isDelayTimeEqualToReverbRoomSize(EffectLoop effectLoop) { 2 return effectLoop.getEffects().stream() 3 .filter(e -> e instanceof Delay || e instanceof Reverb) 4 .map(dr -> { 5 if (dr instanceof Delay d) { 6 return d.getTimeInMs(); } else { 7 Reverb r = (Reverb) dr; 8 return r.getRoomSize(); 9 } 10 11 }).distinct().count() == 1; 12 13 }
  • 62. #DWX22 #PatternMatching @hannotify @PeterWessels It's a kind of Pattern It's a kind of Pattern It's a kind of Pattern It's a kind of Pattern It's a kind of Pattern pattern example deconstruction pattern Delay(int timeInMs) type pattern Guitar lesPaul guarded pattern Tuner tu when !tu.isInTune(guitar) https://thumbs.gfycat.com/DefiantElasticGadwall.webp
  • 63. #DWX22 #PatternMatching @hannotify @PeterWessels Var and any patterns Var and any patterns // Pre-Java 10 Guitar telecaster = new Guitar("Fender Telecaster Baritone Blacktop", GuitarType.TELECASTER // Java 10 var telecaster = new Guitar("Fender Telecaster Baritone Blacktop", GuitarType.TELECASTER); 1 2 3 4 5 https://openjdk.java.net/jeps/286 https://openjdk.java.net/jeps/286
  • 64. #DWX22 #PatternMatching @hannotify @PeterWessels Var and any patterns Var and any patterns static boolean isDelayTimeEqualToReverbRoomSize(EffectLoop effectLoop) { if (effectLoop instanceof EffectLoop(Delay(int timeInMs), Reverb(String name, int roomS return timeInMs == roomSize; } return false; } 1 2 3 4 5 6
  • 65. #DWX22 #PatternMatching @hannotify @PeterWessels Var and any patterns Var and any patterns if (effectLoop instanceof EffectLoop(Delay(var timeInMs), Reverb(var name, var roomSize static boolean isDelayTimeEqualToReverbRoomSize(EffectLoop effectLoop) { 1 2 return timeInMs == roomSize; 3 } 4 return false; 5 } 6
  • 66. #DWX22 #PatternMatching @hannotify @PeterWessels http://gph.is/2lFlHIK
  • 67. #DWX22 #PatternMatching @hannotify @PeterWessels Var and any patterns Var and any patterns static boolean isDelayTimeEqualToReverbRoomSize(EffectLoop effectLoop) { if (effectLoop instanceof EffectLoop(Delay(var timeInMs), Reverb(_, var roomSize))) { return timeInMs == roomSize; } return false; } 1 2 3 4 5 6
  • 68. #DWX22 #PatternMatching @hannotify @PeterWessels Optimization Optimization static String apply(Effect effect) { return switch(effect) { case Delay(int timeInMs) -> String.format("Delay active of %d ms.", timeInMs); case Reverb(String name, int roomSize) -> String.format("Reverb active of type %s case Overdrive(int gain) -> String.format("Overdrive active with gain %d.", gain); case Tremolo(int depth, int rate) -> String.format("Tremolo active with depth %d a case Tuner(int pitchInHz) -> String.format("Tuner active with pitch %d. Muting all case EffectLoop(var effects) -> effects.stream().map(Effect::apply).collect(Collec default -> String.format("Unknown effect active: %s.", effect); }; } 1 2 3 4 5 6 7 8 9 10 11
  • 69. #DWX22 #PatternMatching @hannotify @PeterWessels Optimization Optimization 1 static String apply(Effect effect) { 2 return switch(effect) { 3 // ... 4 case EffectLoop(var effects) -> effects.stream().map(Effect::apply).collect(Collect 5 default -> String.format("Unknown effect active: %s.", effect); 6 }; 7 }
  • 70. #DWX22 #PatternMatching @hannotify @PeterWessels Optimization Optimization case EffectLoop(Tuner(int pitchInHz), _) -> String.format("The EffectLoop contains static String apply(Effect effect) { 1 return switch(effect) { 2 // ... 3 4 5 case EffectLoop(var effects) -> effects.stream().map(Effect::apply).collect(Collect 6 default -> String.format("Unknown effect active: %s.", effect); 7 }; 8 }
  • 71. #DWX22 #PatternMatching @hannotify @PeterWessels Benefits Benefits Better encapsulation a case branch only receives data that it actually references. More elegant logic by using pattern composition Optimization through the use of any patterns
  • 72. #DWX22 #PatternMatching @hannotify @PeterWessels It's a kind of Pattern It's a kind of Pattern It's a kind of Pattern It's a kind of Pattern It's a kind of Pattern pattern example var pattern var timeInMs type pattern Guitar lesPaul guarded pattern Tuner tu when !tu.isInTune(guitar) deconstruction pattern Delay(int timeInMs) https://thumbs.gfycat.com/DefiantElasticGadwall.webp
  • 73. #DWX22 #PatternMatching @hannotify @PeterWessels It's a kind of Pattern It's a kind of Pattern It's a kind of Pattern It's a kind of Pattern It's a kind of Pattern pattern example any pattern _ type pattern Guitar lesPaul guarded pattern Tuner tu when !tu.isInTune(guitar) deconstruction pattern Delay(int timeInMs) var pattern var timeInMs https://thumbs.gfycat.com/DefiantElasticGadwall.webp
  • 74. #DWX22 #PatternMatching @hannotify @PeterWessels Feature Status Feature Status Java version Feature status JEP 19 Preview (composition of record and type patterns only) JEP 405
  • 75. #DWX22 #PatternMatching @hannotify @PeterWessels Pattern Matching Plays Nice Pattern Matching Plays Nice With With Sealed Types Sealed Types Sealed Types Sealed Types Sealed Types and Records and Records and Records and Records and Records https://pxhere.com/en/photo/752901
  • 76. #DWX22 #PatternMatching @hannotify @PeterWessels Demo Demo Make Effect a sealed type https://pxhere.com/en/photo/1458897
  • 77. #DWX22 #PatternMatching @hannotify @PeterWessels Sealed types yield completeness Sealed types yield completeness static String apply(Effect effect) { return switch(effect) { case Delay(int timeInMs) -> String.format("Delay active of %d ms.", timeInMs); case Reverb(String name, int roomSize) -> String.format("Reverb active of type %s case Overdrive(int gain) -> String.format("Overdrive active with gain %d.", gain); case Tremolo(int depth, int rate) -> String.format("Tremolo active with depth %d a case Tuner(int pitchInHz) -> String.format("Tuner active with pitch %d. Muting all case EffectLoop(Tuner(int pitchInHz), _) -> String.format("The EffectLoop contains case EffectLoop(var effects) -> effects.stream().map(Effect::apply).collect(Collec default -> String.format("Unknown effect active: %s.", effect); }; } 1 2 3 4 5 6 7 8 9 10 11 12
  • 78. #DWX22 #PatternMatching @hannotify @PeterWessels Sealed types yield completeness Sealed types yield completeness static String apply(Effect effect) { return switch(effect) { case Delay(int timeInMs) -> String.format("Delay active of %d ms.", timeInMs); case Reverb(String name, int roomSize) -> String.format("Reverb active of type %s case Overdrive(int gain) -> String.format("Overdrive active with gain %d.", gain); case Tremolo(int depth, int rate) -> String.format("Tremolo active with depth %d a case Tuner(int pitchInHz) -> String.format("Tuner active with pitch %d. Muting all case EffectLoop(Tuner(int pitchInHz), _) -> String.format("The EffectLoop contains case EffectLoop(var effects) -> effects.stream().map(Effect::apply).collect(Collec 1 2 3 4 5 6 7 8 9 10 }; 11 } https://cr.openjdk.java.net/~briangoetz/amber/pattern-match.html
  • 79. #DWX22 #PatternMatching @hannotify @PeterWessels Records Records Input: Input: Commit to the class being a transparent carrier for its data. Output: Output: constructors accessor methods equals()-implementation hashCode()-implementation toString()-implementation deconstruction pattern
  • 80. #DWX22 #PatternMatching @hannotify @PeterWessels Array patterns Array patterns record EffectLoop(String name, int volume, Effect... effects) { } 1 static String apply(EffectLoop effectLoop) {} return switch(effectLoop) { case EffectLoop(var name, var volume) -> "Effect loop contains no effects."; } } 1 2 3 4 5
  • 81. #DWX22 #PatternMatching @hannotify @PeterWessels Array patterns Array patterns record EffectLoop(String name, int volume, Effect... effects) { } 1 static String apply(EffectLoop effectLoop) {} return switch(effectLoop) { case EffectLoop(var name, var volume) -> "Effect loop contains no effects."; case EffectLoop(_, _, var effect) -> "Effect loop contains exactly one effect."; 1 2 3 4 5 } 6 }
  • 82. #DWX22 #PatternMatching @hannotify @PeterWessels Array patterns Array patterns record EffectLoop(String name, int volume, Effect... effects) { } 1 static String apply(EffectLoop effectLoop) {} return switch(effectLoop) { case EffectLoop(var name, var volume) -> "Effect loop contains no effects."; case EffectLoop(_, _, var effect) -> "Effect loop contains exactly one effect."; case EffectLoop(_, _, var effect, ...) -> "Effect loop contains more than one effec 1 2 3 4 5 6 } 7 }
  • 83. #DWX22 #PatternMatching @hannotify @PeterWessels Array patterns Array patterns record EffectLoop(String name, int volume, Effect... effects) { } 1 static String apply(EffectLoop effectLoop) {} return switch(effectLoop) { case EffectLoop(var name, var volume) -> "Effect loop contains no effects."; case EffectLoop(_, _, var effect) -> "Effect loop contains exactly one effect."; case EffectLoop(_, _, var effect, ...) -> "Effect loop contains more than one effec case EffectLoop(_, _, var effect1, var effect2) -> "Effect loop contains exactly tw case EffectLoop(_, _, var effect1, var effect2, ...) -> "Effect loop contains more 1 2 3 4 5 6 7 8 } 9 }
  • 84. #DWX22 #PatternMatching @hannotify @PeterWessels It's a kind of Pattern It's a kind of Pattern It's a kind of Pattern It's a kind of Pattern It's a kind of Pattern pattern example array pattern EffectLoop(var name, var effect, ...) .. .. var pattern var timeInMs any pattern _ https://thumbs.gfycat.com/DefiantElasticGadwall.webp
  • 85. #DWX22 #PatternMatching @hannotify @PeterWessels Feature Status Feature Status Sealed Types Sealed Types Java version Feature status JEP 15 Preview 16 Second preview 17 Final JEP 360 JEP 397 JEP 409
  • 86. #DWX22 #PatternMatching @hannotify @PeterWessels Feature Status Feature Status Completeness Completeness Java version Feature status JEP 17 Preview 18 Second preview 19 Third preview JEP 406 JEP 420 JEP 427
  • 87. #DWX22 #PatternMatching @hannotify @PeterWessels Feature Status Feature Status Record Patterns Record Patterns Java version Feature status JEP 19 Preview JEP 405
  • 88. #DWX22 #PatternMatching @hannotify @PeterWessels A Better A Better A Better A Better A Better Serialization? Serialization? Serialization? Serialization? Serialization? https://pxhere.com/en/photo/752901
  • 89. #DWX22 #PatternMatching @hannotify @PeterWessels Here be dragons! Here be dragons! Here be dragons! Here be dragons! Here be dragons! We can't be sure at all that the following features will appear in Java as depicted. They can change a lot in the meantime. https://www.pexels.com/photo/dragon-festival-during-nighttime-6068535/
  • 90. #DWX22 #PatternMatching @hannotify @PeterWessels Opposites Opposites Deconstruction pattern Deconstruction pattern transforms an object into a set of typed fields Constructor Constructor transforms a set of typed fields into an object
  • 91. #DWX22 #PatternMatching @hannotify @PeterWessels Serialization Serialization very important feature but many people hate its current implementation Drawbacks Drawbacks it undermines the accessibility model serialization logic is not 'readable code' it bypasses constructors and data validation
  • 92. #DWX22 #PatternMatching @hannotify @PeterWessels Serialization Serialization public class EffectLoop implements Effect { private String name; private Set<Effect> effects; public EffectLoop(String name) { this.name = name; this.effects = new HashSet<>(); } } 1 2 3 4 5 6 7 8 9
  • 93. #DWX22 #PatternMatching @hannotify @PeterWessels Serialization Serialization 1 public class EffectLoop implements Effect { 2 private String name; 3 private Set<Effect> effects; 4 5 public EffectLoop(String name) { 6 this.name = name; 7 this.effects = new HashSet<>(); 8 } 9 public pattern EffectLoop(String name, Effect[] effects) { 10 name = this.name; 11 effects = this.effects.toArray(); 12 } 13 14 }
  • 94. #DWX22 #PatternMatching @hannotify @PeterWessels Serialization Serialization public EffectLoop(String name, Effect[] effects) { this(name); for (Effect effect : effects) { this.effects.add(effect); } this.name = name; 6 this.effects = new HashSet<>(); 7 } 8 9 10 11 12 13 14 15 } 16 17 public pattern EffectLoop(String name, Effect[] effects) { 18 name = this.name; 19 effects = this.effects.toArray(); } 20 21 }
  • 95. #DWX22 #PatternMatching @hannotify @PeterWessels Serialization Serialization public class EffectLoop implements Effect { private String name; private Set<Effect> effects; public EffectLoop(String name) { this.name = name; this.effects = new HashSet<>(); } @Deserializer 1 2 3 4 5 6 7 8 9 10 11 public EffectLoop(String name, Effect[] effects) { 12 this(name); 13 for (Effect effect : effects) { 14 this.effects.add(effect); 15 } 16 }
  • 96. #DWX22 #PatternMatching @hannotify @PeterWessels Some challenges remain Some challenges remain Q: Q: How to support multiple versions of one class? How to support multiple versions of one class? A: @Serializer and @Deserializer annotations could get a property version in the future.
  • 97. #DWX22 #PatternMatching @hannotify @PeterWessels Feature Status Feature Status Java version Feature status JEP n/a Exploratory document Towards Better Serialization https://cr.openjdk.java.net/~briangoetz/amber/serialization.html
  • 98. #DWX22 #PatternMatching @hannotify @PeterWessels Future Future Future Future Future Expansions Expansions Expansions Expansions Expansions https://pxhere.com/en/photo/752901
  • 99. #DWX22 #PatternMatching @hannotify @PeterWessels Here be super dragons! Here be super dragons! Here be super dragons! Here be super dragons! Here be super dragons! We can't be sure that the following features will appear in Java as depicted, if at all. Proceed with caution! https://www.pexels.com/photo/dragon-festival-during-nighttime-6068535/
  • 100. #DWX22 #PatternMatching @hannotify @PeterWessels Pattern bind statements Pattern bind statements var reverb = new Reverb("ChamberReverb", 2); __let Reverb(String name, int roomSize) = reverb; // do something with name & roomSize 1 2 3 4 5 https://cr.openjdk.java.net/~briangoetz/amber/pattern-match.html
  • 101. #DWX22 #PatternMatching @hannotify @PeterWessels Pattern bind statements Pattern bind statements else throw new IllegalArgumentException("not a Reverb!"); var reverb = new Reverb("ChamberReverb", 2); 1 2 __let Reverb(String name, int roomSize) = reverb; 3 4 5 6 // do something with name & roomSize
  • 102. #DWX22 #PatternMatching @hannotify @PeterWessels Other ideas Other ideas AND patterns: PatternOne&PatternTwo Patterns in catch clauses: (will most likely complement multi-catch blocks) Collection patterns https://mail.openjdk.java.net/pipermail/amber-spec-experts/2021-January/002758.html https://mail.openjdk.java.net/pipermail/amber-spec-experts/2021-January/002758.html
  • 103. #DWX22 #PatternMatching @hannotify @PeterWessels Pattern Pattern Pattern Pattern Pattern Contexts Contexts Contexts Contexts Contexts https://pxhere.com/en/photo/752901
  • 104. #DWX22 #PatternMatching @hannotify @PeterWessels Pattern Contexts Pattern Contexts Pattern context Example Purpose instanceof predicate product instanceof Guitar guitar Test if target matches the indicated pattern. switch statement or expression switch (effect) { case Delay d -> } Test if target matches one (or more) of the indicated patterns. bind statement __let Reverb(var name, var roomSize) = reverb; Destructure a target using a pattern.
  • 105. #DWX22 #PatternMatching @hannotify @PeterWessels Wrap-up Wrap-up Wrap-up Wrap-up Wrap-up https://pxhere.com/en/photo/752901
  • 106. #DWX22 #PatternMatching @hannotify @PeterWessels Pattern matching... Pattern matching... is a rich feature arc that will play out over several versions. allows us to use type patterns in instanceof. improves switch expressions. makes destructuring objects as easy as (and more similar to) constructing them. holds the potential to simplify and streamline much of the code we write today.
  • 107. #DWX22 #PatternMatching @hannotify @PeterWessels Major Feature Major Feature Major Feature Major Feature Major Feature
  • 108. #DWX22 #PatternMatching @hannotify @PeterWessels Thank you! 😀 Thank you! 😀 github.com/hannotify/pattern- matching-music-store hanno.codes peterwessels.nl @hannotify @PeterWessels