Part #2

Use as a code modifying function:
---------------------------------

original-code7: [
        temporary: "temporary"
]
code7: copy original-code7
use [temporary]  code7
same? first original-code7 first code7

== false

You can say: "So what? The Use behaviour is normal!" The problem is, that
you can unintentionally write a Self Modifying Code with all its
disadvantages, as the next code shows:

f7: func [level] [
    use [temporary] [
        if level = 0 [
            temporary: "temporary"
            f7 level + 1
            print ["Temporary:" temporary]
        ]
    ]
]
f7 0

** Script Error: temporary has no value.
** Where: temporary

Is there a way out? Yes there is, quite simple:

f8: func [level] [
    use [temporary] copy/deep [
        if level = 0 [
            temporary: "temporary"
            f8 level + 1
            print ["Temporary:" temporary]
        ]
    ]
]
f8 0

Temporary: temporary

*The WYSIWYG rule*: If you use a modifying function don't allow it to modify
the executed code, supply it a code copy instead.

Another way to cope with the above trouble is to create a non-modifying Use,
e.g. like this:

orig-use: :use
use: func [
    "Defines words local to a block."
    words [block! word!] "Local word(s) to the block"
    body [block!] "Block to evaluate"
] [
    orig-use words copy/deep body
]

Make as a code modifying function:
-----------------------------------

f9: func [level] [
    make object! [
        a: 2 * level
        b: either zero? level [
            f9 1
        ] [
            none
        ]
        a: a + 1
    ]
]
probe f9 0

make object! [
    a: 0
    b: unset
]

Once again, Make modified its second argument, which happened to be the code
in execution. The way out is easy:

f10: func [level] [
    make object! copy/deep [
        a: 2 * level
        b: either zero? level [
            f10 1
        ] [
            none
        ]
        a: a + 1
    ]
]
probe f10 0

make object! [
    a: 1
    b:
    make object! [
        a: 3
        b: none
    ]
]

Repeat as a code modifying function:
-------------------------------------

Let's try a more complicated example. In the Set Theory the sets modelling
integer numbers 0,1,2,3,... are created as follows:

0 is modelled by empty set, which is normally denoted by 0 too
every other number is modelled as the set containing all models of integers
smaller than the modelled integer, i.e.
1 is modelled by [0]
2 is modelled by [0 [0]]
3 is modelled by [0 [0] [0 [0]]]
...

A Rebol function to do this could be written as:

f11: function [n] [result] [
    if n = 0 [
        return 0
    ]
    result: copy []
    repeat i n copy/deep [
        append/only result f11 i - 1
    ]
]

>> f11 0
== 0
>> f11 1
== [0]
>> f11 2
== [0 [0]]
>> f11 3
== [0 [0] [0 [0]]]
>> f11 4
== [0 [0] [0 [0]] [0 [0] [0 [0]]]]
>> f11 5
== [0 [0] [0 [0]] [0 [0] [0 [0]]] [0 [0] [0 [0]] [0 [0] [0 [0]]]]]

What would happen, if we allowed Repeat to modify the executed code? Let's
see:

f12: function [n] [result] [
    if n = 0 [
        return 0
    ]
    result: copy []
    repeat i n [
        append/only result f12 i - 1
    ]
]

>> f12 0
== 0
>> f12 1
== [0]
>> f12 2
== [0 [0]]
>> f12 3
== [0 [0] [0]]

Forskip is a Modifying Function too.

Next part will contain more WYSIWYG examples.

-Ladislav

-- 
To unsubscribe from this list, please send an email to
[EMAIL PROTECTED] with "unsubscribe" in the 
subject, without the quotes.

Reply via email to