spy16 / sabre

Sabre is highly customisable, embeddable LISP engine for Go. :computer:
GNU General Public License v3.0
28 stars 5 forks source link

Invoke on List type #29

Open issadarkthing opened 4 years ago

issadarkthing commented 4 years ago

Hi, how do I invoke an Invokable with List as its argument without the List is being evaluated? Here's a simple implementation to create a reduce function which requires the callback function to accept List and Int64 type.

package main

import (
    "fmt"

    "github.com/spy16/sabre"
)

const program = `
(print (reduce (fn [acc x] (acc.Cons x)) '() '(1 2 3)))
`

func main() {
    scope := sabre.New()
    scope.BindGo("sum", sum)
    scope.BindGo("print", fmt.Println)
    scope.BindGo("fn", sabre.Lambda)
    scope.BindGo("reduce", reduce)

    _, err := sabre.ReadEvalStr(scope, program)
    if err != nil {
        panic(err)
    }
}

func reduce(fn sabre.MultiFn, acc sabre.Value, list *sabre.List) (sabre.Value, error) {

    for _, v := range list.Values {
        applied, err := fn.Invoke(nil, acc, v)
        if err != nil {
            return nil, err
        }
        acc = applied
    }

    return acc, nil
}

This will produce this error.

$ go run main.go
panic: eval-error in '' (at line 0:0): cannot invoke value of type 'sabre.Int64'

goroutine 1 [running]:
main.main()
    /home/terra/Documents/system33/go/sabre/examples/simple/main.go:22 +0x194
exit status 2