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

World: r3wp

[Rebol School] Rebol School

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?
Janko
2-Jan-2009
[1112]
yes :)
Steeve
2-Jan-2009
[1113x2]
and [divide a b] is faster than [/ a b] ?
lol
BrianH
2-Jan-2009
[1115x2]
LENGTH? is prefix, so to use the infix / you would need parens, which 
have overhead.
I wouldn't use prefix / in a mezzanine - bad form.
Steeve
2-Jan-2009
[1117]
in R2 / works as prefix too
BrianH
2-Jan-2009
[1118]
I can't profile them for comparison, because bad form like that has 
not removed from R3, where my profiling functions are better.
Steeve
2-Jan-2009
[1119]
anyway...
BrianH
2-Jan-2009
[1120]
has not -> has
Steeve
2-Jan-2009
[1121]
it was a joke
BrianH
2-Jan-2009
[1122x2]
has not -> has been

I am bad at typing today. Let's not corrupt people in the school 
group :)
Speaking of which, good catch on the foreach bind/copy eliminating 
an explicit copy :)
Steeve
2-Jan-2009
[1124]
yeah, i think too, i will have to remember that trick next time
BrianH
2-Jan-2009
[1125x3]
Couldn't use it here efficiently, but a good trick nonetheless :)
Btw, on R3 that EITHER WORD? trick has half the overhead of the TO-BLOCK 
method.
Not much either way, but we count our miliseconds when writing mezzanines.
Steeve
2-Jan-2009
[1128x2]
even with [to block!] ?
the native one...
Janko
2-Jan-2009
[1130]
(thanks for interesting discussion and code, I have to go to sleep 
it's almost morning here), I will use map a lot :)
BrianH
2-Jan-2009
[1131x2]
Yeah. The either trick saves 20 milliseconds and some memory too, 
on my slow computer.
22 to 33 milliseconds, depending on input.
Steeve
2-Jan-2009
[1133]
it's a shame 'either has a so verbose form ;-)
BrianH
2-Jan-2009
[1134]
This isn't C :)
Steeve
2-Jan-2009
[1135x3]
nite Janko
it"s hard work to optimize such short mezzanine
but it's funny too
BrianH
2-Jan-2009
[1138]
Indeed it is both, but well worth it :)
Steeve
2-Jan-2009
[1139]
for my personnal use, i would have an option to modify the input 
serie instead of creating a new one
BrianH
2-Jan-2009
[1140x2]
The R3 FOREACH is used for that.
Still, good idea :)
Steeve
2-Jan-2009
[1142]
an /keep refinement on map ?
BrianH
2-Jan-2009
[1143]
/no-copy
Steeve
2-Jan-2009
[1144x2]
i want to see :)
i try...
BrianH
2-Jan-2009
[1146x2]
I did some testing and found that, as a general practice, the /into 
option leads to code with less overhead than the /no-copy option.
The implementation tends to be smaller too, as change-in-place code 
looks very different than fill-something code.
Steeve
2-Jan-2009
[1148]
hum, really ?
BrianH
2-Jan-2009
[1149]
Using /into for your functions leads you towards reusable buffers 
and incremental building. The /no-copy option tends towards template 
copying. I mean, as the option is used generally.
Steeve
2-Jan-2009
[1150]
do you mean by default map should do change ?
BrianH
2-Jan-2009
[1151]
Let me show you MAP with /into.
Steeve
2-Jan-2009
[1152x2]
oki
not so easy ? :)
BrianH
2-Jan-2009
[1154x3]
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"
    /into "Collect into a given series, rather than a new block"
    output [series!] "The series to output to"
] [

    unless into [output: make block! either word? word [length? data] 
    [divide length? data length? word]]

    foreach :word data reduce [:insert :tail output to paren! body
    output
]
Sorry, forgot the ] after the foreach
Sorry again, wrong semantics.
Steeve
2-Jan-2009
[1157]
hum, i see now, you don't update the input data.
BrianH
2-Jan-2009
[1158]
The /into option is supposed to have INSERT semantics, not INSERT 
TAIL.