Hi Ladislav,

When I read your explanation on why you oppose self modifying code, I
thought, hey the guy has a good point to make. It's not all black and
white, but still...

However, the kind of code that has been identified as self-modifying and
the proposals to debunk the code both fail to live up to the reasoning you
documented when in explaining your opposition to self modifying code.

I think we urgently need a strong definition of what self-modifying code
is, unless you want to see your arguments be transformed into triviality
because of the examples provided.

I found your reply to Russell puzzling. The only difference between the
code you propose and the code Russell submitted is that you use

b: copy ""

instead of
b: ""

Now, this assignment occurs in the global context both in Russell's example
as well as in your example. You refer to Russell's code as self-modifying
whereas you claim that your code is not self-modifying. Both functions
behave exactly the same way. What do you believe to have accomplished by
adding a copy into the assignment expression? 

Since Russell's assignment b: "" occurs outside of the function's context,
In Russell's example there was no expectation that b would reference an
empty string each time his function is called. 

Ladislave, Russell was following your example, in which you had debunked
someone's code (was it Eric) by transferring Eric's:

links: []

from the local into the global context.

That was your code. You stated that by having transferred links: [] to the
global context, you had successfully transformed the "self modifying code"
into  a non-self-modifying version. Russell followed your example. Now
again your unhappy, no it has to be 

b: copy ""

not just 

b: ""

Well, Ladislav, if b: "" won't do, then neither will your previous
contribution

links: []

right?

My example function continues to stand. If using a global b: copy "" takes
care of it, than the folllowing function is not an example for self
modifying code, right?

words: [ print add write open ]
values: [ 1 "hi" ftp://ftp.rebol.com 2 %temp.txt ]

;- here i'll use your latest notation:

b: copy ""

smc?: func [] [
  forever [
    insert b pick words random 4
    append b  reduce [" " pick values random 5 " " pick values random 5]
    if error? try [do b] [print "hmmm, not so safe."]
    clear head b
  ]
]

What do believe to have gained? I think, you have just added an unnecessary
instruction to duplicate the same behavior as Russell's original. Your code
is just as much or just as little self modifying as Russell's.

In your second example you test whether str was assigned as a reference and
again set it to a copy of an empty string, if it wasn't. Again, I don't see
that you have gained anything over simply saying:

str: ""

What do you mean by self-modifying code, such that in your mind

str: ""

is self-modifying, whereas 

if not value? str [str: copy ""] 

isn't?

Elan

>
>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