String vs &str - why?

Well, map in mathematics is

  • another term for a function, often with some sort of special structure

so it fits nicely.


Of course I do agree that different fields do give different meanings to the same term. And even within mathematics the situation is quite bad. Don’t try to discuss whether 0 is a natural number, if an “ordered set” has a partial order or a total/linear order, or what exactly the symbol means. And don’t tell me about your favorite way to denote power sets.

It’s just: Linear algebra in programming is a thing, so I’m just saying, letting them keep the term “vector” seems like a nice thing to do to me.

They do, in general. However, in the specific case when a String-as-a-concrete-type is involved, it is known that there is a heap allocation somewhere.

It is not my terminology. Rustaceans talk about owning vs. borrowing types all the time.

I'm not. It's just the demonstration of why/how it is owning. A stack-allocated [T; N] array would be an owner of Ts as well.

I'm not going to respond to the other points because I know how borrowing and ownership works in Rust.

You are nitpicking using this special case here, which I find spectacularly unhelpful w.r.t. explaining the general case to a newcomer, which is what I was trying to do here.

Technically, str is a primitive and not a wrapper.

1 Like

While true, it semantically makes no difference. In the same way you can think of bool as an enum with two variants, nothing is different to a user if it's a primitive.

I agree that String and StringBuf would have been better names for str and String, also eliminating a source of confusion about why there are two different types with the same name.

To replace Vec<T> I would have suggested just Buf<T>. A String (StringBuf) is essentially a specialized kind of Vec<u8> (Buf<u8>), so it would make sense to call Vec a more generic name.

The origin of using the name "vector" for a growable array is that when STL was first written, the author (Alex Stepanov) thought that he was copying Lisp's terminology, but really was just confused, because in Lisp it's the exact opposite: a "vector" is a fixed-size array (named with linear algebra applications in mind) while an "array" is growable.

1 Like

I don't see Buf as any more suitable. It implies buffer. If one looks at all the definitions of buffer https://dictionary.cambridge.org/dictionary/english/buffer none of them are appropriate for an array. Not even the the typical use in computing:

"the part of a computer's memory that temporarily stores information before exchanging it with another piece of equipment such as a printer, keyboard, or external drive"

So 'buffer' describes a particular narrow use of arrays, which are far more general purpose.

I don't really have an issue with a vector that can magically change it's number of elements. Who says the number of dimensions of whatever space one is working in cannot change? Perhaps there are mathematicians working on such models.

buffer: a section of computer memory for temporarily storing information especially: one that accepts information at one rate and delivers it at another

This matches growable arrays nicely: as the data elements arrive, you stick them at the end for later delivery to the user of the data.

True.

Although many buffers I have created/used were not like that at all. For example fixed size arrays, as far as the language was concerned, used a cyclic buffers. Data being put in at a "head" position and coming out at a "tail" position. No array resizing or allocation going on.

Or buffers implemented as a pool of blocks chained together in linked lists. Like some old network drivers I worked on.

Arrays are general purpose. Buffers are a specific application of arrays.

Besides, calling arrays "vectors" sound a lot more sophisticated and technical. Which is nice.

If we called them Array then we could have &arr. At that point we could change the name of the language to "Pirate". :slight_smile:

I think that is enough bike shedding for me today.

Nobody has suggested calling all arrays "buffers", only the growable ones. If you don't need the resizing capability, your API shouldn't be using a Vec, it should be taking an array or a slice.

1 Like

I thought you did:

To my mind a Vec is an array. But not necessarily a buffer.

Anyway, things are what they are and all is well.

Not only semantically: to get the length of a string, for example, the standard library transmutes str into [u8], then calls the method [T]::len(). This method creates a union which is, actually, equivalent to:

#[repr(C)]
pub(crate) union Repr<T> {
    pub(crate) rust: *const [T],
    rust_mut: *mut [T],
    pub(crate) raw: FatPtr<T>,
}

#[repr(C)]
pub(crate) struct FatPtr<T> {
    data: *const T,
    pub(crate) len: usize,
}

In fact, that was exactly the code in previous versions.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.