JSConf EU(functional programming) part.1

KIP·2022년 6월 7일
0

https://www.youtube.com/watch?v=e-5obm1G_FY

혹시나 js를 입문하는 사람이나, js를 공부하는 사람이라면 정말로 추천하는 강의다.
JSconference가 있다는 사실을 너무 늦게 알아버렸다.
특히나 저사람 발표능력은 진짜...

혹시나 영어를 알아듣기 힘들다면 자막도 친절히 나오니 적절히 참고하면서 시청하면 된다.
( 한국어 번역은 단어의 의미가 다를 수 있다는 점을 고려, 개인적으론 영어로 듣길 권장합니다.)

오역을 할 수 있어 핵심개념에 대해서는 나 또한 영어를 사용할 예정

25분 영상 속 핵심 내용에 대해서 정리 + 간단한 실습

Why functional? (functional JS(focus) vs Object oriented JS)

함수형 프로그래밍이란, 프로그램의 전부를 함수로 표현한다
(Do everything with function(Input-> Output))

함수형 프로그래밍은 조금 더 안전하고, 쉽고, 라이브러리(커뮤니티의 활성화)가 많다.(safer, easier, more libraries)

또한 함수형을 사용하면 side effects를 다루는데 있어 용이하다.

side effects란 함수가 주어진 인풋에서 아웃풋을 계산하여 반환하지 않는 상황을 얘기한다.
말 그대로 사이드에서 주는 영향이라고 생각하면 된다.

++console.log에 무언갈 인쇄-> 아웃풋을 반환하는 행위가 아니다
++아웃풋 계산에 전역변수를 사용하는 함수 -> 인풋에 의존하지 않는다면 또한 순수 함수가 아니다.

강연자는 즉 함수형 프로그래밍을 지향하기 위해서는 순수함수를 사용하라고 얘기한다(use "pure" function)

영상 속 예시,

non-functional vs functional

non-functional

var name = "it's me"
var greeting = "hi"
console.log (greeting + name)
 => hi it's me

=> 명령형 프로그래밍에 가깝고, 극단적으로 단 한번의 실행만을 위한 함수로는 적절하다고 볼 수 있다.

functional

function greet(name){
retrun "hi" +  " "  + name
}
greet("me")
=> hi me

=> name이라는 매개변수를 가지고 input값을 넣은대로 return (output)값이 출력되는 것을 알수 있다.
조금 더 이해하기 위해 다른 예시를 살펴보자.

var name = "hey"
function greet(){
console.log("hi" +" "+ name)
}
=> hi hey

==> 여기서 name은 함수 내부의 인수가 아니라 전역(global)인수로서 읽어온다.
또한 console.log()는 함수의 반환 값이 아니라 2가지 이유에서 순수하지 않다고 할 수 있다.

functional Programming (main)

1. 최대한 순수하게 생각해야한다.

2.use higher-order-functions (고차함수의 사용)
functions can be inputs/outputs .
즉, 고차함수는 다른 함수를 인풋으로 받거나 함수를 아웃픗으로 반환하는 역할이 가능하다.
=> 함수를 일종의 객체로 취급하고, 함수->다른 함수로 전달하는 것이 된다(함수 내에 함수)

고차함수의 예시를 살펴보자.

function A(adjective){
	return function (string){
		return adjective + " " + string
    }
}

var coolifier = A("cool") 
coolifier("conference")
=> "cool conference"

Avoid! (functional Programming에서 피해야 할 것)

1. Don't iterate(반복문(for, while...)의 사용 지양
대신 use map, filter, reduce ...등의 고차함수(함수도 받는 함수)를 사용해라.

반복문의 사용에 대해선 간단히 생각해보면 샌드위치를 떠올린다.
샌드위치를 여러개 만드는데, 처음 빵, 햄, 치즈, 계란 등의 사이즈를 조절해 여러 개의 샌드위치를 만든다.
반복문이라고 생각을 한다면 for 재료 in 샌드위치..와 같이 하나하나를 개별적으로 sort해서 그 나온 값에 slice를 써 자르는 상상을 하게된다. 이와같이 될 경우, 어떤 샌드위치에서 재료하나를 빼고 싶을 때 굉장히 복잡해지면서 힘들어진다.

이것을 대신하기 위해서 샌드위치 하나에 map을 사용해 복사해, reduce로 그 중에 하나를 제거하거나, filter로 제거된 것을 찾기만 하면된다.

2.mutability(데이터의 변형성)
대신 use immutable data(위치를 변경할 수 없는 불변의
데이터 사용).

  1. 데이터의 변형성은 예시가 있다.
mutation

var rooms = ["1","2","3"];
rooms[2] = "4"
rooms; 
=> ["1","2","4"]

=> 이렇게 객체지향적으로 접근을 할 때 문제가 생기는 이유는 의도치 않게 다른 것들까지 바꿀 수 있다
(버그를 찾기 굉장히 힘들어질 수가 있다.)

no mutation(good)

var rooms = ["1","2","3"]
var newRooms = rooms.map(function(rm){
	if(rm === "3"){
    	return "4"
    }else{
    	return rm
    }
})
rooms =>["1","2","3"]
newRooms => ["1","2","4"]

=>위와의 차이가 보이는가? 기존의 rooms 는 지키면서 새로운 객체를 만들어냈다.
이처럼 모든 데이터를 불변데이터라고 생각해라.

3.persistent data structure for effcient immutability(효율적인 불변성을 위한 영속데이터 구조)
2번의 immutability를 유지하려다 보니 배열을 복사했을 때 사본이 생기는 문제가 생긴다.
그래서 배열의 구조 중 하나만 바꾸려해도 배열의 전체를 새로 만들어야하는 효율의 문제.

함수세계에서는 이런 문제해결법으로 이상적 해시트리를 얘기한다.

여기에는 leafnode라는 용어가 들어간다.

http://www.btechsmartclass.com/data_structures/tree-terminology.html

이 페이지에서 굉장히 디테일한 설명을 해준다. 참고하길.

돌아와서, 어떤 배열이 있다고 가정하고, 그 배열을 새로 만들지않고 리프노드에 연결해 기존구조는 재사용을 하는 것이다(structural sharing)

나도 사용한 적이 있지만, 이런 불변성을 이용할 수 있게 해주는 라이브러리가 많다. (immutable.js, mori,ramda...etc)

but, 라이브러리를 사용하지 않고도 순수 js만으로 함수형 프로그래밍이 가능하다.
built-in함수인 map,reduce와 같은 배열 프로토타입에 있는 함수들이다.

결론

함수형 프로그래밍에 대해서만 얘기를 했기 때문에 포커스는 함수형에 맞춰져있다. 그럼에도 강의 후반부에는 함수형과 객체지향에 대한 질문들이 나왔고, 그에 대한 강연자의 답변을 얘기한다.

"객체지향과 함수형을 비교했을 때 다른 것보다 뛰어나거나 모자란 패러다임은 없다.

각자의 장/단점은 분명히 존재한다. 예를 들어 한번 실행되고말 프로그래밍이면 명령형 프로그래밍이 적절한 패러다임.

but 도서관의 책, 교사와 학생이 있는 교실과 같은 것은 객체지향형 사고방식이고 이것은 객체모델링 패러다임의 이유가 된다.

마지막으로 객체와 관련이 없지만 필요에 의해 객체를 쓰게된다면 각종 부작용(side effects)와 찾기 힘든 버그들이 있다. 이것은 데이터함수와 여러함수를 쓰는 파이프라인을 고려해야 하는데,
기존 인풋에 따라 새 아웃풋이 나오게 할 때(함수형 프로그래밍)의 장점은 한가지 작업만 하는 작은 함수로 쪼갤 수 있다는 점에 의해 이러한 부분을 쉽게 해결해준다. 또한 클래스 구조의 전체를 바꾸지 않아도 되는 점이 있다."

0개의 댓글