Spice you code with Groovy!
Integrates Groovy into Clojure tooling.
Works like regular deftype
.
- Write fast imperative code for special cases
- Reload your groovy code dynamically with REPL
- Dynamically define an Exception classes hierarcy
- Dynamically implement abstract classes faster then
proxy
- Compile groovy code with the regualr
compile
Beta stage.
{:deps {io.github.darkleaf/polyglot.groovy {:git/sha "%SHA%"}}
clj -T:build prep-lib
First. Groovy was designed as embeddable language. So its compiler has good enough compiler API to integrate it with Clojure.
Second. Groovy compiler can link with dynamically loaderd classes. So you can implement an interface of a Clojure protocol in Groovy. It is possible to dynamically compile and load Java or Kotlin code but it will be linked only with AOT compiled classes.
Third. It is much easier to write Groovy code without an IDE than Java code.
Actually there are to flavors of the Groovy language. One is a regular dynamic Groovy. It call methods indirectly and employs both runtime and compile-time metaprogramming Second is a staticaly compiled and type checked Groovy. It uses only compile-time metaprogramming.
In case of Clojure we usually don't need of slow indirect method invocation,
so instead of regular Groovy this library compiles .groovy
files statically.
If you have to use dynamic features like methodMissing
or can't specify types you should use .dgroovy
file extension
or annotate a class or a method with @CompileDynamic
.
.groovy
, .gvy
, .gy
, .sgroovy
, .sg
and .java
are compiled with @CompileStatic
.
.dgroovy
and .dg
are compiled dynamically as a regular Groovy does.
Also you can use @CompileDynamic
and @CompileStatic
annotations to tune single class or method.
See config.
In most cases Static Groovy is a superset of Java, so you can even use .java
file extension!
With dynamically class (re)loading!
It is usefull when you need to load generated Java files.
Use g/defobject
just like def
or defn
.
;; src/my/project/core.clj
(ns my.project.core
(:require
[darkleaf.polyglot.groovy.core :as g]))
(g/defobject imperative-algorithm)
(comment
(imperative-algorithm 42))
// src/my/project/core/imperative_algorithm.groovy
package my.project.core
class imperative_algorithm extends AFunction {
def invoke(x) {
// ...
}
}
gen-class proxy exceptions
with
rwith
tap
When a clojure ns compiles it also compile all defined groovy classes just like deftype
.
It integrates with *compile-files*
. No configuration is required.
(compile 'my.project.core)
var('clojure.core', 'prn')(42)
println and flushing