• Top
    • Documentation
    • Books
    • Recursion-and-induction
    • Boolean-reasoning
    • Projects
    • Debugging
    • Std
    • Proof-automation
    • Macro-libraries
    • ACL2
      • Theories
      • Rule-classes
      • Proof-builder
      • Hons-and-memoization
      • Events
      • History
      • Parallelism
      • Programming
        • Defun
        • Declare
        • System-utilities
        • Stobj
        • State
        • Memoize
        • Mbe
        • Io
        • Defpkg
        • Apply$
        • Mutual-recursion
        • Loop$
        • Programming-with-state
        • Arrays
        • Characters
        • Time$
        • Loop$-primer
        • Fast-alists
          • Slow-alist-warning
          • Hons-acons
          • Fast-alist-fork
          • Hons-acons!
          • With-fast-alist
            • Fast-alist-clean
            • Fast-alist-pop
            • Fast-alist-free
            • Fast-alist-pop*
            • Hons-get
            • Hons-assoc-equal
            • Make-fast-alist
            • Make-fal
            • Fast-alist-free-on-exit
            • With-stolen-alist
            • Fast-alist-fork!
            • Fast-alist-summary
            • Fast-alist-clean!
            • Fast-alist-len
            • With-stolen-alists
            • Fast-alists-free-on-exit
            • Cons-subtrees
            • With-fast-alists
            • Hons-dups-p1
            • Ansfl
            • Hons-revappend
            • Hons-member-equal
            • Hons-make-list
            • Hons-reverse
            • Hons-list*
            • Hons-list
            • Hons-append
          • Defmacro
          • Defconst
          • Evaluation
          • Guard
          • Equality-variants
          • Compilation
          • Hons
          • ACL2-built-ins
          • Developers-guide
          • System-attachments
          • Advanced-features
          • Set-check-invariant-risk
          • Numbers
          • Irrelevant-formals
          • Efficiency
          • Introduction-to-programming-in-ACL2-for-those-who-know-lisp
          • Redefining-programs
          • Lists
          • Invariant-risk
          • Errors
          • Defabbrev
          • Conses
          • Alists
            • Std/alists
            • Omaps
            • Fast-alists
              • Slow-alist-warning
              • Hons-acons
              • Fast-alist-fork
              • Hons-acons!
              • With-fast-alist
                • Fast-alist-clean
                • Fast-alist-pop
                • Fast-alist-free
                • Fast-alist-pop*
                • Hons-get
                • Hons-assoc-equal
                • Make-fast-alist
                • Make-fal
                • Fast-alist-free-on-exit
                • With-stolen-alist
                • Fast-alist-fork!
                • Fast-alist-summary
                • Fast-alist-clean!
                • Fast-alist-len
                • With-stolen-alists
                • Fast-alists-free-on-exit
                • Cons-subtrees
                • With-fast-alists
                • Hons-dups-p1
                • Ansfl
                • Hons-revappend
                • Hons-member-equal
                • Hons-make-list
                • Hons-reverse
                • Hons-list*
                • Hons-list
                • Hons-append
              • Alistp
              • Misc/records
              • Remove-assocs
              • Assoc
              • Symbol-alistp
              • Rassoc
              • Remove-assoc
              • Remove1-assoc
              • Alist-map-vals
              • Depgraph
              • Alist-map-keys
              • Put-assoc
              • Strip-cars
              • Pairlis$
              • Strip-cdrs
              • Sublis
              • Acons
              • Eqlable-alistp
              • Assoc-string-equal
              • Standard-string-alistp
              • Alist-to-doublets
              • Character-alistp
              • Alist-keys-subsetp
              • R-symbol-alistp
              • R-eqlable-alistp
              • Pairlis
              • Pairlis-x2
              • Pairlis-x1
              • Delete-assoc
            • Set-register-invariant-risk
            • Strings
            • Program-wrapper
            • Get-internal-time
            • Basics
            • Packages
            • Defmacro-untouchable
            • Primitive
            • <<
            • Revert-world
            • Set-duplicate-keys-action
            • Unmemoize
            • Symbols
            • Def-list-constructor
            • Easy-simplify-term
            • Defiteration
            • Defopen
            • Sleep
          • Start-here
          • Real
          • Debugging
          • Miscellaneous
          • Output-controls
          • Macros
          • Interfacing-tools
        • Interfacing-tools
        • Hardware-verification
        • Software-verification
        • Testing-utilities
        • Math
      • Fast-alists
      • ACL2-built-ins

      With-fast-alist

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

      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 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.