我实施了一个基本方案(想想SICP) . 现在,我想添加一个基本的导入/库功能,但是无法想出办法 . 到目前为止,我认为两种方法都存在同样的障碍 .
在旧的SICP(第一版)书中有一个make-environment / package章节,也讨论了here . 这将返回一个新环境 .
我想打个电话
(import lib)
其中lib提供环境或过程名称和过程列表 . 我的问题是如何使用库提供的过程以编程方式扩展当前环境 . 使用类似的东西
((lambda (name proc) (define name proc)) 'test (lambda a (+ a a)))
由于 define
无法创建超出 lambda
范围的绑定,因此无法正常工作 .
我查看了r6rs的参考实现,但无法弄清楚 import
的底层机制是什么 . 它是如何创建绑定的?
更新1
我认为我的基本问题(问题)是不可能在 lambda
中使用 define
,因为通过 define
完成的环境修改仅限于周围 lambda
的范围 . 有没有为什么programaticaly define
多个(例如生成)程序 .
这有效(类似于所描述的here):
((eval `square-rrot scientific-lib) 4)
还有这个
(eval `(square-rrot 4) scientific-lib)
我甚至可以写
(define sqrt (eval `square-root scientific-lib))
然而,上面的内容是不可持续的,如果我有一个包含100个函数的库,我无法一个一个地定义它们,我需要一个编程方式来做到这一点,但我不能使用类似的东西:
((lambda (newName, libName) (define newName (eval libName scientific-lib))) sqrt `square-root)
在阅读评论和答案之后,在我看来,基于SIPC提供的内容是不可能的 . 一个人需要更高级的东西,如 define-syntax
. 或者我错了?
2 回答
因此,您的库只需要成为一组具有本地环境(如定义中)的评估表单 . 库生成的值将是某种对象添加到可用库的全局列表中,这些库具有名称以及要导出的值(过程,语法,...) .
导入通常具有大量功能,但实际上它只需要一个库对象并将它想要的绑定插入到一个框架中,并将该程序/库的主体放在该框架中 .
您可以在Scheme中进行粗略的库实现,但只要您不能轻易地更改环境框架,就需要命名您需要导入的内容:
这看起来并不多,但是
add
使用来自同一个库的sub
,因为我们没有导入它,所以全局不可用 . 你看?你甚至可以拥有私人(非出口)程序 .它的主要工作方式是泄漏由库表单创建的闭包部分的过程,它与消息传递背后的想法相同 . (在Scheme中做OOP的一种方法)
这是我最终如何做到的 . 基本上我离开了计划并为lambda添加了一面旗帜 . 然后lambda可以是范围的,也可以不是 . 范围内的lambda表现为通常的lambda . 在lambda没有作用域的情况下,我在空的环境中评估身体 . 然后在当前环境中对其进行评估 . 像这样的东西: