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

World: r3wp

[All] except covered in other channels

Ladislav
4-Sep-2006
[2293x2]
switch expects a block after the value so this is debatable.
 - how about switch/default 1 [1 #[none]] [2] then?
sorry, forget about it, I just want to say, that SWITCH doesn't check 
the value is followed by a block
Gabriele
5-Sep-2006
[2295x3]
yes, i agree it's a problem, it's just not a problem in practice 
:)
i'd actually implement switch using parse. i find it very useful 
to be able to specify multiple values for the same block.
i.e. switch val [2 4 6 ['even] 1 3 5 ['odd]]
Ladislav
5-Sep-2006
[2298x4]
that is what Cyphre wants too
a possible implementation:
switch1: func [
    "Selects a choice and evaluates what follows it."
    [throw]
    value "Value to search for."
    cases [block!] "Block of cases to search."
    /default case [block!] "Default case if no others are found."
    /local blk
][
	value: find cases value
	if value [value: find next value block!]
    either value [do first value] [if default [do case]]
]
it is slower than SWITCH due to "double search", though
Anton
5-Sep-2006
[2302x2]
I like that behaviour. I planned to write something similar for a 
long time... :)
Mmm.. parsing numbers...
Volker
5-Sep-2006
[2304]
How much effort is a switch in c?
Anton
5-Sep-2006
[2305x2]
switch2: func [

    "Selects a choice and evaluates the first block that follows it."
    [throw]
    value "Value to search for."
    cases [block!] "Block of cases to search."
    /default case [block!] "Default case if no others are found."
    /local rule
][
	rule: [
		1 1 () ; <-- value
		to block! set value block! (return do value) 
		to end
		| skip to () ; <-- type? value
	]
	rule/3: value
	change back tail rule type? value
	any [
		parse cases [some rule]
		do case
	]
]

;test
repeat n 10 [
	print [
		n

  switch2/default n [2 4 6 ['even] 1 3 5 ['odd]] [mold "--default--"]
	]
]
switch2 1 []
switch2/default 1 [] ["--default--"]
Actually, don't need to wrap the final two lines in the ANY block.
Ladislav
5-Sep-2006
[2307]
>> switch 1 [1 [2]]
== 2
>> switch1 1 [1 [2]]
== 2
>> switch2 1 [1 [2]]
** Throw Error: Return or exit not in function
** Where: switch2
** Near: return do value
Anton
5-Sep-2006
[2308x6]
fixing it right now...
I think it's fixed, but I'm also working on a version which evaluates 
the action block for every value and following block found.
That could be useful, allowing intersections of behaviours.
(and should not interfere with the usual usage we are used to.)
How about this:
switch2: func [

    "Selects a choice and evaluates the first block that follows it."
    [throw]
    value "Value to search for."
    cases [block!] "Block of cases to search."
    /default case [block!] "Default case if no others are found."
    /local rule
][
	rule: [
		1 1 () ; <-- value
		to block! set case block! ; <- re-use the 'case variable
		to end
		| skip to () ; <-- type? value
	]
	rule/3: value
	change back tail rule type? value
	parse cases [some rule]
	do case
]

{switch2: func [

    "Selects a choice and evaluates the first block that follows it. 
    This occurs for every matching value and following block found."
    [throw]
    value "Value to search for."
    cases [block!] "Block of cases to search."
    /default case [block!] "Default case if no others are found."
    /local rule
][
	rule: [
		1 1 () ; <-- value

  to block! set case block! (case: do case) ; <- re-use the 'case variable, 
  twice...
		| [skip to ()] ; <-- type? value
		| skip
	]
	rule/3: value
	rule/11/3: type? value
	any [
		all [
			parse cases [some rule]
			case
		]
		do case
	]
]}

;test
repeat n 10 [
	print [
		n

  switch2/default n [2 4 6 ['even] 1 3 5 ['odd]] [mold "--default--"]
	]
]
switch2 1 []
switch2/default 1 [] [probe "--default, ok--"]
switch2 1 [1 [probe "ok"]]
switch2 2 [1 [probe "bad"]]
switch2 1 [1 2 [probe "ok"]]
switch2 2 [1 2 [probe "ok"]]
switch2 3 [1 2 [probe "bad"]]

; multiple action blocks
switch2 1 [1 2 [probe "ok"] 1 3 4 [probe "ok#2"]] ; <-- 
switch2 2 [1 2 [probe "ok"] 1 3 4 [probe "bad"]]
switch2 3 [1 2 [probe "bad"] 1 3 4 [probe "ok"]]
switch2 4 [1 2 [probe "bad"] 1 3 4 [probe "ok"]]
switch2 5 [1 2 [probe "bad"] 1 3 4 [probe "bad"]]


switch2/default 5 [1 2 [probe "bad"] 1 3 4 [probe "bad"]] [probe 
"--default, ok--"]
Ladislav
5-Sep-2006
[2314]
looks slightly slower than the FIND-based version according to my 
measurements
Gabriele
5-Sep-2006
[2315x3]
parse block [to value to block! ...etc...]
if TO doesn't behave (i remember the "feature" with integers...) 
then maybe:
parse find block value [to block! ..etc..]
Anton
6-Sep-2006
[2318x2]
Ladislav. Hmm.. that's a bit disappointing, although understandable. 
It's a complex parse rule with some time spent in setup.
I'm enamoured with the multiple action block version, so I'll see 
if I can make a nice FIND-based version of that.
Ladislav
6-Sep-2006
[2320]
I may not understand, doesn't the SWITCH1 above do what you want?
Anton
6-Sep-2006
[2321x2]
Uncomment my second switch2 and have a look at the first test under 
"multiple action blocks".
For that test, both "ok" and "ok#2" should be printed.
Ladislav
6-Sep-2006
[2323x2]
aha, this is what you are after
it would be interesting to know how many users would want this feature 
- I am afraid it can help to hide a programming error
Anton
6-Sep-2006
[2325x3]
That's true. I will definitely be keeping it in my library though.
Can you remind us of the effect of [throw] on return etc.. ?
I got an error "return or exit not in function" when I had [throw] 
in the function header.
Ladislav
6-Sep-2006
[2328x2]
[throw]: "Normal" REBOL functions are expected to return a value 
when "encountering" RETURN. This behaviour differs from REBOL natives, 
though. See e.g. loop 1 [return 1], which does not mean the programmer 
wants the LOOP function to return one. The intended meaning is that 
the RETURN is meant for some other function, not for LOOP. To immitate 
this behaviour (necessary for control functions like SWITCH), Carl 
invented the [throw] attribute, which is "telling", that the function 
should "throw" RETURN to some other function instead of "using it" 
for itself.
For REBOL3 I proposed a change compatible with the above mentioned 
explanation allowing to discern return types.
Anton
6-Sep-2006
[2330x2]
Ah.. thankyou.
This means if I want to allow the user to use 'return in my switch2 
to jump out of her enclosing function, then I must add [throw] to 
the function header.
Ladislav
6-Sep-2006
[2332x2]
yes
unfortunately (in R2) this means, that you are unable to use RETURN 
for the SWITCH implementation purposes
Anton
6-Sep-2006
[2334]
Yes, I see now why you did not use it.
Ladislav
6-Sep-2006
[2335]
(unless you use "black magic", like my TFUNC instead of FUNC)
Anton
6-Sep-2006
[2336]
Ok, here it is:
; FIND-based, multi-action
switch3: func [

    "Selects a choice and evaluates the first block that follows it. 
    This occurs for every matching value and following block found."

    [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."

    /local result done? ; <-- flag so we know whether an action block 
    was done. (Can't just check 'result, could be unset!)
][
	while [cases: find cases value][

  either cases: find next cases block! [set/any 'result do first cases 
  done?: yes][break]
	]
	either done? [
		get/any 'result
	][
		if default [do case]
	]
]


my-switch: :switch3   ; <--- set to the function we want to test


;test
repeat n 10 [
	print [
		n

  my-switch/default n [2 4 6 ['even] 1 3 5 ['odd]] [mold "--default--"]
	]
]
my-switch 1 []
my-switch/default 1 [] [probe "--default, ok--"]
my-switch 1 [1 [probe "ok"]]
my-switch 2 [1 [probe "bad"]]
my-switch 1 [1 2 [probe "ok"]]
my-switch 2 [1 2 [probe "ok"]]
my-switch 3 [1 2 [probe "bad"]]

; multiple action blocks
my-switch 1 [1 2 [probe "ok"] 1 3 4 [probe "ok#2"]] ; <-- 
my-switch 2 [1 2 [probe "ok"] 1 3 4 [probe "bad"]]
my-switch 3 [1 2 [probe "bad"] 1 3 4 [probe "ok"]]
my-switch 4 [1 2 [probe "bad"] 1 3 4 [probe "ok"]]
my-switch 5 [1 2 [probe "bad"] 1 3 4 [probe "bad"]]


my-switch/default 5 [1 2 [probe "bad"] 1 3 4 [probe "bad"]] [probe 
"--default, ok--"]
Geomol
18-Sep-2006
[2337]
Does anyone know of a good alternative to MS Exchange running on 
Linux/UNIX? I've found OpenGroupware.org and Open-XChange. Anything 
else worth looking at?
yeksoon
18-Sep-2006
[2338]
there is Bynari , http://www.bynari.net/

and...Zimbra,   http://www.zimbra.com/products/


if you don't really need so much things...there is always sendmail
Graham
18-Sep-2006
[2339]
we've been using Scalix
Geomol
18-Sep-2006
[2340]
Thanks guys! I also found egroupware.org, which seems promising. 
I have enough now.
Louis
19-Sep-2006
[2341]
Hit any key to start: 19-Sep-2006/11:33:24.687+6:30
Hit any key to stop : 19-Sep-2006/11:33:29.515+6:30


0:00:04.828


How can I force my stopwatch.r script (see announce group) to not 
display the nanoseconds, so instead of 0:00:04.828 it displays only 
0:00:04
Henrik
19-Sep-2006
[2342]
round now/time/precise