본문 바로가기
PL

[PL] CH9. Subprograms (Module) (3)

by 녕인뉸 2022. 5. 19.

1. Type-checking parameters

(1) 소프트웨어의 reliability는 actual paramter의 타입이 상응하는 formal parameter와 일관성을 유지하는지 확인하는 것을 요구

- FORTRAN : 파라미터 타입 체킹 없음

- pascal, Modula-2, FORTRAN 90 : 파라미터 타입 체킹

- Original C : 파라미터의 개수, 타입 체킹 둘다 없음

- ANSI C : 함수의 formal parameter는 2가지 방식으로 선언됨

 -> original C와 같은 방식 : no type checking

-> prototype method : type checking, coercion

coercion : type을 일치시킴, syntax error가 표시됨

 

- C++ : formal parameter list는 지정된 파라미터와 줄임표를 모두 가짐

printf(const char* c, ...) { ... }

const를 사용하였으므로 c는 inmode로 읽기만 할 수 있고 body에서 변경될 수 없음

따라서 body에서 c = 0;의 코드를 넣으면 컴파일 에러가 듬

 

- 상대적으로 새로운 언어인 Perl, JavaScript, PHP는 타입 체킹을 요구하지 않음

파이썬과 루비에선, 변수는 타입을 가지지 않으므로 (object는 가짐), 파라미터 타입 체킹이 불가능

 

 

2. Implementing Parameter-Passing method

(1) Parameter-passing의 주된 구현 모델은 실제로 어떻게 구현이 될까?

 - ALGOL 60 등은 파라미터 통신은 런타임 스택을 통해 발생함

  -> Pass-by-value : 파라미터는 스택 영역에 복사된 값을 가짐

  -> Pass-by-Result : actual parameter에 할당된 값은 스택에 위치하며, 호출된 서브프로그램이 종료될 때 호출하는 프로그램에서 찾을 수 있음

  -> Pass-by-Value-Result : pass-by-value와 -result의 혼합

  -> Pass-by-Reference : actual parameter의 타입과 상관없이, 오직 주소가 스택에 위치함

                               : 경우에 따라, 컴파일러는 표현식을 평가하기 위해, 제어권이 호출된 서브프로그램으로 전달되기 직전에 코드를 생성

표현식의 결과가 위치한 주소는 스택에 위치함

ex. call sub(a*b)

 

  -> Pass-by-name : 파라미터는 파라미터가 없는 procedure나 런타임이 상주하는 세그먼트(thunks)로 구현됨

                         : thunks -> 호출된 서브프로그램에서 pass-by-name 파라미터로 모든 reference에 대해 호출됨

                         : thunk는 전달된 서브프로그램이 선언된 서브프로그램의 적절한 referencing 환경에서 reference를 평가하며, actual parameter의 주소를 반환함

 

 

activation record: 스택에 저장되는 데이터

스택에 저장 : 지역 변수처럼 함수가 호출이 되어야 영역이 할당되며 함수 종료시 영역이 할당 해제됨

메인 함수가 호출될 경우 메인 activation record가 활성화됨

 

-> return value

-> value parameter

-> return address

-> local variables

이 스택 (activation record)안에 저장됨

 

 

 

3. Overloaded Subprograms

(1) 같은 referencing 환경에서 이름은 같지만 다른 서브프로그램

(2) overloaded procedure의 모든 구현은 파라미터의 타입과 반환 값에서 고유해야함

(3) overload된 서브프로그램에 대한 호출의 의미는 actual parameter list에 의해 결정됨

- Ada ; 함수와 procedure 둘다 overload될 수 있음

procedure MAIN is
        type F_VECTOR is array (INTEGER range <>) of FLOAT;
        type I_VECTOR is array (INTEGER range <>) of INTEGER;
        ....
        procedure SORT(FLOAT_LIST : in out F_VECTOR ; //F_VECTOR는 body에서 변경o
        LOWER_BOUND : in INTEGER ;
        UPPER_BOUND : in INTEGER ) is //in 이므로 body에서 변경 x
        …
        end SORT ;
        procedure SORT(INT_LIST : in out I_VECTOR ;  //I_VECTOR는 body에서 변경 o
        LOWER_BOUND : in INTEGER ;
        UPPER_BOUND : in INTEGER ) is 
        …
        end SORT ;
        .....
    end MAIN ;

 

sort는 procedure와 함수에 대해 overloaded

 

 

- C

 

main() {
	sub(3);
    ...
}
sub(int i) { ... }
sub(float j) { ... }

이름으로 구별

 

- C++ ; 파라미터 리스트 타입과 이름으로 구별

각 버전의 파라미터의 타입의 수가 고유한 한 함수는 overloaded

void fun(float b = 0.0) {  // b는 default parameter
…
}
void fun() {
…
}

main() {
…
fun() ; /* ?? */
… 
}

 

- Ada, 자바, C++, C#은 유저가 같은 이름의 서브프로그램의 여러 버전을 사용하는 것을 허용함

 

 

 

4. Generic Subprgrams ; 여러가지 타입의 actual parameter를 전달 받아 실행할 수 있음, parameter passing에 의해 type이 결정됨, dynamic type binding

(1) Ada

- 파라미터가 다른 값과 다른 타입을 가지는 서브프로그램의 구성을 제공

- 서브프로그램의 다른 버전은 유저 프로그램이 요청될 때, 컴파일러에 의해 생성됨

  -> generic unit은 procedure에 대한 절차에 불과함 ; 코드는 컴파일러에 의해 생성되지 않으며, 일부 유형에 대해 instance화 되지 않는 한, 프로그램에 영향을 미치지 않음

  -> 컴파일러는 정수형 타입 변수를 sort하는 INTEGER_SORT라고 불리는 GENERIC_SORT의 버전을 생성

 

 

5. Design Issues for Functions

(1) 함수에 대한 2가지 문제

 - side effect가 허용?

 

int j;
sub() {
 j++;
}

에서 j의 값이 변하는지

 

- 값의 어떤 타입이 반환됨?

 

(2) Functional side effects

 - Ada : 표현식에서 호출된 함수의 side effect의 문제 때문에, 함수에 대한 파라미터는 항상 inmode여야함

   -> 효과적으로 파라미터를 통해 함수가 side effect가 발생하는 것을 예방

 - 파스칼, C : 함수는 pass-by-value와 pass-by-reference 파라미터를 가짐 -> 함수가 side effect를 가지는 것을 허용

 

(3) Type of Returned Values

- 대부분의 언어들은 함수에 의해 반환되는 유형을 제한함

- FORTRAN 77 : 함수는 unstructured type을 반환

- 파스칼, Modular-2 : 오직 단순한 타입만 함수에 의해 반환 -> int, real, char, Boolean, pointers, enumetion types

- C : 배열과 함수를 제외하고 함수에 의해 어느 타입이나 반환될 수 있음

- 자바, C# : 아무 타입을 반환

 

 

 

5. Accessing Nonlocal Environments

(1) 서브 프로그램 사이의 많은 통신이 파라미터를 통해 이뤄지더라도, 대부분의 언어들은 외부 환경으로 부터 변수에 접근하는 방식을 제공

(2) 서브 프로그램의 nonlocal 변수: 서브 프로그램에서 visible하지만 locally하게 서언되지 않음

(3) Static scoping languages : nonlocal에 대한 많은 접근이 제공

(4) Dynamic scoping languages : 서브 프로그램의 모든 로컬 변수는 텍스트 근접성에 상관 없이 실행중인 어느 서브 프로그램에서 visible

 : an inability to statically type check references to nonlocals

(5) FORTRAN commons Blocks

 - COMMON을 통해 glocal storage의 블럭에 접근

   -> common block은 블럭의 이름을 언급하는 첫번째 COMMON이 컴파일러에 의해 발견될 때 생성됨

   -> 문제점: 2개의 서브프로그램은 다른 이름을 가진 같은 데이터 블럭을 포함할 수 있음 -> storage sharing

 

(6) External Declarations and modules

 - Modula-2, Ada

  : access가 필요한 외부의 모듈을 지정하는 unit을 허용함으로써 data sharing의 방식을 제공

     -> 모든 모듈은 더도 말고 덜도 말고("with") 액세스가 필요한 다른 모듈을 정확히 지정

 

- C언어 (no nesting of procedures)

  : 글로벌 변수는 함수의 정의 외부에 함수 선언을 배치함으로써 생성

  : access는 extern 문을 사용하여 외부에 변수를 선언하는 함수의 변수에 제공됨

 

 

 

 

6. User-Defined Overloaded Operators ; 프로그래머가 언어에 정의된 operator를 함수의 이름으로 사용

(1) 파라미터의 유형이나 수가 다르거나 리턴 타입이 다른 경우, Operator는 Ada와 C++ 프로그램에서 유저에 의해 overload 될 수 있음

 

 

(2) Closure : 서브 프로그램이자 정의된 referencing 환경

 

- 자바스크립트 : closure는 makeAdder에 의해 반환된 익명 함수

var add10, add5는 함수

 

비슷한 일을 하는 함수를 여러 개 선언하지 않고 함수 하나를 선언하고 다른 부분만 parameter로 넘겨주어서 새로운 함수 (Closure)를 만들어서 사용한다.

(Macro 혹은 C++ Template 비교하여 장점은 ??)

 

 

7. Coroutines

(1) 여러개의 entry를 가지며 스스로 제어함 (Lua에서 지원)

(2) symmetric control이라고도 불림: 호출자와 호출된 coroutines은 더 동등

(3) 코루틴 호출: resume

(4) 코루틴의 첫 번째 resume은 시작 부분에 있지만 이후 호출은 코루틴에서 마지막으로 실행된 명령문 바로 다음 지점에서 시작

(5) 코루틴은 반복적으로 서로 resume

(6) 코루틴은 프로그램 단위의 quasi(표현상) concurrent 수행을 제공 ; 이 수행은 interleave 될 수 있지만 겹치지는 않음

 

'PL' 카테고리의 다른 글

[PL] CH10. Implementing Subprograms (2)  (0) 2022.05.26
[PL] CH10. Implementing Subprograms  (0) 2022.05.24
[PL] CH9. Subprograms (Module) (2)  (0) 2022.05.17
[PL] CH9. Subprograms (Module)  (0) 2022.05.10
[PL] CH8. Statement-Level Control Structures (2)  (0) 2022.05.10