Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[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 ]