Nested patterns
This issue was originally posted by @haikalpribadi on 2016-10-12 11:03.
Problem to Solve
An example of a simple query involving a single relation:
match
(director: $jc, $m);
$jc has name "James Cameron";
$m has title $t;
select $t;
While queries such as the above are clear in their meaning, they take time to type and for users to parse. Experienced users may find it frustrating to repeatedly type these queries out. This could be resolved by allowing nesting or "inlining" roleplayers, turning this into a one-liner:
match (director: has name "James Cameron", has title $t);
So the above would find titles of movies directed by something with name "James Cameron".
Unfortunately, if we were to allow this nesting of roleplayers then the above becomes ambiguous to parse. It's not clear whether another roleplayer has title $t, or if James Cameron has title $t.
This ambiguity is because commas are used to separate roleplayers, but can also optionally be used to separate properties.
Proposed Solution
Remove optional commas
This can be resolved by not allowing separating properties with commas. This can lead to ugly one-line statements:
movie ako production plays-role production-with-cast has-resource title;
However, in practice, people are not using the commas anyway. They are instead writing the above like this:
movie ako production
plays-role production-with-cast
has-resource title;
See moogi and pokemon for examples.
Separate roleplayers with a semicolon
Another choice is to use semicolons to separate roleplayers:
match (director: has name "James Cameron"; has title $t);
Semicolons are already being used to separate variable patterns, so it makes total sense here. The only issue is that semicolons inside brackets might look strange.
Strictly speaking, there should be a semicolon after the last roleplayer too, but it looks really, really bad so let's not:
match (director: has name "James Cameron"; has title $t;);
Braces
Another option is to require braces (or similar) around nested properties:
match (director: {has name "James Cameron"}, {$x isa movie});
This is not particularly pretty, but fairly consistent with our use of curly braces to nest queries already. It also allows us to nest variables anywhere. For example, instead of:
match
$x isa $y;
$y plays-role actor;
we can say:
match $x isa {plays-role actor};
Mandatory variable names
Another is to always require a variable name for a roleplayer:
match (director: $y has name "James Cameron", $x isa movie);
select $x;
This eliminates one of the major benefits of the syntax: not requiring a variable name can allow for much shorter queries, by avoiding unused variable names and pointless select statements, such as select $x above.
Comparison example
"titles of movies directed by James Cameron":
Old syntax:
match
(director: $jc, $m);
$jc has name "James Cameron";
$m has title $t;
select $t;
Disallow commas:
match (director: has name "James Cameron", has title $t);
Separate roleplayers with semicolons:
match (director: has name "James Cameron"; has title $t);
Braces:
match (director: {has name "James Cameron"}, {has title $t});
Mandatory variable names:
match
(director: $jc has name "James Cameron", $m has title $t);
select $t;