Gisle asked:
What exactly is wrong with this version of filter?
filter: func [f blk] [
if tail? blk [return copy []]
if f first blk [return append filter :f next blk first blk]
return filter :f next blk
]
Or I guess this is in a more functional style:
filter: func [f blk] [
either tail? blk [
copy []
] [
either f first blk [
append filter :f next blk first blk
] [
filter :f next blk
]
]
]
Have you tried them? Here is a test file:
rebol []
enumerate-interval: func [start end] [
result: make block! (end - start)
for i start end 1 [result: insert result i
]
return head result
]
filter1: func [f blk][
result: make block! (length? blk)
foreach element blk [
if f element [result: insert result element]
]
return head result
]
filter2: func [f blk] [
if tail? blk [return copy []]
if f first blk [return append filter2 :f next blk first blk]
return filter2 :f next blk
]
filter3: func [f blk] [
either tail? blk [
copy []
] [
either f first blk [
append filter2 :f next blk first blk
] [
filter2 :f next blk
]
]
]
I had to use an `imperative' version of `enumerate-interval'
because the functional version chokes on large blocks.
filter1 :odd? enumerate-interval 1 20000
=> [1 3 5 7 9 11 13 ...]
filter2 :odd? enumerate-interval 1 20000
=> Stack overflow
filter3 :odd? enumerate-interval 1 20000
=> Stack overflow
filter1 :odd? enumerate-interval 1 10
=> [1 3 5 7 9]
filter2 :odd? enumerate-interval 1 10
=> [9 7 5 3 1]
filter3 :odd? enumerate-interval 1 10
=> [9 7 5 3 1]
The two versions you have return the result in the reverse order
and don't work on blocks bigger than about 1000 elements.
______________________________________________________
Get Your Private, Free Email at http://www.hotmail.com