[REBOL] Re: URL & setword bugs
From: joel:neely:fedex at: 18-Aug-2002 8:18
Hi, Andrew (and Paul and Carl),
Two different issues, and they're both a bit tricky...
Andrew Martin wrote:
> As shown by Joel on the mailing list:
> >> type? garbage:"trash"
> == string!
> >> foo: garbage:"trash"
> == "trash"
> >> foo
> == "trash"
>
> I feel that garbage:"trash" should result in a syntax error.
>
Gabriele already posted my goof in the first case. The opening quote
effectively terminates the set-word! GARBAGE: therefore the syntax
is quite legal. Other examples would be:
>> blk:[2 4 6 8] == [2 4 6 8]
>> blk == [2 4 6 8]
>> str:{no space required} == "no space required"
>> str == "no space required"
>> val:(copy/part str 3) == "no "
>> val == "no "
My apologies for crying wolf over this one!
> >> test: ["a" "b" "c" "d"]
> == ["a" "b" "c" "d"]
> >> i: 2
> == 2
> >> test/:i: "BBBB"
> ** Syntax Error: Invalid word -- :i:
> ** Near: (line 1) test/:i: "BBBB"
>
I raised this issue at least a year ago. The syntax of paths
doesn't allow the last segment to be a get-word followed by
a colon, as if the lexical scanner is choking over the piece
after the last slash, as indicated by the "Invalid word..."
message.
I agree that being able to add a colon to the end of ANY valid
path expression to set the value at that "place" in the structure
would be much cleaner and more notationally consistent that the
hoops we currently must junp through.
HOWEVER... it's easy to be misled by your example!
> I feel that test/2 should now be "BBBB" instead of the syntax error.
>
> After all the following works:
> >> test
> == ["a" "b" "c" "d"]
> >> test/:i/1: #"z"
> == "z"
> >> test
> == ["a" "z" "c" "d"]
>
The reason that works is that TEST is a series (block!) of series
(string!) values, therefore the three-component path is legitimate:
test ["a" "b" "c" "d"]
test/:i "b" (given that I was set to 2)
test/:i/1 #"b"
So we can use the example from Paul's post just as well:
>> test: ["a" "b" "c" "d"]
== ["a" "b" "c" "d"]
>> i: 2
== 2
>> change test/:i "BBBB"
== ""
>> test
== ["a" "BBBB" "c" "d"]
Again, we're applying CHANGE to the series (string!) at TEST/2
to modify that series value. If we populate a block with non-series
values, however, the same game doesn't work:
>> failure: [0 1 2 3]
== [0 1 2 3]
>> change failure/:i "BBBB"
** Script Error: change expected series argument of type: series
port
** Near: change failure/:i "BBBB"
I assume we can agree that we'd like to see
test/:i: "Hello!"
work in either case, equivalent to
poke test (:i) "Hello!"
under the theory that one should be able to make a "set path" value
by appending a colon to any "non-set-path" case of a path.
My original proposal was even more radical. I suggested that
PAREN! values also be allowed as path components, so that one
could navigate through a multi-level structure using expressions
as selectors, so that
test/:i/1
could be written as
test/(i)/1
but one could also write something like
test/(i + 1)/1
instead of the (kudgier IMHO) current
j: i + 1
test/:j/1
After all, the "EB" in "REBOL" stands for "Expression-Based", so
one would expect to be able to use expressions rather than having
to create temporary words in such cases...
My "poster child" illustration for this was the smoothing problem:
Given a block of numbers, modify the block's content so that
all interior value (i.e. except the first and last) are
averaged with their immediate neighbors.
With the expression-based path notation, this could be written as
smooth: func [b [block!]] [
repeat i (length? blk) - 2 [
b/(i + 1): (b/(i) + b/(i + 1) + b/(i + 2)) / 3.0
]
]
instead of the (more cumbersome and less "expression-based" IMHO)
smooth: func [b [block!]] [
repeat i (length? b) - 2 [
poke b i + 1
((pick b i) + (pick b i + 1) + (pick b i + 2))
/ 3.0
]
]
My $0.02...
-jn-
--
; Joel Neely joeldotneelyatfedexdotcom
REBOL [] do [ do func [s] [ foreach [a b] s [prin b] ] sort/skip
do function [s] [t] [ t: "" foreach [a b] s [repend t [b a]] t ] {
| e s m!zauafBpcvekexEohthjJakwLrngohOqrlryRnsctdtiub} 2 ]