[HN Gopher] Glojure: Clojure interpreter hosted on Go, with exte...
       ___________________________________________________________________
        
       Glojure: Clojure interpreter hosted on Go, with extensible interop
       support
        
       Author : networked
       Score  : 219 points
       Date   : 2024-11-29 09:29 UTC (5 days ago)
        
 (HTM) web link (github.com)
 (TXT) w3m dump (github.com)
        
       | breadchris wrote:
       | Clojure hosted on Go is something that I really hope gets more
       | attention. Clojure being built on top of Java is a fine decision,
       | but I would love to use clojure to compose the ever growing
       | library of stable packages that exist in the Go ecosystem.
       | 
       | other related packages: https://joker-lang.org/
       | https://github.com/nooga/let-go
        
         | vips7L wrote:
         | Doesn't the Java ecosystem have even more stable packages?
        
           | packetlost wrote:
           | Maybe, but IME they tend to be lower quality than the Go
           | ones. Java has some truly great libraries, but culturally has
           | an entirely different approach to almost everything.
        
             | tombert wrote:
             | Any specific examples? The stuff I've used has been broadly
             | better in JVM land than Go land, but I mostly work with
             | Kafka stuff.
        
           | xyproto wrote:
           | Stable, often overenigneered and often hard to upgrade when
           | used as several dependencies together.
        
             | gf000 wrote:
             | How does a less expressive language help with any of these?
             | 
             | Also, I very much don't share your opinion based on
             | experience, unless we are talking about straight up
             | frameworks and not libraries.
        
               | 708145_ wrote:
               | A highly expressive language makes overengineering
               | easier.
        
               | gf000 wrote:
               | Java is definitely not even close to being "highly
               | expressive". It has been a very simple language, and was
               | always very conscious of remaining that with a slow, but
               | well-thought-out evolution, learning from others'
               | mistakes.
        
               | agumonkey wrote:
               | i guess java confused verbosity with expressiveness
        
               | gf000 wrote:
               | Without entering the territory of flamewars, Go is
               | objectively more verbose than Java, so I don't really see
               | your point.
        
               | aatd86 wrote:
               | Does someone disagreeing with your statement make it not
               | _objective_ anymore? :o)
        
               | agumonkey wrote:
               | Hmm maybe I'm too out of touch. You're talking about
               | recent java (12+) vs go ?
               | 
               | 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.
        
               | gf000 wrote:
               | Java EE was/is a whole platform, framework, deployment
               | model all in one.
               | 
               | 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.
        
           | pxc wrote:
           | I think most Clojure implementations take the lesson from the
           | original that to be embedded in a platform rich with mature
           | libraries is a great strength, but aren't dogmatic about some
           | idea that only a few runtimes are worthy of such embedding.
           | The idea is more 'make it practical to bring a Lisp to work
           | and integrate it with your existing projects', rather than
           | 'create one implementation to rule them all by choosing the
           | biggest ecosystem to integrate with' (though a consideration
           | aligned with the letter was doubtless a factor in the choice
           | of platform for the first implementation).
           | 
           | 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.
        
             | mark_l_watson wrote:
             | A little off topic, but as someone who has occasionally
             | used Clojure since Rich released a beta version (on many
             | professional gigs, and to support examples in my Clojure AI
             | book), I used to make such a mistake by writing wrappers in
             | Clojure for Java libraries I used.
             | 
             | 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.
        
         | throwaway894345 wrote:
         | I really like Go as well, but the JVM is a lot better at
         | hosting languages than any interpreter implemented in Go. You
         | will likely pay a significant performance cost even for a very
         | optimized Go interpreter. I wish this were not the case.
        
         | iLemming wrote:
         | My latest favorite kid on the block is nbb. The REPL spins up
         | instantaneously, and you can use all Node packages, it requires
         | virtually zero setup.
         | 
         | 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?
        
       | bbqfog wrote:
       | Neat, the macros even work:                 (->> "you"
       | strings.ToUpper         (fmt.Sprintf "hi %s"))             (doto
       | "hi"         fmt.Println         fmt.Println         fmt.Println)
        
       | MathMonkeyMan wrote:
       | I get "panic:" at the REPL once it loads. :(
       | 
       | 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...
        
         | jfhamlin wrote:
         | Sorry to hear it's not working for you . Please feel free to
         | file an issue on the repo with any relevant details! While I
         | only work on Glojure sporadically at the moment, I really value
         | feedback like this, and I'll prioritize investigating critical
         | issues like it.
        
       | behnamoh wrote:
       | Clojure hosted in Go: glojure
       | 
       | Go hosted in Clojure: clogo?
        
         | Maksadbek wrote:
         | Go hosted in Clojure should be Jo
        
           | binary132 wrote:
           | I like "Glo"
        
             | jpcom wrote:
             | Don't host Go in Clojure.
        
               | ludston wrote:
               | You're not my dad.
        
               | xyproto wrote:
               | Luke?
        
         | throw9265017485 wrote:
         | How about "clogure" where the "g" is pronounced as in "GIF"?
        
           | robertlagrant wrote:
           | That made me laugh.
        
       | jpcom wrote:
       | Clojure hosted on Go, fascinating! What must-have Go packages are
       | you most excited for?
        
         | no_wizard wrote:
         | The Go ecosystem does web and http services extremely well. It
         | really shines when used in this manner.
         | 
         | 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
        
           | gf000 wrote:
           | Clojure was meant to be a guest language, so the more
           | platforms it supports, the merrier.
           | 
           | 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.
        
           | monomers wrote:
           | > lot of clojure developers could benefit from this
           | immensely.
           | 
           | 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".
        
       | jitl wrote:
       | Tangentially related clojure dialect compiling via C++ & LLVM:
       | https://jank-lang.org/
       | 
       | jank has a progress page to give you an idea how much is
       | implemented so far: https://jank-lang.org/progress/
        
         | Jeaye wrote:
         | Thanks for the shout out. :) It's always great to see more
         | Clojure dialects.
         | 
         | 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...
         | 
         | 2: https://github.com/jank-lang/clojure.core-test
        
           | jfhamlin wrote:
           | Glojure author here! Your analysis is spot-on :). I'll
           | definitely take a look at clojure.core-test. As components
           | mature, I focus on improving compatibility by porting tests
           | from Clojure [0], but they often require modifications to
           | accommodate differences in the host language. As you noted,
           | there are still several fundamental features missing -- most
           | notably some core data structures. That said, the
           | implementation is robust enough to support another non-
           | trivial hobby project [1].
           | 
           | 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/cloju
           | re/... [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...
        
       | nhlx2 wrote:
       | Perhaps I can finally get into go!
        
       | whateveracct wrote:
       | Can Go easily call Glojure? Not clear from the README.
        
       | anacrolix wrote:
       | Does STM work
        
         | vaylian wrote:
         | Good question. This is probably hard to implement, but I can't
         | recall any real-world Clojure project that uses software
         | transactional memory (STM).
        
       | dmead wrote:
       | In grad school I did a Haskell interpreter hosted in clojoure.
        
       | ValentinA23 wrote:
       | Something I find problematic about the various implementations of
       | Clojure is the lack of specs to determine a common ground.
       | 
       | 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.
        
         | masijo wrote:
         | I agree with your criticism but those "mistakes" sadly come
         | with inheriting implementation details of the hosted
         | environment. As far as I understand, ClojureScript couldn't
         | workaround some JavaScript limitations regarding macros and
         | thus had to go with `:require-macros`.
         | 
         | 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.
        
           | ValentinA23 wrote:
           | >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.
        
         | kccqzy wrote:
         | Oh yeah I definitely lost an hour debugging why something
         | doesn't work in ClojureScript: it turns out I used :refer
         | rather than :refer-macro. It's still possible to use :refer,
         | but it requires some changes to the library such as
         | https://github.com/Engelberg/instaparse/commit/0cd039659dc76...
        
         | iLemming wrote:
         | Legit complaint, can't really argue, yet, at the same time,
         | using various Clojure dialects and Clojure-like Fennel requires
         | so much less mental overhead. Even switching between Javascript
         | and Typescript is not at the same level of unsophistication. I
         | feel biased, but targeting JVM, Node, Browser, Bash, Lua, and
         | now Go using a single set of idioms and patterns feels so much
         | nicer and less frustrating. Even with all the little quirks and
         | differences.
        
       | Imustaskforhelp wrote:
       | Interesting , I was rather interested in seeing something like
       | golang which can compile to bytecode in something like java or
       | the compiler because so many times I have heard that golang is
       | slower because of AOT and what not when I see some comparisons
       | b/w golang and java , and all I thought was well , why not add
       | this feature.
       | 
       | 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
        
       | zerr wrote:
       | Why not transpile to Go and then build a native executable?
        
         | jfhamlin wrote:
         | Glojure author here. Transpiling to Go is definitely something
         | I've considered -- and am still considering! My current focus
         | is on use cases that prioritize interactivity, which makes the
         | existing interpreter-based approach a better fit for now. That
         | said, transpiling parts of the system (especially the core
         | libraries) to Go is a strong possibility down the road,
         | particularly as a way to improve startup performance. After
         | that, it could be made available as a public feature.
        
       | systems wrote:
       | well, it should be lisp all the way down
       | 
       | https://www.loper-os.org/?p=42
        
       | sesm wrote:
       | Regular Clojure relies on JVMs ability to load classes at
       | runtime. Can Go VM do that?
        
         | gf000 wrote:
         | If it's an interpreter, then surely.
        
       | mark_l_watson wrote:
       | I love projects like this. In addition to being great for
       | bringing 'a Lisp lifestyle' to the Go ecosystem, it might be a
       | good addition to the fast startup interpreter space, similar to
       | the very good Babashka project.
        
       ___________________________________________________________________
       (page generated 2024-12-04 23:01 UTC)