       (str/replace #"_" "-")
       keyword))
 
-(def ^:private ^:const dispatchable-tokens
-  "Keywords that have a corresponding function in this namespace that we can 'dispatch' to."
-  #{;; top-level
-    :aggregation :breakout :filter :fields :order-by :source-table :limit :page
-    ;; aggregation subclauses
-    :count :avg :distinct :stddev :sum :cum-sum
-    ;; filter subclauses
-    :and :or :inside :between := :!= :< :> :<= :>= :starts-with :contains :ends-with :time-interval
-    ;; fields
-    :fk-> :datetime-field
-    ;; order-by subclauses
-    :asc :desc
-    ;; values
-    :relative-datetime})
+;;; Function Dispatch
+;; QL functions are any public function in this namespace marked with `^:ql`.
+;; At the bottom of this namespace, we collect these functions and create a dispatch map, `token->ql-fn`.
+
+(declare token->ql-fn)
 
 (defn- apply-fn-for-token
   "Apply the appropriate function for dispatchable token.


;;; ## source-table

(s/defn ^:always-validate source-table
  "Specify the ID of the table to query (required).

     (source-table {} 100)"

   (apply compound-fn (for [v (cons v more)]
                        (equality-filter filter-type compound-fn f v)))))

(def ^:ql ^{:arglists '([f v & more])} =
  "Filter subclause. With a single value, return results where F == V. With two or more values, return results where F matches *any* of the values (i.e.`IN`)

     (= f v)
     (= f v1 v2) ; same as (or (= f v1) (= f v2))"
  (partial equality-filter := or))

(def ^:ql ^{:arglists '([f v & more])} !=
  "Filter subclause. With a single value, return results where F != V. With two or more values, return results where F does not match *any* of the values (i.e. `NOT IN`)

     (!= f v)
