Skip to content

Formatting Conventions

Bryn Rhodes edited this page May 20, 2017 · 20 revisions

Formatting Conventions

This guidance describes syntactic conventions for formatting statements and expressions of Clinical Quality Language (CQL) that encourage consistency, readability, maintainability, and reusability of the resulting CQL. Throughout the discussing, the following simplified syntax element definitions are used. Formal definitions of these elements can be found in the CQL Specification.

  • Whitespace - Whitespace defines the separation between all tokens in the language (e.g. spaces, tabs, returns, etc.)
  • Comment - Comments are ignored by the language, allowing for descriptive text to be included
  • Literal - Literals allow basic values to be represented within the language
  • Symbol - Symbols such as +, -, *, and /
  • Keyword - Grammar-recognized keywords such as define and where
  • Identifier - User-defined identifiers

Case-Related Conventions

CQL is a case-sensitive language, meaning that the grammar uses the case of letters when comparing identifiers and keywords. For example, the keyword define must be expressed with all lower case letters, Define is not recognized. This aspect of CQL encourages consistency and reduces the potential for naming clashes with keywords in the language.

This discussion defines the following terms to describe different approaches to casing:

  • lowercase - All letters are lowercase
  • camelCase - First letters of words are capitalized, except the first word, with no whitespace characters allowed
  • PascalCase - First letters of words are capitalized, including words not capitalized in Title Case like "and" and "of", with no whitespace characters allowed
  • Title Case - Standard title casing including spaces and tabs, but no other whitespace characters allowed

CQL-Defined Casing

These casings are defined by the specification, so they are not conventions per se, but are highlighted here for completeness.

Keywords within CQL are always lowercase.

System library functions are always PascalCase.

System type names are always PascalCase.

Spacing Conventions

CQL treats all whitespace as a single token, meaning that it doesn't matter whether you use spaces or tabs to separate keywords and other tokens, so long as you have some whitespace as defined by the rules of the language. This allows authors to format their expressions using whatever conventions are appropriate for their environment. While this flexibility is beneficial in that it allows CQL to be used in a wide variety of settings, it can also lead to inconsistent formatting, reducing readability. As such, these simple conventions are recommended to ensure consistent formatting:

Use tabs to indent, rather than multiple spaces. The use of tabs reduces keystrokes and simplifies maintenance of the resulting CQL.

Indent using a single tab for related content. This makes it visually clear where the dependencies are in any given expression and helps to organize statements and clauses.

Always use a space after a comma. This helps to visually separate items in a list.

Never use a space before or after a period. The period in CQL is a qualifier, and adding whitespace disconnects the content visually, implying a separation that is not present.

To ensure readability of CQL, lines should fit reasonably within standard view screens. Around 100 characters per line is a good rule of thumb.

Identifiers

There are two types of identifiers within CQL, simple identifiers, and quoted identifiers:

  • Simple Identifiers - Any alphabetic character or underscore, followed by any number of alpha-numeric characters or underscores.

For example: SimpleIdentifier _SimpleIdentifier SimpleIdentifier24

  • Quoted Identifiers - Any sequence of characters enclosed in double-quotes

For example:

"QuotedIdentifier"
"Quoted Identifier"
"Quoted Identifiers Use Double-Quotes"
"To include a double-quote in a quoted identifier, use a backslash (\")"

Note that the actual identifier does not include the delimiting quote marks.

Operators and Functions

CQL distinguishes between operators, which use symbols such as +, *, and and, and functions, which use identifiers followed by parentheses to provide the arguments to the function.

Operators

Operators are always keywords, and always lowercase.

Binary operators (operators with two arguments) are always infix.

Unary operators (operators with one argument) are always prefix.

Always use a space before and after operators.

Functions

Functions are never keywords, and always PascalCase.

When defining a function, always use a PascalCase identifier.

Functions always use parentheses, even if the function has no arguments.

Never put a space between the function name and the argument list.

Always use spaces after commas to separate arguments.

If necessary, an argument list can be continued across multiple lines, but keep the opening parenthesis on the same line as the function identifier, and indent subsequent lines one level.

When continuing an argument list, do not attempt to right-align indented content, as this leads to unnecessary maintenance to preserve the alignment.

Literals

Literals in CQL allow for the expression of values of each of the system-defined types.

Boolean

Boolean literals use the true and false keywords.

Numbers

There are two types of number literals:

  • Integers - 45, 0, -20
  • Decimals - 98.6, 25.0

Quantities

Quantities in CQL are a number (integer or decimal) followed by a string indicating the units:

45 'mg'
28 'mm[Hg]'

The string is required to be a valid UCUM unit.

TODO: Add discussion about case-sensitivity of the UCUM string. CQL allows both, need to determine the impact and whether we should make a specific recommendation.

DateTime

DateTime literals in CQL use the @ symbol followed by a simplified ISO-8601 date/time value:

@2014
@2014-01
@2014-01-25
@2014-01-25T12
@2014-01-25T12:30
@2014-01-25T12:30:30.0Z // specifies UTC timezone
@2014-01-25T12:30:30.0+00:30 // specifies timezone as an offset

Time

Time literals in CQL use @T followed by a simplified ISO-8601 time value:

@T12:30:30.0Z

The Time literal uses the same format as the time portion of the DateTime literal.

String

String literals in CQL use single quotes:

'String literal'
'To include a single quote in a string, use a backslash (\')'

Intervals

Intervals can be expressed based on any type that supports ordered comparison (Integer, Decimal, DateTime, Time, Quantity).

Intervals use standard mathematical notation to indicate whether the boundaries are open or closed:

Interval[1, 5]
Interval(1, 9)
Interval[@2015-01-01T00:00:00.0Z, @2016-01-01T00:00:00.0Z)

Never put a space before or after the opening or closing boundary.

Always put a space after the comma.

Lists and Tuples

Lists in CQL can contain elements of any type.

Always separate the contents of the list with a space to help visually distinguish the braces from parentheses:

{ 1, 2, 3 }
Sum({ 1, 2, 3 })

Tuples in CQL contain named elements of any type.

Always separate the contents of the tuple with a space:

{ name: 'Patrick', birthdate: @2014-01-01 }

The Tuple keyword is optional, but this means that the empty tuple has a special construct:

{ } // empty list
{ : } // empty Tuple

Queries

The central expression construct of CQL is the query. The query construct in CQL is clause-based:

<primary source> <alias>
    <with or without clauses>
    <where clause>
    <return clause>
    <sort clause>

In general, simple queries can fit on a single line:

["Encounter, Performed": "Inpatient"] Encounter where duration in days of Encounter.period >= 120

If a query, or a clause of a query, needs more than one line, continue the clauses indented beneath the query or clause:

"Pharyngitis Encounters with Antibiotics" Pharyngitis
    with ["Laboratory Test, Performed": "Group A Streptococcus Test"] Test
        such that Test.result is not null
            and Test.startDateTime in Interval[Pharyngitis.startTime - 3 days, Pharyngitis.stopDateTime + 3 days]

When a query needs multiple lines, each clause should start on a new line indented one level.

Syntax Highlighting

Syntax highlighting is an important aspect of readability. In order to enable different environments to provide consistent highlighting, the following syntactic categories are defined for CQL:

  • Symbols
  • Keywords
  • Operators
  • Literals
    • Numbers
    • Strings
    • Dates and Times
  • Comments
  • Identifiers
    • Type Identifiers
    • Variable Identifiers
    • Function Identifiers

Wiki Index

Home

Authoring Patterns - QICore v4.1.1

Authoring Patterns - QICore v5.0.0

Authoring Patterns - QICore v6.0.0

Authoring Measures in CQL

Composite Measure Development

Cooking with CQL Examples

Cooking with CQL Q&A All Categories
Additional Q&A Examples

CQL 1.3 Impact Guidance

CQL Error Messages

Developers Introduction to CQL

Discussion Items

Example Measures

Formatting and Usage Topics

Formatting Conventions

Library Versioning

Negation in QDM

QDM Known Issues

Specific Occurrences

Specifying Population Criteria

Supplemental Data Elements

Terminology in CQL

Translator Options For Measure Development

Unions in CQL

Clone this wiki locally