[프로그래밍 언어론] 타입과 언어의 분류
언어의 타입
프로그램에서 변수의 타입이 언제 결정되는지에 따라 언어를 정적 타입, 동적 타입 언어로 구분할 수 있다. 변수의 타입이 컴파일 시간에 결정되어 고정된다면 정적 타입 언어이며, 변수의 타입이 고정되지 않고 실행 중에 변하는 언어를 동적 타입 언어라 한다. 정적 타입 언어에는 Java, C, C++, FORTRAN, Pascal, Scala 등이, 동적 타입 언어로는 Perl, Python, Scheme, JavaScript 등이 있다. 정적 타입 언어는 변수 타입이 컴파일 시간에 결정되어 고정되므로 타입 검사 역시 컴파일 시간에 이루어지는 반면, 동적 타입 언어는 변수 타입이 실행 중에 변할 수 있으므로 타입 검사는 인터프리터에 의해 실행 중에 이루어진다.
강한 타입, 약한 타입
타입 사용 규칙을 타입 규칙이라 하며, 언어가 정하는 타입 규칙의 엄격함에 따라 프로그래밍 언어를 강한 타입, 약한 타입으로 분류할 수 있다. 강한 타입 언어란 엄격한 타입 규칙을 적용해 가능한 모든 타입 오류를 찾아낼 수 있는 언어이며, 느슨한 타입 규칙을 적용해 타입 오류를 찾아내는 언어를 약한 타입 언어라 한다. Java, C#, Python은 강한 타입 언어로 강한 타입 언어일수록 자동 형 변환을 하지 않고 엄격한 타입 검사가 이루어져 프로그램이 실행 중일 때 타입 오류가 발생하지 않는다. 반면 C, C++, PHP, Perl, JavaScript와 같은 약한 타입 언어는 자동 형 변환을 하며 느슨한 타입 검사를 하므로 프로그램이 타입 검사를 통과하여도 프로그램 실행 중 타입 오류가 발생할 수 있다. 몇 가지 언어의 예시를 살펴보자.
Java - 강한 정적 타입 언어
Java는 강한 타입 언어이며 정적 타입 언어이므로, 변수의 타입이 컴파일 시간에 결정되어 고정되고 엄격한 타입 규칙을 적용해 가능한 모든 타입 오류를 찾아낼 것이다. Java에서 다음 문장을 실행하면 어떻게 될까?
int x = 0;
float y = 3.14f;
char z = 'A';
x = y; // 타입 오류
y = z; // 자동 형변환
x에 y 값을 저장하는 것은 정수 자료형에 부동소수점 자료형을 저장하는 것으로 x에 y의 값을 저장하려면 y 값의 정밀도를 잃어버린다. 따라서 위 프로그램은 실행되지 않는다. 추가로 y에 z의 값을 저장하는 것은 오류가 발생하지 않는데, 이것은 문자 'A'의 아스키 코드 값을 부동소수점으로 확장 변환하여 저장할 수 있으므로 오류가 발생하지 않는다.
C - 약한 정적 타입 언어
C는 약한 타입 언어이며 정적 타입 언어이다. 따라서 변수 타입이 Java와 마찬가지로 컴파일 시간에 결정되어 고정된다. 하지만 약한 타입 규칙을 적용해 프로그램 실행 중 타입 오류가 발생할 수 있다.
int x = 0; float y = 3.14; char z = 'A;
x = y;
printf("%d\n", x);
y = z;
printf("%f\n", y);
z = x;
printf("%c\n", z);
C는 약한 타입 검사를 하므로 C에서 위 코드를 실행하면 Java와 다르게 정상적으로 작동하여 변수에 저장된 값을 정상적으로 출력한다. 따라서 첫 번째 x = y 대입문에서는 float 타입 y의 축소 변환이 이루어져 3의 값이 x에 저장된다. y = z 대입문은 문자 'A'의 아스키 코드 값 65가 float로 확장 변환되어 y에 저장될 것이며, z = x 대입문은 아스키 코드 값이 3인 문자가 z에 저장될 것이다.
Python - 강한 동적 타입 언어
Python 언어를 사용한 적이 있다면 Python은 변수를 선언할 때 타입을 작성하지 않는다는 것을 알고 있을 것이다. 이는 Python이 변수가 타입이 고정되지 않고 변할 수 있으며, 강한 타입 검사를 실행하는 언어이기 때문이다.
>>> x = 3
>>> y = "21"
>>> print(x + y)
Python에서 위 코드를 작성해 실행하면 오류가 발생해 정상적으로 실행되지 않을 것이다. 그 이유는 Python이 엄격한 타입 규칙을 적용하여 print(x + y)에서 자동 형변환을 실행하지 않기 때문이다. 이외에 변수의 타입을 선언하지 않는 것은 앞서 말하였듯 Python은 변수의 타입이 고정되지 않고 변할 수 있는 동적 타입 언어이기 때문이다.
JavaScript- 약한 동적 타입 언어
JavaScript는 변수가 타입이 고정되지 않고 변할 수 있으며, 약한 타입 검사를 실행하는 언어이다. JavaScript에서 위 Python 예시 문장을 실행하면 어떻게 될까?
>>> var x = 3
>>> var y = "21"
>>> var print(x + y)
Python에서 실행되지 않았던 위 문장은 JavaScript에서는 잘 실행되어 321이라는 결과를 출력한다. 그 이유는 JavaScript는 약한 타입 규칙을 적용하여 print(x + y)에서 정수 x를 문자열로 자동 형변환하여 x + y를 연산하기 때문이다. 이외에 변수의 타입을 따로 선언하지 않는 것은 앞서 말하였듯 Python과 마찬가지로 JavaScript가 동적 타입 언어이기 때문이다.