At 4:45 PM +0000 2/27/07, Nicholas Clark wrote:
 > 4.  rename():

rename is a Perl 5 builtin. I didn't think that it had been dropped for
Perl 6.

At 6:22 PM +0000 2/27/07, Smylers wrote:
 > 1.  join() aka natural_join():

Remember that Perl already has a C<join> function, for joining strings.

To both of these comments, first I want to repeat that we don't have to use the names I provided if there are other names or syntax that would work better.

As for join(), it already has multiple meanings in Perl.

Not only is join() used for joining strings, but also for joining threads.

Regardless, I see this situation as being similar to Dog.bark() vs Tree.bark(); the operators I described take a Mapping or Hash as their primary argument, while any other join() or rename() do not, so they are very easy to distinguish using normal multi semantics, and they don't even look the same visually.

But once again, the functions|operators can have different names.

At 6:22 PM +0000 2/27/07, Smylers wrote:
Darren Duncan writes:
 > I believe that ... some common relational operations would be a lot
 easier to express if Perl 6 had a few more operators that make them
 concise.

I am prepared to believe that.  But what I'm unclear on is when I'd want
to perform a common relational operation.

Please could you give an example of something which is useful -- that is
useful as a means to some other end, not merely useful to somebody who
has an interest in relational theory -- but which is currently awkward,
and then give the same example again showing how much better it is with
your proposed functions?

At 12:51 PM +0000 2/27/07, Aaron Crane wrote:
(As it happens, I'm not entirely convinced that these operations are
generally useful in the same way as, say, multiplication, or string
concatenation, or cross hypering, but I think that's a side issue.)

I would say that relational operations, in usefulness, place around the order of cross hypering and/or set operations, or just at the next level down.

In functionality, I see relational operations as being like slightly more complicated set operations, in that each set element has multiple significant parts and the set-like operations can be looking at just parts of each element rather than the whole element when querying membership, and that the elements of derived sets can have different elements than either of the set operation arguments. It is convenient for elements to be represented using Mappings|Hashes.

One common usage scenario, of relational-join in particular, is doing operations on tabular data, where you want to know something that involves matching up columns in several tables. For example, say you have data tables {suppliers,foods,shipments} and you want to know what suppliers, along with their countries, that you have received orange-coloured foods from. A country of residence is an attribute of a supplier, and color is an attribute of a part.

Your data, which could come from anywhere, could look like this:

  $suppliers = Set(
    { farm<'Hodgesons'>, country<'Canada'> },
    { farm<'Beckers'>, country<'England'> },
    { farm<'Wickets'>, country<'Canada'> },
  );

  $foods = Set(
    { food<'Bananas'>, colour<'yellow'> },
    { food<'Carrots'>, colour<'orange'> },
    { food<'Oranges'>, colour<'orange'> },
    { food<'Kiwis'>, colour<'green'> },
    { food<'Lemons'>, colour<'yellow'> },
  );

  $shipments = Set(
    { farm<'Hodgesons'>, food<'Kiwis'>, qty<100> },
    { farm<'Hodgesons'>, food<'Lemons'>, qty<130> },
    { farm<'Hodgesons'>, food<'Oranges'>, qty<10> },
    { farm<'Hodgesons'>, food<'Carrots'>, qty<50> },
    { farm<'Beckers'>, food<'Carrots'>, qty<90> },
    { farm<'Beckers'>, food<'Bananas'>, qty<120> },
    { farm<'Wickets'>, food<'Lemons'>, qty<30> },
  );

If the join() and semijoin() operators that I described existed, then the query could look like this:

$supp_of_oran_food = Set( $suppliers.values XsemijoinX ($shipments.values XjoinX $foods.values >>join<< { colour<'orange'> }) );

Or if higher-level operators were made that worked on entire sets of mappings, or relations (which can have multiple indexes) instead, the above query could look more like this instead:

$supp_of_oran_food = $suppliers semijoin ($shipments join $foods join Set( { colour<'orange'> } ) );

The result is then:

  Set(
    { farm<'Hodgesons'>, country<'Canada'> },
    { farm<'Beckers'>, country<'England'> },
  );

Without any join etc operators, you would have to explicitly iterate over each element of each Mapping|Hash and do comparisons between keys and values|elements, which is considerably more verbose.

In conclusion, I consider functionality like relational-join to provide considerable conciseness to very common data processing operations, which given their nature, would likely get a speed benefit from being implemented at the same low level that set operations in general are.

And the operators could have different names if necessary.

Pardon me if I missed addressing some part of an argument.

Thank you. -- Darren Duncan

Reply via email to