오,이 질문에 최선을 다해 답변을 드리겠습니다. 나는 내 생각을 순서대로 알 수 있기를 바랍니다.
@Doval이 언급하고 질문자가 지적했듯이 (무례한 것은 아니지만) 실제로 유형 시스템이 없습니다. 태그를 사용하는 동적 검사 시스템이 있습니다. 일반적으로 훨씬 약하고 흥미도 덜합니다.
"유형 시스템이란 무엇인가"라는 질문은 매우 철학적 일 수 있으며, 그 문제에 대해 다른 견해로 책을 채울 수 있습니다. 그러나 이것은 프로그래머를위한 사이트이므로 가능한 한 실용적으로 답변하려고 노력할 것입니다 (실제로 유형은 프로그래밍에 매우 실용적입니다.
개요
보다 공식적인 토대에 뛰어 들기 전에 바지 자리부터 시작하여 유형 시스템의 장점을 이해하십시오. 타입 시스템은 프로그램에 구조를 부과합니다 . 그들은 우리가 어떻게 다양한 기능과 표현을 함께 연결할 수 있는지 알려줍니다. 구조가 없다면, 프로그램은 불가능하고 매우 복잡하여 프로그래머의 작은 실수로 피해를 입을 수 있습니다.
타입 시스템으로 프로그램을 작성하는 것은 브레이크가 작동하고 문이 안전하게 닫히고 엔진이 기름칠되는 등 박하 상태에서 돌보는 것과 같습니다. 타입 시스템이없는 프로그램을 작성하는 것은 헬멧이없고 바퀴가 달린 모터 사이클을 타는 것과 같습니다 스파게티에서. 당신은 당신을 절대적으로 통제 할 수 없습니다.
토론을 접지하기 위해, 우리는 문자 식으로 언어가 있다고 가정하자 num[n]
및 str[s]
그 숫자 n 및 문자열의 각각과 기본 기능을 나타냅니다 plus
및 concat
의도 된 의미를. 분명히, 당신은 plus "hello" "world"
또는 같은 것을 쓸 수 있기를 원하지 않습니다 concat 2 4
. 그러나 어떻게 이것을 막을 수 있습니까? 선험적으로는 , 문자열 리터럴 "세계"에서 숫자 2를 구별 할 방법이 없습니다. 우리가 말하고 싶은 것은이 표현들이 다른 상황에서 사용되어야한다는 것입니다. 그들은 다른 유형이 있습니다.
언어와 유형
조금 뒤로 물러서 보자 : 프로그래밍 언어 란 무엇인가? 일반적으로 우리는 프로그래밍 언어를 구문과 의미론의 두 계층으로 나눌 수 있습니다. 이것을 각각 statics 및 dynamics 라고도합니다 . 이 두 부분 사이의 상호 작용을 중재하기 위해 유형 시스템이 필요하다는 것이 밝혀졌습니다.
통사론
프로그램은 나무입니다. 컴퓨터에 쓰는 텍스트 줄에 속지 마십시오. 이들은 사람이 읽을 수 있는 프로그램의 표현 일뿐 입니다. 프로그램 자체는 추상 구문 트리 입니다. 예를 들어 C에서는 다음과 같이 작성할 수 있습니다.
int square(int x) {
return x * x;
}
이것이 프로그램 의 구체적인 구문입니다 (조각). 트리 표현은 다음과 같습니다.
function square
/ | \
int int x return
|
times
/ \
x x
프로그래밍 언어는 제공 문법 해당 언어의 유효한 나무 정의 (콘크리트 또는 추상 구문 중 하나를 사용할 수있다)를. 이것은 일반적으로 BNF 표기법과 같은 것을 사용하여 수행됩니다. 나는 당신이 만든 언어에 대해 이것을했다고 가정합니다.
의미론
좋아, 우리는 프로그램이 무엇인지 안다. 그러나 그것은 단지 정적 트리 구조 일 뿐이다. 아마도 우리는 프로그램이 실제로 무언가를 계산하기를 원합니다. 의미론이 필요합니다.
프로그래밍 언어의 의미론은 풍부한 연구 분야입니다. 대체로 두 가지 접근 방식이 있습니다 : dendomtional semantics 및 operating semantics . 명칭 의미론은 프로그램을 기본 수학 구조 (예 : 자연수, 연속 함수 등)에 매핑하여 프로그램을 설명합니다. 그것은 우리 프로그램에 의미를 제공합니다. 반대로 작동 의미론은 프로그램 실행 방법을 자세히 설명하여 프로그램을 정의합니다. 내 생각에, 운영 의미론은 프로그래머 (나 자신을 포함하여)에게 더 직관적이므로 그렇게 생각해 봅시다.
공식적인 운영 의미론을 정의하는 방법은 다루지 않지만 (세부 사항은 약간 관련되어 있음) 기본적으로 다음과 같은 규칙을 원합니다.
num[n]
가치이다
str[s]
가치이다
- 경우
num[n1]
와은 num[n2]
정수로 평가 n_1$ and $n_2$, then
플러스 (NUM [N1], NUM [N2])`정수 $로 평가는 n_1 + n_2를 $.
- 경우
str[s1]
와는 str[s2]
문자열 S1과 S2로 평가 한 후 concat(str[s1], str[s2])
문자열 s1s2로 평가합니다.
등 규칙은 실제로 훨씬 공식적이지만 요점을 얻습니다. 그러나 곧 문제가 발생합니다. 다음을 쓸 때 어떤 일이 발생합니까?
concat(num[5], str[hello])
흠. 이것은 수수께끼입니다. 우리는 숫자를 문자열로 연결하는 방법에 대한 규칙을 정의하지 않았습니다. 이러한 규칙을 만들려고 시도 할 수 있지만이 작업이 의미가 없음을 직관적으로 알고 있습니다. 이 프로그램이 유효하지 않기를 바랍니다. 따라서 우리는 유형에 필연적으로 인도됩니다.
종류
프로그램은 언어 문법에 의해 정의 된 트리입니다. 프로그램은 실행 규칙에 의해 의미가 부여됩니다. 그러나 일부 프로그램은 실행할 수 없습니다. 즉, 일부 프로그램은 의미가 없습니다 . 이러한 프로그램은 잘못된 유형입니다. 따라서 입력은 언어로 의미있는 프로그램을 특징 짓습니다. 프로그램의 형식이 잘 잡히면 실행할 수 있습니다.
몇 가지 예를 들어 봅시다. 평가 규칙과 마찬가지로 입력 규칙을 비공식적으로 제시하지만 엄격하게 만들 수 있습니다. 다음은 몇 가지 규칙입니다.
- 형식의 토큰
num[n]
은 유형이 nat
있습니다.
- 형식의 토큰
str[s]
은 유형이 str
있습니다.
- 표현하면
e1
유형이 nat
표현은 e2
유형이 nat
다음 식을 plus(e1, e2)
입력했다 nat
.
- 표현하면
e1
유형이 str
표현은 e2
유형이 str
다음 식을 concat(e1, e2)
입력했다 str
.
따라서 이러한 규칙에 따라 plus(num[5], num[2])
유형 nat
이 있지만에 유형을 할당 할 수 없습니다 plus(num[5], str["hello"])
. 우리는 프로그램 (또는 표현식)이 어떤 유형을 할당 할 수 있다면 잘 타이핑되고 그렇지 않으면 잘못 타이핑된다고 말합니다. 형식이 잘 잡힌 프로그램을 모두 실행할 수 있으면 형식 시스템은 소리 가 납니다 . 하스켈은 소리입니다. C는 아닙니다.
결론
유형에 대한 다른 견해가 있습니다. 어떤 의미에서 유형은 직관 논리에 해당하며 범주 이론에서 객체로 볼 수도 있습니다. 이러한 연결을 이해하는 것은 매혹적이지만 프로그래밍 언어를 작성하거나 디자인하려는 경우에만 필수적인 것은 아닙니다. 그러나 프로그램의 형성을 제어하기위한 도구로 유형을 이해하는 것입니다 프로그래밍 언어 설계 및 개발에 필수적인. 나는 표현할 수있는 유형의 표면 만 긁었다. 나는 그들이 당신의 언어에 통합 할만큼 가치가 있다고 생각하기를 바랍니다.