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 一般不实现动态作用域,尽管这些示例似乎表明它对 self
和 myself
实现了。)
所以,对于冗长的准备,我们深表歉意。我的问题是关于解释用于 self
和 myself
但不适用于 a
等局部变量的准动态作用域的最佳方法。可以说 self
和 myself
只是 临时 特例,还是有更好的方式来讨论它?
好问题。
self
和myself
所代表的概念在其他编程语言中根本不存在。其他编程语言只是没有 "the agent executing this code" 的概念,因为这些语言首先不是基于代理的。
在 OO 语言中与 this
的任何类比充其量是遥远的,最坏的情况是积极误导。
self
和 myself
都是非常有用的定义,如果它们没有出现在语言中,使用它们的定义,你会在尝试编写所有代码时遇到很大的麻烦各种各样的事情。这是我能给出的最好的简短回答,说明为什么它们被定义为:它们很有用。
至于 a
等局部变量的作用域行为,我认为这是一个单独的问题。您当然可以想象尝试提出某种基于代理的局部变量定义,其中 a
类似于临时创建代理变量。对我来说,这样的设计是否可行或什至是可取的并不明显,但无论如何,我们没有那样做,我认为我们甚至没有认真探索过这种可能性。
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 一般不实现动态作用域,尽管这些示例似乎表明它对 self
和 myself
实现了。)
所以,对于冗长的准备,我们深表歉意。我的问题是关于解释用于 self
和 myself
但不适用于 a
等局部变量的准动态作用域的最佳方法。可以说 self
和 myself
只是 临时 特例,还是有更好的方式来讨论它?
好问题。
self
和myself
所代表的概念在其他编程语言中根本不存在。其他编程语言只是没有 "the agent executing this code" 的概念,因为这些语言首先不是基于代理的。
在 OO 语言中与 this
的任何类比充其量是遥远的,最坏的情况是积极误导。
self
和 myself
都是非常有用的定义,如果它们没有出现在语言中,使用它们的定义,你会在尝试编写所有代码时遇到很大的麻烦各种各样的事情。这是我能给出的最好的简短回答,说明为什么它们被定义为:它们很有用。
至于 a
等局部变量的作用域行为,我认为这是一个单独的问题。您当然可以想象尝试提出某种基于代理的局部变量定义,其中 a
类似于临时创建代理变量。对我来说,这样的设计是否可行或什至是可取的并不明显,但无论如何,我们没有那样做,我认为我们甚至没有认真探索过这种可能性。
NetLogo 中的局部变量与其他词法范围语言中的局部变量完全相同。他们不参与语言的基于代理的性质。