Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Object spec

27 views
Skip to first unread message

Sam Vilain

unread,
Mar 4, 2003, 5:58:56 AM3/4/03
to Dan Sugalski, perl6-l...@perl.org, poop-...@lists.sourceforge.net
Dan,

Sorry if I'm flogging a dead horse, but I just caught this call via the
summarizer.

> Okay, here's another shot at the semantics for objects [for perl 6]. If
> folks,
> especially non-perl folks, would look this over and chime in, I'd
> much appreciate it.
> Objects have (all optional):
> *) Properties
> *) Methods
> *) Attributes

Add to that:
*) A superclass (obviously, but I consider it to be the same level as
Properties, Methods and Attributes.)
*) Associations, eg in UML.
*) a set of Interfaces (similar to multiple inheritance; a way of
grouping methods associated with a class for another to implement).
eg, in Java and IDL.

Associations are similar to special types of attributes, that are typically
represented in Perl 5 by a collection, such as a hash, array or set -
depending on whether the association is keyed, ordered or unordered.

Associations may be *one way* - in which case the referred objects do not
have a way of referring to the objects that contain them for that
particular association. ie, like all of Perl 5's references and
collections.

They may be *two way* - in which case referred objects receive a
`back-reference', which is another container that is the symmetric
opposite of the first association. Two-way associations belong to both
classes. Adding Object A to B.association is the same as adding B to
A.backref. Tangram does something like this with its `back-references',
as does an experimental version of the object prototyping system I have in
the works.

Associations may have *mutliplicity* on BOTH ends. That is, one to many,
many to many, many to one, one to one relationships. Whether or not
multiplicity limits are enforced on the *source* side would probably be
tightly linked with whether or not the relationship is two way or one way.

This information is enough to then take the object structure, and assuming
you have a description of the types of attributes as well, map it to an
RDBMS (say) using foreign keys, link tables et al.

Actually the ability to describe attributes, and place limits on their
contents that are both hints to database mapping tools and generate
run-time exceptions when abused is a damned handy tool from a software
engineer's perspective.

Interfaces are similar to multiple inheritance from a functional
perspective; a bit like adding a class to @ISA, but qualifying exactly
what methods you're including, and probably not inheriting any of the
attributes at all. Which of course, you may later be overriding.

For what it's worth, I have most of this functionality duplicated into
JavaScript. It can be co-erced into having classes, etc - you just need
to rely on convention.

Are you going to implement the concept of `scope' of methods/attributes?
Many other languages have it, and I think in some circumstances it can
help clarify the intent of code. Of course anally requiring it to be
specified ends up with a language like Java :-).

My humble opinion is that `public' attributes should just be implemented in
terms of automatically generated accessor functions.

Sorta like taking Class::Contract, Class::MethodMaker, Alzabo,
Class::Tangram and recognising the common concepts - then making them all
effectively obsolete by unifying the concepts into the language :-).

my 2c.
--
Sam Vilain, s...@vilain.net

"I like a man who grins when he fights."
- Winston Churchill -

Brent Dax

unread,
Mar 4, 2003, 7:31:11 PM3/4/03
to Sam Vilain, Dan Sugalski, perl6-l...@perl.org, poop-...@lists.sourceforge.net
Sam Vilain:
# > Okay, here's another shot at the semantics for objects [for
# perl 6].
# > If folks, especially non-perl folks, would look this over and chime
# > in, I'd much appreciate it.
# > Objects have (all optional):
# > *) Properties
# > *) Methods
# > *) Attributes
#
# Add to that:
# *) A superclass (obviously, but I consider it to be the
# same level as
# Properties, Methods and Attributes.)

Superclass*es*. Perl 5 has MI, and I don't expect that to change in
Perl 6. Parrot absolutely *must* support Perl, or it has failed in its
primary goal.

# *) Associations, eg in UML.

I've deleted your stuff about associations below, which described their
properties nicely, but didn't explain what they *are*. What are they
and when would you use them? Can they be implemented in terms of
properties and/or attributes?

# *) a set of Interfaces (similar to multiple inheritance; a way of
# grouping methods associated with a class for another to
# implement).
# eg, in Java and IDL.

Can this be implemented in terms of MI and/or delegation? (For Perl 6's
part, my understanding is that an interface is just a class that
inherits from Interface--although I could *easily* be wrong about that.)

# Are you going to implement the concept of `scope' of
# methods/attributes?
# Many other languages have it, and I think in some
# circumstances it can
# help clarify the intent of code. Of course anally requiring it to be
# specified ends up with a language like Java :-).

If you mean public/private, yes. If you mean lexically-scoped methods
and such...they have been proposed for Perl 6, although implementing
them is non-trivial.

# My humble opinion is that `public' attributes should just be
# implemented in
# terms of automatically generated accessor functions.

The attribute slots in a Parrot object are private to the object (and,
by extension, any classes it is a member of), so access will be mediated
through accessors.

--Brent Dax <bren...@cpan.org>
@roles=map {"Parrot $_"} qw(embedding regexen Configure)

>How do you "test" this 'God' to "prove" it is who it says it is?
"If you're God, you know exactly what it would take to convince me. Do
that."
--Marc Fleury on alt.atheism

Sam Vilain

unread,
Mar 5, 2003, 9:28:53 AM3/5/03
to Brent Dax, Dan Sugalski, perl6-l...@perl.org, poop-...@lists.sourceforge.net
On Wed, 05 Mar 2003 13:31, Brent Dax wrote:
> # *) A superclass (obviously, but I consider it to be the
> # same level as
> # Properties, Methods and Attributes.)
> Superclass*es*. Perl 5 has MI, and I don't expect that to change in
> Perl 6. Parrot absolutely *must* support Perl, or it has failed in its
> primary goal.
> # *) a set of Interfaces (similar to multiple inheritance; a way of
> # grouping methods associated with a class for another to
> # implement).
> # eg, in Java and IDL.
> Can this be implemented in terms of MI and/or delegation? (For Perl 6's
> part, my understanding is that an interface is just a class that
> inherits from Interface--although I could *easily* be wrong about that.)

Whether to implement interfaces using Multiple Inheritance, or Multiple
Inheritance using Interfaces is a half empty/half full decision. It makes
little difference.

What I'm saying is that it should be possible to `filter' which methods you
inherit via @ISA. Ideally there would be some standard way for a module
to describe groups of methods for other classes to import a la Exporter's
%EXPORT_TAGS.

The result would allow both Multiple Inheritance *and* Interfaces.

In my experience classes only have *is a* relationships with one other
class. The other classes they inherit are *can behave like a*
relationships. MI should be frowned upon where Interfaces will not do
IMHO. But that is a flamewar topic :-).

> # *) Associations, eg in UML.
> I've deleted your stuff about associations below, which described their
> properties nicely, but didn't explain what they *are*. What are they
> and when would you use them? Can they be implemented in terms of
> properties and/or attributes?

Associations are grouping two classes together. Or more, in the general
case, but this is not required as three way associations can be broken
down into an `association class' with three or more two way associations.

It is a simple concept. You use them all the time, whether you call them
associations or not. When I first started recognising them after I
started to learn UML, programming felt like cooking with Garlic for the
first time.

For instance, a biological parent/child relationship is a two to many
association. From the parent's angle, the association might be called
`children'. From the child's angle, the association might be called
`parents'. They are the same relationship, and altering one should affect
the other - this `empathic' effect of the collections is (IMHO) important
to include. It's a bit like declaring a linked list and not having to
worry about maintaining both directions in your user code.

In RDBMS terms, a many to one relationship is implemented with an `id'
column in the referring class. A one to many relationship is implemented
with a `foreign key' in the referant class. Is the relationship from the
class with the foreign key to the class without or the other way? It is
both.

Associations can be implemented in terms of properties and/or attributes,
however I think it would pay to have a common way to access and manipulate
the collections that implement the associations, so a piece of code can
decline to care whether it is a `many to one' relationship implemented
with a simple reference, an `ordered' relationship implemented with a
array, an `unordered' relationship implemenetd with a set or bag, or a
`keyed' relationship implemented with a hash.

In fact, I have implemented such behaviour using attributes, in
Class::Tangram - an experimental pre-release (for Perl 5 :)) is available
at:

http://vilain.net/pm/Class-Tangram-1.12.2.tar.gz

Probably the most relevant for this discussion are the README and
t/04-containers.t. It is not yet complete, I need to flesh the test cases
out more.

Right now the implementation of this particular feature leaves a bit to be
desired (it's still in the `code it slowly but correctly' stage), which is
why I haven't released it to CPAN yet; the real drawback right now for me
is speed. I'm working on some alternatives which would be faster (see
README.Containers in the distribution).

Associations could easily be left out of the object core if it is not
deemed to fit; but I just thought I'd say that I consider these to be one
of the primary elements of objects and so IMHO belong in the Perl 6 object
implementation. UML considers them pretty core, too.

Leave them out to carry on with the status quo of a myriad of subtly
different, non-interchangable approaches to associating classes.
--
Sam Vilain, s...@vilain.net

If you think the United States has stood still, who built the
largest shopping center in the world?
RICHARD M NIXON

Paul

unread,
Mar 5, 2003, 10:19:27 AM3/5/03
to perl6-l...@perl.org

--- Sam Vilain <s...@vilain.net> wrote:
> What I'm saying is that it should be possible to `filter' which
> methods you inherit via @ISA. Ideally there would be some standard
> way for a module to describe groups of methods for other classes to
> import a la Exporter's %EXPORT_TAGS.
> The result would allow both Multiple Inheritance *and* Interfaces.

Are you speaking in terms of limitation, or requirement?
It would be nice to have a syntax solution. I've seen p5 interfaces
with stubs that die so that you have to override them in a subclass. It
works, but seems a little kludgy.

And I'm coming in late on this. Are you saying you want
Exporter/%EXPORT_TAGS functionality built into the language and into
all objects? Wouldn't that jack up the overhead?

Is that what you mean by "associations", below? It seems like a pretty
generic word.

> In my experience classes only have *is a* relationships with one
> other class. The other classes they inherit are *can behave like a*
> relationships. MI should be frowned upon where Interfaces will not
> do IMHO. But that is a flamewar topic :-).

lol -- probably. :)
But did you say that right?
"MI should be frowned upon where Interfaces will not do"?
Or are you using interfaces as a form of MI? I tend to think of them
(inaccurately, I suppose) as "not really inheriting", but just defining
requirements. Java pollution, probably. ;o]

But I think it is generally frowned upon, while not being officially
_bad_. We musn't dictate style. I prefer delegation, and making better
ways available discourages the effectively deprecated methodology, but
sometimes one needs to use what one knows and get the job done. As much
as I dislike it, I have to admit that there are times to apply the
adage "if a jobs worth doing, it's worth doing poorly."

Then again, there are folk who will argue that MI isn't doing it
poorly. For some problems, it might be the most elegant solution, even
if interfaces won't handle the situation. An interface really *isn't* a
true inheritance, after all -- so there must be a reason there's a
difference. :o}

> Associations are grouping two classes together. Or more, in the
> general case, but this is not required as three way associations
> can be broken down into an `association class' with three or more
> two way associations.

Sounds like MI.

> It is a simple concept. You use them all the time, whether you call
> them associations or not. When I first started recognising them
after
> I started to learn UML, programming felt like cooking with Garlic for
> the first time.

LOL!!
(My ex and I once made 40-garlic Chicken Felice.
Our classrooms *reeked* the next day, and the students were dying,
but it took me all day to figure out why they were SO miserable,
and I couldn't smell anything at all!! :)

> Leave them out to carry on with the status quo of a myriad of subtly
> different, non-interchangable approaches to associating classes.

TMTOWTDI?
Still, though your point is valid if I understand it, it will always be
possible to create "non-interchangable approaches", and we don't want
to dictate methods if we can help it.

I think I need an example....unfortunately I'm at work and haven't the
time to properly peruse the one you offered. Thus I must apologize, and
wait for more input.

Paul

__________________________________________________
Do you Yahoo!?
Yahoo! Tax Center - forms, calculators, tips, more
http://taxes.yahoo.com/

gre...@focusresearch.com

unread,
Mar 5, 2003, 10:48:13 AM3/5/03
to Hod...@writeme.com, perl6-l...@perl.org
> Are you speaking in terms of limitation, or requirement?
> It would be nice to have a syntax solution. I've seen p5 interfaces
> with stubs that die so that you have to override them in a subclass. It
> works, but seems a little kludgy.

Back in 1988 programming Objective-C under NeXTSTEP you could have a
class that does these things (based on methods inherited from Object):

- iJustCantSeemToGetAnythingDone
{
[self notImplemented:_cmd]; // TODO: We'd better write this soon!
}

- imFeelingAbstract
{
[self subclassResponsibility:_cmd];
}

- bogus
{
[self error:"Bogon flux exceeds limit %d\n", BOGON_LIMIT];
}

Also, there was a doesNotRecognize: method that was called by the runtime
system when method lookup failed. I presume you could override it to do
nasty things, but I never did that myself.


Regards,

-- Gregor

Sam Vilain

unread,
Mar 5, 2003, 11:02:55 AM3/5/03
to Hod...@writeme.com, Paul, perl6-l...@perl.org, Brent Dax
On Thu, 06 Mar 2003 04:19, Paul wrote:
> Are you speaking in terms of limitation, or requirement?
> It would be nice to have a syntax solution. I've seen p5 interfaces
> with stubs that die so that you have to override them in a subclass. It
> works, but seems a little kludgy.
> And I'm coming in late on this. Are you saying you want
> Exporter/%EXPORT_TAGS functionality built into the language and into
> all objects? Wouldn't that jack up the overhead?

No. All I'm saying is that this sort of construct:

*{$_} = \&{"Class::$_"} foreach (qw(method method2 method3));

Gives you everything that inheriting a class does, apart from the ->isa()
relationship. And potential unwanted namespace pollution.

I'm thinking along the lines of;

use base MyActualObjectSuperClass;
use base XML::Sablotron::DOM => [ "Core" ];

So your class ->isa("MyActualObjectSuperClass"), but ->can() all of the
Core DOM methods, which could perhaps be tested for as
->mimics("XML::Sablotron::DOM", "Core"), but also as
->isa("XML::Sablotron::DOM") for compatibility.

> We musn't dictate style.

No, but we should emanate good style. And I consider opening two class'
namespaces into the same stash to be very bad style.

Whenever I've seen Multiple Inheritance used, it has been because the two
classes inherited are not similar; and you're just doing it to save
yourself the hassle of splitting it into a ``servant class'' (ie,
referring to another object & forwarding methods to it). To re-iterate my
point, an interface is a `more correct' representation of this
relationship. So let's make the semantics of it easy so that people can
avoid it more easily...

Brent says that `attribute slots in a Parrot object are private to the
object', so if you really do inherit from two classes, it should be the
case that one class cannot access the other class' attributes. But - if
the child class accesses an attribute which is defined in both classes,
which does it get? I think that case (MI two classes with clashing
symbols) should be a hard run-time error. If attributes are declared
explicitly, then this enables this test. In Perl 5, the approach taken
with MI namespace clashes is to cross one's fingers ;).
--
Sam Vilain, s...@vilain.net

"Understanding is a kind of ecstasy."
-- Carl Sagan

Garrett Goebel

unread,
Mar 5, 2003, 11:10:11 AM3/5/03
to Sam Vilain, Dan Sugalski, perl6-l...@perl.org
Several people have mentioned a desire to see Perl6 and Parrot facilitate
object persistence. Should such issues be tackled in Parrot? Will there ever
be a Parrot Object Database that we can serialize our Perl, Python and Ruby
objects into, to be used at some later date in code written in Jako?

If an appropriate parrot topic, I'd be especially interested to hear the
thoughts of people like Sam Vilain, Dave Rolsky, Piers Cawley, and others
who've already spent a great deal of tuits tackling these issues.

What does parrot need to facilitate object persistence and cross-language
OO? Obviously the OMG's UML and family of specifications deal with these
issues. What other practical approaches exist?

--
Garrett Goebel
IS Development Specialist

ScriptPro Direct: 913.403.5261
5828 Reeds Road Main: 913.384.1008
Mission, KS 66202 Fax: 913.384.2180
www.scriptpro.com garrett at scriptpro dot com

Paul

unread,
Mar 5, 2003, 11:13:09 AM3/5/03
to perl6-l...@perl.org, gre...@focusresearch.com

--- gre...@focusresearch.com wrote:
> > Are you speaking in terms of limitation, or requirement?
> > It would be nice to have a syntax solution. I've seen p5 interfaces
> > with stubs that die so that you have to override them in a
> > subclass. It works, but seems a little kludgy.
>
> Back in 1988 programming Objective-C under NeXTSTEP you could have a
> class that does these things (based on methods inherited from
> Object):
> - iJustCantSeemToGetAnythingDone {
> [self notImplemented:_cmd]; // TODO: We'd better write this soon!
> }
> - imFeelingAbstract {
> [self subclassResponsibility:_cmd];
> }
> - bogus {
> [self error:"Bogon flux exceeds limit %d\n", BOGON_LIMIT];
> }

As in the p5 equivs (???):
sub iJustCantSeemToGetAnythingDone {
shift->notImplemented(@_); # better write this soon!
}
sub imFeelingAbstract {
shift->{subclassResponsibility}->(@_);
}
sub bogus {
dir sprintf "Bogon flux exceeds limit %d\n", BOGON_LIMIT;
}

or am I completely off base?
(never done Objective-C under NeXTSTEP).
I think I may have missed the point.
Sorry, feeling dense. :)

> Also, there was a doesNotRecognize: method that was called by the
> runtime system when method lookup failed. I presume you could
override
> it to do nasty things, but I never did that myself.

AUTOLOAD()? Oh, I *have* done nasty things with that, that I don't even
like to talk about....

Mostly, though, I just use it to fake up quick templated accessors.
If I know there are forty fields on an object that are all going to
look exactly alike, I'll stick a build-on-the-fly routine in AUTOLOAD
so that if one gets called it has a legitimate accessor the next time.
That way I only have to write one reasonably abstracted routine, rather
than the forty cut-paste-edit versions I've seen folk actually do in
this shop....

"Hey, it was quick and easy...."
Ugh.

Sam Vilain

unread,
Mar 5, 2003, 11:11:50 AM3/5/03
to Hod...@writeme.com, Paul, perl6-l...@perl.org
On Thu, 06 Mar 2003 04:19, Paul wrote:
> > Leave them out to carry on with the status quo of a myriad of subtly
> > different, non-interchangable approaches to associating classes.
> TMTOWTDI?
> Still, though your point is valid if I understand it, it will always be
> possible to create "non-interchangable approaches", and we don't want
> to dictate methods if we can help it.
> I think I need an example....unfortunately I'm at work and haven't the
> time to properly peruse the one you offered. Thus I must apologize, and
> wait for more input.

Consider this excerpt from the test script:

my $joe = new Person(name => "Joe Average");
my $car = new Object(description => "Red Car");

$car->set_owner($joe);

ok($joe->posessions->includes($car), "Joe owns car");

The `Object' class has an association which it calls `owner', to class
`Person' (note: not all associations will be restricted to a particular
class). This is a collection that can only have one element so it is
implemented with a reference.

The `Person' class has an association which it calls `posessions' to class
`Object'. This is an unordered collection that can hold many elements so
it is implemented with a Set::Object.

They are the same relationship, and so setting the relationship from one
direction affects the other direction.

So, it makes sense to allow the same methods to access and update the
collections.

is($joe->get_posessions(0), $car, "Joe's first posession is his car");
ok($joe->posessions->includes($car), "Joe's posessions are a set");
ok($joe->posessions_includes($car), "Joe's set of posessions is
encapsulated");

These tests perhaps illustrate the level to which I've made them similar;

is($car->get_owner(0), $joe, "Refs can look like arrays");
ok($car->owner_includes($joe), "Refs can look like encapsulated sets");
eval { $car->owner->includes($joe) };
ok($@, "Refs cannot behave like real Sets");

To make the last test work would need associations in the object core, I
think.
--
Sam Vilain, s...@vilain.net

Whatever you do will be insignificant, but it is very important that
you do it.
-- Mahatma Gandhi

Paul

unread,
Mar 5, 2003, 11:40:32 AM3/5/03
to perl6-l...@perl.org
> > And I'm coming in late on this. Are you saying you want
> > Exporter/%EXPORT_TAGS functionality built into the language and
> > into all objects? Wouldn't that jack up the overhead?
>
> No. All I'm saying is that this sort of construct:
>
> *{$_} = \&{"Class::$_"} foreach (qw(method method2 method3));
>
> Gives you everything that inheriting a class does, apart from the
> ->isa() relationship. And potential unwanted namespace pollution.

Isn't that potential namespace pollution anyway?
You should obviously pay attention to what you're importing....

Even now, you can explicitly
use Class ();
to import nothing, right?

> I'm thinking along the lines of;
>
> use base MyActualObjectSuperClass;
> use base XML::Sablotron::DOM => [ "Core" ];
>
> So your class ->isa("MyActualObjectSuperClass"), but ->can() all of
> the Core DOM methods, which could perhaps be tested for as
> ->mimics("XML::Sablotron::DOM", "Core"), but also as
> ->isa("XML::Sablotron::DOM") for compatibility.

Ok, forgive me. I see what you're saying, but I'm lost as to why.
As I said before, I'm feeling really dense today.

> > We musn't dictate style.
>
> No, but we should emanate good style. And I consider opening two
> class' namespaces into the same stash to be very bad style.

True enough.
("emanate"? maybe "promote".)

> Whenever I've seen Multiple Inheritance used, it has been because the
> two classes inherited are not similar; and you're just doing it to
> save yourself the hassle of splitting it into a ``servant class''
(ie,
> referring to another object & forwarding methods to it). To
> re-iterate my point, an interface is a `more correct' representation
> of this relationship. So let's make the semantics of it easy so that
> people can avoid it more easily...

I don't know if I can 100% agree with your assumptions, but I do agree
with your suggestion. :) As I said before, I prefer delegation anyway.

> Brent says that `attribute slots in a Parrot object are private to
> the object', so if you really do inherit from two classes, it should
> be the case that one class cannot access the other class' attributes.

Makes sense.

> But - if the child class accesses an attribute which is defined in
> both classes, which does it get? I think that case (MI two classes
> with clashing symbols) should be a hard run-time error.

Ah. P5 does a depth-first-in-@ISA-order search, right?
But that might not be what you want, particularly if you say
@ISA = qw / X Y /;
and you want X's foo() method but Y's bar(). If both have a foo() *and*
a bar(), you couldn't disambiguate with the order of @ISA anymore. It's
probably a rare case, but it will happen. You're right -- no clean
solution comes easily to mind. All that pops up atthe moment is
hardcoding hackery, in fact, but as I said, I'm dense today, lol....

> If attributes are declared explicitly, then this enables this test.
> In Perl 5, the approach taken with MI namespace clashes is to cross
> one's fingers ;).

lol, yeah I guess so.
So how would you write code in your proposed solution to solve the
above example case?

gre...@focusresearch.com

unread,
Mar 5, 2003, 11:40:04 AM3/5/03
to Sam Vilain, Hod...@writeme.com, perl6-l...@perl.org, Sam Vilain, Paul
Seems like you are thinking along the lines of making Parrot support
Prevayler-style

http://www-106.ibm.com/developerworks/web/library/wa-objprev/index.html

stuff naturally and with less coding at the top layer. Is that where you
are headed with
this?


Regards,

-- Gregor Purdy


Sam Vilain <s...@vilain.net>
Sent by: Sam Vilain <s...@vilain.net>
03/05/2003 11:11 AM


To: Hod...@WriteMe.com, Paul <ydb...@yahoo.com>, perl6-l...@perl.org
cc:
Subject: Associations between classes [was: Re: Object spec]

Austin Hastings

unread,
Mar 5, 2003, 11:51:25 AM3/5/03
to Sam Vilain, Hod...@writeme.com, Paul, perl6-l...@perl.org

--- Sam Vilain <s...@vilain.net> wrote:
>
> Consider this excerpt from the test script:
>
> my $joe = new Person(name => "Joe Average");
> my $car = new Object(description => "Red Car");
>
> $car->set_owner($joe);
>
> ok($joe->posessions->includes($car), "Joe owns car");

How much of Association is just "tricky, sticky property"?

You'd like to declare the relationship between them, but this can be
really difficult (consider e.g., nethack, in which the things you can
"own" are constrained by weight/volume/knapsack).

So certainly you need to be able to add code to the equation.

Person::possess(o is Object)
{
if (weight_of_my_stuff() + weight_of(o) > $self.weight_limit)
{
whine(...);
}
else
{
$self.stuff.push(o);
}
}

In other cases, you don't care so much. So then it would be nice if you
could declare the relationship and have the accessor functions get
generated for you.

I work with a tool that provides just a little built in support for
this kind of thing:

When you create a relationship (using the "relate" command) between to
objects, you can do:

ccm relate -from $object_spec_1
-name $relationship_name
-to $object_spec_2

ccm unrelate [spec, as above]

ccm relate -show [partial or complete spec, as above: -f -t -n]

ccm query "is_<relationship_name>_of('$object_spec')"
ccm query "has_<relationship_name>('$object_spec')"

The relate database is pretty straightforward -- a three-column table.

The query part is supported by "magic" -- the query syntax parser knows
how to chop up is_XXX_of() and has_XXX() predicates to extract
relationship names.


I think that the Association concept can be implemented as a non-core
package. You'll declare Associations like classes, except that they'll
mostly be auto-generated. However, if you need to insert code (as
above) you can explicitly spell out your sub.

What would be nice would be a convention for
accessing/creating/querying/modifying them, so that whenever we see
"is_AssociationName_of(...)" (or whatever) we know that this is an
association.

=Austin

Dan Sugalski

unread,
Mar 5, 2003, 12:11:45 PM3/5/03
to Sam Vilain, Hod...@writeme.com, Paul, perl6-l...@perl.org, Brent Dax
At 5:02 AM +1300 3/6/03, Sam Vilain wrote:
>
>No. All I'm saying is that this sort of construct:
>
> *{$_} = \&{"Class::$_"} foreach (qw(method method2 method3));
>
>Gives you everything that inheriting a class does, apart from the ->isa()
>relationship. And potential unwanted namespace pollution.

It's probably time to note that, when I started the discussion, it
was on perl6-internals, and all I was interested in was nailing down
needed semantics. What you've started talking about is perl 6
*language* syntax and such. I'm not sure Larry's ready to start that
yet.
--
Dan

--------------------------------------"it's like this"-------------------
Dan Sugalski even samurai
d...@sidhe.org have teddy bears and even
teddy bears get drunk

Paul

unread,
Mar 5, 2003, 2:53:14 PM3/5/03
to perl6-l...@perl.org

--- Dan Sugalski <d...@sidhe.org> wrote:
> At 5:02 AM +1300 3/6/03, Sam Vilain wrote:
> > *{$_} = \&{"Class::$_"} foreach (qw(method method2 method3));
> > Gives you everything that inheriting a class does, apart from the
> > ->isa() relationship. And potential unwanted namespace pollution.
>
> It's probably time to note that, when I started the discussion, it
> was on perl6-internals, and all I was interested in was nailing down
> needed semantics. What you've started talking about is perl 6
> *language* syntax and such. I'm not sure Larry's ready to start that
> yet.

That explains why it was starting to feel a little "drifty".
Next topic? :)

Piers Cawley

unread,
Mar 5, 2003, 7:20:15 PM3/5/03
to Garrett Goebel, Sam Vilain, Dan Sugalski, perl6-l...@perl.org
Garrett Goebel <gar...@scriptpro.com> writes:

> Several people have mentioned a desire to see Perl6 and Parrot facilitate
> object persistence. Should such issues be tackled in Parrot? Will there ever
> be a Parrot Object Database that we can serialize our Perl, Python and Ruby
> objects into, to be used at some later date in code written in Jako?
>
> If an appropriate parrot topic, I'd be especially interested to hear the
> thoughts of people like Sam Vilain, Dave Rolsky, Piers Cawley, and others
> who've already spent a great deal of tuits tackling these issues.

All I want is good object serialization. So I can say to an object
'write yourself to this stream' and have that do the right thing (ie,
all the objects that are reachable from an object are serialized
before that object, with any cycles broken. It's not much. The trick
is defining the protocol of our stream classes so that we capture
enough information.

For bonus points it would be nice to be able to serialize a class so
that one could send an object of an arbitrary class down a stream and
know that, even if the object is later deserialized in a system which
doesn't have the appropriate modules the object can still work. But
that's probably something you'd do in a stream filter.

Oh yeah, and 'Object' should have an C<instantiate_from($stream)>
method, or what would be the point?

Once I have a simple, stream based serialize/deserialize mechanism
it's relatively easy to add pretty much any datastore management
mechanism I want on top of it.

Oh yeah, for extra bonus points, I'd like to be able to override the
way Perl manipulates instance variables so I can track whether an object
is modified during its 'in memory' time, that way I can write a
storage system that's efficient about which objects it writes back to
the database on a commit. (I can work scary mojo with having every
object carry 'round a flattened copy of its old self, but that's
rather expensive...)

Note that I only need to do this when a database manager is in place,
and I only need the override on unmodified, managed objects. Most of
this stuff is available, at a cost (to both speed and programmer
sanity) in Perl right now, but I really, really want nice
interfaces.

--
Piers

Brent Dax

unread,
Mar 5, 2003, 9:31:22 PM3/5/03
to Sam Vilain, Hod...@writeme.com, Paul, perl6-l...@perl.org
Sam Vilain:
# > We musn't dictate style.
#
# No, but we should emanate good style. And I consider opening
# two class'
# namespaces into the same stash to be very bad style.

We *must* support MI, delegation and interfaces in Parrot. Interfaces
can probably be implemented in terms of MI and/or delegation, so why not
do so?

# Brent says that `attribute slots in a Parrot object are
# private to the
# object', so if you really do inherit from two classes, it
# should be the
# case that one class cannot access the other class'
# attributes. But - if
# the child class accesses an attribute which is defined in
# both classes,
# which does it get?

Neither. Attributes are private to the class that created them. A
subclass can't (well, shouldn't) access a superclass's attributes.

# I think that case (MI two classes with clashing
# symbols) should be a hard run-time error. If attributes are declared
# explicitly, then this enables this test. In Perl 5, the
# approach taken
# with MI namespace clashes is to cross one's fingers ;).

Alternatively, the approach taken with MI namespace clashes in Perl 5 is
to let the programmer arrange the inheritance tree as he sees fit, and
to let him explicitly delegate when there's no single arrangement that
works. That's a lot more *useful* than a hard error. I can see a
warning that can be deactivated, but not a fatal error.

class A {
method X { ... }
}

class B {
method X { ... }
}

class C is A is B {
...
}

Making that a fatal error looks great on paper, but what if B::X was
added in the latest version of B.pm? Do you really want a *fatal* error
to appear on machines that upgrade B, but not those that don't? Do you
have any idea what a nightmare that would be for module writers?

A warning to the effect of "Methods A::X and B::X conflict in mutual
subclass C", deactivatable with both 'no warnings <<oo>>' (or something)
and 'method X is from(A)', would please me much more. The manpage can
strongly encourage use of 'is from' when there's MI afoot.

But we're in language territory again. Parrot has to deal with this
issue in a flexible way, so always emitting a fatal error is simply not
an option.

Sam Vilain

unread,
Mar 5, 2003, 9:48:51 PM3/5/03
to Brent Dax, Hod...@writeme.com, Paul, perl6-l...@perl.org
On Thu, 06 Mar 2003 15:31, Brent Dax wrote:
> Sam Vilain:
> # > We musn't dictate style.
> #
> # No, but we should emanate good style. And I consider opening
> # two class'
> # namespaces into the same stash to be very bad style.
>
> We *must* support MI, delegation and interfaces in Parrot. Interfaces
> can probably be implemented in terms of MI and/or delegation, so why not
> do so?

I'm not disagreeing with you. But I think it would be good to specify
exactly which methods you're inheriting via `is X', rather than
all-or-nothing. This would allow for the concept of modules exporting
Interfaces without the danger of collisions.

But then, I guess so would simply mandating that classes export their
interfaces cleanly, in chunks that are unlikely to collide.

> # attributes. But - if
> # the child class accesses an attribute which is defined in
> # both classes,
> # which does it get?
> Neither. Attributes are private to the class that created them. A
> subclass can't (well, shouldn't) access a superclass's attributes.

Good.

> Alternatively, the approach taken with MI namespace clashes in Perl 5 is
> to let the programmer arrange the inheritance tree as he sees fit, and
> to let him explicitly delegate when there's no single arrangement that
> works. That's a lot more *useful* than a hard error. I can see a
> warning that can be deactivated, but not a fatal error.

You are right - but this is a different condition. There is no error in
this case because there is no ambiguity as to which method to call.

> class A {
> method X { ... }
> }
> class B {
> method X { ... }
> }
> class C is A is B {
> ...
> }
> Making that a fatal error looks great on paper, but what if B::X was
> added in the latest version of B.pm? Do you really want a *fatal* error
> to appear on machines that upgrade B, but not those that don't? Do you
> have any idea what a nightmare that would be for module writers?

Isn't it more of a nightmare if this is silently accepted?

> A warning to the effect of "Methods A::X and B::X conflict in mutual
> subclass C", deactivatable with both 'no warnings <<oo>>' (or something)
> and 'method X is from(A)', would please me much more. The manpage can
> strongly encourage use of 'is from' when there's MI afoot.
> But we're in language territory again. Parrot has to deal with this
> issue in a flexible way, so always emitting a fatal error is simply not
> an option.

It sounds like you already have a plan - I didn't realise about `is from'.
I'll shut up on this subject now :-).
--
Sam Vilain, s...@vilain.net

There is more to life than increasing its speed
-- Mahatma Gandhi

Sam Vilain

unread,
Mar 5, 2003, 9:59:03 PM3/5/03
to Dan Sugalski, perl6-i...@perl.org, poop-...@lists.sourceforge.net, perl6-l...@perl.org
On Thu, 06 Mar 2003 06:01, Dan Sugalski wrote:
> *) We're not talking perl 5 style objects, rather objects as
> fundamental things with attributes. Associations, from what I can see
> from your description, don't really apply.

I was talking about objects as fundamentals, too. I was just using Perl 5
syntax to illustrate.

Perhaps I should use UML instead:

+---------------+
| File |
+---------------+ *
| name: string |<----------+
+---------------+ |
+-------,-------+ |
/ \ | contents
/___\ |
| |
+---------------+ 1 |
| Directory |<*>--------+
+---------------+

Here we see a one to many relationship called `contents' between Classes
Directory and File, as well as an `is a' relationship of Directory and
file. It is composite, indicating that Directory objects are composed of
files.

Associations *are* fundamental object things. Presenting them in terms of
attributes is the real hack.
--
Sam Vilain, s...@vilain.net

It is necessary for me to establish a winner image. Therefore, I
have to beat somebody.
RICHARD M NIXON

Brent Dax

unread,
Mar 5, 2003, 10:22:56 PM3/5/03
to Sam Vilain, Hod...@writeme.com, Paul, perl6-l...@perl.org
Sam Vilain:
# > Alternatively, the approach taken with MI namespace clashes
# in Perl 5
# > is to let the programmer arrange the inheritance tree as he
# sees fit,
#
# You are right - but this is a different condition. There is
# no error in
# this case because there is no ambiguity as to which method to call.

In Perl 5, if there's an A::X and a B::X, the module writer arranges the
inheritance tree to get the one he wants. That's what I'm talking
about. The defined semantics of Perl 5 inheritance resolve the
ambiguity, but it's the module writer's duty to see that they resolve it
*correctly*. :^)

# > Making that a fatal error looks great on paper, but what if
# B::X was
# > added in the latest version of B.pm? Do you really want a *fatal*
# > error to appear on machines that upgrade B, but not those
# that don't?
# > Do you have any idea what a nightmare that would be for module
# > writers?
#
# Isn't it more of a nightmare if this is silently accepted?

Who said it would be silent? I mentioned emitting a warning below. The
module writer will fix the warning, and module users can disable the
warning easily until the new version is out.

# > A warning to the effect of "Methods A::X and B::X conflict
# in mutual
# > subclass C", deactivatable with both 'no warnings <<oo>>' (or
# > something) and 'method X is from(A)', would please me much
# more. The
# > manpage can strongly encourage use of 'is from' when
# there's MI afoot.
#
# It sounds like you already have a plan - I didn't realise
# about `is from'.
# I'll shut up on this subject now :-).

Ugh...sorry, that was rabid speculation on my part. I should have made
that more clear. (I do that way too often...)

Sam Vilain

unread,
Mar 5, 2003, 10:30:12 PM3/5/03
to Garrett Goebel, Dan Sugalski, perl6-l...@perl.org
On Thu, 06 Mar 2003 05:10, Garrett Goebel wrote:
> Several people have mentioned a desire to see Perl6 and Parrot
> facilitate object persistence. Should such issues be tackled in Parrot?

Not necessarily. Just be friendly to object persistence frameworks by
exporting object relationships in a sensible and consistent manner. It is
those relationships that drive the object persistence frameworks, and
implementations of the object structure in various languages.

The exact semantics and mechanisms of object persistence are still quite a
research topic, so it is not appropriate yet to select one method as the
best. However, I believe that the concepts of Object, Attribute,
Association, Methods are stable.

> What does parrot need to facilitate object persistence and
> cross-language OO? Obviously the OMG's UML and family of specifications
> deal with these issues. What other practical approaches exist?

UML does not deal with persistence. It deals with specifying and modelling
objects.

I think that right now persistence fairly and squarely belongs outside of
Parrot :-).
--
Sam Vilain, s...@vilain.net

I dont have any solution, but I certainly admire the problem.
ASHLEIGH BRILLIANT

Sam Vilain

unread,
Mar 5, 2003, 10:34:23 PM3/5/03
to gre...@focusresearch.com, Hod...@writeme.com, perl6-l...@perl.org, Sam Vilain, Paul
On Thu, 06 Mar 2003 05:40, gre...@focusresearch.com wrote:
> Seems like you are thinking along the lines of making Parrot support
> Prevayler-style
> http://www-106.ibm.com/developerworks/web/library/wa-objprev/index.html
> stuff naturally and with less coding at the top layer. Is that where you
> are headed with
> this?

The paper appears to me to describe using serialisation of memory
structures to achieve persistence, which is another approach entirely.

Serialisation is good, but fails for more complicated memory structures.
--
Sam Vilain, s...@vilain.net

The meek shall inherit the earth, but not its mineral rights.
J PAUL GETTY

Sam Vilain

unread,
Mar 5, 2003, 10:49:36 PM3/5/03
to Brent Dax, perl6-l...@perl.org
On Thu, 06 Mar 2003 16:22, Brent Dax wrote:
> Who said it would be silent? I mentioned emitting a warning below. The
> module writer will fix the warning, and module users can disable the
> warning easily until the new version is out.
> # It sounds like you already have a plan - I didn't realise
> # about `is from'.
> # I'll shut up on this subject now :-).
> Ugh...sorry, that was rabid speculation on my part. I should have made
> that more clear. (I do that way too often...)

Well, I for one like this iteration of your speculation.

`is from' would be a bit like `swiss inheritance' (think swiss cheese), or
the *{"foo"} = \&{"X::foo"} Perl 5 idiom.

It would be a clear way for a module author to inherit only the methods
that they desire.

The next question, then is - within the scope of the methods inherited via
`is from', are ALL of the methods of the original object visible, or just
the ones in private scope? If they are in public scope, what if the
derived Class redefines some methods that were effectively obscured, and
the inherited method calls it?

Hmm, I think that would just make it too ugly. If they don't inherit the
methods they need then they'll just have to get a `method not defined'
error.

It just goes to show that MI is an ugly hack compared to using a servant
class. But that is not the point here; the point here is making good MI
semantics.

Sorry, know I said I'd shut up :-) But this is still too interesting ;-)
--
Sam Vilain, s...@vilain.net

Seeing a murder on television... can help work off one's antagonisms.
And if you haven't any antagonisms, the commercials will give you
some.
-- Alfred Hitchcock

Andy Wardley

unread,
Mar 6, 2003, 3:50:34 AM3/6/03
to Sam Vilain, Hod...@writeme.com, Paul, perl6-l...@perl.org, Brent Dax
Sam Vilain wrote:
> No. All I'm saying is that this sort of construct:
>
> *{$_} = \&{"Class::$_"} foreach (qw(method method2 method3));

Like mixins? Perhaps something like this:

class My::Class;
mixin My::Random::Number::Generator qw( rand );
mixin My::Serialisation::Marshall qw( freeze thaw );

# ...class def...

A

Simon Cozens

unread,
Mar 6, 2003, 5:16:40 AM3/6/03
to perl6-l...@perl.org
a...@andywardley.com (Andy Wardley) writes:
> Like mixins? Perhaps something like this:
>
> class My::Class;
> mixin My::Random::Number::Generator qw( rand );
> mixin My::Serialisation::Marshall qw( freeze thaw );

Yey! With this, the Perl6-o-meter now stands at:

PERL 5 RUBY

===========================================[ ]====================
===========================================[ ]====================

--
You're all sick, except Simon. And he's sick, too. -- Kake Lemon Pugh

Dave Whipp

unread,
Mar 6, 2003, 6:17:33 PM3/6/03
to perl6-l...@perl.org
Sam Vilain wrote:
> Associations *are* fundamental object things. Presenting them in terms of
> attributes is the real hack.

I agree with this statement; and Brent previously asked what
associations *are*. The problem with describing them in terms of
attributes/properties not not so much that its a hack, but that its an
implementation. I'd like to attept to define what associations are, and
then work out if attrubutes are the most appropriate representation
within Perl6.

An association is a mechanism that permits one object to navgigate to
another. If the association is bidirectional, then it is possible to
also navigate from the target back to the source. Each direction of
navigation should be given a unique identifer.

An association has an associated multiplicity. This is usually defined
as either "one" or "many", with zero either permitted or excluded.

When the multiplicity is "many", then the order of navigation becomes an
issue. This would typically be either "orderd" or "unordered"; in
addition, we may wish to ensure uniqueness. Ordering my be either the
order in which targets were added; arbitrary, or sorted.

An association may be thought of as a list/set/bag of pairs. Each pair
is an instance of the relationship. If the pair is, itself, and object:
then it can have additional attributes/methods that characterize the
instance of the association. An example might be to record a timestamp
of then the association was made.

An association is either "consitant", or "inconsitant". A consitant
association is one where the number of associated targets is consistant
with the multiplicity defined for the association. While
building/modifying assemplies of objects, it is often necessary/useful
to have an inconsitant association (e.g. a 1:1 association will be
inconsitant for a short period, if one object is created before the
other). If an inconsitant association is navigated, then results may be
garbage. Such navigation could trigger an exception; or, in a threaded
environment, block until the association is consitant.

It is possible to define associations that do not require objects to be
linked/unlinked. Such associations must be "formalized". Formalization
defines the association in terms of values of attributes. The
association then becomes as equivalence relation. For example, if a
"Teacher" object has a name; and a "pupil" object has a "teacher's name"
attribute, then the association can be formalised as "$teacher.name ==
$pupil.teacher_name". The the attribute is a actually a method, then
these relationships can become very dynamic. Relational databases
usually use formalized associations: "$obj1.id == $obj2.foreign_key".


I've probably missed some important properties, but this should be
enough for discussion. Whilst it is obvious that associations can be
implemented using attributes, it seems to me that, to do so, is a bit
like implemented a "while" loop using "if" and "goto". The opposite
extreme: implementing attributes as associations, is also inappropriate.
My thinking is that associations should be defined in much the same was
as classes:

class Assoc1
is association(
Type1 $source,
Type2 @target is sorted { $^a cmp $^b } is unique
)
{
...
}

#later
my @type2_objs = $type1_obj.target;

(Or perhaps the Perl5 arrow syntax would be more appropriate here).

Dave.

Larry Wall

unread,
Mar 6, 2003, 12:40:32 PM3/6/03
to perl6-l...@perl.org
On Thu, Mar 06, 2003 at 10:16:40AM +0000, Simon Cozens wrote:
: > Like mixins? Perhaps something like this:

: >
: > class My::Class;
: > mixin My::Random::Number::Generator qw( rand );
: > mixin My::Serialisation::Marshall qw( freeze thaw );
:
: Yey! With this, the Perl6-o-meter now stands at:
:
: PERL 5 RUBY
:
: ===========================================[ ]====================
: ===========================================[ ]====================

But that's true no matter which language you put on the right. :-)

Larry

Sam Vilain

unread,
Mar 6, 2003, 8:22:52 PM3/6/03
to Austin_...@yahoo.com, perl6-l...@perl.org
On Thu, 06 Mar 2003 05:51, Austin Hastings wrote:
> You'd like to declare the relationship between them, but this can be
> really difficult (consider e.g., nethack, in which the things you can
> "own" are constrained by weight/volume/knapsack).
> So certainly you need to be able to add code to the equation.
> Person::possess(o is Object)
> {
> if (weight_of_my_stuff() + weight_of(o) > $self.weight_limit)
> {
> whine(...);
> }
> else
> {
> $self.stuff.push(o);
> }
> }

No, that's not a part of the association. That's like asking `push' to do
that checking for you.

With the current pre-release version of Class::Tangram you could do that by
overriding, Person->set_stuff, which would be called by
Person->stuff_insert with the new contents of the container as an
argument. It is the job of the set_stuff method to check for the
differences and do relevant modifications to the internal state of the
object, or to raise exceptions if the new container contents are not up to
scratch.

This may seem inefficient, but I consider it a starting point of the
implementation (like the original version of Class::Tangram, which was
implemented with AUTOLOAD and regexp, and took about 20 lines of code
;-)). It seemed cleaner than requiring classes to overload all of
Person->stuff_insert(), Person->stuff_replace, Person->stuff_clear(), etc.

> In other cases, you don't care so much. So then it would be nice if you
> could declare the relationship and have the accessor functions get
> generated for you.

Well, use Class::Tangram then :-).

> I work with a tool that provides just a little built in support for
> this kind of thing:
> When you create a relationship (using the "relate" command) between to
> objects, you can do:
> ccm relate -from $object_spec_1
> -name $relationship_name
> -to $object_spec_2
>
> ccm unrelate [spec, as above]
>
> ccm relate -show [partial or complete spec, as above: -f -t -n]
>
> ccm query "is_<relationship_name>_of('$object_spec')"
> ccm query "has_<relationship_name>('$object_spec')"
>
> The relate database is pretty straightforward -- a three-column table.

Also known as a `link table'. How many columns it has, and whether it
shares a table with either related object (like a foreign ID column),
depends on the multiplicity of the relationship.

> The query part is supported by "magic" -- the query syntax parser knows
> how to chop up is_XXX_of() and has_XXX() predicates to extract
> relationship names.

Tangram inserts special tied variables that have the information needed and
`auto-vivify' by loading the collection from storage when accessed. Very
transparent :-).

> I think that the Association concept can be implemented as a non-core
> package. You'll declare Associations like classes, except that they'll
> mostly be auto-generated. However, if you need to insert code (as
> above) you can explicitly spell out your sub.

Certainly they could.

> What would be nice would be a convention for
> accessing/creating/querying/modifying them, so that whenever we see
> "is_AssociationName_of(...)" (or whatever) we know that this is an
> association.

This is a key point.

Andy Wardley

unread,
Mar 7, 2003, 5:31:45 AM3/7/03
to Dave Whipp, perl6-l...@perl.org
Sam Vilain wrote:
>Associations *are* fundamental object things. Presenting them in terms of
>attributes is the real hack.

Associations *are* fundamental things, but I don't think they are part
of an object.

They describe relationships between objects and should exist independantly
and orthogonal to them.

Dave Whipp wrote:
> An association is a mechanism that permits one object to navgigate to
> another. If the association is bidirectional, then it is possible to
> also navigate from the target back to the source. Each direction of
> navigation should be given a unique identifer.

Category theory has something to say about this. I hope I can provide
an essence of it, despite my limited understanding of the subject...

A category is defined by a collection of elements (objects in this case)
and a number of morphisms (relations) that provide mappings between the
different elements.

There are many different kinds of morphisms: epimorphisms (one-to-),
monomorphisms (-to-one), isomorphisms (one-to-one), polymorphisms
(-to-many) and so on. In category theory, morphisms are dual,
so that for each relationship represented by an arrow between two
objects, there is a reciprocal relationship travelling back down the
arrow in the opposite direction.

Traditional databases and object systems are based on set theory. Set
theory is in fact just one kind of theory that is described by category
theory (think of Category Theory as a class and Set Theory as an instance).

The category morphisms that are defined by set theory are 'identity' and
'contains' (insert general paraphrasing and hand-waving warning here).
The 'identity' isomorphism gives each element in the set a unique identifier
so that you know which one you're talking about at any time. 'contains'
is a polymorphism that defines which elements are contained by which other
elements.

If you want to make it an ordered set, then you need to add another
morphism, 'before' (and its dual morphism 'after') which tells you
which of any two elements in a set is ordered before the other.

If you want to make a tuple, hash, queue, stack, bag, stream or
multi-coloured, cross-referenced, hyper-indexed, double-camel Larry
space in 9 + 3i dimensions, then you just need to add a few more
morphisms that define those extra relations that are characteristic of
that kind of information space.

In summary:

Category == [ Elements, Morphisms ] # math terminology
== [ Objects, Associations ] # programming
== [ Records, Relations ] # database

> An association is either "consitant", or "inconsitant".

I think it is better to assume that there is no such thing as an
inconsistent morphism. If the shoe doesn't fit, then don't wear it!
Find another shoe or go barefoot. :-)

> While it it is obvious that associations can be implemented using
> attributes, it seems to me that, to do so, is [ ...not so good... ]

Agreed. Associations are no more part of an object than an electric
current is part of an electron. The field is defined by the interaction
between fundamental particles but is not an inherent part of the particles
themselves (wave/particle duality and other quantum mechanical chicanery
aside).

The only reason that we are currently forced to use attributes to represent
our relations is because our OO systems and databases are based on set
theory. An object or database record is conceptually nothing more than
a set containing attributes. We define relations using attributes as
foreign keys because there's no other way to do it.

If instead we borrow the conceptual model from category theory and
provide a mechanism for defining elements and relations *separately*,
then it should be possible to build all kinds of fancy information
spaces with any number of different inter-element relationships defined.

The only language that I'm aware of that implements something like this
is CAML (although I'm sure there must be others).

Reading from http://caml.inria.fr/ercim.html :

"It is possible to define a type of collections parameterized by the
type of the elements, and functions operating over such collections.
For instance, the sorting procedure for arrays is defined for any
array, regardless of the type of its elements."

Anyway, the gist of this long rambling post is that In My Humble Opinion,
if Perl 6 is to provide the ability to define associations between objects,
then it should do so as part of a larger category mechanism rather than
as an extension to the class/object mechanism.


A

Paul

unread,
Mar 7, 2003, 10:29:22 AM3/7/03
to Andy Wardley, Dave Whipp, perl6-l...@perl.org

--- Andy Wardley <a...@andywardley.com> wrote:
> Associations *are* fundamental things, but I don't think they are
> part of an object. They describe relationships between objects and
> should exist independantly and orthogonal to them.

Agreed. Is there any reason that shouldb't be done with something like

use Associasions;
associate( $foo => $bar, @opts ); # opts defining association type

I see no real desperate need for that to be an integrally linguistic
mechanism, tho perhaps I'm being dense again. Seems to me a module
could do all that was needed, in p5 and/or p6.

> Dave Whipp wrote:
> > An association is a mechanism that permits one object to navgigate
> > to another. If the association is bidirectional, then it is
possible
> > to also navigate from the target back to the source. Each direction
> > of navigation should be given a unique identifer.

Easy enough for a module to keep and internal doubly-linked list of
objects that describe the relationships of things it has been told to
attend.

> There are many different kinds of morphisms: epimorphisms (one-to-),
> monomorphisms (-to-one), isomorphisms (one-to-one), polymorphisms
> (-to-many) and so on. In category theory, morphisms are dual,
> so that for each relationship represented by an arrow between two
> objects, there is a reciprocal relationship travelling back down the
> arrow in the opposite direction.

So the relation object for any given registered object could have
subtrees that identify all these. It seems simple. Am I missing
something?

> If you want to make it an ordered set, then you need to add another
> morphism, 'before' (and its dual morphism 'after') which tells you
> which of any two elements in a set is ordered before the other.

Sensible, and still reasonably easy to implement....



> I think it is better to assume that there is no such thing as an
> inconsistent morphism. If the shoe doesn't fit, then don't wear it!
> Find another shoe or go barefoot. :-)

hmm... maybe not. Inheritance is an assosiation of sorts, isn't it?
(please don't let that open another can of worms, lol...)
But the child object knows it's parent, and can inherit methods and
atributes, while the parent can know nothing about it's child in
standard OOP structure. That's an inconsistent assosiation, isn't it?

I only mention it because, though I can't really think of a good
example of when it would be needed, I'd hate to say you can't *have*
one, just because.... Easier to code and maintain for flexibility from
the start. :)

> Associations are no more part of an object than an electric
> current is part of an electron. The field is defined by the
> interaction between fundamental particles but is not an inherent
> part of the particles themselves (wave/particle duality and other
> quantum mechanical chicanery aside).

But I *LIKE* quantum mechanical chicanery! >:O}
Still, I concur. The object shouldn't need to know or care who else
"owns" it. My coffee cup doesn't. But if the program needs to identify
whose coffee cup it is, there should be a way. The Cup object shouldn't
be required to have an owner attribute dictated by a theoretical
Association system in the language. Many applications, most, I'd say,
won't need it, and I'd rather skip the overhead. If I need it, I'll
pull in the necessary module and set up the relationships as required.

Now it *would* be nice if the Association module could help shortcut
that and provide some syntactic sweetener, but for that I don't even
mind if it's Aspartame. ;o]

> If instead we borrow the conceptual model from category theory and
> provide a mechanism for defining elements and relations *separately*,
> then it should be possible to build all kinds of fancy information
> spaces with any number of different inter-element relationships
> defined.

I must admit I like this idea -- it's *feels* elegant, but I have no
idea off the top of my head how you would *use* it. Can you give me an
implementation example, in theoretical code?



> Anyway, the gist of this long rambling post is that In My Humble
> Opinion, if Perl 6 is to provide the ability to define associations
> between objects, then it should do so as part of a larger category
> mechanism rather than as an extension to the class/object mechanism.

Maybe. I'm almost convinced, but I need to see more concrete examples.

0 new messages