Since Rama defines it's own dataflow language as a DSL in Clojure, linting it is a difficult problem. This repo defines the rules for how Rama code should be re-written such that clj-kondo can provide helpful warnings and errors as effectively as possible.
The clj-kondo extensions for Rama come bundled with the Rama jar when installing dependencies. This means your editor should import the clj-kondo rules for you automatically, but in case it doesn't or you favour using clj-kondo from a terminal, you can get clj-kondo to import the linting rules for Rama by running
You can get clj-kondo to import the linting rules for Rama by running:
clj-kondo --lint "$(clojure -Spath)" --copy-configs --skip-lint
or
clj-kondo --lint "$(lein classpath)" --copy-configs --skip-lint
If you're using leiningen.
Note that if your dependency on Rama is specified under a specific alias or
profile, you need to make sure to include that in the clojure
or lein
command. Otherwise the Rama jar won't be on the classpath.
There are a number of Rama features that are known to not lint correctly. Since Rama segments get transformed into a graph, reorganizing the code to successfully lint everything is difficult, and as such skips out on a lot of that at the moment.
- Capturing emits from multiple output streams
(my-ramaop :> *out :error> *ex)
- Defining anchors in a nested context
(anchor> <X>)
(<<branch <X>
(anchor> <Y>))
(<<branch <Y>)
- Defining anchors as a part of capturing output streams
(my-ramaop :> *out :error> <error> *ex)
(<<branch <error>
(println *ex))
Rama dataflow code is written in, what appears to be, a linear style, compared
to Clojure where everything is lexically scoped. As such, the general premise
of this is to transform Rama code so that emits are rewritten as nested lets
.
For example,
(?<-
(identity 1 :> *x)
(identity 2 :> *y)
(println (+ *x *y)))
Would be rewritten as
(let [*x (identity 1)]
(let [*y (identity 2)]
(println (+ *x *y))))
The tests contain extensive examples of how every type of form is rewritten such that it can be interpreted as regular Clojure code.
Since having access to the following forms is important for the transformation
rules, hooks in the config.edn
are only defined for top-level forms.
Transformation rules for special Rama forms, such as <<if
or batch<-
are
written as extensions of the split-form
or handle-form
methods in
rama_hooks.clj
.