hydromatic / morel

Standard ML interpreter, with relational extensions, implemented in Java
Apache License 2.0
291 stars 15 forks source link

Allow comma ("`,`") as shorthand for `join` even after `where`, `group`, `order` clauses #189

Open julianhyde opened 1 year ago

julianhyde commented 1 year ago

Currently the from expression starts with several "scan" expressions of the form "id in list" or "id = list", separated by commas, and then a sequence of clauses including "join", "where", "group", "yield". "join" means pretty much the same as ",".

The following is currently illegal:

from x in list1 where x.a > 10,
    y in list2
  yield {x, y}

With this feature it would be legal. It is convenient to be able to add a where after a scan (x in list1) and to still be able to follow it with a comma and another scan (, y in list2).

The following is equivalent and is already legal:

from x in list1
  where x.a > 10
  join y in list2
  yield {x, y}

As is the following:

from x in (from z in list1 where z.a > 10),
    y in list2
  yield {x, y}

But we cannot just enable the comma. The group and order clauses allow commas, and comma as the start of a clause would be ambiguous, as the following illustrate. Group:

from x in list1
  group x.a, x.b,
  y in list2
  yield {x, y}

Group compute:

from x in list1
  group x.a, x.b compute sum(x.c), sum(x.d),
  y in list2
  yield {x. y}

Order:

from x in list1
  order x.a desc, x.b,
  y in list2
  yield {x, y}

To disambiguate, one option is to add parentheses to group and order syntax when there is more than one key/expression. Here are some examples with the new syntax:

Note that composite yield already requires parentheses.

julianhyde commented 5 months ago

I just merged #216, which allows you to use commas in join. While

from x in list1 where x.a > 10,
    y in list2,
    z in list3
  yield {x, y, z}

remains illegal, you can now write

from x in list1
  where x.a > 10
  join y in list2,
      z in list3
  yield {x, y, z}

which looks pretty good to me.