-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
타입으로 견고하게 다형성으로 유연하게 1주차 - 조현우 #447
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -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. 책에서는 트위터의 예시로 동적 타입 언어인 루비를 사용하였다가 서비스가 커지고 난 후에는 정적 타입 언어인 스칼라로 옮겼다고 했는데 이렇게 개발 언어 자체를 바꾸는 경험을 하신 경우가 있으신지 궁금하고 어떤 이유로 바꾸었는지도 궁금합니다. 또한 바꿀 때 가장 주의해야 할 사항은 어떤 게 있을지 궁금합니다. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 저는 그런 경험은 없지만 아마 태형님이 회사에서 이런 과정을 거치고 있는 걸로 알고 있습니다. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
파이썬2버젼 장고로 작성된 레거시 시스템을 자바 스프링으로 다시 만드는 작업을 하고 있습니다. 다만, 자바로 바꾼 이유는 자바가 위의 문제점들을 다 커버하기 때문이 아니라(저는 자바를 싫어합니다 ㅎㅎ), 회사의 채용 상황, 팀의 개발자 구성원을 고려 했을 때, 파이썬 3버젼을 올리는 선택보다 자바를 선택하는게 더 이득이라는 생각 때문 이였습니다
주의 해야할 것 이라고 적어주신게 조금 모호해서, 만약 동적 타이핑 언어를 사용하다가, 정적 타이핑 언어로 변경한다고 했을 때, 주의해야하거나 고려해야할 점에 대해서 회사 입장에서 답변 하자면, 회사에서 쓰는 정적 타이핑 언어를 그냥 사용하는게 제일 좋을 것 같습니다 그 이유는 무언가 특별한 서비스를 만드는게 아닌 보통의 웹 백엔드 API 서버를 만드는 것이고, 팀원들이 유지보수성에 대한 이해도가 있다면, 솔직히 그냥 타입체커가 있는 아무 언어의 아무 프레임워크를 선택해도 문제 없을거 같고, 가급적이면 회사에서 쓰는 것을 주로 쓰는게 회사 입장에서 가장 좋을 것 같습니다 요즘에 개발언어들이 동적언어는 정적언어들의 특징을 가져오고, 정적언어들은 동적언어들의 특징들을 가지고 오면서, 그 경계가 분명히 있지만, 조금씩 흐려지고 있다고 생각합니다 그래서 제 개인적으로는 회사의 입장이 아니라면, 그냥 개인이 가장 선호하고, 익숙한 언어와 프레임웍을 사용해도 왠만한 보통의 웹 백엔드 API 서버를 구축하는데 전혀 문제 없다고 생각하긴 합니다 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 오 재밌는 논의 주제인 것 같아요. 저는 하나의 프로젝트에서 개발 언어를 바꾼 경험은 없어서 저도 궁금하네요👍 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 문장을 더욱 매끄럽게 다듬어 드릴게요. "저는 한 번, 안드로이드 앱을 Flutter로 새롭게 개발하는 프로젝트를 옆에서 지켜본 적이 있습니다. 이 프로젝트의 가장 큰 목적은 iOS까지 지원 범위를 확장하기 위해서였습니다. 즉, 크로스 플랫폼 개발과 네이티브 iOS 개발 사이에서 고민하다가, 팀원들이 이미 Flutter에 익숙했기 때문에 크로스 플랫폼 방식을 선택하게 된 것입니다. 이 과정에서 가장 주의해야 할 점은 비용과 시간이었습니다. 생각보다 개발 기간이 길어지는 경우가 많았고, '이미 알고 있는 기술이니까 금방 끝나겠지' 하는 안일한 생각으로 인해 프로젝트 예측이 어려웠습니다. 특히, 기존 코드를 완전히 새로 작성하는 과정에서 예상치 못한 문제들이 발생할 수 있기 때문에 신중한 계획이 필요합니다. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
시작이 정적타입 언어여서 그런지 딱딱 타입을 적어주는 것이 좋았습니다.
오히려 적지 않으면 (동적타입언어) 불안했던 경험이 있습니다.
비슷하지 않을 수도 있지만 접근제한자 같은 경우에도 private를 꼭 붙여주는 편 입니다.