Programming

C에서 함수형 프로그래밍을위한 도구는 무엇입니까?

procodes 2020. 6. 19. 22:07
반응형

C에서 함수형 프로그래밍을위한 도구는 무엇입니까?


나는 C ( C ++가 아닌) 에서 함수형 프로그래밍을 수행하는 방법에 대해 최근 많이 생각했습니다 . 분명히 C는 절차 적 언어이며 실제로 함수형 프로그래밍을 기본적으로 지원하지 않습니다.

함수형 프로그래밍 구문을 언어에 추가하는 컴파일러 / 언어 확장이 있습니까? GCC는 중첩 함수 를 언어 확장으로 제공합니다 . 중첩 함수는 상위 스택 프레임에서 변수에 액세스 할 수 있지만 여전히 성숙한 클로저와는 거리가 멀습니다.

예를 들어, C에서 실제로 유용 할 수 있다고 생각하는 한 가지는 함수 포인터가 예상되는 곳이라면 람다 식을 전달하여 함수 포인터로 붕괴되는 클로저를 만들 수 있다는 것입니다. C ++ 0x는 람다 식을 포함시킬 것입니다 (굉장하다고 생각합니다). 그러나 나는 직선 C에 적용 가능한 도구를 찾고 있습니다.

명확히하기 위해, 함수형 프로그래밍에 더 적합한 C의 특정 문제를 해결하려고하지 않습니다. 내가 원한다면 어떤 도구가 있는지 궁금합니다.


FFCALL을 사용하면 C에서 클로저를 작성할 수 있습니다 . 호출 callback = alloc_callback(&function, data)과 같은 함수 포인터를 반환합니다 . 그러나 가비지 수집을 수동으로 처리해야합니다.callback(arg1, ...)function(data, arg1, ...)

이와 관련하여 블록 이 Apple의 GCC 포크에 추가되었습니다. 그것들은 함수 포인터가 아니지만, 손으로 캡처 된 변수를 저장하고 여유 공간을 확보 할 필요없이 람다를 전달할 수 있습니다 (효과적으로 일부 복사 및 참조 횟수가 발생하고 일부 구문 설탕 및 런타임 라이브러리 뒤에 숨겨 짐).


GCC의 중첩 함수를 사용하여 람다 식을 시뮬레이션 할 수 있습니다. 사실 나를 위해 매크로가 있습니다.

#define lambda(return_type, function_body) \
  ({ \
    return_type anon_func_name_ function_body \
    anon_func_name_; \
  })

다음과 같이 사용하십시오.

int (*max)(int, int) = lambda (int, (int x, int y) { return x > y ? x : y; });

함수형 프로그래밍은 람다가 아니라 순수한 함수에 관한 것입니다. 따라서 다음은 기능적 스타일을 널리 홍보합니다.

  1. 함수 인수 만 사용하고 전역 상태는 사용하지 마십시오.

  2. 부작용 (예 : printf 또는 IO)을 최소화하십시오. 모든 기능에서 직접 부작용을 일으키지 않고 실행될 수있는 IO를 설명하는 데이터를 반환합니다.

마법 없이도 일반 c로 달성 할 수 있습니다.


Hartel & Muller의 저서 Functional C 는 현재 http://eprints.eemcs.utwente.nl/1077/ 에서 찾을 수 있습니다 ( PDF 버전에 대한 링크가 있음).


가장 중요한 것은 코드 생성기를 사용하는 것입니다. 함수형 프로그래밍을 제공 한 다른 언어로 프로그래밍 한 다음 그로부터 C 코드를 생성 하시겠습니까?

그것이 매력적인 옵션이 아니라면 CPP를 남용하여 그 길을 갈 수 있습니다. 매크로 시스템을 사용하면 기능적 프로그래밍 아이디어를 모방 할 수 있습니다. gcc가 이런 식으로 구현되었다고 들었지만 확인한 적이 없습니다.

C는 물론 함수 포인터를 사용하여 함수를 전달할 수 있으며, 주요 문제는 클로저가 부족하고 형식 시스템이 방해를받는 경향이 있습니다. M4와 같은 CPP보다 강력한 매크로 시스템을 탐색 할 수 있습니다. 궁극적으로, 내가 제안하는 것은 진정한 C는 큰 노력없이 작업에 달려 있지 않지만 C를 확장하여 작업에 맞출 수 있다는 것입니다. CPP를 사용하거나 스펙트럼의 다른 쪽 끝으로 이동하여 다른 언어에서 C 코드를 생성 할 수 있다면이 확장은 C와 가장 비슷해 보일 것입니다.


클로저를 구현하려면 어셈블리 언어와 스택 스와핑 / 관리에 만족해야합니다. 그것에 대해 권장하지 않고, 그것이 당신이해야 할 일이라고 말하면됩니다.

C에서 익명 함수를 어떻게 처리할지 확실하지 않습니다. von Neumann 컴퓨터에서는 익명 함수를 asm으로 수행 할 수 있습니다.


함수형 프로그래밍 스타일의 전제 조건은 일류 함수입니다. 다음에 견딜 수 있다면 휴대용 C로 시뮬레이션 할 수 있습니다.

  • 어휘 범위 바인딩의 수동 관리, 일명 폐쇄.
  • 함수 변수 수명의 수동 관리.
  • 함수 응용 프로그램 / 호출의 대체 구문
/* 
 * with constraints desribed above we could have
 * good approximation of FP style in plain C
 */

int increment_int(int x) {
  return x + 1;
}

WRAP_PLAIN_FUNCTION_TO_FIRST_CLASS(increment, increment_int);

map(increment, list(number(0), number(1)); // --> list(1, 2)


/* composition of first class function is also possible */

function_t* computation = compose(
  increment,
  increment,
  increment
);

*(int*) call(computation, number(1)) == 4;

이러한 코드의 런타임은 다음과 같이 작을 수 있습니다.

struct list_t {
  void* head;
  struct list_t* tail;
};

struct function_t {
   void* (*thunk)(list_t*);
   struct list_t* arguments;
}

void* apply(struct function_t* fn, struct list_t* arguments) {
  return fn->thunk(concat(fn->arguments, arguments));
}

/* expansion of WRAP_PLAIN_FUNCTION_TO_FIRST_CLASS */
void* increment_thunk(struct list_t* arguments) {
  int x_arg = *(int*) arguments->head;
  int value = increment_int(x_arg);
  int* number = malloc(sizeof *number);

  return number ? (*number = value, number) : NULL;
}

struct function_t* increment = &(struct function_t) {
  increment_thunk,
  NULL
};

/* call(increment, number(1)) expands to */
apply(increment, &(struct list_t) { number(1), NULL });

본질적으로 우리는 함수 / 인수 쌍과 매크로의 쌍으로 표현 된 클로저로 일등 함수를 모방합니다. 전체 코드는 여기 에서 찾을 수 있습니다 .


Hartel & Muller의 저서 Functional C를보십시오

http://www.ub.utwente.nl/webdocs/ctit/1/00000084.pdf
http://www.cs.bris.ac.uk/~henkm/f2c/index.html


Well quite a few programming languages are written in C. And some of them support functions as first class citizens, languages in that area are ecl (embbedabble common lisp IIRC), Gnu Smalltalk (gst) (Smalltalk has blocks), then there are libraries for "closures" e.g in glib2 http://library.gnome.org/devel/gobject/unstable/chapter-signal.html#closure which at least got near functional programming. So maybe using some of those implementations to do functional programming may be an option.

Well or you can go learning Ocaml, Haskell, Mozart/Oz or the like ;-)

Regards


The Felix language compiles to C++. Maybe that could be a step stone, if you don't mind C++.


The way I went about doing functional programming in C was to write a functional language interpreter in C. I named it Fexl, which is short for "Function EXpression Language."

The interpreter is very small, compiling down to 68K on my system with -O3 enabled. It's not a toy either - I'm using it for all the new production code I write for my business (web-based accounting for investment partnerships.)

Now I write C code only to (1) add a built-in function that calls a system routine (e.g. fork, exec, setrlimit, etc.), or (2) optimize a function that could otherwise be written in Fexl (e.g. search for a substring).

The module mechanism is based on the concept of a "context". A context is a function (written in Fexl) which maps a symbol to its definition. When you read a Fexl file, you can resolve it with any context you like. This allows you to create custom environments, or run code in a restricted "sandbox."

http://fexl.com


What is it about C that you want to make functional, the syntax or the semantics? The semantics of functional programming could certainly be added to the C compiler, but by the time you were done, you'd essentially have the equivalent of one of the existing functional languages, such as Scheme, Haskell, etc.

It would be a better use of time to just learn the syntax of those languages which directly support those semantics.


Dont Know about C. There are some functional features in Objective-C though, GCC on the OSX also supports some features, however I would again recommend to start using a functional language, there are plenty mentioned above. I personally started off with scheme, there are some excellent books such as The Little Schemer that can help you do so.

참고URL : https://stackoverflow.com/questions/216037/what-tools-are-there-for-functional-programming-in-c

반응형