Contexts of contrived blocks
[1/6] from: john::schuhr::com at: 9-May-2001 13:26
Anyone know how to explain the following?
Whenever I create a block using 'to-block
on a string, the words in the block have their
own context.. what gives?
>> block1: [element element element]
== [element element element]
>> block2: to-block "element element element"
== [element element element]
>> block3: [element element element]
== [element element element]
>> same? block1/1 block2/1
== false
>> same? block1/1 block3/1
== true
>> element: 5
== 5
>> bind block2 'element
== [element element element]
>> same? block1/1 block2/1
== true
>>
--John Schuhr
[2/6] from: joel:neely:fedex at: 9-May-2001 13:51
Hi, John,
[john--schuhr--com] wrote:
> Anyone know how to explain the following?
> Whenever I create a block using 'to-block
> on a string, the words in the block have their
> own context.. what gives?
>
...
Well, as the old gentleman said, "I don't know the answer,
but I surely do admire the question!"
This seems like it might be related to another small mystery
I've been pondering on recently. Given the code:
8<------------------------------------------------------------
#!/usr/local/bin/rebol
rebol []
make object! [
scoper: func [
argvar [integer!] recur? [logic!] /local locvar
][
locvar: argvar + 1
use [usevar] [
usevar: argvar + 2
print [argvar recur? locvar usevar]
if recur? [scoper argvar + 10 false]
print [argvar recur? locvar usevar]
]
]
scoper 1 true
]
8<------------------------------------------------------------
we get the following behavior:
8<------------------------------------------------------------
>> do %scoper.r
1 true 2 3
11 false 12 13
11 false 12 13
1 true 2 13
>>
8<------------------------------------------------------------
Now, it's clear (in some sense) *WHAT* is happening. The USE
establishes a separate context in which USEVAR is known. The
single instance of that context persists across the recursive
call, therefore the value to which USEVAR is set in the inner
call is still acessible upon return to the outer call.
What is not clear to me is *HOW* and *WHEN* that takes place.
Does the USE establish that context...
1) when the source file is loaded?
2) when SCOPER is first invoked?
3) at some other time I haven't imagined?
Option (1) seems inconsistent with what I think I understand
about how FUNC and MAKE OBJECT! do (create a new context when
executed). Option (2) leaves me wondering, "How does it know
that the recursively nested call should re-use the context
created in the outer call (instead of creating another one)
and how does it find that existing context?"
It still appears that contexts have much deep magic associated
with them!
-jn-
[3/6] from: lmecir:mbox:vol:cz at: 9-May-2001 21:50
Hi John,
you may find some answers in http://www.sweb.cz/LMecir/contexts.html
, although the above text is a little bit outdated. You will find that To
block! makes a block that contains Special Context Words.
Regards
Ladislav
[4/6] from: lmecir:mbox:vol:cz at: 9-May-2001 22:35
Hi Joel,
you wrote:
> Well, as the old gentleman said, "I don't know the answer,
> but I surely do admire the question!"
<<quoted lines omitted: 46>>
> with them!
> -jn-
as you might have guessed, 3) is correct.
See this:
nm-use: func [
{
A non-modifying use version.
Defines words local to a block.
}
[throw]
words [block! word!] {Local word(s) to the block}
body [block!] {Block to evaluate}
] [
use words copy/deep body
]
make object! [
scoper: func [
argvar [integer!] recur? [logic!] /local locvar
][
locvar: argvar + 1
nm-use [usevar] [
usevar: argvar + 2
print [argvar recur? locvar usevar]
if recur? [scoper argvar + 10 false]
print [argvar recur? locvar usevar]
]
]
scoper 1 true
]
1 true 2 3
11 false 12 13
11 false 12 13
1 true 2 3
Regards
Ladislav
[5/6] from: lmecir:mbox:vol:cz at: 9-May-2001 23:23
Joel,
I can show you another "black magic code" from my
http://www.sweb.cz/LMecir/contexts.html
f: func [level] [
make object! [
a: 2 * level
b: either zero? level [
f 1
] [none]
a: a + 1
]
]
probe f 0
make object! [
a: 0
b: unset
]
It can be repaired as follows:
make-object: function [
{
A non-modifying make object version,
returns an object with any self value
}
[throw]
blk [block!] "object spec"
/proto
prototype [object!] "object prototype"
] [result getres] [
getres: func [value] [result: :value]
blk: compose [(:getres) :self (:blk)]
error? make either proto [prototype] [object!] copy/deep blk
result
]
f: func [level] [
make-object [
a: 2 * level
b: either zero? level [
f 1
] [none]
a: a + 1
]
]
probe f 0
make object! [
a: 1
b:
make object! [
a: 3
b: none
]
]
Regards
Ladislav
[6/6] from: dmurrill:mindspring at: 10-May-2001 18:29
Hi John,
It seems that every "[ ]", "{ }" block has head/tail/ and empty place holder
(the space =" ") for each word. This space really just knows the
type! of each value, and the only way to make changes is to unset the
variable "block1" "block2" with new one or use "variable: make-string/or
block
foreach indexed value (wich really is not the value but the empty space
that proceeds it, the " " wich is the "to-type! holder"
2cents? maybe,maybe not
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted