r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[Rebol School] Rebol School

Steeve
2-Jan-2009
[1037]
simpler:

map: func [vars list exec][do reduce [:foreach vars list reduce [:append 
[] :do exec]]]
BrianH
2-Jan-2009
[1038]
Note that all functions of this type have bind/copy overhead of the 
code block (including FOREACH).
Steeve
2-Jan-2009
[1039x2]
>> map [x][1 2 3 4][x * x]
== [1 4 9 16]
>> map [x y][1 2 3 4][x * y]
== [2 12]
yes Brian
BrianH
2-Jan-2009
[1041]
Try to source that last version after running it a few times.
Steeve
2-Jan-2009
[1042x2]
i see nothing...
there no need of copy , it's copied by the reduce
BrianH
2-Jan-2009
[1044x2]
No, by the foreach.
It's inserted as-is by the reduce.
Steeve
2-Jan-2009
[1046]
hum ok
BrianH
2-Jan-2009
[1047]
(The teaching stuff is for Janko :)
Steeve
2-Jan-2009
[1048x3]
i thought it was strange
and finaly, we can use a single var:

map: func ['vars list exec][do reduce [:foreach to-block vars list 
reduce [:append [] :do exec]]]

>> map [x][1 2 3 4][x * x]
== [1 4 9 16]
>> map x [1 2 3 4][x * x]
== [1 4 9 16]
is it ok now Brian ?
BrianH
2-Jan-2009
[1051]
The outer do reduce is unnecessary now, but I see no problems :)
Steeve
2-Jan-2009
[1052x6]
it's only missing checking of allowed types
why it is no necessary ?
oh !
i don't see...
foreach need that trick
foreach allow only single var or a block of vars (he can't use the 
result of an evaluation)
BrianH
2-Jan-2009
[1058x2]
For that matter, the to-block is also unnecessary. Try this:

map: func ['vars list exec][foreach :vars list reduce [:append [] 
to-paren exec]]
That handles the 'do capture too :)
Steeve
2-Jan-2009
[1060x3]
argh...
right
i forget the :vars trick, damn...
Janko
2-Jan-2009
[1063]
at the end you two will have just map: func [ ] [ ] and it will work 
:)
Steeve
2-Jan-2009
[1064]
shame on me
BrianH
2-Jan-2009
[1065x2]
map: func [

    {Evaluates a block for each value(s) in a series and returns them 
    as a block.}

    'word [word! block!] "Word or block of words to set each time (local)"
    data [block!] "The series to traverse"
    body [block!] "Block to evaluate each time"
] [
    foreach :word data reduce [:append [] to-paren body]
]
Try it :)
Janko
2-Jan-2009
[1067]
I can just say wow to both
Steeve
2-Jan-2009
[1068]
that's good
BrianH
2-Jan-2009
[1069]
Add a [throw] attribute and it will be good enough for a mezzanine 
:)
Steeve
2-Jan-2009
[1070]
as i said before Janko, just some instructions, ;-)
Janko
2-Jan-2009
[1071]
very cool, this would deserve another blogpost
BrianH
2-Jan-2009
[1072]
I'll post it to DevBase in the R2 section.
Steeve
2-Jan-2009
[1073x2]
the trick about the no need of an intial copy [] when we use foreach 
is so cool
so rebolish
Janko
2-Jan-2009
[1075]
and I just wrote the code with double map instead of double foreach 
and it looks much more elegant ... no collector values no explicit 
returning then , it would be great if this would be in rebol IMHO
BrianH
2-Jan-2009
[1076]
Not too much overhead compared to native MAP. We could cut down on 
memory overhead by preallocating the destination.
Janko
2-Jan-2009
[1077]
that part [] and to-paren is something I still need to explore and 
I need to get better understanding of :word 'word .. etc
Steeve
2-Jan-2009
[1078x2]
Brian, how much would you size the preallocating ?
half of the intial serie length ?
BrianH
2-Jan-2009
[1080]
map: func [

    {Evaluates a block for each value(s) in a series and returns them 
    as a block.}

    'word [word! block!] "Word or block of words to set each time (local)"
    data [block!] "The series to traverse"
    body [block!] "Block to evaluate each time"
] [

    foreach :word data reduce [:append make block! either word? word 
    [length? data] [divide length? data length? word] to paren! body]
]
Steeve
2-Jan-2009
[1081]
humm, really accurate
BrianH
2-Jan-2009
[1082]
That expression is faster than the reallocations for large data.
Steeve
2-Jan-2009
[1083]
agree
BrianH
2-Jan-2009
[1084]
map: func [
    [throw]

    {Evaluates a block for each value(s) in a series and returns them 
    as a block.}

    'word [word! block!] "Word or block of words to set each time (local)"
    data [block!] "The series to traverse"
    body [block!] "Block to evaluate each time"
] [
    foreach :word data reduce [

        :append make block! either word? word [length? data] [divide length? 
        data length? word] to paren! body
    ]
]
[unknown: 5]
2-Jan-2009
[1085]
I would change the append to insert tail just because it is faster.
Steeve
2-Jan-2009
[1086]
yep, agreed too