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

Anton
23-Nov-2006
[2131x6]
Gabriele, ah I see.
I didn't notice the importance of the one line which is different:
        case: clear [ ]
.. and the other line..
	all
never mind me.
Well.. here is what I was thinking. It's a bit shorter, but it's 
not as easy to read:
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)"
][
    while [
        system/words/all [

            any [head? cases all] ; only continue if at the beginning or /ALL 
            was specified
            cases: find cases value
            cases: find next cases block!
        ]
    ] [

     if any [default none? case][default: none case: clear []] ; only 
     clear case the first time
        append case first cases
        cases: next cases
    ]
    do case
]
Gabriele
23-Nov-2006
[2137]
i'm still hoping for someone to come out with a better idea :)
Anton
23-Nov-2006
[2138x3]
Well, how about a parse version with the ALL refinement.
switch: func [

    "Selects a choice and evaluates the first block that follows it."

    [throw] ; <-- allows RETURN to be used by the user to jump out of 
    an enclosing function (not just this one)
    value "Value to search for."
    cases [block!] "Block of cases to search."
    /default case [block!] "Default case if no others are found."
    /all "Evaluate all matches (not just first one)"
    /local rule new
][
	rule: [
		1 1 () ; <-- value
		to block! set new block! ; <- re-use the 'case variable
		(

      if any [default none? case][default: none case: clear []] ; only 
      clear case the first time
			append case new
		)
		to end ; <--
		| skip to () ; <-- type? value
	]
	rule/3: value
	change back tail rule type? value
	rule/11: either all [type? value]['end]
	parse cases [some rule]
	do case
]
(remove the comment  "; <- re-use the 'case variable" )
[unknown: 5]
23-Nov-2006
[2141x2]
Breaks some very useful features of older switch
>> print switch integer! ["1" ["string"] 1 ["integer"]]
none
Ladislav
23-Nov-2006
[2143]
Breaks some very useful features of older switch
 - the question is, whether you prefer:

switch integer! ["1" ['a] 1 ['b] #[datatype! integer!] ['c]]

to yield 'b or 'c, though
[unknown: 5]
23-Nov-2006
[2144]
I don't know that I would want to break switch for it since the name 
"Switch" implies that you are switching.  But since switch is built 
on the select function and it sounds more like what your looking 
for - I would think something like a select/all would be the route 
to go.
Maxim
23-Nov-2006
[2145x2]
I always use switch  with type?/word... cause the block is then able 
to use datatype-like words directly instead of datatype values.
ladislav:  in above example, c is expected IMHO. otherwise it opens 
up the door to too many ... options.
Gabriele
23-Nov-2006
[2147x3]
anton: unfortunately TO in parse does not do what you expect for 
all values (try to pass an integer).
ie i had proposed a parse based switch but it didn't work
paul, /all only makes sense if you allow multiple cases per block, 
so select/all would not help.
[unknown: 5]
23-Nov-2006
[2150x2]
That would be my point Gabriele.
By the way - why is 'select a native anyway?  I understand 'find 
being native but I would think that a 'select function could already 
be built as a mezz function from the native 'find.
Maxim
23-Nov-2006
[2152]
proably just much faster.
[unknown: 5]
23-Nov-2006
[2153]
Yeah that is the only thing that I can think of.
Gabriele
23-Nov-2006
[2154]
paul, the new switch allows multiple cases, thus /all makes sense. 
actually, I was able to use that in the imap protocol, which was 
using a "trick" to obtain the same results. so, now it's more readable 
and more elegant.
Ladislav
23-Nov-2006
[2155]
Max: the trouble with the 'c variant is, that REBOL does not offer 
corresponding FIND
[unknown: 5]
23-Nov-2006
[2156x4]
I don't think using /all is a good idea for any function though. 
 I recall having a problem once where it seemed that I killed the 
global all function by using that.
at least when passed to the function in a block that was being evaluated.
This kinda something like your looking for:
multi-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"
][
    either multi [
        while [all [not none? cases not tail? next cases]][
            cases: find cases value 
            either not none? cases [ 
                do first cases: at cases 2
            ][
                either default [do case][none]  
            ]
        ]     
    ][
        either value: select cases value [do value][
            either default [do case][none]
        ]
    ]
]
Maxim
23-Nov-2006
[2160]
ladislav, I understand that in the current version there is no native 
way to find the first value of integer! (not an integer! type value 
but the datatype value itself)  maybe that could be added to 2.7 
as a refinement.  its a valid request, especially since we are considering 
and openly commiting to updating the switch .   no?
[unknown: 5]
23-Nov-2006
[2161]
Actually, my multi-switch needs a couple more tweaks
Anton
23-Nov-2006
[2162x2]
Gabriele, did you try it ? All my tests til now are with integers 
!  I think you didn't notice that when value is an integer I am changing
	TO END
to
	TO integer!   ; (not the value itself)
(This just proves again that this parse-based version is confusing...)
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.