이 책은 프로그램이 언어가 가지고 있는 다양한 개념이 왜 존재하고 있는지 설명한다.세상에는 많은 프로그래밍 언어가 있으며 관련된 개념도 함수, 형, 스코프, 클래스, 상속 등그 수를 헤어릴 수 없을 정도로 다양하다.많은 프로그래밍 언어에서 공통적으로 사용하는 개념도 있지만 일부 언어만 채용하고 있는개념도 많다. 이런 개념들은 왜 탄생한 것인지 그 이유를 알아내는 서적이다.이를 위해 이 책은 언어 설계자의 관점에서 여러 언어를 비교하고 언어가 어떻게 변화되어 왔는지를설명한다.
프로그래밍 언어 안내서. 수많은 프로그래밍 언어를 효율적으로 학습할 수 있도록 돕는다. 언어 설계자의 관점에서 여러 언어를 비교하고 언어가 어떻게 변화되어 왔는지를 설명하며, 프로그래밍 언어가 가지고 있는 다양한 개념이 ‘왜’ 존재하고 있는지를 알려준다. 이처럼 다양한 개념이 ‘왜’ 탄생했는지를 이해하게 되면 각 언어를 왜, 언제, 어떻게 사용해야 할지를 판단할 수 있게 된다. 또한 이후에 생겨날 새로운 개념도 쉽게 이해할 수 있는 밑거름이 될 것이다.
1장 효율적으로 언어 배우기
1.1 비교를 통한 배움
- 규칙은 언어마다 다르다
- C 언어와 Ruby의 참거짓 값
- Java의 참거짓 값
1.2 역사를 통한 배움
- 언어 설계자의 의도를 이해하자
- 어떤 언어를 배워야 하는지는 아무도 모른다
- 언어에 의존하지 않는 보편적인 지식의 습득
2장 프로그래밍 언어를 조감하다
2.1 프로그래밍 언어 탄생의 역사
- 케이블을 연결하다
- 프로그램 내장 방식으로
- FORTRAN의 등장
2.2 프로그래밍 언어 탄생의 목적
- 나태 ? 프로그래머의 삼대 미덕
- 언어에 따라 다른 ‘편리함’의 의미
3장 문법의 탄생
3.1 문법이란?
- 연산자 우선순위
- 문법은 언어 설계자가 정한 규칙
3.2 스택 머신과 FORTH
- 계산 순서
- 연산 순서를 어떻게 표현할까?
- 현재도 살아있는 스택 머신
3.3 구문 트리와 LISP
- 계산의 흐름
- 계산 순서를 어떻게 표현할까?
- 현재도 살아있는 구문 트리
칼럼: 이해력을 확인하기 위해서는 결과물(Output)을 확인한다
3.4 중위 표기법
- 구문 해석기
칼럼: 무엇을 배우면 좋을지 모르는 이유
- 규칙간 마찰
4장 처리 흐름 제어
4.1 구조화 프로그래밍의 탄생
4.2 if가 탄생하기 전
- if는 왜 있는 걸까?
- If-else는 왜 있는 걸까?
4.3 while, 반복되는 if를 읽기 쉽게 표현
- while 문을 사용하는 방법
- while 문을 사용하지 않는 방법
4.4 for, 수치를 증가시키는 while을 읽기 쉽게 표현
- for를 사용하는 방법
- for를 사용하지 않는 방법
- foreach, 처리 대상으로 반복 제어
5장 함수
5.1 함수의 역할
- 이해(조직을 예로)
- 재사용(부품을 예로)
- 프로그램 재사용의 특징
5.2 돌아가는 명령
- 함수의 탄생
- 돌아갈 목적지를 기록하기 위한 전용 메모리
칼럼: 이름
- 스택
5.3 재귀 호출
- 내포 구조 데이터의 효율적 처리
- 내포 구조를 다루는 방법
6장 에러 처리
6.1 프로그램도 실패를 한다
6.2 실패를 어떻게 전달할까?
- 반환값으로 실패를 전달한다
- 실패하면 점프한다
6.3 실패할 것 같은 처리를 묶는 구문
- John Good enough의 주장
- CLU에 도입
- C++에 도입
- Windows NT 3.1에 도입
6.4 출구는 하나다
- 왜 finally를 도입한 것일까?
- 짝이 되는 처리를 반드시 실행한다
6.5 어떤 경우에 예외를 던질까?
- 함수 호출 시 인수가 부족한 경우
- 배열 범위 밖에 있는 것을 취득하려고 했을 때
- 틀리면 바로 예외를 던진다
6.6 예외의 전파
- 예외 전파의 문제점
- Java의 검사 예외
- 검사 예외가 잘 사용되지 않는 이유
컬럼: 구체적인 지식과 추상적인 지식
칼럼: 이빨로 씹다
칼럼: 필요한 부분부터 흡수한다
7장 이름과 스코프
7.1 왜 이름이 필요할까?
- 어떻게 이름을 붙일까?
- 이름 충돌
- 충돌 피하기
7.2 스코프의 진화
- 동적 스코프
- 정적 스코프
7.3 정적 스코프는 완성체인가?
칼럼: 다른 언어의 스코프
- 내포 함수의 문제점
- 외부 스코프에 재귀속되는 문제
8장 형
8.1 형(型)이란?
8.2 수치를 On과 Off로 표현하는 방법
- 자릿수 발명
- 7 세그먼트 디스플레이
- 주판
8.3 한 자리에 필요한 램프는 몇 개일까?
- 10 진수에서 2 진수로
- 8 진수와 16 진수
8.4 실수는 어떻게 표현할까?
- 고정 소수점 ? 소수점을 어디에 붙일지 정한다
- 부동 소수점 ? 어디부터 소수부인지의 정보 자체를 값에 포함시킨다
8.5 형은 무엇을 위해 존재할까?
- 형이 없을 때 발생하는 문제
- 초기 FORTRAN의 형
- 언어 처리계에 변수 종류를 알린다
- 암묵의 형 승격
8.6 형의 다양한 전개
- 사용자 정의형과 객체 지향
- 사양으로서 형
- 총칭형, 제네릭스, 템플릿
- 동적 형결정
- 형 추론
칼럼: 대략적인 부분을 잡아서 조금씩 상세화한다
9장 컨테이너와 문자열
9.1 다양한 종류의 컨테이너
9.2 왜 다양한 컨테이너가 존재할까?
- 배열과 연결 리스트
- 연결 리스트의 장단점
칼럼: O 기법 ? 계산 시간과 데이터량의 관계를 간단히 나타내는 것
- 언어에 따른 차이
9.3 사전, 해쉬, 연상 배열
- 해쉬 테이블
- 트리
- 요소를 꺼내는 시간
- 만능 컨테이너란 없다
9.4 문자란?
- 문자 집합과 문자 부호화 방식
- 컴퓨터 이전 시대의 부호화
- EDSAC 문자 코드
- ASCII와 EBCDIC 시대
- Unicode에 의한 통일
9.5 문자열이란?
- 길이 정보를 가지고 있는 Pascal 문자열, 가지고 있지 않은 C 문자열
- 한 문자가 16 비트인 Java 문자열
- Python 3에서 이루어진 설계 변경
- Ruby 1.9의 도전
10장 병행 처리
10.1 병행 처리란?
10.2 잘게 분할해서 실행한다
10.3 처리를 변경하는 2가지 방법
- 협력적 멀티태스크
- 선점적 멀티태스크 ? 일정 시간에 교대한다
10.4 경합 상태 방지법
- 경합 상태의 3가지 조건
- 공유하지 않는다 ? 프로세스와 액터 모델
- 변경하지 않는다 ? const, val, Immutable
- 끼어들지 않는다
10.5 락의 문제점과 해결책
- 락의 문제점
- 트랜잭션 메모리
- 트랜잭션 메모리의 역사
트랜잭션 메모리는 성공할까?
11장 객체와 클래스
11.1 객체 지향이란?
- 객체는 현실 세계의 모형
- 클래스란?
11.2 변수와 함수를 합쳐서 모형을 만드는 법
11.3 방법 1: 모듈, 패키지
- 모듈, 패키지란 무엇인가?
- Perl 패키지로 객체를 만든다
- 모듈만으로는 부족하다
- 별도의 데이터 저장소를 만든다
- 인수로 개별 해쉬를 전달한다
- 초기화 처리도 패키지에 넣는다
- 해쉬와 패키지를 연결한다
11.4 방법 2: 함수도 해쉬에 넣는다
- 퍼스트 클래스
- 함수를 해쉬에 넣는다
- 복수 개 카운터를 만든다
- 공유하고 있는 사물을 프로토타입으로 이동한다
- 이것이 객체 지향?
11.5 방법 3: 클로저
- 클로저란?
- 왜 클로저라고 부를까?
11.6 방법 4: 클래스
- Hoare가 생각한 클래스
- C++ 클래스
- 사양으로서 역할
- 클래스의 3가지 역할
12장 상속을 통한 재사용
12.1 상속이란?
- 상속에 관한 다양한 접근법
- 상속은 양날의 칼
- 리스코프의 치환 원칙
12.2 다중 상속
- 하나의 사물을 복수로 분류
- 코드 재사용에 편리한 다중 상속
12.3 다중 상속의 문제점 ? 거듭되는 충돌
- 해결책 1: 다중 상속을 금지한다
- 해결책 2: 메소드 해결 순서를 고민한다
- 해결책 3: 처리를 섞는다
- 해결책 4: 트레이트
칼럼: 끝에서부터 차례대로 베껴간다