[REBOL] Re: COLLECTing results

2003-11-28 Thread Brett Handley

Interesting versions.

I first thought of collect when I was thinking about map.  One downside of
map is that generally it requires a simple series as input, whereas looping
functions can have more flexibile iterations. Map also often needs to be
given a custom function which seems like overkill. The main thing that map
is useful for is the accumulation of the result. With collect I wanted just
the good bit of map.  Unfortunately collect cannot always replace map.

When the series of items is empty, map returns an empty block, collect will
not provide a result (not even an empty block) because it doesn't get called
at all. The result in this case is whatever the looping function returns
when it doesn't do anything Eg.

repeat i 0 collect [i]
foreach x [] collect [x]

So some application code might be needed to handle that case - unless you
pass in a pre-existing series using /initial.

So I got the good bit with collect but with an unwelcome cost!

You win some, you lose some. :-/

Regards,
Brett.

-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: COLLECTing results

2003-11-27 Thread Romano Paolo Tenca

Hi, all

this works also with foreach (not only with loop and repeat):

use [insert-only break-return res] [
 insert-only: func [series value] [insert/only series value]
 break-return: func [value] [break/return value]
 res: func [value] [func [] reduce [value]]
 collectB: func [
  {Collects block evaluations, use as body in For, Repeat, etc.}
  block [block!] "Block to evaluate."
  /initial result [series!] "Initialize the result."
  /only "Inserts into result using the Only refinement."
 ][
  initial: res reduce [none any [make result result make block! 10]]
  reduce [
   :loop 1 reduce [
:change :initial reduce [:break-return]
pick reduce [:insert :insert-only] not only
 :tail :second :initial :do block
 ;:do block could be to-paren block, to make it a little more fast
 ; but so the block is copyed
:change :initial none
   ]
   :do :initial
  ]
 ]
]

---
Ciao
Romano

-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: COLLECTing results

2003-11-26 Thread Romano Paolo Tenca

Hi all,

two more cents to let Break work as usual: :-)

use [insert-only break-return] [
 insert-only: func [series value] [insert/only series value]
 break-return: func [value] [break/return value]
 collectB: func [
  {Collects block evaluations, use as body in For, Repeat, etc.}
  block [block!] "Block to evaluate."
  /initial result [series!] "Initialize the result."
  /only "Inserts into result using the Only refinement."
 ][
  result: reduce [:break-return any [make result result make block! 10]]
  reduce [
:loop 1 reduce [
:change result :first reduce [:break-return]
 :head pick reduce [:insert :insert-only] not only
 :tail :second result :do block
:change result none
   ]
   :do result
  ]
 ]
]

ex.

probe repeat x 10 collectb [if x = 6 [break] x * 2] 

---
Ciao
Romano

-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: COLLECTing results

2003-11-26 Thread Ladislav Mecir

Forget about the last post, just an error.

-L

-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: COLLECTing results

2003-11-26 Thread Ladislav Mecir

Hi all,

two more cents to let Return work as usual:

use [insert-only] [
   insert-only: func [series value] [insert/only series value]
   collect: func [
   {Collects block evaluations, use as body in For, Repeat, etc.}
[throw]
   block [block!] "Block to evaluate."
   /initial result [series!] "Initialise the result."
   /only "Inserts into result using the Only refinement."
   ] [
   result: any [make result result make block! 10]
   reduce [
   :head pick reduce [
   :insert :insert-only
   ] not only :tail result :do block
   ]
   ]
]

-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: COLLECTing results

2003-11-26 Thread Brett Handley

> >collect: func [
> >{Collects block evaluations, use as body in For, Repeat, etc.}
...
> I am sorry I missed your contribution on the subject somehow. I like it.

I like the way it underlines how the body of a looping function has an
independent existence. It amuses me to think of it as a just-in-time
expression factory.

> My two cents changing the behaviour of the function in cases like:
>
> foreach head heads [...]
> foreach insert inserts [...]
> foreach tail tails [...]
> foreach do does [...]
>
> use [insert-only] [
...

Thanks.

Regards,
Brett.

-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: COLLECTing results

2003-11-26 Thread A J Martin

Hi, Ladislav.
Thanks for throwing in your two cents. Let's smunch my 'Collect with yours
and pick out the best survivor!

; Ladislav's:
use [insert-only] [
insert-only: func [series value] [insert/only series value]
collect: func [
{Collects block evaluations, use as body in For, Repeat, etc.}
block [block!] "Block to evaluate."
/initial result [series!] "Initialise the result."
/only "Inserts into result using the Only refinement."
] [
result: any [make result result make block! 10]
reduce [
:head pick reduce [
:insert :insert-only
] not only :tail result :do block
]
]
]

; Andrew's (just for Carl... :) ):
>> source collect
collect: func [
"Collects the results of block evaluations."
Block [block!] "The block to 'do."
/Only "Inserts the result as a series."
/Full "Don't ignore none! values."
/Initial Type [series! datatype!] "Specifies the type of the result."
][
use [Break Result Results] [
Break: func [
"Breaks out of the 'Collect."
/Return "Forces the loop function to return a Value."
Value [any-type!]
] [
system/words/break/return either Return [
Value
] [
Results
]
]
Results: any [
all [
datatype? Type
make Type 0
]
Type
copy []
]
compose/deep [
if not any [
unset? set/any 'Result do [(bind Block 'Break)]
(pick [[none? :Result] []] not Full)
] [
(pick [insert insert/only] not Only) tail Results :Result
Results
]
Results
]
]
]

Anyone else want to collide their code into the pile? :)

Andrew J Martin
Breeding the best Rebol code in this hemisphere!
ICQ: 26227169
http://www.rebol.it/Valley/
http://valley.orcon.net.nz/
http://Valley.150m.com/
-><-

-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.



[REBOL] Re: COLLECTing results

2003-11-26 Thread Ladislav Mecir

Hi Brett, Andrew, Romano et al.,

>---latest version
>
>collect: func [
>{Collects block evaluations, use as body in For, Repeat, etc.}
>block [block!] "Block to evaluate."
>/initial result [series! datatype!] "Initialise the result."
>/only "Inserts into result using Only refinement."
>] [
>if not initial [result: block!]
>result: any [all [datatype? result make result 1000] result]
>reduce ['head pick [insert insert/only] not only 'tail result 'do
>:block]
>]
>  
>

I am sorry I missed your contribution on the subject somehow. I like it. 
My two cents changing the behaviour of the function in cases like:

foreach head heads [...]
foreach insert inserts [...]
foreach tail tails [...]
foreach do does [...]

use [insert-only] [
insert-only: func [series value] [insert/only series value]
collect: func [
{Collects block evaluations, use as body in For, Repeat, etc.}
block [block!] "Block to evaluate."
/initial result [series!] "Initialise the result."
/only "Inserts into result using the Only refinement."
] [
result: any [make result result make block! 10]
reduce [
:head pick reduce [
:insert :insert-only
] not only :tail result :do block
]
]
]

-L

-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.