당신이 본질적 대해 요구하는 것은 사이의 차이 연산 능력 과 어떤 일반적이라고 표현력 (또는 표현 (계산 또는 시스템)) 언어의를.
계산력
연산 능력은 문제의 종류의 언어가 계산할 수있는 일을 의미합니다. 가장 잘 알려진 계산 능력은 Universal Turing Machine 과 동일합니다 . Random Access Machines , λ-calculus , SK combinator calculus , µ-recursive 함수 , WHILE
프로그램 및 기타와 같은 다른 계산 시스템이 많이 있습니다. 그리고이 모든 것이 서로를 시뮬레이션 할 수 있으며, 이는 모두 같은 계산 능력을 가지고 있음을 의미합니다.
이것은 교회 튜링 논문 ( λ-calculus를 만든 Alonzo Church 와 Universal Turing Machine을 만든 Alan Turing의 이름을 따서 지어 짐) 을 일으킨다 . Church-Turing-Thesis는 다음 두 가지 측면에서 계산 가능성에 대한 가설입니다.
- 일반 계산이 가능한 모든 컴퓨팅 시스템은 똑같이 강력하며
- 알고리즘을 따르는 사람은 Turing Machine (및 기타 시스템)이 계산할 수있는 기능을 정확하게 계산할 수 있습니다.
두 번째는 컴퓨터 과학보다 마음의 철학 분야에서 더 중요합니다.
그러나 Church-Turing-Thesis 가 말하지 않은 두 가지 사항이 있습니다.
- 다양한 시뮬레이션이 얼마나 효율적 인지
- 문제의 인코딩이 얼마나 편리한 지 .
(1)의 간단한 예 : Random Access Machine에서 어레이를 복사하는 데는 어레이 길이에 비례하는 시간이 걸립니다. 그러나 Turing Machine에서는 배열 길이의 제곱 에 비례하는 시간이 걸립니다 . Turing Machine은 임의의 메모리 액세스가 없기 때문에 한 번에 한 셀 씩만 테이프를 가로 질러 이동할 수 있습니다. 따라서 배열 의 n 개 요소를 n 번 이동하여 복사해야합니다. 따라서 구현 세부 사항에서 추상화하려고 시도하는 점근 적 경우에도 계산 모델마다 성능 특성이 다를 수 있습니다.
(2)에 대한 예는 풍부합니다. λ- 미적분과 파이썬 은 모두 Turing-complete입니다. 그러나 파이썬이나 λ- 미적분으로 프로그램을 작성 하시겠습니까?
제가 지금까지 주름을 잡은 세 번째 주름도 있습니다. 모든 원래 시스템은 컴퓨터 과학자가 아닌 논리 학자, 철학자 또는 수학자에 의해 설계되었습니다. 단순히 컴퓨터와 컴퓨터 과학이 존재하지 않았기 때문입니다. Konrad Zuse 의 첫 번째 실험 (프로그래밍 및 / 또는 Turing-complete가 아니 었음) 이전에도이 모든 것은 1930 년대 초로 거슬러 올라갑니다 . 그들은 "자연수에 대한 계산 가능한 기능"에 대해서만 이야기합니다.
이제 밝혀진 바와 같이, 자연수에 대한 함수로 표현할 수 있는 것이 많이 있습니다. 결국 현대 컴퓨터는 그보다 훨씬 적은 수를 얻습니다 (기본적으로 숫자 0과 1에 대한 3-4 개의 함수, 그게 전부입니다) 예를 들어 운영 체제는 어떤 기능을 계산합니까?
환경과 상호 작용하는 부작용 인 I / O의 개념은 "자연수에 대한 함수"라는 개념에 의해 포착되지 않습니다. 그럼에도 불구하고, 그것으로, 이후 어떤 중요한 것입니다 사이먼 페이튼 존스가 한 번 넣어 "뜨거운 당신의 CPU를 만들 것입니다 않습니다 어떠한 부작용으로 모두에게 순수한 기능을" 청중 대답하는에, 그, 실제로 " 입니다 측면이 -효과도! "
Idris 의 디자이너 인 Edwin Brady (반만)는 "Tetris-complete"라는 용어를 농담으로 사용합니다. 환경과 상호 작용하는 사소한 프로그램을 작성하는 데 사용됩니다 ". 더 아이러니하게도, 그는 Idris에서 Space Invaders 클론을 구현함으로써 이것을 증명 하지만, Tetris가 Space Invaders로 줄어든다고 확신합니다.
지적해야 할 또 다른 사항은 Turing-equivalence 가 실제로 "유용한"프로그램 작성에 대해 이야기하기에 충분 하지 않을뿐만 아니라 OTOH도 필요 하지 않을 수도 있다는 것 입니다. 예를 들어 SQL은 ANSI SQL : 1999에서만 Turing과 동일 해졌 지만 그 전에는 여전히 유용했습니다. 실제로 일부 사람들은 튜링과 동등하게 만드는 것이 그 유용성에 전혀 추가되지 않았다고 주장 할 수도 있습니다. 튜링과 동등하지 않은 많은 도메인 특정 언어가 있습니다. 데이터 설명 언어는 일반적으로 사용되지 않아야합니다. 전체 언어는 분명히 튜링과 동일 할 수는 없지만 여전히 이벤트 루프, 웹 서버 또는 운영 체제를 작성할 수 있습니다. 튜링과 동등한 언어이지만 실제로는 실수로 간주되는 언어도 있습니다.
따라서 프로그램을 정적으로 분석하지 않는 한 Turing-equivalence는 전혀 흥미롭지 않습니다.
표현력
우리의 계산 시스템이 우리의 문제를 전혀 해결할 수 없을 정도로 계산적으로 강력하다고 가정 할 때, 우리가해야 할 일은 그 문제를 해결하기위한 알고리즘을 해당 시스템에 대한 공식적인 표기법으로 표현하는 것입니다. 다시 말해, 우리는 컴퓨터 언어로 프로그램을 작성해야합니다. 그것이 표현 의 개념이 나오는 곳입니다.
본질적으로 특정 프로그래밍 언어로 프로그램을 작성하는 것이 얼마나 "쉬운"또는 "즐거운"것인지를 말합니다. 보시다시피, 개념은 기술보다 상당히 모호하고 주관적이며 심리적입니다.
그러나보다 정확한 정의가 시도됩니다. 가장 유명한 것 (그리고 내가 알고있는 것 중 가장 엄격한 것)은 Matthias Felleisen 이 그의 논문 에서 프로그래밍 언어의 표현력에 관한 것입니다 (처음 두 페이지는 온화한 소개를 포함하고 나머지는 더 고기입니다).
다른 언어로 언어에서 프로그램을 번역 할 때, 당신이해야 할 몇 가지 변화가 로컬 (예 : 예 : 전환으로 포함되어 있습니다 : 메인 직관이 있습니다 FOR
에 루프를 WHILE
루프 또는 조건부로 루프 GOTO
들), 일부는 세계에 대한 변경이 필요 프로그램의 구조.
로컬 변환만으로 한 언어의 한 기능을 다른 언어의 다른 기능으로 대체 할 수있는 경우 이러한 기능은 표현력에 영향을 미치지 않는다고합니다. 이것을 구문 설탕 이라고 합니다.
반면, 프로그램의 전체 구조를 변경해야하는 경우 번역하려는 언어가 기능을 표현할 수 없다고합니다. 그리고 당신이 번역하는 언어는 (이 기능과 관련하여) 더 표현력 이 있다고합니다 .
이것은 표현의 객관적으로 측정 가능한 정의를 제공합니다. 또한 개념은 기능에 따라 상황에 따라 달라지며 비교됩니다. 따라서 언어 A의 모든 프로그램을 로컬 변경만으로 언어 B 로 변환 할 수 있고 로컬 B 만 변경 하여 A 로 변환 할 수 없는 언어 B의 프로그램이 하나 이상 있으면 언어 B 가 언어보다 엄격하게 표현됩니다 에이. 그러나 두 가지 언어로 된 많은 프로그램을 앞뒤로 번역 할 수 있지만 두 언어로 된 일부 프로그램은 다른 언어로 번역 할 수 없습니다. 이는 어느 언어도 다른 언어보다 엄격하게 표현하지 않으며, 다른 프로그램을 다른 방식으로 표현할 수있는 다른 기능을 가지고 있음을 의미합니다.
이것은 "보다 표현력이있다"는 것이 무엇을 의미하는지에 대한 공식적인 정의를 제공하지만, 현상의 심리적 개념을 여전히 포착하지는 못한다. 예를 들어,이 모델에 따르면 구문 설탕은 언어의 표현력을 향상시키지 않습니다. 언어의 로컬 힘만 사용하여 번역 할 수 있기 때문입니다. 그러나 우리가 경험에서 알고 가지고 FOR
,이 WHILE
, 그리고 IF
그들이 조건부 단지 문법 설탕 경우에도 가능한 GOTO
우리의 의도를 표현하는 차종 쉽게가 .
사실, 언어마다 다른 기능을 사용하여 문제에 대한 다른 사고 방식을 더 쉽고 어렵게 표현할 수 있습니다. 그리고 어떤 사람들은 자신의 의도를 더 쉽게 표현하는 한 가지 방법을 찾고 다른 사람들은 다른 방법을 찾을 수도 있습니다.
StackOverflow의 Ruby 태그에서 찾은 예 : Ruby 태그를 따르는 많은 사용자는 루프가 재귀보다 이해하기 쉽고 재귀는 고급 기능 프로그래머에게만 해당하며 루프는 초보자에게는 더 직관적이라고 주장하지만 다음과 같이 코드를 직관적으로 작성하는 완전한 신규 이민자 :
def rock_paper_scissors
get_user_input
determine_outcome
print_winner
rock_paper_scissors # start from the top
end
어떤 사람들은 일반적으로 "이것이 작동하지 않습니다"와 "그들이 잘못하고 있습니다"라고 "정확한 방법"이라고 말합니다.
def rock_paper_scissors
loop do
get_user_input
determine_outcome
print_winner
end
end
따라서 꼬리 재귀가 루프 구성보다 "루핑"의 개념을 표현하는 더 자연스러운 방법 인 사람들이 있습니다.
요약
두 언어가 튜링과 동등하다는 사실은 똑같이 정확히 한 가지를 말합니다. 튜링 머신처럼 자연수에서 동일한 함수 세트를 계산할 수 있다는 것입니다. 그게 다야.
그것들이 얼마나 빨리 그 함수들을 계산하는지에 대해서는 아무 말도하지 않습니다. 이러한 기능을 쉽게 표현할 수 있다는 말은 없습니다. 그리고 자연수에 대한 계산 기능 외에도 (C 라이브러리에 연결, 사용자의 입력 읽기, 화면에 출력 쓰기) 다른 기능을 수행하지 않습니다.
이것은 각 프로그래밍 언어가 완전히 해결할 수있는 문제의 클래스가 언어에 따라 다양하다는 것을 의미합니까?
예.
- 화면에 인쇄하는 것과 같이 "Turing-complete"라는 용어 (자연수에 대한 컴퓨팅 기능에만 관련됨)라는 용어로 다루지 않는 문제가 있습니다. 두 언어는 튜링이 완료 될 수 있지만 하나는 화면에 인쇄 할 수 있고 다른 하나는 인쇄 할 수 없습니다.
- 두 언어가 모두 같은 문제를 해결할 수 있더라도 인코딩이 얼마나 복잡한 지,이 인코딩을 표현하는 것이 얼마나 쉬운 지에 대해서는 아무 말도하지 않습니다. 예를 들어 C는 Haskell 인터프리터를 C로 작성하여 Haskell이 할 수있는 모든 문제를 해결할 수 있습니다… 그러나 이런 식으로 문제를 해결하려면 Haskell 인터프리터를 먼저 작성해야합니다!