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