对于我的课程项目,我必须实现一个(简单的)Scheme编译器。
此时我正在集思广益,实施各种功能。
为什么典型的Scheme实现会使用复杂的GC?如果代码真正起作用(没有副作用),则当前未执行的函数不能保持分配的内存。永远! (除非是泄密!)
因此,为什么不使用大多数命令式语言所遵循的策略,例如C
,即堆栈分配。每次输入新的词汇上下文(即(define (foo ..)
或(letrec ...
)时,在堆栈上分配变量存储,然后在退出上下文后调整堆栈指针。
由于scheme没有malloc()
并且只允许分配预定义类型,因此一个简单的实现可以使用池或区域分配器,因此“堆栈”永远不会碎片化。
我不必实现闭包,但我认为即使这些也可以通过将绑定值复制到用于专门跟踪闭包状态的单独堆栈来完成。
思想?
答案 0 :(得分:7)
即使没有闭包,混叠也是困难的部分。具体来说,假设一个过程创建一个结构化的数据,然后返回它的一部分?你如何确定哪些部分可以免费?如果你能解决这个问题......那么,你刚刚重新发明了垃圾收集。
对于这个有点不同的看法,你可能想看看Rust(www.rust-lang.org),这是一种系统级语言,它允许程序员通过使用区域和要求程序员来避免所有GC。使用不同的指针类型显式跟踪所有权。
答案 1 :(得分:6)
完成执行返回对象到其调用者的函数。这些对象不能在这些函数的堆栈帧中分配。
所以要么你必须禁止返回值(在这种情况下,你有程序不是函数式编程:并且要做任何有用的事情,那些程序必须有副作用)。
或者您必须按值创建所有内容:当返回一个对象时,它将从返回函数的堆栈帧(随后被释放)复制到调用者的堆栈帧中。
按值系统具有性能和语义限制。