Skip to content

Latest commit

 

History

History
96 lines (70 loc) · 1.89 KB

README.md

File metadata and controls

96 lines (70 loc) · 1.89 KB

Go TailCall

Functions in this go module implement tail calls via trampolining. This module depends on Go's new generics language feature, so Go 1.18 or newer is required.

Tail calling functions return their result using TailRet or call the next function using TailCall. Both return a TailRec struct.

The result of evaluating a tailcalling function can be retrieved from using function TailStart.

Installation

To install go_tailcall module, you can use the command below

go get -u github.com/kandu/go_tailcall@0.3

Quick start

package main

import . "github.com/kandu/go_tailcall/tailcall2"
import "fmt"
import "log"
import "strconv"

func a(v int64) TailRec[int64, error] {
    v++
    fmt.Printf("a %d\n", v)

    var s= strconv.FormatInt(v, 10)
    return TailCall(b, s)
}

func b(s string) TailRec[int64, error] {
    s= s + "0"
    fmt.Printf("b %s\n", s)

    var v, _= strconv.ParseInt(s, 10, 64)
    var limit int64= 1 << 50
    if v >= limit {
        return TailRet[int64, error](v, nil)
    } else {
        return TailCall(a, v)
    }
}

func main() {
    var r, err= TailStart(a(0))
    if err != nil {
        log.Fatal(err)
    } else {
        fmt.Printf("a(): %d\n", r)
    }
}

And below are infinite mutually recursive functions. They will run forever and will not suffer from stack overflow.

package main

import . "github.com/kandu/go_tailcall/tailcall"
import "fmt"
import "strconv"


func a(v int64) TailRec[int64] {
    v++
    fmt.Printf("a %d\n", v)

    var s= strconv.FormatInt(v, 10)
    return TailCall(b, s)
}

func b(s string) TailRec[int64] {
    s= s + "0"
    fmt.Printf("b %s\n", s)

    var v, _= strconv.ParseInt(s, 10, 64)
    var limit int64= 1 << 50
    if v >= limit {
        return TailCall(a, 0)
    } else {
        return TailCall(a, v)
    }
}


func main() {
    fmt.Println("infinite mutually recursive functions")
    TailStart(a(0))
}