diff --git a/2025/RobustWithTypeFlexibleWithPolymorphism/aquamagic9/Chapter1.md b/2025/RobustWithTypeFlexibleWithPolymorphism/aquamagic9/Chapter1.md new file mode 100644 index 00000000..8d128ac7 --- /dev/null +++ b/2025/RobustWithTypeFlexibleWithPolymorphism/aquamagic9/Chapter1.md @@ -0,0 +1,98 @@ +### 1.1 타입 검사의 정의와 필요성 +버그가 있다면 고쳐야한다. 버그 수정도 중요하지만 버그를 찾는 것도 중요하다. 버그의 가장 흔한 오류는 '타입 오류'다. + +타입이란? 타입은 프로그램에 존재하는 값(1, true, "abc")들을 그 능력에 따라 분류한 것이다. 각 타입들의 능력은 서로 다르다. + +어떤 타입의 값을 해당 타입이 갖고 있지 않는 능력이 필요한 자리에 사용하면 버그가 발생한다. 버그를 가장 잘 찾는 방법은 프로그램을 실행해보는 것이지만 실행을 통해 모든 상황을 시험해보기는 힘들다. + +그래서 사람들은 프로그램의 코드를 입력 받아 그 프로그램이 타입 오류를 일으키는지 자동으로 판단해주는 프로그램인 타입 검사기를 사용한다. + +이상적인 완벽한 타입 검사기는 존재하지 않는다. 이는 논리적으로 튜링이 증명한 사실이다. 타입 오류가 없음에도 거부 및 오류 메시지를 출력하는 경우가 있다. + +하지만 타입 검사기가 '통과'라고 한다면 타입오류가 없다고 여전히 확신 가능하다. 이를 타입 안전성(type safety)이라고 부른다. + +타입 검사기가 '거부'라고 한 경우는 정말 타입 오류가 발생한 경우와 사실 타입 오류가 없는데도 '거부'라고 한 경우가 있다. + +타입 검사는 작성한 프로그램에서 버그를 자동으로 찾아준다는 가치를 지닌다. +### 1.2 정적 타입 언어 +사실 타입 안전성을 갖춘 타입 검사기를 만드는 것은 어렵고 시간도 오래 걸린다. 타입 검사기를 만들 시간에 버그를 직접 찾는게 더 빠른 경우도 있다. + +타입 검사기 제작은 언어를 만든 사람들의 몫이다. 언어 제작자가 언어를 설계할 때 타입 검사기도 같이 만든다. 이 타입 검사기를 개발자가 사용할 수 있도록 제공한다. + +**정적 타입 언어**는('정적'이란 말은 '프로그램 실행 전에'라는 뜻) 프로그램 실행 전에 타입이 올바르게 사용되었는지를 확인하는 언어이다. 예시로 자바, C, C++, C#, 타입스크립트, GO, 코틀린, 러스트, 스칼라, 하스켈, 오캐멀 등이 있다. + +**동적 타입 언어**는 타입이 잘못되었다고 해도 프로그램 실행 중에 알 수 있는 언어이다. 예시로 자바스크립트, 파이썬, 루비, 리스트 등이 있다. +### 1.3 타입 검사의 원리 +타입 검사기가 프로그램을 검사하는 방식은 현실에서 물건을 검사하는 것과 똑같다. + +자동차를 예로 들면 휠, 타이어 같은 '기본'부품들을 검사하며 휠과 타이어의 반지름 길이 정보 확보 후 합쳐 타이어를 만들고 타이어와 같은 '복합'부품을 다시 검사하여 작은 부품들이 올바르게 사용되었는지 확인하고 정보 확보하는 방식이다. 이를 반복해 자동차 전체에 이르게 된다. + +타임 검사도 위와 마찬가지로 작은 것에서 큰 것으로 프로그램을 검사한다. + +예시로 printInt(5 + 7) 의 경우를 살펴보면 +1. 기본 부품 검사 + + 부품의 타입을 알아낸다. 5, 7 라는 부품의 타입은 정수 + + printInt의 경우 정수를 인자로 받는 함수. +2. 복합 부품 검사 + + 복합 부품을 구성하는 작은 부품들의 타입이 올바른지 확인한다. -> 5, 7 모두 정수 타입이므로 덧셈이 가능하다. + + 복합 부품의 타입을 확인한다. -> 5 + 7 의 결과는 정수. +3. 2번째를 반복한다. + + printInt(5 + 7) 은 printInt 와 5+7 로 이루어진 복합부품. 두 부품을 함수 호출의 형태로 결합할 때는 함수 부품이 인자에 요구하는 타입과 인자 부품의 타입이 같아야 한다. printInt는 정수를 요구하고, 5+7의 타입은 정수이므로 아무 문제 없다. + 4. printInt(5 + 7) 라는 전체 프로그램에 도달했다. 부품이 모두 올바르게 사용되었으니 프로그램이 검사를 통과한다. + +만약 정수 7이 아닌 문자열인 "7"이 사용되었다면 프로그램 검사를 통과하지 못하고 무엇이 문제인지 알려준다. 예를 들면 정수가 필요한 곳에 문자열인 "7"이 사용되었다고 이야기 한다. + +타입 검사기는 언제나 각 부품의 타입만 신경 쓴다. + +동적 타입 언어의 경우에는 타입 검사기가 없기 때문에 오류가 정확히 원인이 무엇 인지를 파악하려면 조금 더 시간이 걸릴 수도 있다. +### 1.4 타입 검사 결과의 활용 +타입 검사 결과를 바탕으로 얻을 수 있는 두 가지 이점. +1. 코드 편집기의 기능을 보조하여 개발자의 생산성을 높인다. + + 정적 타입 언어를 사용시 자동 완성 기능이 더 정확하게 추측한다. 이름 바꾸기를 할 때도 마찬가지. +2. 뛰어난 성능. 프로그램 실행 시간이 짧다. + + 타입 검사를 통해 얻은 정보를 바탕으로 실행 중에 할 일을 줄일 수 있다. 타입검사를 통과하면 실행 중에는 타입 안전성을 보장하기 때문에 실행 중 추가적인 검사가 필요 없다. +### 1.5 타입 추론 +정적 타입 언어에는 불편한 점도 있다. 그 중 하나가 타입 표시다. 타입 검사기가 변수나 함수의 타입을 알 수 있도록 개발자가 타입 표시를 제공해야 한다. 타입 추론은 타입 검사기가 더 똑똑해져서 타입 표시 없이도 타입 검사를 할 수 있게 되는 것이다. + +타입 표시는 코드에 더 많은 정보를 담음으로써 코드 가독성을 높이기도 한다. '절대로 낡지 않는 주석'이기도 하다. +### 1.6 더 세밀한 타입 +어떤 언어에서는 타입 오류라 볼 수 없었던 버그가 다른 언어에서는 타입 오류가 되기도 한다. + +예를 들면 +```java +String s = null; +s.contains("a"); +// 타입 검사를 통과하지만 오류 발생 -> Exception in thread "main" java.lang.NullPointerExeption +``` + +이 경우 타입 오류라 볼 수 없지만 코틀린에서 위와 같은 코드를 작성한 경우에 타입 오류가 발생한다. 이유는 코틀린에서는 정말 데이터가 있는 문자열만 String 타입에 속하기 때문이다. Java에서는 null도 문자열에 속한다. + +버그를 잡기 위해서는 무조건 값을 세밀하게 분류하는게 좋지 않을까 싶지만 그렇지 않다. 세밀하게 분류 할 수록 버그를 더 많이 잡을 수는 있지만 개발자가 사용하기에는 까다로워진다는 단점이 존재한다. 그래서 코틀린의 경우 null을 사용하는데 불편함이 있기도 하다. + +C컴파일러인 컴서트(CompCert), 운영체제인 서티코스(CertiKos)의 경우 값을 아주 세밀하게 분류하여 버그가 없다는 게 보장된 프로그램이다. +### 1.7 정적 타입 언어의 장단점 +정적 타입 언어의 장단점 +-장점 ++ 프로그램의 모든 타입 오류를 찾을 수 있다. ++ 코드 편집기가 타입 검사 결과 활용 가능 ++ 타입 표시를 통한 가독성 확보 +-단점 ++ 타입 표시 때문에 코드가 장황 해지는 경우 발생 ++ 타입 오류를 일으키지 않는 프로그램인데 타입 검사기가 '거부'라고 틀리게 말하는 경우 존재 + +정적 타입 언어의 장점들은 모두 큰 프로그램에서 뚜렷하게 드러난다. 프로그램이 크면 버그가 많아 오류 찾기가 어렵다. 만드는데도 오래 걸려 긴 코드 이해도 어렵다. 타입 오류를 모두 자동으로 찾고 코드 편집기의 능력을 최대로 끌어내고 코드의 가독성이 우월한 정적 타입 언어가 최적이다. + +반대로 동적 타입 언어가 유리한 때는 작은 프로그램을 만들 때이다. 작은 프로그램을 만들 때는 정적 타입 언어의 장점이 퇴색되며 오히려 단점이 되기도 한다. + +예시로 트위터의 경우 초반 서버 개발에 루비를 사용했지만 서비스가 커지고 난 후에는 정적 타입 언어인 스칼라로 옮겨갔다. 그 결과 코드의 가독성과 개발 과정의 생산성이 높아졌으며 버그를 좀 더 쉽게 고쳤다. +### 1.8 다형성 +정적 타입 언어에서 치명적인 단점은 타입 검사기가 '거부'라고 틀리게 말하는 단점이다. 이 단점은 절대로 완벽하게 해결할 수 없다. 하지만 줄일 수는 있다. + +다형성은 타입 검사기의 오판을 줄이는 안전한 기능의 대부분을 차지하는 개념이다. 다형성은 프로그램의 한 개체가 여러 타입에 속하게 만든다. 이는 타입 안전성을 해치지 않으면서도 타입 검사기의 오판을 줄이며 동시에 개발자가 이해할 수 있도록 오류 메시지를 제공한다. + +다형성의 종류 ++ 서브 타입에 의한 다형성 ++ 매개변수에 의한 다형성 ++ 오버로딩에 의한 다형성 +### 논의 내용 +1. 책에서는 트위터의 예시로 동적 타입 언어인 루비를 사용하였다가 서비스가 커지고 난 후에는 정적 타입 언어인 스칼라로 옮겼다고 했는데 이렇게 개발 언어 자체를 바꾸는 경험을 하신 경우가 있으신지 궁금하고 어떤 이유로 바꾸었는지도 궁금합니다. 또한 바꿀 때 가장 주의해야 할 사항은 어떤 게 있을지 궁금합니다. \ No newline at end of file