Coroutines - Spicery/Nutmeg GitHub Wiki

Work in progress:

  • choose/fail are backtracking constructs from Lisp's AMB / FAIL.
  • fail has variants fail if EXPR and fail ifnot EXPR.
  • returns is a way of adding a normal return value on normal exit.
  • a coroutine that fails returns the unhappy result Fail.
@coroutine
def findSolution() returns (x, y):
    ### Attempt to find a valid solution using CHOICE and FAIL
    x := choose(1, 2, 3)
    y := choose(4, 5, 6)

    fail ifnot x.isValid(y)
enddef

def main():
    try solution... := findSolution():
        print("Solution found: ", solution)
    case Fail:
        print("No valid solution found")
    endtry
enddef

A semi-realistic example:

  • The list handling needs more work
    • the [] will construct immutable lists
    • the use of append isn't very nutmeg like
    • and the backtracking will not undo the surgical assignments.
@coroutine
def solveNQueens(n) returns board:
    board := []
    for row in range(1, n+1):
        col := choose(range(1, n+1))
        fail ifnot board.isSafe(row, col)
        board <- [ (row, col), board... ]
    endfor
enddef

def main():
    n := 8
    try solution... := solveNQueens(n):
        print("Solution for ", n, "-Queens:")
        printBoard(solution)
    case Fail:
        print("No solution found for ", n, "-Queens")
    endtry
enddef