Glojure: Clojure interpreter hosted on Go, with extensible interop support
github.com
github.com
other related packages: https://joker-lang.org/ https://github.com/nooga/let-go
Also, I very much don't share your opinion based on experience, unless we are talking about straight up frameworks and not libraries.
I stopped working in java so maybe I'm too bruised by the J2EE 5 era, but what I saw from Go was an order of magnitude less verbose than my memories of java.
Also, most of the verbosity of that early version was very high flexibility (everything could be replaced) plus an XML-based configuration. I wouldn't really count XML in Java's verbosity, nor do I think that comparing it to vanilla Go is meaningful.
For similarly scoped libraries Java is less verbose due to go's error handling being all over the place.
That being said you should really check out how streams, records, switch expressions, pattern matching and all of the recent additions in the last 5 years have made Java a magnitude less verbose than Go.
- a ton of java is still legacy, ask works with java 7 vs java 17 and enjoy the laugh
- I assumed java culture was still too rotten by its roots. I've used streams but whenever I have to import BiFunction I feel very sad.
on the other side, the few go code I've seen was always very concise, or even when the code base wasn't very well designed it was, at worst, still below java
You’re basing your opinion on your feelings rather than objective facts of being in the ecosystem. Yes you may have to import BiFunction but that isn’t anymore verbose than having to write:
func(a A, b B) C
[0] https://www.jetbrains.com/lp/devecosystem-2023/java/Also, Oracle employees have many statistics available, and they routinely say that Java 8 is no longer the most used version.
Please.
So the thought is more like: because Go is popular, a good Clojure implemented in Go will let me bring all the Clojure goodies to many additional projects with tight integration for little fuss— not 'finally a big ecosystem, the JVM has no software'.
Another way to think about it is that different platforms often have their own 'killer libraries'. Maybe for working with some Docker or some IaC tools, a Go-hosted Clojure would be especially convenient, for example.
A while back someone set me straight, and I no longer do that. So much better to call Java directly. Seeing the Glojure/Go interop examples reminded me of this.
But if I can rich out to Golang, why not? More Clojures is better. Imagine a single Polylith repo with blocks that talk to Node, JVM, Go, Python, etc.? Woah, that's sounds insanely cool, right?
jank has a progress page to give you an idea how much is implemented so far: https://jank-lang.org/progress/
For those jankers wondering what Glojure means for Clojure on native, the main thing to note is that Glojure is an interpreter. No JIT or AOT compilation (right now). Looks like it's a great start for an interpreter, though. Not quite ready for prime time, given some of the todos in the code [0], but the structure of it looks quite intentional. Based on some of the code [1], it looks like the analysis could be largely a port of tools.analyzer, which is honestly a smart way to do it.
To the author, you may be interested in the clojure.core-test intitiative [2]. I'm aiming to get a good test suite for all Clojure dialects.
0: https://github.com/glojurelang/glojure/blob/e54deb6597ceafd3...
1: https://github.com/glojurelang/glojure/blob/e54deb6597ceafd3...
A bit more detail on some of your observations:
> No JIT or AOT compilation (right now).
I do plan to implement AOT compilation eventually. JIT, however, is more complex. Go's "plugin" standard library [2] could serve as a mechanism, but its support is limited and not without issues [3].
> it looks like the analysis could be largely a port of tools.analyzer
Exactly! Another key implementation strategy has been the handling of clojure.core. Instead of reimplementing everything from scratch, the Clojure 1.11 core libraries are programmatically transformed to work with Go [4]. However, this approach has its downsides — many functions appear to be available but are non-functional because parts of their implementation haven't yet been adapted.
And by the way, impressive progress on Jank! I've been following it closely and really admire the work you're doing.
[0] https://github.com/clojure/clojure/tree/master/test/clojure/... [1] https://github.com/jfhamlin/muscrat [2] https://pkg.go.dev/plugin [3] https://github.com/golang/go/issues/19282 [4] https://github.com/glojurelang/glojure/tree/808165fdc7e65672...
The implementation of the [HAMT][1]-based vector in Go is [interesting][2].
[1]: https://infoscience.epfl.ch/server/api/core/bitstreams/f66a3...
[2]: https://github.com/glojurelang/glojure/blob/main/internal/pe...
0. https://pkg.go.dev/github.com/glojurelang/glojure/pkg/glj
1. http://clojure.github.io/clojure/javadoc/clojure/java/api/pa...
I am not sure but this seems rather interesting. But doesn't this technically just implement a flavour of lisp.
I am not sure but a technical way to do this as well could be to use something like fennel which can convert to lua and a lua vm written in golang as a poor man's lisp in go
(->> "you"
strings.ToUpper
(fmt.Sprintf "hi %s"))
(doto "hi"
fmt.Println
fmt.Println
fmt.Println)A lot of clojure developers could benefit from this immensely.
On a different note there was some movement to port clojure to the CLR And that would open the entire .NET ecosystem up, which I would love to see as an alternative to the JVM
But web and http is definitely not lacking in anything in the JVM world, given that half the business-critical backends of the internet runs on it.
Curious what you think Clojure developers could benefit from specifically.
Having done web services in both languages I much prefer the experience in Clojure. E.g. found error handling in Gin to be very cumbersome (AbortWithStatusJSON and such). The deployment story is nicer in Go, tho.
Clojue CLR is behind JVM support (and performance), but it has been a thing from the start, not just a "port".
Clojurescript doesn't use the same conventions in import/require statements: you're supposed to import macros using :require-macros or :refer-macros (I'm not even sure anymore). Conversely, `:refer :all` was banned in a prescriptivist attempt at fixing Clojure "mistakes", the rationale behind this decision being that with `:refer :all` it's not always obvious what namespace required symbols come from. Yet, with a REPL or a language server, it's very easy to get that info.
The point I want to make is that because of this porting Clojure code to Clojurescript implies a lot of inessential changes to the ns forms in your project. E.g: https://github.com/kachayev/muse/blob/8db4d5de82a8acccb4486c..., but I've done far worse.
It doesn't need to be that way.
A workaround is using Reader Conditionals (https://clojure.org/reference/reader#_reader_conditionals) and specifying platform differences where they matter, but it's awkward to say the least. What most projects do is to separate "common" namespaces and use the `.cljc` extension to indicate they're multi platform, and keep platform specific things in namespaces with `.clj`, `.cljs`, etc.
This is exactly what I witnessed when finding the example above.
Out of frustration, I tried patching shadow-cljs one afternoon and was able to implement :refer :all as well as automatically generating :require-macros when needed to some extent, but I haven't put the time to make it work fully. I don't think this is a limitation caused by the lack of a Clojurescript compiler that can run in a Javascript runtime. In short, I don't think this is an essential limitation of the way the language is hosted within its target language, unlike things like Vars, which are not introspectable at runtime in js.
Go hosted in Clojure: clogo?