Here's my solution to the problems I posed.
Don't peek if you are trying to do it yourself.


rebol []

comment1: {
Imperative programs that mimic basic functional operations
mostly through an intense amount of copying.
}

prepend: func [item blk] [
    result: make block! (length? blk) + 1
    insert result item
    insert next result blk
    return result
    ]

ndappend: func [b1 b2] [
    result: make block! (length? b1) + (length? b2)
    insert insert result b1 b2
    return result
    ]

filter: func [f blk][
    result: make block! (length? blk)
    foreach element blk [
        if f element [result: insert result element]
        ]
    return head result
]

comment2: {
No more imperatives.  All the following functions are
`pure' functions.
}

divisible-by?: func [num divisor] [zero? num // divisor]

prime-seive: func [blk] [
  any [all [empty? blk blk]
       prepend
           first blk
           prime-seive
               filter func [x] [not divisible-by? x first blk]
               next blk]
]

accumulate: func [f init block] [
    any [all [empty? block init]
         f first block accumulate :f init next block]
]

head-elements: func [n block] [
    any [all [zero? n []]
         prepend first block head-elements n - 1 next block]
]

enumerate-interval: func [start end] [
    any [all [start = end []]
         prepend start enumerate-interval start + 1 end]
]

enumerate-tree: func [tree] [
    any [all [not block? tree reduce [tree]]
         all [empty? tree []]
         ndappend
             enumerate-tree first tree
             enumerate-tree next tree]
]

comment3: {
    Because the programs are purely functional, we can mix and match
    the elements like so many legos.
    }

;; Task 1 compute the product of the first 10 odd numbers
task1: [accumulate :* 1
        head-elements 10
        filter :odd?
        enumerate-interval 1 20]

;; Task 2 compute the sum of all the primes under 100
task2: [accumulate :+ 0
        prime-seive
        enumerate-interval 2 100]

;; Task 3 given the following nested structure, return a block
;; of the strings present in the structure.
task3-input: [[[3 "Hello"] [6 "world"] [7 "from" 21 ["REBOL"]]]
              [[["hi"] ["this" ['aword] "is"] "a"] "test"]]

task3: [accumulate :prepend []
        filter :string?
        enumerate-tree
        task3-input]

;; Just call do task1 or do task2 or do task3 to see it work.



______________________________________________________
Get Your Private, Free Email at http://www.hotmail.com

Reply via email to