SlideShare a Scribd company logo
1 of 84
Belfast JUG
April 2014
About Me
Goals of this Talk…
Everything Depends on Context…
Some Thoughts from React
Some Thoughts from React 2014
 Architecture is back in fashion
 No more ‘just use the stack’ or ‘wait for speedup’
 Design so there is no bottleneck
 Be ready for the ‘Internet of Things’
 The same lessons apply at different levels
 Key concepts:
 Actors, Futures, Reactive Extensions (RX)
 Eventually consistent data storage
 Convergent replicated data types
 Coding becomes increasingly declarative
 Send code to data and ensure ‘data knows where to go’
A Metaphor…
Why Are We Still Using Rockets?
The Origins Of Rockets
The Killer-App for Rockets… 
Mutually Assured Destruction
The Commercial Payoff
Only Rockets Will Be Insured
From the late 1950's until the early 1980's, the ownership and operation of
satellites was generally undertaken only by government agencies like National
Aeronautics and Space Administration (NASA) and the European Space
Agency (ESA). While commercial satellite insurance has been available since
1964, very little was purchased until the mid 1980's because government
agencies generally self-insure the risk. Starting in the early 1980's, the
commercial satellite industry began to take off and with it came the increased
need for satellite insurance since commercial enterprises are not ordinarily
willing to self-insure such high valued assets that are subject to relatively high
loss frequencies. Market capacity soared in the 1990's, from around $300
million in 1990 to almost $1.2 billion in 1999, 3 well in excess of the $175 to
$250 million of coverage required for most satellites. Occasionally a satellite
may require as much as $400 million of coverage.
Estimating Satellite Insurance Liabilities
Allen J. Gould and Orin M. Linden
The Origins of Java
The Killer App for Java
The Law of the Server Farm
We Are Locked Into Java!!
What is the JVM Today?
What About .NET?
What About The Others…
 Ruby on Rails
 Node.js
 Django
 etc…
What About the Others?
You came close but you never made it. And if
you were gonna make it, you would have
made it before now…
The Perfect Language…
A Newsflash…
Object Orientation Works!!!
The Horsemen of the
Javapocalypse…
Inner
Classes
Non-Reified
Generics
Checked
Exceptions
Value
Types
The Road Not Taken…
The newest version of the Microsoft Visual J++ development environment supports a language
construct called delegates or bound method references…
It is unlikely that the Java programming language will ever include this construct. Sun
already carefully considered adopting it in 1996, to the extent of building and discarding
working prototypes. Our conclusion was that bound method references are unnecessary
and detrimental to the language…
We believe bound method references are unnecessary because another design alternative, inner
classes, provides equal or superior functionality. In particular, inner classes fully support the
requirements of user-interface event handling, and have been used to implement a user-interface
API at least as comprehensive as the Windows Foundation Classes.
We believe bound method references are harmful because they detract from the simplicity of the
Java programming language and the pervasively object-oriented character of the APIs….
Extracts From: About Microsoft’s “Delegates"
Whitepaper by the Java language team at JavaSoft
Our Industry Has Issues…
We Stayed!! (and fixed the bugs…)
Our Industry Has Issues…
Our Industry Has Issues…
Our Industry Has Issues…
The Proposition:
Work till 2 am for 20 years,
hunting bugs fuelled by cold
pizza and warm coke.
The Rewards:
Kudos from peers
Detach from ‘civilian’ life
Grow neckbeard
Present at QCon
Our Industry Has Issues…
The Solution…
Adopt
Agile!
(duh)
Agile Values
 Feedback cycles
 Working as a team
 Universal ownership
 Sustainable pace
 Asking for assistance
 Clear prioritization
 Retrospectives
 No prima-donnas
That he which hath no stomach to this fight,
Let him depart; his passport shall be made,
And crowns for convoy put into his purse;
We would not die in that man's company
...
From this day to the ending of the world,
But we in it shall be remembered-
We few, we happy few, we band of brothers;
The Challenge
A Solution? Add FP to Java???
The Solution
public class Program {
public static void main(String [] args) {
List<Integer> input = Arrays.asList(30,26,22,18,14,10);
input.stream()
.parallel()
.map(Program::waitAndReturn)
.forEach(System.out::println);
}
private static String waitAndReturn(Integer sleep) {
goToSleep(sleep);
return buildMessage(sleep);
}
The Solution
private static void goToSleep(Integer sleep) {
try {
Thread.sleep(sleep * 1000);
} catch (InterruptedException ex) {
System.out.println("BANG! " + ex.getMessage());
}
}
private static String buildMessage(Integer sleep) {
String msg = "Thread %d just returned after waiting %d secs";
long threadId = Thread.currentThread().getId();
return String.format(msg, threadId, sleep);
}
}
The Solution
Thread 11 just returned after waiting 10 secs
Thread 13 just returned after waiting 14 secs
Thread 1 just returned after waiting 18 secs
Thread 14 just returned after waiting 22 secs
Thread 10 just returned after waiting 26 secs
Thread 12 just returned after waiting 30 secs
public class Program {
public static void main(String [] args) {
List<Integer> input = Arrays.asList(30,26,22,18,14,10);
input.stream()
.parallel()
.map(Program::waitAndReturn)
.forEach(System.out::println);
}
…
Thread 1 just returned after waiting 30 secs
Thread 1 just returned after waiting 26 secs
Thread 1 just returned after waiting 22 secs
Thread 1 just returned after waiting 18 secs
Thread 1 just returned after waiting 14 secs
Thread 1 just returned after waiting 10 secs
The Functional Toolkit
 Lambdas
 Method References
 Optional Monad
 Streams (new style)
 And also:
 Implementations
allowed in interfaces
 New data / time library
Lambdas
Supplier<String> ref1 = () -> "Scooby";
Consumer<String> ref2 = s -> System.out.println(s);
Function<String,Integer> ref3 = s -> s.length();
IntToDoubleFunction ref4 = num -> num * 1.0;
Predicate<String> ref5 = s -> s.length() == 5;
UnaryOperator<String> ref6 = s -> s + "wobble";
BinaryOperator<String> ref7 = (s1,s2) -> s1 + s2;
Converter<String,Double> ref8 = s -> Double.parseDouble(s);
@FunctionalInterface
public interface Converter<T,U> {
public U convert(T input);
}
Lambdas
//Never write multi-line lambdas!
Consumer<String> ref9 = (s) -> {
System.out.println(ref1.get());
ref2.accept(s);
System.out.println(ref3.apply(s));
System.out.println(ref4.applyAsDouble(123));
System.out.println(ref5.test(s));
System.out.println(ref6.apply(s));
System.out.println(ref7.apply(s, "wobble"));
System.out.println(ref8.convert("1234.567"));
};
ref9.accept("wibble");
Scooby
wibble
6
123.0
false
wibblewobble
wibblewobble
1234.567
Method References
void demoStaticMethodRefs() {
Supplier<Double> ref1 = Math::random;
Supplier<Thread> ref2 = Thread::currentThread;
DoubleUnaryOperator ref3 = Math::sqrt;
UnaryOperator<String> ref4 = System::getProperty;
System.out.println(ref1.get());
System.out.println(ref2.get().getId());
System.out.println(ref3.applyAsDouble(16.0));
System.out.println(ref4.apply("java.vm.vendor"));
} 0.2960393385581157
1
4.0
Oracle Corporation
Method References
void demoInstanceMethodRefs() throws Exception {
StringBuilder builder = new StringBuilder();
InetAddress address = InetAddress.getByName("localhost");
File currentDir = new File(".");
Function<String,StringBuilder> ref1 = builder::append;
Supplier<String> ref2 = address::getCanonicalHostName;
Supplier<String> ref3 = currentDir::getAbsolutePath;
Consumer<Object> out = System.out::println;
out.accept(ref1.apply("def"));
out.accept(ref2.get());
out.accept(ref3.get());
}
def
localhost
/Users/ggilmour/JavaEightDemos/.
Method References
void demoConstructorRefs() throws Exception {
Function<String,File> ref1 = File::new;
Function<URI,File> ref2 = File::new;
File f1 = ref1.apply(".");
File f2 = ref2.apply(new URI("file:///bin"));
System.out.println(f1.getAbsolutePath());
System.out.println(f2.getAbsolutePath());
}
/Users/ggilmour/JavaEightDemos/.
/bin
Optional
private static Optional<String> fetchSystemProperty(String name) {
String result = System.getProperty(name);
if(result == null) {
return Optional.empty();
} else {
return Optional.of(result);
}
}
Empty
Set
Set of 1
Optional
public static void main(String [] args) {
Optional<String> result1 = fetchSystemProperty("java.version");
Optional<String> result2 = fetchSystemProperty("wibble");
result1.ifPresent(s -> System.out.println(s));
result2.ifPresent(s -> System.out.println(s));
result1.ifPresent(System.out::println);
result2.ifPresent(System.out::println);
System.out.println(result1.orElse("No such property!"));
System.out.println(result2.orElse("No such property!"));
}
Streams
System.out.println("t" + data.stream().findAny().orElse("Empty!"));
if(data.stream().allMatch(s -> s.length() > 1)) {
System.out.println("tAll strings longer than 1");
}
if(data.stream().anyMatch(s -> s.length() > 3)) {
System.out.println("tAt least one string longer than 3");
}
if(data.stream().noneMatch(s -> s.length() > 4)) {
System.out.println("tNo strings longer than 4");
}
Streams
data.stream().forEach(s -> System.out.printf("%s ",s));
Stream<String> results = data.stream().filter(s -> s.length() == 3);
Stream<Integer> results1 = data.stream().map(s -> s.length());
IntStream results2 = data.stream().mapToInt(s -> s.length());
LongStream results3 = data.stream().mapToLong(s -> s.length());
DoubleStream results4 = data.stream().mapToDouble(s -> s.length() * 1.0);
Optional<String> result1 = data.stream().reduce((s1,s2) -> s1 + "-" + s2);
StringBuilder result2 = data.stream()
.reduce(new StringBuilder(),
(sb,s) -> sb.insert(0,s), (sb1,sb2) -> sb1);
int result3 = data.stream()
.reduce(0, (total,s) -> total + s.codePointAt(0), (a,b) -> a + b );
Scala is simpler than Java 8
The Problem
“super”
“cala”
“fragil”
“istic”
“expy”
“ali”
“dotious”
S U P E R C A L A F R A G I L I S T I C E X P Y A L I D O T I O U S
?
The Theoretical Solution
S U P E R
C A L A
I S T I C
F R A G I L
E X P Y
A L I
D O T I O U S
flatMap(String  char [ ])
The Solution in Scala
object Program {
def main(args : Array[String]) {
val data = Array("super","cala","fragil","istic","expy","ali","dotious")
val result = data.flatMap(_.toCharArray)
for(c <- result) {
printf(" %s", c);
}
}
}
s u p e r c a l a f r a g i l i s t i c e x p y a l i d o t i o u s
The Solution in Java (Part 1)
© Garth Gilmour 2011
import static java.util.Arrays.*;
public class Program {
public static void main(String [] args) {
String [] data = {"super","cala","fragil","istic","expy","ali","dotious"};
data.flatMap(s -> null);
}
}
The Solution in Java (Part 2)
import static java.util.Arrays.*;
public class Program {
public static void main(String [] args) {
String [] data = {"super","cala","fragil","istic","expy","ali","dotious"};
asList(data).flatMap(s -> null);
}
}
The Solution in Java (Part 3)
import static java.util.Arrays.*;
public class Program {
public static void main(String [] args) {
String [] data = {"super","cala","fragil","istic","expy","ali","dotious"};
asList(data).stream().flatMap(s -> null);
}
}
The Solution in Java (Part 4)
asList(data).stream().flatMap(s -> s.toCharArray());
The Solution in Java (Part 4)
The Solution in Java (Part 5)
Stream<char[]> results = asList(data)
.stream()
.flatMap(s -> asList(s.toCharArray()).stream());
for(Object obj : results.toArray()) {
System.out.printf("%s ",obj);
}
[C@5caf905d [C@27716f4 [C@8efb846 [C@2a84aee7 [C@a09ee92 [C@30f39991 [C@452b3a41
The Solution in Java (Part 5)
The Solution in Java (Part 5)
Stream<char[]> results = asList(data)
.stream()
.flatMap(s -> stream(s.toCharArray()));
The Solution in Java (Part 6)
import java.util.Arrays;
import java.util.stream.Stream;
public class MyUtils {
public static Stream toStream(String input) {
Character[] output = new Character[input.length()];
for (int i = 0; i < input.length(); i++) {
output[i] = input.charAt(i);
}
return Arrays.stream(output);
}
}
The Solution in Java (Part 6)
import static java.util.Arrays.asList;
import java.util.stream.Stream;
public class Program {
public static void main(String [] args) {
String [] data = {"super","cala","fragil","istic","expy","ali","dotious"};
Stream<char[]> results = asList(data).stream().flatMap(MyUtils::toStream);
for(Object obj : results.toArray()) {
System.out.printf("%s ",obj);
}
}
}
s u p e r c a l a f r a g i l i s t i c e x p y a l i d o t i o u s
Is Java 8 More Complex?
 Is NOT about absolute complexity
 Its about accidental vs. essential complexity
 Scala has higher essential complexity
 But all the features ‘hang together’
 You don’t have to meet it all at once
Is Java 8 More Complex?
Primitive types and boxing
and arrays and collections
and non-reified generics
and var-args and lambdas
and method refs. Oh My!
Can Java Be More Complex?
What About Clojure?
What About Haskell?
Looking Into The Future…
Watch this Presentation
Iterator
(stream of items)
Observer
(stream of events)
The Same (FP) Operators Apply!!
(Filter, Map, Take, Reduce etc… )
RX
public class Item {
public Item(int delay,
String message,
Severity severity) {
this.delay = delay;
this.message = message;
this.severity = severity;
}
public int getDelay() {
return delay;
}
public String getMessage() {
return message;
}
public Severity getSeverity() {
return severity;
}
private final int delay;
private final String message;
private final Severity severity;
}
public enum Severity {
HIGH,
LOW
}
public class MyObservable implements Observable.OnSubscribe<Item> {
@Override
public void call(Subscriber<? super Item> subscriber) {
for(int i=0;i<100;i++) {
int delay = (int)(Math.random() * 1000);
String message = "Message " + i;
Severity severity = (i % 2 == 0) ? Severity.HIGH : Severity.LOW;
try {
Thread.sleep(delay);
subscriber.onNext(new Item(delay,message,severity));
} catch(InterruptedException ex) {
subscriber.onError(ex);
}
}
subscriber.onCompleted();
}
}
public class Program {
public static void main(String [] args) {
demo1(Observable.create(new MyObservable()));
printSpacer();
demo2(Observable.create(new MyObservable()));
printSpacer();
demo3(Observable.create(new MyObservable()));
}
public static void printSpacer() {
System.out.println("----------------------");
}
public static void demo1(Observable<Item> observable) {
observable.filter(item -> item.getSeverity() == HIGH)
.map(item -> item.getMessage())
.subscribe(System.out::println);
}
public static void demo2(Observable<Item> observable) {
observable.reduce(0.0, (a,b) -> a + b.getDelay())
.subscribe(System.out::println);
}
public static void demo3(Observable<Item> observable) {
observable.skip(20)
.takeWhile(item -> !item.getMessage().endsWith("70"))
.subscribe(item -> System.out.println(item.getMessage()));
}
}
Message 0
Message 2
Message 4
Message 6
Message 8
Message 10
Message 12
Message 14
Message 16
LOTS MORE…
Message 84
Message 86
Message 88
Message 90
Message 92
Message 94
Message 96
Message 98
----------------------
47412.0
----------------------
Message 20
Message 21
Message 22
Message 23
Message 24
Message 25
Message 26
Message 27
Message 28
LOTS MORE…
Message 62
Message 63
Message 64
Message 65
Message 66
Message 67
Message 68
Message 69
Concluding Thought
Its not about making everything scalable
today. Its about opening the door to making
arbitrary things scalable tomorrow, and
enabling that decision to be transparent to
the user of the service…
Thanks for Watching!
garth.gilmour@instil.co
@GarthGilmour
@instil
https://www.facebook.com/instilireland

More Related Content

What's hot

Introduction to c sharp 4.0 and dynamic
Introduction to c sharp 4.0 and dynamicIntroduction to c sharp 4.0 and dynamic
Introduction to c sharp 4.0 and dynamic
Gieno Miao
 
5. using variables, data, expressions and constants
5. using variables, data, expressions and constants5. using variables, data, expressions and constants
5. using variables, data, expressions and constants
CtOlaf
 
Method Shelters : Another Way to Resolve Class Extension Conflicts
Method Shelters : Another Way to Resolve Class Extension Conflicts Method Shelters : Another Way to Resolve Class Extension Conflicts
Method Shelters : Another Way to Resolve Class Extension Conflicts
S Akai
 
Ti1220 Lecture 2: Names, Bindings, and Scopes
Ti1220 Lecture 2: Names, Bindings, and ScopesTi1220 Lecture 2: Names, Bindings, and Scopes
Ti1220 Lecture 2: Names, Bindings, and Scopes
Eelco Visser
 

What's hot (20)

Java- Concurrent programming - Synchronization (part 1)
Java- Concurrent programming - Synchronization (part 1)Java- Concurrent programming - Synchronization (part 1)
Java- Concurrent programming - Synchronization (part 1)
 
Introduction to c sharp 4.0 and dynamic
Introduction to c sharp 4.0 and dynamicIntroduction to c sharp 4.0 and dynamic
Introduction to c sharp 4.0 and dynamic
 
Java - Concurrent programming - Thread's basics
Java - Concurrent programming - Thread's basicsJava - Concurrent programming - Thread's basics
Java - Concurrent programming - Thread's basics
 
Preparing Java 7 Certifications
Preparing Java 7 CertificationsPreparing Java 7 Certifications
Preparing Java 7 Certifications
 
TMPA-2015: Kotlin: From Null Dereference to Smart Casts
TMPA-2015: Kotlin: From Null Dereference to Smart CastsTMPA-2015: Kotlin: From Null Dereference to Smart Casts
TMPA-2015: Kotlin: From Null Dereference to Smart Casts
 
Generics and collections in Java
Generics and collections in JavaGenerics and collections in Java
Generics and collections in Java
 
Java - Remote method invocation
Java - Remote method invocationJava - Remote method invocation
Java - Remote method invocation
 
Unit I Advanced Java Programming Course
Unit I   Advanced Java Programming CourseUnit I   Advanced Java Programming Course
Unit I Advanced Java Programming Course
 
Truby
Truby Truby
Truby
 
Java - Concurrent programming - Thread's advanced concepts
Java - Concurrent programming - Thread's advanced conceptsJava - Concurrent programming - Thread's advanced concepts
Java - Concurrent programming - Thread's advanced concepts
 
5. using variables, data, expressions and constants
5. using variables, data, expressions and constants5. using variables, data, expressions and constants
5. using variables, data, expressions and constants
 
Virtual function complete By Abdul Wahab (moon sheikh)
Virtual function complete By Abdul Wahab (moon sheikh)Virtual function complete By Abdul Wahab (moon sheikh)
Virtual function complete By Abdul Wahab (moon sheikh)
 
10 strategy pattern
10 strategy pattern10 strategy pattern
10 strategy pattern
 
Extending and scripting PDT
Extending and scripting PDTExtending and scripting PDT
Extending and scripting PDT
 
Java Exception Handling, Assertions and Logging
Java Exception Handling, Assertions and LoggingJava Exception Handling, Assertions and Logging
Java Exception Handling, Assertions and Logging
 
Oscon keynote: Working hard to keep it simple
Oscon keynote: Working hard to keep it simpleOscon keynote: Working hard to keep it simple
Oscon keynote: Working hard to keep it simple
 
Method Shelters : Another Way to Resolve Class Extension Conflicts
Method Shelters : Another Way to Resolve Class Extension Conflicts Method Shelters : Another Way to Resolve Class Extension Conflicts
Method Shelters : Another Way to Resolve Class Extension Conflicts
 
Ruby
RubyRuby
Ruby
 
Web application architecture
Web application architectureWeb application architecture
Web application architecture
 
Ti1220 Lecture 2: Names, Bindings, and Scopes
Ti1220 Lecture 2: Names, Bindings, and ScopesTi1220 Lecture 2: Names, Bindings, and Scopes
Ti1220 Lecture 2: Names, Bindings, and Scopes
 

Similar to Does Java Have a Future After Version 8? (Belfast JUG April 2014)

Java Intro
Java IntroJava Intro
Java Intro
backdoor
 

Similar to Does Java Have a Future After Version 8? (Belfast JUG April 2014) (20)

Java
JavaJava
Java
 
Javascript
JavascriptJavascript
Javascript
 
Knowledge of Javascript
Knowledge of JavascriptKnowledge of Javascript
Knowledge of Javascript
 
What`s New in Java 8
What`s New in Java 8What`s New in Java 8
What`s New in Java 8
 
LISP: назад в будущее, Микола Мозговий
LISP: назад в будущее, Микола МозговийLISP: назад в будущее, Микола Мозговий
LISP: назад в будущее, Микола Мозговий
 
Building native Android applications with Mirah and Pindah
Building native Android applications with Mirah and PindahBuilding native Android applications with Mirah and Pindah
Building native Android applications with Mirah and Pindah
 
Proxy deep-dive java-one_20151027_001
Proxy deep-dive java-one_20151027_001Proxy deep-dive java-one_20151027_001
Proxy deep-dive java-one_20151027_001
 
Proxy Deep Dive Voxxed Belgrad 2015
Proxy Deep Dive Voxxed Belgrad 2015Proxy Deep Dive Voxxed Belgrad 2015
Proxy Deep Dive Voxxed Belgrad 2015
 
Java introduction
Java introductionJava introduction
Java introduction
 
CSE215_Module_02_Elementary_Programming.ppt
CSE215_Module_02_Elementary_Programming.pptCSE215_Module_02_Elementary_Programming.ppt
CSE215_Module_02_Elementary_Programming.ppt
 
Node.js: CAMTA Presentation
Node.js: CAMTA PresentationNode.js: CAMTA Presentation
Node.js: CAMTA Presentation
 
.NET Foundation, Future of .NET and C#
.NET Foundation, Future of .NET and C#.NET Foundation, Future of .NET and C#
.NET Foundation, Future of .NET and C#
 
Modern_2.pptx for java
Modern_2.pptx for java Modern_2.pptx for java
Modern_2.pptx for java
 
OWASP Poland Day 2018 - Pedro Fortuna - Are your Java Script based protection...
OWASP Poland Day 2018 - Pedro Fortuna - Are your Java Script based protection...OWASP Poland Day 2018 - Pedro Fortuna - Are your Java Script based protection...
OWASP Poland Day 2018 - Pedro Fortuna - Are your Java Script based protection...
 
GWT is Smarter Than You
GWT is Smarter Than YouGWT is Smarter Than You
GWT is Smarter Than You
 
TypeScript - Silver Bullet for the Full-stack Developers
TypeScript - Silver Bullet for the Full-stack DevelopersTypeScript - Silver Bullet for the Full-stack Developers
TypeScript - Silver Bullet for the Full-stack Developers
 
C programming language tutorial
C programming language tutorial C programming language tutorial
C programming language tutorial
 
Introduction To Scala
Introduction To ScalaIntroduction To Scala
Introduction To Scala
 
Java Intro
Java IntroJava Intro
Java Intro
 
Framework engineering JCO 2011
Framework engineering JCO 2011Framework engineering JCO 2011
Framework engineering JCO 2011
 

More from Garth Gilmour

More from Garth Gilmour (20)

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

Recently uploaded

CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
anilsa9823
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
mohitmore19
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
9953056974 Low Rate Call Girls In Saket, Delhi NCR
 

Recently uploaded (20)

Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
Tech Tuesday-Harness the Power of Effective Resource Planning with OnePlan’s ...
 
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
Try MyIntelliAccount Cloud Accounting Software As A Service Solution Risk Fre...
 
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
The Real-World Challenges of Medical Device Cybersecurity- Mitigating Vulnera...
 
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected WorkerHow To Troubleshoot Collaboration Apps for the Modern Connected Worker
How To Troubleshoot Collaboration Apps for the Modern Connected Worker
 
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdfThe Ultimate Test Automation Guide_ Best Practices and Tips.pdf
The Ultimate Test Automation Guide_ Best Practices and Tips.pdf
 
Diamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with PrecisionDiamond Application Development Crafting Solutions with Precision
Diamond Application Development Crafting Solutions with Precision
 
5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf5 Signs You Need a Fashion PLM Software.pdf
5 Signs You Need a Fashion PLM Software.pdf
 
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdfLearn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
Learn the Fundamentals of XCUITest Framework_ A Beginner's Guide.pdf
 
A Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docxA Secure and Reliable Document Management System is Essential.docx
A Secure and Reliable Document Management System is Essential.docx
 
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS LiveVip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
Vip Call Girls Noida ➡️ Delhi ➡️ 9999965857 No Advance 24HRS Live
 
Software Quality Assurance Interview Questions
Software Quality Assurance Interview QuestionsSoftware Quality Assurance Interview Questions
Software Quality Assurance Interview Questions
 
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AISyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
SyndBuddy AI 2k Review 2024: Revolutionizing Content Syndication with AI
 
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
Shapes for Sharing between Graph Data Spaces - and Epistemic Querying of RDF-...
 
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online  ☂️
CALL ON ➥8923113531 🔝Call Girls Kakori Lucknow best sexual service Online ☂️
 
TECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service providerTECUNIQUE: Success Stories: IT Service provider
TECUNIQUE: Success Stories: IT Service provider
 
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICECHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
CHEAP Call Girls in Pushp Vihar (-DELHI )🔝 9953056974🔝(=)/CALL GIRLS SERVICE
 
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
Short Story: Unveiling the Reasoning Abilities of Large Language Models by Ke...
 
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
Steps To Getting Up And Running Quickly With MyTimeClock Employee Scheduling ...
 
Right Money Management App For Your Financial Goals
Right Money Management App For Your Financial GoalsRight Money Management App For Your Financial Goals
Right Money Management App For Your Financial Goals
 
HR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.comHR Software Buyers Guide in 2024 - HRSoftware.com
HR Software Buyers Guide in 2024 - HRSoftware.com
 

Does Java Have a Future After Version 8? (Belfast JUG April 2014)

  • 3. Goals of this Talk…
  • 6. Some Thoughts from React 2014  Architecture is back in fashion  No more ‘just use the stack’ or ‘wait for speedup’  Design so there is no bottleneck  Be ready for the ‘Internet of Things’  The same lessons apply at different levels  Key concepts:  Actors, Futures, Reactive Extensions (RX)  Eventually consistent data storage  Convergent replicated data types  Coding becomes increasingly declarative  Send code to data and ensure ‘data knows where to go’
  • 7.
  • 9. Why Are We Still Using Rockets?
  • 10. The Origins Of Rockets
  • 11. The Killer-App for Rockets… 
  • 14. Only Rockets Will Be Insured From the late 1950's until the early 1980's, the ownership and operation of satellites was generally undertaken only by government agencies like National Aeronautics and Space Administration (NASA) and the European Space Agency (ESA). While commercial satellite insurance has been available since 1964, very little was purchased until the mid 1980's because government agencies generally self-insure the risk. Starting in the early 1980's, the commercial satellite industry began to take off and with it came the increased need for satellite insurance since commercial enterprises are not ordinarily willing to self-insure such high valued assets that are subject to relatively high loss frequencies. Market capacity soared in the 1990's, from around $300 million in 1990 to almost $1.2 billion in 1999, 3 well in excess of the $175 to $250 million of coverage required for most satellites. Occasionally a satellite may require as much as $400 million of coverage. Estimating Satellite Insurance Liabilities Allen J. Gould and Orin M. Linden
  • 16. The Killer App for Java
  • 17. The Law of the Server Farm
  • 18. We Are Locked Into Java!!
  • 19. What is the JVM Today?
  • 21. What About The Others…  Ruby on Rails  Node.js  Django  etc…
  • 22. What About the Others? You came close but you never made it. And if you were gonna make it, you would have made it before now…
  • 25. The Horsemen of the Javapocalypse… Inner Classes Non-Reified Generics Checked Exceptions Value Types
  • 26. The Road Not Taken… The newest version of the Microsoft Visual J++ development environment supports a language construct called delegates or bound method references… It is unlikely that the Java programming language will ever include this construct. Sun already carefully considered adopting it in 1996, to the extent of building and discarding working prototypes. Our conclusion was that bound method references are unnecessary and detrimental to the language… We believe bound method references are unnecessary because another design alternative, inner classes, provides equal or superior functionality. In particular, inner classes fully support the requirements of user-interface event handling, and have been used to implement a user-interface API at least as comprehensive as the Windows Foundation Classes. We believe bound method references are harmful because they detract from the simplicity of the Java programming language and the pervasively object-oriented character of the APIs…. Extracts From: About Microsoft’s “Delegates" Whitepaper by the Java language team at JavaSoft
  • 27.
  • 28.
  • 29. Our Industry Has Issues… We Stayed!! (and fixed the bugs…)
  • 30. Our Industry Has Issues…
  • 31. Our Industry Has Issues…
  • 32. Our Industry Has Issues… The Proposition: Work till 2 am for 20 years, hunting bugs fuelled by cold pizza and warm coke. The Rewards: Kudos from peers Detach from ‘civilian’ life Grow neckbeard Present at QCon
  • 33. Our Industry Has Issues…
  • 35. Agile Values  Feedback cycles  Working as a team  Universal ownership  Sustainable pace  Asking for assistance  Clear prioritization  Retrospectives  No prima-donnas
  • 36. That he which hath no stomach to this fight, Let him depart; his passport shall be made, And crowns for convoy put into his purse; We would not die in that man's company ... From this day to the ending of the world, But we in it shall be remembered- We few, we happy few, we band of brothers;
  • 37.
  • 38.
  • 40. A Solution? Add FP to Java???
  • 41. The Solution public class Program { public static void main(String [] args) { List<Integer> input = Arrays.asList(30,26,22,18,14,10); input.stream() .parallel() .map(Program::waitAndReturn) .forEach(System.out::println); } private static String waitAndReturn(Integer sleep) { goToSleep(sleep); return buildMessage(sleep); }
  • 42. The Solution private static void goToSleep(Integer sleep) { try { Thread.sleep(sleep * 1000); } catch (InterruptedException ex) { System.out.println("BANG! " + ex.getMessage()); } } private static String buildMessage(Integer sleep) { String msg = "Thread %d just returned after waiting %d secs"; long threadId = Thread.currentThread().getId(); return String.format(msg, threadId, sleep); } }
  • 43. The Solution Thread 11 just returned after waiting 10 secs Thread 13 just returned after waiting 14 secs Thread 1 just returned after waiting 18 secs Thread 14 just returned after waiting 22 secs Thread 10 just returned after waiting 26 secs Thread 12 just returned after waiting 30 secs
  • 44. public class Program { public static void main(String [] args) { List<Integer> input = Arrays.asList(30,26,22,18,14,10); input.stream() .parallel() .map(Program::waitAndReturn) .forEach(System.out::println); } … Thread 1 just returned after waiting 30 secs Thread 1 just returned after waiting 26 secs Thread 1 just returned after waiting 22 secs Thread 1 just returned after waiting 18 secs Thread 1 just returned after waiting 14 secs Thread 1 just returned after waiting 10 secs
  • 45. The Functional Toolkit  Lambdas  Method References  Optional Monad  Streams (new style)  And also:  Implementations allowed in interfaces  New data / time library
  • 46. Lambdas Supplier<String> ref1 = () -> "Scooby"; Consumer<String> ref2 = s -> System.out.println(s); Function<String,Integer> ref3 = s -> s.length(); IntToDoubleFunction ref4 = num -> num * 1.0; Predicate<String> ref5 = s -> s.length() == 5; UnaryOperator<String> ref6 = s -> s + "wobble"; BinaryOperator<String> ref7 = (s1,s2) -> s1 + s2; Converter<String,Double> ref8 = s -> Double.parseDouble(s); @FunctionalInterface public interface Converter<T,U> { public U convert(T input); }
  • 47. Lambdas //Never write multi-line lambdas! Consumer<String> ref9 = (s) -> { System.out.println(ref1.get()); ref2.accept(s); System.out.println(ref3.apply(s)); System.out.println(ref4.applyAsDouble(123)); System.out.println(ref5.test(s)); System.out.println(ref6.apply(s)); System.out.println(ref7.apply(s, "wobble")); System.out.println(ref8.convert("1234.567")); }; ref9.accept("wibble"); Scooby wibble 6 123.0 false wibblewobble wibblewobble 1234.567
  • 48. Method References void demoStaticMethodRefs() { Supplier<Double> ref1 = Math::random; Supplier<Thread> ref2 = Thread::currentThread; DoubleUnaryOperator ref3 = Math::sqrt; UnaryOperator<String> ref4 = System::getProperty; System.out.println(ref1.get()); System.out.println(ref2.get().getId()); System.out.println(ref3.applyAsDouble(16.0)); System.out.println(ref4.apply("java.vm.vendor")); } 0.2960393385581157 1 4.0 Oracle Corporation
  • 49. Method References void demoInstanceMethodRefs() throws Exception { StringBuilder builder = new StringBuilder(); InetAddress address = InetAddress.getByName("localhost"); File currentDir = new File("."); Function<String,StringBuilder> ref1 = builder::append; Supplier<String> ref2 = address::getCanonicalHostName; Supplier<String> ref3 = currentDir::getAbsolutePath; Consumer<Object> out = System.out::println; out.accept(ref1.apply("def")); out.accept(ref2.get()); out.accept(ref3.get()); } def localhost /Users/ggilmour/JavaEightDemos/.
  • 50. Method References void demoConstructorRefs() throws Exception { Function<String,File> ref1 = File::new; Function<URI,File> ref2 = File::new; File f1 = ref1.apply("."); File f2 = ref2.apply(new URI("file:///bin")); System.out.println(f1.getAbsolutePath()); System.out.println(f2.getAbsolutePath()); } /Users/ggilmour/JavaEightDemos/. /bin
  • 51. Optional private static Optional<String> fetchSystemProperty(String name) { String result = System.getProperty(name); if(result == null) { return Optional.empty(); } else { return Optional.of(result); } } Empty Set Set of 1
  • 52. Optional public static void main(String [] args) { Optional<String> result1 = fetchSystemProperty("java.version"); Optional<String> result2 = fetchSystemProperty("wibble"); result1.ifPresent(s -> System.out.println(s)); result2.ifPresent(s -> System.out.println(s)); result1.ifPresent(System.out::println); result2.ifPresent(System.out::println); System.out.println(result1.orElse("No such property!")); System.out.println(result2.orElse("No such property!")); }
  • 53. Streams System.out.println("t" + data.stream().findAny().orElse("Empty!")); if(data.stream().allMatch(s -> s.length() > 1)) { System.out.println("tAll strings longer than 1"); } if(data.stream().anyMatch(s -> s.length() > 3)) { System.out.println("tAt least one string longer than 3"); } if(data.stream().noneMatch(s -> s.length() > 4)) { System.out.println("tNo strings longer than 4"); }
  • 54. Streams data.stream().forEach(s -> System.out.printf("%s ",s)); Stream<String> results = data.stream().filter(s -> s.length() == 3); Stream<Integer> results1 = data.stream().map(s -> s.length()); IntStream results2 = data.stream().mapToInt(s -> s.length()); LongStream results3 = data.stream().mapToLong(s -> s.length()); DoubleStream results4 = data.stream().mapToDouble(s -> s.length() * 1.0); Optional<String> result1 = data.stream().reduce((s1,s2) -> s1 + "-" + s2); StringBuilder result2 = data.stream() .reduce(new StringBuilder(), (sb,s) -> sb.insert(0,s), (sb1,sb2) -> sb1); int result3 = data.stream() .reduce(0, (total,s) -> total + s.codePointAt(0), (a,b) -> a + b );
  • 55. Scala is simpler than Java 8
  • 56. The Problem “super” “cala” “fragil” “istic” “expy” “ali” “dotious” S U P E R C A L A F R A G I L I S T I C E X P Y A L I D O T I O U S ?
  • 57. The Theoretical Solution S U P E R C A L A I S T I C F R A G I L E X P Y A L I D O T I O U S flatMap(String  char [ ])
  • 58. The Solution in Scala object Program { def main(args : Array[String]) { val data = Array("super","cala","fragil","istic","expy","ali","dotious") val result = data.flatMap(_.toCharArray) for(c <- result) { printf(" %s", c); } } } s u p e r c a l a f r a g i l i s t i c e x p y a l i d o t i o u s
  • 59. The Solution in Java (Part 1) © Garth Gilmour 2011 import static java.util.Arrays.*; public class Program { public static void main(String [] args) { String [] data = {"super","cala","fragil","istic","expy","ali","dotious"}; data.flatMap(s -> null); } }
  • 60. The Solution in Java (Part 2) import static java.util.Arrays.*; public class Program { public static void main(String [] args) { String [] data = {"super","cala","fragil","istic","expy","ali","dotious"}; asList(data).flatMap(s -> null); } }
  • 61. The Solution in Java (Part 3) import static java.util.Arrays.*; public class Program { public static void main(String [] args) { String [] data = {"super","cala","fragil","istic","expy","ali","dotious"}; asList(data).stream().flatMap(s -> null); } }
  • 62. The Solution in Java (Part 4) asList(data).stream().flatMap(s -> s.toCharArray());
  • 63. The Solution in Java (Part 4)
  • 64. The Solution in Java (Part 5) Stream<char[]> results = asList(data) .stream() .flatMap(s -> asList(s.toCharArray()).stream()); for(Object obj : results.toArray()) { System.out.printf("%s ",obj); } [C@5caf905d [C@27716f4 [C@8efb846 [C@2a84aee7 [C@a09ee92 [C@30f39991 [C@452b3a41
  • 65. The Solution in Java (Part 5)
  • 66. The Solution in Java (Part 5) Stream<char[]> results = asList(data) .stream() .flatMap(s -> stream(s.toCharArray()));
  • 67. The Solution in Java (Part 6) import java.util.Arrays; import java.util.stream.Stream; public class MyUtils { public static Stream toStream(String input) { Character[] output = new Character[input.length()]; for (int i = 0; i < input.length(); i++) { output[i] = input.charAt(i); } return Arrays.stream(output); } }
  • 68. The Solution in Java (Part 6) import static java.util.Arrays.asList; import java.util.stream.Stream; public class Program { public static void main(String [] args) { String [] data = {"super","cala","fragil","istic","expy","ali","dotious"}; Stream<char[]> results = asList(data).stream().flatMap(MyUtils::toStream); for(Object obj : results.toArray()) { System.out.printf("%s ",obj); } } } s u p e r c a l a f r a g i l i s t i c e x p y a l i d o t i o u s
  • 69.
  • 70. Is Java 8 More Complex?  Is NOT about absolute complexity  Its about accidental vs. essential complexity  Scala has higher essential complexity  But all the features ‘hang together’  You don’t have to meet it all at once
  • 71. Is Java 8 More Complex? Primitive types and boxing and arrays and collections and non-reified generics and var-args and lambdas and method refs. Oh My!
  • 72. Can Java Be More Complex?
  • 75. Looking Into The Future…
  • 77. Iterator (stream of items) Observer (stream of events) The Same (FP) Operators Apply!! (Filter, Map, Take, Reduce etc… ) RX
  • 78. public class Item { public Item(int delay, String message, Severity severity) { this.delay = delay; this.message = message; this.severity = severity; } public int getDelay() { return delay; } public String getMessage() { return message; } public Severity getSeverity() { return severity; } private final int delay; private final String message; private final Severity severity; } public enum Severity { HIGH, LOW }
  • 79. public class MyObservable implements Observable.OnSubscribe<Item> { @Override public void call(Subscriber<? super Item> subscriber) { for(int i=0;i<100;i++) { int delay = (int)(Math.random() * 1000); String message = "Message " + i; Severity severity = (i % 2 == 0) ? Severity.HIGH : Severity.LOW; try { Thread.sleep(delay); subscriber.onNext(new Item(delay,message,severity)); } catch(InterruptedException ex) { subscriber.onError(ex); } } subscriber.onCompleted(); } }
  • 80. public class Program { public static void main(String [] args) { demo1(Observable.create(new MyObservable())); printSpacer(); demo2(Observable.create(new MyObservable())); printSpacer(); demo3(Observable.create(new MyObservable())); } public static void printSpacer() { System.out.println("----------------------"); } public static void demo1(Observable<Item> observable) { observable.filter(item -> item.getSeverity() == HIGH) .map(item -> item.getMessage()) .subscribe(System.out::println); }
  • 81. public static void demo2(Observable<Item> observable) { observable.reduce(0.0, (a,b) -> a + b.getDelay()) .subscribe(System.out::println); } public static void demo3(Observable<Item> observable) { observable.skip(20) .takeWhile(item -> !item.getMessage().endsWith("70")) .subscribe(item -> System.out.println(item.getMessage())); } }
  • 82. Message 0 Message 2 Message 4 Message 6 Message 8 Message 10 Message 12 Message 14 Message 16 LOTS MORE… Message 84 Message 86 Message 88 Message 90 Message 92 Message 94 Message 96 Message 98 ---------------------- 47412.0 ---------------------- Message 20 Message 21 Message 22 Message 23 Message 24 Message 25 Message 26 Message 27 Message 28 LOTS MORE… Message 62 Message 63 Message 64 Message 65 Message 66 Message 67 Message 68 Message 69
  • 83. Concluding Thought Its not about making everything scalable today. Its about opening the door to making arbitrary things scalable tomorrow, and enabling that decision to be transparent to the user of the service…