Can access to lexical variables be stripped for internal definitions?无法访问范围内部定义
也许这是一个没有问题,但有时我希望我可以定义内部过程,而无需访问范围。考虑下面这个例子:
(define (usual-racket n)
(define (hi a)
(displayln n))
(hi 'hi)
n)
我在这里“不小心”在内部定义的过程hi
类型n
而不是a
。因为n
在定义点是可见的,所以球拍正确不会抱怨。有什么办法可以制作一个像define-free
这样的特殊表格,它可以放弃这种封闭的上下文吗?我想用strip-context
的工作,但很明显我不能因为这正确思想没有工作:
(define-syntax (define-free stx)
(let ((s (strip-context stx)))
(syntax-case s()
((_ (name args ...) body ...)
#'(define (name args ...) body ...)))))
如果我有一种新的外define
那么它的工作:
(define-syntax (define/free stx)
(syntax-case stx (define-free)
((_ (N A ...) (define-free (n a ...) b ...) B ...)
#'(define N
(let ((n (lambda (a ...) b ...)))
(lambda (A ...) B ...))))))
(define/free (definitely-works n)
(define-free (hi a)
(displayln n)) ; n: unbound identifier in module in: n
(hi 'hi)
n)
...但我希望有一个解决方案,不需要重新定义基地的语法,并试图管理所有的地方内部定义可能会显示他们的头。
澄清编辑 我的动机不是为了解决上述问题,这仅仅是一个范围的例子。我的动机主要是以这种方式管理范围,以帮助我的代码读者(主要是我)了解此过程在其范围内的位置。我使用的许多内部定义都是帮助程序,使代码的主体更易于编写和理解。这样的帮助者不需要访问任何范围 - 他们也可能是顶级定义。但是,将程序放在最高级别,无论是好还是坏,都经常表明它存在,因为要了解各种程序,您必须牢记此过程的定义。因此,如果这种内部定义在写入时被提升到顶层,模块的“表面”将会变得更大。
考虑小谎:
(define (fib n)
(define (f index n-2 n-1)
(if (< index 1)
n-1
(f (sub1 index) n-1 (+ n-2 n-1))))
(f n 0 1))
内部程序f
仅在那里管理计算fib
所需的附加状态。它不需要任何额外的上下文fib
可能有。它可能只是在顶层。但是,如果它处于最高级别,那么对于好的或者不好的含义就是它在多个过程中被多次使用,这就是它具有它所具有的顶级范围的原因。如果它处于最高水平,这不是问题,因为我们(或者更不在意“我”)考虑范围的方式不应该是这样。
我相当肯定地认为,标准实践并不是将一个过程放在范围链的上方,而是因为这个混乱而恰恰需要,但实际上范围的大小只会趋于增加,这意味着在内部定义(比如三个深度级别),代码读者(我)需要考虑这个过程所看到的整个范围,即使过程不需要它。这样说不是很好吗? “啊,这是一个unlocal
区块,它具有它从顶层需求和它自己的论点所需的所有信息。”
有趣!首先,这是一个简单的问题;你为什么不直接在顶层定义你的内部函数(在这里是'hi')?我认为这个问题的答案可能有助于澄清你正在寻找的设备的细节。 –
@JohnClements对我来说顶级定义会让人产生很多精神混乱。代码位置说明了代码的一些内容。顶级代码是所有人都可以看到的,并且可能随时需要了解一些过程。一般来说,你没有内部定义的问题,它们只能在闭包中泄漏出来。所以我的问题与此相反,以防止泄漏。 –