This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-08-15
Channels
- # alda (1)
- # beginners (24)
- # biff (9)
- # calva (55)
- # cherry (1)
- # clj-kondo (36)
- # cljs-dev (3)
- # clojure (37)
- # clojure-austin (2)
- # clojure-brasil (1)
- # clojure-europe (14)
- # clojure-nl (1)
- # clojure-norway (24)
- # clojure-spec (3)
- # clojure-uk (1)
- # community-development (6)
- # core-typed (1)
- # datalevin (5)
- # datomic (28)
- # emacs (14)
- # events (1)
- # gratitude (9)
- # hyperfiddle (27)
- # instaparse (3)
- # joker (16)
- # lsp (89)
- # malli (24)
- # missionary (2)
- # nbb (5)
- # off-topic (59)
- # re-frame (12)
- # reitit (17)
- # releases (4)
- # sci (14)
- # spacemacs (1)
- # squint (7)
- # xtdb (41)
hey, folks! another plug of a related project here 🙂. i've been lurking in this channel for a bit because i've been interested in bringing together go and clojure, and a while back - before i was aware of joker - i began working on a clojure interpreter in go with comprehensive support for both the clojure core libraries and host language interop
the project is not yet at enough feature parity to warrant what i'd call an "alpha" release - e.g. some basic functions like mapv
don't yet work because of some missing primitives (in the case of mapv
, the missing primitive is a transient vector implementation) - but it's got enough in it that i'm curious to gauge interest and solicit some feedback
given that the goal is to get as close as possible to a full implementation of clojure in golang, i've namesquatted the name "glojure." i'd be happy to rename the project if the community believes this is too presumptuous 🙂
https://github.com/glojurelang/glojure
some example usage in the 🧵, but here are some quick highlights and lowlights
Highlights
1. transparent Go interop with arbitrary packages (some codegen required).
a. all of the go 1.19 standard library is included by default.
2. progress towards implementation of all of clojure.core
(sans java-specific features).
a. glojure.core
is "implemented" as a programmatic transformation of clojure's own core libraries (as of clojure 1.11) rather than by implementing core by hand.
3. a partial implementation of glojure.core.async
using go's concurrency primitives (goroutines and channels)
Lowlights
1. minimal and out-of-date documentation
a. i intend to update it after a few more features are added
2. poor performance relative to clojure
a. the interpreter is a tree-walking interpreter, which incurs a ton of overhead. this may eventually be mitigated by implementing a bytecode interpreter
b. the REPL CLI takes 500-1000ms to start up, due to processing the core libraries. i'm already looking at addressing this by pre-processing the core libraries (much as joker appears to)
3. many broken core functions which have yet to be mapped to work in glojure, or whose primitive dependencies (e.g. transients or STM) have yet to be implemented
Acknowledgement
joker itself has been very helpful in bootstrapping this project. the persistent hash map implementation was taken, with some modification to allow for arbitrary go keys and values, from joker 🙂
a short example of interop in action, from the README:
;; example.glj
(ns example.server)
(defn echo-handler
[w r]
(io.Copy w (.Body r))
nil)
(net$http.Handle "/" (net$http.HandlerFunc echo-handler))
(net$http.ListenAndServe ":8080" nil)
and using core.async in the REPL:
user=> (require '[glojure.core.async :as a])
nil
user=> (def ch (a/chan))
#'user/ch
user=> (a/go
... (doseq [x (range 10)]
... (a/>! ch x))
... (a/close! ch))
#object[ 0xf381f80e "#object[chan interface {}]"]
user=> (a/<! ch)
0
user=> (a/<! ch)
1
user=> (a/<! (a/go-loop []
... (let [v (a/<! ch)]
... (when-not (nil? v)
... (println "got:" v)
... (recur)))))
got: 2
got: 3
got: 4
got: 5
got: 6
got: 7
got: 8
got: 9
nil
user=>
feel free to respond in this thread or DM me if you have questions or feedback. i'd also be happy to see issues filed if you give it a spin and want to report bugs or feature requests (or contribute!)
@U04CAK74QG4 this is great work!
I am getting the following error when trying to install glojure:
> go install
#
mod/github.com/glojurelang/[email protected]/pkg/gen/gljimports/gljimports_darwin_amd64.go:5592:41: undefined: runtime.GOTOOLDIR
Small correction on https://github.com/glojurelang/glojure#comparisons-to-other-go-ports-of-clojure: Joker does have https://candid82.github.io/joker/joker.core.html#go, although admittedly very limited.
what version of go are you using? it looks like you have a name missing from the runtime package. currently you’ll need at least go 1.19
and whoops, i’ll correct the table! thanks for pointing that out. (it’s a very early pass at the readme btw; i intend to add additional aspects, e.g. maturity/stability)
interesting! i use nix in development, and it looks like nix patches extern.go to add this function on installation for some reason . not great for compatibility. i'll need a more reliable way to generate these imports (and to test). thanks for finding the bug 🙂
pushed a small fix to omit the symbol!
thanks for giving it a spin!