Hi, Russell,

only one change and you have got a non-SMC, which is preferrable

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

Results:
>> b: copy ""
== ""
>> f: func[/local a][a: b insert a "1" b]
>> f
== "1"
>> f
== "11"
>> f
== "111"

You can write it even like this, if you prefer:

f: func [] [
    if not value? 'str [str: copy ""]
    insert str "1"
]

this is non-SMC either and the results are:

>> f
== ""
>> f
== "1"
>> f
== "11"
>> f
== "111"

----- Original Message -----
From: <[EMAIL PROTECTED]>
To: <[EMAIL PROTECTED]>
Sent: Thursday, December 23, 1999 1:37 AM
Subject: [REBOL] "logical" value referencing ... Re:(10)


> Hi Elan.  This is not really a reply to your message, which I'm still
> digesting.
> I used 'reply" as a cheap way to stay on the thread.
>
> But here's a new approach to the problem of executing a function modifying
> its source.
> Look at this console stuff:
>
> >> b: ""
> == ""
> >> f: func[/local a][a: b insert a "1" b]
> >> f
> == "1"
> >> f
> == "11"
> >> f
> == "111"
> >> b
> == "111"
> >> source f
> f: func [/local a][a: b insert a "1" b]
> >>
> I started by defining a global variable, 'b,  referencing a null string.
> In the function defn I used 'b instead of a literal "".
> It's quite clear (to me) that the local, 'a, is simply another "pointer"
to
> the same data as 'b points to.
> Repeated executions of 'f show the same effect, but note that the source
for
> 'f has not been changed.
>
> Somehow, this makes me a lot more comfortable about the results with
> f: func[/local a][a: "" insert a "1" a]
> in which case repeated executions change the "" to "1" "11" etc.
>
> Russell [EMAIL PROTECTED]
> ----- Original Message -----
> From: <[EMAIL PROTECTED]>
> To: <[EMAIL PROTECTED]>
> Sent: Wednesday, December 22, 1999 1:00 PM
> Subject: [REBOL] "logical" value referencing ... Re:(9)
>
>
> > Hi Ladislav,
> >
> > At 04:01 AM 12/22/99 -0800, I wrote. And I should have been in bed fast
> > asleep. Sorry for taking up so much unnecessary bandwidth. My
imagination
> > was running wild.
> >
> > Two points I'd like to make:
> >
> > in 1. I comment on the unlikelyhood of there being a "return context".
> >
> > in 2. I provide a simple illustration for what I spent too much time on
> > earlier this morning.
> >
> > 1. I mentioned the "return context of reduce". I have no proof that
there
> > is a return context. On the contrary, it appears much more likely that
> > there is no return context. The following code certainly demonstrates
that
> > a word returned from a function is bound in the function's context and
not
> > in some return context:
> >
> > >> f: func [/local a] [ a: 4 return 'a ]
> > >> b: f
> > == a
> > >> get b
> > == 4
> >
> > As expected. Now let us modify the value of a in the function's
evaluation
> > block:
> >
> > >> set first second :f 10
> > == 10
> >
> > b's version of 'a is apparently bound the context of the function's
body,
> > since it also returns the new value:
> >
> > >> get b
> > == 10
> >
> > 2. After a few hours of sleep, I think I also came up with a much better
> > example to illustrate what I'm driving at with the literal string thing:
> >
> > Assume the following function
> > >> f: func []
>
> >      insert "" "bcd"
> >      insert make string! 0 "xyz"
> > ]
> >
> > Before we evaluate 'f, let's see what the function's body contains:
> >
> > >> token: second :f
> >
> > ;- You could use probe or mold here:
> >
> > >> forall token
>
> >      print [
> >        rejoin [mold first token ":"]
> >        mold type? first token
> >      ]
> > ]
> > insert: word!
> > "": string!
> > "bcd": string!
> > insert: word!
> > make: word!
> > string!: word!
> > 0: integer!
> > "xyz": string!
> >
> > Now we evaluate 'f:
> >
> > >> f
> > == ""
> >
> > Let's see what the function's body contains after the evaluation:
> > >> token: second :f
> >
> > ;- You could use probe or mold here:
> >
> > >> forall token
>
> >      print [
> >        rejoin [mold first token ":"]
> >        mold type? first token
> >      ]
> > ]
> > insert: word!
> > "bcd": string!
> > "bcd": string!
> > insert: word!
> > make: word!
> > string!: word!
> > 0: integer!
> > "xyz": string!
> >
> > a) The literal string retains its modification: it was "", has now
become
> > "bcd". We expected that.
> > b) Where did the string returned by make string! 0, into which we
inserted
> > "xyz" go?
> >
> > I conclude from 2 that besides - as you pointed out - 'b being assigned
to
> > a new string returned by copy each time your function was called, there
is
> > another, underlying phenomenon. That phenomenon is documented in my 'f
> > function above: The return value of make string! (or copy ""), is not
> > retained from one function call to the next. In this respect the literal
> > string and the string returned by make string! "" are different. It was
> > this difference I had been commenting on.
> >
> > The literal string continues to exist - and with it the modifications
made
> > to it. The string returned by copy is not retained and the modifications
> > made to it disappear with it.
> >
> > What determines whether a value continues to exist or not? The extent of
> > its context. The literal string is created in the global context. The
> > string returned by copy is created in the context of the function body
at
> > the time the expressions in the body are evaluated.
> >
> > My hypothesis is that as a result of being created during the time the
> > function's body is evaluated, its context is the function's evaluation
> > context. In saying that I'm assuming that a function has an evaluation
> > context. When the function ceases to be evaluated, its context ceases to
> be
> > valid and the string returned by copy is eventually garbage collected.
> >
> > When I assign a word as a reference to the string returned by copy, I
> > extend that string's context. The extent of the set-word! b: is the
> > function body's context. When the string returned by copy becomes
> > referenced by 'b, the string's context is extended. That is why you can
> > retrieve the string returned by copy after the function body has been
> > evaluated, provided you reference it with a word:
> >
> > >> f: func [/local b] [ b: copy "xyz" ]
> > >> f
> > == "xyz"
> > >> get first second :f
> > == "xyz"
> >
> > Last I remember, the REBOL Tech crew commented on the extent of words
> local
> > to the body of a function saying that the persistence of their value
> > binding between function calls is not guaranteed.
> >
> > Hope this helps,
> >
> > Elan
> >
> >
> >
> >
>
>

Reply via email to