해석 된 코드와 컴파일 된 코드의 차이점은 아마도 Raphael의 주석에서 강조한 것처럼 허구 일 것입니다 .
the claim seems to be trivially wrong without further assumptions: if there is
an interpreter, I can always bundle interpreter and code in one executable ...
사실 코드는 항상 소프트웨어, 하드웨어 또는 두 가지의 조합으로 해석되며 컴파일 과정에서 코드가 어떤 것인지 알 수 없습니다.
컴파일로 인식하는 것은 한 언어 (소스)에서 다른 언어 (대상) 로의 변환 프로세스입니다 . 그리고 의 해석기 는 일반적으로 의 해석기와 다릅니다 .STST
컴파일 된 프로그램은 하나의 구문 형태에서 번역 다른 구문 형태에 , 등, 그 언어의 의도 된 의미를 부여 와 , 및 당신이 일반적으로하려고하는 몇 가지까지 같은 연산 동작을 복잡성 또는 단순한 효율성 (시간, 공간, 표면, 에너지 소비)과 같은 최적화를 위해 변경 될 수 있습니다. 정확한 정의가 필요하기 때문에 기능적 동등성에 대해 이야기하지 않습니다.PSPTSTPSPT
일부 컴파일러는 실제로 "실행"을 향상시키지 않고 코드 크기를 줄이기 위해 단순히 사용되었습니다. 이것은 플라톤 시스템 에서 사용되는 언어의 경우입니다 (컴파일 링이라고 부르지는 않았지만).
컴파일 프로세스 후에 더 이상 의 인터프리터가 필요하지 않으면 코드가 완전히 컴파일 된 것으로 간주 할 수 있습니다 . 적어도 이것이 이론적 질문보다는 공학적 질문 으로 귀하의 질문을 읽을 수있는 유일한 방법입니다 (이론적으로는 항상 통역사를 재구성 할 수 있기 때문에).S
문제를 일으킬 수있는 것 중 하나는 메타 순환 입니다. 프로그램이 자체 소스 언어 로 구문 구조를 조작 하여 프로그램 프래그먼트를 작성하여 마치 원래 프로그램의 일부인 것처럼 해석되는 경우입니다. 당신이 언어에 임의의 프로그램 조각을 생성 할 수 있기 때문에 의미 구문 조각을 조작하는 임의의 계산의 결과로, 당신이 (공학적인 관점에서)이 거의 불가능 만들 수있는 언어로 프로그램을 컴파일 할 거라 생각 있도록, 이제 조각을 생성 합니다. 따라서 대한 인터프리터 가 필요하거나 적어도 에서 컴파일러 로SSTTSST 에서 생성 된 프래그먼트의 온더 플라이 컴파일 의 경우 입니다 ( 이 문서 참조 ).S
그러나 이것이 어떻게 올바르게 공식화 될 수 있는지 잘 모르겠습니다 (지금은 시간이 없습니다). 그리고 공식화되지 않은 문제에 대한 큰 단어는 불가능 합니다.
추가 사항
36 시간 후에 추가되었습니다. 이 매우 긴 속편을 건너 뛸 수 있습니다.
이 질문에 대한 많은 의견은 문제에 대한 두 가지 견해를 보여줍니다. 문제를 의미가없는 것으로 보는 이론적 견해와 불행히도 그렇게 쉽게 공식화되지 않은 공학적 견해.
해석과 편집을 보는 방법에는 여러 가지가 있으며 몇 가지를 스케치하려고합니다. 내가 관리 할 수있는 한 비공식적으로 노력할 것이다
묘비 다이어그램
초기 공식화 (1990 년대 후반에 1960 년대 초) 중 하나는 T 또는이다
묘비도 . 이 다이어그램은 인터프리터 또는 컴파일러의 구현 언어, 해석 또는 컴파일되는 소스 언어 및 컴파일러의 경우 대상 언어를 작성 가능한 그래픽 요소로 표시합니다. 보다 정교한 버전은 속성을 추가 할 수 있습니다. 이 그래픽 표현은 공리, 추론 규칙으로 볼 수 있으며, 공리에서 존재한다는 증거, 즉 Curry-Howard에서 프로세서 생성을 기계적으로 도출하는 데 사용할 수 있습니다.
부분 평가
또 다른 흥미로운 관점은 부분 평가 패러다임입니다. 입력 데이터가 주어지면 답을 계산하는 일종의 함수 구현으로 프로그램을 간단하게 볼 수 있습니다. 통역자는
언어에 대한 프로그램 수행하는 프로그램이다
작성된 와 데이터 해당 프로그램을, 그리고 의미에 따른 계산 결과 . 일부 평가는 두 인수의 프로그램을 전문으로하는 기술이다 및 , 단 하나의 인수는, 말할 때 , 알려져있다. 의도는 마지막으로 두 번째 인수를 얻을 때 더 빠른 평가를하는 것입니다ISSpSSdSa1a2a1a2 . 경우에 특히 유용합니다 보다 더 자주 변경 와 부분 평가의 비용으로 경우에만 모든 계산을 상각 할 수있다 변화하고있다.a2a1a1a2
이는 데이터의 좀 더 정적 인 부분이 사전 처리되는 알고리즘 설계 (종종 SE-CS에 대한 첫 번째 의견 주제)에서 빈번한 상황이므로 모든 응용 프로그램에서 사전 처리 비용을 상각 할 수 있습니다. 입력 데이터의 가변 부분이 많은 알고리즘
첫 번째 인수는 실행될 프로그램이며 일반적으로 다른 데이터로 여러 번 실행되거나 하위 데이터가 다른 데이터로 여러 번 실행되므로 이는 인터프리터의 상황이기도합니다. 따라서 주어진 프로그램을 첫 번째 논거로이 프로그램에서 부분적으로 평가함으로써 주어진 프로그램의 빠른 평가를 위해 통역사를 전문화하는 것이 당연한 생각이되었습니다. 이것은 프로그램을 컴파일하는 방법으로 여겨 질 수 있으며 첫 번째 (프로그램) 논거에서 통역사의 부분 평가를 통해 컴파일에 대한 중요한 연구 작업이 진행되었습니다.
Smn 정리
부분 평가 접근법에 대한 좋은 점은 이론, 특히 Kleene의 Smn 정리에 뿌리를두고 있다는 것
입니다. 나는 순수한 이론가들을 화나게하지 않기를 희망하면서 그것을 직관적으로 제시하려고 노력하고 있습니다.
재귀 함수 의 Gödel 번호 매기기 가 주어지면 를 하드웨어로 볼 수 있으므로 프로그램 의 Gödel 번호
(읽기 객체 코드 ) 가 주어지면 는 의해 정의 된 함수입니다 (예 : 객체 코드로 계산) 하드웨어).φφpφpp
가장 간단한 형태로 정리는 다음과 같이 위키피디아에 표시됩니다 (소수의 표기법이 약간 변경됨).
괴델 넘버링 감안 재귀 함수의 원시적 재귀 함수가 추종성 두 인자는 : 모든 괴델 번호에 대한 일부 계산 가능한 함수 두 인수의 표정 및 는 자연수 와 의 동일한 조합에 대해 정의 되며 해당 값은 해당 조합에 대해 동일합니다. 다시 말해, 모든 대해 다음과 같은 확장 기능이 동일합니다 .
φσqfφσ(q,x)(y)f(x,y)xyxφσ(q,x)≃λy.φq(x,y).
이제 를 인터프리터 , 를 프로그램 의 소스 코드로 , 를 해당 프로그램 의 데이터 로 사용하면 다음 과 같이 쓸 수 있습니다.
qISxpSydφσ(IS,pS)≃λd.φIS(pS,d).
φIS 는
하드웨어 에서 인터프리터 를 실행하는 것으로 , 즉 언어 작성된 프로그램을 해석 할 수있는 블랙 박스로 볼 수 있습니다 .ISS
함수 통역자 전문 함수로 간주 될 수있다 프로그램의 부분적으로 평가. 따라서 Gödel) 번호 는 프로그램 의 컴파일 된 버전 인 객체 코드를 가지고 있음을 알 수 있습니다 .σISPSσ(IS,pS)pS
따라서 함수 는
언어 작성된 프로그램 의 소스 코드를 인수로 해당 프로그램의 객체 코드 버전을 반환 하는 함수로 볼 수 있습니다 따라서 는 보통 컴파일러라고합니다.CS=λqS.σ((IS,qS)qSSCS
몇 가지 결론
그러나 내가 말했듯이 "이론은 거짓말 쟁이가 될 수있다"거나 실제로는 하나 인 것처럼 보인다. 문제는 함수를 전혀 모른다는 것입니다 . 실제로 그러한 기능이 많이 있으며, 내 생각에 정리 증명은 매우 간단한 정의를 사용할 수 있으며 엔지니어링 관점에서 Raphael이 제안한 솔루션보다 더 나을 수도 있습니다. 소스 코드 인터프리터와 . 이 작업은 항상 수행 할 수 있으므로 컴파일이 항상 가능합니다.q S I SσqSIS
컴파일러에 대한보다 제한적인 개념을 공식화하려면보다 미묘한 이론적 접근이 필요합니다. 나는 그 방향으로 무엇을했는지 모른다. 부분 평가에 대한 실제 작업은 엔지니어링 관점에서보다 현실적입니다. 물론 Curry-Howard isomorphism을 기반으로 형식 이론의 맥락에서 개발 된 사양 증명에서 프로그램 추출을 포함하여 컴파일러를 작성하는 다른 기술도 있습니다 (그러나 저는 제 도메인 외부로 나가고 있습니다) .
여기에서의 나의 목적은 라파엘의 말이 "미친"것이 아니라 일이 명백하지 않고 단순하지도 않다는 것을 상기시켜 준다는 것입니다. 불가능하다고 말하는 것은 그것이 어떻게 그리고 왜 불가능한 지를 정확하게 이해하기 위해서는 정확한 정의와 증거를 요구하는 강력한 진술입니다 . 그러나 그러한 증거를 표현하기 위해 적절한 공식화를 구축하는 것은 매우 어려울 수 있습니다.
이는 특정 기능을 컴파일 할 수 없더라도 엔지니어가 이해한다는 의미에서 Gilles의 답변에서 언급 한 것처럼 이러한 기능을 사용하지 않는 프로그램의 일부에는 표준 컴파일 기술을 항상 적용 할 수 있습니다.
언어에 따라 컴파일 타임에 어떤 작업이 수행되고 런타임에 다른 작업이 수행되어야하므로 특정 코드가 필요하다는 Gilles의 주요 설명을 따르기 위해 컴파일 개념이 실제로 있음을 알 수 있습니다 잘못 정의되어 있으며 아마도 만족스러운 방식으로 정의 할 수 없을 것입니다. 컴파일은 일부 알고리즘에서 정적 데이터 전처리와 비교할 때 부분 평가 섹션 에 표시하려고 시도한 최적화 프로세스 일뿐 입니다.
복잡한 최적화 프로세스로서 컴파일 개념은 실제로 연속체에 속합니다. 언어 또는 프로그램의 특성에 따라 일부 정보를 정적으로 사용할 수 있으며 더 나은 최적화가 가능합니다. 다른 것들은 런타임에 연기되어야합니다. 상황이 정말 나빠지면 적어도 프로그램의 일부 부분에 대해 런타임에 모든 작업을 수행해야하며 소스 코드를 인터프리터와 번들링하면됩니다. 따라서이 번들링은이 컴파일 연속체의 최저 수준 일뿐입니다. 컴파일러에 대한 많은 연구는 동적으로 수행되었던 작업을 정적으로 수행하는 방법을 찾는 것입니다. 컴파일 타임 가비지 콜렉션이 좋은 예입니다.
컴파일 과정에서 머신 코드를 생성해야한다는 말은 도움이되지 않습니다. 인터프리터가 기계 코드이기 때문에 번들링으로 할 수있는 일입니다 (물론, 크로스 컴파일로 조금 더 복잡해질 수 있습니다).