Open labra opened 7 years ago
Just a comment: I find an IF ... THEN ... ELSE ... rather limiting and would wonder if a CASE pattern would be more scalable to cover more cases with less verbosity.
I am trying to compare possible syntaxes. Let's take an example from this question :
Can I have a shape that says "if state is assigned, assignee must have a value, if it is unassigned, it must not" ?
A possible definition with the current syntax could be something like:
:IssueShape { a [ :Issue ] }
AND ( NOT { :state [:assigned ] } OR { :assignee @:Value })
AND ( { :state [:assigned ] } OR { :assignee @:Value {0,0} } )
:Value { a [ :Value ] }
Which is not very readable.
Using the IF-THEN-ELSE, we could write it as:
:IssueShape { a [ :Issue ] } AND
IF { :state [ :assigned ] }
THEN { :assignee @:Value }
ELSE { :assignee @:Value {0,0} }
If we tried to use a CASE, it could be something like:
:IssueShape { a [ :Issue ] } AND
CASE { :state [ :assigned ] } => { :assignee @:Value }
CASE . => { :assignee @:Value {0,0} }
One concern about several CASE's is that the order of them affect the shape definition, while with the IF-THEN-ELSE, although is more verbose, it forces the author to think what he really intends to express.
For example, if one wants to express now:
Can I have a shape that says "if state is assigned, assignee must have a value, if, state is onReview, reviewer must have a value, and if state is neither assigned nor on review, then it must have no value" ?
A simple representation of the above with CASEs could be:
:IssueShape { a [ :Issue ] } AND
CASE { :state [ :assigned ] } => { :assignee @:Value }
CASE { :state [ :onReview ] } => { :reviewer @:Value }
CASE . => { :assignee @:Value {0,0} }
It looks OK but the order of the cases can affect the validation.
For example, if one issue has both values for :assigned
and :onReview
the validator would need to decide if it checks the first CASE or the second CASE (or both). Usually, programming languages like C or Java choose the first one...but having to take into account the order of definitions in ShEx could make it more complex than necessary.
If we had only IF-THEN-ELSE expressions, the author would be more forced to take into account the different cases. For example, the following definition makes clear, that the validator checks first that the state is assigned so on:
:IssueShape { a [ :Issue ] } AND
IF { :state [ :assigned ] } THEN { :assignee @:Value }
ELSE IF { :state [ :onReview ] } THEN { :reviewer @:Value }
ELSE { :assignee @:Value {0,0} }
Looking for a precedent from programming languages. does static analysis catch shadowed cases? or some shadowed cases?
A common pattern for data models is the IF-THEN-ELSE construct.
In ShEx, it can be modelled using the logical operators AND, OR, NOT.
For example, if we want to model a node that, if the value of property
:p
is 1, then the value of property:q
is"one"
, otherwise it is"other"
, we could use something like:we could simulate that by making use of the logical equivalence
so the previous shape could be written as:
However, I think it is a pain for the users to have to remember that kind of expressions and that it is also error-prone.
I think future versions of ShEx could add some macro or operation for the
IF-THEN-ELSE
pattern.