Hi.

See attached rebol file and output.

Seems promising, although it turned up 
a bug in 'repeat apparently.

I thought that bug had been squashed 
a while ago!

Probably this would be interesting 
for Elan, Sterling, Brett, Ladislav, etc.

I included the script in this mail, and as an attachment, too.

At first I tried using bind, but I couldn't figure 
out how to get what I wanted with that.
So I was pretty lucky I thought to make it work 
with word replacement, even dealing with "scoping"
properly, so far as my testing indicates to date.

-Galt

Rebol [
Title: "test looper"
File: %test-looper.r
Author: "Galt Barber"
Purpose: {
 The person who wanted to have the benefits of foreach,
 where you can refer to the element by name alone,
 and yet also be able to get the current index,
 which is not available with foreach,
 motivated me to try to write his "ideal" looper,
 which takes an index word accessible in the block.
 I am just trying to roll my own enhanced version
 of foreach.
 It seemed to work pretty well, but I did notice
 that 'repeat seems to have a bug, reminiscent
 of something I thought I remember was a problem
 reported long ago in an earlier version!
}
]

;;; hack to quickly re-load edited source
r: func [][do %test-looper.r]

rec-replace-words: func [
 b [block!]
 target [word!]
 replacement [word!]
][
 forall b [
  if word? first b [
   if (first b) = target [
    change b replacement
   ]
  ]
  if block? first b [
   rec-replace-words first b target replacement
  ]
 ]
 head b
]

ideal-looper: func [
 'element [word!]
 'index [word!]
 s [series!]
 code [block!]
 /local
 eee
 iii
 ccc
][
 ccc: copy/deep code
 rec-replace-words ccc element 'eee
 rec-replace-words ccc index   'iii
 repeat i length? s [
  iii: i
  eee: s/:i
  do ccc
 ]
]

{
Here is what the output looks like, which is wrong!
>> r
>> do z
1   h  h hello
6   none  none hello
6   none  none hello
6   none  none hello
6   none  none hello
== false

I thought I may have made a mistake, 
but then I thought to try removing 
repeat from the definition, and using 
while instead, and that did work!
see below!
}


x: "hello"

z: [  ;;; test function, usage is do z

 ideal-looper char pos x [

  embedit: func [][
   prin [pos " " char]
  ]
  embedit

  sillyobj: make object! [
   q: char
   showit: func [][prin [" " q]]
  ]
  sillyobj/showit

  prin " "
  ideal-looper char pos x [
   prin [char]
  ]

  print ""
 ]
]


{  ;;; this one works, using while instead of repeat!
   ;;; it is commented out at the moment.

ideal-looper: func [
 'element [word!]
 'index [word!]
 s [series!]
 code [block!]
 /local
 eee
 iii
 ccc
 i
][
 ccc: copy/deep code
 rec-replace-words ccc element 'eee
 rec-replace-words ccc index   'iii
 i: 0
 while [i < length? s] [
  i: i + 1
  iii: i
  eee: s/:i
  do ccc
 ]
]
}

{ ;;; here is the correct output!
>> r
>> do z
1   h  h hello
2   e  e hello
3   l  l hello
4   l  l hello
5   o  o hello
== false
>>
}


halt

test-looper.r

Reply via email to