Home

Awesome

The Slick programming language

The Slick programming language is a Lisp/Scheme-style s-expression surface syntax for the Go programming language, with a few additional features. Apart from the additional features, it is a faithful mapping of all Go programming language features into s-expression notation, with very few, very minor intentional exceptions.

This is an early release and should be considered work in progress. A lot about Slick might still change, and it is not recommended to use in production unless you're adventurous.

Here is a Hello World in Slick:

(package main)

(import "fmt")

(func main () ()
  (fmt:Println "Hello, World!"))

Additional features:

Deviations from Go:

These are the only deviations. Especially, like Go, Slick is statically typed, distinguishes between statements and expressions, etc., etc.

See the Slick programming language specification for the full picture.

Macros

Macros are provided by way of Go's plugin facility. For this reason, if you want to use macros, this currently only works on Linux, FreeBSD, and macOS. You should still be able to use Slick on other platforms without macro support, and may be able to cross-compile from Linux, FreeBSD, and macOS, but we haven't tested this yet.

An advantage of using plugins to provide macros is that there is no need for a Slick interpreter. The current implementation is a pure Slick-to-Go compiler.

Lisp/Scheme-style lists for Go

The Slick package also includes a comprehensive library for pair/cons-cell-based list processing with all kinds of bells and whisles that advanced Lisp/Scheme programmers are used to. The library is designed in such a way that it can be used from Go as well as Slick. See the folder list for more details.

How to build Slick

So far, we only provide the Slick-to-Go compiler. It is a simple compiler that doesn't perform any type checks or advanced semantic analysis on its own, but relies on the Go compiler to do most of the actual work. There is also no build system, or so - the compiler so far can only process one file at a time.

Building the core Slick compiler

You can build the core Slick compiler just by issuing go build in the main folder.

Building the core Slick plugin

The core Slick plugin provides implementations for quotation and quasiquotation as a built-in set of macros implemented in Slick itself. Therefore, you first need to build the Slick compiler before you can compile the Slick plugin. Proceed as follows:

Building your own macro libraries

A library typically consists of some runtime support functions and some compile-time macro functions.

Let's say you want to implement a library for Lisp/Scheme-style binding forms. Here is a step-by-step guide how to do this:

    (package bindings)

    (func Bind ((f (func ((x (interface))))) (x (interface))) ()
      (f x))
    (package main)

    (import
      "github.com/pcostanza/slick/list"
      "github.com/pcostanza/slick/compiler"
      '(bl "github.com/pcostanza/bindings"))

    (use '(bp "github.com/pcostanza/bindings"))

    (func LetStar ((form (* list:Pair)) (_ compiler:Environment))
                  ((newForm (interface)) (_ error))
      (:= bindings (list:Cadr form))
      (:= body (list:Cddr form))
      (if (== bindings (list:Nil))
        (return (values `(splice ,@body) nil))
        (begin
          (:= firstBinding (list:Car bindings))
          (:= restBindings (list:Cdr bindings))
          (return (values
                    `(bl:Bind (func ((,(list:Car firstBinding) (interface))) ()
                                (bp:LetStar (,@restBindings) ,@body))
                              ,(list:Cadr firstBinding))
                    nil)))))

Using a macro library

Let's try to use the bindings library in an example project.

    (package main)

    (import "fmt")

    (use "github.com/pcostanza/bindings")

    (func main () ()
      (bindings:LetStar ((x "Hello, World!"))
        (fmt:Println x)))

What's next?

The next step is to make sure that user-defined read tables can be used in source code; and that "funcall" forms can be declared (the latter is not straightforward to explain, not sure it will actually work, but also not that important).

Other things to do:

If you want to help with any of this, you are very welcome. Feel free to contact me at pascal dot costanza at imec dot be

Community