[REBOL] RFC/REP - paren! segments in path! values
From: joel:neely:fedex at: 29-Oct-2000 21:56
Request For Comment / REBOL Enhancement Proposal
I propose for discussion as a possible REBOL enhancement that the
syntax for path! values be extended to allow paren! segments as
well as the current integer! literal, word!, and get-word! options.
BACKGROUND:
The REBOL path! type provides a compact notation for retrieving
values from nested structures, using either symbolic or positional
references:
b3x3x3: [
[[1 2 3][4 5 6][7 8 9]]
[[10 11 12][13 14 15][16 17 18]]
[[19 20 21][22 23 24][25 26 27]]
]
>> b3x3x3/1/2/3 == 6
>> b3x3x3/3/2/1 == 22
By using get-word segments, paths may retrieve values based on
selectors computed during evaluation:
for i 1 3 1 [
for j 1 3 1 [
for k 1 3 1 [
tot: tot + b3x3x3/:i/:j/:k
]
]
]
== 378
LIMITATIONS:
The current path notation also provides a compact way to store values:
>> b3x3x3/2/2/2: 28
== [13 28 15]
>> b3x3x3
== [
[[1 2 3] [4 5 6] [7 8 9]]
[[10 11 12] [13 28 15] [16 17 18]]
[[19 20 21] [22 23 24] [25 26 27]]
]
...but only when the last segment (at least) is literal:
>> for i 1 3 1 [for j 1 3 1 [b3x3x3/:i/:j/3: b3x3x3/:i/:j/3 + 1]]
== [25 26 28]
>> b3x3x3
== [
[[1 2 4] [4 5 7] [7 8 10]]
[[10 11 13] [13 28 16] [16 17 19]]
[[19 20 22] [22 23 25] [25 26 28]]
]
It is not possible to "get" the last segment in a set-path.
>> for i 1 3 1 [for j 1 3 1[ b3x3x3/1/:i/:j: b3x3x3/1/:i/:j + 1]]
** Syntax Error: Invalid word -- :j:.
** Where: (line 1) for i 1 3 1 [for j 1 3 1[ b3x3x3/1/:i/:j:
b3x3x3/1/:i/:j + 1]]
In addition, the path notation often requires the use of extra
words for "names", as expressions are not allowed within paths --
an odd constraint on an "Expression-Based" language. For example,
given a block (serving as a one-dimensional array), calculating
averages of adjacent pairs of values requires something similar to
>> b1
== [15 12 20 16 7 12 13 12 4 15 11 12]
for i 1 ((length? b1) - 1) 1 [
use [j] [
j: i + 1
print b1/:i + b1/:j / 2
]
]
13.5
16
18
11.5
9.5
12.5
12.5
8
9.5
13
11.5
Some conceptually simple tasks require much more complex code, such
as the code required to modify b1 so that each element (other than
the first and last) is replaced by the three-element moving average
of that element with its adjacent "neighbors".
PROPOSAL:
Extend the path notation so that path segments (except the first)
may be paren! values (containing arbitrary expressions). Evaluating
such an extended path would consist of evaluating all of the paren!
segments, then evaluating the path as if those values had been
literally present. In addition, the last segment may be followed
by a colon to form an extended set-path! with the obvious meaning.
Under this extension, the last two problems are easily solved. To
set all positions of the 3x3x3 array to zero:
for i 1 3 1 [
for j 1 3 1 [
for k 1 3 1 [
b3x3x3/(i)/(j)/(k): 0
]
]
]
To set alternating positions in a 3-d "checkerboard" pattern of
ones and zeroes:
for i 1 3 1 [
for j 1 3 1 [
for k 1 3 1 [
b3x3x3/(i)/(j)/(k): (i + j + k) // 2
]
]
]
To replace each element (except first and last) of a block (serving
as a one-dimensional array) to a three-element moving average:
for i 2 ((length? b1) - 1) 1 [
b1/(i): b1/(i - 1) + b1/(i) + b1/(i + 1) / 3
]
I believe this suggested extension is in keeping with REBOL style,
should not break any existing REBOL code, and allows "simple things
to be done in simple ways".
-jn-