eclipse-viatra / org.eclipse.viatra

Main components of the VIATRA framework
https://eclipse.dev/viatra
Eclipse Public License 2.0
0 stars 1 forks source link

Provide a default value syntax #167

Open bergmanngabor opened 2 months ago

bergmanngabor commented 2 months ago

A very common pattern is retrieving the value of some attribute, or a default value if it does not exist. Instead of a disjunctive pattern, we could simply use an aggregator to provide a default value where there is none:

pattern p (e: ENamedElement, n: java String) {
  n == defaultTo<"(unnamed element)"> ENamedElement.name(e, #);
}

In the MVP, we should be able to pass a compile-time constant to initialize the aggregator, because it is not always the same default value that we need. Therefore, in addition to the new aggregator class, we also need some new language-level support. I have used the angle brackets here for the parametrization, but concrete syntax is TBD.

ujhelyiz commented 2 months ago

I am unsure how much it helps if unknown elements defaults to a constant instead of an expression. Because we already have the expression concept in the language (and an expressionevaluator for runtime), this shouldn't be too hard to generalize.

As a syntax, I'd rather suggest something like the Elvis operator, as that is already used in Xbase expressions for similar context:

pattern p (e: ENamedElement, n: java String) {
  n == ENamedElement.name(e, #) ?: "unnamed";
}

or if we want to have something more textual, maybe we could reuse the else keyword:

pattern p (e: ENamedElement, n: java String) {
  n == ENamedElement.name(e, #) else "unnamed";
}

or possibly the default

pattern p (e: ENamedElement, n: java String) {
  n == ENamedElement.name(e, #) default "unnamed";
}

I'd like to avoid introducing new keywords (like the defaultsTo) to the language, as it could break existing patterns that use these keywords as variable or type names; and I think it is more logical to add the default value after the element reference.

bergmanngabor commented 2 months ago

I did not mean to introduce a new keyword, just a new aggregator class. Of course, a new keyword can enable nicer syntax, if we are willing to put in the work.

As for expressions, i.e. default values that can depend on pattern variables, I feel like they would be powerful and useful, but architecturally somewhat more difficult to implement - it is definitely not a simple aggregator in that case.

ujhelyiz commented 2 months ago

In that case, I wouldn't support it as an aggregator as that would directly conflict with a more generic implementation I am sure there would be relevant cases for. Furthermore, adding the "parameter" to the aggregator would also require language extensions, right now an aggregator is a simple class reference.

bergmanngabor commented 2 months ago

Even more powerful variants:

pattern p (e: ENamedElement, n: java String) {
  ENamedElement.name(e, n ?: "unnamed");
}
find foo(x, y, z, p ?: eval(u + y), q ?: "foobar", w);

In the latter case, even though this is not an aggregator, pattern parameters x,y,z,w and external variable dependency u must all be enumerable in order for such a default constraint to be evaluable.