Meet zygomys — An embedded scripting language for Go

Time for some cuteness to brighten up your Monday. This time we have a dialect of LISP that is designed as an embedded extension language for Go. Meet zynomys, the pocket gopher that will help you drive your program with minimal fuss and maximum convenience.

Zynomys is named after ‘zygo’ the Greek word for yoke, indicating a pair or a union of two things, and ‘mys’ also Greek for mouse and it’s a dialect of LISP that is designed as an embedded extension language for Go.

Let’s take a closer look.

Cuteness comes in all shapes and sizes

Some of the benefits of using zygomys include:

Drive your program with minimal fuss and maximum convenience, since zygomys allows you to create a Domain Specific Language.

Plays nicely with Go programs and Go structs.

Ideally suited for driving complex configurations and providing projects with a domain specific language customized to your problem domain since it speaks JSON and Msgpack fluently.

As mentioned earlier, zygomys is a dialect of LISP, however, it has certain differences from traditional LISP syntax, namely:

Using = for assignment and multiple assignment — The = sign represents assignment. To support Go-like multiple assignment, the = assignment operator supports multiple values on either side of the = sign.

Using dot-symbols for nested member selection — Dot-symbols act like path descriptors for referencing nested objects.

Minor syntax improvement: ^ replaces ` — In macros, templates (syntax-quotes) are introduced by the caret ^ instead of the backtick. This allows the convenient use of the backtick to delimit verbatim, newline and double quote containing strings, just as in Go.

defmap to create records — The defmap macro defines a new record type that is a hash table with a new name. Field definition order is always preserved upon display.

clojure like field access with the ‘:’ colon operator— Instead of writing (hget acre100 :friend), there is the briefer (:friend acre100)

clojure like threading with (-> hash field: field2: …) for picking out nested fields — Note a difference from clojure however: the colon is always on the trailing (right) side of the symbol. Note that a space after the -> operator is required. The newer dot-symbol syntax now offers the same functionality with even more compact notation. Both are retained as one may be easier to generate programmatically.

== instead of = for equality checking — Notice this in the repl snippet above. Its just less confusing to eyes accustomed to more common Go, C, etc. And we use ‘=’ for assignment.

Symbols can be invoked directly —Like scheme, in a function call, we evaluate the (1st) position just like all the other positions. The function position isn’t special. This means if a symbol refers to a function’s name, you can use that symbol in the first (function name) position, without fuss. No (funcall sym) needed as in lisp. There is a single namespace for all symbols.