함수의 색상

May 21, 2021

algebraic effects 를 조사하다가 좋은 글을 찾게 되었다.
해당 주제를 보기 전 일단

What Color is Your Function

이 글을 읽고 진행하길 바란다.

.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.
.

해당 글은 비동기 함수의 전염성에 관한 불평 글이다.
동기함수는 Blue, 비동기 함수는 Red 로 표현하였다.

우리가 함수를 작성할때 동기함수 즉 Blue 색상의 함수에서는
비동기함수 (=Red) 를 사용할 수 없다.

시용할 수 없다는 말은 비동기 함수의 결과를 가지고 어떠한 처리를 하거나 비동기함수를 실행할 수 없다는 뜻이다.

Promise

Promise 가 있지 않은가?
오 Promise 는 비동기 함수를 await 하여 동기적으로 실행순서를 맞춰준다.

하지만 event loop 설계방식의 js 에서는 await 된 함수는 microtask 로 들어가게 된다. 실행순서로 보면 이미 함수 내부 다른 프로세스가 끝난 뒤, 해당 함수들을 실행한다.

만약 promise 의 결과값을 받아서 처리하고 싶다면?
순간 async await 가 떠올랐을 것 이다.
await 하여 비동기 함수의 결과 값을 받아 그 뒤를 진행 할 수 있다.

async function logName() { const user = await fetchUser("something api") if (user.name) { console.log(user.name) } }

확실히 순서를 보면 동기적으로 작동하는 함수다.
하지만 function 앞에 있는 async 지시문을 보자.

해당 함수는 비동기함수 입니다. 라고 떡하니 적혀있다.
결국 비동기함수는 동기함수 내부에서 사용할 수 없다!

비동기 함수를 사용하기 위해서는 해당함수도 비동기 함수가 되어야 한다.
이는 async 뿐만 아니라 generate 도 똑같다.

이로 인해 비동기 함수가 중간에 들어오면 해당 함수를 사용하는 모든 함수는
비동기가 되어야 한다. 이것이 비동기 함수의 전염성이다.

HighOrder Function

위 글에서는 이런 문제가 더욱 불거진 이유가 (=전염성이 문제가 되는 경우) 함수형 프로그래밍의 사용으로 보고 있다.

단일값을 반환하는 함수만 존재한다면 전염성은 큰 문제가 되지 않는다.
하지만 고차 함수는 함수를 반환한다.

여기서 해당 함수에 비동기가 있다면?
이제 모든 함수는 async 로 변해야 한다.
전염성은 프로그램 모든곳으로 급격히 퍼져 나갈 것 이다.

색상이 없는 언어

결국 이 전염성을 해결하기 위해서는 Multi Thread 를 이용해야 한다.
모든 함수의 실행이 병렬로 진행되고 결과값을 가지고 Thread 끼리 통신해야 한다.

이런 부분을 가장 적절하게 사용하는 언어가 구글에서 만든 Go 언어다.
(본인은 go 언어를 해본적은 없다…)
Go 는 수많은 green thread 를 생성하여 모든 작업이 비동기로 흘러간다.

그리고 GoRoutine 을 이용하여 모든 함수에서 이를 제어 할 수 있다.
모든 함수에서 동기함수와 비동기 함수 실행이 가능하다.

go 는 내부적으로 모든 i/o 관련 라이브러리들이 thread 에서 await 하고 있다.
다른 thread (=작업) 에서 메시지를 보내면 해당 메시지를 받기위해 대기하게 된다.
이는 go 가 실제로 모든 작업은 비동기 지만 동기처럼 보이는 방식이 된다.

또다른 색상

red, blue 와 같이 동기, 비동기를 나누는 것 외에
해당 함수의 args, return type, 사용하는 프레임워크, 라이브러리의
전용함수 등 2가지 색상이 아닌 수많은 색상이 나올 것이다.

하지만 가장 실제 제품을 개발할때 가장 성가신 것은 동기와 비동기를 나누게 되는 red, blue 임은 확실하다.

그래서 지금은?

현재 개발되는 새로운 언어들은 이런 문제를 해결하기 위해
내부적으로 async await 를 심어두고, 외부에서는 이를 노출하지 않는 방식으로 만들어
실제로 multi thread 방식으로 작동하는 것 처럼 보이고 있지만..

multi thread 가 아니라면 결국 우리는 해당 비동기함수의 작업을 다시 실행할때
해당 함수의 call stack 전부를 가져와야 한다.

최근에는 pc 나 모바일의 성능이 평균적으로 상향되었기 때문에 성능의 큰 문제는
없으리라 보지만 그래도 여전히 엔진 내부에서는 call stack 을 찾기 위한 여정을
하고 있다는 건 기억하길 바란다.

그리고 여전히 색상을 구분지어 작성해야 하는 부분도 존재한다는 것도.