Control Flow
- Sequencing: 절차지향언어에서는 기본적으로 순차적으로 코드 실행
- Selection(alternation) : 조건문: 특정 런타임 컨디션에 의존함, 가장 자주 볼 수 있는 구조의 조건문은 if 와 case(switch) 문임
- Iteration : 반복문: 반복적으로 특정 부분의 코드가 실행됨 예로는 for/do, while, repeat문이 있음
- Procedural abstaction: control construct의 잠재적으로 복잡한 콜랙션을 단일 단위로 처리할 수 있는 방식으로 캡슐화하며 일반적으로 매개변수화의 대상이 된다. 예로는 함수, 클래스 등
- Recursion: 직접적 혹은 간접적으로 스스로에 의해 정의된 표현으로 복잡한 모델의 경우 식의 인스턴스를 부분적으로 판단하는 것과 관련된 정보를 스택위에 저장하는 것이 필요로 함
Exception handling and speculation
- Exception Handling: 예외 사항 처리
- Speculation: 원래 실행해야하는 것이 아닌데 CPU가 캐쉬 이용해서 미리 처리 → 실제 일어나야하지 않는 것을 실행 → undo, rollback
Concurrency & Nondeterminacy
- Concurreny: 병행해서 처리, 여러 개 CPU
- Paralle 병렬 처리: Single CPU 나눠서 씀
- Non determinacy: 정해지지 않음
- 실행 순서가 정확하게 정해지지 않음 → 어떤 순서로 실행되더라도 같은 값
6.1 Expression Evaluation
- Expression: 표현식
- 결과에 값이 생김 ( "abc", 32.7 (literal constant: 상수), const int a =3 (named variable: 변수 이름))
- operator or function
- Operator: 2+3, C++ → Operator + ()
- Operand: 2,3
- 대부분 절차 지향은, 함수 콜은 함수 이름 괄호, 콤마로 분리된 인자의 리스트
- 연산자를 함수로 취급할 수도 → a+b (operator + (a,b)) : syntax sugar
- 연산자 오버로딩
- +2, -1, *p, &p, a++ : unary operators
- Lisp: prefix notation
- ML-family: 괄호 사용
- R: infix - 새로운 연산자를 생성해줌
- Smalltalk 은 모든 함수들을 위해 infix notation을 사용함(both built-in and user-defined)
6.1.1 Precedence and Associativity
우선순위
- 괄호가 없을때 특정 연산자가 먼저 계산
- C 언어는 연산자가 많음 →, . 포함
- Pacal: 간단
- 산술 → 비교 → 논리 순서
결합 순서
- Associativity rules
- 표현식
- Haskell: 사용자가 정할 수 있음
- infixr 8 ^ (오 → 왼)
- 0 ~9 레벨 지정
6.1.2 Assignments
- functional 순수한 함수형 언어(연산 → 함수 → 함수 : 인자로 연결, 변수 조차 없음)의 경우 - Haskell Miranda
- 값 어디다가 저장? f(2+3, 3*7+4) → 전달하고 끝남, 다른데에 사용할거면 애초에 변수에 저장 a=2+3
- 그때 이외에 사용하지 않음
- 항상 일정한 값이 나와야 함
- ex) Hasekll, Miranda
- Imperative(계속해서 값 변경): side-effect → 전체 값 바뀜, 다음 계산에 영향을 미침 - Python, C#, Ruby
- expression: 값을 만들어냄
- statements: side effect를 위해 존재 ⇒ 3;
- 다른 결과 반환 side effect의 결과
- 대다수 섞여 있음
References and values
Value Model of variables
- 표면적으로 assignment는 직관적
- 절차지향 언어에서 semantic 안에서 미묘하게 다른 점 존재
- 공간에 값 복사
- C언어의 변수는 값을 위한 지정된 컨테이너이다(named container)
- l-value: 공간 (location)
- 모든 표현식이 가능한건 아님 2+3 =a; → error, 주소값 없음
- r-value: 변수의 값
(f(a) + 3)->b[c] = 2;
: 복잡하게 표현 가능
- 주소값 (ptr) → 구조체의 b의 변수에 c
- f(a); void func(int k){};
- C++ 에서 포인터 대신
g(a).b[c] = 2;
참조 가능
Reference model of variables
- L value, R value 사이를 명확하게 해야함
- 상황에 따라 reference, container 결정됨
- Algol 68, Clu, Lisp/Scheme, ML, Smalltalk
- 변수가 단순하게 값을 저장하는 named cotainer가 아님
- Pascal → named container, Clu → named reference
- 2라는 숫자가 어느 메모리를 차지하는데, b는 2의 주소를 담아라
c := b;
l value 따름 b가 참조하는 곳을 c도 참조하게 해줘
a := b+c;
r value 따름
- 기본적으로 모두 l value임, 상황에 따라 dereferenced(r- value를 사용해야 할 것 같은 상황에 해당 value 얻어냄) 해야함 → Implicit, automatic/ (explicit: C 언어 → * , ML → !)
b:=2
b:=4
- 값 자체를 변경할 수 있다 → linked list 라고 가정
- 같은 값을 가지고 있는 다른 오브젝트가 있을 수 있다
- b →2// c→2 라면 b→4, c→2 면 c에 영향 미치지 않음
- 같은 오브젝트를 가지고 있는지 구별 필요, (다른 오브젝트인데 우연히 같은 값인지 구별 필요)
- r-value가 예상되는 컨텍스트에서 나타나는 경우 dereferenced 작업해야 참조되는 값을 얻어야 함.
- 자바
- value model: built in types (기본형)
- reference model: user-defined, class types
- C#, Eiffel 프로그래머가 고름
- reference: class
- value: struct
Boxing
- 클래스 타입의 파라미터 인자를 기대하고 있는 메소드에 빌트인 타입을 전달할 수 없음
- ArrayList: Object 타입 요소 가지도록 함
- Wrap: built-in types→클래스
- int - Integer, float - Float 클래스로 변환
- 31 → new (Integer(31))
- int → Integer → int 필요
Orthogonality (일관성)
- 공통적인 디자인 목표는 다양한 기능들이 일관성있도록 만드는 것이 목표
- 언어의 기능이 어떠한 조합으로 만들더라도 사용할 수 있어야 함
- Algol 68: 초창기 언어 중 하나
- 다른 많은 언어 안에서 statement라고 부를 수 있는 문맥 속의 임의의 표현식
- if문이 표현식 안에서도 사용할 수 있음
- 표현식(expression), statement 차이가 없음
1. 문장을 표현식처럼 씀 (a=(b<c)? d : e); → statement
2. 블럭을 표현식에 넣음
3. 함수: 표현식
4. statement
-
a = (b<c)? d:e;
: 표현식
-
문장
→ 표현식 ↔ 문장
- C언어는 표현식, statement 구분함
- ; 붙는 순간 statement
- (명령 언어) side effect → 2+3을 해놓고 저장을 해야 의미가 있는데, 이것을 가능하게 함 → 근데 가능은 함
-
expression statement: 함수호출 → 표현식 ; → statement → 끝
- 표현식에 statement;
- 삼항 연산자 → statement와 expression 표현
- ? (selection) ,(sequencing)
- algol 60 → 할당
- C
- 같으면 true
- b를 a에 넣었다가 0이 아니면 true
- C언어의 자동 형 변환으로 인해서 문제 발생
- java, C#는 2번의 경우 에러 발생 (Boolean context에 정수 타입 들어가는 것을 문법적으로 허용하지 않음)
Lack of Orthogonality in C
- 구조체에서 변수를 선언하는 것은 가능, 함수 선언은 불가능
- 구조체에 정수를 넣은건 되는데 정수자체는 안됨 등등
- 자바는 Object 는 저장 가능하나 class는 불가
- 대부분의 언어는 정수, 소수의 간단한 타입들만 배열의 인덱스 표시 허용
- 대부분 언어들은 switch, case문의 경우 정수와 같이 간단한 타입만 가능
- 어떠한 변수든 간에 assignment (=)의 왼쪽에 어떠한 변수가 와도 됨
Combination Assignment Operator
- 자신에 자신을 넣음
- +=, -=, *=
- a = a+1 한다면 찾고 또 찾아야 함 (redundant address calculation)
- 서로 다른 a에 할당될 수도 (side effect 문제)
- 다른 결과 값을 출력할 수 있음
- i =4 전달 // A[9] = A[8] +1 (side effect로 인해) → 복합 대입 연산자 사용
- 실행 속도 자체도 빠름, 같은 어드레스 주소 보장, side effect 문제 피함
A[--i] = b;
*p++ = *q++;
Multiway Assignment ( Clu, ML, Perl, Python, Ruby)
- orthogonality 하지 않은 것을 제거 해줌
- 함수 인자는 여러 개 → 반환 값은 하나 (C++, java 등등)
6.1.3 Initialization
- Imperative 언어에서 변수를 선언하면서 초기화를 항상 하는 것은 아님
- 함수 내부의 static의 경우 초기값이 있는 것이 필요 → a에 대한 값이 계속 유지됨 → y선언시 전역 메모리에 우선 할당될 수 있어서 초기 값을 할당하는 비용을 줄일 수 있음
- 초기화를 하지 않은 상태에서 변수를 사용하면 에러 발생 커짐
대부분 언어는 초기값을 지정하는 방법 제공함 (built-in type)
- 완성적이고, 일관적인(orthogonal) 접근 방법은?
- aggregate(구조체, 배열)에도 해당
- 초기화는 전역, static(정적) 변수에만 (컴파일시) 초기화되어야 한다.
- stack, heap 의 경우는 그럴 필요 없음
초기화하지 않았을 때 문제점
- 포인터에 의해서 레퍼런스되는 것을 deallocation
- newp : 허상 포인터 (dangling pointer)
- variant record 수정 (c - union)
- 가장 큰 변수의 공간만 만들어두고 하나만 쓰도록 함
- type: tag
- 4바이트만 쓰다가 (초기화되지 않은)8바이트 다쓰게 됨
- 사용자가 임의적으로 초기화하지 않으면 default value 지정하기도 함
- C: (statically allocated) 전역 변수, static(data 영역) 0으로 지정 or 0에 준한
- 자바, C#(statically allocated): 클래스 안의 멤버 변수에 대해서 0에 준하는 값
- 대부분 스크립트: 초기화
Dynamic Checks
- 디폴트 값으로 초기화 값을 지정해주는 대신에 초기화되지 않은 값을 사용하면 semantic error 발생하기도
- 장점: 런타임에서 catch 가능
- IEEE 기반의 컴파일러에서 부동 소수점 계산시 초기화가 되어 있지 않을 경우 NaN(Not a Number) value임을 알려줌
- NaN value 사용 시 하드웨어에서 이를 감지하고 semantic error message 발생
- 단점: 시간도 많이 걸림. 단 하드웨어 지원이 적절치 않은 경우, 비용이 증가하고 오버헤드가 발생할 수 있음, 런타임에서 손해
- 대부분 모든 초기화되지 않은 변수를 찾아내는 것이 손해 → 초기화 시키는 것이 좋음
Definite Assignment
- 함수의 지역 변수들을 위해 definite assignment 사용
- 초기화되지 않은 값을 사용하는 것에 대해 보완
- conservative rule(보수적인 룰) 동작
- 모든 변수에 값을 미리 할당
- java의 경우 지역 변수는 초기화 시키지 않았음 (클래스 멤버 아님)
- 초기화 안됐을 수도 있다고 에러
- j 가 0보다 작을 수도 있는 경우 있음
Constructors
- 동적으로 할당되는 변수들을 초기화해줌
- C++: 초기화(생성자 호출), assignment 구별
- initial 값이 생성자의 인자로 전달
- coercion (자동 형변환) 이 부재할 경우 → assignment 연산자(함수) 가 없다 → bit-wise copy (그대로 붙임)
- 정의 추상 데이터 타입을 위해서 특히 중요함
class A {
public A(int a){
g_a = a;
}
void operator = (int a){
g_a = a;
}
private:
int g_a;
}
A a(3);
A a = 3;
A a;
a=3
- java, C# 구분하지 않음
- A a = new A(b);
- a = b;
- java(reference model: assignment 할 때 값을 복사하는 것은 아님) → 주소 값 복사
- c++ 내용을 복사하는 경우도 있음
- A = a; A b = a; : 복사함
- A a = new A; A b=a; 주소값 복사 (java, c#)
- c#: value(struct), reference(class) 모델 선택 가능