首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >用于方案导入实现的简单库机制

用于方案导入实现的简单库机制
EN

Stack Overflow用户
提问于 2014-11-21 17:35:54
回答 2查看 295关注 0票数 3

我实施了一个基本计划(想想SICP)。现在,我想添加一个基本的导入/库功能,但是很难找到这样的方法。到目前为止,我考虑了两种方法,它们都面临着同样的障碍。

在旧的SICP (第一版)一书中,有一个制作环境/软件包的章节,其中也讨论了here。这将返回一个新的环境。

我想称之为

代码语言:javascript
复制
(import lib)

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

代码语言:javascript
复制
((lambda (name proc) (define name proc)) 'test (lambda a (+ a a)))

由于define无法创建超出lambda范围的绑定,因此无法工作。

我已经看过r6rs的参考实现,但无法弄清楚import的底层机制是什么。它是如何创建绑定的?

更新1

我认为我所面临的基本问题(问题)是,不可能在define中使用lambda,因为通过define进行的环境修改仅限于周围lambda的范围。是否存在以编程方式define多个过程(例如生成)的原因。

这一工作(类似于所描述的here):

代码语言:javascript
复制
((eval `square-rrot scientific-lib) 4)

还有这个

代码语言:javascript
复制
(eval `(square-rrot 4) scientific-lib)

我甚至可以写

代码语言:javascript
复制
(define sqrt (eval `square-root scientific-lib))

但是,上面的内容是不可持续的,如果我有一个包含100个函数的库,我不能一个一个地定义它们,我需要一个编程的方法来完成这个任务,但是我不能使用这样的方法:

代码语言:javascript
复制
((lambda (newName, libName) (define newName (eval libName scientific-lib))) sqrt `square-root)

在我看来,在阅读了评论和答案后,它似乎不可能建立在SIPC中的内容上。一个人需要更高级的东西,比如define-syntax。还是我错了?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-12-28 09:03:36

最后我是怎么做到的。基本上,我脱离了计划,在lambda中添加了一个旗子。然后,λ可以被限定范围,也可以不限定作用域。范围内的lambda行为与通常的lambda一样。在这种情况下,lambda没有作用域,我在一个空的环境中评估身体。然后在当前环境中对此进行评估。就像这样:

代码语言:javascript
复制
    if (lambdaHasAttribute(lambda, SCOPED)) {
        eenv = environment_extend(parameter, arguments, lambda_env);
        tmp = eval(lambda_body, eenv);
    } else {
        eenv = environment_extend(parameter, arguments, , mk_environment());
        /* scope arguments */
        tmp = eval(lambda_body, eenv);
        /* evaluate unscoped */
        tmp = eval(tmp, global_env);
    }
票数 0
EN

Stack Overflow用户

发布于 2014-11-23 01:19:58

因此,您的库只需要成为一堆具有本地环境的计算表单,就像定义中的那样。库产生的值将是添加到全局可用库列表中的某种对象,这些库具有名称及其值(过程、语法、.)。出口。

一个导入通常有大量的特性,但实际上它只接受一个库对象,并将它想要的绑定插入到一个框架中,并将程序/库的主体与该框架相结合。

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

代码语言:javascript
复制
;; 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,因为我们没有导入它,所以这个库是全局不可用的。你看?您甚至还可以使用私有(而不是导出)过程。

它的主要工作是泄漏库表单创建的部分闭包的过程,这与消息传递背后的想法相同。(一种在计划中执行OOP的方法)

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27067117

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档