试图欺骗 NetLogo 执行作为参数传递的函数
Attempting to trick NetLogo into executing a function passed as an argument
以下会产生编译错误。
to-report call-first/last [first/last a-list]
report first/last a-list
end
正文中的 a-list
突出显示错误:预期命令。
所以我尝试了以下方法。
to-report call-first/last [first/last a-list]
report first map first/last (list a-list)
end
此代码已编译(!),但当我试图让观察者执行它时
call-first/last first [1 2 3]
call-first/last
突出显示错误消息:CALL-FIRST/LAST 需要 2 个输入。
对替代方法有任何想法吗?
谢谢。
P.S。更大的图景是找到一种方法(如果有的话)在 NetLogo 中编写高阶函数。
更新:
要求观察者执行以下操作正常!
call-first-last [[a-list] -> first a-list] [1 2 3]
;; => 1
call-first-last [[a-list] -> last a-list] [1 2 3]
;; => 3
但这确实是一个很长的路要走!
另一个更新:
尝试过
to-report call-first-last [first-last a-list]
report first map (runresult first-last) (list a-list)
end
编译到此。
但要求观察者 运行 call-first-last "first" [1 2 3]
产生运行时错误:FIRST expected 1 input
所以问题似乎归结为是否有办法(除了使用上面的匿名表达式之外)编写一个 returns 函数的表达式?
我不确定所有细节是否正确,但当我看到您要尝试做的事情时,我的第一个想法是使用 runresult
。这有效:
to-report call-first-last [first-last a-list]
report runresult word first-last a-list
end
使用(例如):call-first-last "last" [1 2 3]
您需要为 word
和 runresult
添加一些括号,因为您使用两个以上的术语来处理更复杂的表达式。
So the question seems to come down to whether there is a way (other than using an anonymous expression as above) to write an expression that returns a function?
答案归结为...不。
当您尝试编写 call-first/last first [1 2 3]
时,您尝试使用“简洁语法”将过程传递给高阶过程:直接传递过程的名称,而不是传递像 [=11] 这样的表达式=]. (您可以在 the programming guide 中阅读一些相关内容。)
此语法适用于 map
和 foreach
等内置 NetLogo 基元,但不适用于用户定义的过程。不用太正式,这样做的原因是 NetLogo 原语的参数是类型化的:NetLogo 知道 map
期望一个报告者作为它的第一个参数,所以它可以解析一个正确调用 map first my-list-of-lists
。用户编写的代码不是这样的:NetLogo 知道您的 call-first/last
过程的 first/last
参数的类型应该是什么。
处理这个问题的标准方法是硬着头皮写一些像call-first-last [xs -> first xs] [1 2 3]
。
如果这真的困扰您,您可以使用 Jen 的解决方案(虽然它会慢一点)。
你也可以write an extension。 NetLogo 扩展允许您编写行为类似于本机 NetLogo 过程的原语,从而支持简洁的语法。如果你有一整套这样的程序,也许是值得的,否则,为了节省几个字符,那就太麻烦了。
(旁注:当然,这取决于你,但我会避免在 NetLogo 变量名称中使用 /
。语言允许它,是的,但对于几乎所有寻找在你的代码中,它看起来很像一个除法...)
以下会产生编译错误。
to-report call-first/last [first/last a-list]
report first/last a-list
end
正文中的 a-list
突出显示错误:预期命令。
所以我尝试了以下方法。
to-report call-first/last [first/last a-list]
report first map first/last (list a-list)
end
此代码已编译(!),但当我试图让观察者执行它时
call-first/last first [1 2 3]
call-first/last
突出显示错误消息:CALL-FIRST/LAST 需要 2 个输入。
对替代方法有任何想法吗?
谢谢。
P.S。更大的图景是找到一种方法(如果有的话)在 NetLogo 中编写高阶函数。
更新:
要求观察者执行以下操作正常!
call-first-last [[a-list] -> first a-list] [1 2 3]
;; => 1
call-first-last [[a-list] -> last a-list] [1 2 3]
;; => 3
但这确实是一个很长的路要走!
另一个更新:
尝试过
to-report call-first-last [first-last a-list]
report first map (runresult first-last) (list a-list)
end
编译到此。
但要求观察者 运行 call-first-last "first" [1 2 3]
产生运行时错误:FIRST expected 1 input
所以问题似乎归结为是否有办法(除了使用上面的匿名表达式之外)编写一个 returns 函数的表达式?
我不确定所有细节是否正确,但当我看到您要尝试做的事情时,我的第一个想法是使用 runresult
。这有效:
to-report call-first-last [first-last a-list]
report runresult word first-last a-list
end
使用(例如):call-first-last "last" [1 2 3]
您需要为 word
和 runresult
添加一些括号,因为您使用两个以上的术语来处理更复杂的表达式。
So the question seems to come down to whether there is a way (other than using an anonymous expression as above) to write an expression that returns a function?
答案归结为...不。
当您尝试编写 call-first/last first [1 2 3]
时,您尝试使用“简洁语法”将过程传递给高阶过程:直接传递过程的名称,而不是传递像 [=11] 这样的表达式=]. (您可以在 the programming guide 中阅读一些相关内容。)
此语法适用于 map
和 foreach
等内置 NetLogo 基元,但不适用于用户定义的过程。不用太正式,这样做的原因是 NetLogo 原语的参数是类型化的:NetLogo 知道 map
期望一个报告者作为它的第一个参数,所以它可以解析一个正确调用 map first my-list-of-lists
。用户编写的代码不是这样的:NetLogo 知道您的 call-first/last
过程的 first/last
参数的类型应该是什么。
处理这个问题的标准方法是硬着头皮写一些像call-first-last [xs -> first xs] [1 2 3]
。
如果这真的困扰您,您可以使用 Jen 的解决方案(虽然它会慢一点)。
你也可以write an extension。 NetLogo 扩展允许您编写行为类似于本机 NetLogo 过程的原语,从而支持简洁的语法。如果你有一整套这样的程序,也许是值得的,否则,为了节省几个字符,那就太麻烦了。
(旁注:当然,这取决于你,但我会避免在 NetLogo 变量名称中使用 /
。语言允许它,是的,但对于几乎所有寻找在你的代码中,它看起来很像一个除法...)