Predicate macros

Predicate macros allow you to arbitrarily compose together other predicates. Predicate macros are defined when input or output vars are explicitly defined using :> or :< within the declared variables of a query.

When a predicate macro is used, it expands to one or more predicates.

For example, here’s the how you can compose together sum and count to create average:

(def average 
  (<- [!val :> !avg] 
      (c/count !c)
      (c/sum !val :> !s)
      (div !s !c :> !avg))) 

Here’s an example of how average is expanded within a query:

(<- [?avg-age] 
    (age _ ?a)
    (average ?a :> ?avg-age))

expands to:

(<- [?avg-age]
    (age _ ?a)
    (count !c_1)
    (sum ?a :> !s_1)
    (div !s_1 !c_1 :> ?avg-age))

Any non-declared variables used in a predicate macro, like !s and !c in average, are given unique names so as not to conflict with other variables when expanded.

Another example of a predicate macro is “distinct count”, which will count the number of unique occurrences of a value. distinct-count secondary sorts the values and then does the computation in a single scan of the values through a custom aggregator:

(def distinct-count 
  (<- [!v :> !c] 
      (:sort !v) 
      (distinct-count-agg !v :> !c))) 

Help improve this site

Let us know what was unclear or what has not been covered. Maybe you do not like the guide style or grammar or discover spelling mistakes. Reader feedback is key to making the documentation better.

This documentation site is open source and we welcome pull requests.