[REBOL] Re: for bug?
From: joel:neely:fedex at: 18-Jun-2002 23:12
Hi, Gabriele,
Gabriele Santilli wrote:
> Hi Joel,
>
> On Monday, June 17, 2002, 8:51:19 PM, you wrote:
>
> JN> foreachin gleep bletch [...]
>
> My QAD solution:
>
> foreachin: func ['word object body /local result] [
> if none? object [return none]
...
until [
set/any 'result body object/current
object/next
]
get/any 'result
> ]
>
> range: func [start end' bump'] [
> if end' - start / bump' < 1 [return none]
> context [
...
> ]
> ]
>
That's a nice first cut, but it assumes that the object passed
to FOREACHIN will be able to deliver at least one value (since
the UNTIL loop doesn't check for failure until after trying to
evaluate the body on CURRENT.
I realize that you handled that for RANGE objects, but the
thing that's nice about the iterator-driven loop in Python is
that ANY object (including one with mutable state/content) can
expose the correct interface to allow FOREACHIN to operate on
it (including the "do nothing gracefully" case).
It's too late for me to play any more with this tonight, but
there are two approaches that immediately come to mind around
this issue:
1) Inside FOREACHIN simply repeatedly apply the body to /NEXT
until /NEXT throws an error. If the error contains a
"Stop Iteration" message, simply return RESULT's value as
the value of FOREACHIN; if the error is any other kind,
then pass it on.
2) Require the object to have two methods /MORE? and /NEXT
where /MORE? indicates whether it is possible to call /NEXT
without failure, and /NEXT returns the next unused value
from the iterator.
Sketching out an example for (2), we could then imagine
foreachin temp series-iterator some-series [...]
where (DANGER, WILL ROBINSON: UNTESTED CODE AHEAD!)
series-iterator: func [s [series!]] [
make object! [
ser: s
more?: func [] [empty? ser]
next: func [/local result] [
result: first ser
ser: next ser
result
]
]
]
as an example of something that could do nothing gracefully.
-jn-
--
; Joel Neely joeldotneelyatfedexdotcom
REBOL [] do [ do func [s] [ foreach [a b] s [prin b] ] sort/skip
do function [s] [t] [ t: "" foreach [a b] s [repend t [b a]] t ] {
| e s m!zauafBpcvekexEohthjJakwLrngohOqrlryRnsctdtiub} 2 ]