Hi, Andrew,

I love peer review!  Open source works!

[EMAIL PROTECTED] wrote:
> 
> >     nondiv: func [d] [func [n] [either n // d = 0 [none] [n]]]
> 
> This could be quicker as:
>         nondiv: func [d] [func [n] [if n // d <> 0 [n]]]
>     as 'if returns 'none when the condition is false.
> 
> Also, this:
> > map: function [[catch] b [block!] f [function!] /all]
> is better as:
> 
>         map: function [[catch] b [block!] f [any-function!] /all]
> 
> so you can use native! functions as well.
> 

I've changed my copy to reflect these suggestions.  Thanks!  (I *did*
say it was the "latest" version, not the "last" version...)

>
> jn, is there a name for a generic function like:
> 
> >> something: function [B [block!] F [any-function!]] [Arg1] [
> [        Arg1: first B
> [        B: next B
> [        foreach Arg2 B [
> [                Arg1: F Arg1 Arg2
> [                ]
> [        Arg1
> [        ]
> >>
> >> something [1 2 3 4 5] :+
> == 15
> 

Well, APL called it "reduce", but that name is already taken!  ;-)
The next most common name I can recall for that kind of thing is
"accumulate", but I'm too lazy to type that all the way out.

I suggest one slight change: supplying the initial value of the
accumulator lets it function correctly even with an empty block
of values.  Normally one would use a left identity appropriate for
the  f  in use (e.g., 0 for addition, 1 for multiplication, etc.).

With this change in hand, we get:

    accumulate: func [a [any-type!] b [block!] f [any-function!]] [
        foreach c b [a: f a c]
        a
    ]

which allows us to say

    >> accumulate  0  iota 20  :+
    == 210
or
    >> accumulate  1  iota 10 :*
    == 3628800

Since the accumulation function need not be symmetric, we can also say

    >> accumulate  ""  iota 10  :append
    == "12345678910"

Of course, some functions don't have a left identity (theoretically or
practically), so it's up to the user to choose a reasonable stand-in:

    >> accumulate 9999999 iota 20  :min
    == 1
    >> accumulate -9999999 iota 20  :max
    == 20


Incidentally, there's a whole family of such so-called higher-order
functions that can be quite interesting.  The next one (I can't recall
if there's a common name for it) can be used for statistics and other
fun things:

    pair-wise: function [
        b1 [block!] b2 [block!] f [any-function!]
    ][
        r
    ][
        r: make block! min length? b1 length? b2
        loop min length? b1 length? b2 [
            append r f first b1 first b2
            b1: next b1
            b2: next b2
        ]
        r
    ]

...such as...

    >> my-scores: [4 7 16 2 12 13]
    == [4 7 16 2 12 13]
    >> your-scores: [9 5 15 1 15 15]
    == [9 5 15 1 15 15]
    >> winning-scores: pair-wise my-scores your-scores :max
    == [9 7 16 2 15 15]
    >> losing-scores: pair-wise my-scores your-scores :min
    == [4 5 15 1 12 13]
    >> spreads: pair-wise winning-scores losing-scores :subtract
    == [5 2 1 1 3 2]

Then (hold on to your Funk-and-Wagnall's) a function named after the
mathematical operation known as "convolution" can be defined as

    convolve: func [
        a [any-type!]
        b1 [block!] b2 [block!]
        fa [any-function!] fb [any-function!]
    ][
        accumulate a pair-wise b1 b2 :fb :fa
    ]

...which can do tricks such as...

    >> worst-winning-score: convolve 9999 my-scores your-scores :min :max
    == 2
    >> best-losing-score: convolve -9999 my-scores your-scores :max :min
    == 15
    >> season-grand-score: convolve 0 my-scores your-scores :+ :max
    == 64

...as well as the more mathematical...

    >> inner-product: convolve 0 my-scores your-scores :+ :*
    == 688

> 
> And if you're Grouchy, who's Sneezy, Happy, Doc,... ? :-)
> 

Well, after all the interesting and useful suggestions from the list,
I guess I'm Happy!  (Although overlooking the quadratic time complexity
of my earlier versions of  iota  and  map  made me feel Dopey!)

-jn-

-- 
; Joel Neely  [EMAIL PROTECTED]  901-263-4460  38017/HKA/9677
REBOL []  print to-string debase decompress #{
    789C0BCE0BAB4A7176CA48CAB53448740FABF474F3720BCC
    B6F4F574CFC888342AC949CE74B50500E1710C0C24000000}

Reply via email to