r3wp [groups: 83 posts: 189283]
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

World: r3wp

[Core] Discuss core issues

Dockimbel
12-Aug-2011
[2033x2]
You're right, I missed your point about recursion. As I understand 
it, the behavior you're observing is caused by function context values 
being pushed on stack on recursive calls, as showed by Ladislav's 
simulation (http://www.rebol.net/wiki/Bindology#Model_of_function_evaluation
). So the value of 'v word bound to 'f context, inserted in a block 
and evaluated later, depends on the "current" level of 'f function 
recursion.
as showed
 => "as shown"
Geomol
12-Aug-2011
[2035]
Yes, you got it. Thanks!

I'm not saying, this is a bug, I'm just wondering about the behaviour. 
It might actaully be seen as a benefit, as this gives us 2 different 
behaviours depending on, if we use recursive calls or call another 
function (which can then be recursive), like the G function in my 
original examples.
Dockimbel
12-Aug-2011
[2036]
It looks like a side-efffect of the implementation, I do not think 
that this behavior was planned as a feature. I guess some recursive 
algorithms could benefit from it, but I fear it can quickly lead 
to code that is hard to maintain.
Geomol
12-Aug-2011
[2037x2]
Yeah, that's also my concern.
Are there other high level languages (or maybe interpreted languages), 
that can put references to variables into tables? I took a look at 
Python and Lua, but I don't think, they can.
Dockimbel
12-Aug-2011
[2039]
I don't remember seeing such property in another language. What about 
io or self?
Ladislav
12-Aug-2011
[2040x4]
I can't get my head around, what's going on internally.

 - I do not know if you already got your head around or not, but the 
 behaviour is exaplained by the simulation.
Anyway, the explanation is as follows: since the function F is called 
twice, it creates two objects having the attribute A. While the first 
object has got the attribute A set to "ok" initially, it ends up 
having the attribute A set to the "bug!" string before the F is called 
for the second time. After the second call to the function F occurs, 
the function does not "see" the first object's A attribute when setting 
the A using the a: "ok" expression.
Regarding "There are several versions of V, one for each call to 
F" - the fact is, that there is only one version of the word 'V, 
not "several". If you wanted to have "several versions of V" you 
could have used a closure, as is demonstrated later.
http://www.rebol.net/wiki/Bindology#Computed_binding_functions_.28Closures.29
Geomol
12-Aug-2011
[2044]
About the bug thing. When returning to the first object, A is set 
again to "OK" in the line just after the call to F:
	f 2
	a: "OK"
]
...


That should be the A in the first object, shouldn't it? So I can't 
figure out the internals giving the result, we see.
Ladislav
12-Aug-2011
[2045]
That should be the A in the first object, shouldn't it?

 - it certainly is not the first object, that is why you see the "bug!"
Geomol
12-Aug-2011
[2046]
To me, it's like if the following code would return "bug":

>> o: context [a: "bug" a: "ok"]
>> get in o 'a
== "ok"
Ladislav
12-Aug-2011
[2047]
The fact is, that in the article, there is a simulation fully explaining 
what is going on. And, moreover, the MAKE OBJECT! [...] binds the 
[...] block, which is a modification, that does not get "reversed". 
And, moreover, there is a code that shows how to "cure" it.
Geomol
12-Aug-2011
[2048]
Anyway, such deep bug in REBOL is worrying.
Ladislav
12-Aug-2011
[2049x2]
such deep bug in REBOL
 is not a bug in REBOL at all
it is just a bug in the example code
Geomol
12-Aug-2011
[2051]
wow
Ladislav
12-Aug-2011
[2052]
There is the code that shows how it should have been written
Geomol
12-Aug-2011
[2053]
If this is not a bug in REBOL, then there is a bigger problem, as 
I see it. The language is way too complicated.
Ladislav
12-Aug-2011
[2054x3]
Actually, it is not. The only thing you should know is, that the

    MAKE OBJECT! [...]


expression modifies the [...] block. If you want to use the block 
as code (in a recursive, or otherwise repetitive manner), you need 
to realize that.
And, there is an easy remedy, the expression:

    MAKE OBJECT! copy/deep [...]

does not modify the [...], so it is OK
if you want the things to become simple, you can just define a new 
non-modifying function and you are safe.
Geomol
12-Aug-2011
[2057]
Nah, better start over and make a new language, that is simple in 
the first place.
Ladislav
12-Aug-2011
[2058x4]
That does not make sense in this case, when what you need is just 
a function like:

safe-object: func [blk [block!]] [make object! copy/deep blk]

and you are done
So, this is not about the language, this is just about a different 
function to use.
It is obvious, that using the SAFE-OBJECT function you are safe, 
plain and simple.
But, of course, it looks easier (at the first sight) to push somebody 
to define a new language for you. I can guarantee you, that no matter 
how hard you push, there will always be something you find "complicated".
Gabriele
13-Aug-2011
[2062]
Geomol... what is your definition of simple? Python?

REBOL's model is very simple, if you understand it. :-)
Geomol
14-Aug-2011
[2063]
Gabriele, I guess, you're joking, but to answer your question: it 
would be simple, if the above function returning "bug!" would instead 
return "ok" like this function:

g: does [
	get in make object! [
		a: "ok"
		a: "bug!"
		get in make object! [
			a: "ok"
		] 'a
		a: "ok"
	] 'a
]

>> g
== "ok"
Gabriele
14-Aug-2011
[2064x2]
It would be simple because it fits your model better? Or because 
the model to describe that behavior would be simpler?


I'm asking because the latter is certainly false, especially if you 
want to preserve things like dialecting.
In REBOL, literal blocks are just literal blocks. If you modify them... 
they are modified. Binding a block modifies the words inside the 
block, ie. it modifies the block. It can't get any simpler than this.


Now, you may argue that MAKE OBJECT! should bind/copy the block instead; 
the reason it does not is purely performance (as 99.99% of the time 
the copy is not necessary). In that 0.01% of cases where you need 
it... you just write MAKE OBJECT! COPY/DEEP [...] instead.
Geomol
14-Aug-2011
[2066]
Our understanding of "simple" is different, or I would go as far 
as saying, your understanding of "simple" is twisted.


It would be simple because it fits your model better? Or because 
the model to describe that behavior would be simpler?
I'm asking 
because the latter is certainly false, especially if you want to 
preserve things like dialecting.


I would say, the model giving my suggested behaviour is simpler. 
If you disagree, then look at the code again. 'a' is set to "ok" 
again, after the recursive call. A model giving some other result 
is not simple. If you think, it is, then describe that model in a 
simple way! A simple model should also be simple to describe, right?
Ladislav
14-Aug-2011
[2067x7]
Geomol, the behaviour of self modifying code is never simple to understand, 
that is where Gabriele and I can agree with you.


In contrast to that, what both Gabriele and I call simple is the 
suggestion to use the SAFE-OBJECT [...] (or MAKE OBJECT! COPY/DEEP 
[...]) non-modifying expression, which, indeed, exhibits the simple 
behaviour.
On the other hand, the behaviour of self-modifying code is not as 
terribly complicated as you are trying to suggest, since:


* Taking into account the modifying properties of the MAKE OBJECT! 
[...] expression I wanted to write a relatively simple example to 
show what bug you may run into when ignoring the modifications.

* I succeeded immediately without actually running into such a case 
in practice, i.e. I did not have to hit my head to the wall first 
to run into this.

* It sufficed to think of a case when the modification would twist 
the block behaviour relatively to what you might find simple.

* Since I did it without actually running into it, I am fully entitled 
to saying, that the behaviour is actually transparent to me.
(and, I guess, the same applies to Gabriele as well)
And, one more note to the ability to modify the code:


* since the REBOL's ability to modify the code blocks (and, create 
self-modifying code this way) lies at the heart of REBOL's reflexivity, 
which allows to define and process unlimited amount of REBOL dialects, 
I am strictly *for* keeping this feature in REBOL.
As demonstrated above, it is easy (simple) to avoid *undesired* code 
modifications anyway.
BTW, did you already succeed to get your head around the difference 
between a function and a closure?
;-)
Geomol
14-Aug-2011
[2074x2]
Yeah, I have a reasonable understanding of what a function and a 
closure is, and if I remember correctly, R2 functions are neither 
... or are a combination.


Back to the self-modifying code when making objects. Look at this:

>> b: [print 'ok a: 1]
== [print 'ok a: 1]
>> o: make object! b
ok
>> ? b
B is a block of value: [print 'ok a: 1]


Since making the object doesn't change the block, do you still think, 
the above bug isn't a bug in REBOL?
* since the REBOL's ability to modify the code blocks (and, create 
self-modifying code this way) lies at the heart of REBOL's reflexivity, 
which allows to define and process unlimited amount of REBOL dialects, 
I am strictly *for* keeping this feature in REBOL.


Gettin' rid of this bug doesn't mean, we should or would sacrifice 
self-modifying code, so I don't understand, why you bring this argument 
up.
Ladislav
14-Aug-2011
[2076x5]
Since making the object doesn't change the block

 - it does, I leave it as an exercise for the reader to find out how
Gettin' rid of this bug doesn't mean, we should or would sacrifice 
self-modifying code

 - actually, you get rid of the bug by not writing a self-modifying 
 code. Unless you forbid me to write a self-modifying code, I can 
 always recreate the bug.
(one way or the other)
I have a reasonable understanding of what a function and a closure 
is, and if I remember correctly, R2 functions are neither ... or 
are a combination

 - this looks quite superficial. Seems to me you did not read the 
 suggested section of the article and have actually no idea.
(the general definition does not apply to REBOL closures, I am not 
sure I picked a correct name, that may be my mistake)
Geomol
14-Aug-2011
[2081x2]
:) ok

Since making the object doesn't change the block" - it does, I leave 
it as an exercise for the reader to find out how"

>> b: [print 'ok a: 1]
== [print 'ok a: 1]
>> b2: copy b
== [print 'ok a: 1]
>> make object! b
ok
>> b = b2
== true
>> b == b2
== true


b and b2 are clearly not the same, so I won't test that. Now, before 
you suggest a fourth type of equal test, maybe you should reconsider 
your statement, that this is a simple part of the language? And that 
my claim of this being a bug has something to it.


(I know, the difference lies in the binding, so you don't have to 
make any 'smart-ass' points about that, just take a step back and 
look at all this again. That's all I'm asking.)