The Forum for Discussion about The Third Manifesto and Related Matters

Please or Register to create posts and topics.

Update on "C# is a D" project

After some deep and meaningful experiments with C# generics, the latest code looks this:

WriteLine(Supplier.S.Select(t => t.Status == 30)
     .Rename<TupSX>()    // "SNo", "SName", "Status", "Supplier City"
     .Project<Tup1>()    // "Supplier City"
     .Format());

   WriteLine(Supplier.P
     .Rename<TupPcolour>()                 //  "PNo", "PName", "Colour", "Weight", "City"
     .Select(t => t.Colour == "Red")
     .Project<TupPPno>()                   // "PNo", "PName"
     .Join<TupSP, TupPjoin>(Supplier.SP)   // "PNo", "PName", "SNo", "Qty"
     .Format());

I'm happy with this. Actually, better than I expected.

Other points.

  • Generalised aggregation as per RM Pre 6 is straightforward.  Andl has this, but I'm not aware of any other D that has.
  • RM VSS 5 (GTC) is straightforward. Andl has this, I'm not aware of any other D that has.
  • RM VSS 6 (user defined generic relational operators) is satisfied. I don't think any other D has it.
  • RM VSS 7 (SQL in D) is obviously satisfied.

 

Andl - A New Database Language - andl.org
Quote from dandl on May 10, 2020, 8:04 am
  • Generalised aggregation as per RM Pre 6 is straightforward.  Andl has this, but I'm not aware of any other D that has.

Rel does. See https://reldb.org/c/wp-content/uploads/2016/06/User-Defined-Aggregate-Operators-in-Tutorial-D-and-Rel.pdf

 

I'm the forum administrator and lead developer of Rel. Email me at dave@armchair.mb.ca with the Subject 'TTM Forum'. Download Rel from https://reldb.org
Quote from Dave Voorhis on May 10, 2020, 9:07 am
Quote from dandl on May 10, 2020, 8:04 am
  • Generalised aggregation as per RM Pre 6 is straightforward.  Andl has this, but I'm not aware of any other D that has.

Rel does. See https://reldb.org/c/wp-content/uploads/2016/06/User-Defined-Aggregate-Operators-in-Tutorial-D-and-Rel.pdf

It does indeed. Not quite the OO Pre 6, but actually in a way I prefer it. But I guess it took you quite a while to figure all that out?

I just added aggregation to by 'C# as a D' project. It looks like this.

WriteLine("Aggregation");
WriteLine(Supplier.SP
  .Aggregate<TupAgg,int>((t,a) => a + t.Qty)  //  "PNo", "TotQty"
  .Format());

  public class TupAgg : TupleBase {
    public readonly static string[] Heading = { "PNo", "TotQty" };
  }

Aggregation
PNo: P1, TotQty: 600
PNo: P2, TotQty: 1000
PNo: P3, TotQty: 400
PNo: P4, TotQty: 500
PNo: P5, TotQty: 500
PNo: P6, TotQty: 100

Took maybe half a day, including debugging some dumb mistakes. The bar for adding features is low.

 

 

Andl - A New Database Language - andl.org
Quote from dandl on May 12, 2020, 11:27 am
Quote from Dave Voorhis on May 10, 2020, 9:07 am
Quote from dandl on May 10, 2020, 8:04 am
  • Generalised aggregation as per RM Pre 6 is straightforward.  Andl has this, but I'm not aware of any other D that has.

Rel does. See https://reldb.org/c/wp-content/uploads/2016/06/User-Defined-Aggregate-Operators-in-Tutorial-D-and-Rel.pdf

It does indeed. Not quite the OO Pre 6, but actually in a way I prefer it. But I guess it took you quite a while to figure all that out?

Yes. As I recall, it was most of an afternoon. The actual aggregation was trivial, particularly as I'd added lambda expressions to Rel some time before. Determining how to slot user-defined aggregation into Tutorial D syntax and semantics so that it would work without changing existing Tutorial D code was most of it.

I'm the forum administrator and lead developer of Rel. Email me at dave@armchair.mb.ca with the Subject 'TTM Forum'. Download Rel from https://reldb.org

I've added while and Generalised Transitive Closure to my 'C# is a D' project (RM VSS 5). The sample is per DTATRM p238.

I also added Transform (superset of Rename, Project, Extend). It can really shorten and simplify the code. I'm surprised TD doesn't have it.

That completes the Extended RA:

  • First order (Codd): Select, Project, Join, Rename, Union (literals only)
  • Negation: Antijoin, Minus
  • Functional: Select, Extend, Transform, Aggregate
  • Recursive: Transitive Closure, Generalised TC, While
// code
      WriteLine("While");
      var seed = MMQData.MMQ.Extend<TupMMQA>(t => t.Qty);    // "Major", "Minor", "Qty", "AggQty"
      var zmq = MMQData.MMQ.Rename<TupzMQ>();    // "zmatch", "Minor", "Qty"
      var exp = seed.While(t => t
        .Rename<TupMzA>()             // "Major", "zmatch", "AggQty"
        .Join<TupzMQ, TupMMQA>(zmq)
        .Transform<TupMMQA>(tt => TupMMQA.Create(tt.Major, tt.Minor, 0, tt.AggQty * tt.Qty)));
      WriteLine(exp.Format());
      WriteLine("P1 -> P5");
      WriteLine(exp.Select(t => t.Major == "P1" && t.Minor == "P5")
        .Aggregate<TupMMT,int>((t,a) => a + t.AggQty)
        .Format());

// type definitions
  public class RelMMQA : RelationBase<TupMMQ> { }
  public class TupMMQA : TupMMQ {
    new public readonly static string[] Heading = { "Major", "Minor", "Qty", "AggQty" };
    public int AggQty { get { return (int)Values[3]; } }
    public static TupMMQA Create(string major, string minor, int qty, int aggqty) {
      return Create<TupMMQA>(new object[] { major, minor, qty, aggqty });
    }
  }
  public class TupMzA : TupleBase {
    public readonly static string[] Heading = { "Major", "zmatch", "AggQty" };
  }
  public class TupzMQ : TupleBase {
    public readonly static string[] Heading = { "zmatch", "Minor", "Qty" };
  }
  public class TupMMT : TupleBase {
    public readonly static string[] Heading = { "Major", "Minor", "TotQty" };
  }

// data
  public static class MMQData {
    public static RelMMQ MMQ = RelMMQ.Create<RelMMQ>(
      new List<TupMMQ> {
        TupMMQ.Create("P1", "P2", 5),
        TupMMQ.Create("P1", "P3", 3),
        TupMMQ.Create("P2", "P3", 2),
        TupMMQ.Create("P2", "P4", 7),
        TupMMQ.Create("P3", "P5", 4),
        TupMMQ.Create("P4", "P6", 8),
      });
  }

// output
While
Major: P4, Minor: P6, Qty: 8, AggQty: 8
Major: P3, Minor: P5, Qty: 4, AggQty: 4
Major: P2, Minor: P4, Qty: 7, AggQty: 7
Major: P2, Minor: P6, Qty: 0, AggQty: 56
Major: P2, Minor: P3, Qty: 2, AggQty: 2
Major: P2, Minor: P5, Qty: 0, AggQty: 8
Major: P1, Minor: P3, Qty: 3, AggQty: 3
Major: P1, Minor: P5, Qty: 0, AggQty: 12
Major: P1, Minor: P2, Qty: 5, AggQty: 5
Major: P1, Minor: P4, Qty: 0, AggQty: 35
Major: P1, Minor: P6, Qty: 0, AggQty: 280
Major: P1, Minor: P3, Qty: 0, AggQty: 10
Major: P1, Minor: P5, Qty: 0, AggQty: 40
P1 -> P5
Major: P1, Minor: P5, TotQty: 52

 

 

Andl - A New Database Language - andl.org
Quote from Dave Voorhis on May 10, 2020, 9:07 am
Quote from dandl on May 10, 2020, 8:04 am
  • Generalised aggregation as per RM Pre 6 is straightforward.  Andl has this, but I'm not aware of any other D that has.

Rel does. See https://reldb.org/c/wp-content/uploads/2016/06/User-Defined-Aggregate-Operators-in-Tutorial-D-and-Rel.pdf

 

SIRA_PRISE has too.  See http://shark.armchair.mb.ca/~erwin/languageandgrammar_0105.html

<ROaggregate> := AGGREGATE(<RelationalExpression>,(<AggregationDef>+))
Quote from Erwin on May 14, 2020, 8:55 am
Quote from Dave Voorhis on May 10, 2020, 9:07 am
Quote from dandl on May 10, 2020, 8:04 am
  • Generalised aggregation as per RM Pre 6 is straightforward.  Andl has this, but I'm not aware of any other D that has.

Rel does. See https://reldb.org/c/wp-content/uploads/2016/06/User-Defined-Aggregate-Operators-in-Tutorial-D-and-Rel.pdf

 

SIRA_PRISE has too.  See http://shark.armchair.mb.ca/~erwin/languageandgrammar_0105.html

<ROaggregate> := AGGREGATE(<RelationalExpression>,(<AggregationDef>+))

Doesn't SIRA_PRISE have generalised transitive closure, too?

I'm the forum administrator and lead developer of Rel. Email me at dave@armchair.mb.ca with the Subject 'TTM Forum'. Download Rel from https://reldb.org

I've added relational assignment and the conventional shortcuts: insert, update and delete.

It should be noted that these are all type safe and provide native type inference in the editor. In fact that's also true of select, while, union and friends. It's the operators that depend on the heading that can cause errors that need to be detected at runtime: project, rename, join and related.

// code
      WriteLine("Insert P6 P7");
      v1.Insert(
        RelS.Create<RelS>(
          new List<TupS> {
            TupS.Create( "S6", "White", 25, "Paris" ),
            TupS.Create( "S7", "Black", 15, "London" ),
          })
        );
      WriteLine(v1.Format());

      WriteLine("Move to Sydney");
      v1.Update(t => t.City == "Paris", t => TupS.Create(t.SNo, t.SName, t.Status, "Sydney"));
      WriteLine(v1.Format());

      WriteLine("Delete Sydneysiders");
      v1.Delete(t => t.City == "Sydney");
      WriteLine(v1.Format());

// output
Insert P6 P7
SNo: S1, SName: Smith, Status: 20, City: London
SNo: S2, SName: Jones, Status: 10, City: Paris
SNo: S3, SName: Blake, Status: 30, City: Paris
SNo: S4, SName: Clark, Status: 20, City: London
SNo: S5, SName: Adams, Status: 30, City: Athens
SNo: S6, SName: White, Status: 25, City: Paris
SNo: S7, SName: Black, Status: 15, City: London
Move to Sydney
SNo: S1, SName: Smith, Status: 20, City: London
SNo: S2, SName: Jones, Status: 10, City: Sydney
SNo: S3, SName: Blake, Status: 30, City: Sydney
SNo: S4, SName: Clark, Status: 20, City: London
SNo: S5, SName: Adams, Status: 30, City: Athens
SNo: S6, SName: White, Status: 25, City: Sydney
SNo: S7, SName: Black, Status: 15, City: London
Delete Sydneysiders
SNo: S1, SName: Smith, Status: 20, City: London
SNo: S4, SName: Clark, Status: 20, City: London
SNo: S5, SName: Adams, Status: 30, City: Athens
SNo: S7, SName: Black, Status: 15, City: London

 

Andl - A New Database Language - andl.org
Quote from Dave Voorhis on May 14, 2020, 10:08 am
Quote from Erwin on May 14, 2020, 8:55 am
Quote from Dave Voorhis on May 10, 2020, 9:07 am
Quote from dandl on May 10, 2020, 8:04 am
  • Generalised aggregation as per RM Pre 6 is straightforward.  Andl has this, but I'm not aware of any other D that has.

Rel does. See https://reldb.org/c/wp-content/uploads/2016/06/User-Defined-Aggregate-Operators-in-Tutorial-D-and-Rel.pdf

 

SIRA_PRISE has too.  See http://shark.armchair.mb.ca/~erwin/languageandgrammar_0105.html

<ROaggregate> := AGGREGATE(<RelationalExpression>,(<AggregationDef>+))

Doesn't SIRA_PRISE have generalised transitive closure, too?

If not, I'm sure it could be added easily (and you should add it to Rel as well). A while operator just isn't hard. Happy to provide code if you need it (but I'm sure you don't).

Andl - A New Database Language - andl.org
Quote from dandl on May 14, 2020, 10:44 am
Quote from Dave Voorhis on May 14, 2020, 10:08 am
Quote from Erwin on May 14, 2020, 8:55 am
Quote from Dave Voorhis on May 10, 2020, 9:07 am
Quote from dandl on May 10, 2020, 8:04 am
  • Generalised aggregation as per RM Pre 6 is straightforward.  Andl has this, but I'm not aware of any other D that has.

Rel does. See https://reldb.org/c/wp-content/uploads/2016/06/User-Defined-Aggregate-Operators-in-Tutorial-D-and-Rel.pdf

 

SIRA_PRISE has too.  See http://shark.armchair.mb.ca/~erwin/languageandgrammar_0105.html

<ROaggregate> := AGGREGATE(<RelationalExpression>,(<AggregationDef>+))

Doesn't SIRA_PRISE have generalised transitive closure, too?

If not, I'm sure it could be added easily (and you should add it to Rel as well). A while operator just isn't hard. Happy to provide code if you need it (but I'm sure you don't).

I'm not sure there's much justification for a generalised transitive closure or while, because Tutorial DRel supports general-purpose recursive functions.

I'm the forum administrator and lead developer of Rel. Email me at dave@armchair.mb.ca with the Subject 'TTM Forum'. Download Rel from https://reldb.org