LISP - Vector Functions
Lisp - Vector Functions
Section titled “Lisp - Vector Functions”Vectors are a fundamental sequence type in Common Lisp, providing O(1) random access to elements. This chapter explores key functions for creating, modifying, and operating on vectors, following modern and idiomatic practices.
Modifying Vector Elements
Section titled “Modifying Vector Elements”Individual elements of a vector are modified using (setf aref).
Using (setf aref)
Section titled “Using (setf aref)”aref (ARray REFerence) is the universal function for accessing elements of any array, including vectors. svref is a specialized version for simple vectors that can be faster, but aref is more general and usually sufficient.
(let ((my-vector (vector 10 20 30 40))) (format t "Original vector: ~a~%" my-vector)
;; Modify the element at index 2 (the third element) (setf (aref my-vector 2) 99)
(format t "Modified vector: ~a~%" my-vector))Output
Section titled “Output”Original vector: #(10 20 30 40)Modified vector: #(10 20 99 40)Using fill
Section titled “Using fill”The fill function efficiently sets all or a subsequence of a vector’s elements to a single value.
(let ((my-vector (vector 1 2 3 4 5))) (format t "Original vector: ~a~%" my-vector)
;; Fill the entire vector with 0 (fill my-vector 0)
(format t "Filled vector: ~a~%" my-vector))Output
Section titled “Output”Original vector: #(1 2 3 4 5)Filled vector: #(0 0 0 0 0)Accessing Vector Information
Section titled “Accessing Vector Information”You can inspect a vector’s properties, such as its length and element type.
;; A general-purpose vector holds any type of element (T)(let ((general-vector (vector "hello" 42 #\c))) (format t "Vector: ~a~%" general-vector) (format t " Length: ~a~%" (length general-vector)) (format t " Element Type: ~a~%" (array-element-type general-vector)))
(terpri)
;; A specialized vector is optimized for a specific type, like integers(let ((specialized-vector (make-array 3 :element-type 'fixnum :initial-contents '(100 200 300)))) (format t "Vector: ~a~%" specialized-vector) (format t " Length: ~a~%" (length specialized-vector)) (format t " Element Type: ~a~%" (array-element-type specialized-vector)))Output
Section titled “Output”Vector: #("hello" 42 #\c) Length: 3 Element Type: T
Vector: #(100 200 300) Length: 3 Element Type: FIXNUMFunctional Vector Operations
Section titled “Functional Vector Operations”Common Lisp’s functional heritage shines with higher-order functions like map and reduce, which can operate on vectors to produce new results without mutation.
Transforming with map
Section titled “Transforming with map”The map function applies a function to each element of a sequence, returning a new sequence. The first argument 'vector specifies that the result should be a vector.
(let* ((original (vector 1 2 3 4 5)) (doubled (map 'vector #'(lambda (x) (* x 2)) original)))
(format t "Original: ~a~%" original) (format t "Doubled: ~a~%" doubled))Output
Section titled “Output”Original: #(1 2 3 4 5)Doubled: #(2 4 6 8 10)Aggregating with reduce
Section titled “Aggregating with reduce”The reduce function combines the elements of a sequence into a single value using a binary function.
(let* ((numbers (vector 1 2 3 4 5 6)) (sum (reduce #'+ numbers)))
(format t "Numbers: ~a~%" numbers) (format t "Sum: ~a~%" sum))Output
Section titled “Output”Numbers: #(1 2 3 4 5 6)Sum: 21Best Practices: Testing Your Functions
Section titled “Best Practices: Testing Your Functions”When writing functions that operate on vectors, it’s crucial to test them. While full testing frameworks like FiveAM or Prove are recommended for projects, you can perform simple checks using assert.
(defun sum-vector (vec) (reduce #'+ vec))
;; Test cases(assert (= (sum-vector (vector 1 2 3)) 6))(assert (= (sum-vector (vector)) 0))(assert (= (sum-vector (vector -1 1)) 0))
(format t "All sum-vector tests passed!~%")This simple approach validates that your function works for typical inputs, empty inputs (an edge case), and other scenarios.