为什么重复循环变量不起作用
Why does loop variable in repeat not work
repeat 的循环变量可以在其块中使用,如下所示:
>> b: func [x] [x + i]
== func [x][x + i]
>> repeat i 2 [print reduce append copy [b] [3]]
4
5
可以看到函数“b”使用了变量“i”。
然而,在下面的例子中,函数没有看到循环变量“idx”。给出错误信息:
*** Script Error: idx has no value
Red []
map: function [a-func a-block][
result: [] args: [] clear result
either parse a-block [some block!][
repeat idx length? a-block/1 [
clear args
foreach x a-block [append args to-block x/:idx]
append result reduce append copy [a-func] args
]
return result
]
[
repeat idx length? a-block [
append result to-block a-func a-block/:idx
]
]
]
map func [x y] [x + y - idx] [[1 2] [3 4]]
为什么第二个密码错了?以及如何让它发挥作用?
Loop variable of repeat can be used in its block like this
不幸的是,这在概念上是错误的。 在块中没有使用循环“变量”,它对函数的主体块和repeat
.
都是“全局可见的”
>> repeat index 5 []
>> index
== 5
从图表上看,那是 lambda → <idx in global context> ← repeat
,而不是您可能认为的 lambda → repeat → <idx in repeat's "scope">
。
However,in the following example, the loop variable "idx" is not seen by the function.
这是因为您正在使用 function
构造函数,这使得 idx
单词在其上下文中是局部的,如下所示:
>> function [][repeat index 3 []]
== func [/local index][repeat index 3 []]
相比之下,func
(在您的第一个示例中使用)不会这样做。
>> func [][repeat index 3 []]
== func [][repeat index 3 []]
也就是这段代码中:
map func [x y] [x + y - idx] [[1 2] [3 4]]
idx
在你映射到块上的匿名函数中和 idx
在 map
实现中是两个完全不同的“变量”,绑定到不同的上下文:一个到全局(其中它没有值,因此是错误消息),另一个是本地的(默认设置为 none
)。
Red 的“作用域”模型(或者更确切地说完全没有)的机制是一个高级主题,但如果需要我可以详细说明。
可以说它不依赖于传统的词法范围(就像在大多数 Lisp 方言中一样),也没有严格意义上的变量。相反,它依赖于符号值(又名单词),这些符号值带有与名称空间(又名上下文)的绑定,可以在运行时随意更改(参见下面示例中的 bind
)——有点像 f -Kernel 和更早的 Lisp 中的表达式,或者可能是照应宏,其中 collect
(另见下文)是一个主要示例:请注意它“捕获”keep
词,从那时起on 指的是它的内部上下文,它被定义为 append
的临时别名。查看 source collect
输出以了解我的意思。
这是 map
的草图(从技术上讲,您的草图更像 zip
,但无论如何),以提示您潜在的解决方案。
map: function [
function [function!]
series [series!]
][
spec: spec-of :function ; ideally needs to be cleaned up
step: length? spec
index: 1
bind body-of :function 'index
collect [
foreach :spec series [
keep/only do compose [(:function) (:spec)]
index: index + step
]
]
]
示例:
>> map func [x] [reduce [index x]][a b c d]
== [[1 a] [2 b] [3 c] [4 d]]
>> map func [x y] [reduce [index x + y - index]][9 2 1 4]
== [[1 10] [3 2]]
repeat 的循环变量可以在其块中使用,如下所示:
>> b: func [x] [x + i]
== func [x][x + i]
>> repeat i 2 [print reduce append copy [b] [3]]
4
5
可以看到函数“b”使用了变量“i”。
然而,在下面的例子中,函数没有看到循环变量“idx”。给出错误信息:
*** Script Error: idx has no value
Red []
map: function [a-func a-block][
result: [] args: [] clear result
either parse a-block [some block!][
repeat idx length? a-block/1 [
clear args
foreach x a-block [append args to-block x/:idx]
append result reduce append copy [a-func] args
]
return result
]
[
repeat idx length? a-block [
append result to-block a-func a-block/:idx
]
]
]
map func [x y] [x + y - idx] [[1 2] [3 4]]
为什么第二个密码错了?以及如何让它发挥作用?
Loop variable of repeat can be used in its block like this
不幸的是,这在概念上是错误的。 在块中没有使用循环“变量”,它对函数的主体块和repeat
.
>> repeat index 5 []
>> index
== 5
从图表上看,那是 lambda → <idx in global context> ← repeat
,而不是您可能认为的 lambda → repeat → <idx in repeat's "scope">
。
However,in the following example, the loop variable "idx" is not seen by the function.
这是因为您正在使用 function
构造函数,这使得 idx
单词在其上下文中是局部的,如下所示:
>> function [][repeat index 3 []]
== func [/local index][repeat index 3 []]
相比之下,func
(在您的第一个示例中使用)不会这样做。
>> func [][repeat index 3 []]
== func [][repeat index 3 []]
也就是这段代码中:
map func [x y] [x + y - idx] [[1 2] [3 4]]
idx
在你映射到块上的匿名函数中和 idx
在 map
实现中是两个完全不同的“变量”,绑定到不同的上下文:一个到全局(其中它没有值,因此是错误消息),另一个是本地的(默认设置为 none
)。
Red 的“作用域”模型(或者更确切地说完全没有)的机制是一个高级主题,但如果需要我可以详细说明。
可以说它不依赖于传统的词法范围(就像在大多数 Lisp 方言中一样),也没有严格意义上的变量。相反,它依赖于符号值(又名单词),这些符号值带有与名称空间(又名上下文)的绑定,可以在运行时随意更改(参见下面示例中的 bind
)——有点像 f -Kernel 和更早的 Lisp 中的表达式,或者可能是照应宏,其中 collect
(另见下文)是一个主要示例:请注意它“捕获”keep
词,从那时起on 指的是它的内部上下文,它被定义为 append
的临时别名。查看 source collect
输出以了解我的意思。
这是 map
的草图(从技术上讲,您的草图更像 zip
,但无论如何),以提示您潜在的解决方案。
map: function [
function [function!]
series [series!]
][
spec: spec-of :function ; ideally needs to be cleaned up
step: length? spec
index: 1
bind body-of :function 'index
collect [
foreach :spec series [
keep/only do compose [(:function) (:spec)]
index: index + step
]
]
]
示例:
>> map func [x] [reduce [index x]][a b c d]
== [[1 a] [2 b] [3 c] [4 d]]
>> map func [x y] [reduce [index x + y - index]][9 2 1 4]
== [[1 10] [3 2]]