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

World: r3wp

[All] except covered in other channels

Pekr
4-Sep-2006
[2274x5]
yes, twice :-)
found? select 1 reduce [1 none] .... should be found? select reduce 
[1 none] 1 probably?
I like 'found? as-is, but it is true, that I sometimes thought, that 
it would perform 'find for me too .... found? find series value - 
simply that 'find is redundant here ....
but that is just my non-native english perspective, which came to 
my mind few times, without actually thinking more deeply about consequences 
...
as to found? select ... dunno if it is valid thinking - you are not 
searching the series, altough reading the expression "in english" 
might suggest it - you are performing found? on the result of select 
function call ....
Ladislav
4-Sep-2006
[2279]
right, Pekr, I mentioned the SELECT issue because it is "at the heart" 
of the SWITCH problem
Oldes
4-Sep-2006
[2280x2]
Using found? select .. can be problem anyway as the selected value 
can be 'none (you found 'none) :-)) I'm not using found? much often 
i prefere none? and not none? (found? is a shortcut anyway)
(sorry I can see pekr founded this issue as well:-)
Ladislav
4-Sep-2006
[2282]
how about the SWITCH question?
sqlab
4-Sep-2006
[2283]
>> to logic! select [a b 0] 'b
== false
Ladislav
4-Sep-2006
[2284]
aha, that doesn't look good either
sqlab
4-Sep-2006
[2285]
This is also problematic
Gabriele
4-Sep-2006
[2286x6]
i got that bounce email after my last post today too.
maybe someone subscribed to the list is bouncing? although the error 
message refers to a mail loop.
select reduce [1 none] 1 is the same problem as pick reduce [none] 
1 and so on... the problem with switch can be considered a bug, however 
switch expects a block after the value so this is debatable.
i think, that since we have other ways to check for existence (find 
for select, or length? for pick), the behavior is still acceptable 
because useful in many cases.
of course, Ladislav's /default approach would probably be better.
(but can never solve the switch problem completely, because any value 
used as default could appear in the block  - you have to use find)
Ladislav
4-Sep-2006
[2292x3]
right, Gabriele, but SWITCH can be implemented using FIND, which 
would solve this issue
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
[2323]
aha, this is what you are after