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 급의 강한 타입시스템
모나드로 부작용 명시해주기
이 안전성은 참.... 좋단말이지
1번같은경우도, 개별적인 기능들이 산재되어있고 혼잡하고 라이브러리마다 독자적으로 제공해주는 자바와 달리 하스켈은 그냥 모두다 통일된 양식으로 펑터 어플리카티브 트래버서블 폴더블 모나드 이렇게 규약맞추고 모나드의 수학적 규칙. 퀵첵 이렇게 만들어버리니까 참 뭔가 편안하단말이지...
1번도 할말이 많음. 코틀린도 ? 가지고 체인 이뤄봤자 이거 옵셔널 체인이라, 중간에 가져온 산물들에 접근 못하잖아. 이거 하나땜에 코드가 엉망이 된다니까? 하스켈에서는 그냥 자연스럽게 아주 진짜 그냥 뭐 생각이란게 필요없이 당연히 되야하는거 아니야? 싶은데 자바 코틀린에선 그게 안된다고
옵셔널로 지랄하지말고 이거 봐라
https://lexi-lambda.github.io/blog/2019/11/05/parse-don-t-validate/
이거 하스켈 아니냐? 하스켈은 걍 쉬움
내가 옵셔널쓰고싶어서 쓰는게 아니고, 자바에 모나드가 없으니까 걍 그거라도 쓰는거임
하스켈에 한정된 얘기 아님
근데... 만들만...한데.. .라고도 생각했었는데 람다가 존나 제한적이라서 못만듦 ㅆㅂ...... 람다를 쓸때마다 타입을 계속 뭐 타입선언도 아니야 뭔 인터페이스 선언하고 앉아있어야하는데 미칠노릇이지
ㅇㅎ
이거 존나 좋네 근데 나도 하스켈 가면 이렇게 하려고 했었음. 이거 구라아니고 진심임. 나 그래서 자바때도 에러반환이랑 옵셔널이랑 섞었던건데
이것도 결국 IO에 담든, Optional 맞나? 하스켈에서 옵셔널이 뭐였지 Some None 그게 옵셔널인가? 여튼 옵셔널 모나드로 묶던, IO 모나드로 묶던 그냥 a <- getA 하면 그만인건 똑같잖아
좀더 읽어볼게. 내가 부분만본듯
앞쪽에 개소리 많으니까 TLDR을 원하면 "Parsing, not validating, in practice" 파트만이라도 제대로 읽어보셈
뒷부분은 안읽었는데, 그냥 IO 로 감싸는거 만들어서 IO 안에서 화살표 그으면 되는거 아닌가 싶은데 근데 이거 보고나니까 드는 생각이 이거 이러다가 모든 함수에 죄다 IO 박게 되는거 아닌가 싶네
제대로 읽질 않았네 너는 그냥 애들용 버전이나 봐라
https://stianlagstad.no/2022/05/parse-dont-validate-python-edition/
병신아 한번 밸리데이션했으면 타입갈아끼워서 안전성 표시해달라는건데, 시발 리스트를 비지않은리스트로 바꾸는거나 옵셔널에서 옵셔널 빼는거나 그게 똑같은소리고 최초의 밸리데이션은 들어가야할거아냐 그래야 파싱을 하건 에러를 내뱉건하지. DB에서 꺼내올때 널러블인걸 어쩌라고
니가 딴소리하는거임
디비에서 애초에 널러블 펄스 박아놓고 가져올때부터 아 Maybe네 여튼 Maybe 빼고 걍 원래타입 그대로 가져오면 씨발 그럼 아무상관없지 근데 디비에서 가져올때 널러블인걸 어쩌라고 근데 이것도 원래는 레프트조인 안쓰면 이럴 일 없는데 나는 레프트조인도 쓸거라고 아 근데 이런 상황 별로 안일어나는건 맞음.
디비에서 가져올때 Maybe 로 감싸건 IO로 감싸건 뭐로 감싸긴 해야할거아님. 근데 하스켈은 그거 빼내는거 존나 쉬운데 자바는 그거 안된다고
한번 빼낸다음에 다시 Maybe에 넣는 바보짓을 왜하냐 지금 본문이 그거 하지말라는건데 걍 딴소리잖아
밸리데이션 했으면, 즉 Maybe에서 None 대신 값 빼내올수있는거 인지했으면 validate했다고 좋아하고 넘기지말고 다음번에 validate 안해도 되게 Maybe에서 빼낸거 가져오란 소리가 뭐 좋은 소리긴한데 그래서 뭐 어쩌라고
글구 하스켈 디비에서 조회할때 아마 Maybe로 감싸겠지. 이걸 뭐 자동으로 에러반환시키는건 미친짓이고. 근데 내가 Api 만들때는 그냥 IO로 감쌀 생각임
드디어 이해했구나 ㅄ쉑ㅋㅋ
자바에서 클로저 제공안되는거때문에 ... 아 아닌가... 자바로 구현이 되나? 자바로 그냥 모나드 만들수 있는건가? 모나드를 만든다는 표현보다는 Optional같은거에 bind 연산을 제공할수있냐느건데 Optional -> (T -> Optional<s>) -> Optional<s> 를 반환하는 시그니처를 만들수가있나? 나는 저 람다를 표현못해가지고... 아 이거 되나?? 되나보다...</s></s>
아니 근데 된다고 하더라도 이거 가독성 극혐이야 do 블록 없으면 하스켈도 모나드 쓰는거 개극혐임
자 생각해보자.. 람다는 내부값을 받아서 람다를 반환해야하는데... 그 람다는 람다를 인자로 받아서 옵셔널을 반환.... 일단 해보고 옴
근데 난 가능성 측면에서만 얘기하는거지, 이거 당연히 실무에서 쓰면 병신새끼임. 이게 뭐하는짓임
아 나 바본가봐.. 그냥 바인드 만들면 되는데??