The Slick programming language is an s-expression surface syntax for Go.

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:

  • Support for Lisp-style macros.
  • Support for Scheme-style quotation and quasiquotation.
  • Support for Common-Lisp-style reader / read tables.
  • Support for spliced blocks and spliced declarations.

Deviations from Go:

  • Block comments nest.
  • All numbers start with a digit. Especially, floating point numbers cannot start with a ..
  • An identifier cannot start with a _ if it has more than one character.

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:

  • Change to the directory lib/slick.
  • Compile the Slick plugin to Go using the Slick compiler: slick plugin.slick plugin.go.
  • [Optional] Format the code to make it look nicer: go fmt plugin.go.
  • Build the Slick plugin: go build -buildmode=plugin plugin.go.
  • Change back to the root folder: ../...
  • Copy the plugin to the plugins folder: cp lib/slick/plugin.so plugins.

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:

  • Create a folder bindings and change to it.
  • Create a go.mod file for the Go module system. In our example, we add only one line: module github.com/exascience/bindings. Feel free to use your own package name and location.
  • Create a file bind.slick with the following contents. (This is not a very useful library, but provided only for illustration.)
    (package bindings)

    (func Bind ((f (func ((x (interface))))) (x (interface))) ()
      (f x))
  • Compile the Slick code to Go: slick bind.slick bind.go.
  • [Optional] Format the code to make it look nicer: go fmt bind.go.
  • Create a folder slick and change to it.
  • Create a file plugin.slick with the following contents. This file provides the macro function LetStar which is similar to the let* binding form found in many Lisp and Scheme dialects.
    (package main)

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

    (use '(bp "github.com/exascience/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)))))
  • Set the SLICKROOT environment variable to the root folder of your Slick installation: export SLICKROOT=~/develop/go/slick, so that the default Slick plugin (with support for quotation and quasiquotation) can be found.
  • Compile the Slick code to Go: slick plugin.slick plugin.go.
  • [Optional] Format the code to make it look nicer: go fmt plugin.go.
  • Build the plugin: go build -buildmode=plugin plugin.go.

Using a macro library

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

  • Create a test folder and change to it.
  • Create a file hello.slick with the following contents:
    (package main)

    (import "fmt")

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

    (func main () ()
      (bindings:LetStar ((x "Hello, World!"))
        (fmt:Println x)))
  • Create a folder for storing the bindings plugin that we want to use in this code: mkdir -p plugins/github.com/exascience/bindings/slick.
  • Copy the plugin from above into this folder: cp ~/develop/go/bindings/slick/plugin.so plugins/github.com/exascience/bindings/slick.
  • Set the SLICKPATH environment variable to the current folder, so that the bindings plugin can be found: export SLICKPATH=..
  • Compile the Slick code to Go: slick hello.slick hello.go.
  • [Optional] Format the code to make it look nicer: go fmt hello.go.
  • Run the program: go run hello.go.

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:

  • Add a variant of destructing-bind or destructuring-case to aid in macro programming.
  • Add static type checks, semantic analysis, and support for compiler environments directly into the Slick compiler.
  • Add support for building complete packages rather than single files.
  • Get rid of SLICKROOT and SLICKPATH, and embed Slick into the Go module system somehow.
  • Add a mode for Emacs, Goland, or other editors.
  • Add support for local macros (macro and macrolet).
  • Implement an interpreter for Slick.
  • Implement a Go-to-Slick compiler.
  • Stress-test the compiler, try out all the language features, see if they work well and are easy to read and write.
  • Write some tutorials, example code, better documentation, etc.

A discussion forum to discuss Slick would probably also be helpful.

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

Similar Resources

⛳ A minimal programming language inspired by Ink, JavaScript, and Python.

⛳ Golfcart My blog post: Creating the Golfcart Programming Language Getting Started Scope Rules Usage Building and tests Contributions License Golfcar

Sep 6, 2022

Simple, safe and compiled programming language.

The X Programming Language Simple, safe and compiled programming language. Table of Contents Overview OS Support Contributing License Overview The X p

Dec 28, 2022

A interpreter of SweetLang, is writed in Go Programming language.

SweetLang ( Soon ) A interpreter of SweetLang, is writed in Go Programming language. SweetLang is made with clarity and simplicity we try to make its

Oct 31, 2021

Monkey programming language project from 'Writing An Interpreter In Go'and 'Writing A Compiler In Go' Books

Monkey programming language project from 'Writing An Interpreter In Go'and 'Writing A Compiler In Go' Books

Monkey Monkey programming language 🐒 project from "Writing An Interpreter In Go

Dec 16, 2021

ReCT-Go-Compiler - A compiler for the ReCT programming language written in Golang

ReCT-Go-Compiler A compiler for the ReCT programming language written in Golang

Nov 30, 2022

ReCT-Go-Compiler - A compiler for the ReCT programming language written in Golang

ReCT-Go-Compiler A compiler for the ReCT programming language written in Golang

Nov 30, 2022

WindLang, A simple programming language built with golang 🍃

WindLang, A simple programming language built with golang 🍃

WindLang, A simple programming language built with golang 🍃 WindLang, A simple programming language built with golang 🍃 What is wind? Playground Coo

Dec 1, 2022

A dialect of Lisp extended to support concurrent programming, written in Go.

LispEx A dialect of Lisp extended to support concurrent programming. Overview LispEx is another Lisp Interpreter implemented with Go. The syntax, sema

Nov 22, 2022

Golem is a general purpose, interpreted scripting language.

Golem is a general purpose, interpreted scripting language.

The Golem Programming Language Golem is a general purpose, interpreted scripting language, that brings together ideas from many other languages, inclu

Sep 28, 2022
T# Programming Language. Something like Porth, Forth but written in Go. Stack-oriented programming language.

The T# Programming Language WARNING! THIS LANGUAGE IS A WORK IN PROGRESS! ANYTHING CAN CHANGE AT ANY MOMENT WITHOUT ANY NOTICE! Something like Forth a

Jun 29, 2022
Yayx programming language is begginer friendly programming language.
Yayx programming language is begginer friendly programming language.

Yayx Yayx programming language is begginer friendly programming language. What have yayx: Easy syntax Dynamic types Can be compiled to outhers program

Dec 27, 2021
Yayx programming language is begginer friendly programming language.

Yayx Yayx programming language is begginer friendly programming language. What have yayx: Easy syntax Dynamic types Can be compiled to outhers program

May 20, 2022
Expression evaluation engine for Go: fast, non-Turing complete, dynamic typing, static typing
Expression evaluation engine for Go: fast, non-Turing complete, dynamic typing, static typing

Expr Expr package provides an engine that can compile and evaluate expressions. An expression is a one-liner that returns a value (mostly, but not lim

Dec 30, 2022
a dynamically typed, garbage collected, embeddable programming language built with Go

The agora programming language Agora is a dynamically typed, garbage collected, embeddable programming language. It is built with the Go programming l

Dec 30, 2022
Gentee - script programming language for automation. It uses VM and compiler written in Go (Golang).

Gentee script programming language Gentee is a free open source script programming language. The Gentee programming language is designed to create scr

Dec 15, 2022
Port of the lemon parser generator to the Go programming language

From the golang-nuts mailing list (with few modifications): --== intro ==-- Hi. I just want to announce a simple port of the lemon parser generator

Feb 17, 2022
An LL(1) parser generator for the Go programming language.

What is it? I have implemented an LL(1) parser generator for the Go programming language. I did this to build parse trees for my HAML parser. You can

Jan 18, 2022
PHP bindings for the Go programming language (Golang)

PHP bindings for Go This package implements support for executing PHP scripts, exporting Go variables for use in PHP contexts, attaching Go method rec

Dec 27, 2022
Pineapple Lang is a simple programming language demo implements by Go

Pineapple Lang is a simple programming language demo implements by Go. It includes a hand-written recursive descent parser and a simple interpreter, although the language is not even Turing-complete. But this repo's main goal is to give beginners of compilation principles a warm up and a simple look at how a programming language is built.

Dec 26, 2022