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

Chris
24-Nov-2006
[2202]
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
Henrik
24-Nov-2006
[2214x2]
trace is native. I vote for adding something to trace to make stats 
from the output, perhaps just a single integer that shows how many 
functions were run through.
I hardly ever use it because I think it provides too much output
[unknown: 5]
24-Nov-2006
[2216x2]
yeah but it gives you a good idea of what is going on.
especially the resulting values
Henrik
24-Nov-2006
[2218]
is it possible to store trace output?
[unknown: 5]
24-Nov-2006
[2219x2]
sure
you can use echo or copy from the console
Henrik
24-Nov-2006
[2221]
hmm.... a bit inflexible, I think. It would be nice to bypass console 
output, and store the output in memory for later scrutiny. this would 
avoid needing to popup a console to an end user.
[unknown: 5]
24-Nov-2006
[2222x3]
just echo the information
before you turn on trace just do this:
echo %trace.txt
Henrik
24-Nov-2006
[2225]
still outputs to console. I'd like to avoid that.
[unknown: 5]
24-Nov-2006
[2226x2]
oh I see
I never tried it - or had need to without console output
Henrik
24-Nov-2006
[2228]
well, I'm not sure how useful trace is to me anyway.
Gabriele
24-Nov-2006
[2229x4]
chris, that is nice too.
about trace, if you need a count you can probably just use the STATS 
function.
however, in a trace a call to a slow function will count the same 
as a call to a fast function.
(second stats/eval should be the number of function calls)
[unknown: 5]
24-Nov-2006
[2233x2]
wow I just looked at stats on the latest view 2.7.1 and never noticed 
all the options for it before.
Yeah that is very useful Gabriele.
Anton
25-Nov-2006
[2235x6]
Paul, I don't share your concern about using ALL as a refinement 
of switch. I don't see that "killing the global ALL function" is 
a risk here. We are all aware of the danger of accidentally leaking 
words.
The advantage is we gain the freedom to use any word we like for 
the user interface.
Gabriele, slight optimization, swap these two lines:
            cases: next cases
            unless all [break]
Also, does this line:
	code: clear [ ]
mean that switch can't be used recursively ?
Chris' version looks pretty good too. (He just needs to document 
it properly.. :P)
Chris, what about [throw] ?
Gabriele
25-Nov-2006
[2241]
calling switch recursively - hmm, indeed it will be a problem. then 
i prefer chris' version which can avoid the allocation if not needed.
Anton
25-Nov-2006
[2242]
Yes, Chris' first line now seems clear to me. :)
Chris
25-Nov-2006
[2243x2]
Indeed I did abbreviate the function header.
Re. recursive, if you were to make block! [] instead of clear [] 
- I guess it's a difference in resultant garbage: with 'make the 
block becomes unbound when a subsequent switch is called, while with 
clear the cleared values become unbound.
[unknown: 5]
25-Nov-2006
[2245x5]
do we even need 'all - I mean I think we should just make that the 
default for switch and leave select to do the light lifting.
here is a switch that defaults to 'all
switch: func [
    "Finds all choices and evaluates what follows each."
    [throw]
    value "Value to search for."
    cases [block!] "Block of cases to search."
    /default case "Default case if no others are found."
    
][  
    default: copy []
    while [cases][
        if cases: find cases value [
            append default first cases: find cases block! 
        ]
    ]
    if not empty? default [case: default]
    do case    
]
Select is by far more efficient to use for single choices.
What I found interesting with stats/evals is that "block: copy []" 
is more efficient than "block: make block []"  I would not have expected 
that.
Chris
25-Nov-2006
[2250x2]
Only issue here is that it passes over empty values.  switch/default 
[1 []][print "one"]
Try this: