Logo是否真的使用动态范围,这与全局变量有何不同?

时间:2014-03-20 10:55:48

标签: global-variables scope logo-lang

Logo是我小时候学过的第一种编程语言。我最近发现Logo应该使用动态范围,这对我来说是一个惊喜,因为我一直认为它只是使用了全局变量。这让我想知道是否我不明白动态范围是什么意思。

思考通过动态范围,变量将进入全局堆栈,因此当您调用另一个方法时,变量仍然可见。 (到目前为止,就像一个全局变量。)然后,如果你声明一个具有相同名称的新变量,这将被推送到全局堆栈,隐藏原始变量。 (此时,与为全局变量分配新值仍然没有太大区别。)最后,当您退出方法时,新的赋值将从堆栈中弹出,变量将恢复为其原始值。 (这似乎是使其成为动态范围的关键部分,而不仅仅是重新分配全局变量。)

所以听说Logo使用了动态范围,我期待这个程序:

to test1
  make "x "foo
  print (se [In test1: ] :x)
  test2
  print (se [Back in test1: ] :x)
end

to test2
  print (se [In test2: ] :x)
  make "x "bar
  print (se [Still in test2: ] :x)
end

test1

获得此输出:

In test1: foo
In test2: foo
Still in test2: bar
Back in test1: foo

但是当我在FMSLogo中运行它时,它实际上有这个输出:

In test1: foo
In test2: foo
Still in test2: bar
Back in test1: bar

这实际上与我小时候的记忆相符,如果有一个名为x的全局变量,则与我期望的一致。但我不知道这是动态范围 - 变量永远不会超出范围!

那么为什么像this one这样的引用声称Logo使用动态范围?

1 个答案:

答案 0 :(得分:3)

Logo确实有动态范围,但您的示例没有局部变量,因此在test2函数中设置的变量是全局变量。您需要使用local关键字而不是make关键字来创建局部变量。

这应该展示动态范围:

to test1 :x
  test2
end

to test2
  print (se [In test2: ] :x)
end

make "x "foo    
test2
test1 "bar

如果我做对了(自从我写了任何徽标以来大约二十年),它应该产生:

In test2: foo
In test2: bar

直接调用test2函数使用全局变量,但是从test1调用时,它将使用传递给test1的参数而不是全局变量。