코드를 작성할 때, 우리는 당연하게도 다양한 프로퍼티를 선언하고 할당하게 되는데 이 경우 어쩔 수 없이 타입 지정에 대한 고민을 할 수 밖에 없다. 물론 언어에 따라서 타입을 꼭 선언해주지 않아도 컴파일러가 알아서 체크를 해주기도 하지만 그렇지 않은 언어도 분명 존재한다.
강한 타입(StrongType) vs 약한 타입(WeakType)
타입을 구분하는 데에 있어 2가지 정도의 구분 방식이 있는데 그 중 하나가 강한 타입과 약한 타입이다. 그렇다면 대체 무엇을 기준으로 이들을 나누는 것일까?
먼저 약한 타입은 옳고 그름이 실행에 있어 방해요소가 되지 않는 타입을 의미한다. 즉, 우리가 작성한 타입 정보가 잘못되어 런타임 시에 타입 오류가 발생하여도 실행 자체를 막지 않는다.
그렇다면 당연히 강한 타입은 이와 반대되는 개념으로서 타입 검사에서 실패가 될 경우에는 프로그램의 실행 자체가 불가하게 되는 것을 의미하게 된다.
다만 두 타입 모두 뚜렷한 장단점을 기반으로 나뉘어져 있다기보다는 이러한 타입의 특성에 대하여 조금이라도 뚜렷함을 드러내고자 원시적인 타입 개념에 용어를 붙여준 것에 가깝기에 이 둘을 확실히 나눌 수 있는 대척적인 개념이라고 보기에는 어렵다고 할 수 있다.
정적 타입(StaticType) vs 동적 타입(DynamicType)
위의 타입 구분 외에도 정적 타입 검사와 동적 타입 검사로 타입 시스템에 대한 언어 구분이 가능하다.
먼저 정적 타입 검사의 경우에는 우리가 작성한 코드의 타입이 올바른 지 확인하는 절차를 런타임 이전에 시행하는 것을 의미한다. 따라서 정적 타입 검사의 언어들은 프로그램을 실행하기 전부터 이미 타입에 대한 에러를 바로 포착할 수 있기에 실행 시에 오류를 방지할 수 있다.
물론 타입 검사가 미리 진행된다고 해서 모든 오류를 방지할 수 있는 것은 아니다.
(divided-by-zero를 대표적인 예외로 든다.)
이와 달리 동적 타입 검사는 작성한 코드의 타입이 올바른 지에 대한 확인 절차가 런타임 시에 실행된다. 그러므로 프로그램을 실행하기 전까지는 타입과 관련된 에러가 발생하는 지에 대해서 알 수가 없으며, 프로그램을 실행해야 오류를 확인할 수 있게 된다.
두 타입 확인 방식은 결론적으로 정적 방식은 타입이 정해지면 변할 수 없는 컴파일러 언어, 동적 방식은 타입이 그때그때 변할 수 있는 인터프리터 언어라고 풀어낼 수 있다.
정적 방식의 경우 사소한 수정에도 통째로 컴파일을 할 필요가 있어 생산적인 측면에서는 동적 방식이 유리하나, 컴파일 이후의 속도적인 측면에서는 정적 방식이 더 유리하다.
그 외에도 정적 타입 언어는 코드의 가독성이 좋다, 동적 타입 언어는 타입 관련 코드나 규칙이 상대적으로 적어 코드가 짧고 Learning-Curve가 낮다는 점들의 장단점도 존재한다.
그럼 Swift는 어떤 언어인가?
Swift는 데이터 타입에 대한 구분이 엄격하고, 이에 대하여 컴파일 단계에서 이미 에러 유무를 알려주는 정적 타입 언어이다.
상수인 let은 컴파일 전에 미리 선언되어야 하고, 변수인 var는 데이터 타입에 대한 변경이 불가하다는 점 또한 정적 타입 언어라는 것을 여실히 보여주는 점 중에 하나이다.