Scala is Java8.next()
Twitter - @blueiur
La-scala - daewon
// Before Java 8
Collections.sort(strings, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {...
Programmer
●

http://office.naver.com
오! 벌써 새벽
3시네, 컴퓨
터 끄고 자야
겠어!

Programmer
●

http://daewon.github.io/
한 시간 후 ...
Overview
●
●

Scala
Java8 features
○
○

lambda
■ benefit of lambda expressions
comparison to Scala
●
●
●

Scalable Language
Born in 2003
Object-Oriented Meets Functional
Martin odersky
●
●

Designed the Scala programming language
Generic Java, and built the current generation of javac, the
J...
Features
●
●
●
●
●
●

SEAMLESS JAVA INTEROP
TYPE INFERENCE
CONCURRENCY & DISTRIBUTION
TRAITS
PATTERN MATCHING
HIGHER-ORDER...
Scala is used in many worldclass companies
Rod johnson joins typesafe
●
●

Creator of Spring
Keynote at ScalaDays 2013
○ Scala in 2018
●
●
●

Lambda Expressions
Method References
Virtual Extension Methods
●
●
●

Lambda Expressions
Method References
Virtual Extension Methods
Project Lambda - JSR 335
2006 - Gosling: "We will never have closures in Java"
2008 - Reinhold: "We will never have closures in Java"

Project Lamb...
2007 - 3 different proposals for closures in Java
2009 - Start of project Lambda (JSR 335)

Project Lambda
JDK 8: General Availability - 2014/04/18
○
○
○
○

2006
2007
2008
2009

-

Gosling: "We will never have closures in Java"
3...
Lambda?
●
●
●
●

lambda calculus
anonymous function
function literal
closure
Lambda?
●
●
●
●

lambda calculus
anonymous function
function literal
closure
Anonymous Function
Wikipedia
●

function defined, and possibly called, without being bound
to an identifier.
익명 함수
Wikipedia
●

특정 식별자 없이 정의되거나 호출될 수 있는 함수
익명 함수
Wikipedia
●

특정 식별자 없이 정의되거나 호출될 수 있는 함수
Languages that support anonymous functions
ActionScript
Ada
C
C#
C++
Clojure
Curl
D
Dart
Dylan
Erlang
Elixir
F#
Frink
Go

...
Languages that no support anonymous functions
ActionScript
Ada
C
C#
C++
Clojure
Curl
D
Dart
Dylan
Erlang
Elixir
F#
Frink
G...
Languages that no support anonymous functions
ActionScript
Ada (1977)
C (1969)
C#
C++
Clojure
Curl
D
Dart
Dylan
Erlang
Eli...
Languages that no support anonymous functions
ActionScript
Ada
C
C#
C++
Clojure
Curl
D
Dart
Dylan
Erlang
Elixir
F#
Frink
G...
Java8 support Lambda
●

General Availability - 2014/04/18
Lambda syntax
●

(parameters) -> { body }

●

(int x, int y) -> { return x + y; }

Lambda Syntax
Lambda syntax
●
●
●
●

(param) -> {return 100}
(param) -> {100}
(param) -> 100
param -> 100

Lambda Syntax
Lambda syntax
●
●
●
●

(param) -> {return 100}
(param) -> {100}
(param) -> 100
param -> 100

Lambda Syntax
Lambda syntax
●
●
●
●

(param) -> {return 100}
(param) -> {100}
(param) -> 100
param -> 100

Lambda Syntax
Lambda syntax
●
●
●
●

(param) -> {return 100}
(param) -> {100}
(param) -> 100
param -> 100

Lambda Syntax
Lambda syntax
●
●
●
●

(param) -> {return 100}
(param) -> {100}
(param) -> 100
param -> 100

Lambda Syntax
Lambda syntax
●
●
●
●
●
●

x -> x + 1
(x) -> x + 1
(int x) -> x + 1
(int x, int y) -> x + y
(x, y) -> { System.out.println...
Storing Lambda
●
●
●

int n = 10;
String name = “daewon”;
? adder = (int x, int y) -> x + y
Storing Lambda
●
●
●

int n = 10;
String name = “daewon”;
? adder = (int x, int y) -> x + y
@Functional Interface
●

Lambda Expression -> Anonymous Inner Class
Replace with Lambda
@FunctionalInterface
interface Adder {
int add(int a, int b);
}

????? func = (int a, int b) -> { return a + b };
Adder sh...
@FunctionalInterface
interface Adder {
int add(int a, int b);
}

Adder func = (int a, int b) -> { return a + b };
Adder sh...
@FunctionalInterface
interface Adder {
int add(int a, int b);
}

Adder func = (int a, int b) -> { return a + b };
Adder sh...
Predefined Functional Interfaces
BiConsumer<T,U>
BiFunction<T,U,R>
BinaryOperator<T>
BiPredicate<T,U>
BooleanSupplier
Cons...
Lambda in Java
●
●

anonymous inner class
lambda expressions
// Spring
jdbcTemplate.queryForObject("select * from student where id = ?",
new Object[]{1212l},
new RowMapper() {
public ...
// Spring
jdbcTemplate.queryForObject("select * from student where id = ?",
new Object[]{1212l},
new RowMapper() {
public ...
// Before Java 8
Collections.sort(strings, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {...
// Java 8
Collections.sort(strings, (s1, s2) -> s1.compareTo(s2));

Clear syntax!
// Before Java 8
Collections.sort(strings, new Comparator<String>() {
@Override
public int compare(String s1, String s2) {...
Functions are Data
●
●
●

function as parameter
function as return value
lazy eval
함수는 데이터
●
●
●

함수를 다른 함수에 인자로 사용
함수를 함수의 반환 값으로 사용
지연 평가
함수는 데이터
●
●
●

함수를 다른 함수에 인자로 사용
함수를 함수의 반환값으로 사용
지연 평가
Functions as parameter - Loan Pattern
●

scala_for_java_programmer
public void withFile(String fileName) {
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(ne...
public void withFile(String fileName) {
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(ne...
public void withFile(String fileName) {
BufferedReader bufferedReader = null;
try {
bufferedReader = new BufferedReader(ne...
public void withFile(String fileName, Consumer<String> work) {
BufferedReader bufferedReader = null;
try {
bufferedReader ...
public void withFile(String fileName, Consumer<String> work) {
BufferedReader bufferedReader = null;
try {
bufferedReader ...
// print each line to stdout
withFile(filename, line -> System.out.println(line));

// store each line to db
withFile(file...
// print each line to stdout
withFile(filename, line -> System.out.println(line));

// store each line to db
withFile(file...
// Scala
def withFile(filename: String)(work: String => Unit) {
Source.fromFile(filename).getLines.forEach work
}

Scala
// Scala
def withFile(filename: String)(work: String => Unit) {
Source.fromFile(filename).getLines.forEach work
}

Scala
// Java8 - print each line to stdout
withFile(filename, line -> System.out.println(line));
// Java8 - store each line to d...
Lambda with Collections
●
●

Imperative - external iteration
Functional - internal iteration
// External Iterator
for (Iterator iter = var.iterator(); iter.hasNext(); ) {
Object obj = iter.next();
// Operate on obj
...
// External Iterator
for (Iterator iter = var.iterator(); iter.hasNext(); ) {
Object obj = iter.next();
// Operate on obj
...
// External Iterator
for (Iterator iter = var.iterator(); iter.hasNext(); ) {
Object obj = iter.next();
// Operate on obj
...
// External Iterator
for (Iterator iter = var.iterator(); iter.hasNext(); ) {
Object obj = iter.next();
// Operate on obj
...
// Java8:: print each line to stdout
withFile(filename, line -> System.out.println(line));
// Java8 - store each line to d...
// Java8:: print each line to stdout
withFile(filename, line -> System.out.println(line));
// Java8 - store each line to d...
No more loop with Scala
●
●

Project Lambda J
Google guava-libraries/
case class Person(firstName: String, lastName: String, age:Int, male: Boolean)
case class Sale(buyer: Person, seller: Pers...
object db {
// car
val sonata = Car("Hyundai", "Sonata", 1982, 30000000)
val santafe = Car("Hyundai", "Santafe", 1990, 500...
// Iterative version
List<Sale> salesOfAHyundai = new ArrayList<Sale>();
for (Sale sale : sales) {
if (sale.getCar().getBr...
// Iterative version
List<Sale> salesOfAHyundai = new ArrayList<Sale>();
for (Sale sale : sales) {
if (sale.getCar().getBr...
// Iterative version
List<Sale> salesOfAHyundai = new ArrayList<Sale>();
for (Sale sale : sales) {
if (sale.getCar().getBr...
// Iterative version
List<Double> costs = new ArrayList<Double>();
for (Car car : cars) {
costs.add(car.getOriginalValue()...
// Iterative version
List<Double> costs = new ArrayList<Double>();
for (Car car : cars) {
costs.add(car.getOriginalValue()...
// Iterative version
List<Double> costs = new ArrayList<Double>();
for (Car car : cars) {
costs.add(car.getOriginalValue()...
// Iterative version
double maxCost = 0.0;
for (Sale sale : sales) {
double cost = sale.getCost();
if (cost > maxCost) {
m...
// Iterative version
double maxCost = 0.0;
for (Sale sale : sales) {
double cost = sale.getCost();
if (cost > maxCost) {
m...
// Iterative version
// 01. find youngest person in persons
Person youngest = null;
for (Person person : persons){
if (you...
// Iterative version
// 01. find youngest person in persons
Person youngest = null;
for (Person person : persons){
if (you...
// 01. 가장 어린 사람을 찾고
val youngestPerson = db.persons.minBy( _.age )
// 02. 가장 어린 사람과 나이가 같은 판매자들을 찾는다.
val buys = db.sales....
// Iterative version
Map<String, List<Car>> carsByBrand = new HashMap<>();
for (Car car : db.getCars()) {
List<Car> carLis...
// Iterative version
Map<String, List<Car>> carsByBrand = new HashMap<>();
for (Car car : db.getCars()) {
List<Car> carLis...
// Iterative version
Map<String, List<Car>> carsByBrand = new HashMap<>();
for (Car car : db.getCars()) {
List<Car> carLis...
// Iterative version
Map<Car, Integer> carsBought = new HashMap<Car, Integer>();
for (Sale sale : sales) {
Car car = sale....
// Functional version
val carsBought = db.sales.groupBy( _.car ).mapValues( _.length )
val mostBoughtCar = carsBought.maxB...
// Functional version
val carsBought = db.sales.groupBy( _.car ).mapValues( _.length )
val mostBoughtCar = carsBought.maxB...
// Iterative version
Map<Person,Map<Person,Sale>> map = new HashMap<Person, Map<Person,Sale>>();
for (Sale sale : sales) {...
// Functional version
val map = db.sales.groupBy(_.buyer).mapValues{
ls => ls.groupBy(_.seller).mapValues(_.head)
}
val yo...
Java8 Streams vs Scala For Comprehension
●
●

streams and sql
○ how-java-emulates-sql
for comprehension
// sql
select sum(salary)
from people
where gender = 'FEMALE'
// Java8 stream with lambda
people.stream()
.filter(p -> p.g...
// sql
select sum(salary)
from people
where gender = 'FEMALE'
// scala for comprehension
(for (p <- people;
(if p.gender =...
// sql
select sum(salary)
from people
where gender = 'FEMALE'
// scala for comprehension
(for (p <- people;
(if p.gender =...
// sql
select distinct(firstName)
from people
where gender = 'MALE'
// Java8 stream with lambda
people.stream()
.filter(p ...
// sql
select distinct(firstName)
from people
where gender = 'MALE'
// scala for comprehension
(for (p <- people;
if (p.ge...
// sql
select distinct(firstName)
from people
where gender = 'MALE'
// scala for comprehension
(for (p <- people;
if (p.ge...
// sql
나이가 가장 많은 남자들
select *
from
people
where age =
(select max(age) from people where gender ='MALE' )
and
gender ='MAL...
Is Java8 a functional language?
●

What is Functional Programming?
○ Immutable state
○ Functions as first class citizens
○...
Immutable
●
●

No setter
Variable must be final

final int i = 0;
while(i < 5) {
System.out.println("compile error!");
i++...
Persistent Data Structure
Java8
●
●
●

Immutable state
Functions as first class citizens
Persistent data structure

Scala
●
●
●

Immutable state
Fun...
Java8 is not a functional language.
●
●
●

So what?

Real-world programming isn't always perfectly functional
Java is stee...
자바는 함수형 언어가 아닙니다.
●
●
●

그래서요?

Real-world 문제가 항상 함수형에 적합하지는 않습니다
자바는 여전히 세계에서 가장 많이 쓰이고 있는 언어입니다
함수형 언어는 은탄환이 아닙니다
Java8 is Good!
Scala is Best!
One more thing
●

Lambda? Closure?
Lambda? Closure?
// lambda is just an anonymous function
Collection.filter(lists, e ‑> e.length() >= 5)

// closure is fun...
Lambda? Closure?
// lambda is just an anonymous function
Collection.filter(lists, e ‑> e.length() >= 5)

// closure is fun...
Lazy eval -

Better logging with Lambda
// log message only debug mode
public void debug(String message) {
if (log.isDebugEnabled()) {
log.log(message);
}
}

debu...
// log message only debug mode
public void debug(String message) {
if (log.isDebugEnabled()) {
log.log(message);
}
}

debu...
// log message only debug mode
public void debug(Consumer<String> consumer) {
if (log.isDebugEnabled()) {
log.log(consumer...
// log message only debug mode
public void debug(Consumer<String> consumer) {
if (log.isDebugEnabled()) {
log.log(consumer...
// without Lambda
debug(some.expensive("operation"));

// with Lambda
debug(() -> some.expensive("operation"));

bulk synt...
// Scala
def debug(message: => String) {
if (log.isDebugEnabled) log.log(message)
}
debug(some.expensive("operation"))

La...
// Scala
def debug(message: => String) {
if (log.isDebugEnabled) log.log(message)
}
debug(some.expensive("operation"))

La...
// Java:: Eager eval
debug(some.expensive("operation"));
// Java8:: Lazy eval
debug(() -> some.expensive("operation"));
//...
Question => Answer
// quiz
Lambda를 저장시 사용되는 인터페이스에 사용되는 Annotation은?

경품!
Scala is java8.next()
Scala is java8.next()
Scala is java8.next()
Upcoming SlideShare
Loading in …5
×

Scala is java8.next()

3,006 views
2,911 views

Published on

scala is java8.next()

Published in: Technology
0 Comments
23 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
3,006
On SlideShare
0
From Embeds
0
Number of Embeds
111
Actions
Shares
0
Downloads
69
Comments
0
Likes
23
Embeds 0
No embeds

No notes for slide

Scala is java8.next()

  1. 1. Scala is Java8.next() Twitter - @blueiur La-scala - daewon
  2. 2. // Before Java 8 Collections.sort(strings, new Comparator<String>() { @Override public int compare(String s1, String s2) { return s1.compareTo(s2); } }); // Java 8 Collections.sort(strings, (s1, s2) -> s1.compareTo(s2)); Same thing different syntax
  3. 3. Programmer ● http://office.naver.com
  4. 4. 오! 벌써 새벽 3시네, 컴퓨 터 끄고 자야 겠어! Programmer ● http://daewon.github.io/ 한 시간 후 ...
  5. 5. Overview ● ● Scala Java8 features ○ ○ lambda ■ benefit of lambda expressions comparison to Scala
  6. 6. ● ● ● Scalable Language Born in 2003 Object-Oriented Meets Functional
  7. 7. Martin odersky ● ● Designed the Scala programming language Generic Java, and built the current generation of javac, the Java compiler
  8. 8. Features ● ● ● ● ● ● SEAMLESS JAVA INTEROP TYPE INFERENCE CONCURRENCY & DISTRIBUTION TRAITS PATTERN MATCHING HIGHER-ORDER FUNCTIONS
  9. 9. Scala is used in many worldclass companies
  10. 10. Rod johnson joins typesafe ● ● Creator of Spring Keynote at ScalaDays 2013 ○ Scala in 2018
  11. 11. ● ● ● Lambda Expressions Method References Virtual Extension Methods
  12. 12. ● ● ● Lambda Expressions Method References Virtual Extension Methods
  13. 13. Project Lambda - JSR 335
  14. 14. 2006 - Gosling: "We will never have closures in Java" 2008 - Reinhold: "We will never have closures in Java" Project Lambda
  15. 15. 2007 - 3 different proposals for closures in Java 2009 - Start of project Lambda (JSR 335) Project Lambda
  16. 16. JDK 8: General Availability - 2014/04/18 ○ ○ ○ ○ 2006 2007 2008 2009 - Gosling: "We will never have closures in Java" 3 different proposals for closures in Java Reinhold: "We will never have closures in Java" Start of project Lambda (JSR 335)
  17. 17. Lambda? ● ● ● ● lambda calculus anonymous function function literal closure
  18. 18. Lambda? ● ● ● ● lambda calculus anonymous function function literal closure
  19. 19. Anonymous Function Wikipedia ● function defined, and possibly called, without being bound to an identifier.
  20. 20. 익명 함수 Wikipedia ● 특정 식별자 없이 정의되거나 호출될 수 있는 함수
  21. 21. 익명 함수 Wikipedia ● 특정 식별자 없이 정의되거나 호출될 수 있는 함수
  22. 22. Languages that support anonymous functions ActionScript Ada C C# C++ Clojure Curl D Dart Dylan Erlang Elixir F# Frink Go Gosu Groovy Haskell Java JavaScript Lisp Logtalk Lua Mathematica Maple Matlab Maxima OCaml Octave Object Pascal Objective-C Pascal Perl PHP Python R Racket Ruby Scala Scheme Smalltalk Standard ML TypeScript Tcl Vala Visual Basic .NET Visual Prolog
  23. 23. Languages that no support anonymous functions ActionScript Ada C C# C++ Clojure Curl D Dart Dylan Erlang Elixir F# Frink Go Gosu Groovy Haskell Java JavaScript Lisp Logtalk Lua Mathematica Maple Matlab Maxima OCaml Octave Object Pascal Objective-C Pascal Perl PHP Python R Racket Ruby Scala Scheme Smalltalk Standard ML TypeScript Tcl Vala Visual Basic .NET Visual Prolog
  24. 24. Languages that no support anonymous functions ActionScript Ada (1977) C (1969) C# C++ Clojure Curl D Dart Dylan Erlang Elixir F# Frink Go Gosu Groovy Haskell Java JavaScript Lisp Logtalk Lua Mathematica Maple Matlab Maxima OCaml Octave Object Pascal Objective-C Pascal (1969) Perl PHP Python R Racket Ruby Scala Scheme Smalltalk Standard ML TypeScript Tcl Vala Visual Basic .NET Visual Prolog
  25. 25. Languages that no support anonymous functions ActionScript Ada C C# C++ Clojure Curl D Dart Dylan Erlang Elixir F# Frink Go Gosu Groovy Haskell Java (1995) JavaScript Lisp Logtalk Lua Mathematica Maple Matlab Maxima OCaml Octave Object Pascal Objective-C Pascal Perl PHP Python R Racket Ruby Scala Scheme Smalltalk Standard ML TypeScript Tcl Vala Visual Basic .NET Visual Prolog
  26. 26. Java8 support Lambda ● General Availability - 2014/04/18
  27. 27. Lambda syntax ● (parameters) -> { body } ● (int x, int y) -> { return x + y; } Lambda Syntax
  28. 28. Lambda syntax ● ● ● ● (param) -> {return 100} (param) -> {100} (param) -> 100 param -> 100 Lambda Syntax
  29. 29. Lambda syntax ● ● ● ● (param) -> {return 100} (param) -> {100} (param) -> 100 param -> 100 Lambda Syntax
  30. 30. Lambda syntax ● ● ● ● (param) -> {return 100} (param) -> {100} (param) -> 100 param -> 100 Lambda Syntax
  31. 31. Lambda syntax ● ● ● ● (param) -> {return 100} (param) -> {100} (param) -> 100 param -> 100 Lambda Syntax
  32. 32. Lambda syntax ● ● ● ● (param) -> {return 100} (param) -> {100} (param) -> 100 param -> 100 Lambda Syntax
  33. 33. Lambda syntax ● ● ● ● ● ● x -> x + 1 (x) -> x + 1 (int x) -> x + 1 (int x, int y) -> x + y (x, y) -> { System.out.println(x + y) } () -> { System.out.println("runnable!"); } Lambda Syntax
  34. 34. Storing Lambda ● ● ● int n = 10; String name = “daewon”; ? adder = (int x, int y) -> x + y
  35. 35. Storing Lambda ● ● ● int n = 10; String name = “daewon”; ? adder = (int x, int y) -> x + y
  36. 36. @Functional Interface ● Lambda Expression -> Anonymous Inner Class
  37. 37. Replace with Lambda
  38. 38. @FunctionalInterface interface Adder { int add(int a, int b); } ????? func = (int a, int b) -> { return a + b }; Adder shortFunc = (a, b) -> a + b; Functional Interface
  39. 39. @FunctionalInterface interface Adder { int add(int a, int b); } Adder func = (int a, int b) -> { return a + b }; Adder shortFunc = (a, b) -> a + b; Functional Interface
  40. 40. @FunctionalInterface interface Adder { int add(int a, int b); } Adder func = (int a, int b) -> { return a + b }; Adder shortFunc = (a, b) -> a + b; Type Inference
  41. 41. Predefined Functional Interfaces BiConsumer<T,U> BiFunction<T,U,R> BinaryOperator<T> BiPredicate<T,U> BooleanSupplier Consumer<T> DoubleBinaryOperator DoubleConsumer DoubleFunction<R> DoublePredicate DoubleSupplier DoubleToIntFunction DoubleToLongFunction DoubleUnaryOperator Function<T,R> IntBinaryOperator IntConsumer IntFunction<R> IntPredicate IntSupplier IntToDoubleFunction IntToLongFunction IntUnaryOperator LongBinaryOperator LongConsumer LongFunction<R> LongPredicate LongSupplier LongToDoubleFunction LongToIntFunction LongUnaryOperator ObjDoubleConsumer<T> ObjIntConsumer<T> ObjLongConsumer<T> Predicate<T> Supplier<T>
  42. 42. Lambda in Java ● ● anonymous inner class lambda expressions
  43. 43. // Spring jdbcTemplate.queryForObject("select * from student where id = ?", new Object[]{1212l}, new RowMapper() { public Object mapRow(ResultSet rs, int n) throws SQLException { return new Student(rs.getString("name"), rs.getInt("age")); } }); // Google Guava Iterables.filter(persons, new Predicate<Person>() { public boolean apply(Person p) { return p.getAge() > 18; } }); Lambda in Java
  44. 44. // Spring jdbcTemplate.queryForObject("select * from student where id = ?", new Object[]{1212l}, new RowMapper() { public Object mapRow(ResultSet rs, int n) throws SQLException { return new Student(rs.getString("name"), rs.getInt("age")); } }); // Google Guava Iterables.filter(persons, new Predicate<Person>() { public boolean apply(Person p) { return p.getAge() > 18; } }); Lambda in Java
  45. 45. // Before Java 8 Collections.sort(strings, new Comparator<String>() { @Override public int compare(String s1, String s2) { return s1.compareTo(s2); } }); // Java 8 Collections.sort(strings, (s1, s2) -> s1.compareTo(s2)); Bulky syntax!
  46. 46. // Java 8 Collections.sort(strings, (s1, s2) -> s1.compareTo(s2)); Clear syntax!
  47. 47. // Before Java 8 Collections.sort(strings, new Comparator<String>() { @Override public int compare(String s1, String s2) { return s1.compareTo(s2); } }); // Java 8 Collections.sort(strings, (s1, s2) -> s1.compareTo(s2)); Same thing different syntax
  48. 48. Functions are Data ● ● ● function as parameter function as return value lazy eval
  49. 49. 함수는 데이터 ● ● ● 함수를 다른 함수에 인자로 사용 함수를 함수의 반환 값으로 사용 지연 평가
  50. 50. 함수는 데이터 ● ● ● 함수를 다른 함수에 인자로 사용 함수를 함수의 반환값으로 사용 지연 평가
  51. 51. Functions as parameter - Loan Pattern ● scala_for_java_programmer
  52. 52. public void withFile(String fileName) { BufferedReader bufferedReader = null; try { bufferedReader = new BufferedReader(new FileReader(filename)); String line = null; while ((line = bufferedReader.readLine()) != null) { System.out.println(line); } } catch (IOException ex) { ex.printStackTrace(); } finally { if (bufferedReader != null) bufferedReader.close(); } } Print each line to STDOUT
  53. 53. public void withFile(String fileName) { BufferedReader bufferedReader = null; try { bufferedReader = new BufferedReader(new FileReader(filename)); String line = null; while ((line = bufferedReader.readLine()) != null) { DB.store(line); } } catch (IOException ex) { ex.printStackTrace(); } finally { if (bufferedReader != null) bufferedReader.close(); } } Store each line to DB
  54. 54. public void withFile(String fileName) { BufferedReader bufferedReader = null; try { bufferedReader = new BufferedReader(new FileReader(filename)); String line = null; while ((line = bufferedReader.readLine()) != null) { // insert code at here } } catch (IOException ex) { ex.printStackTrace(); System.out.println(line); } finally { if (bufferedReader != null) DB.store(line); bufferedReader.close(); } } Duplicate and Variation
  55. 55. public void withFile(String fileName, Consumer<String> work) { BufferedReader bufferedReader = null; try { bufferedReader = new BufferedReader(new FileReader(filename)); String line = null; while ((line = bufferedReader.readLine()) != null) { work.accept(line); } } catch (IOException ex) { ex.printStackTrace(); } finally { if (bufferedReader != null) bufferedReader.close(); } } Refactoring with Lambda
  56. 56. public void withFile(String fileName, Consumer<String> work) { BufferedReader bufferedReader = null; try { bufferedReader = new BufferedReader(new FileReader(filename)); String line = null; while ((line = bufferedReader.readLine()) != null) { work.accept(line); } } catch (IOException ex) { ex.printStackTrace(); } finally { if (bufferedReader != null) bufferedReader.close(); } } Refactoring with Lambda
  57. 57. // print each line to stdout withFile(filename, line -> System.out.println(line)); // store each line to db withFile(filename, line -> storeToDb(line)); // print and store each line withFile(filename, line -> { System.out.println(line) storeToDb(line); }); Refactoring with Lambda
  58. 58. // print each line to stdout withFile(filename, line -> System.out.println(line)); // store each line to db withFile(filename, line -> storeToDb(line)); Refactoring with Lambda
  59. 59. // Scala def withFile(filename: String)(work: String => Unit) { Source.fromFile(filename).getLines.forEach work } Scala
  60. 60. // Scala def withFile(filename: String)(work: String => Unit) { Source.fromFile(filename).getLines.forEach work } Scala
  61. 61. // Java8 - print each line to stdout withFile(filename, line -> System.out.println(line)); // Java8 - store each line to db withFile(filename, line -> storeToDb(line)); // Scala - print each line to stdout withFile(filename) { line => println(line) } // Scala - store each line to db withFile(filename) { line => storeToDb(line) } Multiple parameter lists(curried function)
  62. 62. Lambda with Collections ● ● Imperative - external iteration Functional - internal iteration
  63. 63. // External Iterator for (Iterator iter = var.iterator(); iter.hasNext(); ) { Object obj = iter.next(); // Operate on obj } // Internal Iterator var.each( new Functor() { public void operate(Object arg) { arg *= 2; } }); Internal iterator? External iterator?
  64. 64. // External Iterator for (Iterator iter = var.iterator(); iter.hasNext(); ) { Object obj = iter.next(); // Operate on obj } // Internal Iterator var.each( new Functor() { public void operate(Object arg) { arg *= 2; } }); When you pass a function object to a method to run over a collection, that is an internal iterator
  65. 65. // External Iterator for (Iterator iter = var.iterator(); iter.hasNext(); ) { Object obj = iter.next(); // Operate on obj } // Internal Iterator var.each( new Functor() { public void operate(Object arg) { arg *= 2; } }); 컬렉션을 순회하는 동안 특정 행동을 하는 함수 객체를 전달하는 방식을 내부 반복자라고 한다
  66. 66. // External Iterator for (Iterator iter = var.iterator(); iter.hasNext(); ) { Object obj = iter.next(); // Operate on obj } // Internal Iterator var.each( new Functor() { public void operate(Object arg) { arg *= 2; } }); 컬렉션을 순회하는 동안 특정 행동을 하는 함수 객체를 전달하는 방식을 내부 반복자라고 한다
  67. 67. // Java8:: print each line to stdout withFile(filename, line -> System.out.println(line)); // Java8 - store each line to db withFile(filename, line -> storeToDb(line)); // Scala - print each line to stdout withFile(filename) { line => println(line) } // Scala:: store each line to db withFile(filename) { line => storeToDb(line) } Internal iterator
  68. 68. // Java8:: print each line to stdout withFile(filename, line -> System.out.println(line)); // Java8 - store each line to db withFile(filename, line -> storeToDb(line)); // Scala - print each line to stdout withFile(filename) { line => println(line) } // Scala:: store each line to db withFile(filename) { line => storeToDb(line) } Iterator
  69. 69. No more loop with Scala ● ● Project Lambda J Google guava-libraries/
  70. 70. case class Person(firstName: String, lastName: String, age:Int, male: Boolean) case class Sale(buyer: Person, seller: Person, car: Car, cost: Double) case class Car(brand: String, model: String, year: Int, originalValue: Double) LambdaJ Demo Data Model
  71. 71. object db { // car val sonata = Car("Hyundai", "Sonata", 1982, 30000000) val santafe = Car("Hyundai", "Santafe", 1990, 50000000) val k7 = Car("KIA", "K7", 2000, 50000000) val k9 = Car("KIA", "K9", 2008, 70000000) val orlando = Car("GM", "Orlando", 2011, 30000000) val chevrolet = Car("GM", "Chevrolet", 2010, 50000000) val alpheon = Car("GM", "Alpheon", 2012, 70000000) def cars = List(sonata, santafe, k7, k9, orlando, chevrolet, alpheon); // person val daewon = Person("daewon", "jeong", 31, true) val youngtek = Person("youngtek", "hong", 32, true) val jiwong = Person("jiwong", "kang", 34, true) val taehee = Person("taehee", "kim", 32, false) def persons = List(youngtek, daewon, jiwong, taehee) // sales: map person/car def sales = List(Sale(daewon, taehee, sonata, 30000000), Sale(daewon, youngtek, santafe, 50000000), Sale(daewon, jiwong, santafe, 50000000), Sale(jiwong, taehee, santafe, 50000000), Sale(taehee, daewon, chevrolet, 50000000), Sale(youngtek, daewon, chevrolet, 50000000), Sale(youngtek, taehee, orlando, 30000000), Sale(taehee, jiwong, chevrolet, 30000000)) }
  72. 72. // Iterative version List<Sale> salesOfAHyundai = new ArrayList<Sale>(); for (Sale sale : sales) { if (sale.getCar().getBrand().equals("Hyundai")) { salesOfAHyundai.add(sale); } } // Functional version val salesOfHyundai = db.sales.filter(_.car.brand == "Hyundai") 현대차를 판매하는 모든 Sales객체를 선택
  73. 73. // Iterative version List<Sale> salesOfAHyundai = new ArrayList<Sale>(); for (Sale sale : sales) { if (sale.getCar().getBrand().equals("Hyundai")) { salesOfAHyundai.add(sale); } } // Functional version val salesOfHyundai = db.sales.filter(_.car.brand == "Hyundai") sales 목록에서 car brand가 Hyundai인 것만 필터링
  74. 74. // Iterative version List<Sale> salesOfAHyundai = new ArrayList<Sale>(); for (Sale sale : sales) { if (sale.getCar().getBrand().equals("Hyundai")) { salesOfAHyundai.add(sale); } } // Functional version val salesOfHyundai = db.sales.filter(_.car.brand == "Hyundai") Select all sales of Hyundai
  75. 75. // Iterative version List<Double> costs = new ArrayList<Double>(); for (Car car : cars) { costs.add(car.getOriginalValue()); } // Functional version val costs = db.cars.map(_.originalValue) 자동차에 Original 가격 목록을 작성
  76. 76. // Iterative version List<Double> costs = new ArrayList<Double>(); for (Car car : cars) { costs.add(car.getOriginalValue()); } // Functional version val costs = db.cars.map(_.originalValue) cars 목록으로부터 originalValue를 추출해서 새 목록을 작성
  77. 77. // Iterative version List<Double> costs = new ArrayList<Double>(); for (Car car : cars) { costs.add(car.getOriginalValue()); } // Functional version val costs = db.cars.map(_.originalValue) Extract car’s original cost
  78. 78. // Iterative version double maxCost = 0.0; for (Sale sale : sales) { double cost = sale.getCost(); if (cost > maxCost) { maxCost = cost; } } // Functional version val maxCost = db.sales.maxBy(_.cost).cost 가장 비싸게 판매한 값은?
  79. 79. // Iterative version double maxCost = 0.0; for (Sale sale : sales) { double cost = sale.getCost(); if (cost > maxCost) { maxCost = cost; } } // Functional version val maxCost = db.sales.maxBy(_.cost).cost Find most costly sale
  80. 80. // Iterative version // 01. find youngest person in persons Person youngest = null; for (Person person : persons){ if (youngest == null || person.getAge() < youngest.getAge()) { youngest = person; } } // 02. find buyer have age equal to younggest person List<Sale> buys = new ArrayList<Sale>(); for (Sale sale : sales){ if (sale.getBuyer().equals(youngest)) { buys.add(sale); } } // Functional version val youngestPerson = db.persons.minBy( _.age ) val buys = db.sales.filter( _.buyer == youngestPerson ) 가장 어린 사람과 나이가 같은 판매자들 찾기
  81. 81. // Iterative version // 01. find youngest person in persons Person youngest = null; for (Person person : persons){ if (youngest == null || person.getAge() < youngest.getAge()) { youngest = person; } } // 02. find buyer have age equal to younggest person List<Sale> buys = new ArrayList<Sale>(); for (Sale sale : sales){ if (sale.getBuyer().equals(youngest)) { buys.add(sale); } } // Functional version val youngestPerson = db.persons.minBy( _.age ) val buys = db.sales.filter( _.buyer == youngestPerson ) Find buys of youngest person
  82. 82. // 01. 가장 어린 사람을 찾고 val youngestPerson = db.persons.minBy( _.age ) // 02. 가장 어린 사람과 나이가 같은 판매자들을 찾는다. val buys = db.sales.filter( _.buyer == youngestPerson ) Find buys of youngest person
  83. 83. // Iterative version Map<String, List<Car>> carsByBrand = new HashMap<>(); for (Car car : db.getCars()) { List<Car> carList = carsByBrand.get(car); if (carList == null){ carList = new ArrayList<Car>(); carsByBrand.put(car.getBrand(), carList); } carList.add(car); } // Functional version val carsByBrand = db.cars.groupBy(_.brand) brand 기준으로 car를 그루핑
  84. 84. // Iterative version Map<String, List<Car>> carsByBrand = new HashMap<>(); for (Car car : db.getCars()) { List<Car> carList = carsByBrand.get(car); if (carList == null){ carList = new ArrayList<Car>(); carsByBrand.put(car.getBrand(), carList); } carList.add(car); } // Functional version val carsByBrand = db.cars.groupBy(_.brand) Select * from cars group by brand
  85. 85. // Iterative version Map<String, List<Car>> carsByBrand = new HashMap<>(); for (Car car : db.getCars()) { List<Car> carList = carsByBrand.get(car); if (carList == null){ carList = new ArrayList<Car>(); carsByBrand.put(car.getBrand(), carList); } carList.add(car); } // Functional version val carsByBrand = db.cars.groupBy(_.brand) Index cars by brand
  86. 86. // Iterative version Map<Car, Integer> carsBought = new HashMap<Car, Integer>(); for (Sale sale : sales) { Car car = sale.getCar(); int boughtTimes = carsBought.get(car); carsBought.put(car, boughtTimes == null ? 1 : boughtTimes+1); } Car mostBoughtCarIterative = null; int boughtTimesIterative = 0; for (Entry<Car, Integer> entry : carsBought.entrySet()) { if (entry.getValue() > boughtTimesIterative) { mostBoughtCarIterative = entry.getKey(); boughtTimesIterative = entry.getValue(); } } 가장 많이 구매한 차
  87. 87. // Functional version val carsBought = db.sales.groupBy( _.car ).mapValues( _.length ) val mostBoughtCar = carsBought.maxBy { case (_, boughtCount) => boughtCount }._1 val boughtTimes = carsBought(mostBoughtCar) Find most bought car
  88. 88. // Functional version val carsBought = db.sales.groupBy( _.car ).mapValues( _.length ) val mostBoughtCar = carsBought.maxBy { case (_, boughtCount) => boughtCount }._1 val boughtTimes = carsBought(mostBoughtCar) Find most bought car
  89. 89. // Iterative version Map<Person,Map<Person,Sale>> map = new HashMap<Person, Map<Person,Sale>>(); for (Sale sale : sales) { Person buyer = sale.getBuyer(); Map<Person, Sale> buyerMap = map.get(buyer); if (buyerMap == null) { buyerMap = new HashMap<Person, Sale>(); map.put(buyer, buyerMap); } buyerMap.put(sale.getSeller(), sale); } Person youngest = null; Person oldest = null; for (Person person : persons) { if (youngest == null || person.getAge() < youngest.getAge()){ youngest = person; } if (oldest == null || person.getAge() > oldest.getAge()) { oldest = person; } } Group sales by Sale saleFromYoungestToOldest = map.get(youngest).get(oldest); buyer and sellers
  90. 90. // Functional version val map = db.sales.groupBy(_.buyer).mapValues{ ls => ls.groupBy(_.seller).mapValues(_.head) } val youngest = db.persons.minBy(_.age) val oldest = db.persons.maxBy(_.age) val saleFromYoungestToOldest = map(youngest)(oldest) Group sales by buyer and sellers
  91. 91. Java8 Streams vs Scala For Comprehension ● ● streams and sql ○ how-java-emulates-sql for comprehension
  92. 92. // sql select sum(salary) from people where gender = 'FEMALE' // Java8 stream with lambda people.stream() .filter(p -> p.getGender() == Person.Gender.FEMALE) .mapToInt(p -> p.getSalary()) .sum(); 모든 여성의 급여의 합
  93. 93. // sql select sum(salary) from people where gender = 'FEMALE' // scala for comprehension (for (p <- people; (if p.gender == Person.Gender.FEMALE)) yield p.salary).sum() Find the sum of all the salaries of all the females.
  94. 94. // sql select sum(salary) from people where gender = 'FEMALE' // scala for comprehension (for (p <- people; (if p.gender == Person.Gender.FEMALE)) yield p.salary).sum() Find the sum of all the salaries of all the females.
  95. 95. // sql select distinct(firstName) from people where gender = 'MALE' // Java8 stream with lambda people.stream() .filter(p -> p.getGender() == Person.Gender.MALE) .map(p -> p.getFirstName()) .distinct() 중복을 제거한 모든 남성의 이름
  96. 96. // sql select distinct(firstName) from people where gender = 'MALE' // scala for comprehension (for (p <- people; if (p.getGender == Person.Gender.MALE)) yield p.firstName).distinct Prepare a list of all (distinct) first names of the males
  97. 97. // sql select distinct(firstName) from people where gender = 'MALE' // scala for comprehension (for (p <- people; if (p.getGender == Person.Gender.MALE)) yield p.firstName).distinct Prepare a list of all (distinct) first names of the males
  98. 98. // sql 나이가 가장 많은 남자들 select * from people where age = (select max(age) from people where gender ='MALE' ) and gender ='MALE' // Java8 int maxAge = people.stream().max( (p1, p2) -> p1.getAge() - p2.getAge()).get()); people.stream() .filter(p -> p.getGender() == Person.Gender.MALE && p.getAge() == max_age) .collect(Collections.toList())); // scala for comprehension for { maxAge <- Seq(person.maxBy(_.age)); p <- people; if (p.age == maxAge && p.gender == Person.Gender.MALE) } yield p
  99. 99. Is Java8 a functional language? ● What is Functional Programming? ○ Immutable state ○ Functions as first class citizens ○ Persistent data structure
  100. 100. Immutable ● ● No setter Variable must be final final int i = 0; while(i < 5) { System.out.println("compile error!"); i++; }
  101. 101. Persistent Data Structure
  102. 102. Java8 ● ● ● Immutable state Functions as first class citizens Persistent data structure Scala ● ● ● Immutable state Functions as first class citizens Persistent data structure
  103. 103. Java8 is not a functional language. ● ● ● So what? Real-world programming isn't always perfectly functional Java is steel the most popular language in the world Functional programming is not a silver bullet
  104. 104. 자바는 함수형 언어가 아닙니다. ● ● ● 그래서요? Real-world 문제가 항상 함수형에 적합하지는 않습니다 자바는 여전히 세계에서 가장 많이 쓰이고 있는 언어입니다 함수형 언어는 은탄환이 아닙니다
  105. 105. Java8 is Good! Scala is Best!
  106. 106. One more thing ● Lambda? Closure?
  107. 107. Lambda? Closure? // lambda is just an anonymous function Collection.filter(lists, e ‑> e.length() >= 5) // closure is function that closes over the environment it was defined int min = 5; Collection.filter(lists, e -> e.length() >= min);
  108. 108. Lambda? Closure? // lambda is just an anonymous function Collection.filter(lists, e ‑> e.length() >= 5) // closure is function that closes over the environment it was defined int min = 5; Collection.filter(lists, e -> e.length() >= min);
  109. 109. Lazy eval - Better logging with Lambda
  110. 110. // log message only debug mode public void debug(String message) { if (log.isDebugEnabled()) { log.log(message); } } debug(some.expensive("operation")); log expensive operation
  111. 111. // log message only debug mode public void debug(String message) { if (log.isDebugEnabled()) { log.log(message); } } debug(some.expensive("operation")); log expensive operation
  112. 112. // log message only debug mode public void debug(Consumer<String> consumer) { if (log.isDebugEnabled()) { log.log(consumer.accept()); } } debug(() -> some.expensive("operation")); log expensive operation with Lambda
  113. 113. // log message only debug mode public void debug(Consumer<String> consumer) { if (log.isDebugEnabled()) { log.log(consumer.accept()); } } debug(() -> some.expensive("operation")); log expensive operation with Lambda
  114. 114. // without Lambda debug(some.expensive("operation")); // with Lambda debug(() -> some.expensive("operation")); bulk syntax!
  115. 115. // Scala def debug(message: => String) { if (log.isDebugEnabled) log.log(message) } debug(some.expensive("operation")) Lazy eval in Scala
  116. 116. // Scala def debug(message: => String) { if (log.isDebugEnabled) log.log(message) } debug(some.expensive("operation")) Lazy eval in Scala
  117. 117. // Java:: Eager eval debug(some.expensive("operation")); // Java8:: Lazy eval debug(() -> some.expensive("operation")); // scala:: Lazy eval debug(some.expensive("operation"))
  118. 118. Question => Answer
  119. 119. // quiz Lambda를 저장시 사용되는 인터페이스에 사용되는 Annotation은? 경품!

×