Re: A shorter long dot

2006-05-04 Thread Markus Laire

On 5/1/06, Paul Johnson [EMAIL PROTECTED] wrote:

Maybe you all write your code differently to me, but looking through a
load of my OO code I had trouble finding three method calls in a row to
any methods on any objects, let alone six calls to the same method name
on different objects.

If I saw code like

 $xyzzy.foo();
 $fooz\.foo();
 $foo\ .foo();
 $fa\  .foo();
 $and_a_long_one_I_still_want_to_align\
   .foo();
 $etc\ .foo();

I'd probably take that as a pretty strong clue that I should really have
written

$_.foo for @things_to_foo;

or something.

I like lining up my code as much as the next programmer, and probably a
lot more, but I just don't see the need for this syntax which seems
ugly, confusing and unnecessary.

But then again, as I said, I really don't see the problem that is being
solved.


This long-dot can be used for many things, not just method calls.

IMHO This example from S03 is a lot better:

quote
Whitespace is no longer allowed before the opening bracket of an array
or hash accessor. That is:

   %monsters{'cookie'} = Monster.new;  # Valid Perl 6
   %people  {'john'}   = Person.new;   # Not valid Perl 6

One of the several useful side-effects of this restriction is that
parentheses are no longer required around the condition of control
constructs:

   if $value eq $target {
   print Bullseye!;
   }
   while 0  $i { $i++ }

It is, however, still possible to align accessors by explicitly using
the long dot syntax:

%monsters.{'cookie'} = Monster.new;
%people\ .{'john'}   = Person.new;
%cats\   .{'fluffy'} = Cat.new;
/quote

--
Markus Laire


Linking Synopses to corresponding pod-files?

2006-05-04 Thread Markus Laire

When reading Synopses, I sometimes notice some mistakes or typos,
which I'd like to submit a patch for, but it's not easy to do so as I
don't know where to get the source.

Could each Synopsis include a link to the corresponding .pod (if it's
available in Internet, that is), so that submitting patches would be
easier?

--
Markus Laire


Re: Linking Synopses to corresponding pod-files?

2006-05-04 Thread Juerd
Markus Laire skribis 2006-05-04 14:55 (+0300):
 When reading Synopses, I sometimes notice some mistakes or typos,
 which I'd like to submit a patch for, but it's not easy to do so as I
 don't know where to get the source.

Have you tried s/html/pod/? :)


Juerd
-- 
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html 
http://convolution.nl/gajigu_juerd_n.html


Re: A shorter long dot

2006-05-04 Thread Paul Johnson
On Thu, May 04, 2006 at 01:56:44PM +0300, Markus Laire wrote:

 On 5/1/06, Paul Johnson [EMAIL PROTECTED] wrote:

 But then again, as I said, I really don't see the problem that is being
 solved.
 
 This long-dot can be used for many things, not just method calls.

Thanks for taking the time to explain this.  The long dot here does seem to be
solving more important problems.  Now I'm not as up to date with Perl 6 syntax
as I once was, nor as much as I probably should be to be part of this thread,
but ...

 IMHO This example from S03 is a lot better:
 
 quote
 Whitespace is no longer allowed before the opening bracket of an array
 or hash accessor. That is:
 
%monsters{'cookie'} = Monster.new;  # Valid Perl 6
%people  {'john'}   = Person.new;   # Not valid Perl 6

What does Not valid Perl 6 mean?  A syntax error?  Is it not possible
to make it valid and to mean what would be meant without the whitespace?

Thinking about it a bit, I suppose the problem would be how to parse
something like

  if $person eq %people  {'john'} { ... }

which would be valid whichever way you parsed it, right?

 One of the several useful side-effects of this restriction is that
 parentheses are no longer required around the condition of control
 constructs:
 
if $value eq $target {
print Bullseye!;
}
while 0  $i { $i++ }
 
 It is, however, still possible to align accessors by explicitly using
 the long dot syntax:
 
 %monsters.{'cookie'} = Monster.new;
 %people\ .{'john'}   = Person.new;
 %cats\   .{'fluffy'} = Cat.new;
 /quote

I'm probably not seeing what the rest of the several useful
side-effects are, and I'm probably far too conservative,  but given the
choice between the following I know which one I would choose.

if ($value eq $target) {
$monsters{cookie} = Monster-new;
$people  {john  } = Person -new;
$cats{fluffy} = Cat-new;
}

if $value eq $target {
%monsters.{'cookie'} = Monster.new;
%people\ .{'john'  } = Person\.new;
%cats\   .{'fluffy'} = Cat\   .new;
}

if $value eq $target {
%monsters.cookie = Monster.new;
%people\ .john   = Person\.new;
%cats\   .fluffy = Cat\   .new;
}

However, I'm really not looking to drive perl6-language round in circles, so if
there is some document somewhere explaining the rest of the several useful
side-effects I'd love a pointer to it (I couldn't find anything appropriate).
Otherwise I'll hope that, as has happened a number of times before, someone
will decide that this is too ugly to live and will create something nicer.

-- 
Paul Johnson - [EMAIL PROTECTED]
http://www.pjcj.net


RFC: Community education page

2006-05-04 Thread David K Storrs
I was chatting with a P6 person the other day (who can remain  
nameless unless he chooses to identify himself).  He made the  
following observation:


Every time we're lambasted for how long Perl 6 is taking I remind  
myself that Short Term Thinking is the norm now.


I think there are a couple of reasons for this lambasting, and the  
more important (and remediable) one is lack of education on the part  
of the baster.  They don't understand :


(A) how hard it is to design a language; and,
(B) how much progress really has been made.

I'd like to propose that there be a single web page (or maybe a small  
wiki, but one page might be preferable) somewhere that could be  
pointed at to show just how much has been done.  It could list all  
the CPAN modules in the Bundle::Perl6 module (are those all Perl6  
modules explicitly or are some of them support framework?), all the  
sites where Pugs has been deployed in production (I gather there are  
some?), any non-toy / non-arcane projects that are being worked on in  
Perl6, etc.  I suppose it could also list the various language  
implementations that are targetting Parrot, but that's much less  
impressive to the common hacker who just wants to get work done, and  
not terribly relevant to the question Why is __Perl6__ taking time?.


Also, the page should talk about why it is difficult to do what is  
being done.  Ask the reader questions:  You want to support  
continuations / have coroutines / embedd yacc in your language /  
whatever.  How do you do it?  Then offer up an analysis of various  
design choices that were considered and rejected and why.  In  
particular, since the average person probably thought of the naïve  
answer, shoot big holes in that one.  That way they sit up and say  
Oh.  Hmm, I guess this really is kinda hard.



I see this as a small effort towards community outreach, where  
community is both the existing Perl people and the wider Internet.   
I volunteer to create the page, host it, and maintain it, but I would  
need help gathering the information in the first place.  And if the  
Perl6 community doesn't think it's a good idea, then I won't bother.


Comments?


--Dks


Re: RFC: Community education page

2006-05-04 Thread james
On Thu, May 04, 2006 at 10:44:29AM -0400, David K Storrs wrote:
 Also, the page should talk about why it is difficult to do what is  
 being done.  Ask the reader questions:  You want to support  
 continuations / have coroutines / embedd yacc in your language /  
 whatever.  How do you do it?  Then offer up an analysis of various  
 design choices that were considered and rejected and why.  
I think this will see a lot of use, not just in terms of people really
outside the perl6 project, looking at it, and wondering what's taking so
long, but also people on the semi-inside, trying to remember things like
I'm sure there's a reason other then C if condition_without_parens
{block}  that we can't have C %foo  {'bar'}  DTRT, but I can't
remember it, which certianly happens to me fairly often.

Also, as a checklist for proposals.  If you're thinking of proposing
something, go look there.  If it's already there, do you have any new pros
to put against the existing cons?

   -=- James Mastros


Re: RFC: Community education page

2006-05-04 Thread David K Storrs


On May 4, 2006, at 10:59 AM, [EMAIL PROTECTED] wrote:


On Thu, May 04, 2006 at 10:44:29AM -0400, David K Storrs wrote:

Also, the page should talk about why it is difficult to do what is
being done.  Ask the reader questions:  You want to support
continuations / have coroutines / embedd yacc in your language /
whatever.  How do you do it?  Then offer up an analysis of various
design choices that were considered and rejected and why.

I think this will see a lot of use, not just in terms of people really
outside the perl6 project, looking at it, and wondering what's  
taking so
long, but also people on the semi-inside, trying to remember things  
like

I'm sure there's a reason other then C if condition_without_parens
{block}  that we can't have C %foo  {'bar'}  DTRT, but I can't
remember it, which certianly happens to me fairly often.

Also, as a checklist for proposals.  If you're thinking of proposing
something, go look there.  If it's already there, do you have any  
new pros

to put against the existing cons?

   -=- James Mastros


That's an advantage I hadn't thought of.

We'd have to be careful to keep it brief, though.  The whole point is  
that this is supposed to be a single page that can be read in a  
reasonable period of time (~10 mins).  It's supposed to answer one  
question:  Why should I still be excited about Perl6 even though  
it's taking longer than was expected?, not a horde of questions like  
why were coroutines implemented that way? and such.



--Dks


Re: RFC: Community education page

2006-05-04 Thread Paul Johnson
On Thu, May 04, 2006 at 03:59:47PM +0100, [EMAIL PROTECTED] wrote:

   but also people on the semi-inside, trying to remember things like
 I'm sure there's a reason other then C if condition_without_parens
 {block}  that we can't have C %foo  {'bar'}  DTRT, but I can't
 remember it, which certianly happens to me fairly often.

Well, I'd obviously quite like that ;-)

-- 
Paul Johnson - [EMAIL PROTECTED]
http://www.pjcj.net


Perl 6 Perl 6 Wiki Wiki (RFC: Community education page)

2006-05-04 Thread Juerd
Not entirely related, but:

it would be great if someone wrote usable wiki software (with revision
control support) in Perl 6, and could maintain it so that it keeps up
with Pugs. Because of the current state of Pugs, it will have to be
written in a very simple way.

Especially if it looks great on the outside, this will do Perl 6 much
good.

I've been meaning to do this myself, but I'm past the point where I give
up waiting for sufficient sufficiently round tuits.

Of course, feather can host it :)


Juerd
-- 
http://convolution.nl/maak_juerd_blij.html
http://convolution.nl/make_juerd_happy.html 
http://convolution.nl/gajigu_juerd_n.html


Re: Linking Synopses to corresponding pod-files?

2006-05-04 Thread Markus Laire

On 5/4/06, Juerd [EMAIL PROTECTED] wrote:

Markus Laire skribis 2006-05-04 14:55 (+0300):
 When reading Synopses, I sometimes notice some mistakes or typos,
 which I'd like to submit a patch for, but it's not easy to do so as I
 don't know where to get the source.

Have you tried s/html/pod/? :)


Thanks :)

--
Markus Laire


Re: A shorter long dot

2006-05-04 Thread Markus Laire

On 5/4/06, Paul Johnson [EMAIL PROTECTED] wrote:

On Thu, May 04, 2006 at 01:56:44PM +0300, Markus Laire wrote:

Thanks for taking the time to explain this.  The long dot here does seem to be
solving more important problems.  Now I'm not as up to date with Perl 6 syntax
as I once was, nor as much as I probably should be to be part of this thread,
but ...

 IMHO This example from S03 is a lot better:

 quote
 Whitespace is no longer allowed before the opening bracket of an array
 or hash accessor. That is:

%monsters{'cookie'} = Monster.new;  # Valid Perl 6
%people  {'john'}   = Person.new;   # Not valid Perl 6

What does Not valid Perl 6 mean?  A syntax error?  Is it not possible
to make it valid and to mean what would be meant without the whitespace?


Yep, I think it's syntax error.

Note that {} here is a postfix (actually postcircumfix) operator, and
the decision to never allow whitespace before postfix operators seems
to be quite fundamental in perl6.

Some relevant sections from Synopses:
(These sections are quite long, so I'm not copy-pasting them here.)


From Synopsis 2 at http://dev.perl.org/perl6/doc/design/syn/S02.html

See the section starting with In general, whitespace is optional in
Perl 6 except


From Synopsis 3 at http://dev.perl.org/perl6/doc/design/syn/S03.html

See the section starting with List operators are all parsed consistently.

And Synopsis 4 at http://dev.perl.org/perl6/doc/design/syn/S04.html
is also related to this.


However, I'm really not looking to drive perl6-language round in circles, so if
there is some document somewhere explaining the rest of the several useful
side-effects I'd love a pointer to it (I couldn't find anything appropriate).


Have you *recently* read the Synopses at
http://dev.perl.org/perl6/doc/synopsis.html

I'm currently re-reading them, and if you have some time (few days or
weeks :), I'd suggest reading them all.

--
Markus Laire


using the newer collection types

2006-05-04 Thread Darren Duncan
As I carry on in my spare time to implement a Relation type for Perl 
6, I would like to use some of the simpler types that were added to 
the Synopsis recently and seem to lack a lot of explanatory details 
that older types have, and moreover they don't seem to be implemented 
yet in Pugs.


So I have a few questions whose answers should clarify the intended 
meaning and features of these newer types, as well as the syntax for 
declaring them.


Some relevant example types from Synopsis 6:

  Immutable types

  Objects with these types behave like values, i.e. C$x === $y is true
  if and only if their types and contents are identical.

ListLazy Perl list (composed of Seq and Range parts)
Seq Completely evaluated (hence immutable) sequence
Range   Incrementally generated (hence lazy) sequence
Set Unordered Seqs that allow no duplicates
JunctionSets with additional behaviours
PairSeq of two elements that serves as an one-element Mapping
Mapping Pairs with no duplicate keys
Signature   Function parameters (left-hand side of a binding)
Capture Function call arguments (right-hand side of a binding)

  Mutable types

  Objects with these types have distinct C.id values.

Array   Perl array
HashPerl hash

The intended new Relation type could be described like this, if I 
correctly understand the meaning of the existing types:


  Immutable types

RelationSet of Mappings where all Mappings have the same keys

Speaking a little more technically, a Relation has 2 main components, 
its heading and its body.  The heading is a set of 0..N keys (called 
attributes in relation-land), and the body is a set of 0..N 
Mappings (called tuples in relation-land), where they set of keys 
of each Mapping is identical to the Relation's heading.  Its very 
likely that a language-embedded Relation implementation would 
actually not repeat the keys for each member Mapping, but we can 
conceptualize as if they were present for simplicity.


The operations that you can do with a Relation are a proper super-set 
of those you can do with a Set.  So, the Relation type supports all 
the same Set operators, with the same meanings, such as: equal(), 
subset(), superset(), union(), intersection(), difference(), 
symmetric_difference(), none(), any(), all(), member_exists(), 
members(), member_count().  Moreover, the Relation type has these 
operators that the Set type doesn't have: rename(), project(), 
restrict(), extend(), join(), divide(), summarize(), group(), 
ungroup(), wrap(), unwrap(), matching(), etc.  Moreover, there would 
probably be convenience wrapper functions over combinations of the 
above operators such as insert(), update(), delete(), etc, though 
they aren't essential (those examples are not mutators, despite their 
name-sakes).  Some extra operators like sort() would also be 
provided, which convert Relations to Seqs or Arrays.


Now, some of the questions:

1.  Are Sets or Junctions allowed to contain undefined elements?  Can 
undef be a key of a Mapping or Hash?


2.  What actually is the practical distinction between a Set and a 
Junction?  Why would someone use one over the other?  I recognize 
that the use of Junctions is supposed to make parallelism easier, as 
iterating through one is known to be order independent.  But, 
conceptually a Set and a Relation are exactly the same;  you could 
process their members in any order and/or in parallel as well.  So is 
the use of a Junction effectively like a compiler flag to make 
certain kinds of Set ops faster at the expense of others?


3.  Is a Signature like the keys of a Mapping but that it has extra 
stuff like associated types and such?  Can one declare and use a 
Signature separately from declaring a function?


4.  What is the syntax for declaring anonymous Sets and Mappings?  I 
am already aware of these syntax for other types (correct me if I'm 
wrong):


  $a = [1,2,3]; # Array
  $b = {'x'=2,'y'=4}; # Hash
  $c = (1=2);  # Pair
  $d = (1,2,3); # Seq
  $e = 1..5;# Range
  $f = all(1,2,3);  # Junction

If this hasn't yet been decided, might I suggest the following?:

  $g = set(1,2,3);  # Set
  $h = ('x'=2,'y'=4); # Mapping

If that works, then perhaps an anonymous Relation declartion could look like:

  $r = relation( set( 'x', 'y' ): ('x'=2,'y'=4), ('x'=5,'y'=6) );

I'm not particular with the exact syntax; it just needs to be something good.

Note that a terse form of this could leave out the heading 
declaration if at least one Mapping/tuple is provided, since that 
contains the same key list.


  $r = relation( ('x'=2,'y'=4), ('x'=5,'y'=6) );

Then the heading declaration is only needed if the Relation has no 
Mappings/tuples.


  $r = relation( set( 'x', 'y' ): );

5.  What is the syntax for subscripting or extracting Mapping 
components?  Eg, can we use the same .keys, .values, .pairs, etc that 
we use 

Re: using the newer collection types

2006-05-04 Thread Sam Vilain
Darren Duncan wrote:

Speaking a little more technically, a Relation has 2 main components, 
its heading and its body.  The heading is a set of 0..N keys (called 
attributes in relation-land), and the body is a set of 0..N 
Mappings (called tuples in relation-land), where they set of keys 
of each Mapping is identical to the Relation's heading.  Its very 
likely that a language-embedded Relation implementation would 
actually not repeat the keys for each member Mapping, but we can 
conceptualize as if they were present for simplicity.
  


I don't think this terminology or these restrictions are particularly
useful.

I do think that a Pair should be a sub-type of a more general Tuple
type, with the 'where' clause being { .items == 2 } or something like that.

I think that the most flexible arrangement is to define;

- a Collection as a Bag of Tuples
- a Relation as a Collection where the tuples have a shape and no
duplicate tuples are allowed (but Relation does not need to be a core type)

Then, Mappings, Sequences, etc, become sub-types of one of the above two
types. For instance, a sequence is a Collection of (Int, Any) where the
first Int is unique across the collection. Similarly a Mapping is a
Collection of (Any, Any) where Unique(0).

something like

role Tuple { has @.items };
role Collection { has Tuple @.tuples };
subset Pair of Tuple where { .items.items == 2 };
subset Bag of Collection where { ! .tuples.grep:{.items  1 } }
subset Set of Bag where {
all( .tuples.map:{ .items } ) == one( .tuples.map:{ .items } )
}
subset Mapping of Collection where { ! .tuples.grep:{ .items != 2 } }
subset Array of Mapping where { .tuples.grep:{ .items[0].isa(Int) } }
subset Hash of Mapping where { .tuples.grep:{ .items[0].does(Str) } }

The above should probably all be written in terms of parametric roles
(see S12), but for now the above run-time checking versions should
hopefully express the relationships between the core collection-like
types as I see them.

That sounds like it might bite, but you wouldn't normally access an
Array as a Collection of (Int, Any), you'd access it as an Array, so you
get the nice .post_circumfix:[ ] method that makes array access easy.
You don't care that it has this higher order type as a parent class, and
you certainly wouldn't care for the 'bare' Collection interface (as for
one, you don't want to have to deal with the Integer keys). And it is
probably all backed by native methods.

I'm prototyping much of this using Moose in Perl 5, however Hubris is
delaying its release :-)

Moreover, the Relation type has these 
operators that the Set type doesn't have: rename(), project(), 
restrict(), extend(), join(), divide(), summarize(), group(), 
ungroup(), wrap(), unwrap(), matching(), etc.


Is there a reference for the meaning of these methods?

1.  Are Sets or Junctions allowed to contain undefined elements?  Can 
undef be a key of a Mapping or Hash?
  


undef.isa(Object), so you should be able to use it as you would any
other object. I would definitely not think of it as the absence of a
value in this context.

2.  What actually is the practical distinction between a Set and a 
Junction?  Why would someone use one over the other?  I recognize 
that the use of Junctions is supposed to make parallelism easier, as 
iterating through one is known to be order independent.  But, 
conceptually a Set and a Relation are exactly the same;  you could 
process their members in any order and/or in parallel as well.  So is 
the use of a Junction effectively like a compiler flag to make 
certain kinds of Set ops faster at the expense of others?
  


Well one side effect at the moment is that Junctions are immutable,
whilst Sets are mutable. This is perhaps a deficiency in my original
Set.pm design; all of the mutating functions should be in a seperate
role, really (or just not be mutators).

6.  Can I declare with named Set (or Junction) and Mapping typed 
variables and/or parameters that their members are restricted to 
particular types, such as Str, as I can with Arrays and Hashes, so 
that Perl itself will catch violations?  Eg, can I say as a parameter 
Set of Str :$heading? or Set of Mapping(Str) of Any :$body? so 
Perl will check that arguments are suchwise correct?
  


These are variously called Generics (ada I think, Java 1.5+),
Parametric Types, Higher Order Types (Pierce et al), Generic
Algebraic Data Types (Haskell)

In Perl 6 they are parametric roles (as in S12 mentioned above)

7.  Can we add some operators to Mapping that are like the Relation 
ones, so that implementing a Relation over Mappings is easier (or, 
see the end of #8)?  Eg, these would be useful: rename(), project(), 
extend(), join().  In particular, implementing join() into Mapping 
would help save CPU cycles:
  


Again, a reference to a prototype of the behaviour would be useful.

Sam.


Re: using the newer collection types

2006-05-04 Thread Darren Duncan

At 10:51 AM +1200 5/5/06, Sam Vilain wrote:

 Moreover, the Relation type has these

operators that the Set type doesn't have: rename(), project(),
restrict(), extend(), join(), divide(), summarize(), group(),

 ungroup(), wrap(), unwrap(), matching(), etc.

Is there a reference for the meaning of these methods?

 7.  Can we add some operators to Mapping that are like the Relation

ones, so that implementing a Relation over Mappings is easier (or,
see the end of #8)?  Eg, these would be useful: rename(), project(),
extend(), join().  In particular, implementing join() into Mapping
would help save CPU cycles:


Again, a reference to a prototype of the behaviour would be useful.


There are many written references to these methods; just type 
relational algebra into Google.


That said, some of those search results may not explain things in the 
same way, so I specifically prefer the definitions in Date and 
Darwen's book Databases, Types, and The Relational Model; 
equivalent definitions are probably on the 'net' but I'm not sure 
where.


I also defined part of the join() operator in my last email.  How 
that definition, for Tuples, extends to a Relation is that you pair 
every tuple in each relation being joined to every tuple in each of 
the others, and apply my earlier definition with each pairing; the 
output Relation contains a tuple where the earlier definition 
returned a tuple, and no tuple where it returned undef.


Alternately, if you want to wait a week, I will be coding up 
documented implementations as soon as possible within Pugs' 
ext/Relation/ dir.


But in order for me to do this, I was needing some answers about the 
nature of existing types like Set and Mapping and Junction etc, which 
I asked in this email.


Regarding your other comments:

I don't think this terminology or these restrictions are particularly
useful.

I do think that a Pair should be a sub-type of a more general Tuple
type, with the 'where' clause being { .items == 2 } or something like that.

I think that the most flexible arrangement is to define;

- a Collection as a Bag of Tuples
- a Relation as a Collection where the tuples have a shape and no
duplicate tuples are allowed (but Relation does not need to be a core type)

Then, Mappings, Sequences, etc, become sub-types of one of the above two
types. For instance, a sequence is a Collection of (Int, Any) where the
first Int is unique across the collection. Similarly a Mapping is a
Collection of (Any, Any) where Unique(0).


You may be on to something here, but I'll withold comments for now.

My main concerns with this whole Relation thing are that I want an 
efficient way in Perl 6 to represent what relation-land's concept of 
tuples and relations are, as well as an efficient implementations of 
relational algebra that are just as easy to use and fast in Perl 6 as 
are the language's other collection types such as Sets.


If Perl 6 is to be the choice language of the singularity, it needs 
to be easy and fast to do any common type of work with it, and 
relational algebra is an extremely common kind of work being done.


-- Darren Duncan


Re: using the newer collection types

2006-05-04 Thread Darren Duncan

Actually, I'll add a few more things to my reply, which should be helpful ...

At 5:11 PM -0700 5/4/06, Darren Duncan wrote:

At 10:51 AM +1200 5/5/06, Sam Vilain wrote:

 Moreover, the Relation type has these

operators that the Set type doesn't have: rename(), project(),
restrict(), extend(), join(), divide(), summarize(), group(),

 ungroup(), wrap(), unwrap(), matching(), etc.

Is there a reference for the meaning of these methods?


There are many written references to these methods; just type 
relational algebra into Google.


I will add that the first hit on such a search, the Wikipedia page on 
relational algebra ( http://en.wikipedia.org/wiki/Relational_algebra 
), is a perfectly good primer on what relational algebra is and what 
its importance is.


The article's introduction says:

	Relational algebra, an offshoot of first-order logic, is a 
set of relations closed under operators. Operators operate on one or 
more relations to yield a relation. Relational algebra is a part of 
computer science.


	Relation algebra in pure mathematics is an algebraic 
structure, relevant to mathematical logic and set theory.


That article also explains many of the most important relational operators.

Note that there is a related set of operators comprising relational 
calculus, and you can do everything in one that you can in the other, 
though less or more verbosely as the case may be.


At 10:51 AM +1200 5/5/06, Sam Vilain wrote:

I do think that a Pair should be a sub-type of a more general Tuple
type, with the 'where' clause being { .items == 2 } or something like that.

I think that the most flexible arrangement is to define;

- a Collection as a Bag of Tuples
- a Relation as a Collection where the tuples have a shape and no
duplicate tuples are allowed (but Relation does not need to be a core type)

Then, Mappings, Sequences, etc, become sub-types of one of the above two
types. For instance, a sequence is a Collection of (Int, Any) where the
first Int is unique across the collection. Similarly a Mapping is a
Collection of (Any, Any) where Unique(0).

something like

role Tuple { has @.items };
role Collection { has Tuple @.tuples };
subset Pair of Tuple where { .items.items == 2 };
subset Bag of Collection where { ! .tuples.grep:{.items  1 } }
subset Set of Bag where {
all( .tuples.map:{ .items } ) == one( .tuples.map:{ .items } )
}
subset Mapping of Collection where { ! .tuples.grep:{ .items != 2 } }
subset Array of Mapping where { .tuples.grep:{ .items[0].isa(Int) } }
subset Hash of Mapping where { .tuples.grep:{ .items[0].does(Str) } }


While this may not actually change anything, I should point out that 
every collection type can also be expressed in terms of a Relation 
definition and/or they can all be implemented over a Relation (whose 
members are actually always unique).  For example:


1. A Set of Any is a Relation with one Any attribute.
2. A Bag of N Any attributes is a Relation of N+1 attributes, where 
the extra attribute is an Int (constrained = 1) that counts 
occurrances of the distinct other attributes.

3. A Mapping can be a Relation of 2 Any attributes.
4. A Hash is a Relation of 2 attributes, Str (key) and Any (value), 
where the key has a unique constraint.
5. A Seq is a Relation of 2 attributes, typed Int (= 0) and Any, 
where the first shows their ordinal position and the second is the 
actual value; the first has a unique constraint.
6. An Array is the same, assuming it is a sparse; if it is not 
sparse, there is an additional constraint that the greatest Int value 
is the same / one less than the count of Relation members.


Suffice it to say that I'm sure you would implement a bag using some 
other type, whether a relation or a hash or an array, where the 
member is stored once with an occurrance count.


-- Darren Duncan