Skip to content

Project: DSL Syntax Simplifications and Improvements

SimonCockx edited this page Aug 17, 2022 · 14 revisions

Rosetta has grown over the years: new features have appeared and new kinds of expressions got supported. Looking back, some features could have been implemented in a better way and some are unnecessarily complex. To simplify the upcoming work described in the Roadmap, we intend to clean up the syntax of Rosetta in a couple of non-intrusive ways. Furthermore, we introduce a new and explicit way to instantiate data types with a JSON-like syntax.

Phase 2: clean up Rosetta syntax to simplify upcoming work

Improve the implementation of the current syntax of Rosetta

This change should not have a noticeable effect, but it will simplify upcoming improvements to the type system and code generators of Rosetta.

  1. The argument of an only exists operation should always end in a feature call ->.

Currently, it is possible to write an expression such as myVariable only exists, which is not intentional. Arguments of only exists should always end in a feature call such as myVariable -> myAttribute only exists. As Simon Cockx discusses in his thesis, this might only look like a small thing, but it would actually decrease the complexity of code generators in a non-trivial way.

  1. The only-element operation can be used in any context.

Currently, the only-element operator is only valid in two locations: after a feature call a -> b only-element and after a function call MyFunc() only-element. This is an unnecessary restriction, introducing unnecessary complexity.

  1. Allow empty list literals [].

Empty lists [] are currently not allowed syntactically. We intend to lift this restriction.

  1. Remove parentheses from the internal abstract syntax tree (AST) of Rosetta.

Parentheses currently are parsed as a separate node in the AST of a Rosetta model. This is redundant: they are only relevant in the concrete syntax of a Rosetta model, and representing them in the AST complicates downstream processing such as type checking and code generation.

Remove redundant AST elements using syntactic sugar

This is only an internal change, and does not change the concrete syntax of Rosetta.

  1. Parse the empty literal as a empty list literal []. (i.e., make them equivalent to downstream processes such as the type checker and code generator)
  2. Parse a conditional expression with an absent else branch as else empty. (i.e., make if condition then value equivalent with if condition then value else empty to downstream processes)

This reduces the number of cases that the type checker and code generators should be able to handle.

Further suggestions

The following proposals still need to be discussed and might not make it to the final version of this project.

  1. Rethink the assign-output/set/add syntax for defining the output of a function.

Right now, the output of a function is defined as a series of assign-output/set/add statements, each of which has a so called "assign path" consisting of an arbitrary number of feature calls together with optional indexing. This complicates checking the validity of a function: does this series of statements define the output completely? How should we type check an assign path involving features with plural cardinality? How should we check the cardinality constraint for a series of set and add statements?

Proposal 1: With the new JSON syntax to instantiate data types, we might be able to replace these multiple statements with a single set: <expression> statement that completely defines the output with a single expression. This would circumvent creating complex solutions to the problems from above. On the downside, this would require changes to every existing Rosetta model.

Proposal 2: Create a validity rule to check that every attribute of the output is completely defined. If the implementation of a function is intended to be left abstract, then a user should make this intention explicit by writing abstract before the function declaration. Also add validity rules that an assign path may not contain attributes with non-singular cardinality in the middle (i.e., it may only end with such an attribute). Also make it possible to index the root of an assign path. This is less intrusive; only the abstract modifier would need to be added to functions that are left abstract.

  1. Add a not operator.

There is currently no operator for boolean negation. This could be added quite simply.