[REBOL] Re: Embedded objects.
From: joel:neely:fedex at: 13-Mar-2003 13:50
Hi, Terry,
Possible alternative...
Terry Brownell wrote:
> What I'm looking for is a method to deal with Semantic Networks
> with Rebol... handling IsA and hasPart etc. Needs to deal with
> inheritance properly.
>
> Person: make object! [IsA: Organism name: none hasParts [eyes]]
> ;The hasParts is endless.
>
> Eyes: make object! [Color: none hasParts [cornea]]
>
> "Bob IsA Person" - Creates a new object called Bob, and Inherits
> all the attributes of the "Person" object, including inheritance
> of Organism object, eyes etc.
>
> BUT... if something in the eye's or organism objects change,
> these should "trickle down" to Bob...
>
I assume you want this to be controllable; if we decide that all
human eyes have retinas that should propagate, but we can set the
eye color for Bob independently of the eye color for Terry?
> So perhaps objects aren't the best approach?
>
Or at least a different way of using objects? REBOL doesn't know
inheritance
or "interface" as hard-wired concepts, but I think
that its introspective capabilities could come to the rescue.
Delegation-based
OO languages (e.g. Self and NewtonScript)
contrast with "class-based" OO languages (e.g. Smalltalk and Java)
in that stand-alone objects can be created (as with REBOL) but one
can also specify a "prototype" object (actually a whole chain of
prototype ancestry) as a place to put common/default stuff.
Here's a *VERY* quick sketch to illustrate the idea I'm talking
about.
8<--------------------------------------------------------------------
proto: make object! [
_proto: none
_dynamics: []
dynaget: func [key [string!] /local where that] [
where: self
while [found? where] [
if found? that: select where/_dynamics key [
return that
]
where: where/_proto
]
]
dynaset: func [key [string!] value [any-type!] /local here] [
either found? here: find _dynamics key [
change next here value
][
insert tail _dynamics reduce [key value]
]
value
]
instantiate: func [
statics [block!] dynamics [block!]
/local result here
][
result: make self statics
foreach [name value] dynamics [
result/dynaset name value
]
result/_proto: self
result
]
]8<--------------------------------------------------------------------
This allows the following behavior:
The prototypical person has arbitrary hair and eye color properties.
>> person: proto/instantiate [] ["hair" "brown" "eyes" "brown"]
Bob is an instance of person with his own eye color, but std hair.
>> Bob: person/instantiate [] ["eyes" "green"]
>> Bob/dynaget "eyes"
== "green"
>> Bob/dynaget "hair"
== "brown"
Phil has standard eye color, but pulled his hair out while debugging.
>> Phil: person/instantiate [] ["hair" "bald"]
>> Phil/dynaget "eyes"
== "brown"
Phil goes to a "stylist" to improve his image.
>> Phil/dynaset "hair" "wig"
== "wig"
>> Phil/dynaget "hair"
== "wig"
Bob now has a kid, who inherits most of his attributes.
>> BobJr: Bob/instantiate [] ["hair" "not yet"]
>> BobJr/dynaget "hair"
== "not yet"
>> BobJr/dynaget "eyes"
== "green"
Oops! We forgot that people are left- or right-handed! Let's use
the most common case as the default, and see what happens to Phil.
>> person/dynaset "handed" "right"
== "right"
>> Phil/dynaget "handed"
== "right"
And let's imagine that "handedness" is heredetary.
>> Bob/dynaset "handed" "left"
== "left"
>> BobJr/dynaget "handed"
== "left"
Perhaps that will point in a useful direction. Of course, more
complex hierarchies of properties could be constructed, so that
people have eyes, and eyes have color and acuity (e.g. 20/20). It
wouldn't be too hard to use composite keys for such things (but
DYNAGET and DYNASET would become more complex), to allow us to say
things such as
Bob/dynaset ["eye" "color"] "bloodshot"
or, with alternate syntax
Bob/dynaset eye/color "bloodshot"
or even construct a dialect...
-jn-
--
----------------------------------------------------------------------
Joel Neely joelDOTneelyATfedexDOTcom 901-263-4446
Counting lines of code is to software development as
counting bricks is to urban development.