r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[RAMBO] The REBOL bug and enhancement database

Gabriele
24-Nov-2006
[2164x3]
paul, your version would not work as you intend in some cases. about 
/multi vs /all, the "all" is a standard, used by CASE too; it does 
not create any problems with the global all in the cases block.
Anton, so let me try that...
1 1 value    will not work if value is a word!, which is common with 
switch.
Anton
24-Nov-2006
[2167x2]
Ah yes, you are right. Parse tries to evaluate the word. Hmm... Looking 
worse and worse...
I suppose I could convert words to lit-words, but then I will have 
to continue on to also make a custom rule to parse lit-words, which 
are more difficult.
Ladislav
24-Nov-2006
[2169]
what do you think about: load "[<]>]"
Anton
24-Nov-2006
[2170]
Interesting. Looks correct to me. The block begins, then the tag 
(a type of string) begins which can contain any character just like 
strings, then the tag finishes with the >
Ladislav
24-Nov-2006
[2171]
unfortunately, this disallows load "[<]" to work
Henrik
24-Nov-2006
[2172]
so tags are really parsed?
Maxim
24-Nov-2006
[2173x4]
I always thought being able to load tags within scripts was a risky 
business... there is no lexical differenciation from the operators, 
its the same problem as with html itself.
IMHO blocks must be the clear winner in lexical analysis whenever 
there is an ambiguity.
rebol is the boss here, not html.  and if this means escaping block 
chars in other datatypes, well I think it should be done.
I'm not saying tags should not be able to contain any string like 
they do now, but maybe, they should be extended to support escaping 
like strings, which can handle   {}}  when the inner } is escaped.
Pekr
24-Nov-2006
[2177]
hmm, maybe we should first look for the first occurance of "] ", 
with space involved, as only this case means end of the block, no? 
:-)
Anton
24-Nov-2006
[2178]
Ladislav, yes, it's just like:  load "[{]"
Pekr
24-Nov-2006
[2179]
hmm, what a nonsense I wrote :-) end of block can't be determined 
in such a simplistic way :-)
[unknown: 5]
24-Nov-2006
[2180]
What do you mean Gabriele - what kinda of scenarios do you believe 
that multi-switch wont  in?  Maybe I can fix it for those.
Gabriele
24-Nov-2006
[2181x3]
paul, for example a BREAK inside the cases block will break the WHILE 
inside SWITCH, not the loop the user probably intended.
ladislav: since <]> is not a valid tag in html, i'd say that could 
safely be considered a block close bracket.
i.e. if we make tag parsing more strict, we can probably solve the 
problem.
[unknown: 5]
24-Nov-2006
[2184x2]
Maybe then if we just add all the valid cases that meet the criteria 
to a block during the while loop and then evaluate each item in the 
while loop is completed?
after the while loop is completed rather.
Gabriele
24-Nov-2006
[2186]
that's what my switch does :)
[unknown: 5]
24-Nov-2006
[2187x3]
hehe
sounds good to me
Ahh I see where yours might have a problem also
Gregg
24-Nov-2006
[2190x2]
Max, WRT FILL, I have similar funcs, and I agree that we need something 
like this. I tried FILL and PAD as names, but didn't like them as 
much as JUSTIFY. JUSTIFY is longer, but IMO it removes the ambiguity 
for /left and /right.
Rather than pushing for R3 inclusion, we should try to get revault 
up, and put things there. :-)
[unknown: 5]
24-Nov-2006
[2192x2]
Here is my new switch:
switch: func [
    "Finds a choice and evaluates what follows it."
    [throw]
    value "Value to search for."
    cases [block!] "Block of cases to search."
    /default case "Default case if no others are found."
    /multi "evaluates what follows all matching choices"
][
    cases: find cases value
    if multi [
        multi: copy []
        while [all [not none? cases not tail? next cases]][
            if not none? cases [
                append multi first cases: find cases block! 
                cases: find cases value
            ]
        ] 
    ]
    either not none? multi [
        if not empty? multi [do multi]
    ][

        either cases [do first find cases block!][either default [do case][none]]
    ]
]
Chris
24-Nov-2006
[2194]
Small end tweak, instead of [either default [do case][none]] just 
[do case] -- if the there is no default, the result will still be 
none.
[unknown: 5]
24-Nov-2006
[2195x3]
true - I see another problem also thought which is when multi and 
default are used together so I need to fix that also
see if this is any better:
switch: func [
    "Finds a choice and evaluates what follows it."
    [throw]
    value "Value to search for."
    cases [block!] "Block of cases to search."
    /default case "Default case if no others are found."
    /multi "evaluates what follows all matching choices"
][
    cases: find cases value
    either multi [
        multi: copy []
        while [all [not none? cases not tail? next cases]][
            if not none? cases [
                append multi first cases: find cases block! 
                cases: find cases value
            ]
        ] 
        either not empty? multi [do multi][if default [do case]]
    ][

        either cases [do first find cases block!][if default [do case]] 
    ]
]
Gabriele
24-Nov-2006
[2198x2]
With some help from Carl, I got to this:

switch: func [
    "Selects a choice and evaluates the block that follows it."
    [ throw ]
    value "Value to search for."
    cases [block!] "Block of cases to search."
    /default case "Default case if no others are found."
    /all "Evaluate all matches (not just first one)."

    /local code found?
][
    code: clear [ ]
    while [cases: find cases value] [
        either cases: find next cases block! [
            found?: yes
            append code first cases
            cases: next cases
            unless all [break]
        ] [break]
    ]
    do either found? [code] [case]
]
two local words, but shorter. also, it turns out that using a path 
for system/words/all is slower than using the either inside the while.
[unknown: 5]
24-Nov-2006
[2200]
thats cool Gabriele.  Nice and concise
Chris
24-Nov-2006
[2201x2]
I had this (how many ways to skin a cat?):
switch: func [val cases /all /default case][
    all: if all [make block! []] 
    while [cases: find/tail cases val] [
        either cases: find cases block! [
            either all [
                case: append all first cases
            ][
                case: first cases
                break
            ]
        ][break]
    ]
    do case
]
[unknown: 5]
24-Nov-2006
[2203x3]
I like Carl's code - I can't remember the last time I used the 'unless 
function.
or your code Gabriele - or both
Ok I looked at the performance from a trace perspective of three 
switch implementations - mine, Gabriels and Chris's.  Out of all 
of them mine was least efficient, while Chris's was the most efficient. 
 So if all of them do what is needed then I would say go with Chris's 
implementation.
Henrik
24-Nov-2006
[2206]
what if append was replaced with insert tail? that would make it 
a tiny bit faster
[unknown: 5]
24-Nov-2006
[2207]
Yes I would think so Henrik
Chris
24-Nov-2006
[2208]
Don't forget that 'append will be made native.  Also is it faster 
yet to change the first line to -- all: if all [clear []] -- as with 
Gabriele's function?
[unknown: 5]
24-Nov-2006
[2209x3]
I can check
Yep barely faster
When I say faster I mean in less trace output
Henrik
24-Nov-2006
[2212]
paul, that's a good idea, using trace to do that. wonder if that 
could be wrapped into a counting function that counts the amount 
of trace output?
[unknown: 5]
24-Nov-2006
[2213]
I do it all the time to optimize my scripts these days