LISP - Vectors
Lisp - Vectors
Section titled “Lisp - Vectors”Vectors are one-dimensional arrays and, along with lists, are a fundamental sequence type in Common Lisp. Unlike lists, which are optimized for sequential access and modification at the front, vectors provide fast, constant-time (O(1)) random access to their elements. This makes them ideal for collections where you need to look up elements by index.
Creating Vectors
Section titled “Creating Vectors”There are several ways to create vectors, each suited to different needs.
1. The vector function
Section titled “1. The vector function”The simplest way to create a vector with predefined elements is with the vector function. It takes any number of arguments and returns a new vector containing them.
(let ((v1 (vector 1 2 3 4 5)) (v2 (vector 'a "hello" t))) (format t "Numeric vector: ~a~%" v1) (format t "Mixed vector: ~a~%" v2))Output
Section titled “Output”Numeric vector: #(1 2 3 4 5)Mixed vector: #(A "hello" T)2. The #( ... ) reader macro
Section titled “2. The #( ... ) reader macro”Lisp provides a literal syntax for vectors: #( ... ). This is convenient for embedding constant vector data directly in your code.
Warning: According to the standard, you should never modify a literal object. Doing so can lead to undefined behavior, as the Lisp system may store literals in read-only memory. For vectors you intend to modify, always use vector or make-array.
(defvar *my-constant-vector* #(A B C))(write *my-constant-vector*)3. The make-array function
Section titled “3. The make-array function”make-array is the most general and powerful function for creating arrays, including vectors. For a vector, you provide a single dimension.
;; Create a vector of size 5, with each element initialized to 0.(let ((zero-vec (make-array 5 :initial-element 0))) (format t "Zero-initialized vector: ~a~%" zero-vec))
;; Create a vector from an existing list of contents(let ((from-list (make-array 3 :initial-contents '(10 20 30)))) (format t "Vector from list: ~a~%" from-list))Output
Section titled “Output”Zero-initialized vector: #(0 0 0 0 0)Vector from list: #(10 20 30)Dynamic Vectors with Fill Pointers
Section titled “Dynamic Vectors with Fill Pointers”A key feature of Lisp vectors is the fill pointer. A vector with a fill pointer acts like a dynamic array or list from other languages (e.g., C++ std::vector or Python list). It maintains a length independent of its total allocated capacity, allowing for efficient additions to the end.
You create one by passing the :fill-pointer argument to make-array.
vector-push: Adds an element to the end of the vector and increments the fill pointer. It returns the index where the element was added, ornilif the vector is full.vector-pop: Removes and returns the last element (at the fill pointer) and decrements the fill pointer.
Example
Section titled “Example”;; Create a vector with a capacity of 5 but an initial length of 0(let ((dyn-vec (make-array 5 :fill-pointer 0))) (format t "Initial: ~a (Length: ~a)~%" dyn-vec (length dyn-vec))
;; Push some elements (vector-push 'a dyn-vec) (vector-push 'b dyn-vec) (vector-push 'c dyn-vec) (format t "After 3 pushes: ~a (Length: ~a)~%" dyn-vec (length dyn-vec))
;; Pop an element (let ((popped-item (vector-pop dyn-vec))) (format t "Popped '~a'. Vector is now: ~a (Length: ~a)~%" popped-item dyn-vec (length dyn-vec)))
;; Fill the rest of the capacity (vector-push 'd dyn-vec) (vector-push 'e dyn-vec) (format t "Filled to capacity: ~a~%" dyn-vec)
;; This push will fail because the vector is full (let ((result (vector-push 'f dyn-vec))) (format t "Attempting to push past capacity returned: ~a~%" result)))Output
Section titled “Output”Initial: #() (Length: 0)After 3 pushes: #(A B C) (Length: 3)Popped 'C'. Vector is now: #(A B) (Length: 2)Filled to capacity: #(A B D E)Attempting to push past capacity returned: NILPro Tip: For truly dynamic, resizable vectors, use make-array with both :fill-pointer and :adjustable t. This allows you to use vector-push-extend (a common utility, often from a library) which automatically resizes the vector’s capacity when it becomes full.