Hi Elan,
the problem has been solved by the function For2 (you can see it
at the end of the mail). Your solution (I call it For1) differs
here:
>> for1 i a: [1 2] tail a 1 [print mold i]
[1 2]
[2]
>> for2 i a: [1 2] tail a 1 [print mold i]
[1 2]
[2]
[]
Regards
Ladislav
> Hi Galt,
>
> it appears I didn't got all the emails in this thread. So the
problem may
> already be solved.
>
> you wrote:
> >Ladislav,
> >
> >That is an impressive For function!
> >your example of using
> >>a: [1 2]
> >>for s a tail a 1 [print s]
> >as a test is very amusing bug, looks
> >like an infinite loop on windows, just
> >keeps printing newlines without ever ending.
>
> I guess you would rather see
>
> >> for s a tail a 1 [print s]
> 1 2
> 2
>
> I think that that's reasonable. The patched for version below
does that.
>
> If you source the for function you'll see why for behaves as it
does. The
> patched version corrects this and the other observed oddities.
The results
> of running the patched version:
>
> >> for s a next a -1 [print s]
> == none
> >> for s a next a 1 [print s]
> 1 2
> 2
> >> for s a tail a 1 [print s]
> 1 2
> 2
> >> for s a back tail a 1 [print s]
> 1 2
> 2
>
> I added the following code to for:
>
> ;- the following line forces for to interpret
> ;- "tail of a series" as intended to mean "break at end of a
series".
>
> if all [positive? bump tail? end ] [ end: back end ]
>
>
> ;- the following either any .. all .. combo catches errors
resulting
> ;- from an end index that is higher than a start index with
a
> ;- negative bump value, and also catches infinite loops that
result
> ;- from passing an empty series
>
> either any [
> empty? head end
> all [
> if (negative? bump) [ op: :lesser?]
> op index? start index? end
> ]
> ]
> [
> none
> ][
>
>
> Note that I moved the expression if (negative? bump) [ op:
:lesser?] into
> the all block of either's any block.
>
>
> The complete pathced for function follows:
>
> for: func [
> "Repeats a block over a range of values."
> [catch throw]
> 'word [word!] "Variable to hold current value"
> start [number! series! money! time! date! char!] "Starting
value"
> end [number! series! money! time! date! char!] "Ending
value"
> bump [number! money! time! char!] "Amount to skip each time"
> body [block!] "Block to evaluate"
> /local result do-body op
> ][
> if (type? start) <> (type? end) [
> throw make error! reduce ['script 'expect-arg 'for 'end
type? start]
> ]
> do-body: func reduce [[throw] word] body
> op: :greater-or-equal?
> either series? start [
> if not same? head start head end [
> throw make error! reduce ['script 'invalid-arg end]
> ]
> ;- the following line forces for to interpret
> ;- "tail of a series" as intended to mean "break at end of a
series".
>
> if all [positive? bump tail? end ] [ end: back end ]
>
> ;- the following either any .. all .. combo catches errors
resulting
> ;- from an end index that is higher than a start index with
a
> ;- negative bump value, and also catches infinite loops that
result
> ;- from passing an empty series
>
> either any [
> empty? head end
> all [
> if (negative? bump) [ op: :lesser?]
> op index? start index? end
> ]
> ]
> [
> none
> ][
> ;- we are dealing with a valid series
> while [op index? end index? start] [
> set/any 'result do-body start
> start: skip start bump
> ]
> if (negative? bump) [
> set/any 'result do-body start
> ]
> ]
> ] [
> if (negative? bump) [op: :lesser-or-equal?]
> while [op end start] [
> set/any 'result do-body start
> start: start + bump
> ]
> ]
> get/any 'result
> ]
>
>
>
> >
> >Just for kicks, I just tried this:
> >>> for s a back tail a 1 [print s]
> >1 2
> >2
> >
> >so that it stops at the last real position,
> >and that seemed to work, althout the expression
> >is more awkward and wordy!
> >
> >Your other example is this:
> >>> for s a next a -1 [print s]
> >1 2
> >
> >which I am not sure I get.
> >This would never get to next a by skipping -1.
> >Either you have a typo here, or I missed the point.
> >
> >If this were integers, it would look like
> >for x = 1 30 step -1
> >
> >>> for s a next a 1 [print s]
> >1 2
> >2
> >
> >What is the proper behavior of
> >>> for s a next a -1 [print s]
> >???
> >
> >-Galt
> >
> >p.s. As far as the second-class vs. first-class values
> >goes, I am inclined to agree with you. There are some
> >fishy issues that don't seem entirely cooked. You are
> >right to bring them up for discussion. So far, however,
> >in the programs that have come up naturally in my
> >use of Rebol, I haven't been banging into these issues
> >alot. I have seen the errorhandling stuff e.g. try, disarm
> >seems like it's more awkward than it should be.
> >I could run smack into more of them at any moment,
> >though!
> >
> >p.p.s. I think the desire to share Rebol data and
> >objects across the net between two instances of rebol.exe,
> >or storing them and retrieving them later in native Rebol
format,
> >will come up strongly in the near future.
> >Even the RebMail program might be a lot simpler if
> >you could just save your mail objects and reload later.
> >Having to create extra functions for converting from
> >Rebol to some other disk structure and then back
> >again is a pain. I think Rebol can do better.
> >It just needs to make a few new tricks available...
> >
> >
> >
> >
> >
> >>===== Original Message From "Ladislav Mecir"
<[EMAIL PROTECTED]> =====
> >>2. For loop. Here is my version working properly for series
(just
> >>a minor improvement):
> >>
> >>Nobody uses For to traverse a series, I guess. OTOH, the
> >>implementation of For should be correct.
> >>
> >>; Example of incorrect behaviour:
> >>a: [1 2]
> >>for s a tail a 1 [print s]
> >>for s a next a -1 [print s]
> >>
> >>My correction:
> >>
> >>for: func [
> >> {Repeats a block over a range of values.}
> >> [catch throw]
> >> 'word [word!] {Variable to hold current value}
> >> start [number! series! money! time! date! char!] {Starting
> >>value}
> >> end [number! series! money! time! date! char!] {Ending
value}
> >> bump [number! money! time! char!] {Amount to skip each
time}
> >> body [block!] {Block to evaluate}
> >> /local result do-body op cond
> >>][
> >> if (type? start) <> (type? end) [
> >> throw make error! reduce ['script 'expect-arg 'for
'end
> >>type? start]
> >> ]
> >> do-body: func reduce [[throw] word] body
> >> op: either positive? bump [:greater-or-equal?][
> >> :lesser-or-equal?
> >> ]
> >> either series? start [
> >> if not same? head start head end [
> >> throw make error! reduce ['script 'invalid-arg
end]
> >> ]
> >> cond: op index? end index? start
> >> while [cond] [
> >> set/any 'result do-body start
> >> cond: op index? end (index? start) + bump
> >> start: skip start bump
> >> ]
> >> ] [
> >> while [op end start] [
> >> set/any 'result do-body start
> >> start: start + bump
> >> ]
> >> ]
> >> get/any 'result
> >>]
> >>
> >
> >
> >
>
> ;- Elan [ : - ) ]
> author of REBOL: THE OFFICIAL GUIDE
> REBOL Press: The Official Source for REBOL Books
> http://www.REBOLpress.com
> visit me at http://www.TechScribe.com
>
>
>