From my understanding Strings are vectors of type character. So far my attempts have been unfruitful
(vector-push #\a "Hol")
;; "Hol" Is not of type vector and simple-array
Is the literal "Hol" a constant vector in the same manner that '(1 2 3) is not the same as (list 1 2 3)? Should I just create a vector of characters explicitly and add characters to it?
You've got the right diagnosis. It's not even a matter of literal data (e.g., (list 1 2 3)
vs. '(1 2 3)
) versus modifiable data, though. It's whether the vector has a fill pointer. The documentation for vector-push
and vector-push-extend
say that the vector argument is a vector with a fill pointer. You'll get a similar error with non-literal arrays that don't have a fill pointer, as in:
(let ((v (make-array 3)))
(vector-push nil v))
All you need to do is make sure that you create the vector with a fill pointer, and that it big enough to hold the things you push in:
(let ((v (make-array 2 :fill-pointer 0)))
(print v)
(vector-push 'x v)
(print v)
(vector-push 'y v)
(print v)
(vector-push 'z v)
(print v))
vector-push
doesn't adjust the array, so you get not z
in the vector from the final vector-push
:
#()
#(X)
#(X Y)
#(X Y)
If you make the vector adjustable, and use vector-push-extend
, you can get a bigger array:
(let ((v (make-array 2 :adjustable t :fill-pointer 0)))
(print v)
(vector-push 'x v)
(print v)
(vector-push 'y v)
(print v)
(vector-push-extend 'z v)
(print v))
#()
#(X)
#(X Y)
#(X Y Z)
Using an element type of character
, you'll be doing this with strings:
(let ((v (make-array 2 :element-type 'character :adjustable t :fill-pointer 0)))
(print v)
(vector-push #\x v)
(print v)
(vector-push #\y v)
(print v)
(vector-push-extend #\z v)
(print v))
""
"x"
"xy"
"xyz"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With