View Source Document



    -> Tests for functionality "Evaluate Robin Expression (with literal and bind)"

`bind` binds a single identifier to the result of evaluating a single
expression, and makes that binding available in another expression which
it evaluates.

    | (bind x (literal hello)
    |   (prepend x (prepend x ())))
    = (hello hello)

    | (bind dup (fexpr (args env)
    |             (prepend (head args) (prepend (head args) ())))
    |   (dup g))
    = (g g)

    | (bind dup (fexpr (args env)
    |             (bind x (eval env (head args))
    |               (prepend x (prepend x ()))))
    |   (dup (literal g)))
    = (g g)

    | (bind dup (fexpr (args env)
    |             (bind x (eval env (head args))
    |               (prepend x (prepend x ()))))
    |   (dup (dup (literal g))))
    = ((g g) (g g))

`bind` can bind a recursive fexpr to a name.

    | (bind elem?-r
    |   (fexpr (args env)
    |     (bind self (eval env (head args))
    |       (bind target (eval env (head (tail args)))
    |         (bind items (eval env (head (tail (tail args))))
    |           (if (equal? items ()) #f
    |             (if (equal? (head items) target) #t
    |               (self self target (tail items))))))))
    |   (elem?-r elem?-r (literal c) (literal (a b c d e f))))
    = #t

`bind` expects exactly three arguments, or else an abort value will be produced.

    | (bind smoosh (fun (x y) (list y x)))
    ? abort

    | (bind smoosh)
    ? abort

    | (bind)
    ? abort

The identifier in a binding must be a symbol.

    | (bind 3 1 3)
    ? abort

`bind` is basically equivalent to Scheme's `let`, but only one
binding may be given.


(define bind (fexpr (args env)
    (symbol? (head args))
        (prepend (head args) (prepend (eval env (head (tail args)))
                                         ())) env)
      (head (tail (tail args))))
    (abort ((literal expected-symbol) (head args))))))