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
21-Nov-2006
[2102]
An ever-present question. I guess being non-standard, the character 
can cause trouble in another situation. Then who is to blame ?
Gabriele
21-Nov-2006
[2103x2]
use a block instead of a url
Anton, the problem is actually that rebol does not handle percent 
encoding correctly in URLs. (i hope we can fix this in r3)
Maxim
21-Nov-2006
[2105x2]
#4143  not sure I like the proposed change, .  I'd prefer if this 
new version was a refinement  /ONLY .  I don't see what is the issue 
with switch as it stands !?!?
I've been using switch for years and have used other second values 
than blocks many times... its very usefull.  sometimes I put functions 
there.
Gabriele
21-Nov-2006
[2107]
max, there was a discussion here about switch and the new one was 
agreed to be a better solution. Ladislav can explain better what 
his concerns with the current switch are (mainly dealing with none 
i think). the feature with multiple values going to one block is 
very useful (i needed it many times and implemented my own switch 
because of that), so it seemed a good idea to integrate it in switch 
directly; but it could be a refirement if that would create too many 
problems.
Maxim
21-Nov-2006
[2108x2]
Ladislav, care to clue me on why the proposed change of "evaluates 
following value" to "evaluates following block" ?

if you already have only blocks, I don't see the advantage, it seems 
like adding a limitation !?
ok, I just looked more deeply into the #4143 ticket.... its a nice 
alternative to switch cause it allows multiple cases for each action... 
 

it functions differently, why not call it 'CHOOSE   ?
Anton
22-Nov-2006
[2110x2]
We already have CHOOSE.
Gabriele, I have noted that in a file. You will never have to remind 
me of that again, hopefully.
Maxim
22-Nov-2006
[2112]
about 'CHOOSE  eek I hate that VID populates the global space  like 
that...
Gabriele
22-Nov-2006
[2113]
max, i would be ok with switch/multiple. but is it worth to "bloat" 
switch? anyway if the change breaks actual code maybe we'll need 
to. do you think we should still let it in 2.7.2 and then you can 
test it and see how it goes in practice? if it only breaks one script 
in the world, it's quite easy to fix just that :)
Maxim
22-Nov-2006
[2114x2]
I agree that the new switch is better in practice.  I will try it 
against my current code base and report back  I use switch profusely... 
so if its not an issue for me I think that it should be a good reference 
in general.
any tests wrt speed?  is it much slower than previous version?


I also think we should add /all  like the 'CASE.... since we are 
revisiting and operating on such a fundamental mezz, it could be 
a good time to make it as consistent with other similar mezz...  
 and the /all could be usefull. especially for handling non-exclusive 
refinements.
Gabriele
22-Nov-2006
[2116x2]
not sure i understand how /all should work.
speed: it's probably a bit slower (two calls to find instead of one 
to select) but i haven't done benchmarks.
Maxim
22-Nov-2006
[2118]
do all the switches which match instead of only the first one ex:

switch [ 1 2 3 [do this]  3 4 5 [do that]]

3 would execute both blocks.
Gabriele
22-Nov-2006
[2119]
ah, i see, with multiple values it makes sense.
Maxim
22-Nov-2006
[2120x2]
yep it almost looks  like the third friend in the ANY/ALL  combination
new switch nicely replaces any/all in such circumstances as this: 


color: switch/default value  [ 0 false 'off 'no none [] "" [red] 
1 true 'on 'yes [green ]] [color: blue]
Gabriele
22-Nov-2006
[2122x2]
can we do better than 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)"
][
    if system/words/all [
        cases: find cases value
        cases: find next cases block!
    ] [
        case: clear [ ]
        append case first cases
        cases: next cases
        while [
            system/words/all [
                all
                cases: find cases value
                cases: find next cases block!
            ]
        ] [
            append case first cases
            cases: next cases
        ]
    ]
    do case
]
Anton
22-Nov-2006
[2124]
Better to just have the WHILE, and break if not ALL ?
Gregg
22-Nov-2006
[2125]
Haven't followed in detail; is there a reason it doesn't use FIND/ONLY 
instead of just FIND? We should also write a doc on SWITCH, SELECT, 
CASE, and DISPATCH (any others?) to note their differences. These 
funcs are an easy place to introduce subtle bugs if you don't understand--or, 
like me, sometimes forget--exactly how they work.
Maxim
22-Nov-2006
[2126]
can I propose this for R3?

fill: func [
	"Fills a series to a fixed length"
	data "series to fill, any non series is converted to string!"
	len [integer!] "length of resulting string"
	/with val "replace default space char"
	/right "right justify fill"
	/truncate "will truncate input data if its larger than len"
	/local buffer
][
	unless series? data [
		data: to-string data
	]
	val: any [
		val " " ; default value
	]
	buffer: head insert/dup make type? data none val len
	either right [
		reverse data
		change buffer data
		reverse buffer
	][
		change buffer data
	]
	if truncate [
		clear next at buffer len
	]
	buffer
]
Gabriele
22-Nov-2006
[2127x3]
Anton: the do has to be out of the while, otherwise a break inside 
cases would not work; maybe i could make it only a while if i use 
an extra variable instead of appending to case.
what i'd like to avoid is the copying, because that could have a 
negative impact on performance, but it seems to me it gets ugly very 
quickly without.
Max: head insert/dup tail copy data val len - length? data can save 
you some of that :)
Maxim
22-Nov-2006
[2130]
I think I was more concerned with the fill function itself and its 
range of arguments... I agree that the reverse stuff is not optimal. 
  could 'FILL itself (a faster implementation) be considered for 
2.7 ?  I've had to implement this kind of func so often...?  it handles 
all series, and transforms non series automatically...  so you can 
easily fill any value:

fill 1 3
== "1  "

also:

zfill: func [i len][fill/with/right i len 0]
zfill 1 3
== "001"


/right might be /left depending on POV  I prefer /right in the sense 
where the output is right justified... a /center could also be added 
pretty easily.
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.