Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] Re: Binding

From: ladislav:mecir:vslib:cz at: 19-Nov-2002 18:35

Hi Robert,
> Let's get back to my first code snippet: > > forall-records: func [list predicate action /local object][ > if any [none? list empty? predicate empty? action][return none] > > list: select list 'values > > predicate: bind/copy predicate 'list > action: bind/copy action 'list > > ; iterate through the whole list of values > ; check if the first entry satisfies the predicate > ; if so execute the action. > foreach [id object] list [ > if do predicate [do action] > ] > ] > > result: make block! [] > forall-records graph/nodes [?? object][append result id] > > And see what I think we have (please correct if wrong): > 1. result is bound to the global context
Look out! A sentence like this can have no sense at all! Look at the following example, try it at the console: sample-block: [x] append sample-block use [x] ['x] sample-block ; == [x x] Now we see, that SAMPLE-BLOCK contains two words. Can we say "SAMPLE-BLOCK is bound to the global context"? No way! Let's make sure: x: 1 get sample-block/1 ; == 1 , if we try the same for the second word, we obtain: get sample-block/2 ** Script Error: x has no value ** Near: get sample-block/2 So, can we say, that SAMPLE-BLOCK isn't bound to the global context? This looks wrong, again, because the first word clearly *is bound to the global context*. What always makes sense is a question: "To which context is bound the first word of the SAMPLE-BLOCK?", or "To which context is bound the second word of the SAMPLE-BLOCK?", because words always have a context attribute, i.e. an information, to which context they are bound.
> 2. Are OBJECT, RESULT and ID bound at all? Where? Global context?
A general answer is: every Rebol word is either unbound or it is bound to a context. Nevertheless, your question is potentially dangerous, because you didn't *exactly* specify the words you meant. If you meant something like: Is the word 'object that can be found at: foreach [id object] list [ (the second element of the block following the word 'foreach) bound to the global context? , it makes more sense, but the question is still ambiguous. If you allow me to suppose, that you are referring to the body of the FORALL-RECORDS function, I would answer no. Then I can say, that the word 'object is bound to the local context of the FOREACH-RECORD function, because of the /local object part of the function specification. If you ask me about the binding of a word 'object, that can be found in the PREDICATE block, the answer is the same, after the binding in: predicate: bind/copy predicate 'list is evaluated. Your trouble is, that this binding doesn't help you to achieve what you probably want to. If you ask me the same question about the word 'id, the correct answer is: I have got no idea!
> 3. Now the function call happens. LIST PREDICATE ACTION are set > as aliases to > - graph/nodes > - [?? object] > - [append result id]
No aliases in this case, the variables simply refer to the corresponding values (alias is a specific notion in Rebol, that doesn't apply to this situation).
> 4. action will be set to a copy of [append result id] with the words > bound to ?? > > And now I'm lost... > > Is there a graphical picture that shows how all this binding etc. stuff > works together? I said one-shot because IFAIK the binding of a word > can't be changed once set.
This is something I should explain a bit. Let's have a look at the SAMPLE-BLOCK as created above. It contains two words, which are bound to different contexts, although the words "look the same": same? sample-block/1 sample-block/2 ; == false It is pretty easy to replace the second word as follows: sample-block/2: sample-block/1 What is the result of this operation? Both words in the SAMPLE-BLOCK now have the same binding, they are bound to the same context! This means, that I changed the SAMPLE-BLOCK substantially, although I didn't try to change the binding of the second word, because I simply replaced it. I may say, that I changed SAMPLE-BLOCK, by replacing its second word. This means, that Rebol blocks are dynamic, you can change them, and you often do, while Rebol words are being replaced.
> > No such information exists. A block can contain words. Every > > word in a block has its own binding attribute. > Ok, that's something I can imagine. Is there a binding visualizer > available? I would like to see where a word is bound to, not only get > the message: It's not bound to the actual context.
I can offer you only the following means to visualize context: UNBOUND?, GLOBAL?, LOCAL?, EQUAL-BINDING?, IN-OBJECT?, which can tell you something about words you are checking. These functions are available in my Contexts.html article at www.rebolforces.com/~ladislav The trouble with the visualization is, that you can always compare the binding attributes of two words, but Rebol doesn't offer us any direct way how to visualize/get the binding of a word. Moreover "the actual context" is something, that doesn't exist, I am sorry. A proof: Let's create SAMPLE-BLOCK again as before, try to execute it and see, what is going to be the "actual context": sample-block: [x] append sample-block use [x] ['x] sample-block ; == [x x] do sample-block ** Script Error: x has no value ** Near: x As we made sure, it wasn't be the Global Context, because the second 'x in SAMPLE-BLOCK isn't global, OTOH, it couldn't have been any other context, because the first 'x is global. The only thing we may say is, that the SAMPLE-BLOCK contains equal words with different binding, IOW, the SAMPLE-BLOCK may be considered a "mixed context" block.
> > No. FOREACH binds its BODY argument appropriately. > > At the moment the body is evaluated the first time?
Correct answer is: "Before it starts to evaluate the body for the first time."
> > Unfortunately, if you use variables 'predicate and 'action, > > FOREACH binds only the variables instead of the values they represent. > > Hmm... Does this make any sense? What does is mean "binds only the > variables..." So these have no values at all?
It means this: something like bind [if do predicate [do action]] 'id will happen, but it will do nothing, because BIND will find only words: 'if 'do 'predicate, 'action, while it finds neither 'id, nor 'object. I could have written analogical simulation of FOREACH as I wrote for USE, but I guess, that you could write it too now. -L