3

私の知る限り、再帰を明示的に使用せずに再帰関数を記述したい場合は、yコンビネータが便利です。Cプリプロセッサは再帰をサポートしていません。再帰をサポートするために、Cプリプロセッサにyコンビネータを実装できますか?

ありがとう。

4

2 に答える 2

3

実際、これは完全に可能です。私のプロジェクトCSP Git Repoを参照してください。これは、Cマクロプリプロセッサに完全に実装されたLISPインタープリターであり、もちろんYコンビネーターを実装できます。

あなたがそれに興味があるなら、あなたといくつかのテスト/例を願っています。

これが最も関連性の高い部分です。(csp.hから)これは、クロージャとラムダを正常に実装し、固定小数点コンビネータの実装をサポートします。

#define EVAL_e(x) x
#define _be(y) y)
#define ZIP(x)   _n() (x,_be

#define _PAIR(x,y) _e( __PAIR(x,y))
#define __PAIR(x,y) _E COND((NULL SAFE_CDR(x)((SAFE_CAR(x) SAFE_CAR(y))))((T)((SAFE_CAR (x) SAFE_CAR (y)) _e(_PAIR2(_e SAFE_CDR(x),_e SAFE_CDR(y))))))

#define _PAIR2(x,y)  _E COND((NULL SAFE_CDR(x)((SAFE_CAR(x) SAFE_CAR(y))))((T)((SAFE_CAR (x) SAFE_CAR (y)) _e(_PAIR3(_e SAFE_CDR(x),_e SAFE_CDR(y))))))

#define _PAIR3(x,y)  _E COND((NULL SAFE_CDR(x)((SAFE_CAR(x) SAFE_CAR(y))))((T)((SAFE_CAR (x) SAFE_CAR (y)) _e(_PAIR4(_e SAFE_CDR(x),_e SAFE_CDR(y))))))

#define _PAIR4(x,y)  _E COND((NULL SAFE_CDR(x)((SAFE_CAR(x) SAFE_CAR(y))))((T)((SAFE_CAR (x) SAFE_CAR (y)) _e(DELAY_INT_54(__PAIR_R) ()(SAFE_CDR(x) SAFE_CDR(y))))))
#define __PAIR_R() _$pair
#define TEST_R() TEST
#define TEST(x) test
#define _PAIR_e(x) x
#define _$pair(x) _PAIR_e(_PAIR ZIP x)
#define PAIR_EVAL(...) PAIR_EVAL2(PAIR_EVAL2(PAIR_EVAL2(__VA_ARGS__)))
#define PAIR_EVAL2(...) PAIR_EVAL3(PAIR_EVAL3(PAIR_EVAL3(__VA_ARGS__)))
#define PAIR_EVAL3(...) PAIR_EVAL4(PAIR_EVAL4(PAIR_EVAL4(__VA_ARGS__)))
#define PAIR_EVAL4(...) PAIR_EVAL_E(PAIR_EVAL_E(PAIR_EVAL_E(__VA_ARGS__)))
#define PAIR_EVAL_E(...) __VA_ARGS__
#define $pair(x) PAIR_EVAL(_$pair(x))

#define $zipped_evlis_R() $zipped_evlis
#define EVLIS_e_R() EVLIS_e
#define EVLIS_e(x) x
#define _EVLIS_ZIP(...) _n() (__VA_ARGS__,_BE
#define _BE(...) __VA_ARGS__)
#define _EVLIS_R() _EVLIS
#define _EVLIS_E(...) __VA_ARGS__
#define _EVLIS_N(...)
#define _EVLIS_B _EVLIS_E (_EVLIS_N,_EVLIS_E(_EVLIS_N,_EVLIS_N))
#define ___EVLIS(a,b,k,...) k($zipped_eval((b),(a)) DELAY_INT_2(_EVLIS_R)()(a))
#define __EVLIS(a,b,...) ___EVLIS(a,b,__VA_ARGS__ _EVLIS_E)
#define _EVLIS_EVAL_E(...) __VA_ARGS__
#define _EVLIS_EVAL_5(...) _EVLIS_EVAL_E(_EVLIS_EVAL_E(_EVLIS_EVAL_E(__VA_ARGS__)))
#define _EVLIS_EVAL_4(...) _EVLIS_EVAL_5(_EVLIS_EVAL_5(_EVLIS_EVAL_5(__VA_ARGS__)))
#define _EVLIS_EVAL_3(...) _EVLIS_EVAL_4(_EVLIS_EVAL_4(_EVLIS_EVAL_4(__VA_ARGS__)))
#define _EVLIS_EVAL_2(...) _EVLIS_EVAL_3(_EVLIS_EVAL_3(_EVLIS_EVAL_3(__VA_ARGS__)))
#define _EVLIS_EVAL(...) _EVLIS_EVAL_2(_EVLIS_EVAL_2(_EVLIS_EVAL_2(__VA_ARGS__)))

#define _EVLIS(x) __EVLIS _EVLIS_ZIP(x)
#define $zipped_evlis(x,y) _EVLIS_EVAL(_EVLIS y x (_EVLIS_B))

#define $zipped_eval_R() $zipped_eval
#define $zipped_eval(e,a) /**sth irrelevant**/
        ($eq(SAFE_CAR SAFE_CAR e (lambda))\
        (DELAY_INT_26(EVAL_e_R)() DELAY_INT_23($zipped_eval_R)()(\
        EVAL_e(EVAL_e(EVAL_e(EVAL_e(SAFE_CAR SAFE_CDR SAFE_CDR SAFE_CAR e)))),\
        EVAL_e(APPEND DELAY_INT_13($pair_R)()(EVAL_e(EVAL_e(EVAL_e(SAFE_CAR SAFE_CDR SAFE_CAR e)))\
                                              (DELAY_INT_19($zipped_evlis_R)()(EVAL_e(_e EVAL_e(SAFE_CDR e)), a)))a)))\
        /**end of eval recursion**/

#define $pair_R() $pair
#define EVAL_e_R() EVAL_e
#define $eval_E(...) __VA_ARGS__
#define $eval_expand5(...) $eval_E($eval_E($eval_E(__VA_ARGS__)))
#define $eval_expand4(...) $eval_expand5($eval_expand5($eval_expand5(__VA_ARGS__)))
#define $eval_expand3(...) $eval_expand4($eval_expand4($eval_expand4(__VA_ARGS__)))
#define $eval_expand2(...) $eval_expand3($eval_expand3($eval_expand3(__VA_ARGS__)))
#define $eval_expand(...) $eval_expand2($eval_expand2($eval_expand2(__VA_ARGS__)))
#define $zeval(x,y) $eval_expand($zipped_eval(x,y))
于 2018-03-29T03:24:54.383 に答える
1

Yコンビネータは高階関数であり、明示的な再帰置換を実装するには、言語での高階関数のサポートが必要です。したがって、特定のタスクの場合、これは、Scheme、SML、およびその他の関数型言語で実行できます。

後でCプリプロセッサについて話しましょうが、C自体はどうですか?関数の参照を関数の引数として渡し、それらを返して高階関数をエミュレートできるため、Cで高階関数を使用できる可能性があります。ただし、この言語でクロージャがサポートされていないため、Yコンビネータを実装できません。

プリプロセッサはCよりもさらに制限が厳しいため、ラムダ計算の概念に基づくYコンビネータを実装する方法はありません。Yコンビネータの適用は、高階関数を完全にサポートする関数型プログラミング言語でのみ実現できます。

Cプリプロセッサは、テキスト内の文字列置換のみを行うため、非常に簡単です。ラムダ計算や関数型プログラミングの概念を適用しようとはしません。

于 2013-01-18T21:53:56.283 に答える