타입 검사, 강타입, 타입 동등성
정수 3과 실수 0.5는 타입이 다른데 왜 더해질까?
타입 검사
피연산자가 연산자와 맞는가
타입 검사(type checking)는 연산자에 주어진 피연산자의 타입이 맞는지 확인하는 일입니다. 그대로 맞거나, 컴파일러가 맞는 타입으로 자동으로 바꿔 줄 수 있으면 호환 타입(compatible type)입니다. 이 자동 변환이 강제 변환(coercion)입니다.
연산자는 계산 기호이고 피연산자는 계산에 쓰이는 값입니다. 함수 호출과 대입문도 연산자와 피연산자로 보고 검사합니다.
타입 오류와 검사하는 때
실행 전에 잡거나 실행 중에 잡거나
맞지 않는 타입의 피연산자에 연산자를 쓰는 것이 타입 오류(type error)입니다. 타입이 모두 실행 전에 정해지는 언어는 거의 모든 타입 검사를 실행 전에 할 수 있습니다. 타입이 실행 중에 정해지는 언어는 검사도 실행 중에 해야 합니다.
예시입니다. 위 줄이 4강에서 본 정적 타입 바인딩, 아래 줄이 동적 타입 바인딩의 경우입니다.
강타입
타입 오류를 빠짐없이 잡는 언어
타입 오류가 언제나 잡히는 언어를 강타입(strongly typed) 언어라고 합니다. C와 C++는 강타입이 아닙니다. 함수에 넘기는 값의 타입 검사를 피해 갈 수 있고, 공용체는 검사하지 않기 때문입니다. 자바와 C#은 거의 강타입이고, ML과 F#은 강타입입니다.
'거의'인 것은 (int) 3.5처럼 프로그래머가 타입을 직접 바꾸는 명시적 타입 캐스팅 때문입니다. 점과 구멍의 수는 예시입니다.
타입 동등성 ① 이름
이름이 같아야 같은 타입
두 타입을 같은 타입으로 볼지 정하는 규칙이 타입 동등성(type equivalence)입니다. 이름 타입 동등성(name type equivalence)은 타입 이름이 같아야 같은 타입으로 봅니다. 구현은 쉽지만 빡빡합니다. 정수의 일부만 쓰는 부분 범위 타입은 속이 정수여도 정수와 다른 타입이 됩니다.
예시입니다. 부분 범위 타입(subrange type)은 1부터 100까지처럼 범위를 좁힌 타입입니다.
타입 동등성 ② 구조
속이 같으면 같은 타입
구조 타입 동등성(structure type equivalence)은 이름을 보지 않습니다. 두 타입의 속 구조가 같으면 같은 타입으로 봅니다. 이름 방식보다 유연하지만, 구조를 끝까지 견줘야 해서 구현이 더 어렵습니다.
예시입니다. 뜻이 다른 타입도 구조만 같으면 같은 타입이 된다는 점은 약점입니다.
5강을 돌아보면
유연함과 안전함 사이
이번 강에서 같은 줄다리기를 여러 번 봤습니다. 마음대로 쓰게 두면 타입 검사가 뚫리고, 검사를 지키면 쓸 수 있는 방법이 줄어듭니다. 1강에서 본 절충입니다.
절충(trade-off)은 하나를 얻으려 다른 하나를 내주는 것입니다.
다음 강의