develooper Front page | perl.perl6.language | Postings from August 2006

derived class generators and introspection

Thread Next
Darren Duncan
August 30, 2006 04:15
derived class generators and introspection
Message ID:

This email is part of a brain dump from my thoughts over the last 
week while I was away from a computer.  If anything doesn't make 
sense, I will clarify or expand it in the following days.

I believe that Perl 6 already has basically all of the necessary 
parts built-in for implementing a true relational database, and that 
any needed remainder can be added and integrated in an elegant 
fashion, as I will outline and/or ask about.


At the center of this idea is the thought that the "Tuple" and 
"Relation" of the relational data are not each single classes, but 
rather are each roles / abstract interfaces that many classes can be 
composed of / implement.

This is much the same as how I see the existing "Array" and "Hash" of 
Perl 6, where each is a role, and eg, that "Array of Int" and "Array 
of Str" are 2 different actual classes (or roles) that .does(Array); 
in this context, saying "Array of ..." is acting as a class generator 
which defines a new class that composes the Array role.  I say that 
"Array of Int" and "Array of Str" are 2 different classes because the 
Perl 6 type system would treat each as being a repository for 
different sets of possible values, and would reject the assignment of 
one to the other.

And so, a "Tuple" type is essentially defined using an ordinary class 
(or classless object type) definition that .does(Tuple) but that that 
it also has certain restrictions.  A Tuple value is then simply an 
object of that class.

The routines that the Tuple class provides are essentially just 
wrappers over certain meta-class and/or class routines, and Tuple 
does not add any new attributes nor hide any existing class 
functionality.  The attributes of the Tuple and the attributes 
defined by the class are one and the same.

The design restrictions that a Tuple doing class must obey, or appear 
to obey as far as its users can see, are such as these:

   1. All significant attributes which together define the Tuple 
object's value must be public and/or have accessors with the same 
names as the attributes (extra implicit attributes that eg index 
those are not significant in this sense); an introspection method 
should also exist where one can inquire what the names and types of 
the significant attributes are; conceptually, a Tuple class is 

   2. The Tuple class must have a constructor that takes values for 
all significant attributes of the new object.  Every logically 
distinct Capture of that constructor must produce a logically 
distinct new object.

   3. A Tuple class needs to provide the interface details necessary 
that the Perl 6 type system can treat it as a value type.  The === 
operator should return True just for 2 Tuple objects that are of the 
same class and where all pairs of corresponding significant 
attributes using === return True.

Conjecture:  As well, 2 Tuple objects that are of different classes, 
where at least one is anonymous, should compare like they were of the 
same class if their significant attribute definition sets are 
identical; this is so a system where most classes are generated from 
other classes DWIM correctly, like two distinct "Array of Int" have 
the same definition.

   4. Conjecture: all Tuple classes should be immutable following 
their construction, either actually or in appearance, but this may 
not be essential for all uses of it.

   5. Each significant Tuple attribute is mutually exclusive from all 
of the others, in that the interface to an attribute conceptually 
maps 1:1 to the attribute; reading or changing any of them does not 
have visible side-effects on any others.  This is similar to how 
array or hash elements are exclusive.

Now, a "Relation" type is one step removed; it is simply or in 
appearances to the user a "Set of <Tuple-doing-class>" or some-such 
that also .does(Relation), or perhaps alternately, a "Relation" type 
could be declared with "Relation of <Tuple-doing-type>", which looks 
more natural.

A "Relation" is a "Set" that is restricted to all of its members 
being of the same single class that is specified in the Relation type 
definition, and within that constraint, it is useable like any Set, 
and the Relation role adds several additional routines that wrap 
meta-class or class methods of the Set, but don't hide any existing 

Presumably any Tuple used in a Relation has to be immutable, since 
changing a Tuple that is a member of a Relation would have the same 
issues to contend with as when you change a mutable object that is 
used as a Hash key.

Inherited from Set, a Relation class must have the necessary details 
that the Perl 6 type system can treat it as a value type, including 
that === works.

It goes without saying that any attribute of a Tuple can be either a 
class that .does(Tuple) or that .does(Relation), as it can be any 
other class.

Note that many of the methods which the Tuple and Relation roles 
provide will have the effect of generating new anonymous classes, 
along with objects of said new classes; these may very well be in 
fact be classless objects as is appropriate; in some cases, the new 
objects will have the same classes as the parent objects.  Some will 
generate one output object from one input object and/or the invocant; 
others will generate one output object from 2 or N input objects.


Now, in order for all the above to work effectively, a few things may 
or will be needed in the Perl 6 meta-model and programmatic API to 

   1. It must be possible to define new classes or classless objects 
whose definition can be determined at run time or compile time 
depending on what data is known.

   2. It must be possible to both read the list of significant 
attributes from an existing class definition / meta-class object, 
including their names and full type definitions, and to copy these 
names and definitions into a new class definition or classless object.

   3. Generally speaking, it should be possible to take several 
existing meta-class objects and treat their attribute lists as sets 
which can then have set operations applied to them, like union, 
intersect, subtract, etc; anything that supports this will only 
succeed if same-named attributes also have identical type 
definitions; non-identical types for the same names result in an 
exception.  Or additionally, it should be possible to copy one class 
definition into another one to use as a basis for further changes. 
If this isn't built-in, then the Tuple|Relation Role can implement 
this over #1/#2.  Note that these such derived definitions are static 
and don't change if their derived-from class definitions later 
change, as they aren't subclasses.

   4. We need to be able to programmatically define accessors and 
constructors for new classes/classless-objects too, unless those come 
for free when we declare attributes public-ish.


In closing for now, I imagine that a lot of this stuff is connected 
to the meta-model, though doing it well will have clean support in 
the language syntax as well.

Feedback is appreciated.

Thank you. -- Darren Duncan

Thread Next Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at | Group listing | About