First-Class Procedure in C
sicp2014 스터디에 참여하면서 first-class procedure (function)에 대해 공부하게 되었는데, 여기에 그 내용을 올린다. 먼저, SICP 책에서 first-class procedure는 다음 4가지로 정리된다.
정의 (SICP 1.3절 (pp.98))
- 변수의 값이 될 수 있다. 다시 말해, 이름이 붙을 수 있다.
- 프로시저 인자로 쓸 수 있다.
- 프로시저의 결과로 만들어질 수 있다.
- 데이터 구조 속에 집어 넣을 수 있다.
C Implementation
C 언어의 함수는 위 요구사항들을 어떻게 만족시킬 수 있을까? 함수 포인터가 알파요 오메가다.
변수의 값으로 사용
typedef int (*operator_f)(int, int);
int my_mul(int a, int b)
{
return (a*b);
}
int main(void)
{
operator_f mul = my_mul; // (1)
int a = 4, b = 5;
printf("%d x %d = %d\n", a, b, mul(a, b));
return 0;
}
프로시저의 인자로 사용
typedef int (*operator_f)(int, int);
int my_mul(int a, int b)
{
return (a*b);
}
int op(int a, int b, operator_f operation)
{
return operation(a, b);
}
int main(void)
{
int a = 4, b = 5;
printf("%d x %d = %d\n", a, b, op(a, b, my_mul)); // (2)
return 0;
}
프로시저의 결과로 받기
typedef int (*operator_f)(int, int);
int my_mul(int a, int b)
{
return (a*b);
}
operator_f get_op_mul(void)
{
return my_mul; // (3)
}
int main(void)
{
int a = 4, b = 5;
printf("%d x %d = %d\n", a, b, get_op_mul()(a, b));
return 0;
}
데이터 구조 속에 집어 넣기
typedef int (*operator_f)(int, int);
typedef struct {
int a;
int b;
operator_f op;
} calc_t;
int my_mul(int a, int b)
{
return (a*b);
}
int main(void)
{
calc_t calc = { 4, 5, my_mul };
printf("%d x %d = %d\n", calc.a, calc.b, calc.op(calc.a, calc.b));
return 0;
}
기타
SICP에서 first-class procedure의 조건을 정의한 이후로, 함수형 언어에 대한 연구가 계속 이어져 오면서 몇 가지 조건들이 더 추가되었다.
- 중첩된 합수 정의
- 익명 함수
- 클로저 (closure)
C 언어는 위 조건들을 충족하지 못한다. 최신 C 언어 표준인 C11에서도 포함되어 있지 않다.
다만 OS X의 clang에서는 block의 형태로 closure를 지원한다. 아래 코드는 영문판 wikipedia에 있는 것이다.
#include <stdio.h>
#include <Block.h>
typedef int (^IntBlock)();
IntBlock MakeCounter(int start, int increment)
{
__block int i = start;
return Block_copy(^{
int ret = i;
i += increment;
return ret;
});
}
int main(void)
{
IntBlock mycounter = MakeCounter(5, 2);
printf("1st call: %d\n", mycounter());
printf("2nd call: %d\n", mycounter());
printf("3rd call: %d\n", mycounter());
Block_release(mycounter);
return 0;
}
— END OF POST.