[REBOL] Rolling your own ideal looper: does Repeat still have a bug? Re:(4)

2000-08-30 Thread galtbarber

Thanks, Gabriele,

I have enjoyed studying this foreach code you created!
Excellent!  I appreciate your help, it's very valuable.
I wanted to say, sorry for not getting back to you 
immediately, there's a lot going on right now!!!

Ciao!

-Galt

p.s. The way you use bind on this-context is something 
new to me, it seems, I am enjoying this kind of enlightenment.


>= Original Message From [EMAIL PROTECTED] =
>Hello [EMAIL PROTECTED]!
>
>On 28-Ago-00, you wrote:
>
> g> By the way, do you know how Rebol itself
> g> does foreach internally? Do they use a function
> g> like you did, or is it done some other way?
>
>Probably they're doing something like:
>
>  foreach: func [
>"Evaluates a block for each value(s) in a series."
>'word [get-word! word! block!] {Word or block of words to set each time 
(will be local)}
>data [series!] "The series to traverse"
>body [block!] "Block to evaluate each time"
>/local amount
>  ] [
>if get-word? word [word: get word]
>use compose [(word) this-context] [ ; of course the native code
>; doesn't need the extra word
>  bind body 'this-context
>  amount: either block? word [length? word] [1]
>  while [not tail? data] [
>set word data
>do body
>data: skip data amount
>  ]
>]
>  ]
>
>Obviously the native code might look a lot different. ;-)
>
>Also, since they're probably not calling the WHILE native, there
>will be some magic code to make BREAK etc. work as expected.
>
>Regards,
>Gabriele.
>--
>Gabriele Santilli <[EMAIL PROTECTED]> - Amigan - REBOL programmer
>Amiga Group Italia sez. L'Aquila -- http://www.amyresource.it/AGI/




[REBOL] Rolling your own ideal looper: does Repeat still have a bug? Re:(4)

2000-08-28 Thread galtbarber

The original question, which may have been posted 
by Paul Tretter, but I don't remember exactly,
was something like this:
a: "101"
foreach item a [
 print index? item
]

Now, we all know why that doesn't work.

This does, but probably doesn't really 
address his concern:
forall a [
 print index? a
]

and now you have to remember to reset a
a: head a
and you have to use "first a" 
to get the element everywhere in your code.

Sometimes I myself have wished I could 
have my cake and eat it too.  I want the index 
that forall gives and I want the ease of use 
of the assigned word for each element.
I am pretty dang sure lots of other Rebolers 
out there beside me have come across the same 
thing.

So I wrote something that did that, but I couldn't 
figure out how to do that simply.  Gabriele came 
up with a wonderful little gem and Ladislav and 
he made some more little improvements.

So, here it is, a kind of foreach with index access:

ideal-looper: func [
'element [word!]
'index [word!]
series [series!]
code [block!]
/local f i
] [
f: func reduce [[throw] element [any-type!] index] code
i: 1
while [i <= length? series] [f series/:i i i: i + 1]
]

>Regards,
>Gabriele.

And that's why we love Rebol!

And the punchline for Paul would be 
this usage:


a: "101"
ideal-looper item indx a [
 print [item indx]
]

the output is:
1 1
0 2
1 3
== false

And of course, there is no harm in having calls 
to "ideal-looper" multiply nested or used inside 
recursively called functions.  And the words used 
for the element and index are also just known 
in the "scope" of the code block, and will not 
stomp on your global wordspace.

I still don't really understand Ladislav's addition 
of Throw and [any-type!].  Would anyone care 
to divulge?

-Galt




[REBOL] Rolling your own ideal looper: does Repeat still have a bug? Re:(4)

2000-08-28 Thread lmecir

Hi,

being asked I try to explain my changes.

1. Thanks, Gabriele, I forgot to use one more Throw, but the
original is needed too. I used Throw attribute to make sure, that
any Return or Exit contained in code like:
f: does [ideal-looper elem indx [1 2 3] [exit]]
does what it should, ie. causes the exit of F.

2. Any-type! specification is needed, because a series in Rebol
can contain even eg. Unset! values, in which case the function
without the spec. wouldn't work.

3. For uses While anyway, so it is a shortcut. (see Source For,
but look out! It still contains the series bug I reported to
feedback.)

The corrected version:

ideal-looper: func [
[throw]
'element [word!]
'index [word!]
series [series!]
code [block!]
/local f i
] [
f: func reduce [[throw] element [any-type!] index] code
i: 1
while [i <= length? series] [f series/:i i i: i + 1]
]

Regards
Ladislav

> Hello [EMAIL PROTECTED]!
>
> On 27-Ago-00, you wrote:
>
>  l> Hi,
>
>  l> just a small change:
> [...]
>
> Perhaps you meant:
>
> ideal-looper: func [
> 'element [word!]
> 'index [word!]
> series [series!]
> code [block!]
> /local f i
> ] [
> f: func reduce [[throw] element [any-type!] index] code
> i: 1
> while [i <= length? series] [f series/:i i i: i + 1]
> ]
>
> F is the function that should have the THROW attribute.
>
> Regards,
> Gabriele.
> --
> Gabriele Santilli <[EMAIL PROTECTED]> - Amigan - REBOL
programmer
> Amiga Group Italia sez. L'Aquila --
http://www.amyresource.it/AGI/
>
>