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
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
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