NetLogo 中自我和我自己的动态范围?

Dynamic scoping of self and myself in NetLogo?

当我运行这段代码时:

  to myself1
    create-turtles 1 
    let a "a"
    ask turtle 0 [
      show a
      show self
      ask patch-here [
        show a
        show self
        show myself
      ]
    ]
  end

我得到这个输出:

(turtle 0): "a"
(turtle 0): (turtle 0)
(patch 0 0): "a"
(patch 0 0): (patch 0 0)
(patch 0 0): (turtle 0)

所以在ask patch代码块里面self指的是补丁,myself指的是turtle 0

这就是 NetLogo 用户手册(和示例代码)让您期待的。

我不清楚为什么 self 应该指补丁而不是 turtle 0

诚然,我已经很久没有写任何Java了,但我的理解是,匿名函数中的this指的是函数嵌入的对象。相比之下,上面代码中的 self 指的是 运行 代码中的任何一个补丁——而不是 self 在词法上出现的乌龟。此外,局部变量 a 可从代码块内访问。

self 设置为代码块本地的决定,大概是为了提供一种引用正在执行该块的代理的方法,要求 NetLogo 定义另一种引用调用上下文的方法。这就是 myself 的功能,如示例输出所示。

更一般地说,即使在单独的函数中使用,myself 似乎也指调用乌龟。

to myself2
  let a "a"
  ask turtle 0 [
    show a
    show self
    ask patch-here [ myself2' ]   
  ]
end

to myself2'
  ; show a
  show self    
  show myself
end

输出为:

(turtle 0): "a"
(turtle 0): (turtle 0)
(patch 0 0): (patch 0 0)
(patch 0 0): (turtle 0)

所以 myself 可以从一个单独的函数访问并返回调用 turtle。但是变量a,看似相似,却无法访问。如果 show a 没有被注释掉,NetLogo 会发出一条错误信息说 a 没有在 myself2' 中定义。 (换句话说,NetLogo 一般不实现动态作用域,尽管这些示例似乎表明它对 selfmyself 实现了。)

所以,对于冗长的准备,我们深表歉意。我的问题是关于解释用于 selfmyself 但不适用于 a 等局部变量的准动态作用域的最佳方法。可以说 selfmyself 只是 临时 特例,还是有更好的方式来讨论它?

好问题。

selfmyself所代表的概念在其他编程语言中根本不存在。其他编程语言只是没有 "the agent executing this code" 的概念,因为这些语言首先不是基于代理的。

在 OO 语言中与 this 的任何类比充其量是遥远的,最坏的情况是积极误导。

selfmyself 都是非常有用的定义,如果它们没有出现在语言中,使用它们的定义,你会在尝试编写所有代码时遇到很大的麻烦各种各样的事情。这是我能给出的最好的简短回答,说明为什么它们被定义为:它们很有用。

至于 a 等局部变量的作用域行为,我认为这是一个单独的问题。您当然可以想象尝试提出某种基于代理的局部变量定义,其中 a 类似于临时创建代理变量。对我来说,这样的设计是否可行或什至是可取的并不明显,但无论如何,我们没有那样做,我认为我们甚至没有认真探索过这种可能性。

NetLogo 中的局部变量与其他词法范围语言中的局部变量完全相同。他们不参与语言的基于代理的性质。