함수적 사고 2장

HyeonSeok Choi
HyeonSeok ChoiSoftware Developer um ktds
Functional Thinking
Ch2. 전환
아꿈사
Cecil
함수형 코드를 작성하기 위해서는
프로그래밍 언어의 전환이 필요한 것이 아니라
문제에 접근하는 방식의 전환이 필요
명령형 처리 vs 함수형 처리
예제: 문자열 연결
명령형 처리(Java)
public class TheCompanyProcess {

public String cleanNames(List<String> listOfNames) {

StringBuilder result = new StringBuilder();

for (int i = 0; i < listOfNames.size(); i++) { // loop 사용이 일반적

if (listOfNames.get(i).length() > 1) {

// 한 문자 이상인 문자열을 연결

result.append(capitalizeString(listOfNames.get(i))).append(",");

}

}

return result.substring(0, result.length() - 1).toString();

}



public String capitalizeString(String s) {

return s.substring(0, 1).toUpperCase() + s.substring(1, s.length());

}

}
함수형 처리(scala)
val employees = List("neal", "s", "stu", "j", "rich", "bob", "aiden",
"j", "ethan", "liam", "mason", "noah", "lucas",
"jacob", "jayden", “jack")


val result = employees

.filter(_.length() > 1) // 필터

.map(_.capitalize) // 변형(Transform)

.reduce(_ + "," + _) // 변환(convert)
수학 공식을 모델링하는 표현과 변형으로 기술하며, 가변 상태를 지양
무엇이 다른가?
명령형 처리: How를 기술
함수형 처리: What을 기술
문자열 예제의 What?
1. len(x) > 1인 큰 문자열을 찾음
2. 대문자로 변환
3. 문자열을 연결
Java 8
public class Process {

public String cleanNames(List<String> names) {

if (names == null) return "";

return names.stream() // stream을 생성

.filter(name -> name != null)

.filter(name -> name.length() > 1)

.map(name -> capitalize(name))

.collect(Collectors.joining(",")); // reduce의 특별한 경우

}



private String capitalize(String e) {

return e.substring(0, 1).toUpperCase() + e.substring(1, e.length());

}

}
Groovy
public class TheCompanyProcess {

public static String cleanUpNames(listOfNames) {

listOfNames

.findAll { it.length() > 1 } // 필터

.collect { it.capitalize() } // 변형

.join ',' // 변환

}

}
Clojure
; 기본적인 clojure 버전
; 리스프 계열 언어는 안에서 밖으로 실행됨.

(defn process [list-of-emps]

(reduce str (interpose ","

(map s/capitalize

(filter #(< 1 (count %)) list-of-emps)

))))



; 매크로를 사용한 가독성 향상 버전

(defn process2 [list-of-emps]

(->> list-of-emps

(filter #(< 1 (count %)))

(map s/capitalize)

(interpose ",")

(reduce str)

))
함수형 사고로의 전환은?
세부적인 구현에 뛰어들지 않고
고수준의 추상 개념을 적용하는 것
고수준 추상적 사고의 이점
문제를 다른 시각에서 분류할 수 있게 함
런타임에 최적화가 가능(작업 순서 조정)
개발자가 엔진 세부사항을 고려하지 않으면 할 수 없던 일을
가능하게 함(ex: 병렬 처리)
고수준 추상화의 스레드 적용
// Scala

val parallelResult = employees

.par // 스레드로 처리

.filter(_.length() > 1)

.map(_.capitalize)

.reduce(_ + "," + _)
// java 8

public String cleanNamesP(List<String> names) {
if (names == null) return "";

return names

.parallelStream() // 스레드로 처리

.filter(n -> n.length() > 1)

.map(e -> capitalize(e))

.collect(Collectors.joining(","));

}
사례 연구
예제: 자연수의 분류
6(완전수) = 1 + 2 +3
분류 조건
완전수 N의 진약수의 합 = N
과잉수 N의 진약수의 합 > N
부족수 N의 진약수의 합 < N
명령형 자연수 분류
public class ImpNumberClassifierSimple {

private int _number;

private Map<Integer, Integer> _cache; // 내부 캐시



public ImpNumberClassifierSimple(int targetNumber) {

_number = targetNumber;

_cache = new HashMap<>();

}

// 약수인가?

public boolean isFactor(int potential) {

return _number % potential == 0;

}


public boolean isPerfect() {

return aliquotSum() == _number;

}

public boolean isAbundant() {

return aliquotSum() > _number;

}

public boolean isDeficient() {

return aliquotSum() < _number;

}
// 진약수 구하기

public Set<Integer> getFactors() {

Set<Integer> factors = new HashSet<>();

factors.add(1);

factors.add(_number);

for (int i = 2; i < _number; i++)

if (isFactor(i)) factors.add(i);

return factors;

}

// 진약수의 합

public int aliquotSum() {

if (_cache.get(_number) == null) {

int sum = 0;

for (int i : getFactors())

sum += i;

_cache.put(_number, sum - _number);

}

return _cache.get(_number);

}

}
Java 8을 사용한 자연수 분류
public class NumberClassifier {

// 함수 호출시 실제 작업이 수행되는 것이 아님. stream을 반환

public static IntStream factorsOf(int number) {

return range(1, number + 1)

.filter(potential -> number % potential == 0);

}

// sum 내부에서 stream을 해석 

public static int aliquotSum(int number) {

return factorsOf(number).sum() - number;

}



public static boolean isPerfect(int number) {

return aliquotSum(number) == number;

}



public static boolean isAbundant(int number) {

return aliquotSum(number) > number;

}



public static boolean isDeficient(int number) {

return aliquotSum(number) < number;

}

}
함수형 언어의 공통된 빌딩 블록
필터, 맵, 폴드/리듀스
필터
Figure 2-1. Filtering a list of numbers from a larger list
When filtering, you produce another list (or collection) potentially smaller than the
original, depending on the filtering criteria. In the number-classifier example, I use
filtering to determine the factors of a number, as shown in Example 2-14.
Example 2-14. Filtering in Java 8
public static IntStream factorsOf(int number) {
return range(1, number + 1)
.filter(potential -> number % potential == 0);
}
The code in Example 2-14 creates a range of numbers from 1 to the target number, then
사용자가 지정한 조건으로 목록을 더 작은 목록으로 만드는 작업
public static IntStream factorsOf(int number) {

return range(1, number + 1)

.filter(potential -> number % potential == 0);

}
맵
리스트의 각 요소에 같은 함수를 적용하여 새로운 리스트를 생성
// 약수 구하기 최적화 버전.

static def factors(number) {

def factors = (1..round(sqrt(number)+1)).findAll({number % it == 0})

(factors + factors.collect {number / it}).unique()

}
Figure 2-2. Mapping a function onto a collection
To illustrate map() and related transformations, I create an optimized version of my
number classifier. First, I create an imperative version, shown in Example 2-16.
Example 2-16. Number classifier optimized
import java.util.HashMap;
import java.util.HashSet;
폴드/리듀스
Figure 2-3. Fold operation
Because addition is commutative, it doesn’t matter if you do a foldLeft() or fold
Right(). But some operations (including subtraction and division) care about order,
so the foldRight() method exists to handle those cases. In purely functional languages,
leftandrightfoldshaveimplementationdifferences.Forexample,rightfoldscanoperate
on infinite lists whereas left folds cannot.
Example 2-13 uses the Functional Java-supplied add enumeration; the framework in‐
cludes the most common mathematical operations for you. But what about cases in
누산기(Accumulator)를 사용해서 값을 모으는 작업
reduce, foldLeft => (f (f (f (f 0,N1) N2) N3) N4)
foldRight => (f N1 (f N2 (f N3 (f N4 0))))
foldLeft
언어별 용어 차이
필터
• Scala
• filter, partition, find, takeWhile, DropWhile
• Groovy
• findAll(filter), split(partition), takeWhile, DropWhile
• Clojure
• filter
맵
• Scala
• map, flatMap
• Groovy
• collect(Map), flatten(flatMap)
• Clojure
• map, flatten(flatMap)
폴드/리듀스
• Scala
• reduceLeft, reduceRight, foldLeft, foldRight
• Groovy
• inject(reduce)
• Clojure
• reduce
References
•Neal Ford, Functional Thinking(김재완 옮김). 서울
시 마포구 양화로 한빛미디어, 2016.
1 von 24

Recomendados

7가지 동시성 모델 - 3장. 함수형 프로그래밍 von
7가지 동시성 모델 - 3장. 함수형 프로그래밍7가지 동시성 모델 - 3장. 함수형 프로그래밍
7가지 동시성 모델 - 3장. 함수형 프로그래밍Hyunsoo Jung
698 views22 Folien
7가지 동시성 모델 4장 von
7가지 동시성 모델 4장7가지 동시성 모델 4장
7가지 동시성 모델 4장HyeonSeok Choi
376 views21 Folien
7가지 동시성 모델 - 데이터 병렬성 von
7가지 동시성 모델 - 데이터 병렬성7가지 동시성 모델 - 데이터 병렬성
7가지 동시성 모델 - 데이터 병렬성HyeonSeok Choi
3K views25 Folien
Startup JavaScript 5 - 객체(Date, RegExp, Object, Global) von
Startup JavaScript 5 - 객체(Date, RegExp, Object, Global)Startup JavaScript 5 - 객체(Date, RegExp, Object, Global)
Startup JavaScript 5 - 객체(Date, RegExp, Object, Global)Circulus
1.3K views20 Folien
Startup JavaScript 6 - 함수, 스코프, 클로저 von
Startup JavaScript 6 - 함수, 스코프, 클로저Startup JavaScript 6 - 함수, 스코프, 클로저
Startup JavaScript 6 - 함수, 스코프, 클로저Circulus
1.5K views16 Folien
Startup JavaScript 4 - 객체 von
Startup JavaScript 4 - 객체Startup JavaScript 4 - 객체
Startup JavaScript 4 - 객체Circulus
1.5K views18 Folien

Más contenido relacionado

Was ist angesagt?

Startup JavaScript 3 - 조건문, 반복문, 예외처리 von
Startup JavaScript 3 - 조건문, 반복문, 예외처리Startup JavaScript 3 - 조건문, 반복문, 예외처리
Startup JavaScript 3 - 조건문, 반복문, 예외처리Circulus
2K views18 Folien
2.Startup JavaScript - 연산자 von
2.Startup JavaScript - 연산자2.Startup JavaScript - 연산자
2.Startup JavaScript - 연산자Circulus
2.7K views19 Folien
자바8 스트림 API 소개 von
자바8 스트림 API 소개자바8 스트림 API 소개
자바8 스트림 API 소개beom kyun choi
49.3K views20 Folien
NDC14 - Rx와 Functional Reactive Programming으로 고성능 서버 만들기 von
NDC14 - Rx와 Functional Reactive Programming으로 고성능 서버 만들기NDC14 - Rx와 Functional Reactive Programming으로 고성능 서버 만들기
NDC14 - Rx와 Functional Reactive Programming으로 고성능 서버 만들기Jong Wook Kim
70.2K views105 Folien
EcmaScript6(2015) Overview von
EcmaScript6(2015) OverviewEcmaScript6(2015) Overview
EcmaScript6(2015) Overviewyongwoo Jeon
3.9K views23 Folien
track2 04. MS는 Rx를 왜 만들었을까? feat. RxJS/ 네이버, 김훈민 von
track2 04. MS는 Rx를 왜 만들었을까? feat. RxJS/ 네이버, 김훈민 track2 04. MS는 Rx를 왜 만들었을까? feat. RxJS/ 네이버, 김훈민
track2 04. MS는 Rx를 왜 만들었을까? feat. RxJS/ 네이버, 김훈민 양 한빛
628 views65 Folien

Was ist angesagt?(20)

Startup JavaScript 3 - 조건문, 반복문, 예외처리 von Circulus
Startup JavaScript 3 - 조건문, 반복문, 예외처리Startup JavaScript 3 - 조건문, 반복문, 예외처리
Startup JavaScript 3 - 조건문, 반복문, 예외처리
Circulus2K views
2.Startup JavaScript - 연산자 von Circulus
2.Startup JavaScript - 연산자2.Startup JavaScript - 연산자
2.Startup JavaScript - 연산자
Circulus2.7K views
자바8 스트림 API 소개 von beom kyun choi
자바8 스트림 API 소개자바8 스트림 API 소개
자바8 스트림 API 소개
beom kyun choi49.3K views
NDC14 - Rx와 Functional Reactive Programming으로 고성능 서버 만들기 von Jong Wook Kim
NDC14 - Rx와 Functional Reactive Programming으로 고성능 서버 만들기NDC14 - Rx와 Functional Reactive Programming으로 고성능 서버 만들기
NDC14 - Rx와 Functional Reactive Programming으로 고성능 서버 만들기
Jong Wook Kim70.2K views
EcmaScript6(2015) Overview von yongwoo Jeon
EcmaScript6(2015) OverviewEcmaScript6(2015) Overview
EcmaScript6(2015) Overview
yongwoo Jeon3.9K views
track2 04. MS는 Rx를 왜 만들었을까? feat. RxJS/ 네이버, 김훈민 von 양 한빛
track2 04. MS는 Rx를 왜 만들었을까? feat. RxJS/ 네이버, 김훈민 track2 04. MS는 Rx를 왜 만들었을까? feat. RxJS/ 네이버, 김훈민
track2 04. MS는 Rx를 왜 만들었을까? feat. RxJS/ 네이버, 김훈민
양 한빛628 views
골때리는 자바스크립트 발표자료 von 욱진 양
골때리는 자바스크립트 발표자료골때리는 자바스크립트 발표자료
골때리는 자바스크립트 발표자료
욱진 양10.5K views
모델링 연습 리뷰 von beom kyun choi
모델링 연습 리뷰모델링 연습 리뷰
모델링 연습 리뷰
beom kyun choi16K views
Javascript function 이해 von Kihoon Kim
Javascript function 이해Javascript function 이해
Javascript function 이해
Kihoon Kim134 views
UML distilled 1장 스터디 발표 자료 von beom kyun choi
UML distilled 1장 스터디 발표 자료UML distilled 1장 스터디 발표 자료
UML distilled 1장 스터디 발표 자료
beom kyun choi3.3K views
[devil's camp] - 알고리즘 대회와 STL (박인서) von NAVER D2
[devil's camp] - 알고리즘 대회와 STL (박인서)[devil's camp] - 알고리즘 대회와 STL (박인서)
[devil's camp] - 알고리즘 대회와 STL (박인서)
NAVER D24.6K views
Learning Node Book, Chapter 5 von Ji Hun Kim
Learning Node Book, Chapter 5Learning Node Book, Chapter 5
Learning Node Book, Chapter 5
Ji Hun Kim2.5K views
스위프트 성능 이해하기 von Yongha Yoo
스위프트 성능 이해하기스위프트 성능 이해하기
스위프트 성능 이해하기
Yongha Yoo25.8K views
Javascript 교육자료 pdf von Hyosang Hong
Javascript 교육자료 pdfJavascript 교육자료 pdf
Javascript 교육자료 pdf
Hyosang Hong4.7K views
Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En... von Young-Beom Rhee
Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...
Javascript 실행 가능한 코드(Executable Code)와 실행 콘텍스트(Execution Context), Lexical En...
Young-Beom Rhee1.9K views
프로그래밍 대회: C++11 이야기 von Jongwook Choi
프로그래밍 대회: C++11 이야기프로그래밍 대회: C++11 이야기
프로그래밍 대회: C++11 이야기
Jongwook Choi46.6K views
Es2015 Simple Overview von Kim Hunmin
Es2015 Simple OverviewEs2015 Simple Overview
Es2015 Simple Overview
Kim Hunmin2.2K views
자바8 람다식 소개 von beom kyun choi
자바8 람다식 소개자바8 람다식 소개
자바8 람다식 소개
beom kyun choi48K views

Similar a 함수적 사고 2장

나에 첫번째 자바8 람다식 지앤선 von
나에 첫번째 자바8 람다식   지앤선나에 첫번째 자바8 람다식   지앤선
나에 첫번째 자바8 람다식 지앤선daewon jeong
2.7K views75 Folien
Functional programming von
Functional programmingFunctional programming
Functional programmingssuserdcfefa
32 views22 Folien
헷갈리는 자바스크립트 정리 von
헷갈리는 자바스크립트 정리헷갈리는 자바스크립트 정리
헷갈리는 자바스크립트 정리은숙 이
7.7K views21 Folien
SpringCamp 2013 : About Jdk8 von
SpringCamp 2013 : About Jdk8SpringCamp 2013 : About Jdk8
SpringCamp 2013 : About Jdk8Sangmin Lee
1.8K views46 Folien
스칼라와 스파크 영혼의 듀오 von
스칼라와 스파크 영혼의 듀오스칼라와 스파크 영혼의 듀오
스칼라와 스파크 영혼의 듀오Taeoh Kim
888 views72 Folien
Scala, Scalability von
Scala, ScalabilityScala, Scalability
Scala, ScalabilityDongwook Lee
2.7K views93 Folien

Similar a 함수적 사고 2장(20)

나에 첫번째 자바8 람다식 지앤선 von daewon jeong
나에 첫번째 자바8 람다식   지앤선나에 첫번째 자바8 람다식   지앤선
나에 첫번째 자바8 람다식 지앤선
daewon jeong2.7K views
헷갈리는 자바스크립트 정리 von 은숙 이
헷갈리는 자바스크립트 정리헷갈리는 자바스크립트 정리
헷갈리는 자바스크립트 정리
은숙 이7.7K views
SpringCamp 2013 : About Jdk8 von Sangmin Lee
SpringCamp 2013 : About Jdk8SpringCamp 2013 : About Jdk8
SpringCamp 2013 : About Jdk8
Sangmin Lee1.8K views
스칼라와 스파크 영혼의 듀오 von Taeoh Kim
스칼라와 스파크 영혼의 듀오스칼라와 스파크 영혼의 듀오
스칼라와 스파크 영혼의 듀오
Taeoh Kim888 views
06장 함수 von 유석 남
06장 함수06장 함수
06장 함수
유석 남1.7K views
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍 von Young-Beom Rhee
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
스파르탄스터디 E04 Javascript 객체지향, 함수형 프로그래밍
Young-Beom Rhee645 views
2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 나의 첫번째 자바8 람다식 (정대원) von JiandSon
2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 나의 첫번째 자바8 람다식 (정대원)2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 나의 첫번째 자바8 람다식 (정대원)
2014.07.26 KSUG와 지앤선이 함께하는 테크니컬 세미나 - 나의 첫번째 자바8 람다식 (정대원)
JiandSon479 views
불어오는 변화의 바람, From c++98 to c++11, 14 von 명신 김
불어오는 변화의 바람, From c++98 to c++11, 14 불어오는 변화의 바람, From c++98 to c++11, 14
불어오는 변화의 바람, From c++98 to c++11, 14
명신 김161 views
Javascript개발자의 눈으로 python 들여다보기 von 지수 윤
Javascript개발자의 눈으로 python 들여다보기Javascript개발자의 눈으로 python 들여다보기
Javascript개발자의 눈으로 python 들여다보기
지수 윤6.6K views
파이썬+함수이해하기 20160229 von Yong Joon Moon
파이썬+함수이해하기 20160229파이썬+함수이해하기 20160229
파이썬+함수이해하기 20160229
Yong Joon Moon5.4K views
12장 상속 (고급) von 유석 남
12장 상속 (고급)12장 상속 (고급)
12장 상속 (고급)
유석 남1.8K views
R 프로그램의 이해와 활용 v1.1 von happychallenge
R 프로그램의 이해와 활용 v1.1R 프로그램의 이해와 활용 v1.1
R 프로그램의 이해와 활용 v1.1
happychallenge5.3K views
Lua 문법 -함수 von Jaehoon Lee
Lua 문법 -함수Lua 문법 -함수
Lua 문법 -함수
Jaehoon Lee1.6K views
Macro & compilation von Ikhoon Eom
Macro & compilationMacro & compilation
Macro & compilation
Ikhoon Eom66 views
RHive tutorial 4: RHive 튜토리얼 4 - UDF, UDTF, UDAF 함수 von Aiden Seonghak Hong
RHive tutorial 4: RHive 튜토리얼 4 - UDF, UDTF, UDAF 함수RHive tutorial 4: RHive 튜토리얼 4 - UDF, UDTF, UDAF 함수
RHive tutorial 4: RHive 튜토리얼 4 - UDF, UDTF, UDAF 함수
Aiden Seonghak Hong2.1K views

Más de HyeonSeok Choi

밑바닥부터시작하는딥러닝 Ch05 von
밑바닥부터시작하는딥러닝 Ch05밑바닥부터시작하는딥러닝 Ch05
밑바닥부터시작하는딥러닝 Ch05HyeonSeok Choi
2K views28 Folien
밑바닥부터시작하는딥러닝 Ch2 von
밑바닥부터시작하는딥러닝 Ch2밑바닥부터시작하는딥러닝 Ch2
밑바닥부터시작하는딥러닝 Ch2HyeonSeok Choi
1.6K views26 Folien
프로그래머를위한선형대수학1.2 von
프로그래머를위한선형대수학1.2프로그래머를위한선형대수학1.2
프로그래머를위한선형대수학1.2HyeonSeok Choi
1.8K views31 Folien
알고리즘 중심의 머신러닝 가이드 Ch04 von
알고리즘 중심의 머신러닝 가이드 Ch04알고리즘 중심의 머신러닝 가이드 Ch04
알고리즘 중심의 머신러닝 가이드 Ch04HyeonSeok Choi
750 views19 Folien
딥러닝 제대로시작하기 Ch04 von
딥러닝 제대로시작하기 Ch04딥러닝 제대로시작하기 Ch04
딥러닝 제대로시작하기 Ch04HyeonSeok Choi
969 views16 Folien
밑바닥부터시작하는딥러닝 Ch05 von
밑바닥부터시작하는딥러닝 Ch05밑바닥부터시작하는딥러닝 Ch05
밑바닥부터시작하는딥러닝 Ch05HyeonSeok Choi
2K views25 Folien

Más de HyeonSeok Choi(20)

밑바닥부터시작하는딥러닝 Ch05 von HyeonSeok Choi
밑바닥부터시작하는딥러닝 Ch05밑바닥부터시작하는딥러닝 Ch05
밑바닥부터시작하는딥러닝 Ch05
HyeonSeok Choi2K views
밑바닥부터시작하는딥러닝 Ch2 von HyeonSeok Choi
밑바닥부터시작하는딥러닝 Ch2밑바닥부터시작하는딥러닝 Ch2
밑바닥부터시작하는딥러닝 Ch2
HyeonSeok Choi1.6K views
프로그래머를위한선형대수학1.2 von HyeonSeok Choi
프로그래머를위한선형대수학1.2프로그래머를위한선형대수학1.2
프로그래머를위한선형대수학1.2
HyeonSeok Choi1.8K views
알고리즘 중심의 머신러닝 가이드 Ch04 von HyeonSeok Choi
알고리즘 중심의 머신러닝 가이드 Ch04알고리즘 중심의 머신러닝 가이드 Ch04
알고리즘 중심의 머신러닝 가이드 Ch04
HyeonSeok Choi750 views
딥러닝 제대로시작하기 Ch04 von HyeonSeok Choi
딥러닝 제대로시작하기 Ch04딥러닝 제대로시작하기 Ch04
딥러닝 제대로시작하기 Ch04
HyeonSeok Choi969 views
밑바닥부터시작하는딥러닝 Ch05 von HyeonSeok Choi
밑바닥부터시작하는딥러닝 Ch05밑바닥부터시작하는딥러닝 Ch05
밑바닥부터시작하는딥러닝 Ch05
HyeonSeok Choi2K views
실무로 배우는 시스템 성능 최적화 Ch8 von HyeonSeok Choi
실무로 배우는 시스템 성능 최적화 Ch8실무로 배우는 시스템 성능 최적화 Ch8
실무로 배우는 시스템 성능 최적화 Ch8
HyeonSeok Choi812 views
실무로 배우는 시스템 성능 최적화 Ch7 von HyeonSeok Choi
실무로 배우는 시스템 성능 최적화 Ch7실무로 배우는 시스템 성능 최적화 Ch7
실무로 배우는 시스템 성능 최적화 Ch7
HyeonSeok Choi366 views
실무로 배우는 시스템 성능 최적화 Ch6 von HyeonSeok Choi
실무로 배우는 시스템 성능 최적화 Ch6실무로 배우는 시스템 성능 최적화 Ch6
실무로 배우는 시스템 성능 최적화 Ch6
HyeonSeok Choi560 views
Logstash, ElasticSearch, Kibana von HyeonSeok Choi
Logstash, ElasticSearch, KibanaLogstash, ElasticSearch, Kibana
Logstash, ElasticSearch, Kibana
HyeonSeok Choi4.2K views
실무로배우는시스템성능최적화 Ch1 von HyeonSeok Choi
실무로배우는시스템성능최적화 Ch1실무로배우는시스템성능최적화 Ch1
실무로배우는시스템성능최적화 Ch1
HyeonSeok Choi1.1K views

함수적 사고 2장

  • 2. 함수형 코드를 작성하기 위해서는 프로그래밍 언어의 전환이 필요한 것이 아니라 문제에 접근하는 방식의 전환이 필요
  • 3. 명령형 처리 vs 함수형 처리 예제: 문자열 연결
  • 4. 명령형 처리(Java) public class TheCompanyProcess {
 public String cleanNames(List<String> listOfNames) {
 StringBuilder result = new StringBuilder();
 for (int i = 0; i < listOfNames.size(); i++) { // loop 사용이 일반적
 if (listOfNames.get(i).length() > 1) {
 // 한 문자 이상인 문자열을 연결
 result.append(capitalizeString(listOfNames.get(i))).append(",");
 }
 }
 return result.substring(0, result.length() - 1).toString();
 }
 
 public String capitalizeString(String s) {
 return s.substring(0, 1).toUpperCase() + s.substring(1, s.length());
 }
 }
  • 5. 함수형 처리(scala) val employees = List("neal", "s", "stu", "j", "rich", "bob", "aiden", "j", "ethan", "liam", "mason", "noah", "lucas", "jacob", "jayden", “jack") 
 val result = employees
 .filter(_.length() > 1) // 필터
 .map(_.capitalize) // 변형(Transform)
 .reduce(_ + "," + _) // 변환(convert) 수학 공식을 모델링하는 표현과 변형으로 기술하며, 가변 상태를 지양
  • 6. 무엇이 다른가? 명령형 처리: How를 기술 함수형 처리: What을 기술 문자열 예제의 What? 1. len(x) > 1인 큰 문자열을 찾음 2. 대문자로 변환 3. 문자열을 연결
  • 7. Java 8 public class Process {
 public String cleanNames(List<String> names) {
 if (names == null) return "";
 return names.stream() // stream을 생성
 .filter(name -> name != null)
 .filter(name -> name.length() > 1)
 .map(name -> capitalize(name))
 .collect(Collectors.joining(",")); // reduce의 특별한 경우
 }
 
 private String capitalize(String e) {
 return e.substring(0, 1).toUpperCase() + e.substring(1, e.length());
 }
 }
  • 8. Groovy public class TheCompanyProcess {
 public static String cleanUpNames(listOfNames) {
 listOfNames
 .findAll { it.length() > 1 } // 필터
 .collect { it.capitalize() } // 변형
 .join ',' // 변환
 }
 }
  • 9. Clojure ; 기본적인 clojure 버전 ; 리스프 계열 언어는 안에서 밖으로 실행됨.
 (defn process [list-of-emps]
 (reduce str (interpose ","
 (map s/capitalize
 (filter #(< 1 (count %)) list-of-emps)
 ))))
 
 ; 매크로를 사용한 가독성 향상 버전
 (defn process2 [list-of-emps]
 (->> list-of-emps
 (filter #(< 1 (count %)))
 (map s/capitalize)
 (interpose ",")
 (reduce str)
 ))
  • 10. 함수형 사고로의 전환은? 세부적인 구현에 뛰어들지 않고 고수준의 추상 개념을 적용하는 것
  • 11. 고수준 추상적 사고의 이점 문제를 다른 시각에서 분류할 수 있게 함 런타임에 최적화가 가능(작업 순서 조정) 개발자가 엔진 세부사항을 고려하지 않으면 할 수 없던 일을 가능하게 함(ex: 병렬 처리)
  • 12. 고수준 추상화의 스레드 적용 // Scala
 val parallelResult = employees
 .par // 스레드로 처리
 .filter(_.length() > 1)
 .map(_.capitalize)
 .reduce(_ + "," + _) // java 8
 public String cleanNamesP(List<String> names) { if (names == null) return "";
 return names
 .parallelStream() // 스레드로 처리
 .filter(n -> n.length() > 1)
 .map(e -> capitalize(e))
 .collect(Collectors.joining(","));
 }
  • 13. 사례 연구 예제: 자연수의 분류 6(완전수) = 1 + 2 +3 분류 조건 완전수 N의 진약수의 합 = N 과잉수 N의 진약수의 합 > N 부족수 N의 진약수의 합 < N
  • 14. 명령형 자연수 분류 public class ImpNumberClassifierSimple {
 private int _number;
 private Map<Integer, Integer> _cache; // 내부 캐시
 
 public ImpNumberClassifierSimple(int targetNumber) {
 _number = targetNumber;
 _cache = new HashMap<>();
 }
 // 약수인가?
 public boolean isFactor(int potential) {
 return _number % potential == 0;
 } 
 public boolean isPerfect() {
 return aliquotSum() == _number;
 }
 public boolean isAbundant() {
 return aliquotSum() > _number;
 }
 public boolean isDeficient() {
 return aliquotSum() < _number;
 } // 진약수 구하기
 public Set<Integer> getFactors() {
 Set<Integer> factors = new HashSet<>();
 factors.add(1);
 factors.add(_number);
 for (int i = 2; i < _number; i++)
 if (isFactor(i)) factors.add(i);
 return factors;
 }
 // 진약수의 합
 public int aliquotSum() {
 if (_cache.get(_number) == null) {
 int sum = 0;
 for (int i : getFactors())
 sum += i;
 _cache.put(_number, sum - _number);
 }
 return _cache.get(_number);
 }
 }
  • 15. Java 8을 사용한 자연수 분류 public class NumberClassifier {
 // 함수 호출시 실제 작업이 수행되는 것이 아님. stream을 반환
 public static IntStream factorsOf(int number) {
 return range(1, number + 1)
 .filter(potential -> number % potential == 0);
 }
 // sum 내부에서 stream을 해석 
 public static int aliquotSum(int number) {
 return factorsOf(number).sum() - number;
 }
 
 public static boolean isPerfect(int number) {
 return aliquotSum(number) == number;
 }
 
 public static boolean isAbundant(int number) {
 return aliquotSum(number) > number;
 }
 
 public static boolean isDeficient(int number) {
 return aliquotSum(number) < number;
 }
 }
  • 16. 함수형 언어의 공통된 빌딩 블록 필터, 맵, 폴드/리듀스
  • 17. 필터 Figure 2-1. Filtering a list of numbers from a larger list When filtering, you produce another list (or collection) potentially smaller than the original, depending on the filtering criteria. In the number-classifier example, I use filtering to determine the factors of a number, as shown in Example 2-14. Example 2-14. Filtering in Java 8 public static IntStream factorsOf(int number) { return range(1, number + 1) .filter(potential -> number % potential == 0); } The code in Example 2-14 creates a range of numbers from 1 to the target number, then 사용자가 지정한 조건으로 목록을 더 작은 목록으로 만드는 작업 public static IntStream factorsOf(int number) {
 return range(1, number + 1)
 .filter(potential -> number % potential == 0);
 }
  • 18. 맵 리스트의 각 요소에 같은 함수를 적용하여 새로운 리스트를 생성 // 약수 구하기 최적화 버전.
 static def factors(number) {
 def factors = (1..round(sqrt(number)+1)).findAll({number % it == 0})
 (factors + factors.collect {number / it}).unique()
 } Figure 2-2. Mapping a function onto a collection To illustrate map() and related transformations, I create an optimized version of my number classifier. First, I create an imperative version, shown in Example 2-16. Example 2-16. Number classifier optimized import java.util.HashMap; import java.util.HashSet;
  • 19. 폴드/리듀스 Figure 2-3. Fold operation Because addition is commutative, it doesn’t matter if you do a foldLeft() or fold Right(). But some operations (including subtraction and division) care about order, so the foldRight() method exists to handle those cases. In purely functional languages, leftandrightfoldshaveimplementationdifferences.Forexample,rightfoldscanoperate on infinite lists whereas left folds cannot. Example 2-13 uses the Functional Java-supplied add enumeration; the framework in‐ cludes the most common mathematical operations for you. But what about cases in 누산기(Accumulator)를 사용해서 값을 모으는 작업 reduce, foldLeft => (f (f (f (f 0,N1) N2) N3) N4) foldRight => (f N1 (f N2 (f N3 (f N4 0)))) foldLeft
  • 21. 필터 • Scala • filter, partition, find, takeWhile, DropWhile • Groovy • findAll(filter), split(partition), takeWhile, DropWhile • Clojure • filter
  • 22. 맵 • Scala • map, flatMap • Groovy • collect(Map), flatten(flatMap) • Clojure • map, flatten(flatMap)
  • 23. 폴드/리듀스 • Scala • reduceLeft, reduceRight, foldLeft, foldRight • Groovy • inject(reduce) • Clojure • reduce
  • 24. References •Neal Ford, Functional Thinking(김재완 옮김). 서울 시 마포구 양화로 한빛미디어, 2016.