Skip to content

Query language syntax and structure

The pattern you want to search for is your query. SYNG uses the S-expression notation for writing queries, which will be familiar to Lisp or Clojure programmers: it is a minimalist yet expressive syntax that allows us to describe exactly what we're looking for and without ambiguity, if a little verbose and parenthesis-heavy.

The entirety of the syntax is built of two primitives: the atom, which can be an identifier (x), a string ("x"), a pattern (/x/) or a number (1). An atom may appear by itself or inside a list -- the second primitive. Lists are denoted by parenthesis () and can contain any number of atoms or lists.

A most basic query in SYNG, made of the single identifier atom x, looks like this:

clojure
x
x

A query may also look like this:

clojure
(call x)
(call x)

In (call x), there is a list of two atoms: call and x. In SYNG queries, the first atom appearing in a list is called a selector -- selectors are predicates, or functions, that match a particular JavaScript expression. The (call) selector, for example, matches a call to a function.

Consider another query:

clojure
(call (mem b a))
(call (mem b a))

There are two selectors in this query: call, which takes another selector, mem, for its argument, which in turn takes two atoms for its arguments: b and a. mem stands for Member Expression and matches expressions like a.b, or this.count.

This describes the structure of all queries you will write in SYNG: selectors are lists, which are marked with parenthesis and a leading atom, and may contain other atoms and selectors as arguments.

It might help to think of selectors as functions that apply to the syntactic elements of your program, similar to how CSS selectors apply to HTML elements. Each argument to the function adds additional constraints to what will be considered a match, similar to how attribute selectors in CSS further constrain the elements they apply to.

In CSS:

css
button[type="submit"] {} /* <button type="submit" /> */
button[type="submit"] {} /* <button type="submit" /> */

In SYNG:

clojure
(fun x) ; function x() {}
(fun x) ; function x() {}

Don't be put off if the syntax looks strange to you at first! As you encounter the different selectors in the coming chapters, you will - I hope - come to appreciate its elegance and power.

Copyright © 2022-present Semantic Works, Inc.