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

class attr set defs as their names

7 views
Skip to first unread message

Darren Duncan

unread,
Sep 17, 2006, 6:05:19 AM9/17/06
to perl6-l...@perl.org
Another bit of a questioning brain dump, which topically follows my
post of August 30th titled "derived class generators and
introspection", since I'm having trouble sleeping at the moment, with
it on my mind ...

Any answers would be appreciated.

I would like to know, first of all, if we anonymously declare 2
specialized classes that happen to be the same, does Perl treat them
as the same.

Take this situation:

my Array of Int $foo;
my Array of Int $bar;
my Array of Str $baz;
$foo.WHAT eqv $bar.WHAT; # true or false?
$foo.WHAT eqv $baz.WHAT; # true or false?

I don't know if eqv will do what I want in this case, or whether I
need to use something else, but I would like a terse generic test
that returns true for the first comparison and false for the second.

The test should also work for any such arbitrary 2 specialized class
definitions, regardless of their dimensionality and regardless of
what they are composed of, be it Array, Hash, Set, Mapping, Seq,
Pair, Signature, Capture, etc.

I would also like to know if the collection of a class' attributes is
the same as a Signature or not, since they look rather similar to me.
If it is not a Signature, then what is the name of the data type that
represents just the collection of attributes that a class has?
Similarly, what is the name of the data type that represents a single
attribute definition, or of a single element of a Signature?

In a similar fashion, I would like an easy way to use a class'
collection of attributes like a uniquely identifying fingerprint, and
use that to generate the name of that class or use it in its place.

Within certain limits that can be otherwise specified, such as for
those that subclass a certain other class (let's call it Tuple), I
would like for class definitions to be like singletons, such that no
2 classes can have the same collection of attributes, and if one
tries to define a class with the same attributes twice, the second
attempt just returns the existing class from the first attempt rather
than making a new one.

Perhaps the problem can be simplified in a fashion by leveraging the
feature where you can declare a symbolic alias for a class, so that
the same class definition can be known by multiple names, but they
are treated as the same.

For one example:

class Foo is Tuple {
has Str $.name;
has Int $.age;
}

class Bar is Tuple {
has Str $.name;
has Int $.age;
}

class Baz is Tuple {
has Str $.name;
has Int $.age;
has Bool $.is_alive;
}

$a.WHAT =:= $b.WHAT; # true
$a.WHAT =:= $c.WHAT; # false

my Foo $a = Foo.new(...); # successful
my Foo $b = Bar.new(...); # successful
my Foo $c = Baz.new(...); # compile or runtime exception

In the above example, I want to be able to declare Tuple in such a
way that it would cause the above behaviour implicitly, eg that Bar
::= Foo without the user who declares Foo or Bar doing the ::=
explicitly.

But this needs to work for both explicitly and implicitly defined
classes. For example, continuing from the above:

my Baz $d = Baz.new(...); # successful
my Foo $e = $d.project( 'name', 'age' ); # successful
$e === Foo.new( name => $d.name, age => $d.age ); # true

class Quux is Tuple {
has Bool $is_alive;
}

my Quux $f = Quux.new(...); # successful
my Baz $g = $a.join( $f ); # successful

class Fuz is Tuple {
has Int $.is_alive;
}

class Fizz is Tuple {
has Bool $.is_dead;
}

my Quux $h = Fuz.new(...); # fails
my Quux $i = Fizz.new(...); # fails
my Baz $j = $a.join( $h ); # fails

Now, maybe I can accomplish what I want in some submethod or other of
Tuple, which has access to the pseudo meta-class or whatever of the
class being created around it, but I would appreciate some helpful
code examples for exactly how to accomplish this.

I would also appreciate examples of how to generate a class or
classless object period at runtime using the meta-model, since the
above project() and join() methods above would be doing just that.

(Now, the reason that I didn't use Tuple with 'does' rather than 'is'
is that I wanted to keep separate 2 classes that do Tuple but are
implemented differently, such as in-RAM-only vs tied-to-disk-file;
they would say "is TupleInRAM" or "is TupleOnDisk" respectively, and
even if a class of one declares the same attributes as the other,
they would be treated as 2 distinct classes by Perl; while they could
be used interchangeably in some situations, certain other situations
would make that unwise. That said, practically speaking, "does"
*may* be better than "is" for what I'm suggesting, or it may not, but
either way I would like to have something like the above behaviour.)

Oh yes, while I didn't include it in the above examples, any class
that is/does Tuple should be able to be an attribute type of another
one. For example:

class Pouf is Tuple {
has Foo $.foo;
has Quux $.z;
has Str $.str;
}

class Perf is Tuple {
has Bar $.foo;
has Quux $.z;
has Str $.str;
}

class Putz is Tuple {
has Foo $.foo;
has Fuz $.z;
has Str $.str;
}

Pouf.WHAT =:= Perf.WHAT; # true
Pouf.WHAT =:= Putz.WHAT; # false

A key thing is, generally or specific to an implementation, a Tuple's
class name doesn't matter, but just what its attribute names and
types are what matter.

Thank you for any feedback and help. A proper Perl-saavy
Set::Relation implementation is much closer to reality if I can get
these issues solved and implemented in practice.

-- Darren Duncan

0 new messages