하스켈같은거 보면 pure function 파트하고 IO 파트가 나뉘어 있잖아.
이걸 좀 극단적으로 가져가서 pure function 파트에 있는 코드를 전부 컴파일 타임에 연산하는거.
연산한 결과는 IO 타입의(AST 같은거) main이라는 값이 되고, 이걸 다시 컴파일해서 바이너리를 얻음.
IO 타입 자체가 rust마냥 메모리 안정성 같은걸 보장하면 더 좋고.
물론 컴파일에 성공 하려면 pure function 파트가 정지 해야됨.
그러니까 불완전한 totality 검사에 기댈지, 컴파일러가 종료하지 않을 가능성을 남겨둘지 둘중에 선택해야됨.
함수형 단점이 gc를 때놓을 수가 없다는건데, 이렇게 하면 gc는 컴파일 타임에만 존재함.
Nat = Z | S Nat 같은 졸라 비효율적인 자료형도 런타임 값이 포함할 수 없게하면 컴파일 타임에 다 지울 수 있음
좀 다르게 보면 pure 한 파트를 IO 코드를 생성해내는 type-safe한 매크로처럼 쓰는거지.
pure파트를 컴파일 타임에 돌린다 봐도 되고, 매크로를 강타입 순수 함수형 언어로 만든다고 봐도 됨.
(말만 쉬움)
어차피 런타임에서 연산해야할것들이 많은데
컴파일타임에 계산하는건 지원하는 언어들 이미 꽤 있음
ㅇㅇ 어차피 런타임에 연산할텐데, 그걸 함수형 언어를 사용해서 얼마나 추상화 할 수 있느냐가 관건임.
나는 그걸 굳이 타입으로 할필요는 없는듯
https://youtu.be/wkXNm_qo8aY
걍 런타임처럼 연산시키고 결과 받은다음에 안전검사만 하면편함
저번에 컴파일타임 소팅하는것도 희한하게 타입레벨에서 북적북적 안하고 const fn에 넣는걸로 끝나는게 더 직관적이잖아
저번에 타입레벨 소팅은 하스켈에서 타입레벨 프로그래밍 자체가 tricky한 탓도 있음. 그리고 저정도 까지 가면 타입도 first class 라 좀더 유연한 느낌임.
그리고 단순히 컴파일 타임 연산을 하는게 목적이 아님. 그런건 당연히 const fn으로 충분히 커버 치지. 로우레벨 언어에 추상화를 넣는데에는 한계가 있고, 하이레벨 코드를 로우레벨 코드로 번역하는데에도 한계가 있으니, 로우레벨 파트는 그대로 두고 하이레벨 언어로 로우레벨 코드를 찍어내는건 어떨까 하는거임.
F*같이 언어내부에서 타입으로 나누는거?
나는 어떤식으로 변환될지 감이 안오네 하이레벨 코드를 아얘 런타임에 안돌릴수는 없잖아
F* 는 전혀 모르는데.. 일단 런타임하고 컴파일 타임 타입이 완전 구분되는걸 상상하는건 맞음.
그리고 하이레벨 언어로 로우레벨 만드는건 지금도 컴파일러들이 다 하고있는거아니냐 Haskell 코드가 그대로 cpu에 안들어가자너
IL2CPP같은거 말하는거임?
C나 Rust수준 언어의 AST를 하스켈 데이터 타입으로 정의하고 그 값을 하스켈로 코딩한다고 보면 됨
그러니까 하스켈 실행에 필요한 thunk 같은 개념을 실제 런타임까지 가져갈 필요가 없어지지
그러니까 메타프로그래밍 전용으로 만든다는거냐 그게 뭐가 좋은거임 그 언어 ast는 그 언어로 만들기 제일 좋게 돼있는데
ㅇㅇ 메타프로그래밍 전용. C는 그냥 수준이 그렇다는 말이고, AST 언어 자체도 직접 정의하는거지. 하스켈 IO타입 처럼 편하게 쓸 수 있을 정도로. 장점은 추상화된 파트(증명언어로 쓸 수 있는 부분)에서는 gc 도움을 받을 수 있고, 런타임에는 gc를 배제할 수 있는거.
정리하면 하스켈로 컴파일러를 만든다 이거네
AST 언어라는건 코드생성용 백엔드이상의 의미없는거같은데 걍 하스켈로 컴파일러 만들면 그대로 나올듯
아니다 컴파일러가 아니라 코드생성기라고 해야겠누 프론트엔드는 없고 하스켈로 짤테니
긴단하게는 그렇게 할 수 있을텐데, 하스켈 수준으로 AST 타입 안정성 보장하는게 힘들듯. 당연히 코딩하기 개힘들거고. 이런거 할꺼면 채소 dependent type은 있어야