1.


데이터를 처리하는 우아한 방법. (여기는 필수가 아님. 그리고 다른 언어에서 이미 다 채용하고 있는 부분)


널처리, 에러반환, Map이나 List등의 데이터구조물에 대한 깔끔한 처리(fmap과 traversable, foldable),

Builder 패턴(어플리카티브)


그리고 패턴매칭 : 패턴매칭을 사용한다는 것은 모든 경우에 대한 처리가 이루어진다는 뜻임.


널처리같은 경우는 코틀린같은데에서도 잘 구현하고있고

fmap 이나 foldable같은 경우는 뭐 모든 객체지향언어에 다들 있지?

Builder 패턴도 그냥 자바에서 쓰기 편해.


그래 여기까진 허세야. 굳이 함수형으로 할 이유가 없어.

객체지향보다 함수형이 더 깔끔하기는 한데 굳이 함수형으로 할 필요는 없음.


Null 처리같은거, 하스켈같은경우는 진짜 엄격하게 다 된단말야. 코틀린도 이정도로 엄격하게 되는진 모르겠는데



예를 들자면


one.getTwo().getThree().getFour() 를 한다고 했을때


자바에서는??

One one = getOneByJPA();

if (one == null) throw error

Two two = one.getTwo();

if (two == null) throw error

Three three = two.getThree();

if (three == null) throw error

Four four = three.getFour();


뭐 이런식이겠지? 그 다음에 가져온 four를 가지고서 로직을 들어가겠지.



이게 코틀린에서는 one?.getTwo()?.getThree()?.getFour() 로 되는건가?? ㅈㄴ 좋네

걍 코틀린쓰자 ㅇㅇㅇㅇ


여튼 하스켈에서는


one <- getOneByJPA

two <- getTwo one

three <- getThree two

four <- getFour three


이런식으로 진행됨.


이걸 자바에서

그나마 어케 좀 해보겠다고


Optional에다가 맵이랑 필터걸고 해봤거든?

근데 그렇게 해버리면

Optional.of(one).map(getTwo).map(getThree).get(Four) 를 하고 났을때


이후의 로직에서 갖고온 one two three 에 접근을 못하고 마지막 Four 밖에 안남음 이게 문제임.


하스켈에서는 클로저로 계속 이전 변수들이 이어지는데

자바에서 옵셔널 야매로 처리하면 답이 없음.



그래!!

코틀린쓰자 ㅋㅋㅋㅋ 코틀린쓰면 되겠네!!!


어 그냥 코틀린쓰자 ㅅㅂ



2. 사실이 두번째가 진짜 이유임.

하스켈은 함수 시그니처에 모든 입력값과 출력값이 다들어가.

그니까

함수시그니처에 아무 특별한 점이 없으면

그건 그냥 계산식이야.

테스트를 돌리고싶으면 quick check 돌려서 랜덤값 집어넣고 테스트 돌려보면 됨. 아주 쉬움.
얘네는 디버깅할게없어

내가 원하는 계산을 정의해서 테스트에 기술하고
그 테스트가 통과한다?
그러면 그 함수는 더이상 볼거없어 그냥 그 순간 확정된 하나의 완성된 모듈이 됨.


근데

어? 함수의 반환값에 DB1Monad 라는게 붙어있네??
그냥 내가 예시를 든거야.

이러면 얘는 DB1을 찍고오는거야.
그리고 DB1Monad들을 가지고 있는 애들은, 위험한 함수를 통해서 점화할수있어.

보통 runDB1 같은거랑 같이 존재하는데,

하스켈 안에서 runDB1 하고 인자로 DB1Monad 넘겨주면 부작용을 실행한다고

그니까 결국엔 하스켈도
main 함수가 IO () 모나드고

DB1Monad 를 IO 모나드로 변환하는 liftIO 같은걸 쓰거나

여튼 어케저케

결국은 모든 부작용은 IO니까, IO로 바까치기 해서

맨 바깥의 main을 점화시키면

그때부터

부작용들이 쭈루루룩 전파되는거야.


어? 하스켈은 부작용 없는거 아니냐고?
돌았냐? 그러면 DB에서 값 읽지도 않고 쓰지도 않게?

하스켈도 부작용 다 있어.


그러면 뭐하러 이런 개 싸발짓을 하냐


시그니처를 보고 알수가있어.

아 이 함수는 이런 부작용을 담고있구나

이런걸 시그니처로 써줄수가있음.

그래 걍 그거 하는거야.


러스트도 그렇잖아
라이프타임 그거 기술 안해도되는데 일부러 이거 내가 규칙어기면 컴파일러 너가 잡아줘

라고 하면서 라이프타임 기술해대잖아

걍 그런거임.


코딩을 하다보면 자연스럽게 코드의 부작용과 부작용이 아닌점
이런것이 다 기술이 돼.


그리고

아 내가 몰랐지만 지금 이 로직에서는 이러이런 디펜던시(외부상황에 의존한다는거)가 있구나
이런걸 투명하게 볼 수 있고

그냥 그거 하나 하겠다고 이지랄하는거야

그리고 이 규칙을 어기고 나도 모르는 부작용을 쓰려고하면

어 너 지금 위험한짓했어

라고 경고해주는거임.



나 그래서 오늘인가 어제인가

자바코드에다가

부작용 내는 부분만 따로 모아서 어케 표시를 해볼까 이런생각도 했었거든?

근데 솔직히 이 기능도 진짜 쓸모없다.

러스트 안전성 그것도 그냥 가비지컬렉터쓰면 쓸모없으니까 우리 웹개발자들한텐 특별한거 아니고



아 덧없다

내가 뭐하는거냐....


근데 진짜 뭔가 깔끔하고 투명하게 모든것을 기술한다는 점이 참 매력적이야.


우리가 정적 타입시스템을 쓰는 이유가 뭔데.
안전하잖아.

런타임에 안튕기고 컴파일타임에 튕기고.

그리고 테스트코드

나 테스트코드에다가 진짜 가능한한 모든 시그니처를 다 넣어서
이 시그니처가 맞는지 확인해달라고 부탁하는 편인데



ML 급의 강한 타입시스템

모나드로 부작용 명시해주기

이 안전성은 참.... 좋단말이지