프로그래밍에서의 타입

프로그래밍에서의 타입

타입의 탄생

변수를 선언할 때 타입을 지정해야하는 언어를 써본 적이 있다면 거의 확실히 띠꺼움도 함께 느껴봤을 것이다. 어떤 언어들은 굳이 타입이 뭔지 정해주지 않더라도 알아서 계산을 해주는데, 굳이 지저분하고 의미 없어 보이는 코드를 쓰는 것이 시간과 에너지의 낭비처럼 느껴지는 것이다.타입이 없던 시기의 프로그래밍 환경을 상상해보자.

컴퓨터가 이해하는 데이터는 수로 이루어져있고, 인간 입장에서 그 수만 보아서는 실제로 정수를 의미하는지 문자열을 의미하는지 등은 알 수가 없었다. 물론 짠 사람이 잘 기억하면 괜찮겠지만, 프로그램이 고도화되고 여러 사람의 손을 거치기 시작하면 뭐가 뭐였는지 헷갈려서 버그가 생길 수밖에 없다. 문자열을 제곱해도 어떤 수는 나오는데, 이렇게 무의미한 문자열이 생기는 정도는 애교다. 이런 버그는 금방 잡을 수 있다. 그런데 수백, 수천줄의 코드 사이에서 어떤 정수가 어떤 포인터와 곱해졌음에도 여전히 정수의 모양을 취하고 있다면, 도대체 이 버그를 어떻게 잡을 것인가? 프로그램은 문제 없어보이지만 그 결과는 엉망진창일 것이다.

상식적으로 당장 해봄직한 대처는 ‘주석을 꼼꼼히 써서 알아보기 편하게 하는 것’이다. 가령 A 는 정수다, B 는 문자열이다 하는 식으로 꼼꼼하게 적어두는 것이다. 그 다음 문제는 ‘이 주석이 확실한가?‘다. 버그를 줄이고 생산성을 올리기 위해 변수 하나하나에 주석을 달아놓은 것까진 좋다. 개발 중에 변수의 용도가 바뀌면 그 주석도 잘 고치는 꼼꼼함이 있다면 다행이다. 그러나 주석 역시 사람이 다는데, 실수 때문에 주석조차 틀릴 수 있기에 마냥 믿을 수가 없다. 이럴 바에는 아예 변수가 정확히 무엇이라고 정확하게 명시할 수 있는 문법이 있는게 낫겠다.

그런데 이 발상은 어딘가 낯이 익다. 그렇다. 이것이 바로 타입 지정 이다.

이렇듯 타입은 어떤 변수가 무엇인지 나타내는 주석 정도의 의미였으나, 타입의 역할이 대두되고 이에 대한 연구가 이어졌다.

강한 타입과 약한 타입

약한 타입강한 타입 에 대비되는 용어로써, 앞에서 언급된 타입의 개념에서 크게 달라지지 않았다. 약한 타입 언어는 타입 검사에 문제가 없다면 비록 프로그래머의 의도와 다를지라도 일단 코드를 실행1 시킨다. 물론 이렇게 ‘프로그래머를 의심하지 않는 태도’는 빠른 속도를 내지만, 이로 인해 생기는 버그를 사전에 잡고 생산성을 올리기 위해 강한 타입의 개념을 고안하게 된다.

강한 타입 언어는 타입 검사에 문제가 없다면 프로그램 역시 제대로 돌아가는 것을 보장한다. 검사가 엄격해지면서 시도 때도 없이 버그가 난다고 불평해선 안 된다. 미리 파악해주지 않았다면 언젠간 더 위험하고 커다란 버그가 되어서 돌아올 것이다. 타입 검사가 엄격하다는 것은 제약인데, 프로그래밍에서 제약은 ‘제한’보다는 ‘편의’를 의미하는 경우가 많다. 타입 시스템이 강하면 ‘귀찮게 타입을 다 지정해줘야하는 것’이 아니라 ‘프로그래머의 사정에 맞춰서 세밀한 조정이 가능해지는 것’으로 받아들일 수 있다.

약한 타입에도 장단점은 있겠지만 그게 딱히 의도된 것은 아니며, 강한 타입이 왜 강한 타입인지를 설명하기 위해 원시적인 타입의 개념에 이름을 붙인 것이라고 보아도 무방하다.

정적 타입과 동적 타입

정적 언어는 컴파일 할 때 타입 검사를 실시하고, 동적 언어는 실제로 코드가 실행될 때, 즉 런타임에 타입 검사를 실시한다. 쉽게 말하자면 정적 언어는 자료형이 정해지면 변하지 않는 컴파일러 언어, 동적 타입은 자료형이 그때그때 변하는 인터프리터 언어다. 아무래도 컴파일러 언어는 사소한 걸 수정할 때마다 통째로 컴파일을 해야하기 때문에 인터프리터 언어의 생산성이 높으나, 컴파일이 무사히 끝났다면 속도 면에서 컴파일러 언어가 아주 유리하다.


  1. 자바 스크립트가 이 쪽에서 악명이 높은 것으로 알려져 있다 ↩︎

댓글