Hi Ladislav,
you wrote:
>can't resist to show you a few examples of Rebol code (just for fun, don't
>be afraid).
Ladislav, can't resist to show you a few comments I have regarding your
examples of REBOL code (just for fun, don't be afraid).
>Ex1:
>
>f: func [/local a][
> do func [] [
> a: ""
> ]
> insert a "1"
>]
>
>Results:
>>> f
>== ""
>>> f
>== ""
>
>interesting, isn't it?
Let me explain:
What is func? This is func
>> source func
func: func [
"Defines a user function with given spec and body." [catch]
spec [block!] {Help string (opt) followed by arg words (and opt type
and string)}
body [block!] "The body block of the function"
][
throw-on-error [make function! spec body]
]
Most importantly, in func the expression make function! spec body is
evaluated. I.e. when
do func [] [ a: ""]
is evaluated in your example, what happens is that the first, empty block
becomes make function!'s spec block and the second block [ a: "" ] becomes
make function!'s body block. Then make function! spec body is evaluated.
Now make function! does not simply reuse the spec and body blocks, make
function! creates a new copy of both. So, when "" is inserted into the
string referenced by 'a, that string is a copy of and not the original
literal string referred to in f's block.
Example:
>> a: [x y]
== [x y]
>> f: make function! [] a
>> source f
f: func [][x y] <=== [x y] is a copy of the block referenced
by 'a,
not the original block referenced by 'a
itself.
>> insert tail a 'z <=== Proof 1: We are modifying 'a
== []
>> a
== [x y z] <=== Proof 2: the block referenced by 'a
has indeed been modified
>> source f
f: func [][x y] <=== Proof 3: The body of 'f was not modified.
The function body is a copy of the block referenced by a and not the block
referenced by the original 'a itself. Therefore it did not participate in
the modification made to the original block by insert. Same thing in your
example:
Each time the expression do func [] [a: ""] is evaluated as part of the
evaluation of f's body, and that is each time 'f is evaluated,
make function! spec body
is evaluated anew, which in this case is
make function! [] [ a: "" ]
and therefore a new *copy* of the block, including a new copy of the
literal string is created. The literal string in 'f is never modified,
because 'a has been assigned to a new copy of the string, by the time
insert gets to insert something into the string referenced by 'a.
BTW, earlier releases of REBOL actually used a shallow copy and therefore
series contained in the body block were referenced and not copied, which
led to protests on the list and make function! was modified accordingly. It
now uses copy/deep.
>
>Ex2:
>a: [""]
>b: copy a
>change/only a "x"
>a
>b
>
>>> a: [""]
>== [""]
>>> b: copy a
>== [""]
>>> change/only a "x"
>== []
>>> a
>== ["x"]
>>> b
>== [""]
>You see, that by changing A we didn't change it's copy B.
>
Well, b is not a copy of 'a. b and a are two words referencing two blocks.
The block referenced by 'b is a copy of the block referenced by 'a. Why
should the copy of a block be subject to modifications made to the block
its was copied from, after copying the block was completed?
>Ex3:
>a: [""]
>b: copy a
>insert first a "x"
>a
>b
>
>Results:
>>> a: [""]
>== [""]
>>> b: copy a
>== [""]
>>> insert first a "x"
>== ""
>>> a
>== ["x"]
>>> b
>== ["x"]
>
>Now, even B looks changed. How did I manage to do it?
Because copy only copies one level of series and not multiple levels. You
need to use copy/deep, in order to copy not only the embedding block but
also the embedded string:
>> Help copy
Returns a copy of a value.
Arguments:
value -- Usually a series (series port bitset)
Refinements:
/part -- Limits to a given length or position.
range -- (number series port)
/deep -- Also copies series values within the block.
>>
Using copy/deep you get:
>> a: [""]
== [""]
>> b: copy/deep a
== [""]
>> insert first a "z"
== ""
>> a
== ["z"]
>> b
== [""]
REBOL is an interesting language, and, as I think your mailings to the list
demonstrate, it's also alot of fun to learn. I believe your emails provide
alot of interesting study material.
Keep up it up.
Elan