At 11:37 PM 12/21/99 +0100, you wrote:
>Hi, I had a problem to find your post and respond to it (sorry).

Tell me which one you couldn't find and I'll be happy to email you a copy
off list.

>
>just want to point out some errors made by you:
>
>1) In Rebol A and B don't mean the same as you suggest: 'a and 'b, which is
>misleading.

I assume you are saying that A and B are not the same as 'a and 'b. That is
true. Nevertheless, we have had a convention here for quite some time,
whereby we use the tick mark in commenting text to distinguish the REBOL
word 'a from the english word a, as in a football. Here is an example:

date: Sun, 23 May 1999 8:33 +0000
From: [EMAIL PROTECTED]
>Consider:
>
>a: [b]
>b: [a]
>
>    'A is a word that refers to a block that holds the word 'B
>and 'B is a word that refers to a block that holds the word
>'A.  

Note that 'A is being used in the commenting text to denote the word a as in
a: [b]
and 'B is used in the commenting text to denote the REBOL word b. I prefer
to follow this convention. I hope it doesn't confuse you too much. Keep in
mind that there is a relationship between a, 'a and a:. They each reflect a
different aspect of a. a is only valid as the bound word. 'a is valid as
the unbound word, the literal word. And a: is the binding form that
constructs a valid a from an 'a. With tick, without tick or with colon are
different grammatical forms of 'a.

you wrote:
>
>2) You are inferring: "In REBOL it is a property of literal strings that
>they are global and
>therefore persistent." - Interesting. The first part of the sentence is
>wrong 

on Fri, 25 Jun 1999 17:31:10 -0700, [EMAIL PROTECTED] wrote:
>... whenever you evaluate a string you
>create a global binding.

If it's wrong, at least I'm in good company.

>and second is (almost) right. Anyhow, I do like the word "persistent",
>it's OK with me. To be exact, there are no persistent values
>in Rebol, every value is only quasi-persistent, which means, that it can be
>garbage-collected under some circumstances. 

>> word: 3
== 3
>> value? 'word
== true
>> recycle
>> word
== 3

You see that 'word survives the recycle.

But is a word a value? 

On Sun, 23 May 1999 8:33 +0000, From: [EMAIL PROTECTED] wrote:
>... even words are data, 
>so really everything is just data.  

The User's Guide says the same thing. Since words are data (whip) or values
(User's Guide), to say that "Every value is only quasi-persistent" is not
correct. Words in the global context continue to be persistent until they
are explicitly unset. And since words are data or values, there do exist
values that are not "quasi-persistent".

I think you misunderstand the point I am trying to make. I sincerely
believe that it is well worth your time to hear me out. Let's see if I can
get my point across to you:

Given the function

f: func [/local a b] [ 
  a: "" 
  b: copy "" 
  insert a "a" 
  insert b "b" 
  exit
]

the word 'a is assigned as a reference to a literal string. How? What is
the mechanism that accomplishes that assignment? It is a:, the set-word!
value of 'a.

The word 'b is assigned as a reference to the value returned by the
expression copy "". How? What is the mechanism that accomplishes that
assignment? It is the b:, the set-word! value of 'b.

The mechanism that assigns the two words 'a and 'b as references to their
respective values is the exact same mechanism in both cases. Since the
assignment mechanism is the same in both cases, the HOW of the assignment
cannot be responsible for the fact that the string referenced by 'a
accumulates values over function calls, whereas the string referenced by 'b
does not.

The reason that a's value does and b's value does not accumulate inserted
elements over function calls cannot have anything to do with how 'a and 'b
are assigned. It must have to do with WHAT they are being assigned TO.

At that point you point out that 'b is not being assigned to the same value
repeatedly. First of all, that is true. You are right in reporting that
copy returns a different string each time the function is called. No
argument from me with respect to that observation. Absolutely, 'b is being
reassigned to a new string each time. 

But, Ladislav, what does a new string mean conceptually? If you try to
express what a new string means in terms of memory allocation, you
providing a mechanism, where we are talking about a meaning. How do you
think the literal string manages to constantly grow, in order to accomodate
added data? Of course, occasionally, REBOL will have to allocate a new
memory block, and quite likely makes a copy of the old, shorter string,
into the new memory block. Even if that is not how REBOL is implemented,
REBOL could be implemented that way. I'm saying this because if allocating
new memory means that we have a new string, then the literal string
referenced by 'a is also constantly a new string. Allocated-memory-wise for
sure it constantly is a new string. Conceptually it remains the old string.

Same thing here. Copy or make string! may allocate new memory, as does the
literal string. What we need here is a conceptual explanation, why in one
case the newly allocated memory, continues to function as the old literal
string, where as in the other case the same newly allocated memory
functions as a new string.

In other words, why is the prototype string, which copy uses to create a
new string each time f is evaluated, why is that prototypical, empty string
not affected by the modifications made to the string copy returns? It could
be if REBOL was built that way. It's not automatic. But the string returned
by copy is local to the return context of copy. When b: assigns 'b as a
reference to that string, the string becomes bound to the context of 'b,
which in our example is a word local to the function. In contrast, the
literal string, which 'a is assigned to, and the literal, prototype string
used by copy, both are bound to REBOL's global context. There is no way
that modifications made to local values could affect global counterparts of
those values. This is clearly demonstrated when we use functions and use
contexts and declare words local to these contexts. Remember that words are
also data. The protoype string used by copy is not affected by
modifications made to the string returned by copy, because the literal
prototype string is globally bound, whereas the returned string is locally
bound.

BTW, two local strings can also be independent of each other. But they are
independent of each other for other reasons. I can make a copy of a local
string and use that copy as a local string and both will be independent of
each other. This has its own reason here and that has its own reason there.
The reasons may even overlap.

Even if we take it for granted that the string returned by copy does not
propagate changes done to its prototype used by copy, that observation does
not explain why the string referenced by 'a DOES accumulate elements over
function calls. Granted, 'a is assigned to the same string at each function
call, but so does copy use the same literal string at each function call.
The fact that a's literal string retains elements previously inserted into
it needs to be explained. Its behavior is not explained by the fact the b's
string comes about in a different way. Fine, so b's string comes about in a
different way.

a: make string! ""
b: copy ""

is also different, but the behavior of the two strings will be the same.
So, if the literal string behaves as it does, there must be a reason for
that. A reason that has to do with what literal strings are.

Why does the literal string not lose its values from one function call to
the next? Because literal strings are bound to REBOL's global context, they
retain modifications executed on them even in a local context, whereas
because the string returned by copy is a local to copy's return context and
- at the point of assignment becomes bound to the word's context, therefore
the literal string used by copy is not affected by modifications done to
the string returned by copy. The modification done to that string are local
to the function and not affective in REBOL's global context and therefore
they cannot affect the globally bound literal string.

Let me clearly demonstrate and prove what I am saying:

The behavior described above is not specific to literal strings. A literal
block also retains its values:

g: func [] [ insert [] 1 ]

>> g
== []
>> g
== [1]
>> g
== [1 1]
>> g
== [1 1 1]

Here we have no referencing words. Just the naked literal block. The
literal block in the function 'g accumulated the 1's that were inserted
into it within the function. But the literal block is not being referenced
by a word. How come it retains the 1's being inserted? Because it does not
need to be referenced by a word. Perhaps that is due to the fact that it is
contained in a block (the function's expression block) which in turn as
part of the function is referenced by the word 'g? Let's see:

>> a: [ insert [] 1 ]
== [insert [] 1]
>> head first reduce a
== [1]
>> a
== [insert [1] 1]

First the embedded block was empty, then we inserted 1 into the embedded
block by reducing the surrounding block, and as a result the empty block
was populated with the integer 1. 

Ok. Let's replace the embedded block by an embedded string:

>> a: [ insert make string! 0 "12345" ]
== [insert make string! 0 "12345"]
>> head first reduce a
== "12345"

Reduce evaluated the expression in the block. The result of the evaluation
of the expression was that a string was created and the string "12345" was
inserted into that string, as demonstrated by the value returned by head
first reduce a. 

Just as the embedded block in the previous example retained the integer 1,
we now expect the newly created string to have been accumulated in the
surrounding block. This is what we expect the block should now look like:

["12345" insert make string! 0 "12345"]

The first element, "12345" should be the result of the evaluation of the
expression: insert make string! 0 "12345". A new string was made. It must
be there. Is it there?

When we look at the block referenced by a after we reduced it, we find:
>> a
== [insert make string! 0 "12345"]

The newly created string is missing. Why did it disappear? Why did the
embedded block in the previous example retain the integer 1 after the block
was reduced, whereas the result of reducing the block in our last example
did not retain the string created as a result of reducing the block? Why is
one change preserved whereas the other change disappears?

This has nothing to do with 'b being assigned new strings each time the
function is evaluated. There is no 'b, there is no assignment. Let us see
what happens when we replace the expression make string! 0 by a literal
embedded string:

>> a: [ insert "" "12345" ]
== [insert "" "12345"]
>> head first reduce a
== "12345"

Ok, same result we just got when we reduced the block containing the
expression make string! 0. But here, as in the previous example, the
modification is made to the block RETURNED by reduce. Based on our most
recent experience, when we used make string! 0, reducing the block should
not have modified the block PASSED to reduce. Let's see:

>> a
== [insert "12345" "12345"]

Oh, oh. The original block contained the expresson insert "" "12345", the
same block now contains the expression insert "12345" "12345". The
previously empty string, "", now contains the inserted string "12345". The
effect of reducing the block did not manifest itself exclusively in the
block RETURNED by reduce, it also affected the string in the block that was
BEING reduced, the block PASSED to reduce!

There is a difference between literal strings and strings returned by make
string! or copy "", a difference which has nothing to do with repeatedly
assigning the word 'b to a new copy of an empty string.

Here there were no new assignments of words as references to strings. In
both cases reduce returned a new block, which manifested the result of
evaluating the expressions contained in the block. However, whereas reduce
did NOT affect the contents of the PASSED block when we used make string!
0, when we used a LITERAL string the contents of the PASSED block WERE
modified.

What's the point? When make string! 0 was evaluated, the string that was
created during the reduction of the block was local to the block returned
by reduce. 

In contrast the LITERAL string in the block returned by reduce is NOT LOCAL
to that block. It is the same GLOBAL string that is embedded in the block
we PASSED TO reduce. Therefore, the modifications that affected the string
in the block RETURNED also, simultaneously affected the string embedded in
the block PASSED. 

A value that is not local to a local context, the local context of the
block passed to reduce and the local context of the block returned by
reduce, such a value is bound to the global context.

So, make string! 0, or copy "", returns a string that is local. It is local
to the return context of make or copy respectively. In contrast a literal
string is bound to REBOL's global context. It is global in that it retains
modifications made to it beyond the local context within which that
modification occurs.

So, Ladislav, yes, 'b was re-assigned to a new string returned by copy each
time the function was evaluated. And because that string was local,
modifications made to the returned string did not affect the prototypical,
literal, global empty string passed to copy. And therefore, because the
string returned by copy was local to copy's return context, whereas the
string passed to copy was a globally bound string, it is therefore that the
modifications made to the returned string did not affect the prototypical
string and, on the second evaluation of the function, copy continued to
find an empty string as its prototype. 

On the other hand it is because 'a referenced a literal string, which is
bound in REBOL's global context and therefore retains its changes between
function calls quite on its own, that that literal string accumulated
values that were inserted into it.

Am I starting to make sense to you?

Take Care,

Elan

Reply via email to