访问块和Y组合器内的外部变量

时间:2015-03-16 17:05:24

标签: lambda-calculus y-combinator xbase

我希望你们都好。我正在海港实施定点 Y-combinator ,我遇到了一些麻烦。那么,Y-combinator可以由 lambda-calculus 定义为:

Y = (λh.λF.F(λ x.((h(h))(F))(x))) (λh.λF.F(λ x.((h(h))(F))(x)))

我正在尝试通过性能问题对Y-combinator应用memoization。我目前的实施是:

Function YMem( bF, aCache )
   Local xAnswer
    If !lCache ; lCache := { } ; EndIf
    Return { |Arg| Iif( aCache[ Arg ] ;
        , /* then      */ aCache[ Arg ];
        , /* otherwise */ aCache[ Arg ] := ;
            Eval( Eval( bF, { |N| Eval( Eval( YMem, bF, aCache ), N ) } ), Arg ) ) }

基本上,我不能在块内部使用语句,但我可以使用表达式,它可以正常工作。我正在避免无限递归,并且限制经历0到无限。

直到这个时候,它编译得很好,但是当我试图访问外部块的变量时,Harbour会在Face中踢我!

为了测试Y-combinator实现,我尝试应用一个简单的fibonacci序列实现,但是当我返回一个接收参数G的块并隐式返回一个接收参数{{1}的块时},N因为我无法使用,编译器告诉我“外部代码块变量是遥不可及的”。

G

这也可以让我吃块。我的问题是:如何在Harbor中访问块内的外部变量?

1 个答案:

答案 0 :(得分:4)

在Harbor,Clipper和基于xBase的编程语言中,块从不可以引用 到父块的变量。块不是闭包。我们可以通过 创建本地存储并在内部块中使用它们:

Function TestOuterScope
  Local accA
  Local bAdd := { |A| accA := A, { |B| accA + B } }
  Return Eval( Eval( bAdd, 10 ), 20 )