힙력이 떨어진 깃갤에 코드 투척https://github.com/damhiya/MetaLambda/아아- 이것은 「Contextual modal type thery」 라는 것이다.메타프로그래밍을 타입 안전하게 할 수 있지.contextual modgall.dcinside.com


GitHub - damhiya/MetaLambdaContribute to damhiya/MetaLambda development by creating an account on GitHub.github.com



이거 예전에 올렸을 때 댓글에 뭔지 하나도 모르겠다 뭐 그런말이 많았는데

나도 인지하고 있었다만 설명하기엔 쓸 내용이 너무너무 많아서 못썼음.


한 1/3쯤 써둔거 올려봄


근데 사실 논리학 설명 밖에 없음 ㅋㅋ 메타프로그래밍까지 연결되려면 다음글까지는 써야될듯

바빠서 다음글 쓸지도 잘 모르겠고


X X X



메타프로그래밍은 코드 생성을 자동화 할 수 있는 강력한 도구지만 배우고 사용하기 어려워요

특히 자동 생성된 코드를 보면서 디버깅 하기는 정말 쉽지 않겟죠


한가지 이유는 메타프로그램이 만들어 내는 대상(오브젝트) 언어 코드의 올바름을 보장하기 힘들기 때문이에요

메타프로그램이 항상 잘 컴파일 되는 대상 코드를 만든다면 프로그래머가 자동 생성된 코드를 읽을 일이 줄어들겠죠

대상 코드의 올바름을 어떻게 보장 할 수 있을까요


hygienic macro 라는게 있어요

CPP(C preprocessor)가 수행하는 문자열 치환이나 (hygienic이 아닌) 리습 매크로에서는 의도하지 않은 variable capture가 일어날 수 있기 때문에 치환에 변수 이름을 바꾸는 과정을 추가한거에요

Scheme이랑 Rust 하는 사람들 맨날 이걸로 매크로 시스템 자랑하는데 그냥 capture avoiding substitution 같은거에여


hygienic macro는 변수 바인딩을 올바르게 처리하기 때문에 그나마 쓰기 편하지만 모든 문제를 해결하진 않아요

오브젝트 코드의 컴파일 까지 보장하려면 타입을 맞춰야죠

이건 그리 간단한 문제가 아니에요

보통 메타프로그래밍 시스템은

메타프로그램의 타입체킹 -> 메타프로그램 실행 -> 생성된 오브젝트 코드 타입체킹 -> 오브젝트 코드 컴파일 -> 컴파일된 프로그램 실행 ... 이런 순서로 진행 될텐데

메타프로그램이 well typed 오브젝트 코드를 만드는걸 보장한다는건 메타프로그래밍과 생성될 오브젝트 코드의 타입체킹을 동시에 수행한다는 말이죠

놀랍게도 실제로 가능하고 multi-stage programming이라는 분야 에서는 이런 언어에 대해서 연구해요




multi-stage programming language의 타입시스템은 어떻게 설계해야 할까요

Davies & Pfenning의 A Modal Analysis of Staged Computation에선 necessity modality를 응용했어요 https://www.cs.cmu.edu/~fp/papers/jacm00.pdf
근데 제가 보기엔 저것 보다 A Judgemental Reconstruction of Modal Logic을 먼저 훑어 보는게 조은것 가타요 https://www.cs.cmu.edu/~fp/papers/mscs00.pdf


이 시스템들에서 box(necessity) modality는 validity를 logic system에 internalize한 type/proposition 이에요

그래서 이 시스템을 이해하려면 먼저 natural deduction, (hypothetical) judgement, truth, validity의 개념들에 대해 알아야 해요

그냥 A Judgemental Reconstruction of Modal Logic 읽으라고 하고 싶은데 아무도 안읽을테니까 조금 설명해볼게여


우리가 다루고 싶은건 논리 시스템이에요
논리 시스템이면 proposition이니 predicate니 하는 것들이 나오겠죠
저것들이 뭔지는 얘기하지 않을게요. 저는 철학은 안배워서 그런건 못하겟어요
논리 시스템을 정의하고 다루고자 하면 그 대상논리를 설명하기 위한 논리 시스템, 메타논리가 필요해요

즉 대상논리의 proposition과 메타논리의 proposition이 생기겠죠. 메타논리의 proposition은 judgement라고 불러요


가장 기본적인 judgement로는 "A is a proposition", "A is true"가 있어요

"A is a proposition"은 대상 논리의 명제가 될 수 있는것이 무엇인지 얘기하는 거고 "A is true"는 "A"라는 대상논리의 명제가 참(truth) 임을 얘기하는거에요

간단하게 A prop, A true 이런식으로 표기해요


이 "A is true" judgement를 사용하면 연결사(logical connective) 들에 대한 추론 규칙(inference rule)을 줄 수 있어요

자연연역(natural deduction, logic system의 한 종류) 에서는 and(∧)에 대한 추론 규칙을 아래처럼 줘요

  A true      B true           A ∧ B true          A ∧ B true

--------------------I1       ------------E1       ------------E2

      A ∧ B true                A true               B true

큰 가로선은 가로선 위의 judgement들을 가정했을 때 가로선 아래의 judgement가 결론으로 나온다는 의미에요

I1은 "A true 이고 B true 이다면 A ∧ B true이다"
E1은 "A ∧ B true 이면 A true 이다"

E2는 "A ∧ B true 이면 B true 이다"

라고 해석하면 돼요

문장을 잘 곱씹어 보면 눈치 챌 수 있는데, 이 추론 규칙이란 것들은 judgement들의 관계를 기술하는 언어이기 때문에 메타논리의 메타논리라고 볼 수 있어요

추론 규칙 자체는 judgement가 아닌거죠

한편 I1을 ∧의 introduction rule, E1과 E2는 ∧의 elimination rule 이라고 해요

자연연역 시스템은 추론 규칙이 이렇게 introduction/elimination rule로 주어지는 특징이 있어요


이것만으론 ∧말고 다른 연결사를 설명할 수가 없어요

implication (A → B)의 추론 규칙은 "If (If A true, then B true) then A → B true"가 되어야 하는데 괄호 안의 If에 해당하는 judgement가 필요하죠

그래서 hypothetical judgement 라는걸 만들었어요

Hypothetical judgement는 "J₁, ..., Jₙ ⊢ J" 꼴로 쓰고, judgement J₁, ..., Jₙ 를 가정한 J를 의미해요

"A true, B true ⊢ C true"는 "A가 참이고 B가 참이면 C가 참이다" 라는 의미의 judgement 인거죠

자연연역에서는 주로 A true, B true, ..., C true ⊢ D true 꼴의 hypothetical judgement를 많이 쓰기 때문에 A true, B true, ..., C true 를 흔히 Γ로 줄여써요


이제 가정인 Γ를 사용하기 위한 규칙이 있어요

---------------

Γ₁, J, Γ₂ ⊢ J

의미는 "(Γ₁, J, Γ₂ 를 가정할 때 J)이다"

가로선 위가 비어있는건 이 inference rule이 가정하는 바가 없다는 뜻이에요


드디어 implication의 추론 규칙을 쓸 수 있어요

Γ, A true   ⊢ B true         Γ ⊢ A → B true       Γ ⊢ A true

--------------------I→       ---------------------------------E→

   Γ ⊢ A → B true                      Γ ⊢ B true


∧의 추론 규칙도 비슷하게 Γ를 붙여서 다시 만들 수 잇어요

 Γ ⊢ A true    Γ ⊢ B true          Γ ⊢ A ∧ B true         Γ ⊢ A ∧ B true

--------------------------I1      -----------------E1      ----------------E2

     Γ ⊢ A ∧ B true                  Γ ⊢ A true              Γ ⊢ B true


마지막으로 validity만 대충 얘기할게요

"A is valid", 혹은 "A valid"는 "A가 truth에 대한 아무 가정 없이 참이다"를 의미해요. 즉

· ⊢ A true

-----------

  A valid


A가 valid 하다면 당연히 true 겠지요

원래 빈 가정이었으니 다른 가정을 넣어도 당연히 성립할거구요

   A valid

------------

 Γ ⊢ A true


(논리학에서 흔히 말하는 validity와 Pfenning & Davies가 말하는 validity가 분명 관계가 있을텐데 공부를 안해서 모르겟어요

그냥 이걸로 PL이나 만들면 되지 않을까요)




validity까지 길고 지루한 설명을 했는데 이딴걸 왜 정의했는지는 얘기를 안했죠

사실 box와 함께 얘기하는게 맞는것 같은데 box까지 설명하긴 지쳤고 validity도 빠지면 그냥 자연연역 뿐이라 제목값을 못해서 넣엇어요




사족으로 Per Martin-Löf의 ON THE MEANINGS OF THE LOGICAL CONSTANTS AND THE JUSTIFICATIONS OF THE LOGICAL LAWS를 보면
(물론 저도 안읽었습니다만)

A true, ⊢ A, Γ | A true 등의 노테이션을 쓰는데 Γ ⊢ A true는 없어요

위키 백과 turnstile 항목을 보면 왜 그런지 알 수 있어요

https://en.wikipedia.org/wiki/Turnstile_(symbol)

Turnstile (symbol) - WikipediaTurnstile (symbol) - Wikipediaen.wikipedia.org


turnstile (⊢) 에서 |는 "I know", -는 "... is true"를 의미하기 때문에

⊢ A true 라고 쓰면 "I know A is true is true"가 되버린다

때문에 Per Martin-Löf는 저런 무근본 표기를 지양한 것이지요