Loop variable of repeat can be used in its block like this:
>> b: func [x] [x + i]
== func [x][x + i]
>> repeat i 2 [print reduce append copy [b] [3]]
4
5
You can see that the variable "i" is used by the function "b".
However,in the following example, the loop variable "idx" is not seen by the function. Error message is given:
*** 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]]
Why is the second code wrong? And how to make it working?
Unfortunately, this is conceptually wrong. Loop "variable" is not used in the block, it is "globally visible" both to function's body block and to
repeat.Diagrammatically, that's
lambda → <idx in global context> ← repeat, notlambda → repeat → <idx in repeat's "scope">as you probably think.This is because you are using
functionconstructor, which makesidxword local to its context, like so:By contrast,
func(used in your first example) doesn't do that.That is, in this code:
idxwithin the anonymous function that you map over the block andidxinmapimplementation are two completely different "variables", bound to different contexts: one to the global (in which it has no value, hence the error message), and another to a local (where it is set tononeby default).The mechanics of Red's "scoping" model (or rather complete absence thereof) is a bit of an advanced topic, though I can elaborate on it if needed.
Suffice to say that it does not rely on traditional lexical scoping (like in most of the Lisp dialects), nor does it have variables in the strict sense of the term. Rather, it relies on symbolic values (aka words) that carry with them a binding to namespaces (aka contexts), which can be changed at will during the runtime (see
bindin the example below) — a bit like f-expressions in Kernel and older Lisps, or perhaps anaphoric macro, of whichcollect(see below also) is a prime example: note that it "captures"keepword, which from then on refers to its internal context, where it is defined as an ad-hoc alias forappend. Check outsource collectoutput to see what I mean.Here's a sketch of
map(yours technically is more likezip, but anyway) to give you a hint at the potential solution.Example: