gpt4 book ai didi

scheme - 方案的简单库机制 - 导入实现

转载 作者:行者123 更新时间:2023-12-02 03:30:29 26 4
gpt4 key购买 nike

我实现了一个基本方案(想想 SICP)。现在,我想添加一个基本的导入/库功能,但很难想出一种方法来做到这一点。到目前为止,我考虑了两种方法,它们都遇到了同样的障碍。

在旧的 SICP(第一版)书中有一个 make-environment/package 章节也被讨论了 here .这将返回一个新环境。

我想调用类似的东西

(import lib)

其中 lib 提供环境或过程名称和过程的列表。我的问题是如何使用库提供的过程以编程方式扩展当前环境。使用类似

((lambda (name proc) (define name proc)) 'test (lambda a (+ a a)))

不会工作,因为 define 无法创建 lambda 范围之外的绑定(bind)。

我查看了 r6rs 的引用实现,但无法弄清楚 import 的底层机制是什么。它如何创建绑定(bind)?

更新 1

我认为我的根本问题(问题)是不可能在 lambda 中使用 define,因为通过 define 完成了环境修改 被限制在周围 lambda 的范围内。为什么要以编程方式定义多个(例如生成的)过程。

这有效(类似于描述的 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。还是我错了?

最佳答案

所以你的库只需要变成一堆评估形式,就像定义中那样具有本地环境。库产生的值将是某种对象,添加到可用库的全局列表中,这些库具有要导出的名称及其值(过程、语法等)。

导入通常有大量的特性,但实际上它只需要一个库对象并将它想要的绑定(bind)插入到一个框架中,然后将程序/库的主体放入该框架中。

您可以在 Scheme 中实现一个粗略的库实现,但只要您不能轻易改变环境框架,您就需要命名您需要导入的内容:

;; crude library support made with 
;; syntax rules and closures
#!r6rs
(import (rnrs base)
(only (srfi :1) filter any))

(define-syntax lib
(syntax-rules ()
((_ name (export-symbols ...) body ...)
(define name
(let ()
; make the defines local
; here you import other libraries
body ...

;; ^binds is a assoc between symbols and
;; implementation.
(define ^binds
(list (cons 'export-symbols export-symbols) ...))

;; the function to leak definitions
(lambda args
(apply values
(map cdr
(filter
(lambda (x)
(any (lambda (e)
(eq? e (car x)))
args))
^binds)))))))))

(define-syntax imp
(syntax-rules ()
((_ name sym1)
(define sym1 (name 'sym1)))
((_ name symn ...)
(begin
(imp name symn) ...))))

;; test
(lib test (add sub)
(define (add a b)
(sub a (sub 0 b)))
(define (sub a b)
(- a b)))

(imp test add)
(add 5 3) ; ==> 8

这看起来不太像,但是 add 使用了来自同一个库的 sub,因为我们没有导入它,所以它在全局范围内不可用。你看?您甚至还可以拥有私有(private)(未导出)过程。

它的主要工作原理是通过库形式泄漏部分闭包的过程,这与消息传递背后的想法相同。 (Scheme中做OOP的一种方式)

关于scheme - 方案的简单库机制 - 导入实现,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27067117/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com