[REBOL] Re: Embedded Object and Scope yet again...
From: joel:neely:fedex at: 11-May-2001 7:58
Hi, Larry,
Thanks for the very clear descriptions, and more than "a little"
light. (I wish I could always be so succinct! ;-)
Larry Palmiter wrote:
> Hi Joel
>
> You have been coming up with some fun examples lately. Maybe I can
> throw a little light on the topic.
>
> First the effect in your example is also obtained with this code:
>
> ob1: make object! [
> a: 1
> init: func [n [integer!]] [a: n]
> set 'ob11 make object! [
> b: 10
> init: func [n [integer!]] [b: n]
> wot: func [] [a + b]
> ]
> ]
>
> All of your tests below give the same result as when using the do []
> construct. The form above is the poor man's module capability (until
> the real thing comes along in REBOL/Core 3). Carl, myself, and many
> others often use this construction. In fact, much of VID is written
> using this mechanism.
>
Maybe in this case I was *too* succinct, as I really had a reason
for
using the DO block instead of SET, but ran out of time to cover the
distinction.
IMHO, using DO or USE is a more general mechanism, as it actually
allows you to "embed" references wherever you wish, instead of being
limited to the global level as with SET. For example:
>> o-top: make object! [
[ a: 1
[ init: func [n][a: n]
[ tunnel: none ;; placeholder
[ o-middle: make object! [
[ b: 10
[ init: func [n][b: n]
[ use [temp] [
[ temp: make object! [
[ c: 100
[ init: func [n][c: n]
[ wot: func [][a + b + c]
[ ]
[ tunnel: temp
[ ;; but we could have put
[ ;; a ref to temp anywhere!
[ ]
[ ]
[ ]
>> source o-top
o-top:
make object! [
a: 1
init: func [n][a: n]
tunnel:
make object! [
c: 100
init: func [n][c: n]
wot: func [][a + b + c]
]
o-middle:
make object! [
b: 10
init: func [n][b: n]
]
]
>> o-top/tunnel/wot
== 111
> This is very useful because it allows you to export a few interface
> functions for the object to the global context...
>
I'm suggesting that the DO or USE trick is even more useful because
it allows you to locate the ob refs or interface functions
*anywhere*
in the nested collection of namespaces under construction. Of
course,
as with any highly powerful tool, it's easy to end up constructing
logical Gordian knots that surpass all untangling!
> ... in one of the early stages the object spec block is scanned for
> all first-level set-words. A context for the object is created with
> these words bound to it.
>
> After this stage, the code in the object spec is executed, in exactly
> the same way as a block of code in the global context. The only
> difference is that those words which occurred in the spec-block as
> set-words are bound to the objects context...
>
I'd only add that the process you described above apparently is
nested
nicely when another MAKE OBJECT! ... is encountered within the
execution
of the spec block.
> This feature is also very handy. I often wrap a whole script this way:
>
> REBOL []
> ctx-my-script [
> ... all of the script code ...
> ] end ctx-my-script
>
] ; end ctx-my-script
Yes, that's my stereotypical script layout as well, although I often
end
the object with something like
....
run: func [...] [...]
] ; end of object
so that I can DO the script once within another script and re-run it
as
needed without reloading.
> ... There are some extra precautions when using vid which I will skip
> here.
>
Do tell?!?! Precautions are A Good Thing!
> There are a couple of facts about "embedded" objects which are good
> to know:
>
I guess the key point I was trying to make in my earlier post (which
I
didn't state very well) is that the *conventional* use of the term
embedded
implies the following:
If object EO is embedded in a parent object PO, then:
1) EO has visibility into the namespace of PO, and
2) PO contains a reference to EO (at the class or instance
level).
However, that simply isn't the case with REBOL. Using SET, or the
more flexible USE or DO, with the definition of PO allows us to
create
different flavors of EO in which the two characteristics above can
be
manipulated independently. In other words, we can create any (or
all)
of the following cases:
EO doesn't know words in PO PO doesn't contain a ref to EO
EO does know words in PO PO doesn't contain a ref to EO
EO doesn't know words in PO PO does contain a ref to EO
EO does know words in PO PO does contain a ref to EO
(Of course, when I speak of "knowing" words, I mean the ability to
use the words *as words in the specified context* and not just the
ability to get to their content via a path.)
Therefore, it may not be useful to talk in terms of "embedded"
objects at all. (When I was discussing the concepts in this thread
with a collegue yesterday, she observed, "This would give you a way
to implement the equivalent of 'friend' from c++", thought a moment,
and then added, "But why would anyone want to do that???" ;-)
> Your conclusion can be extended to state that it is often misleading
> to apply the concepts of object-oriented programming in trying to
> understand REBOL. REBOL's objects do not support the key concepts of
> OO. They are primarily name-spaces, and have their own distinctive
> properties relating to the underlying symbolic language. They are
> one-of-kind objects, sometimes called objects by prototype in the
> books.
>
ABSOLUTELY (and well said)! Which is why I have minor heartburn
over
the way in which existing writings (including this list) sometimes
use
well-established terms from comp sci, but use them with distinctly
non-standard meanings. That can serve to increase barriers to the
wider understanding and use of REBOL, IMHO. Let me be clear: it's
A Good Thing for REBOL to be able to introduce ideas and mechanisms
that are "out of the box" of conventional languages. We just need
to have vocabulary/definitions/explanations that make it clear when
that is happening, else we risk miscommunication and
misunderstanding.
And, to the extent that some of those "key concepts of OO" have to
do
with performance and resource utilization, I thing our community
needs
to take a close look at where the scalability and performance issues
arise, and to be reasonable in our claims about REBOL.
Thanks for clarifying the conclusion I've been hinting at but didn't
manage to express with sufficient force or clarity. Must be the
caffeine deficiency!
-jn-