在C中模拟Lambda? [英] Emulating lambdas in C?

查看:115
本文介绍了在C中模拟Lambda?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我应该提到的是,我是用C语言生成代码,而不是手动执行代码。我之所以这样说,是因为它背后是否有很多代码都无关紧要,因为编译器应将其全部管理。无论如何,我将如何在C中模拟lambda?我以为我可以在源代码中的某个地方生成一个带有一些随机名称的函数,然后调用它?我不太确定。我还没有真正尝试过任何东西,因为我想在实现它之前先把它弄清楚。

I should mention that I'm generating code in C, as opposed to doing this manually. I say this because it doesn't matter too much if there's a lot of code behind it, because the compiler should manage it all. Anyway, how would I go around emulating a lambda in C? I was thinking I could just generate a function with some random name somewhere in the source code and then call that? I'm not too sure. I haven't really tried anything just yet, since I wanted to get the idea down before I implement it.

我可以做某种预处理程序指令吗?一些宏,可以使这个清洁器做什么?乔恩·布洛(Jon Blow)启发了我尝试编译器开发,他似乎用Jai语言实现Lambdas。但是,我认为他在生成字节码,然后生成C的地方做了什么?我不确定。

Is there some kind of preprocessor directive I can do, or some macro that will make this cleaner to do? I've been inspired by Jon Blow to try out compiler development, and he seemed to implement Lambdas in his language Jai. However, I think he does something where he generates bytecode, and then into C? I'm not sure.

编辑:
我正在开发一个编译器,该编译器只是我的一个使我忙的项目,而且我想更多地了解编译器。我主要使用clang,我使用的是Ubuntu 14.10。我没有任何垃圾收集器,但我想尝试一下某种智能的指针,y / rust / ARC启发式内存模型进行垃圾收集,即几乎没有开销。我选择C是因为我想进一步涉猎它。我的项目是免费软件,只是一个业余项目。

I'm working on a compiler, the compiler is just a project of mine to keep me busy, plus I wanted to learn more about compilers. I primarily use clang, I'm on Ubuntu 14.10. I don't have any garbage collection, but I wanted to try my hand at some kind of smart pointer-y/rust/ARC inspired memory model for garbage collection, i.e. little to no overhead. I chose C because I wanted to dabble in it more. My project is free software, just a hobby project.

推荐答案

有几种方法可以做到这一点(在C语言中具有 lambda )。需要了解的重要一点是,lambda提供了闭包,并且闭包正在混合代码和数据(封闭值);请注意,对象还将代码与数据混合在一起,并且对象与闭包之间存在相似之处。另请参阅程序员上的此答案。 a>。

There are several ways of doing it ("having" lambdas in C). The important thing to understand is that lambdas give closures and that closures are mixing "code" with "data" (the closed values); notice that objects are also mixing "code" with "data" and there is a similarity between objects and closures. See also this answer on Programmers.

传统上,在C语言中,您不仅使用函数指针,而且还针对回调。例如, GTK 就是这种情况:每次传递函数指针时,您还传递带有它。您可以查看回调(为C函数指针提供一些 void * 数据的惯例),作为实现闭包的一种方式。

Traditionally, in C, you not only use function pointers, but you adopt a convention regarding callbacks. This for instance is the case with GTK: every time you pass a function pointer, you also pass some data with it. You can view callbacks (the convention of giving C function pointer with some void*data) as a way to implement closures.

由于您生成C代码(这是一个明智的主意,因此我在 MELT (在Linux上)在运行时生成C ++代码,将其编译为共享对象,然后 dlopen -s)可以采用回调约定并将一些闭合值传递给所生成的每个函数。

Since you generate C code (which is a wise idea, I'm doing similar things in MELT which -on Linux- generates C++ code at runtime, compile it into a shared object, and dlopen-s that) you could adopt a callback convention and pass some closed values to every function that you generate.

您还可以将闭合值视为 static 变量,

You might also consider closed values as static variables, but this approach is generally unwise.

过去曾经有一些 lambda.h 头文件库会生成一个特定于机器的蹦床代码用于关闭(本质上是生成将某些关闭的代码值作为参数,然后调用某些例程)。您可以使用 JIT编译技术(使用 libjit ,GNU 闪电 LLVM asmjit ,....)执行相同操作。另请参见 libffi 以调用任意函数(其签名在

There have been in the past some lambda.h header library which generates a machine-specific trampoline code for closures (essentially generating a code which pushes some closed values as arguments then call some routine). You might use some JIT compilation techniques (using libjit, GNU lightning, LLVM, asmjit, ....) to do the same. See also libffi to call an arbitrary function (of signature known at runtime only).

请注意,闭包与垃圾收集(请阅读 GC手​​册(更多),并且并非每一个功能语言都具有偶然性。 C ++ 11 lambda函数对此是一个例外(并且很难理解C ++ 11闭包的所有内存管理复杂性)。因此,如果您要生成C代码,则可以并且可能应该使用 Boehm的保守垃圾收集器(包装 dlopen ),您将获得闭包GC版本的值。 (您可以使用其他一些GC库,例如 Ravenbrook的MPS 或我未维护的 Qish ...)然后,您可以约定每个生成的C函数都将其闭包作为第一个参数。

Notice that there is a strong -but indirect- relation between closures and garbage collection (read the GC handbook for more), and it is not by accident that every functional language has a GC. C++11 lambda functions are an exception on this (and it is difficult to understand all the intricacies of memory management of C++11 closures). So if you are generating C code, you could and probably should use Boehm's conservative garbage collector (which is wrapping dlopen) and you would have closure GC-ed values. (You could use some other GC libraries, e.g. Ravenbrook's MPS or my unmaintained Qish...) Then you could have the convention that every generated C function takes its closure as first argument.

我建议阅读斯科特的书( Programming Language Pragmatics 和(假设您了解一点Scheme或Lisp;如果您不了解,则应该学习方案并阅读 SICP Queinnec的书小碎裂 (如果您碰巧会读法语,请阅读最新的Frenc h 变体)。

I would suggest to read Scott's book on Programming Language Pragmatics and (assuming you know a tiny bit of Scheme or Lisp; if you don't you should learn a bit of Scheme and read SICP) Queinnec's book Lisp In Small Pieces (if you happen to read French, read the latest French variant).

这篇关于在C中模拟Lambda?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆