/gowen

clojure, but worse

Primary LanguageGo

yet another lisp

A lisp that tries to look like clojure with topological sorting by dependencies before evaluation. Run with go run cmd/gowen/* or install with go install github.com/niklasfasching/gowen/cmd/gowen

https://raw.githubusercontent.com/niklasfasching/gowen/master/etc/repl-example.gif

features

destructuring

(let [[x & xs :as original] [1 2 3]]
  [x xs original])
;; [1 (2 3) [1 2 3]]

(let [{:keys [x y z] :as m} {:x 1 :y 2}]
  [x y m])
;; [1 2 {:y 2, :x 1}]

(let [{{[bar & bars] :bars} :foo} {:foo {:bars ["bar" "bar" "bar"]}}]
  [bar bars])
;; ["bar" ("bar" "bar")]

seamless go interop

Conversion from/to go is handled automatically. Go packages can be added to gowen via generate - check out lib/core main.go for that.

var values = map[string]interface{}{
	"add":   func(x, y int) int { return x + y },
	"time/now":   time.Now,
}
gowen.Register(values, "(def x 42)")
(print x)
;; 42

(add x 42.0)
;; 84

(time/now)
;; time.Time{wall:0xbef3400896edba59, ext:2270378317, loc:(*time.Location)(0x704160)}
(type (time/now))
;; "time.Time"

;; field & method access via dot symbols

(.year (time/now)) ; automatic capitalization - translates to .Year()
;; 2018

(let [out (-> (exec/command "echo" "Hello World!")
              .combinedOutput)]
  (format "%s" out))
;; "Hello World!\n"

macros & quasiquote

(defmacro foo-defn [name args & body]
  `(defn ~(symbol (str "foo" name)) ~args ~@body))
(foo-defn bar [] (print "foobar!"))
(foobar)
;; foobar!

order independent evaluation

EvalTopological sorts toplevel forms before evaluation. As global symbols can only be defined at the toplevel (and cannot be altered) this takes care of e.g. “circular” dependencies between files. No real use case for that yet, just found it interesting.

;; e.g. save as x.gow and run via gowen ./x.gow
(def bar (+ foo 1))
(def foo 1)

(print foo bar)
;; 1 2

non features

performance

  • pretty > fast
    ;; gowen is crazy slow! just summing a few number takes a second :D
    (time/measure (reduce + 0 (repeat 10000 1)))
    ;; took 1254.757247 ms
    ;; 10000
        

resources