我用C语言实现了closure

版主: hci

magagop
知名作家
知名作家
帖子互动: 69
帖子: 1071
注册时间: 2024年 12月 5日 17:35

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

帖子 magagop »

hci 写了: 2025年 4月 21日 18:46 Closure,close over,说白了就是函数自带一些环境变量,跟著函数走,調用这个函数的时候,函数内部可以直接用这些变量,不需要用参数傳進去。
我又看了一下,closure這個概念翻譯成C++語言就是functor或者function object,而lambda expression是一種特殊的unnamed function object。C++強大在lambda可以跟template還有macro混合,配合各種concurrent和parallel語法,製造出非常難debug的代碼,好像別的語言還真的不行。所以我感覺用closure的總瞧不起C++裡面用lambda或者callback的,雖然功能一樣。

根據wiki解釋:Joel Moses credits Landin with introducing the term closure to refer to a lambda expression with open bindings (free variables) that have been closed by (or bound in) the lexical environment, resulting in a closed expression, or closure. The term closure is often used as a synonym for anonymous function, though strictly, an anonymous function is a function literal without a name, while a closure is an instance of a function, a value, whose non-local variables have been bound either to values or to storage locations depending on the language. A closure can be used to associate a function with a set of "private" variables, which persist over several invocations of the function. The scope of the variable encompasses only the closed-over function, so it cannot be accessed from other program code. These are analogous to private variables in object-oriented programming, and in fact closures are similar to stateful function objects (or functors) with a single call-operator method. Closures are typically implemented with a special data structure that contains a pointer to the function code, plus a representation of the function's lexical environment (i.e., the set of available variables) at the time when the closure was created. The referencing environment binds the non-local names to the corresponding variables in the lexical environment at the time the closure is created, additionally extending their lifetime to at least as long as the lifetime of the closure. When the closure is entered at a later time, possibly with a different lexical environment, the function is executed with its non-local variables referring to the ones captured by the closure, not the current environment. An important issue for closures in concurrent programming languages is whether the variables in a closure can be updated and, if so, how these updates can be synchronized. C++ enables defining function objects by overloading operator(). These objects behave somewhat like functions in a functional programming language. They may be created at runtime and may contain state, but they do not implicitly capture local variables as closures do. As of the 2011 revision, the C++ language also supports closures, which are a type of function object constructed automatically from a special language construct called lambda-expression. A C++ closure may capture its context either by storing copies of the accessed variables as members of the closure object or by reference. In the latter case, if the closure object escapes the scope of a referenced object, invoking its operator() causes undefined behavior since C++ closures do not extend the lifetime of their context. Some C libraries support callbacks. This is sometimes implemented by providing two values when registering the callback with the library: a function pointer and a separate void* pointer to arbitrary data of the user's choice. When the library executes the callback function, it passes along the data pointer. This enables the callback to maintain state and to refer to information captured at the time it was registered with the library. The idiom is similar to closures in functionality, but not in syntax. The void* pointer is not type safe. A typical use of a function object is in writing callback functions. A callback in procedural languages, such as C, may be performed by using function pointers. However it can be difficult or awkward to pass a state into or out of the callback function. This restriction also inhibits more dynamic behavior of the function. A function object solves those problems since the function is really a façade for a full object, carrying its own state. Many modern languages, e.g. C++, support first-class function objects and may even make significant use of them. Functional programming languages additionally support closures, i.e. first-class functions that can 'close over' variables in their surrounding environment at creation time. During compilation, a transformation known as lambda lifting converts the closures into function objects. In addition to class type functors, other kinds of function objects are also possible in C++. They can take advantage of C++'s member-pointer or template facilities. The expressiveness of templates allows some functional programming techniques to be used, such as defining function objects in terms of other function objects (like function composition). Much of the C++ Standard Template Library (STL) makes heavy use of template-based function objects.

标签/Tags:
magagop
知名作家
知名作家
帖子互动: 69
帖子: 1071
注册时间: 2024年 12月 5日 17:35

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

帖子 magagop »

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

在python里面所有东西都是一个object,function也是,只要定义成callable,都可以当成函数用,要多少变量都可以。python像是更高的尺度看编程。
Python這種設計,把所有東西都放在heap裡面做成通通callable,有很大的性能問題,給heap allocator造成很大壓力,而且性能不可預測,不能用在實時系統裡面。而且需要運行時支持,不能做成baremetal,還依靠garbage collection,缺點很多,性能比C++差幾萬倍。相比之下,C++可以靈活選擇stack還是heap,value或者reference,甚至直接寫CUDA PTX匯編,成就了deepseek的神話。
Caravel
论坛元老
论坛元老
Caravel 的博客
帖子互动: 480
帖子: 22764
注册时间: 2022年 7月 24日 17:21

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

帖子 Caravel »

magagop 写了: 2025年 4月 23日 12:38 Python這種設計,把所有東西都放在heap裡面做成通通callable,有很大的性能問題,給heap allocator造成很大壓力,而且性能不可預測,不能用在實時系統裡面。而且需要運行時支持,不能做成baremetal,還依靠garbage collection,缺點很多,性能比C++差幾萬倍。相比之下,C++可以靈活選擇stack還是heap,value或者reference,甚至直接寫CUDA PTX匯編,成就了deepseek的神話。
效率是另外一回事,从语法表达能力,c++弱爆了

c++这个语言的规则太乱,每次都invent一些smart trick,只是为了炫技。
magagop
知名作家
知名作家
帖子互动: 69
帖子: 1071
注册时间: 2024年 12月 5日 17:35

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

帖子 magagop »

Caravel 写了: 2025年 4月 23日 16:53 效率是另外一回事,从语法表达能力,c++弱爆了

c++这个语言的规则太乱,每次都invent一些smart trick,只是为了炫技。
我倒是覺得C++表達能力很強,可以表述各種各樣的corner case,但是語言風格極不統一,甚至是對立的,導致難學難用,寫起來爽,讀起來噁心,如果兩個人正好風格不同的話。Python只不過是寫法單調統一而已,很多細節根本不能表述,譬如我就是不想用某幾個寄存器,等等。
Caravel
论坛元老
论坛元老
Caravel 的博客
帖子互动: 480
帖子: 22764
注册时间: 2022年 7月 24日 17:21

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

帖子 Caravel »

magagop 写了: 2025年 4月 23日 17:16 我倒是覺得C++表達能力很強,可以表述各種各樣的corner case,但是語言風格極不統一,甚至是對立的,導致難學難用,寫起來爽,讀起來噁心,如果兩個人正好風格不同的話。Python只不過是寫法單調統一而已,很多細節根本不能表述,譬如我就是不想用某幾個寄存器,等等。
Python 也可以控制直接用寄存器,可以embed assembly,只是需要一些lib,这些都不是问题。
magagop
知名作家
知名作家
帖子互动: 69
帖子: 1071
注册时间: 2024年 12月 5日 17:35

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

帖子 magagop »

Caravel 写了: 2025年 4月 23日 18:22 Python 也可以控制直接用寄存器,可以embed assembly,只是需要一些lib,这些都不是问题。
是嗎?我還是頭一次聽說,編程多年從來沒見到有哪個Python項目這麼用的。C++搞匯編倒是經常遇到。
头像
Koch(白牛疯WhiteCowFrenzy)
见习点评
见习点评
帖子互动: 80
帖子: 1705
注册时间: 2022年 10月 25日 11:25

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

帖子 Koch(白牛疯WhiteCowFrenzy) »

TheMatrix 写了: 2025年 4月 21日 16:50 C语言函数指针是静态的。声明完就固定了。而closure应该是动态函数指针,也就是依赖参数的函数指针。但是C语言里没有这个东西,所以要想一些办法来实现,这就是这里主要解决的问题。
你在函数指针里放个全局变量不就行了
头像
TheMatrix楼主
论坛支柱
论坛支柱
2024年度优秀版主
TheMatrix 的博客
帖子互动: 246
帖子: 13033
注册时间: 2022年 7月 26日 00:35

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

帖子 TheMatrix楼主 »

Koch 写了: 2025年 5月 10日 23:01 你在函数指针里放个全局变量不就行了
这也不行吧。你写个示意看看?
回复

回到 “葵花宝典(Programming)”