Rebol Programming/apply

USAGE:

edit
APPLY func block /only 

DESCRIPTION:

edit

Apply a function to a reduced block of arguments.

APPLY is a function value.

ARGUMENTS

edit
  • func -- Function value to apply (Type: any-function)
  • block -- Block of args, reduced first (unless /only) (Type: block)

REFINEMENTS

edit
  • /only -- Use arg values as-is, do not reduce the block

(SPECIAL ATTRIBUTES)

edit
  • throw

SOURCE CODE

edit
apply: func [
    "Apply a function to a reduced block of arguments." 
    [throw] 
    func [any-function!] "Function value to apply" 
    block [block!] "Block of args, reduced first (unless /only)" 
    /only "Use arg values as-is, do not reduce the block" 
    /local words path todo noref value vars var 
    v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18 v19 v20
][
    unless only [block: reduce block] 
    words: first :func 
    vars: [
        v1 v2 v3 v4 v5 v6 v7 v8 v9 v10 v11 v12 v13 v14 v15 v16 v17 v18 v19 v20
    ] 
    path: to-path [func] 
    todo: head insert/only make block! 1 + length? block path 
    noref: false 
    while [not tail? words] [
        set/any 'value pick block 1 
        switch type?/word first words [
            word! [
                unless noref [
                    either word? get/any 'value [
                        insert tail todo to-lit-word get/any 'value
                    ] [
                        insert/only insert tail todo 'quote get/any 'value
                    ]
                ]
            ] 
            lit-word! [
                unless noref [
                    either get-word? get/any 'value [
                        either var: pick vars 1 [vars: next vars] [
                            var: use [a] copy ['a]
                        ] 
                        set var value 
                        insert tail todo to-get-word var
                    ] [
                        insert/only tail todo get/any 'value
                    ]
                ]
            ] 
            get-word! [
                unless noref [
                    either word? get/any 'value [
                        either var: pick vars 1 [vars: next vars] [
                            var: use [a] copy ['a]
                        ] 
                        set var value 
                        insert tail todo var
                    ] [
                        insert/only tail todo get/any 'value
                    ]
                ]
            ] 
            refinement! [
                unless noref: not get/any 'value [
                    insert tail path to-word first words
                ]
            ]
        ] 
        words: next words 
        block: next block
    ] 
    also do todo (
        set [func words block path todo value vars var] set head vars none
    )
]