Skip to content

Binding Values to the Environment

Louis Thibault edited this page Mar 16, 2021 · 1 revision

Environment Bindings

In this tutorial, we will show how to bind values and functions to the environment from Go code. In other languages, this is sometimes called "assigning to a variable". Note that Slurp provides special forms such as def and let to perform such actions from lisp code, and should generally be preferred. There are however two common scenarios in which it makes sense to bind values from Go:

  • You need to export a native Go datatype (e.g. a special struct) to lisp.
  • You need to export a native Go function (or struct method) to lisp.

This tutorial assumes you know how to configure and embed a Slurp interpreter in a Go program.

Binding Values

The preferred method for binding data is Interpreter.Bind, which takes a map[string]core.Any representing symbol-to-value mapping.

import (
    "context"

    "github.com/spy16/slurp"
    "github.com/spy16/slurp/builtin"
    "github.com/spy16/slurp/core"
    "github.com/spy16/slurp/repl"
)

var globals = map[string]core.Any{
    "nil":     builtin.Nil{},
    "true":    builtin.Bool(true),
    "false":   builtin.Bool(false),
    "version": builtin.String("1.0"),
}

func main() {
    interp := slurp.New()

    // Bind the globals to the interpreter's global scope.
    if err := interp.Bind(global); err != nil {
        panic(err)
    }

    // configure and start the interpreter
    r := repl.New(env,
	repl.WithBanner("Welcome to slurp!"),
	repl.WithPrompts(">>", " |"))

    if err := r.Loop(context.Background()); err != nil {
        panic(err)
    }
}

Note that core.Any is an alias of interface{}. Slurp allows you to export Go values directly to lisp without any intermediate step.

A complete example can be found in examples/simple/main.go.

Binding Functions

Binding Go functions to the Slurp environment requires an extra step. In order to make the Go function value invokable, it must be wrapped in slurp.Func.

var globals = map[string]core.Any{
    // ...
    "+": slurp.Func("sum", func(a ...int) int {
	sum := 0
	for _, item := range a {
	    sum += item
	}
	return sum
    }),
    // ...
}

A complete example can be found in examples/simple/main.go.

Clone this wiki locally