Hi Brian

Thanks for your comments. I am aware of the small stack space for recursion
and should have added a cautionary note in my post. I found your suggestions
for generalizing the MAP function interesting, but there a few problems with
your suggested code.

According to Eric the subtypes of any-block are:

        any-block
            block
            list
            lit-path
            hash
            paren
            path
            set-path

Of these, it seems to me that the functionality of MAP would be most useful
for the list, hash, and (when nested in a block) parens types. For the
others, I guess I would like to see some simples examples of how MAP would
be useful. But your function, renamed here to MAP2, has some problems:

>> a: make list! [1 2 3]
== make list! [1 2 3]
>> map2 to-string a
** Script Error: Cannot use make on datatype! value.
** Where: out: make type? :b length?

and similarly for hash.

I also tried a block with nested parens:

>> a: [1 2 (3)]
== [1 2 (3)]

>> map2 to-string a                    ;this works, but
== ["1" "2" (3)]

>> map2/deep to-string a
** Script Error: tail expected series argument of type: series port.
** Where: insert tail series :value

Not sure whether you intended to map into the nested parens?

Some of these problems surfaced when I developing the MAP function which led
me to decide to stick to just dealing with blocks.

In my applications speed and simplicity are fairly important, and I have
found that attaining extra generality in REBOL tends to require a fair
amount of extra code to handle special cases and often incurs a noticeable
speed penalty.

In any case, MAP is a simple function and my main goal in posting it was to
illustrate the technique of passing a function with a get-word in the spec
and using the parens to handle function literals. This technique can be
applied to any function which requires a function passed as an input
parameter and IMHO results in a clean syntax for the function calls.

Your thoughts?

Larry

----- Original Message -----
From: <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Thursday, February 03, 2000 9:45 AM
Subject: [REBOL] Map Function for Nested Blocks Re:


> [EMAIL PROTECTED] wrote:
> >Here is a fast general map function which handles nested blocks
> [skip]
> >Any comments or discussion would be welcome.
> [skip]
> >===============CODE===============
> >
> >REBOL [
> >    Title: "Map Function"
> >    Date:  "24-November-1999"
> >    Author: "Larry Palmiter"
> >    Purpose: { Maps a function of one arg
> >onto a (nested) block of values.
> >    }
> >]
> >
> >map: func [
> >    "Maps a function onto elements of a block"
> >    :f               "function (use parens for literal)"
> >    b [block!]    "block of values"
> >    /deep         "maps function into nested blocks"
> >    /local out
> >][
> >    out: make block! length? b
> >    if paren? :f [f: f]
> >    foreach el b [
> >        either block? el [
> >            either deep [
> >                append/only out map/deep f el
> >            ][
> >                append/only out el
> >            ]
> >        ][
> >            append out f el
> >        ]
> >    ]
> >]
>
> All right Larry, how about this?
>
> map: func [
>     "Maps a function onto elements of a block"
>     :f [any-function! paren!] "function (use parens for literal)"
>     b [any-block!]            "block of values"
>     /deep                     "maps function into nested blocks"
>     /local out
> ][
>     out: make type? :b length? :b
>     if paren? :f [f: f]
>     foreach el :b [
>         either any-block? :el [
>             append/only :out either deep [map/deep f :el] [:el]
>         ][
>             append :out f :el
>         ]
>     ]
> ]
>
> The changes allow you to map other block types and have
> function and paren elements. It's shorter too :)
>
> You're going to have to watch that recursion though...
> REBOL generally has limited stack space, so deeply nested
> blocks or ones with circular references will cause stack
> overflows. There are techniques for eliminating recursion,
> even ones that can be used here.
>
> Brian
>

Reply via email to