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
[1062]
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
BrianH
2-Jan-2009
[1087]
Yeah, I forgot that append is mezzanine in R2 :(
Steeve
2-Jan-2009
[1088]
even shorter with a to-block instead of either:
foreach :word data reduce [

        :insert :tail make block! divide length? data length? to-block word] 
        to paren! body
    ]
BrianH
2-Jan-2009
[1089]
to-block has block copy overhead, but yeah.
Steeve
2-Jan-2009
[1090x2]
it's just for intialisation... ;-)
*during
btiffin
2-Jan-2009
[1092]
/me quietly files into the lecture hall and sits down as a crowd 
gathers ...
BrianH
2-Jan-2009
[1093x2]
I'll profile to see which is faster. We already have block creation 
overhead with the reduce and to-paren.
Actually, as overhead goes the to-block would be minimal in comparison 
:)
[unknown: 5]
2-Jan-2009
[1095x2]
But I would go with the more efficient code in that situation since 
it would be a mezz
We can care less how long the code is in a mezz as long as it performs 
at the optimum.
Steeve
2-Jan-2009
[1097]
Brian, i wonder what will be the overhead if map was a mezzanine 
in R3 (you should test that too) ?
BrianH
2-Jan-2009
[1098x2]
Since the profiling functions are better in R3, I am comparing the 
differences there.
The either is faster.
[unknown: 5]
2-Jan-2009
[1100x2]
pick is usually faster than either when eithers first argument is 
logic based.
which in this case it is
Steeve
2-Jan-2009
[1102]
ahah, i was thinking about pick too
BrianH
2-Jan-2009
[1103]
Yes, but we have to calculate. Let me check that too.
Steeve
2-Jan-2009
[1104]
but in that cas we have to pre-calculate length? data
[unknown: 5]
2-Jan-2009
[1105x2]
Yes, I agree, alwasy profile - never assume
at least when building mezzanines.
BrianH
2-Jan-2009
[1107]
I still want to backport the profiler to R2.
Steeve
2-Jan-2009
[1108]
length? pick reduce [[1] data] word? word
but there is an overhead too
BrianH
2-Jan-2009
[1109]
Here's the fastest version for R2:
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"
] [
    head foreach :word data reduce [

        :insert :tail make block! either word? word [length? data] [divide 
        length? data length? word] to paren! body
    ]
]
Janko
2-Jan-2009
[1110]
btw: python was recieving criticism because guido made it more and 
more awkward to use functional programming , which wasn't handeled 
that well previoulsly either. The way you added a powerful (with 
variable number of params) map that looks like native in other languages 
really speaks something about a language. Interestingly this article 
about python also mentions REBOL http://lambda-the-ultimate.org/node/2302
BrianH
2-Jan-2009
[1111]
Interesting to see how much optimization expands the code, isn't 
it?