Ampersand
Ampersand copied to clipboard
Language proposal: include patterns
Current situation
Composing Ampersand scripts currently works by taking the union of a bunch of ADL files. This gives a lot of flexibility but also provides little to no structure. One of the problems solved by simply taking the union of a bunch of ADL files is that it allows the reuse of designs. A good convention is to ensure that an ADL design can only talk about itself: rules and populations that mention relations outside of that design aren't supposed to exist. Ampersand doesn't enforce such conventions, and allowing Ampersand users to create a mess for themselves. I propose to make reuse of designs something on which Ampersand is opinionated, that is: Ampersand as a language provides constructs for the programmer to make design (re)use explicit. This will give up some flexibility, forcing Ampersand users to be a bit more structured, with the benefit of the system offering certain guarantees.
Scope of the solution
To describe the composition of Ampersand patterns, I want to start by talking about design (re)use within a file. One of the issues that will come up is what should happen if a design is reused twice: does that mean the relations mentioned in that design end up in the final system once or twice? Additionally, when composing designs, we might want to make changes (or additions) to how the inclusion of files work.
Proposal
I propose the following changes:
- Patterns have a name, and that name is implicitly used as a name-space for anything inside that pattern
- Patterns can be included in other patterns, indicating design reuse
- The only way one can refer to things within a pattern, is by including it
Concretely, I propose the following would be a valid script:
PATTERN Siam
RELATION role[User * Role]
ENDPATTERN
PATTERN EmployeePortal
INCLUDE Siam AS Siam
RELATION homepage[Siam.User * Page]
RELATION access[Page * Siam.Role]
RULE homepage_access : homepage :- Siam.role ; access
MEANING "A user must have a role that gives it access to its homepage"
ENDPATTERN
INCLUDE EmployeePortal AS EmployeePortal
POPULATION EmployeePortal.access CONTAINS [("Employee", "Welcome")]
POPULATION EmployeePortal.Siam.role CONTAINS [("Sebastiaan", "Employee")]
Here the EmployeePortal.Siam.role
reference intends to illustrate that we can refer to named things (relations, concepts, rules) in patterns from outside of them by adding a prefix. An equivalent way to achieve the same thing would be to replace the last line with:
INCLUDE Siam AS Siam
POPULATION Siam.role CONTAINS [("Sebastiaan","Employee")]