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

World: r3wp

[Core] Discuss core issues

Robert
27-Feb-2005
[495]
As you said: file-part, dir-part
JaimeVargas
1-Mar-2005
[496x4]
Does rebol has some form of inheritance? Well not according to the 
docs. But when intializing within context there seems to be an initialization 
chain that look like a bit like inheritance to me.
o: context [ 
    a: 0 
    b: none 
    o1: context [
        a: 1 
        c: 3 
        set 'b 2 
        o2: context [
            set 'b 4 
            set 'c 5 
            set 'd 6
        ] 
    ] 
]
O is an object of value: 
   a               integer!  0 
   b               integer!  4 
   o1              object!   [a c o2] 

>> ? o/o1
O/O1 is an object of value: 
   a               integer!  1 
   c               integer!  5 
   o2              object!   [] 

>> ? o/o1/o2
O/O1/O2 is an object of value: 

>> d
== 6
The slots got the last value set by the child context of each parent.
Ammon
2-Mar-2005
[500]
Uhm...  But that isn't inheritance, it is simply context.
Anton
2-Mar-2005
[501x2]
o: context [
A new object begins to be created.
Ammon
2-Mar-2005
[503]
I should say, it is context that allows sub-contexts.  It's more 
of a hierarchy...
Anton
2-Mar-2005
[504x3]
The top-level of the spec block is scanned for set-words; in this 
case, there are three ( a:  b:  o1: ). These three words are added 
to the newly forming object. The spec block is now scanned *deeply* 
and where one of those three words ( a b o1 ) is found, they are 
bound to the object.
Using  "set notation" (eg.  context [ set 'b 4 ] )  does not attach 
'b to the object. It must be a set-word (eg.  context [ b: 4 ] )
So, in the creation of your object o2, 'b and 'c are found to have 
been previously bound to o and o1, respectively. Setting them does 
not modify the binding. 'd was found not to be bound to anything 
so it was set in the global context. (people use this last trick 
to "export" functions or values from a context).
Brett
2-Mar-2005
[507x5]
Rebol's elegant use of context is really powerful.
; Jaime try comparing your example with this:
o: context [a: 0 b: o1: none]
o/o1: context bind [a: 1 c: 3 set 'b 2 o2: none] in o 'a

o/o1/o2: context bind (bind [set 'b 4 set 'c 5 set 'd 6] in o 'a) 
in o/o1 'a
; I think you'll find they are equivalent.
Imagine context as a "colour" of a word (btw would be nice to see 
in an ide).

Then, in your example, the first context function changes the colour 
of all the a,b and o1 words to "red" say.

Then the next inside context function changes a,c, and o2 to green.

And finally the inmost context function doesn't get to change anything 
because there are no set-words to process - if there were they would 
have been made blue of course ;-)
By my analogy, the b, c, d of the inmost block would have the colours 
red, green and black - black being the global context.

Normally, all words start as black when they are loaded into REBOL.
Colourful analogy don't u think?
I don't think there is a hierarchy of contexts.

In Jaime's example there is a hierarchy of blocks (nested). As evaluation 
proceeds, the words in those blocks get "painted" different colours. 
That's why my code using bind ends up with the same binding of words 
even though I didn't have the same hierarchy of blocks  - I simulated 
the same order of binding.
JaimeVargas
2-Mar-2005
[512]
Brett I aggre that there is hierarchy of blocks. I guess what I was 
getting at is that rebol implements context  internally using some 
sort OO technique to keep track of the assignments. In this case 
the OO technique is  lookup chain.
Anton
2-Mar-2005
[513]
I think that is correct, remembering a discussion with Carl Sassenrath 
a long time ago.
Ammon
2-Mar-2005
[514]
Brett, well said.  That is what I was trying to say but couldn't 
put it to words for some reason...
Volker
2-Mar-2005
[515x4]
Not a chain, a "compiletime" replacement.
red: context[a: 'red blue: context[a: 'blue]]
'a is first bound to 'global, then to 'red, then to 'blue (going 
from outer to inner block). then it stays blue until you bind it 
again.
(the 'a in [a: 'blue] not the others. better remove them..
 red: context[ blue: context[a: 'blue] ]
Ammon
2-Mar-2005
[519]
Yes, but you're using a set-word! which doesn't properly demonstrate 
what we are talking about.  Change [a: 'blue] to [set a 'blue] and 
then you have it. ;-)
Volker
2-Mar-2005
[520x3]
What did i not get? Jaime: "that rebol implements context  internally 
using some sort OO technique to keep track of the assignments. In 
this case the OO technique is  lookup chain." in your case 'a is 
never recolored.
and for demo my first example was right. trying again:

loading: all 'a in [red: context[a: 'red blue: context[a: 'blue]] 
] are colored global

creating outer context: all 'a in [a: 'red blue: context[a: 'blue]] 
are colored red
creating inner context: all 'a in [a: 'blue] are colored blue.
now all 'a have their right colors :)
lookup-chain
 sounds like runtime-searching to me.
Ammon
2-Mar-2005
[523x4]
1. It has to be happening during runtime there is no compiling.  
2. I don't understand your second attempt there.

3. If you use a set-word in a context then that word becomes part 
of that context.  If you use SET then it reverts to the context's 
 "parent context" or the context in which the context itself is defined. 
 If the word exists in that context then it is set there, if not 
then it grabs that context's parent until it has made it to the global 
or top level.  If the word doesn't exist globally then it is created...
I missed a step there...  If you use SET then it first checks the 
context of the word if the word has a context then it attempts to 
assign the word there.  If the word doesn't have a context then it 
uses the current context.
It may or may not actually be checking to see if the word exists 
but the effect is the same...
I keep trying to explain this but haven't really found the right 
words for it YET...
Brett
2-Mar-2005
[527x8]
Jaime, yes I agree that rebol implements context internally. You 
mention the idea of a lookup chain or initialisation chain, if you 
mean that such a chain maintains some relationship between your ancestor 
and descendent objects then no I don't think so.  Once the context 
function has finished being evaluated then the idea of ancestor and 
descendent is finished. The two objects stand equally at the same 
level, no relationship between them exists even internally, except 
that you might consider them to be associated because they share 
some function value or other values.


As Anton has said, words know their context. I tried to put it visually 
by saying they have a colour and that colour identifies their context.
I guess what I'm saying is that the idea of a lookup chain is not 
needed to understand rebol. We only need to know that a rebol word 
is a member of some context and that association between a word and 
its context can be changed by functions like Context, Bind, Func 
and Use when they are evaluated.
Have a look at the In function. The In function returns a word. The 
word that it returns still has its original association with the 
object context.
name: "black"
red-ctx: context [
	name: "red"
	green-ctx: context [
		name: "green"
		blue-ctx: context [name: "blue"]
	]
]
names: reduce [
	name
	in red-ctx 'name
	in red-ctx/green-ctx 'name
	in red-ctx/green-ctx/blue-ctx 'name
]


; Names is now a block that contains four words of different colour 
(context binding)
probe reduce names
For fun this next example is totally equivalent.
name: "black"
red-ctx: context [name: "red"]
green-ctx: context [name: "green"]
blue-ctx: context [name: "blue"]
names: reduce [
	name
	in red-ctx 'name
	in green-ctx 'name
	in blue-ctx 'name
]


; Names is now a block that contains four words of different colour 
(context binding)
probe reduce names
Except of course for that fact that red-ctx does not have a field 
green-ctx!
Ammon. On your point 3 above. "If the word exists in that context 
then it is set there, if not then it grabs that context's parent 
until it has made it to the global or top level."  No, it doesn't 
work this way. There does not need to be runtime searching.

It is more like this...

Look at my nested context example, and focus just on the 'name words.

(1) When the first context function is encounted during evaluation, 
it has a single argument a block - which happens to contain 5 values. 
A set-word, a string, a set-word a word and a block.

(2) Now when this first context function is evaluated it creates 
a new context, and binds to this context the all 'name words it can 
find in the block and nested blocks. To visualise this imagine all 
the 'name words including within the nested blocks have just changed 
Red.

(3) After this colouring of the words, the block is evaluated (as 
in DO) so that at some point the second reference to the Context 
function is evaluated.

(4) Like the first, it colours the name words in its block and nested 
blocks - let's say to green.
(5) The final level is blue of course.

(6) By the time all evaluation is finished the 'name words have the 
appropriate bindings (colours). Conceptually, maybe even actually, 
the innermost 'name word has had its binding (colour) changed three 
times, the second level one twice, and the highest once.


In this way there does not need to be any runtime searching for "parent" 
contexts, because the words themselves maintain the references to 
the appropriate contexts. The Set function does not need to search 
it can see the binding (colour) already.
Ammon
2-Mar-2005
[535x2]
Heh, I guess I'm hard to understand. ;~>
This particular subject has come up a number of times since I started 
playing with REBOL in 2000 but for some reason I can't seem to make 
the point that I am attempting to make everytime it comes up.  I 
think I'll leave it alone now...
Brett
2-Mar-2005
[537]
lol - the context of our understanding keeps changing ;-)
Ammon
2-Mar-2005
[538]
Something like that. ;-)
Volker
2-Mar-2005
[539]
Ammon: "1. It has to be happening during runtime there is no compiling."
load-time and loop-time then? ;)

ammon: "3. If you use a set-word in a context then that word becomes 
part of that context.  If you use SET then it reverts to the context's 
 "parent context" or the context in which the context itself is defined."

Thats the important point: there is no reverting :) and so there 
is no need to keep track of parent-contexts.which is quite clever 
:)
DideC
3-Mar-2005
[540]
What is the quickest way to transform this :
	[ ["a" 11 #toto] ["b" 28 #titi] ["c" 3 #pim] ]
into this :
	[ "a" 11 #toto "b" 28 #titi "c" 3 #pim ]
???
Sunanda
3-Mar-2005
[541]
Fastest, I don;t know.  But this works:
xx: [ ["a" 11 #toto] ["b" 28 #titi] ["c" 3 #pim] ]
loop length? xx  [append xx xx/1 remove xx]
 head xx
== ["a" 11 #toto "b" 28 #titi "c" 3 #pim]
Geomol
3-Mar-2005
[542x2]
Close to being fastest:
xx: [ ["a" 11 #toto] ["b" 28 #titi] ["c" 3 #pim] ]
x: copy []
loop length? xx [insert tail x xx/1 xx: next xx]
x
A time function to measure the speed of code:

time: func [:f /local t0] [t0: now/time/precise do f now/time/precise 
- t0]

Now you can do e.g.:
time [loop 40000 [
xx: [ ["a" 11 #toto] ["b" 28 #titi] ["c" 3 #pim] ]
x: copy []
loop length? xx [insert tail x xx/1 xx: next xx]
]]
sqlab
3-Mar-2005
[544]
foreach b  [ ["a" 11 #toto] ["b" 28 #titi] ["c" 3 #pim] ] [append 
 [] b ]

If you want faster execution you should initialize the block [] outside 
the loop