WITH-FAST-ALIST.html -- ACL2 Version 6.3

## WITH-FAST-ALIST

`(with-fast-alist name form)` causes `name` to be a fast alist for the `` execution of `form`.

    Major Section:  HONS-AND-MEMOIZATION

Logically, `with-fast-alist` just returns `form`.

Under the hood, we cause `alist` to become a fast alist before executing `form`. If doing so caused us to introduce a new hash table, the hash table is automatically freed after `form` completes.

More accurately, under the hood `(with-fast-alist name form)` essentially expands to something like:

     (if (already-fast-alist-p name)
         form
       (let ((<temp> (make-fast-alist name)))
         (prog1 form
                (fast-alist-free <temp>))))

Practically speaking, `with-fast-alist` is frequently a better choice then just using `make-fast-alist`, and is particularly useful for writing functions that can take either fast or slow alists as arguments. That is, consider the difference between:

     (defun bad (alist ...)
       (let* ((fast-alist (make-fast-alist alist))
              (answer     (expensive-computation fast-alist ...)))
        (prog2$ (fast-alist-free fast-alist)
                answer)))

     (defun good (alist ...)
        (with-fast-alist alist
          (expensive-computation alist ...)))

Either approach is fine if the caller provides a slow `alist`. But if the input `alist` is already fast, `bad` will (perhaps unexpectedly) free it! On the other hand, `good` is able to take advantage of an already-fast argument and will not cause it to be inadvertently freed.

See also the macro `with-fast-alists` defined in the community book `"books/centaur/misc/hons-extra.lisp"`, which allows you to call `with-fast-alist` on several alists simultaneously.

The community book `"books/centaur/misc/hons-extra.lisp"` extends the `b*` macro (defined in the community book `"books/tools/bstar.lisp"`) with the `with-fast` pattern binder. That is, after executing `(include-book "centaur/misc/hons-extra.lisp" :dir :system)` you may write something like this:

     (b* (...
          ((with-fast a b c ...))
          ...)
       ...)

which causes `a`, `b`, and `c` to become fast alists until the completion of the `b*` form.

Note that `with-fast-alist` will cause logically tail-recursive functions not to execute tail-recursively if its cleanup phase happens after the tail-recursive call returns.