Skip to content

Syntactic sugar for unique and foreign key constraints #327

@julianhyde

Description

@julianhyde

Case #240 showed how complex constraints could be expressed as queries. But you have to spend a few seconds reading each query to see which of them are unique and foreign key constraints. Therefore in this case we propose syntactic sugar.

Case 240 gave the example

val database = {parts, shipments, suppliers}
  check (forall s in suppliers
      require s.status >= 1 andalso s.status)
  check (forall s in suppliers
    require s.city = 'London' implies s.status = 20)
  check (exists p in parts)
    implies (exists p in parts where p.color = "Blue")
  check (forall s1 in suppliers, s2 in suppliers
    require s1.key = s2.key implies s1 = s2)
  check (forall sp in shipments
    require (exists s in suppliers where s.key = sp.skey))
  check (forall s in suppliers, sp in shipments
    require s.key = sp.skey
      implies (s.status >= 20 orelse sp.quantity <= 500));

Unique constraint

In the example, the unique key on suppliers is

  check (forall s1 in suppliers, s2 in suppliers
    require s1.key = s2.key implies s1 = s2)

We propose unique(collection, keyExtractor) as a shorthand function:

  check Relational.unique(suppliers, s => s.key)

The signature is as follows:

unique : 'a collection * ('a -> 'b) -> bool

(where collection is either list or bag)
and it desugars to the forall query as above.

Using a template syntax for lambdas similar to Scala, the syntax could be

  check unique(suppliers, _.key)

Foreign key constraint

In the example, the foreign key from shipments to suppliers is

  check (forall sp in shipments
    require (exists s in suppliers where s.key = sp.skey))

We propose Relational.references(collection, foreignKeyExtractor, targetCollection, unqiueKeyExtractor) as a shorthand:

  check references(shipments, fn s => s.key, suppliers, fn sp => sp.skey)

Its signature is as follows:

references: 'a collection * ('a -> 'b) * 'b collection * ('c -> 'b) -> bool

(where each collection is either list or bag) and it desugars to the forall query as above.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions