What Color is Your Function? (feat. 함수의 색 전염성)
본 블로그 글의 내용은 이전 글인 'Java도 한다 경량 쓰레드 (Virtual Thread)' 중에서 설명하는 함수의 색상 문제를 다룬다.
Java도 한다 경량 쓰레드 (Virtual Thread)
봄(Spring)은 왔는가?Java의 위대한 산물인 가상 쓰레드는 분명 JVM 생테계에 엄청난 열풍을 일으켰음에 의심할 여지가 없다.많은 개발자들이 그 패러다임에 발맞춰서 프레임워크를 개선하고 있듯
downfa11.tistory.com
함수의 색 문제 (Function coloring Problem)
아래의 포스트에서부터 시작한 논의로 Java, Kotlin, Go 등의 언어에 대해서 활발하게 이야기되고 있다.
What Color is Your Function? – journal.stuffwithstuff.com
I don’t know about you, but nothing gets me going in the morning quite like a good old fashioned programming language rant. It stirs the blood to see someone skewer one of those “blub” languages the plebians use, muddling through their day with it be
journal.stuffwithstuff.com
즉, 동기 함수(blue)와 비동기 함수(red)는 함께 쓸 수 없고, 비동기 함수를 사용하기 위해서 점점 동기 함수들의 색이 변한다고 한다.
- 비동기 함수는 비동기 함수에서만 호출할 수 있다.
- 동기 함수에서 비동기 함수를 호출하기 위해서는 비동기 함수가 요구하는 패러다임을 따라야한다.
위 글에서는 함수형 프로그래밍의 사용으로 이런 전염성 문제가 더욱 불거진 것으로 보고 있다.
단일값을 반환하는 함수만 존재한다면 전염성은 큰 문제가 되지 않는다.
하지만 고차 함수(Higher-order Function)는 함수를 반환한다.
이런 고차 함수에서 비동기 로직이 들어간다면? 이제 모든 함수는 async 로 변해야 한다.
고차함수의 비동기 로직은 전염성을 갖는다
함수에 색이 뭔 소리고 전염된다는게 무슨 말인지 이해되지 않는 사람들을 위해서 예시를 준비했다.
전염되지 않은 경우
private Integer syncFunction() { reutrn 42; }
public static void main(String[] args) {
System.out.println(suncFunction());
}
Java의 CompletableFuture로 전염되는 경우
public static CompletableFuture<Integer> asyncFunction() {
return CompletableFuture.supplyAsync(() -> 42);
}
public static void main(String[] args) throws ExecutionException, InterruptedException {
System.out.println(asyncFunction()); // CompletableFuture 반환
System.out.println(asyncFunction().get()); // get()이나 thenApply()
}
Java써서 CompletableFuture, Future 객체로 생각해야한다.
Mono와 Flux로 이뤄진 Reactor Project에서 전염되는 경우
private Mono<Integer> asyncFunction() { return Mono.just(42); }
public static void main(String[] args) {
System.out.println(aysncFunction());
asyncFunction().subscribe(System.out::println); // 42
}
우리에게(나에게) 흔한 Spring Webflux를 예시로 보여주겠다.
Mono<Integer>를 반환하기 위해서 subscribe()나 block()를 사용해야하는데, 모든 코드들도 비동기로 변경해야한다.
동기함수는 Blue, 비동기 함수는 Red 로 표현할때 프로그램 곳곳으로 비동기 함수(red)가 전염된다는게 어떤 의미인지 이제 좀 와닿는가?
이와 같이 동기 함수가 비동기 함수의 패러다임에 의해 점점 변경되기 때문에, 전염성을 가지고 있다고 표현된다.
함수를 작성할때 동기함수(=Blue)에서는 비동기함수 (=Red) 를 사용할 수 없는 의미이다.
여기서 '사용할 수 없다'는 말은 비동기 함수의 결과를 가지고 어떠한 처리를 하거나 비동기함수를 실행할 수 없다는 뜻이다.
색상이 없는 언어 Go Go Go
이런 부분을 가장 적절하게 사용하는 언어가 구글에서 만든 Go 언어다.
결론적으로 Go 언어는 모든 함수에서 동기함수와 비동기 함수 실행이 가능하다.
실제 모든 작업은 비동기로 이뤄지지만 동기처럼 보이도록 한 것이다.
Go 는 수많은 경량 쓰레드를 생성하여 모든 작업이 비동기로 흘러가고, GoRoutine 을 이용하여 모든 함수에서 이를 제어한다.
내부적으로 모든 IO 관련 라이브러리들이 thread에서 await 하고 있고 이 쓰레드들 안에서 메시지를 보내면 해당 메시지를 받기위해 대기하게 된다.