Существует несколько способов сделать это («наличие» лямбда в C). Важно понять, что lambdas дают closures и что замыкатели смешивают «код» с «данными» (закрытые значения); обратите внимание, что объекты также смешивают «код» с «данными», и есть сходство между объектами и замыканиями. См. Также this answer на Programmers.
Традиционно, в C, вы не только используете указатели функций, но и используете соглашение относительно callbacks. Это, например, имеет место с GTK: каждый раз, когда вы передаете указатель на функцию, вы также передаете с ней некоторые данные. Вы можете просмотреть обратные вызовы (соглашение с указанием указателя функции C с некоторыми данными void*
) в качестве способа реализации замыканий.
Поскольку вы создаете код C (это мудрая идея, я делаю аналогичные вещи в MELT, который в Linux генерирует код C++ во время выполнения, компилирует его в общий объект и dlopen
-s) принять соглашение об обратном вызове и передать некоторые закрытые значения для каждой функции, которую вы создаете.
Вы также можете рассматривать закрытые значения как переменные static
, но этот подход, как правило, неразумный.
В прошлом была некоторая некоторая lambda.h
библиотека заголовков, которая генерирует код trampoline, предназначенный для блокировки (по существу генерирующий код, который выталкивает некоторые закрытые значения в качестве аргументов, а затем вызывает некоторую процедуру). Вы можете использовать некоторые методы JIT compilation (используя libjit, GNU lightning, LLVM, asmjit, ....), чтобы сделать то же самое. См. Также libffi для звонка произвольно функция (подписи, известной по адресу времени выполнения).
Обратите внимание, что существует сильная бут indirect- соотношение между затворами и garbage collection (читать GC handbook для более), и это не случайно, что каждый functional language имеет GC. C++ 11 лямбда-функции являются исключением из этого (и трудно понять все сложности управления памятью на закрытиях C++ 11).Поэтому, если вы генерируете код C, вы можете и, вероятно, должны использовать Boehm's conservative garbage collector (который обертывает dlopen
), и у вас будут закрытые значения GC-ed. (Вы могли бы использовать некоторые другие библиотеки GC, например, Ravenbrook's MPS или мой unmaintained Qish ...) Тогда вы могли бы иметь соглашение, согласно которому каждая сгенерированная функция C принимает свое закрытие в качестве первого аргумента.
Я хотел бы предложить, чтобы прочитать Scott's book on Programming Language Pragmatics и (предполагая, что вы знаете, чуть-чуть Scheme или Lisp, если вы не вы должны узнать немного Scheme и читать SICP) Queinnec's book Lisp In Small Pieces (если вам случится читать по-французски, читать последний французский variant).
В каком контексте вы генерируете код C? С какой операционной системой и компилятором? Почему C и не что-то лучше (Common Lisp или Ocaml)? Вы внедряете какой-то компилятор? У вас есть сборщик мусора? Измените свой вопрос, чтобы улучшить его. –
Что такое проект, каков его URL? –
Слишком плохо, что на вашем языке нет GC или закрытий. –