Gimmick aims to be a lisp language that features static type checking, first class concurrency support and native code generation on top of a classic Scheme-like core.
At present, all of these features are missing and only a basic interpreter exists that can be called from within a Go program.
- readline - a Go library implementing readline features (
cmd/gimmickREPL dependency only)
- echo - a Go http router used for the Ruse server
The dependency Go libraries can be installed with the following commands.
go get github.com/chzyer/readline go get github.com/tbogdala/gimmick
First, build the main tool:
cd $GOPATH/src/github.com/tbogdala/gimmick/cmd/gimmick go build
Once this executable is built, it can be called with a command-line
parameter to indicate the operation to perform. At present only the
command is supported.
To start the REPL interpreter, run the following:
./gimmick repl <file_to_load.gmk>*
At this point, you can enter in code and evaluate it in a multiline fashion.
The following special commands are supported:
.helpprints the list of special commands
.parseshows the parse message for the current sexp
.quitexits the REPL
.resetresets the environment currently used for evaluation
.typeshows the type of the last result value
[empty line]erases the current command in a multi-line context
- basic interpreter easily callable from Go
- uses symbolic expressions (sexp) for code and data like a lisp
- embedded HTTP server within the REPL for editor integration
- supports types: int64, float64, boolean, lists, symbols and strings
- basic math operations:
- basic comparisons:
- basic special forms:
- special syntax for:
quasiquoteas backquote (`),
unquoteas a comma (,), and
unquote-splicingas comma-ampersand (,@)
- basic lisp list functions:
- function construction:
- variable number of parameters with the form:
(lambda (x y . z) ...)
- non-hygienic macros (lisp style) with the form:
(defmacro name (args) body)
- basic timing for benchmarks:
(timed-apply <proc> <args>*)
- tail-call optimized
A more verbose guide to the current language features can be found in
Many major features are yet to come:
- transition unit tests to gimmick itself
- module system
- static type checking
- concurrency support
- consider possible error handling mechanisms
- native code generation
- debugging support
- consider a 'safe' compilation/interpreter method that will not
have functions like
set!supported to fully enforce a non-mutable world view
A small example would look like this:
(begin (define fib (lambda (n) (if (< n 2) 1 (+ (fib (- n 1)) (fib (- n 2)))))) (fib 30) )
- (Windows only) The readline library used doesn't play nice with the terminal
mintty, but the executable works fine from the basic command prompt or other terminals such as cmder.
History and Thanks
One major influence on how this projected developed was Peter Norvig's article (How to Write a (Lisp) Interpreter (in Python)). Long before I read that article, I stumbled on Write Yourself a Scheme in 48 Hours back in my Haskell days. I messed around with it and started to believe in my ability to get something of my own up and running.
In the interim, I spent some time working with Lua having embedded it in my C graphics library called Portable Glue. All this time I wanted to use Scheme but things didn't work out despite some early success with my Gambit-C usage.
Now that I've been working on Fizzle and my associated game libraries, I've been looking for a good lisp-like embedded language and found quite a few. However, after some investigation, I felt that it'd be better if I start on my own language to support the features that I'm interested in. I came across this article on scm.go which helped restart me on the language design path. And naturally, I had to read the relevant portions of SICP.
Gimmick is released under the BSD license. See the LICENSE file for more details.