<함수 = subprograms>
1. 수학의 함수
2. pl의 procedure
이 2가지를 아우러서 subprogram이라고 한다.
process abstraction
data abstraction
activate되었다
parameter
-formal
-actual
ㅡ> 포멀과 액츄얼을 position에 의해 매칭
ㅡ> 어떤 언어에서는, 호출할 때 formal parameter의 이름도 명시 (파이썬)
(9.2.4) Procedures and Functions
procedure은 기본적으로 side effect 발생
ㅡ> 남의 변수 건드림
남의변수
ㅡ> global 전역변수
ㅡ> call by reference로 넘어온 parameter
(9.4) local Referencing Evironments
9.4부터는 함수와 관련된 여러가지 이슈들
(9.4.1) 지역변수
(C언어) 지역변수를 static으로 선언하면
Scope는 지역이지만, lifetime은 전역과 같이 프로그램 실행중에 계속 메모리 할당
(9.4.2) Nested Subprograms
'함수안의 함수'
ALGOLㅡ> nesting허용
ALGOL계열에서 nesting허용하나, C에선 빼버림
소프트웨어 공학적으론, 허용하는게 좋음
(그림)
큰 문제를 여러개의 모듈로 나누고
그 모듈도 여러개의 함수로 나눈다.
그런데 C에선 그 함수들을 같은 level에둔다.
nesting을 허용하면, 모듈안에 모듈을 nesting시켜서 계층화
ㅡ> 딴데서는 그 안의 함수들 호출못함
non-local이라든지, nested을 허용하면 좋은점이 있다
js나 파이썬 ruby등은 nested허용
(9.5) Parameter-Passing Methods
(9.5.1) Semantics Models of Parameter Passing
파라미터 패싱
call by referencing
call by value
를 배워왔지만..
3가지로 나눌 수 있다.
- In mode
- Out mode
- Inout mode
(9.5.2) Implementation Models of Parameter Passing
(그림 F9.1)
In mode : 함수호출할 때, a값을 x에다 복사
Out mode : 함수가 끝난 후, y의 값이 b로 복사
Inout mode : 1번+2번
대부분의 언어에서는, 2번을 3번의 subset으로 봐서
'call by referencing', 'call by value' 두가지만 언급한다.
일부언어에선, 이 3가지를 명시적으로 구분한다.
in x, out y, inout c 이런식의 키워드를 쓴다.
(9.5.2.1) Pass-by-Value
call by value
호출할 때 actual값을 formal에 복사해주는 형태
(9.5.2.2) Pass-by-Result
함수가 다 끝난뒤, y의 값을 actual에 복사해주는 형태
C# ㅡ> out이라는 키워드
(9.5.2.3) Pass-by-Value-Result
Inout mode
호출할 때 actual값을 formal에 복사해줬다가
함수가 다 끝난뒤, y의 값을 actual에 복사해주는 형태
(P) actual parameter가 큰 array같이 큰 data일 때 복사하는 과정에서 시간, 공간 낭비
(S) Call-by-reference : data 복사 안하고 주소를 보낸다
(9.5.2.4) Pass-by-Name
ㅡ> 사용 안되는 방법
Call-by-Reference와 유사
ref는, binding되는 시점이 호출될 때,
name은, 사용될 때 binding
(9.5.3) Implementing Parameter-Passing Methods
(그림9.1)
abcdㅡ> sub의 지역변수
Stack ㅡ> sub의 지역변수 공간
(9.5.4) Parameter-Passing Methods of Some Common Languages
C를 비롯한 대부분 언어들의 디폴트
ㅡ> call-by-value
call-by-reference
ㅡ> l-value 보냄
ㅡ> &(주소), *(indirect-addressing)
ref a
var a ㅡ> ALGOL, variable의 약자
등의 키워드 쓰는 언어도 있음
C는 &, *를 씀
(9.5.4) Type Checking Parameter
strong/weak type checking얘기 할때처럼,
actual과 formal의 type이 어긋났을 때 error를 줄것이냐의 문제
초창기 C ㅡ> coercion
요즘 ㅡ> warning, error등
typographical errors ㅡ> 타이핑 에러
(9.5.8) Example
swap
&
*
(9.6) Parameters That Are Subprograms
(그림 418pg 코드, pdf 그림)
ㅡ> ALGOL계열의 문법 (근데 begin end가 아닌 braces쓴 짬뽕)
ㅡ> function과 procedure을 명백히 구분해서 씀, 그것 자체가 키워드
sub2가 실행 됐을 때, 참조한 경우는 어떻게 봐야 하는가
sub4에서 sub2를 호출, sub4의 변수를 참조할 수 있느냐의 문제
static scope
ㅡ> 어떤 상황에서 실행됐건, sub2가 참조할 수 있는 변수는 컴파일 때 이미 결정
ㅡ> 자기변수, 부모변수, 전역변수 등
dynamic scope
ㅡ> 호출된 과정에 따라 다름
(9.7) Calling Subprograms Indirectly
sub중에 어떤게 호출될지
ㅡ> 프로그램 짤 때(컴파일타임)에 정해지지 않고,
ㅡ> 프로그램 실행 중(런타임)에 결정
subx를 써서 호출 (위에서 subx와 다름)
함수에 대한 포인터로 만들어 놓고
runtime에 subx에 sub2를 assign하면
subx를 호출하면 sub2가 호출된다.
일종의 polymorphism
protocol, prototype
ㅡ> header부분에 나와있는 것
ㅡ> formal parameter의 갯수, type, 리턴 type
ㅡ> protocol : 호출하고 결과를 리턴받는다는 맥락에서 봄
ㅡ> prototype : 함수의 interface부분만 정의가 되어있다는 맥락에서 봄
(420pg 코드예시 그림)
float (*pfun) (float, int);
ㅡ> 함수를 가리키는 pfun 함포인터
ㅡ> 아무 함수나 가리킬 수 있는게 아니라, protocol이 맞아야 함
ㅡ> formal parameter 갯수, type, 리턴 type
C#
ㅡ> delegate (대리인)
public delegate int change(int x);
(9.8) Design Issues for Functions
(9.8.1) Functional Side Effects
side effect
ㅡ> 자기변수( 역변수)이외의 변수를 고쳤다
ㅡ> 모듈간의 carpooling이 생긴다.
ㅡ> 코드가 길어지면 찾아내기 어려워진다.
남의변수
ㅡ> 전역변수
ㅡ> call by reference
(9.8.2) Types of Returned Values
리턴이 어떤 구조체라던지 하면
하나로 쓸 수가 없어서
포인터 변수를 써서 사용한다 (C에서)
(9.8.3) Number of Returened Values
함수가 2개 이상 리턴하는 언어도 있다
(9.9) Overloaded Subprograms
overloaded operator
ㅡ> 하나의 연산자 symbol이 여러가지로 쓰인다
ㅡ> *가 int 곱에도 쓰이고, float곱에도 쓰이고, c에서 indirect addressing에도 쓰이고....
Overloaded subprogram
ㅡ> constructor오버로드, catch오버로드 등
ㅡ> protocol은 달라야 한다 > polymorphism
(9.10) Generic Subprograms
예를들어 sort다,
헤더부분에 type을 선언해야 한다.
이것이 static type binding을 쓰는 언어의 한계다.
헤더부분에 parameter로 int를 위한 sort다 라고 선언하면
호출할 때 int만 보낼 수 있다
로직은 같은데, type이 다를 경우에
여러개 만들어야되는데
오버로딩 말고
다르게 처리하는 방법이 generic을 만드는 것
오버로딩 (ad hoc)
ㅡ> 여러개 만들어 놨지만, 사용자 입장에선 polymorphism
ad hoc solution
ㅡ> 특이, 특별한 해결책
<ㅡ> general solution (일반해)
Java에서 polymorphism
ㅡ> 부모의 포인터(큰 타입)로 자식(작은 타입)의 instance 가리킬 수 있다
formal parameter의 type을 부모type으로 해놓으면 자식의 instance를 받을 수 있다
■ Parametric polymorphism
(그림)
type을 비워놓고 만든다
type은 instance만드는 사람이 정해서 쓴다
ㅡ> generic인 이유는 일반해를 생각해보면 될 듯
C++
ㅡ> Template
ㅡ> Template은 키워드이다.
Jave
ㅡ> generic
ㅡ> generic이란 키워드를 쓰진 않는다.
ㅡ> 그냥 이렇게 만들어진 클래스를 generic이라 부른다.
(9.10.2) Generic Methods in Jave 5.0
'<>'
ㅡ> pointer blacket
ㅡ> c++나 java나 template, generic할 때는 이 기호를 쓴다
427pg 맨아래 코드 예시
Collection
ㅡ> Jave에서 모든 자료구조를 가지고 있는 클래스의 상위
ㅡ> array, linked-list, queue, stack 등
ㅡ> primitive type은 그냥 변수로 사용하지만, 그 외 data type은 class로 존재
ㅡ> 보통 class가 generic으로 선언이 돼서 만들어 씀(???)
collection<?>
'wildcard types'
(9.11) User-Defined Overloaded Operators
함수 정의할 때
문자열 말고 기호써도 된다
그런걸 허용하는 언어들도 있다~
(9.13) Coroutines
하나의 세트처럼 움직이는 함수
여기선 2개가 나왔는데
A에서 돌다가 일시중단 (timeout이나 동기화 wait등)
B가 작동하다가 중단되고
A에서 중단된 위치에서 resume
resume : 재개하다
비유) 카드게임 턴이 돌아가는 것
'CS > 프로그래밍 언어론' 카테고리의 다른 글
힙 vs 스택 (0) | 2024.06.08 |
---|---|
과제 (0) | 2024.06.08 |
[양PL] 7장 Expressions and Assignment Statements (0) | 2024.05.28 |
[양PL] 6장 Data Type (0) | 2024.04.30 |
[양PL] 5장 Names, Bindings, and Scopes (0) | 2024.04.25 |