If a string in lisp is a vector, why can't I access the first element using svref?
Asked Answered
M

2

7

So, I'm trying to learn Lisp, and I've come across a problem in the definition of what a String is.

I'm reading the ANSI Common Lisp by Paul Graham, and in this book it states that a String is a vector, or one-dimensional Array.

So, I create a String:

(defvar *my-string* "abc")

And then I can access the first value of my-string this way:

(aref *my-string* 0)

But if it is a vector, why can't I access that element this way:

(svref *my-string* 0)

I mean, when I create a vector this way:

(defvar my-vec (make-array 4 :initial-element 1))

I can access first element using svref:

(svref my-vec 0) ; returns 1

I forgot to add error when I try svref on String:

"The value "abc" is not of type (SIMPLE-ARRAY T (*))."

Malaco answered 2/10, 2014 at 15:40 Comment(2)
What is the error message or behavior you're actually getting from svref?Sybilla
@RobertHarvey thanks for reminding me! The reason why I'm asking is because I constantly work with Strings, and I read in Graham's book that svref is faster than aref, so wanted to see if I could utilise this in my coding.Malaco
L
9

String is a vector, but it isn't a simple-vector. svref takes a simple-vector as first argument.

You can check it by calling:

(vector-p *my-string*)

which returns true

Unlike:

(simple-vector-p *my-string*)

which returns false.

Notice that (simple-vector-p my-vec) will return true as well, which confirms that make-array creates a simple-vector.

Longhand answered 2/10, 2014 at 15:49 Comment(6)
So, could you explain what the difference between a vector and simple-vector is, I can't find it in the documentation? I can only find that simple-vector is a subtype of vector.Malaco
@ArashSaidi here's a nice discussion of the subject. Basically simple-vectors are specialized to hold certain type of elements. strings are another specialization of vectors, but they're not simple-vectors.Longhand
Thanks, will look into it. Was planning on reading that book after Graham's!Malaco
@ArashSaidi It may just be a typo, but I think that description is backwards: a simple-vector is one that can hold any time of element. The documentation for simple-vector says that its element type is t; that is, it can hold any type of element. If you consider the possible implementations, this becomes a bit clearer: if a vector is specialized for a particular type (e.g., cons), then the vector could hold the cons cells "in place", but if a vector is a simple vector, then it's essentially an array of (what would be in C) void pointers. It would make the pointer arithmetic...Copro
... much simpler, and (I'd expect) that svref can take advantage of that fact.Copro
@JoshuaTaylor yeah I mixed that up.Longhand
C
5

soulcheck's answer is absolutely right, but it's worth the time to become comfortable with the HyperSpec. For instance, if you start at the page for svref, there's a note at the bottom:

Notes:

svref is identical to aref except that it requires its first argument to be a simple vector.

The glossary entry for simple vector (linked above) says:

simple vector n. a vector of type simple-vector, sometimes called a "simple general vector." Not all vectors that are simple are simple vectors—only those that have element type t.

15.2 The Arrays Dictionary is also helpful here, as is 15. Arrays as a whole.

Copro answered 2/10, 2014 at 18:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.