Hi Ladislav,

you wrote:
>The use of self-modifying code is not considered as  advisable (not by me,
>it's an old rule). Every programmer should take care, if his code is clean
>from such effects.

Indeed it is an old rule. I wonder what reasoning backs it up? 

There are many - often contradictory - rules about programming. You can
probably find an authoritative statement about pretty much every aspect of
programming, both encouraging and discouraging the use of certain techniques. 

I am wary of perpetuating myths, by disregarding the pro and con arguments.
A rational decision should be based on insight and not rely solely on
"accepted truths".

I am especially suspicious of rules that are formulated as absolutes as the
above one. Often, there are circumstances, under which a rule makes sense,
whereas other circumstances may promote deviating from a rule. Intelligence
is the capability that allows us to identify, which rules apply given a set
of circumstances. It is based on the our understanding of what arguments
promote or discourage the application of a rule.

Is there more information available in support and opposing this "old rule"?

you wrote:
>The non Self-Modifying code:
>
>block: [
>    a: "-1"
>    counting-func: func [/local counter] [
>        counter: 1 + to-integer a
>        a: to-string counter
>    ]
>]
>do block

[snipped documentation of behavior.]

>How can I be so sure that this code isn't Self-Modifying? I am not. By can
>make sure:
[snipped sourcing the block.]
>>> print block
>-1 ?function?
>
>So, we can see, that even in this case block got modified. Who is guilty?
>(Do).

No, 'print is guilty. Are you aware that print does a reduce on blocks?

Look:
>> do block
>> get first block
== "-1"


>> counting-func
== "0"
>> get first block
== "0"


>> reduce block
== ["-1" func [/local counter][
    counter: 1 + to-integer a
    a: to-string counter
]]
>> get first block
== "-1"

Reduce, as you know, is similar to do, in that it evaluates the expressions
contained in a block:

Two examples:
>> reduce [a: 1]
== [1]

>> type? first [func [] [return 1]]
== word!
>> type? first reduce [func [] [return 1]]
== function!

Since print reduces a block, when you print the block, you are setting 'a
to the value "-1" - as a side-effect of printing. 

That is why no matter how often you have evaluated the function
counting-func, which modifies your global word 'a, whenever you 'print the
'block, as part of what 'print does, the global word 'a will be assigned
the string "-1".

>> do block

>> counting-func
== "0"
>> get first block
== "0"

>> print block
-1 ?function?

>> get first block
== "-1"


Hope this helps,

Elan

Reply via email to