我用C语言实现了closure

版主: hci

头像
TheMatrix楼主
论坛支柱
论坛支柱
2024年度优秀版主
TheMatrix 的博客
帖子互动: 240
帖子: 12975
注册时间: 2022年 7月 26日 00:35

#1 我用C语言实现了closure

帖子 TheMatrix楼主 »

非常的不容易。

当然了,我很多年没碰过C语言了。语法还是清楚的。function pointer, struct, typedef, void*, malloc,主要就是这些。

C语言的语法真是简单,这么多年没碰了,还是这些东西。C++我也学过,但是现在能用的只是c-subset了。

用C语言实现closure,也就是function as a first-class member,真是很难。很拗头。我用的方法,叫context passing。后来查了一下,有个叫continuation-passing的。发现我的这个和它的那个还不一样。很拗头。当然,如果变成design pattern的话,多熟悉几遍就好一些了。

另外我发现我还是把C当python用。全是malloc,还没敢考虑释放内存。这已经令我调试的很困难了。我不会gdb。

几个基本定义:

typedef Result* (*BNF)(State);
typedef Result* (*BNF_c)(State, void*);
typedef struct { BNF_c f; void* ctx; } BNF_clo;

typedef Result* (*PostProc)(Result*);
typedef Result* (*PostProc_c)(Result*, void*);
typedef struct { PostProc_c f; void* ctx; } PostProc_clo;

+2.00 积分 [版主 hci 发放的奖励]
x1 图片

标签/Tags:
头像
TheMatrix楼主
论坛支柱
论坛支柱
2024年度优秀版主
TheMatrix 的博客
帖子互动: 240
帖子: 12975
注册时间: 2022年 7月 26日 00:35

#2 Re: 我用C语言实现了closure

帖子 TheMatrix楼主 »

TheMatrix 写了: 2025年 4月 19日 17:59 非常的不容易。

当然了,我很多年没碰过C语言了。语法还是清楚的。function pointer, struct, typedef, void*, malloc,主要就是这些。

C语言的语法真是简单,这么多年没碰了,还是这些东西。C++我也学过,但是现在能用的只是c-subset了。

用C语言实现closure,也就是function as a first-class member,真是很难。很拗头。我用的方法,叫context passing。后来查了一下,有个叫continuation-passing的。发现我的这个和它的那个还不一样。很拗头。当然,如果变成design pattern的话,多熟悉几遍就好一些了。

另外我发现我还是把C当python用。全是malloc,还没敢考虑释放内存。这已经令我调试的很困难了。我不会gdb。

几个基本定义:

typedef Result* (*BNF)(State);
typedef Result* (*BNF_c)(State, void*);
typedef struct { BNF_c f; void* ctx; } BNF_clo;

typedef Result* (*PostProc)(Result*);
typedef Result* (*PostProc_c)(Result*, void*);
typedef struct { PostProc_c f; void* ctx; } PostProc_clo;
现在对closure更清楚了。以前对closure到底是个啥还有点模糊。用c语言实现一下就清楚了。

另外就是觉得c语言真不是人用的,指针真的很难调试。所以没有指针,编程负担小太多了。没有指针还能实现c语言的速度,这就是Rust的优势。
头像
hci(海螺子)
论坛支柱
论坛支柱
帖子互动: 420
帖子: 9647
注册时间: 2022年 7月 22日 15:29

#3 Re: 我用C语言实现了closure

帖子 hci(海螺子) »

不应该发在编程版么?
sporky
职业作家
职业作家
帖子互动: 85
帖子: 761
注册时间: 2023年 9月 19日 18:58

#4 Re: 我用C语言实现了closure

帖子 sporky »

TheMatrix 写了: 2025年 4月 19日 19:37 现在对closure更清楚了。以前对closure到底是个啥还有点模糊。用c语言实现一下就清楚了。

另外就是觉得c语言真不是人用的,指针真的很难调试。所以没有指针,编程负担小太多了。没有指针还能实现c语言的速度,这就是Rust的优势。
rust更不是人用的
头像
hci(海螺子)
论坛支柱
论坛支柱
帖子互动: 420
帖子: 9647
注册时间: 2022年 7月 22日 15:29

#5 Re: 我用C语言实现了closure

帖子 hci(海螺子) »

这就是为什么要分层混合编程。不同层次的语言適合不同层次的问题。
TheMatrix 写了: 2025年 4月 19日 19:37 现在对closure更清楚了。以前对closure到底是个啥还有点模糊。用c语言实现一下就清楚了。

另外就是觉得c语言真不是人用的,指针真的很难调试。所以没有指针,编程负担小太多了。没有指针还能实现c语言的速度,这就是Rust的优势。
头像
Koch(白牛疯WhiteCowFrenzy)
见习点评
见习点评
帖子互动: 76
帖子: 1668
注册时间: 2022年 10月 25日 11:25

#6 Re: 我用C语言实现了closure

帖子 Koch(白牛疯WhiteCowFrenzy) »

c的函数指针和closure区别不大
头像
TheMatrix楼主
论坛支柱
论坛支柱
2024年度优秀版主
TheMatrix 的博客
帖子互动: 240
帖子: 12975
注册时间: 2022年 7月 26日 00:35

#7 Re: 我用C语言实现了closure

帖子 TheMatrix楼主 »

Koch 写了: 2025年 4月 21日 10:30 c的函数指针和closure区别不大
C语言函数指针是静态的。声明完就固定了。而closure应该是动态函数指针,也就是依赖参数的函数指针。但是C语言里没有这个东西,所以要想一些办法来实现,这就是这里主要解决的问题。
magagop
知名作家
知名作家
帖子互动: 54
帖子: 982
注册时间: 2024年 12月 5日 17:35

#8 Re: 我用C语言实现了closure

帖子 magagop »

TheMatrix 写了: 2025年 4月 21日 16:50 C语言函数指针是静态的。声明完就固定了。而closure应该是动态函数指针,也就是依赖参数的函数指针。但是C语言里没有这个东西,所以要想一些办法来实现,这就是这里主要解决的问题。
我不是很明白,Closure是做什麼的?
依賴參數的函數指針,難道不能用C++的重載和強制類型轉換?
上次由 hci 在 2025年 4月 21日 18:45 修改。
原因: 未提供修改原因
头像
hci(海螺子)
论坛支柱
论坛支柱
帖子互动: 420
帖子: 9647
注册时间: 2022年 7月 22日 15:29

#9 Re: 我用C语言实现了closure

帖子 hci(海螺子) »

Closure,close over,说白了就是函数自带一些环境变量,跟著函数走,調用这个函数的时候,函数内部可以直接用这些变量,不需要用参数傳進去。
magagop 写了: 2025年 4月 21日 17:51 我不是很明白,Closure是做什麼的?
依賴參數的函數指針,難道不能用C++的重載和強制類型轉換?
上次由 hci 在 2025年 4月 21日 18:51 修改。
原因: 未提供修改原因
头像
TheMatrix楼主
论坛支柱
论坛支柱
2024年度优秀版主
TheMatrix 的博客
帖子互动: 240
帖子: 12975
注册时间: 2022年 7月 26日 00:35

#10 Re: 我用C语言实现了closure

帖子 TheMatrix楼主 »

magagop 写了: 2025年 4月 21日 17:51 我不是很明白,Closure是做什麼的?
依賴參數的函數指針,難道不能用C++的重載和強制類型轉換?
Closure就是 a family of functions that depend on a parameter.

比如用python写的话:

代码: 全选

def outer(p):
    def f(x):
        return x * p
    return f
这个内部的f(x)就是一个closure。它名义上是一个 f: x --> y,但实际上它是一个family of functions: fp: x -->y。也可以说是一个 ff: p --> (f: x --> y)。也可以说是动态的函数,给一个p就有一个f,换一个p就有另一个f。这就是closure。

你在c语言里定义一个函数指针:
int (*fn)(int);

这不行。定义完了fn就固定了,不能再变了。如何能让它depend on一个参数p?C++的重载和强制类型转换应该也解决不了这个问题。
头像
verdelite(众傻之傻)
论坛元老
论坛元老
帖子互动: 837
帖子: 21728
注册时间: 2022年 7月 21日 23:33

#11 Re: 我用C语言实现了closure

帖子 verdelite(众傻之傻) »

TheMatrix 写了: 2025年 4月 21日 19:24 Closure就是 a family of functions that depend on a parameter.

比如用python写的话:

代码: 全选

def outer(p):
    def f(x):
        return x * p
    return f
这个内部的f(x)就是一个closure。它名义上是一个 f: x --> y,但实际上它是一个family of functions: fp: x -->y。也可以说是一个 ff: p --> (f: x --> y)。也可以说是动态的函数,给一个p就有一个f,换一个p就有另一个f。这就是closure。

你在c语言里定义一个函数指针:
int (*fn)(int);

这不行。定义完了fn就固定了,不能再变了。如何能让它depend on一个参数p?C++的重载和强制类型转换应该也解决不了这个问题。
这比outer(p,x)强在什么地方呢?
没有光子;也没有量子能级,量子跃迁,量子叠加,量子塌缩和量子纠缠。
头像
hci(海螺子)
论坛支柱
论坛支柱
帖子互动: 420
帖子: 9647
注册时间: 2022年 7月 22日 15:29

#12 Re: 我用C语言实现了closure

帖子 hci(海螺子) »

这样的函数自带状态,把这样的函数传到别处,有点object的意思,但又是immutable的。

主要好处是,p和x的值知道的时间不一样。p在函数生成时己知,x在函数调用时才己知。这种参数生存时间的不同,让这种函数很强大。

这有点類似于编译时与运行时的区别,允許前者,就得到了宏。有宏的语言当然比没有的强大。

总之强在编程很方便,高级语言大都支持closure。比如可以用closure来实现objects
verdelite 写了: 2025年 4月 21日 20:16 这比outer(p,x)强在什么地方呢?
x2 图片
上次由 hci 在 2025年 4月 21日 21:16 修改。
原因: 未提供修改原因
头像
TheMatrix楼主
论坛支柱
论坛支柱
2024年度优秀版主
TheMatrix 的博客
帖子互动: 240
帖子: 12975
注册时间: 2022年 7月 26日 00:35

#13 Re: 我用C语言实现了closure

帖子 TheMatrix楼主 »

verdelite 写了: 2025年 4月 21日 20:16 这比outer(p,x)强在什么地方呢?
对。fp(x)就是outer(p,x),加了一个函数参数,函数就可以固定下来了,C语言就能实现它了,int (*outer) (int, int)。

至于Closure有啥好处。这个大家可以一起说说。c语言用加多一个参数的函数可以实现它,那就说明它们是等价的。那么好处就是简练,表达力,理解性,等等的。是不是这样?

就像物理中总是说一个tensor,实际上不是一个tensor,而可能是一个tensor-valued function defined on a manifold。好处可能是说起来更加简练,注意力更加集中在目标上吧。
magagop
知名作家
知名作家
帖子互动: 54
帖子: 982
注册时间: 2024年 12月 5日 17:35

#14 Re: 我用C语言实现了closure

帖子 magagop »

hci 写了: 2025年 4月 21日 20:58 这样的函数自带状态,把这样的函数传到别处,有点object的意思,但又是immutable的。

主要好处是,p和x的值知道的时间不一样。p在函数生成时己知,x在函数调用时才己知。这种参数生存时间的不同,让这种函数很强大。

这有点類似于编译时与运行时的区别,允許前者,就得到了宏。有宏的语言当然比没有的强大。

总之强在编程很方便,高级语言大都支持closure。比如可以用closure来实现objects
我剛才研究了一下,是不是C++ lambda和functional就是closure?也能實現函數式編程和immutable,只不過名字不一樣,還能支持template,C++本身就是OOP,這樣宏、函數、模板、對象、同步異步(async、future、promise、thread, coroutine, fiber)、機器匯編等等就都搞到C++裡面了,所以C++根本就不提closure,對不對。。。

還有最新的concept和reflection,我都暈了。。。
magagop
知名作家
知名作家
帖子互动: 54
帖子: 982
注册时间: 2024年 12月 5日 17:35

#15 Re: 我用C语言实现了closure

帖子 magagop »

TheMatrix 写了: 2025年 4月 21日 21:02 对。fp(x)就是outer(p,x),加了一个函数参数,函数就可以固定下来了,C语言就能实现它了,int (*outer) (int, int)。

至于Closure有啥好处。这个大家可以一起说说。c语言用加多一个参数的函数可以实现它,那就说明它们是等价的。那么好处就是简练,表达力,理解性,等等的。是不是这样?

就像物理中总是说一个tensor,实际上不是一个tensor,而可能是一个tensor-valued function defined on a manifold。好处可能是说起来更加简练,注意力更加集中在目标上吧。
你前面舉的python例子,可以用C++ lambda實現,即可以immutable [=],也可以mutable [&],匿名函數本身也可以動態生成,也能抓取各種變量和對象實例,還有auto自動匹配類型,也能實現運行時根據輸入類型動態生成匿名函數。。。但是C++就是不說closure這個關鍵詞,所以我很困惑,不知道在C++裡面closure到底應該是什麼意義。。。
Caravel
论坛元老
论坛元老
Caravel 的博客
帖子互动: 466
帖子: 22529
注册时间: 2022年 7月 24日 17:21

#16 Re: 我用C语言实现了closure

帖子 Caravel »

hci 写了: 2025年 4月 21日 18:46 Closure,close over,说白了就是函数自带一些环境变量,跟著函数走,調用这个函数的时候,函数内部可以直接用这些变量,不需要用参数傳進去。
python实现这个很容易,python class可以callable
magagop
知名作家
知名作家
帖子互动: 54
帖子: 982
注册时间: 2024年 12月 5日 17:35

#17 Re: 我用C语言实现了closure

帖子 magagop »

hci 写了: 2025年 4月 21日 18:46 Closure,close over,说白了就是函数自带一些环境变量,跟著函数走,調用这个函数的时候,函数内部可以直接用这些变量,不需要用参数傳進去。
這不就是C++ lambda function的capture嗎?為啥C++不直接叫closure,而是改名lambda?憑空增加更多混亂。。。
Caravel
论坛元老
论坛元老
Caravel 的博客
帖子互动: 466
帖子: 22529
注册时间: 2022年 7月 24日 17:21

#18 Re: 我用C语言实现了closure

帖子 Caravel »

magagop 写了: 2025年 4月 22日 03:31 這不就是C++ lambda function的capture嗎?為啥C++不直接叫closure,而是改名lambda?憑空增加更多混亂。。。
Capture只是lambda的一个feature,

在python里面所有东西都是一个object,function也是,只要定义成callable,都可以当成函数用,要多少变量都可以。python像是更高的尺度看编程。
magagop
知名作家
知名作家
帖子互动: 54
帖子: 982
注册时间: 2024年 12月 5日 17:35

#19 Re: 我用C语言实现了closure

帖子 magagop »

Caravel 写了: 2025年 4月 22日 11:39 Capture只是lambda的一个feature,

在python里面所有东西都是一个object,function也是,只要定义成callable,都可以当成函数用,要多少变量都可以。python像是更高的尺度看编程。
C++也可以把raw指針強制轉換成function pointer,也能實現萬物皆可call啊。另外自己申請一頁內存,自己寫數據,強制轉換成可執行頁面,再執行裡面的code,這不就是JIT的原理嗎。。。
头像
TheMatrix楼主
论坛支柱
论坛支柱
2024年度优秀版主
TheMatrix 的博客
帖子互动: 240
帖子: 12975
注册时间: 2022年 7月 26日 00:35

#20 Re: 我用C语言实现了closure

帖子 TheMatrix楼主 »

magagop 写了: 2025年 4月 21日 22:41 我剛才研究了一下,是不是C++ lambda和functional就是closure?也能實現函數式編程和immutable,只不過名字不一樣,還能支持template,C++本身就是OOP,這樣宏、函數、模板、對象、同步異步(async、future、promise、thread, coroutine, fiber)、機器匯編等等就都搞到C++裡面了,所以C++根本就不提closure,對不對。。。

還有最新的concept和reflection,我都暈了。。。
对。lambda就是closure。只是不同的名字而已。可能closure这个名字在理论中用的比较多。

C++里有lambda了?这我不知道。Java好像在Java 8还是9里也实现了lambda。现在几乎所有语言都有lambda。也就是说几乎所有语言都有closure了。只有C里没有。

我在C里实现这个,也只是为了自己更好的理解一下closure。
回复

回到 “葵花宝典(Programming)”